示例#1
0
void
dictionary_rep::load (url u) {
  if (is_none (u)) return;
  if (is_or (u)) {
    load (u[1]);
    load (u[2]);
    return;
  }

  string s;
  if (load_string (u, s, false)) return;
  tree t= block_to_scheme_tree (s);
  if (!is_tuple (t)) return;

  int i, n= N(t);
  for (i=0; i<n; i++)
    if (is_func (t[i], TUPLE, 2) &&
        is_atomic (t[i][0]) && is_atomic (t[i][1]))
    {
      string l= t[i][0]->label; if (is_quoted (l)) l= scm_unquote (l);
      string r= t[i][1]->label; if (is_quoted (r)) r= scm_unquote (r);
      if (to == "chinese" ||  to == "japanese"  || to == "german" ||
          to == "korean"  ||  to == "taiwanese" ||
          to == "russian" ||  to == "ukrainian" || to == "bulgarian")
        r= utf8_to_cork (r);
      table (l)= r;
    }
}
示例#2
0
bool
is_rooted (url u, string protocol) {
  return
    is_root (u, protocol) ||
    (is_concat (u) && is_rooted (u[1], protocol)) ||
    (is_or (u) && is_rooted (u[1], protocol) && is_rooted (u[2], protocol));
}
示例#3
0
bool
is_rooted (url u) {
  return
    is_root (u) ||
    (is_concat (u) && is_rooted (u[1])) ||
    (is_or (u) && is_rooted (u[1]) && is_rooted (u[2]));
}
示例#4
0
 /**
    \brief Given
               C1 : H1,  where C1 contains l
               C2 : H2,  where C2 contains not_l
     Return a proof of the resolvent R of C1 and C2
 */
 expr mk_or_elim_tree1(expr const & l, expr const & not_l, expr C1, expr const & H1, expr const & C2, expr const & H2,
                       expr const & R, extension_context & ctx) const {
     check_system("resolve macro");
     expr lhs, rhs;
     if (is_or(C1, lhs, rhs)) {
         return mk_or_elim_tree1(l, not_l, lhs, rhs, H1, C2, H2, R, ctx);
     } else {
         C1 = whnf(C1, ctx);
         if (is_or(C1, lhs, rhs)) {
             return mk_or_elim_tree1(l, not_l, lhs, rhs, H1, C2, H2, R, ctx);
         } else if (is_def_eq(C1, l, ctx)) {
             return mk_or_elim_tree2(C1, H1, not_l, C2, H2, R, ctx);
         } else {
             return mk_or_intro(C1, H1, R, ctx);
         }
     }
 }
示例#5
0
url
delta (url base, url u) {
  if (is_or (u))
    return delta (base, u[1]) | delta (base, u[2]);
  url res= delta_sub (base, u);
  if (is_none (res)) return u;
  return res;
}
示例#6
0
 bool collect(expr cls, expr const & l, buffer<expr> & R, extension_context & ctx) const {
     check_system("resolve macro");
     expr lhs, rhs;
     if (is_or(cls, lhs, rhs)) {
         return collect(lhs, rhs, l, R, ctx);
     } else {
         cls = whnf(cls, ctx);
         if (is_or(cls, lhs, rhs)) {
             return collect(lhs, rhs, l, R, ctx);
         } else if (is_def_eq(cls, l, ctx)) {
             return true; // found literal l
         } else {
             if (!already_contains(cls, R, ctx))
                 R.push_back(cls);
             return false;
         }
     }
 }
示例#7
0
bool
descends (url u, url base) {
  if (is_or (base)) return descends (u, base[1]) || descends (u, base[2]);
  if (is_concat (u) && is_atomic (base))
    return u[1] == base;
  if (is_concat (u) && is_concat (base))
    return u[1] == base[1] && descends (u[2], base[2]);
  return false;
}
示例#8
0
 /**
    Given
          l  : H
          C2 : H2, where C2 contains not_l
    produce a proof for R
 */
 expr mk_or_elim_tree2(expr const & l, expr const & H, expr const & not_l, expr C2, expr const & H2,
                       expr const & R, extension_context & ctx) const {
     check_system("resolve macro");
     expr lhs, rhs;
     if (is_or(C2, lhs, rhs)) {
         return mk_or_elim_tree2(l, H, not_l, lhs, rhs, H2, R, ctx);
     } else {
         C2 = whnf(C2, ctx);
         if (is_or(C2, lhs, rhs)) {
             return mk_or_elim_tree2(l, H, not_l, lhs, rhs, H2, R, ctx);
         } else if (is_def_eq(C2, not_l, ctx)) {
             // absurd_elim {a : Prop} (b : Prop) (H1 : a) (H2 : ¬ a) : b
             return mk_app(*g_absurd_elim, l, R, H, H2);
         } else {
             return mk_or_intro(C2, H2, R, ctx);
         }
     }
 }
示例#9
0
static url
sort_sub (url add, url to) {
  if (is_or (to)) {
    if (add <= to[1]) return add | to;
    return to[1] | sort_sub (add, to[2]);
  }
  if (add <= to) return add | to;
  else return to | add;
}
示例#10
0
url
glue (url u, string s) {
  if (is_atomic (u)) return as_url (tree (u->t->label * s));
  if (is_concat (u)) return u[1] * glue (u[2], s);
  if (is_or (u)) return glue (u[1], s) | glue (u[2], s);
  failed_error << "u= " << u << "\n";
  failed_error << "s= " << s << "\n";
  FAILED ("can't glue string to url");
  return u;
}
示例#11
0
url
tail (url u) {
  if (is_concat (u)) {
    if (is_root_web (u[1]) && is_atomic (u[2])) return url_here ();
    return tail (u[2]);
  }
  if (is_or (u)) return tail (u[1]) | tail (u[2]);
  if (is_root (u)) return url_here ();
  return u;
}
示例#12
0
url
unglue (url u, int nr) {
  if (is_atomic (u))
    return as_url (tree (u->t->label (0, max (N(u->t->label) - nr, 0))));
  if (is_concat (u)) return u[1] * unglue (u[2], nr);
  if (is_or (u)) return unglue (u[1], nr) | unglue (u[2], nr);
  failed_error << "u = " << u << "\n";
  failed_error << "nr= " << nr << "\n";
  FAILED ("can't unglue from url");
  return u;
}
示例#13
0
string
get_root (url u) {
  if (is_concat (u)) return get_root (u[1]);
  if (is_or (u)) {
    string s1= get_root (u[1]);
    string s2= get_root (u[2]);
    if (s1 == s2) return s1; else return "";
  }
  if (is_root (u)) return u[1]->t->label;
  return "";
}
示例#14
0
static url
complete (url base, url sub, url u, string filter, bool flag) {
  if (is_or (sub)) {
    url res1= complete (base, sub[1], u, filter, flag);
    if ((!is_none (res1)) && flag) return res1;
    return res1 | complete (base, sub[2], u, filter, flag);
  }
  if (is_concat (sub) && is_rooted (sub[1])) {
    url res= complete (sub[1], sub[2], u, filter, flag);
    return sub[1] * res;
  }
  return sub * complete (base * sub, u, filter, flag);
}
示例#15
0
文件: loliwm.c 项目: holomorph/loliwm
static void
relayout(struct wlc_space *space)
{
   if (!space)
      return;

   struct wl_list *views;
   if (!(views = wlc_space_get_userdata(space)))
      return;

   uint32_t rwidth, rheight;
   struct wlc_output *output = wlc_space_get_output(space);
   wlc_output_get_resolution(output, &rwidth, &rheight);

   struct wlc_view *v;
   uint32_t count = 0;
   wlc_view_for_each_user(v, views)
      if (is_tiled(v)) ++count;

   bool toggle = false;
   uint32_t y = 0, height = rheight / (count > 1 ? count - 1 : 1);
   uint32_t fheight = (rheight > height * (count - 1) ? height + (rheight - height * (count - 1)) : height);
   wlc_view_for_each_user(v, views) {
      if (wlc_view_get_state(v) & WLC_BIT_FULLSCREEN) {
         wlc_view_resize(v, rwidth, rheight);
         wlc_view_position(v, 0, 0);
      }

      if (wlc_view_get_type(v) & WLC_BIT_SPLASH)
         wlc_view_position(v, rwidth * 0.5 - wlc_view_get_width(v) * 0.5, rheight * 0.5 - wlc_view_get_height(v) * 0.5);

      struct wlc_view *parent;
      if (is_managed(v) && !is_or(v) && (parent = wlc_view_get_parent(v)))
         layout_parent(v, parent, wlc_view_get_width(v), wlc_view_get_height(v));

      if (!is_tiled(v))
         continue;

      uint32_t slave = rwidth * loliwm.cut;
      wlc_view_set_state(v, WLC_BIT_MAXIMIZED, true);
      wlc_view_resize(v, (count > 1 ? (toggle ? slave : rwidth - slave) : rwidth), (toggle ? (y == 0 ? fheight : height) : rheight));
      wlc_view_position(v, (toggle ? rwidth - slave : 0), y);

      if (toggle)
         y += (y == 0 ? fheight : height);

      toggle = true;
   }
}
示例#16
0
void
tmfs_import (url prj_dir, url u, string prj) {
  cout << "Process " << (prj_dir * u) << "\n";
  if (is_or (u)) {
    tmfs_import (prj_dir, u[1], prj);
    tmfs_import (prj_dir, u[2], prj);
  }
  else if (is_directory (prj_dir * u)) {
    bool flag;
    array<string> a= read_directory (prj_dir * u, flag);
    if (flag) return;
    for (int i=0; i<N(a); i++)
      if (!is_cruft (a[i]) && a[i] != "." && a[i] != "..")
	tmfs_import (prj_dir, u * a[i], prj);
  }
  else if (is_regular (prj_dir * u)) {
    string loc= as_string (u);
    properties ps;
    ps << seq ("mirror", "?file", prj, loc) << seq ("in", "?file", prj);
    collection files= tmfs_query (ps, "?file");
    if (N (files) == 0) {
      properties xps; xps << seq ("mirror", "self", prj, loc);
      string val = load_string (prj_dir * u);
      string name= create_name (as_string (tail (u)), val);
      string file= tmfs_create_file (name, val, prj, xps);
      cout << "Import " << u << " -> " << file << "\n";
    }
    else {
      string file= first (files);
      string val1= tmfs_load_file (file);
      string val2= load_string (prj_dir * u);
      if (val1 == val2) return;
      tmfs_save_file (file, val2);
      cout << "Update " << u << " -> " << file << "\n";
    }
  }

  properties ps= tmfs_list_heads_inside (u, prj);
  for (int i=0; i<N(ps); i++) {
    url    v = ps[i][0];
    string file= ps[i][1];
    if (!exists (prj_dir * v)) {
      tmfs_reset_head (file);
      cout << "Remove " << v << " -> " << file << "\n";
    }
  }
}
示例#17
0
bool
is_path (url u) {
  if (is_atomic (u)) return true;
  if ((!is_or (u)) && (!is_concat (u))) return false;
  return is_path (u[1]) && is_path (u[2]);
}
示例#18
0
文件: eval.c 项目: ingramj/bs
object *bs_eval(object *exp, object *env)
{
tailcall:
    if (is_empty_list(exp)) {
        error("unable to evaluate empty list");
    } else if (is_self_evaluating(exp)) {
        return exp;
    } else if (is_variable(exp)) {
        return lookup_variable_value(exp, env);
    } else if (is_quoted(exp)) {
        return quoted_expression(exp);
    } else if (is_assignment(exp)) {
        return eval_assignment(exp, env);
    } else if (is_definition(exp)) {
        return eval_definition(exp, env);
    } else if (is_if(exp)) {
        if (is_true(bs_eval(if_predicate(exp), env))) {
            exp = if_consequent(exp);
        } else {
            exp = if_alternate(exp);
        }
        goto tailcall;
    } else if (is_lambda(exp)) {
        return make_compound_proc(lambda_parameters(exp),
                lambda_body(exp),
                env);
    } else if (is_begin(exp)) {
        exp = begin_actions(exp);
        if (is_empty_list(exp)) {
            error("empty begin block");
        }
        while (!is_empty_list(cdr(exp))) {
            bs_eval(car(exp), env);
            exp = cdr(exp);
        }
        exp = car(exp);
        goto tailcall;
    } else if (is_cond(exp)) {
        exp = cond_to_if(exp);
        goto tailcall;
    } else if (is_let(exp)) {
        exp = let_to_application(exp);
        goto tailcall;
    } else if (is_and(exp)) {
        exp = and_tests(exp);
        if (is_empty_list(exp)) {
            return get_boolean(1);
        }
        object *result;
        while (!is_empty_list(cdr(exp))) {
            result = bs_eval(car(exp), env);
            if (is_false(result)) {
                return result;
            }
            exp = cdr(exp);
        }
        exp = car(exp);
        goto tailcall;
    } else if (is_or(exp)) {
        exp = or_tests(exp);
        if (is_empty_list(exp)) {
            return get_boolean(0);
        }
        object *result;
        while (!is_empty_list(cdr(exp))) {
            result = bs_eval(car(exp), env);
            if (is_true(result)) {
                return result;
            }
            exp = cdr(exp);
        }
        exp = car(exp);
        goto tailcall;
    } else if (is_application(exp)) {
        object *procedure = bs_eval(application_operator(exp), env);
        object *parameters = eval_parameters(application_operands(exp), env);

        // handle eval specially for tailcall requirement.
        if (is_primitive_proc(procedure) &&
                procedure->value.primitive_proc == eval_proc) {
            exp = eval_expression(parameters);
            env = eval_environment(parameters);
            goto tailcall;
        }

        // handle apply specially for tailcall requirement.
        if (is_primitive_proc(procedure) &&
                procedure->value.primitive_proc == apply_proc) {
            procedure = apply_operator(parameters);
            parameters = apply_operands(parameters);
        }

        if (is_primitive_proc(procedure)) {
            return (procedure->value.primitive_proc)(parameters);
        } else if (is_compound_proc(procedure)) {
            env = extend_environment(
                    procedure->value.compound_proc.parameters,
                    parameters,
                    procedure->value.compound_proc.env);
            exp = make_begin(procedure->value.compound_proc.body);
            goto tailcall;
        } else {
            error("unable to apply unknown procedure type");
        }
    } else {
        error("unable to evaluate expression");
    }
}
示例#19
0
string
as_string (url u, int type) {
  // This routine pritty prints an url as a string.
  // FIXME: the current algorithm is quadratic in time.
  if (is_none (u)) return "{}";
  if (is_atomic (u)) return u->t->label;
  if (is_concat (u)) {
    int stype= type;
    if (is_root (u[1]) && (!is_root (u[1], "default"))) stype= URL_STANDARD;
    string sep= (stype==URL_SYSTEM? string (URL_CONCATER): string ("/"));
    string s1 = as_string (u[1], type);
    string s2 = as_string (u[2], stype);
    if (is_root (u[1], "default")) s1= "";
    if ((!is_name (u[1])) && (!is_root (u[1]))) s1= "{" * s1 * "}";
    if ((!is_concat (u[2])) && (!is_atomic (u[2])) && (!is_wildcard (u[2], 1)))
      s2= "{" * s2 * "}";
#ifdef WINPATHS
		if (((is_root (u[1],"default") && type == URL_SYSTEM) || is_root (u[1],"file"))) { // have to return the windows format
			string root,remain;
			if (is_concat (u[2])) {		
				root = as_string (u[2][1], type);   // root might be unit letter or hostname. It depends on the length
				remain = as_string (u[2][2], type);
			} else {
				root = s2;
				remain = "";
			}
			if (is_root (u[1],"default")) {
				if (N(root) == 1) return root * ":\\" * remain;	//drive letter
				else return "\\\\" * root * "\\" * remain;
			} else {
				if (N(root) == 1) return s1 * "/" * root * ":/" * remain;	//local file
				else return s1 * root * "/" * remain; //remote
			}
		} 
#endif
    return s1 * sep * s2;
  }
  if (is_or (u)) {
    string s1= as_string (u[1], type);
    string s2= as_string (u[2], type);
    if (!is_name_in_path (u[1])) s1= "{" * s1 * "}";
    if ((!is_or (u[2])) && (!is_name_in_path (u[2]))) s2= "{" * s2 * "}";
#ifdef WINPATHS
    if (type == URL_STANDARD) return s1 * ":" * s2;
    else return s1 * string (URL_SEPARATOR) * s2;
#else
    return s1 * string (URL_SEPARATOR) * s2;
#endif
  }
#ifdef WINPATHS
  if (is_root (u, "default")) {
    int stype= type;
    if (is_root (u[1]) && (!is_root (u[1], "default"))) stype= URL_STANDARD;
	if (stype == URL_SYSTEM) return ""; else return "/";
  }
#else
  if (is_root (u, "default")) return "/";
#endif
  if (is_root (u, "blank")) return "/";
  if (is_root (u, "file")) return u[1]->t->label * "://";
  if (is_root (u)) return u[1]->t->label * ":/";
  if (is_wildcard (u, 0)) return "**";
  if (is_wildcard (u, 1)) return u->t[1]->label;
  FAILED ("bad url");
  return "";
}
示例#20
0
文件: loliwm.c 项目: holomorph/loliwm
static bool
is_tiled(struct wlc_view *view)
{
   uint32_t state = wlc_view_get_state(view);
   return !(state & WLC_BIT_FULLSCREEN) && !wlc_view_get_parent(view) && is_managed(view) && !is_or(view) && !is_modal(view);
}
示例#21
0
url
expand (url u) {
  if (is_or (u)) return expand (u[1]) | expand (u[2]);
  if (is_concat (u)) return expand (expand (u[1]), expand (u[2]));
  return u;
}
示例#22
0
object *eval(object *exp, object *env) {

    object *procedure;
    object *arguments;
    object *result;
    bool tailcall = false;

    do {

        if (is_self_evaluating(exp))
            return exp;

        if (is_variable(exp))
            return lookup_variable_value(exp, env);

        if (is_quoted(exp))
            return text_of_quotation(exp);

        if (is_assignment(exp))
            return eval_assignment(exp, env);

        if (is_definition(exp))
            return eval_definition(exp, env);

        if (is_if(exp)) {
            exp = is_true(eval(if_predicate(exp), env)) ? if_consequent(exp) : if_alternative(exp);
            tailcall = true;
            continue;
        }

        if (is_lambda(exp))
            return make_compound_proc(lambda_parameters(exp), lambda_body(exp), env);

        if (is_begin(exp)) {
            exp = begin_actions(exp);
            while (!is_last_exp(exp)) {
                eval(first_exp(exp), env);
                exp = rest_exps(exp);
            }
            exp = first_exp(exp);
            tailcall = true;
            continue;
        }

        if (is_cond(exp)) {
            exp = cond_to_if(exp);
            tailcall = true;
            continue;
        }

        if (is_let(exp)) {
            exp = let_to_application(exp);
            tailcall = true;
            continue;
        }

        if (is_and(exp)) {
            exp = and_tests(exp);
            if (is_empty(exp))
                 return make_boolean(true);
            while (!is_last_exp(exp)) {
                result = eval(first_exp(exp), env);
                if (is_false(result))
                    return result;
                exp = rest_exps(exp);
            }
            exp = first_exp(exp);
            tailcall = true;
            continue;
        }

        if (is_or(exp)) {
            exp = or_tests(exp);
            if (is_empty(exp)) {
                return make_boolean(false);
            }
            while (!is_last_exp(exp)) {
                result = eval(first_exp(exp), env);
                if (is_true(result))
                    return result;
                exp = rest_exps(exp);
            }
            exp = first_exp(exp);
            tailcall = true;
            continue;
        }

        if (is_application(exp)) {

            procedure = eval(operator(exp), env);
            arguments = list_of_values(operands(exp), env);

            if (is_primitive_proc(procedure) && procedure->data.primitive_proc.fn == eval_proc) {
                exp = eval_expression(arguments);
                env = eval_environment(arguments);
                tailcall = true;
                continue;
            }

            if (is_primitive_proc(procedure) && procedure->data.primitive_proc.fn == apply_proc) {
                procedure = apply_operator(arguments);
                arguments = apply_operands(arguments);
            }

            if (is_primitive_proc(procedure))
                return (procedure->data.primitive_proc.fn)(arguments);

            if (is_compound_proc(procedure)) {
                env = extend_environment(procedure->data.compound_proc.parameters, arguments, procedure->data.compound_proc.env);
                exp = make_begin(procedure->data.compound_proc.body);
                tailcall = true;
                continue;
            }

            return make_error(342, "unknown procedure type");
        } // is_application()

    } while (tailcall);

    fprintf(stderr, "cannot eval unknown expression type\n");
    exit(EXIT_FAILURE);
}
示例#23
0
static url
descendance_sub (url u) {
  if (is_or (u))
    return descendance_sub (u[1]) | descendance_sub (u[2]);
  return complete (u, url_wildcard (), "r", false);
}
示例#24
0
url
complete (url base, url u, string filter, bool flag) {
  // cout << "complete " << base << " |||| " << u << LF;
  if (!is_rooted(u)) {
     if (is_none (base)) return base;
     if (is_none (u)) return u;
     if ((!is_root (base)) && (!is_rooted_name (base))) {
        failed_error << "base= " << base << LF;
        FAILED ("invalid base url");
     }
  }
  if (is_name (u) || (is_concat (u) && is_root (u[1]) && is_name (u[2]))) {
    url comp= base * u;
    if (is_rooted (comp, "default") || is_rooted (comp, "file")) {
      if (is_of_type (comp, filter)) return reroot (u, "default");
      return url_none ();
    }
    if (is_rooted_web (comp) || is_rooted_tmfs (comp) || is_ramdisc (comp)) {
      if (is_of_type (comp, filter)) return u;
      return url_none ();
    }
    failed_error << "base= " << base << LF;
    failed_error << "u= " << u << LF;
    ASSERT (is_rooted (comp), "unrooted url");
    FAILED ("bad protocol in url");
  }
  if (is_root (u)) {
    // FIXME: test filter flags here
    return u;
  }
  if (is_concat (u) && is_wildcard (u[1], 0) && is_wildcard (u[2], 1)) {
    // FIXME: ret= ret | ... is unefficient (quadratic) in main loop
    if (!(is_rooted (base, "default") || is_rooted (base, "file"))) {
      failed_error << "base= " << base << LF;
      FAILED ("wildcards only implemented for files");
    }
    url ret= url_none ();
    bool error_flag;
    array<string> dir= read_directory (base, error_flag);
    int i, n= N(dir);
    for (i=0; i<n; i++) {
      if ((!is_none (ret)) && flag) return ret;
      if ((dir[i] == ".") || (dir[i] == "..")) continue;
      if (starts (dir[i], "http://") || starts (dir[i], "ftp://"))
        if (is_directory (base * dir[i])) continue;
      ret= ret | (dir[i] * complete (base * dir[i], u, filter, flag));
      if (match_wildcard (dir[i], u[2][1]->t->label))
	ret= ret | complete (base, dir[i], filter, flag);
    }
    return ret;
  }
  if (is_concat (u)) {
    url sub= complete (base, u[1], "", false);
    // "" should often be faster than the more correct "d" here
    return complete (base, sub, u[2], filter, flag);
  }
  if (is_or (u)) {
    url res1= complete (base, u[1], filter, flag);
    if ((!is_none (res1)) && flag) return res1;
    return res1 | complete (base, u[2], filter, flag);
  }
  if (is_wildcard (u)) {
    // FIXME: ret= ret | ... is unefficient (quadratic) in main loop
    if (!(is_rooted (base, "default") || is_rooted (base, "file"))) {
      failed_error << "base= " << base << LF;
      FAILED ("wildcards only implemented for files");
    }
    url ret= url_none ();
    if (is_wildcard (u, 0) && is_of_type (base, filter)) ret= url_here ();
    bool error_flag;
    array<string> dir= read_directory (base, error_flag);
    int i, n= N(dir);
    for (i=0; i<n; i++) {
      if ((!is_none (ret)) && flag) return ret;
      if ((dir[i] == ".") || (dir[i] == "..")) continue;
      if (starts (dir[i], "http://") || starts (dir[i], "ftp://"))
        if (is_directory (base * dir[i])) continue;
      if (is_wildcard (u, 0))
	ret= ret | (dir[i] * complete (base * dir[i], u, filter, flag));
      else if (match_wildcard (dir[i], u[1]->t->label))
	ret= ret | complete (base, dir[i], filter, flag);
    }
    return ret;
  }
  failed_error << "url= " << u << LF;
  FAILED ("bad url");
  return u;
}
示例#25
0
static url
factor_sub (url u) {
  if (is_concat (u)) return u[1] * factor (u[2]);
  if (is_or (u)) return factor_sub (u[1]) | factor_sub (u[2]);
  return u;
}
示例#26
0
url
sort (url u) {
  if (is_or (u))
    return sort_sub (u[1], sort (u[2]));
  else return u;
}
示例#27
0
文件: eval.c 项目: lienhua34/CSchemer
///////////////////////////////////////////////////////////////////
//eval
//requires two arguments:exp & tail_context
///////////////////////////////////////////////////////////////////
cellpoint eval(void)
{
	if (is_true(is_self_evaluating(args_ref(1)))){
		reg = args_ref(1);
	}else if (is_true(is_variable(args_ref(1)))){
		reg = args_ref(1);
		args_push(current_env);
		args_push(reg);
		reg = lookup_var_val();
	}else if (is_true(is_quoted(args_ref(1)))){
		args_push(args_ref(1));
		reg = quotation_text();
	}else if (is_true(is_assignment(args_ref(1)))){
		args_push(args_ref(1));
		reg = eval_assignment();
	}else if (is_true(is_definition(args_ref(1)))){
		args_push(args_ref(1));
		reg = eval_definition();
	}else if (is_true(is_if(args_ref(1)))){
		//eval if expression with the second argument (tail_context)
		reg = args_ref(1);
		args_push(args_ref(2));
		args_push(reg);
		reg = eval_if();
	}else if (is_true(is_lambda(args_ref(1)))){
		args_push(args_ref(1));
		reg = eval_lambda();
	}else if (is_true(is_begin(args_ref(1)))){
		args_push(args_ref(1));
		reg = begin_actions();
		//eval the actions of begin exp with the second argument (tail_context)
		args_push(args_ref(2));
		args_push(reg);
		reg = eval_sequence();
	}else if (is_true(is_cond(args_ref(1)))){
		args_push(args_ref(1));
		reg = cond_2_if();
		//eval the exp with the second argument (tail_context)
		args_push(args_ref(2));
		args_push(reg);
		reg = eval();
	}else if (is_true(is_and(args_ref(1)))){
		reg = args_ref(1);
		args_push(args_ref(2));
		args_push(reg);
		reg = eval_and();
	}else if (is_true(is_or(args_ref(1)))){
		reg = args_ref(1);
		args_push(args_ref(2));
		args_push(reg);
		reg = eval_or();
	}else if (is_true(is_let(args_ref(1)))){
		//convert let to combination
		args_push(args_ref(1));
		reg = let_2_combination();
		//evals the combination
		args_push(args_ref(2));
		args_push(reg);
		reg = eval();
	}else if (is_true(is_letstar(args_ref(1)))){
		//convert let* to nested lets
		args_push(args_ref(1));
		reg = letstar_2_nested_lets();
		//evals the nested lets
		args_push(args_ref(2));
		args_push(reg);
		reg = eval();
	}else if (is_true(is_application(args_ref(1)))){
		//computes operator
		args_push(args_ref(1));
		reg = operator();
		args_push(a_false);
		args_push(reg);
		reg = eval();
		stack_push(&vars_stack, reg);
		//computes operands
		args_push(args_ref(1));
		reg = operands();
		args_push(reg);
		reg = list_of_values();
		//calls apply with the second argument (tail_context)
		args_push(args_ref(2));
		args_push(reg);
		args_push(stack_pop(&vars_stack));
		reg = apply();
	}else {
		printf("Unknown expression type -- EVAL\n");
		error_handler();
	}
	args_pop(2);
	return reg;
}