jl_value_t *jl_toplevel_eval_flex(jl_value_t *e, int fast, int *plineno) { //jl_show(ex); //JL_PRINTF(JL_STDOUT, "\n"); if (!jl_is_expr(e)) return jl_interpret_toplevel_expr(e); jl_expr_t *ex = (jl_expr_t*)e; if (ex->head == null_sym || ex->head == error_sym) { // expression types simple enough not to need expansion return jl_interpret_toplevel_expr(e); } if (ex->head == module_sym) { return jl_eval_module_expr(ex, plineno); } // handle import, export toplevel-only forms if (ex->head == importall_sym) { jl_module_t *m = eval_import_path(ex->args); jl_sym_t *name = (jl_sym_t*)jl_cellref(ex->args, ex->args->length-1); assert(jl_is_symbol(name)); m = (jl_module_t*)jl_eval_global_var(m, name); if (!jl_is_module(m)) jl_errorf("invalid import statement"); jl_module_importall(jl_current_module, m); return jl_nothing; } if (ex->head == import_sym) { jl_module_t *m = eval_import_path(ex->args); jl_sym_t *name = (jl_sym_t*)jl_cellref(ex->args, ex->args->length-1); assert(jl_is_symbol(name)); jl_module_import(jl_current_module, m, name); return jl_nothing; } if (ex->head == export_sym) { for(size_t i=0; i < ex->args->length; i++) { jl_module_export(jl_current_module, (jl_sym_t*)jl_cellref(ex->args, i)); } return jl_nothing; } jl_value_t *thunk=NULL; jl_value_t *result; jl_lambda_info_t *thk=NULL; int ewc = 0; JL_GC_PUSH(&thunk, &thk, &ex); if (ex->head != body_sym && ex->head != thunk_sym) { // not yet expanded ex = (jl_expr_t*)jl_expand(e); } if (jl_is_expr(ex) && ex->head == thunk_sym) { thk = (jl_lambda_info_t*)jl_exprarg(ex,0); assert(jl_is_lambda_info(thk)); ewc = jl_eval_with_compiler_p(jl_lam_body((jl_expr_t*)thk->ast), fast); if (!ewc) { jl_array_t *vinfos = jl_lam_vinfo((jl_expr_t*)thk->ast); int i; for(i=0; i < vinfos->length; i++) { if (jl_vinfo_capt((jl_array_t*)jl_cellref(vinfos,i))) { // interpreter doesn't handle closure environment ewc = 1; break; } } } } else { if (jl_is_expr(ex) && jl_eval_with_compiler_p((jl_expr_t*)ex, fast)) { thk = jl_wrap_expr((jl_value_t*)ex); ewc = 1; } else { result = jl_interpret_toplevel_expr((jl_value_t*)ex); JL_GC_POP(); return result; } } if (ewc) { thunk = (jl_value_t*)jl_new_closure(NULL, (jl_value_t*)jl_null, thk); if (!jl_in_inference) { jl_type_infer(thk, jl_tuple_type, thk); } result = jl_apply((jl_function_t*)thunk, NULL, 0); } else { result = jl_interpret_toplevel_thunk(thk); } JL_GC_POP(); return result; }
static jl_value_t *eval(jl_value_t *e, jl_value_t **locals, size_t nl) { if (jl_is_symbol(e)) { jl_value_t *v; size_t i; for(i=0; i < nl; i++) { if (locals[i*2] == e) { v = locals[i*2+1]; break; } } if (i >= nl) { v = jl_get_global(jl_current_module, (jl_sym_t*)e); } if (v == NULL) { jl_errorf("%s not defined", ((jl_sym_t*)e)->name); } return v; } if (jl_is_symbolnode(e)) { return eval((jl_value_t*)jl_symbolnode_sym(e), locals, nl); } if (jl_is_quotenode(e)) { return jl_fieldref(e,0); } if (jl_is_topnode(e)) { jl_sym_t *s = (jl_sym_t*)jl_fieldref(e,0); jl_value_t *v = jl_get_global(jl_base_relative_to(jl_current_module),s); if (v == NULL) jl_errorf("%s not defined", s->name); return v; } if (!jl_is_expr(e)) { if (jl_is_getfieldnode(e)) { jl_value_t *v = eval(jl_getfieldnode_val(e), locals, nl); jl_value_t *gfargs[2] = {v, (jl_value_t*)jl_getfieldnode_name(e)}; return jl_f_get_field(NULL, gfargs, 2); } if (jl_is_lambda_info(e)) { return (jl_value_t*)jl_new_closure(NULL, (jl_value_t*)jl_null, (jl_lambda_info_t*)e); } if (jl_is_linenode(e)) { jl_lineno = jl_linenode_line(e); } return e; } jl_expr_t *ex = (jl_expr_t*)e; jl_value_t **args = &jl_cellref(ex->args,0); size_t nargs = jl_array_len(ex->args); if (ex->head == call_sym || ex->head == call1_sym) { jl_function_t *f = (jl_function_t*)eval(args[0], locals, nl); if (!jl_is_func(f)) jl_type_error("apply", (jl_value_t*)jl_function_type, (jl_value_t*)f); return do_call(f, &args[1], nargs-1, locals, nl); } else if (ex->head == assign_sym) { jl_value_t *sym = args[0]; size_t i; for (i=0; i < nl; i++) { if (locals[i*2] == sym) { return (locals[i*2+1] = eval(args[1], locals, nl)); } } jl_binding_t *b = jl_get_binding_wr(jl_current_module, (jl_sym_t*)sym); jl_value_t *rhs = eval(args[1], locals, nl); jl_checked_assignment(b, rhs); return rhs; } else if (ex->head == new_sym) { jl_value_t *thetype = eval(args[0], locals, nl); jl_value_t *v=NULL; JL_GC_PUSH(&thetype, &v); assert(jl_is_structtype(thetype)); v = jl_new_struct_uninit((jl_datatype_t*)thetype); for(size_t i=1; i < nargs; i++) { jl_set_nth_field(v, i-1, eval(args[i], locals, nl)); } JL_GC_POP(); return v; } else if (ex->head == null_sym) { return (jl_value_t*)jl_nothing; } else if (ex->head == body_sym) { return eval_body(ex->args, locals, nl, 0); } else if (ex->head == exc_sym) { return jl_exception_in_transit; } else if (ex->head == static_typeof_sym) { return (jl_value_t*)jl_any_type; } else if (ex->head == method_sym) { jl_sym_t *fname = (jl_sym_t*)args[0]; jl_value_t **bp=NULL; jl_binding_t *b=NULL; jl_value_t *gf=NULL; int kw=0; if (jl_is_expr(fname)) { if (((jl_expr_t*)fname)->head == kw_sym) { kw = 1; fname = (jl_sym_t*)jl_exprarg(fname, 0); } gf = eval((jl_value_t*)fname, locals, nl); assert(jl_is_function(gf)); assert(jl_is_gf(gf)); if (!kw) { fname = (jl_sym_t*)jl_fieldref(jl_exprarg(fname, 2), 0); bp = &gf; } else { bp = (jl_value_t**)&((jl_methtable_t*)((jl_function_t*)gf)->env)->kwsorter; } assert(jl_is_symbol(fname)); } else { for (size_t i=0; i < nl; i++) { if (locals[i*2] == (jl_value_t*)fname) { bp = &locals[i*2+1]; break; } } if (bp == NULL) { b = jl_get_binding_for_method_def(jl_current_module, fname); bp = &b->value; } } jl_value_t *atypes=NULL, *meth=NULL, *tvars=NULL; JL_GC_PUSH(&atypes, &meth, &tvars); atypes = eval(args[1], locals, nl); meth = eval(args[2], locals, nl); tvars = eval(args[3], locals, nl); jl_method_def(fname, bp, b, (jl_tuple_t*)atypes, (jl_function_t*)meth, (jl_tuple_t*)tvars); JL_GC_POP(); return *bp; } else if (ex->head == const_sym) { jl_value_t *sym = args[0]; for (size_t i=0; i < nl; i++) { if (locals[i*2] == sym) { return (jl_value_t*)jl_nothing; } } jl_binding_t *b = jl_get_binding_wr(jl_current_module, (jl_sym_t*)sym); jl_declare_constant(b); return (jl_value_t*)jl_nothing; } else if (ex->head == global_sym) { // create uninitialized mutable binding for "global x" decl // TODO: handle type decls for (size_t i=0; i < jl_array_len(ex->args); i++) { assert(jl_is_symbol(args[i])); jl_get_binding_wr(jl_current_module, (jl_sym_t*)args[i]); } return (jl_value_t*)jl_nothing; } else if (ex->head == abstracttype_sym) { jl_value_t *name = args[0]; jl_value_t *para = eval(args[1], locals, nl); jl_value_t *super = NULL; JL_GC_PUSH(¶, &super); jl_datatype_t *dt = jl_new_abstracttype(name, jl_any_type, (jl_tuple_t*)para); jl_binding_t *b = jl_get_binding_wr(jl_current_module, (jl_sym_t*)name); jl_checked_assignment(b, (jl_value_t*)dt); super = eval(args[2], locals, nl); jl_set_datatype_super(dt, super); JL_GC_POP(); return (jl_value_t*)jl_nothing; } else if (ex->head == bitstype_sym) { jl_value_t *name = args[0]; jl_value_t *super = NULL, *para = NULL, *vnb = NULL; JL_GC_PUSH(¶, &super, &vnb); para = eval(args[1], locals, nl); vnb = eval(args[2], locals, nl); if (!jl_is_long(vnb)) jl_errorf("invalid declaration of bits type %s", ((jl_sym_t*)name)->name); int32_t nb = jl_unbox_long(vnb); if (nb < 1 || nb>=(1<<23) || (nb&7) != 0) jl_errorf("invalid number of bits in type %s", ((jl_sym_t*)name)->name); jl_datatype_t *dt = jl_new_bitstype(name, jl_any_type, (jl_tuple_t*)para, nb); jl_binding_t *b = jl_get_binding_wr(jl_current_module, (jl_sym_t*)name); jl_checked_assignment(b, (jl_value_t*)dt); super = eval(args[3], locals, nl); jl_set_datatype_super(dt, super); JL_GC_POP(); return (jl_value_t*)jl_nothing; } else if (ex->head == compositetype_sym) { void jl_add_constructors(jl_datatype_t *t); jl_value_t *name = args[0]; jl_value_t *para = eval(args[1], locals, nl); jl_value_t *fnames = NULL; jl_value_t *super = NULL; jl_datatype_t *dt = NULL; JL_GC_PUSH(¶, &super, &fnames, &dt); fnames = eval(args[2], locals, nl); dt = jl_new_datatype((jl_sym_t*)name, jl_any_type, (jl_tuple_t*)para, (jl_tuple_t*)fnames, NULL, 0, args[6]==jl_true ? 1 : 0); dt->fptr = jl_f_ctor_trampoline; dt->ctor_factory = eval(args[3], locals, nl); jl_binding_t *b = jl_get_binding_wr(jl_current_module, (jl_sym_t*)name); jl_checked_assignment(b, (jl_value_t*)dt); inside_typedef = 1; dt->types = (jl_tuple_t*)eval(args[5], locals, nl); inside_typedef = 0; jl_check_type_tuple(dt->types, dt->name->name, "type definition"); super = eval(args[4], locals, nl); jl_set_datatype_super(dt, super); jl_compute_field_offsets(dt); jl_add_constructors(dt); JL_GC_POP(); return (jl_value_t*)jl_nothing; } else if (ex->head == macro_sym) { jl_sym_t *nm = (jl_sym_t*)args[0]; assert(jl_is_symbol(nm)); jl_function_t *f = (jl_function_t*)eval(args[1], locals, nl); assert(jl_is_function(f)); if (jl_boot_file_loaded && f->linfo && f->linfo->ast && jl_is_expr(f->linfo->ast)) { jl_lambda_info_t *li = f->linfo; li->ast = jl_compress_ast(li, li->ast); li->name = nm; } jl_set_global(jl_current_module, nm, (jl_value_t*)f); return (jl_value_t*)jl_nothing; } else if (ex->head == line_sym) { jl_lineno = jl_unbox_long(jl_exprarg(ex,0)); return (jl_value_t*)jl_nothing; } else if (ex->head == module_sym) { return jl_eval_module_expr(ex); } else if (ex->head == error_sym || ex->head == jl_continue_sym) { if (jl_is_byte_string(args[0])) jl_errorf("syntax: %s", jl_string_data(args[0])); jl_throw(args[0]); } jl_errorf("unsupported or misplaced expression %s", ex->head->name); return (jl_value_t*)jl_nothing; }
jl_value_t *jl_toplevel_eval_flex(jl_value_t *e, int fast, volatile size_t *plineno) { //jl_show(ex); //ios_printf(ios_stdout, "\n"); if (!jl_is_expr(e)) return jl_interpret_toplevel_expr(e); jl_expr_t *ex = (jl_expr_t*)e; if (ex->head == null_sym || ex->head == error_sym) { // expression types simple enough not to need expansion return jl_interpret_toplevel_expr(e); } if (ex->head == module_sym) { return jl_eval_module_expr(ex, plineno); } jl_value_t *thunk=NULL; jl_value_t *result; jl_lambda_info_t *thk=NULL; int ewc = 0; JL_GC_PUSH(&thunk, &thk, &ex); if (ex->head == body_sym || ex->head == thunk_sym) { // already expanded } else { ex = (jl_expr_t*)jl_expand(e); } if (jl_is_expr(ex) && ex->head == thunk_sym) { thk = (jl_lambda_info_t*)jl_exprarg(ex,0); assert(jl_is_lambda_info(thk)); ewc = eval_with_compiler_p(jl_lam_body((jl_expr_t*)thk->ast), fast); if (!ewc) { jl_array_t *vinfos = jl_lam_vinfo((jl_expr_t*)thk->ast); int i; for(i=0; i < vinfos->length; i++) { if (jl_vinfo_capt((jl_array_t*)jl_cellref(vinfos,i))) { // interpreter doesn't handle closure environment ewc = 1; break; } } } } else { if (jl_is_expr(ex) && eval_with_compiler_p((jl_expr_t*)ex, fast)) { thk = jl_wrap_expr((jl_value_t*)ex); ewc = 1; } else { result = jl_interpret_toplevel_expr((jl_value_t*)ex); JL_GC_POP(); return result; } } if (ewc) { thunk = jl_new_closure_internal(thk, (jl_value_t*)jl_null); if (fast && !jl_in_inference) { jl_type_infer(thk, jl_tuple_type, thk); } result = jl_apply((jl_function_t*)thunk, NULL, 0); } else { result = jl_interpret_toplevel_thunk(thk); } JL_GC_POP(); return result; }
jl_value_t *jl_toplevel_eval_flex(jl_value_t *e, int fast) { //jl_show(ex); //jl_printf(JL_STDOUT, "\n"); if (!jl_is_expr(e)) return jl_interpret_toplevel_expr(e); jl_expr_t *ex = (jl_expr_t*)e; if (ex->head == null_sym || ex->head == error_sym) { // expression types simple enough not to need expansion return jl_interpret_toplevel_expr(e); } if (ex->head == module_sym) { return jl_eval_module_expr(ex); } // handle import, using, importall, export toplevel-only forms if (ex->head == importall_sym) { jl_module_t *m = eval_import_path(ex->args); if (m==NULL) return jl_nothing; jl_sym_t *name = (jl_sym_t*)jl_cellref(ex->args, jl_array_len(ex->args)-1); if (!jl_is_symbol(name)) jl_error("syntax: malformed \"importall\" statement"); m = (jl_module_t*)jl_eval_global_var(m, name); if (!jl_is_module(m)) jl_errorf("invalid %s statement: name exists but does not refer to a module", ex->head->name); jl_module_importall(jl_current_module, m); return jl_nothing; } if (ex->head == using_sym) { jl_module_t *m = eval_import_path(ex->args); if (m==NULL) return jl_nothing; jl_sym_t *name = (jl_sym_t*)jl_cellref(ex->args, jl_array_len(ex->args)-1); if (!jl_is_symbol(name)) jl_error("syntax: malformed \"using\" statement"); jl_module_t *u = (jl_module_t*)jl_eval_global_var(m, name); if (jl_is_module(u)) { jl_module_using(jl_current_module, u); } else { jl_module_use(jl_current_module, m, name); } return jl_nothing; } if (ex->head == import_sym) { jl_module_t *m = eval_import_path(ex->args); if (m==NULL) return jl_nothing; jl_sym_t *name = (jl_sym_t*)jl_cellref(ex->args, jl_array_len(ex->args)-1); if (!jl_is_symbol(name)) jl_error("syntax: malformed \"import\" statement"); jl_module_import(jl_current_module, m, name); return jl_nothing; } if (ex->head == export_sym) { for(size_t i=0; i < jl_array_len(ex->args); i++) { jl_sym_t *name = (jl_sym_t*)jl_cellref(ex->args, i); if (!jl_is_symbol(name)) jl_error("syntax: malformed \"export\" statement"); jl_module_export(jl_current_module, name); } return jl_nothing; } if (ex->head == toplevel_sym) { int i=0; jl_value_t *res=jl_nothing; for(i=0; i < jl_array_len(ex->args); i++) { res = jl_toplevel_eval_flex(jl_cellref(ex->args, i), fast); } return res; } jl_value_t *thunk=NULL; jl_value_t *result; jl_lambda_info_t *thk=NULL; int ewc = 0; JL_GC_PUSH3(&thunk, &thk, &ex); if (ex->head != body_sym && ex->head != thunk_sym && ex->head != return_sym && ex->head != method_sym) { // not yet expanded ex = (jl_expr_t*)jl_expand(e); } jl_sym_t *head = jl_is_expr(ex) ? ex->head : NULL; if (head == toplevel_sym) { int i=0; jl_value_t *res=jl_nothing; for(i=0; i < jl_array_len(ex->args); i++) { res = jl_toplevel_eval_flex(jl_cellref(ex->args, i), fast); } JL_GC_POP(); return res; } if (head == thunk_sym) { thk = (jl_lambda_info_t*)jl_exprarg(ex,0); assert(jl_is_lambda_info(thk)); assert(jl_is_expr(thk->ast)); ewc = jl_eval_with_compiler_p((jl_expr_t*)thk->ast, jl_lam_body((jl_expr_t*)thk->ast), fast, jl_current_module); if (!ewc) { if (jl_lam_vars_captured((jl_expr_t*)thk->ast)) { // interpreter doesn't handle closure environment ewc = 1; } } } else { if (head && jl_eval_with_compiler_p(NULL, (jl_expr_t*)ex, fast, jl_current_module)) { thk = jl_wrap_expr((jl_value_t*)ex); ewc = 1; } else { if (head == body_sym) { result = jl_toplevel_eval_body(ex->args); } else if (jl_is_toplevel_only_expr((jl_value_t*)ex)) { result = jl_toplevel_eval((jl_value_t*)ex); } else { result = jl_interpret_toplevel_expr((jl_value_t*)ex); } JL_GC_POP(); return result; } } if (ewc) { thunk = (jl_value_t*)jl_new_closure(NULL, (jl_value_t*)jl_emptysvec, thk); if (!jl_in_inference) { jl_type_infer(thk, (jl_tupletype_t*)jl_typeof(jl_emptytuple), thk); } result = jl_apply((jl_function_t*)thunk, NULL, 0); } else { result = jl_interpret_toplevel_thunk(thk); } JL_GC_POP(); return result; }