JL_DLLEXPORT void jl_add_standard_imports(jl_module_t *m) { jl_module_t *base_module = jl_base_relative_to(m); assert(base_module != NULL); // using Base jl_module_using(m, base_module); }
static void jl_uv_call_close_callback(jl_value_t *val) { jl_value_t *args[2]; args[0] = jl_get_global(jl_base_relative_to(((jl_datatype_t*)jl_typeof(val))->name->module), jl_symbol("_uv_hook_close")); // topmod(typeof(val))._uv_hook_close args[1] = val; assert(args[0]); jl_apply(args, 2); }
static void jl_uv_call_close_callback(void *val) { jl_value_t *cb; if (!jl_old_base_module) { if (close_cb == NULL) close_cb = jl_get_global(jl_base_module, jl_symbol("_uv_hook_close")); cb = close_cb; } else { cb = jl_get_global(jl_base_relative_to(((jl_datatype_t*)jl_typeof(val))->name->module), jl_symbol("_uv_hook_close")); } assert(cb && jl_is_function(cb)); jl_apply((jl_function_t*)cb, (jl_value_t**)&val, 1); }
static void jl_uv_call_close_callback(jl_value_t *val) { jl_value_t *cb; if (!jl_old_base_module) { if (close_cb == NULL) close_cb = jl_get_global(jl_base_module, jl_symbol("_uv_hook_close")); cb = close_cb; } else { cb = jl_get_global(jl_base_relative_to(((jl_datatype_t*)jl_typeof(val))->name->module), jl_symbol("_uv_hook_close")); } assert(cb); jl_value_t *args[2] = {cb,val}; jl_apply(args, 2); }
jl_value_t *jl_eval_dot_expr(jl_module_t *m, jl_value_t *x, jl_value_t *f, int fast) { jl_value_t **args; JL_GC_PUSHARGS(args, 3); args[1] = jl_toplevel_eval_flex(m, x, fast, 0); args[2] = jl_toplevel_eval_flex(m, f, fast, 0); if (jl_is_module(args[1])) { JL_TYPECHK("getfield", symbol, args[2]); args[0] = jl_eval_global_var((jl_module_t*)args[1], (jl_sym_t*)args[2]); } else { args[0] = jl_eval_global_var(jl_base_relative_to(m), jl_symbol("getproperty")); args[0] = jl_apply(args, 3); } JL_GC_POP(); return args[0]; }
static int has_intrinsics(jl_expr_t *e) { if (e->args->length == 0) return 0; if (e->head == static_typeof_sym) return 1; jl_value_t *e0 = jl_exprarg(e,0); if (e->head == call_sym && ((jl_is_symbol(e0) && is_intrinsic(jl_current_module,(jl_sym_t*)e0)) || (jl_is_topnode(e0) && is_intrinsic(jl_base_relative_to(jl_current_module),(jl_sym_t*)jl_fieldref(e0,0))))) return 1; int i; for(i=0; i < e->args->length; i++) { jl_value_t *a = jl_exprarg(e,i); if (jl_is_expr(a) && has_intrinsics((jl_expr_t*)a)) return 1; } return 0; }
int jl_has_intrinsics(jl_expr_t *e, jl_module_t *m) { if (jl_array_len(e->args) == 0) return 0; if (e->head == static_typeof_sym) return 1; jl_value_t *e0 = jl_exprarg(e,0); if (e->head == call_sym && ((jl_is_symbol(e0) && is_intrinsic(m,(jl_sym_t*)e0)) || (jl_is_topnode(e0) && is_intrinsic(jl_base_relative_to(m),(jl_sym_t*)jl_fieldref(e0,0))))) return 1; int i; for(i=0; i < jl_array_len(e->args); i++) { jl_value_t *a = jl_exprarg(e,i); if (jl_is_expr(a) && jl_has_intrinsics((jl_expr_t*)a, m)) return 1; } return 0; }
static jl_value_t *eval(jl_value_t *e, jl_value_t **locals, size_t nl, size_t ngensym) { 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_undefined_var_error((jl_sym_t*)e); } return v; } if (jl_is_symbolnode(e)) { return eval((jl_value_t*)jl_symbolnode_sym(e), locals, nl, ngensym); } if (jl_is_gensym(e)) { ssize_t genid = ((jl_gensym_t*)e)->id; if (genid >= ngensym || genid < 0) jl_error("access to invalid GenSym location"); else return locals[nl*2 + genid]; } 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_undefined_var_error(s); return v; } if (!jl_is_expr(e)) { if (jl_is_globalref(e)) { jl_value_t *gfargs[2] = {(jl_value_t*)jl_globalref_mod(e), (jl_value_t*)jl_globalref_name(e)}; return jl_f_get_field(NULL, gfargs, 2); } if (jl_is_lambda_info(e)) { jl_lambda_info_t *li = (jl_lambda_info_t*)e; if (jl_boot_file_loaded && li->ast && jl_is_expr(li->ast)) { li->ast = jl_compress_ast(li, li->ast); jl_gc_wb(li, li->ast); } return (jl_value_t*)jl_new_closure(NULL, (jl_value_t*)jl_emptysvec, li); } if (jl_is_linenode(e)) { jl_lineno = jl_linenode_line(e); } if (jl_is_newvarnode(e)) { jl_value_t *var = jl_fieldref(e,0); assert(!jl_is_gensym(var)); assert(jl_is_symbol(var)); for(size_t i=0; i < nl; i++) { if (locals[i*2] == var) { locals[i*2+1] = NULL; break; } } return (jl_value_t*)jl_nothing; } return e; } jl_expr_t *ex = (jl_expr_t*)e; jl_value_t **args = (jl_value_t**)jl_array_data(ex->args); size_t nargs = jl_array_len(ex->args); if (ex->head == call_sym) { if (jl_is_lambda_info(args[0])) { // directly calling an inner function ("let") jl_lambda_info_t *li = (jl_lambda_info_t*)args[0]; if (jl_is_expr(li->ast) && !jl_lam_vars_captured((jl_expr_t*)li->ast) && !jl_has_intrinsics((jl_expr_t*)li->ast, (jl_expr_t*)li->ast, jl_current_module)) { size_t na = nargs-1; if (na == 0) return jl_interpret_toplevel_thunk(li); jl_array_t *formals = jl_lam_args((jl_expr_t*)li->ast); size_t nreq = jl_array_len(formals); if (nreq==0 || !jl_is_rest_arg(jl_cellref(formals,nreq-1))) { jl_value_t **ar; JL_GC_PUSHARGS(ar, na*2); for(int i=0; i < na; i++) { ar[i*2+1] = eval(args[i+1], locals, nl, ngensym); jl_gc_wb(ex->args, ar[i*2+1]); } if (na != nreq) { jl_error("wrong number of arguments"); } for(int i=0; i < na; i++) { jl_value_t *v = jl_cellref(formals, i); ar[i*2] = (jl_is_gensym(v)) ? v : (jl_value_t*)jl_decl_var(v); } jl_value_t *ret = jl_interpret_toplevel_thunk_with(li, ar, na); JL_GC_POP(); return ret; } } } jl_function_t *f = (jl_function_t*)eval(args[0], locals, nl, ngensym); if (jl_is_func(f)) return do_call(f, &args[1], nargs-1, NULL, locals, nl, ngensym); else return do_call(jl_module_call_func(jl_current_module), args, nargs, (jl_value_t*)f, locals, nl, ngensym); } else if (ex->head == assign_sym) { jl_value_t *sym = args[0]; jl_value_t *rhs = eval(args[1], locals, nl, ngensym); if (jl_is_gensym(sym)) { ssize_t genid = ((jl_gensym_t*)sym)->id; if (genid >= ngensym || genid < 0) jl_error("assignment to invalid GenSym location"); locals[nl*2 + genid] = rhs; return rhs; } if (jl_is_symbol(sym)) { size_t i; for (i=0; i < nl; i++) { if (locals[i*2] == sym) { locals[i*2+1] = rhs; return rhs; } } } jl_module_t *m = jl_current_module; if (jl_is_globalref(sym)) { m = jl_globalref_mod(sym); sym = (jl_value_t*)jl_globalref_name(sym); } assert(jl_is_symbol(sym)); JL_GC_PUSH1(&rhs); jl_binding_t *b = jl_get_binding_wr(m, (jl_sym_t*)sym); jl_checked_assignment(b, rhs); JL_GC_POP(); return rhs; } else if (ex->head == new_sym) { jl_value_t *thetype = eval(args[0], locals, nl, ngensym); jl_value_t *v=NULL; JL_GC_PUSH2(&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, ngensym)); } 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, ngensym, 0, 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_value_t *bp_owner=NULL; jl_binding_t *b=NULL; jl_value_t *gf=NULL; int kw=0; if (jl_is_expr(fname) || jl_is_globalref(fname)) { if (jl_is_expr(fname) && ((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, ngensym); if (jl_is_expr(fname)) fname = (jl_sym_t*)jl_fieldref(jl_exprarg(fname, 2), 0); bp = &gf; 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; bp_owner = (jl_value_t*)jl_current_module; } } if (jl_expr_nargs(ex) == 1) return jl_generic_function_def(fname, bp, bp_owner, b); jl_value_t *atypes=NULL, *meth=NULL; JL_GC_PUSH2(&atypes, &meth); atypes = eval(args[1], locals, nl, ngensym); if (jl_is_lambda_info(args[2])) { jl_check_static_parameter_conflicts((jl_lambda_info_t*)args[2], (jl_svec_t*)jl_svecref(atypes,1), fname); } meth = eval(args[2], locals, nl, ngensym); jl_method_def(fname, bp, bp_owner, b, (jl_svec_t*)atypes, (jl_function_t*)meth, args[3], NULL, kw); JL_GC_POP(); return *bp; } else if (ex->head == copyast_sym) { return jl_copy_ast(eval(args[0], locals, nl, ngensym)); } else if (ex->head == const_sym) { jl_value_t *sym = args[0]; assert(jl_is_symbol(sym)); 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, ngensym); jl_value_t *super = NULL; jl_value_t *temp = NULL; jl_datatype_t *dt = NULL; JL_GC_PUSH4(¶, &super, &temp, &dt); assert(jl_is_svec(para)); assert(jl_is_symbol(name)); dt = jl_new_abstracttype(name, jl_any_type, (jl_svec_t*)para); jl_binding_t *b = jl_get_binding_wr(jl_current_module, (jl_sym_t*)name); temp = b->value; check_can_assign_type(b); b->value = (jl_value_t*)dt; jl_gc_wb_binding(b, dt); super = eval(args[2], locals, nl, ngensym); jl_set_datatype_super(dt, super); b->value = temp; if (temp==NULL || !equiv_type(dt, (jl_datatype_t*)temp)) { jl_checked_assignment(b, (jl_value_t*)dt); } 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, *temp = NULL; jl_datatype_t *dt = NULL; JL_GC_PUSH4(¶, &super, &temp, &dt); assert(jl_is_symbol(name)); para = eval(args[1], locals, nl, ngensym); assert(jl_is_svec(para)); vnb = eval(args[2], locals, nl, ngensym); if (!jl_is_long(vnb)) jl_errorf("invalid declaration of bits type %s", ((jl_sym_t*)name)->name); ssize_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); dt = jl_new_bitstype(name, jl_any_type, (jl_svec_t*)para, nb); jl_binding_t *b = jl_get_binding_wr(jl_current_module, (jl_sym_t*)name); temp = b->value; check_can_assign_type(b); b->value = (jl_value_t*)dt; jl_gc_wb_binding(b, dt); super = eval(args[3], locals, nl, ngensym); jl_set_datatype_super(dt, super); b->value = temp; if (temp==NULL || !equiv_type(dt, (jl_datatype_t*)temp)) { jl_checked_assignment(b, (jl_value_t*)dt); } JL_GC_POP(); return (jl_value_t*)jl_nothing; } else if (ex->head == compositetype_sym) { jl_value_t *name = args[0]; assert(jl_is_symbol(name)); jl_value_t *para = eval(args[1], locals, nl, ngensym); assert(jl_is_svec(para)); jl_value_t *temp = NULL; jl_value_t *super = NULL; jl_datatype_t *dt = NULL; JL_GC_PUSH4(¶, &super, &temp, &dt); temp = eval(args[2], locals, nl, ngensym); // field names dt = jl_new_datatype((jl_sym_t*)name, jl_any_type, (jl_svec_t*)para, (jl_svec_t*)temp, NULL, 0, args[5]==jl_true ? 1 : 0, jl_unbox_long(args[6])); jl_binding_t *b = jl_get_binding_wr(jl_current_module, (jl_sym_t*)name); temp = b->value; // save old value // temporarily assign so binding is available for field types check_can_assign_type(b); b->value = (jl_value_t*)dt; jl_gc_wb_binding(b,dt); JL_TRY { // operations that can fail inside_typedef = 1; dt->types = (jl_svec_t*)eval(args[4], locals, nl, ngensym); jl_gc_wb(dt, dt->types); inside_typedef = 0; for(size_t i=0; i < jl_svec_len(dt->types); i++) { jl_value_t *elt = jl_svecref(dt->types, i); if (!jl_is_type(elt) && !jl_is_typevar(elt)) jl_type_error_rt(dt->name->name->name, "type definition", (jl_value_t*)jl_type_type, elt); } super = eval(args[3], locals, nl, ngensym); jl_set_datatype_super(dt, super); } JL_CATCH { b->value = temp; jl_rethrow(); } for(size_t i=0; i < jl_svec_len(para); i++) { ((jl_tvar_t*)jl_svecref(para,i))->bound = 0; } jl_compute_field_offsets(dt); if (para == (jl_value_t*)jl_emptysvec && jl_is_datatype_singleton(dt)) { dt->instance = newstruct(dt); jl_gc_wb(dt, dt->instance); } b->value = temp; if (temp==NULL || !equiv_type(dt, (jl_datatype_t*)temp)) { jl_checked_assignment(b, (jl_value_t*)dt); } else { // TODO: remove all old ctors and set temp->name->ctor_factory = dt->name->ctor_factory } JL_GC_POP(); return (jl_value_t*)jl_nothing; }
static jl_value_t *scm_to_julia_(fl_context_t *fl_ctx, value_t e, jl_module_t *mod) { if (fl_isnumber(fl_ctx, e)) { int64_t i64; if (isfixnum(e)) { i64 = numval(e); } else { assert(iscprim(e)); cprim_t *cp = (cprim_t*)ptr(e); numerictype_t nt = cp_numtype(cp); switch (nt) { case T_DOUBLE: return (jl_value_t*)jl_box_float64(*(double*)cp_data(cp)); case T_FLOAT: return (jl_value_t*)jl_box_float32(*(float*)cp_data(cp)); case T_UINT8: return (jl_value_t*)jl_box_uint8(*(uint8_t*)cp_data(cp)); case T_UINT16: return (jl_value_t*)jl_box_uint16(*(uint16_t*)cp_data(cp)); case T_UINT32: return (jl_value_t*)jl_box_uint32(*(uint32_t*)cp_data(cp)); case T_UINT64: return (jl_value_t*)jl_box_uint64(*(uint64_t*)cp_data(cp)); default: ; } i64 = conv_to_int64(cp_data(cp), nt); } #ifdef _P64 return (jl_value_t*)jl_box_int64(i64); #else if (i64 > (int64_t)S32_MAX || i64 < (int64_t)S32_MIN) return (jl_value_t*)jl_box_int64(i64); else return (jl_value_t*)jl_box_int32((int32_t)i64); #endif } if (issymbol(e)) { if (e == jl_ast_ctx(fl_ctx)->true_sym) return jl_true; else if (e == jl_ast_ctx(fl_ctx)->false_sym) return jl_false; return (jl_value_t*)scmsym_to_julia(fl_ctx, e); } if (fl_isstring(fl_ctx, e)) return jl_pchar_to_string((char*)cvalue_data(e), cvalue_len(e)); if (iscons(e) || e == fl_ctx->NIL) { value_t hd; jl_sym_t *sym; if (e == fl_ctx->NIL) { hd = e; } else { hd = car_(e); if (hd == jl_ast_ctx(fl_ctx)->ssavalue_sym) return jl_box_ssavalue(numval(car_(cdr_(e)))); else if (hd == jl_ast_ctx(fl_ctx)->slot_sym) return jl_box_slotnumber(numval(car_(cdr_(e)))); else if (hd == jl_ast_ctx(fl_ctx)->null_sym && llength(e) == 1) return jl_nothing; } if (issymbol(hd)) sym = scmsym_to_julia(fl_ctx, hd); else sym = list_sym; size_t n = llength(e)-1; if (issymbol(hd)) e = cdr_(e); else n++; // nodes with special representations jl_value_t *ex = NULL, *temp = NULL; if (sym == line_sym && (n == 1 || n == 2)) { jl_value_t *linenum = scm_to_julia_(fl_ctx, car_(e), mod); jl_value_t *file = jl_nothing; JL_GC_PUSH2(&linenum, &file); if (n == 2) file = scm_to_julia_(fl_ctx, car_(cdr_(e)), mod); temp = jl_new_struct(jl_linenumbernode_type, linenum, file); JL_GC_POP(); return temp; } JL_GC_PUSH1(&ex); if (sym == label_sym) { ex = scm_to_julia_(fl_ctx, car_(e), mod); temp = jl_new_struct(jl_labelnode_type, ex); } else if (sym == goto_sym) { ex = scm_to_julia_(fl_ctx, car_(e), mod); temp = jl_new_struct(jl_gotonode_type, ex); } else if (sym == newvar_sym) { ex = scm_to_julia_(fl_ctx, car_(e), mod); temp = jl_new_struct(jl_newvarnode_type, ex); } else if (sym == globalref_sym) { ex = scm_to_julia_(fl_ctx, car_(e), mod); temp = scm_to_julia_(fl_ctx, car_(cdr_(e)), mod); assert(jl_is_module(ex)); assert(jl_is_symbol(temp)); temp = jl_module_globalref((jl_module_t*)ex, (jl_sym_t*)temp); } else if (sym == top_sym) { assert(mod && "top should not be generated by the parser"); ex = scm_to_julia_(fl_ctx, car_(e), mod); assert(jl_is_symbol(ex)); temp = jl_module_globalref(jl_base_relative_to(mod), (jl_sym_t*)ex); } else if (sym == core_sym) { ex = scm_to_julia_(fl_ctx, car_(e), mod); assert(jl_is_symbol(ex)); temp = jl_module_globalref(jl_core_module, (jl_sym_t*)ex); } else if (sym == inert_sym || (sym == quote_sym && (!iscons(car_(e))))) { ex = scm_to_julia_(fl_ctx, car_(e), mod); temp = jl_new_struct(jl_quotenode_type, ex); } if (temp) { JL_GC_POP(); return temp; } ex = (jl_value_t*)jl_exprn(sym, n); size_t i; for (i = 0; i < n; i++) { assert(iscons(e)); jl_array_ptr_set(((jl_expr_t*)ex)->args, i, scm_to_julia_(fl_ctx, car_(e), mod)); e = cdr_(e); } if (sym == lambda_sym) ex = (jl_value_t*)jl_new_code_info_from_ast((jl_expr_t*)ex); JL_GC_POP(); if (sym == list_sym) return (jl_value_t*)((jl_expr_t*)ex)->args; return (jl_value_t*)ex; } if (iscprim(e) && cp_class((cprim_t*)ptr(e)) == fl_ctx->wchartype) { uint32_t c, u = *(uint32_t*)cp_data((cprim_t*)ptr(e)); if (u < 0x80) { c = u << 24; } else { c = ((u << 0) & 0x0000003f) | ((u << 2) & 0x00003f00) | ((u << 4) & 0x003f0000) | ((u << 6) & 0x3f000000); c = u < 0x00000800 ? (c << 16) | 0xc0800000 : u < 0x00010000 ? (c << 8) | 0xe0808000 : (c << 0) | 0xf0808080 ; } return jl_box_char(c); } if (iscvalue(e) && cv_class((cvalue_t*)ptr(e)) == jl_ast_ctx(fl_ctx)->jvtype) { return *(jl_value_t**)cv_data((cvalue_t*)ptr(e)); } jl_error("malformed tree"); }
static inline jl_module_t *topmod(jl_codectx_t *ctx) { return jl_base_relative_to(ctx->module); }
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; }
static jl_value_t *scm_to_julia_(fl_context_t *fl_ctx, value_t e, int eo) { if (fl_isnumber(fl_ctx, e)) { int64_t i64; if (isfixnum(e)) { i64 = numval(e); } else { assert(iscprim(e)); cprim_t *cp = (cprim_t*)ptr(e); numerictype_t nt = cp_numtype(cp); switch (nt) { case T_DOUBLE: return (jl_value_t*)jl_box_float64(*(double*)cp_data(cp)); case T_FLOAT: return (jl_value_t*)jl_box_float32(*(float*)cp_data(cp)); case T_UINT8: return (jl_value_t*)jl_box_uint8(*(uint8_t*)cp_data(cp)); case T_UINT16: return (jl_value_t*)jl_box_uint16(*(uint16_t*)cp_data(cp)); case T_UINT32: return (jl_value_t*)jl_box_uint32(*(uint32_t*)cp_data(cp)); case T_UINT64: return (jl_value_t*)jl_box_uint64(*(uint64_t*)cp_data(cp)); default: ; } i64 = conv_to_int64(cp_data(cp), nt); } #ifdef _P64 return (jl_value_t*)jl_box_int64(i64); #else if (i64 > (int64_t)S32_MAX || i64 < (int64_t)S32_MIN) return (jl_value_t*)jl_box_int64(i64); else return (jl_value_t*)jl_box_int32((int32_t)i64); #endif } if (issymbol(e)) { if (e == jl_ast_ctx(fl_ctx)->true_sym) return jl_true; else if (e == jl_ast_ctx(fl_ctx)->false_sym) return jl_false; return (jl_value_t*)scmsym_to_julia(fl_ctx, e); } if (fl_isstring(fl_ctx, e)) return jl_pchar_to_string((char*)cvalue_data(e), cvalue_len(e)); if (iscons(e) || e == fl_ctx->NIL) { value_t hd; jl_sym_t *sym; if (e == fl_ctx->NIL) { hd = e; } else { hd = car_(e); if (hd == jl_ast_ctx(fl_ctx)->ssavalue_sym) return jl_box_ssavalue(numval(car_(cdr_(e)))); else if (hd == jl_ast_ctx(fl_ctx)->slot_sym) return jl_box_slotnumber(numval(car_(cdr_(e)))); else if (hd == jl_ast_ctx(fl_ctx)->null_sym && llength(e) == 1) return jl_nothing; } if (issymbol(hd)) sym = scmsym_to_julia(fl_ctx, hd); else sym = list_sym; size_t n = llength(e)-1; if (issymbol(hd)) e = cdr_(e); else n++; if (!eo) { if (sym == line_sym && n==1) { jl_value_t *linenum = scm_to_julia_(fl_ctx, car_(e), 0); JL_GC_PUSH1(&linenum); jl_value_t *temp = jl_new_struct(jl_linenumbernode_type, linenum); JL_GC_POP(); return temp; } jl_value_t *scmv = NULL, *temp = NULL; JL_GC_PUSH1(&scmv); if (sym == label_sym) { scmv = scm_to_julia_(fl_ctx,car_(e),0); temp = jl_new_struct(jl_labelnode_type, scmv); JL_GC_POP(); return temp; } if (sym == goto_sym) { scmv = scm_to_julia_(fl_ctx,car_(e),0); temp = jl_new_struct(jl_gotonode_type, scmv); JL_GC_POP(); return temp; } if (sym == inert_sym || (sym == quote_sym && (!iscons(car_(e))))) { scmv = scm_to_julia_(fl_ctx,car_(e),0); temp = jl_new_struct(jl_quotenode_type, scmv); JL_GC_POP(); return temp; } if (sym == top_sym) { scmv = scm_to_julia_(fl_ctx,car_(e),0); assert(jl_is_symbol(scmv)); temp = jl_module_globalref(jl_base_relative_to(jl_current_module), (jl_sym_t*)scmv); JL_GC_POP(); return temp; } if (sym == core_sym) { scmv = scm_to_julia_(fl_ctx,car_(e),0); assert(jl_is_symbol(scmv)); temp = jl_module_globalref(jl_core_module, (jl_sym_t*)scmv); JL_GC_POP(); return temp; } if (sym == globalref_sym) { scmv = scm_to_julia_(fl_ctx,car_(e),0); temp = scm_to_julia_(fl_ctx,car_(cdr_(e)),0); assert(jl_is_module(scmv)); assert(jl_is_symbol(temp)); temp = jl_module_globalref((jl_module_t*)scmv, (jl_sym_t*)temp); JL_GC_POP(); return temp; } if (sym == newvar_sym) { scmv = scm_to_julia_(fl_ctx,car_(e),0); temp = jl_new_struct(jl_newvarnode_type, scmv); JL_GC_POP(); return temp; } JL_GC_POP(); } else if (sym == inert_sym && !iscons(car_(e))) { sym = quote_sym; } jl_value_t *ex = (jl_value_t*)jl_exprn(sym, n); JL_GC_PUSH1(&ex); // allocate a fresh args array for empty exprs passed to macros if (eo && n == 0) { ((jl_expr_t*)ex)->args = jl_alloc_vec_any(0); jl_gc_wb(ex, ((jl_expr_t*)ex)->args); } size_t i; for(i=0; i < n; i++) { assert(iscons(e)); jl_array_ptr_set(((jl_expr_t*)ex)->args, i, scm_to_julia_(fl_ctx, car_(e), eo)); e = cdr_(e); } if (sym == lambda_sym) ex = (jl_value_t*)jl_new_lambda_info_from_ast((jl_expr_t*)ex); JL_GC_POP(); if (sym == list_sym) return (jl_value_t*)((jl_expr_t*)ex)->args; return (jl_value_t*)ex; } if (iscprim(e) && cp_class((cprim_t*)ptr(e)) == fl_ctx->wchartype) { return jl_box32(jl_char_type, *(int32_t*)cp_data((cprim_t*)ptr(e))); } if (iscvalue(e) && cv_class((cvalue_t*)ptr(e)) == jl_ast_ctx(fl_ctx)->jvtype) { return *(jl_value_t**)cv_data((cvalue_t*)ptr(e)); } jl_error("malformed tree"); return jl_nothing; }