// wrap expr in a thunk AST jl_lambda_info_t *jl_wrap_expr(jl_value_t *expr) { // `(lambda () (() () ()) ,expr) jl_expr_t *le=NULL, *bo=NULL; jl_value_t *vi=NULL; jl_value_t *mt = jl_an_empty_cell; JL_GC_PUSH(&le, &vi, &bo); le = jl_exprn(lambda_sym, 3); jl_cellset(le->args, 0, mt); vi = (jl_value_t*)jl_alloc_cell_1d(3); jl_cellset(vi, 0, mt); jl_cellset(vi, 1, mt); jl_cellset(vi, 2, mt); jl_cellset(le->args, 1, vi); if (!jl_is_expr(expr) || ((jl_expr_t*)expr)->head != body_sym) { bo = jl_exprn(body_sym, 1); jl_cellset(bo->args, 0, (jl_value_t*)jl_exprn(return_sym, 1)); jl_cellset(((jl_expr_t*)jl_exprarg(bo,0))->args, 0, expr); expr = (jl_value_t*)bo; } jl_cellset(le->args, 2, expr); jl_lambda_info_t *li = jl_new_lambda_info((jl_value_t*)le, jl_null); JL_GC_POP(); return li; }
// wrap expr in a thunk AST jl_lambda_info_t *jl_wrap_expr(jl_value_t *expr) { // `(lambda () (() () () ()) ,expr) jl_expr_t *le=NULL, *bo=NULL; jl_value_t *vi=NULL; jl_value_t *mt = jl_an_empty_vec_any; jl_lambda_info_t *li = NULL; JL_GC_PUSH4(&le, &vi, &bo, &li); le = jl_exprn(lambda_sym, 3); jl_array_ptr_set(le->args, 0, mt); vi = (jl_value_t*)jl_alloc_vec_any(4); jl_array_ptr_set(vi, 0, mt); jl_array_ptr_set(vi, 1, mt); // front end always wraps toplevel exprs with ssavalues in (thunk (lambda () ...)) jl_array_ptr_set(vi, 2, jl_box_long(0)); jl_array_ptr_set(vi, 3, mt); jl_array_ptr_set(le->args, 1, vi); if (!jl_is_expr(expr) || ((jl_expr_t*)expr)->head != body_sym) { bo = jl_exprn(body_sym, 1); jl_array_ptr_set(bo->args, 0, (jl_value_t*)jl_exprn(return_sym, 1)); jl_array_ptr_set(((jl_expr_t*)jl_exprarg(bo,0))->args, 0, expr); expr = (jl_value_t*)bo; } jl_array_ptr_set(le->args, 2, expr); li = jl_new_lambda_info_from_ast(le); JL_GC_POP(); return li; }
static jl_value_t *copy_ast(jl_value_t *expr, jl_tuple_t *sp, int do_sp) { if (jl_is_symbol(expr)) { if (!do_sp) return expr; // pre-evaluate certain static parameters to help type inference for(int i=0; i < jl_tuple_len(sp); i+=2) { assert(jl_is_typevar(jl_tupleref(sp,i))); if ((jl_sym_t*)expr == ((jl_tvar_t*)jl_tupleref(sp,i))->name) { jl_value_t *spval = jl_tupleref(sp,i+1); if (jl_is_long(spval)) return spval; } } } else if (jl_is_lambda_info(expr)) { jl_lambda_info_t *li = (jl_lambda_info_t*)expr; /* if (sp == jl_null && li->ast && jl_lam_capt((jl_expr_t*)li->ast)->length == 0) return expr; */ // TODO: avoid if above condition is true and decls have already // been evaluated. JL_GC_PUSH(&li); li = jl_add_static_parameters(li, sp); li->ast = jl_prepare_ast(li, li->sparams); JL_GC_POP(); return (jl_value_t*)li; } else if (jl_typeis(expr,jl_array_any_type)) { jl_array_t *a = (jl_array_t*)expr; jl_array_t *na = jl_alloc_cell_1d(jl_array_len(a)); JL_GC_PUSH(&na); size_t i; for(i=0; i < jl_array_len(a); i++) jl_cellset(na, i, copy_ast(jl_cellref(a,i), sp, do_sp)); JL_GC_POP(); return (jl_value_t*)na; } else if (jl_is_expr(expr)) { jl_expr_t *e = (jl_expr_t*)expr; jl_expr_t *ne = jl_exprn(e->head, jl_array_len(e->args)); JL_GC_PUSH(&ne); size_t i; if (e->head == lambda_sym) { jl_exprarg(ne, 0) = copy_ast(jl_exprarg(e,0), sp, 0); jl_exprarg(ne, 1) = copy_ast(jl_exprarg(e,1), sp, 0); jl_exprarg(ne, 2) = copy_ast(jl_exprarg(e,2), sp, 1); } else { for(i=0; i < jl_array_len(e->args); i++) jl_exprarg(ne, i) = copy_ast(jl_exprarg(e,i), sp, 1); } JL_GC_POP(); return (jl_value_t*)ne; } return expr; }
JL_DLLEXPORT jl_value_t *jl_copy_ast(jl_value_t *expr) { if (expr && jl_is_expr(expr)) { jl_expr_t *e = (jl_expr_t*)expr; size_t i, l = jl_array_len(e->args); jl_expr_t *ne = jl_exprn(e->head, l); JL_GC_PUSH2(&ne, &expr); for (i = 0; i < l; i++) { jl_value_t *a = jl_exprarg(e, i); jl_exprargset(ne, i, jl_copy_ast(a)); } JL_GC_POP(); return (jl_value_t*)ne; } return expr; }
static jl_value_t *scm_to_julia(fl_context_t *fl_ctx, value_t e, jl_module_t *mod) { jl_value_t *v = NULL; JL_GC_PUSH1(&v); JL_TRY { v = scm_to_julia_(fl_ctx, e, mod); } JL_CATCH { // if expression cannot be converted, replace with error expr jl_expr_t *ex = jl_exprn(error_sym, 1); v = (jl_value_t*)ex; jl_array_ptr_set(ex->args, 0, jl_cstr_to_string("invalid AST")); } JL_GC_POP(); return v; }
DLLEXPORT jl_value_t *jl_copy_ast(jl_value_t *expr) { if (jl_is_expr(expr)) { jl_expr_t *e = (jl_expr_t*)expr; size_t i, l = jl_array_len(e->args); jl_expr_t *ne = NULL; JL_GC_PUSH2(&ne, &expr); ne = jl_exprn(e->head, l); if (l == 0) { ne->args = jl_alloc_cell_1d(0); } else { for(i=0; i < l; i++) jl_exprarg(ne, i) = jl_copy_ast(jl_exprarg(e,i)); } JL_GC_POP(); return (jl_value_t*)ne; } else if (jl_typeis(expr,jl_array_any_type)) { jl_array_t *a = (jl_array_t*)expr; size_t i, l = jl_array_len(a); jl_array_t *na = NULL; JL_GC_PUSH2(&na, &expr); na = jl_alloc_cell_1d(l); for(i=0; i < l; i++) jl_cellset(na, i, jl_copy_ast(jl_cellref(a,i))); JL_GC_POP(); return (jl_value_t*)na; } else if (jl_is_quotenode(expr)) { if (jl_is_symbol(jl_fieldref(expr,0))) return expr; jl_value_t *q = NULL; JL_GC_PUSH2(&q, &expr); q = jl_copy_ast(jl_fieldref(expr,0)); jl_value_t *v = jl_new_struct(jl_quotenode_type, q); JL_GC_POP(); return v; } return expr; }
static jl_value_t *scm_to_julia(value_t e) { #ifdef JL_GC_MARKSWEEP int en = jl_gc_is_enabled(); jl_gc_disable(); #endif jl_value_t *v; JL_TRY { v = scm_to_julia_(e); } JL_CATCH { // if expression cannot be converted, replace with error expr jl_expr_t *ex = jl_exprn(error_sym, 1); jl_cellset(ex->args, 0, jl_cstr_to_string("invalid AST")); v = (jl_value_t*)ex; } #ifdef JL_GC_MARKSWEEP if (en) jl_gc_enable(); #endif return v; }
JL_DLLEXPORT jl_value_t *jl_copy_ast(jl_value_t *expr) { if (expr == NULL) { return NULL; } else if (jl_is_expr(expr)) { jl_expr_t *e = (jl_expr_t*)expr; size_t i, l = jl_array_len(e->args); jl_expr_t *ne = NULL; JL_GC_PUSH2(&ne, &expr); ne = jl_exprn(e->head, l); if (l == 0) { ne->args = jl_alloc_vec_any(0); jl_gc_wb(ne, ne->args); } else { for(i=0; i < l; i++) { jl_exprargset(ne, i, jl_copy_ast(jl_exprarg(e,i))); } } JL_GC_POP(); return (jl_value_t*)ne; } else if (jl_typeis(expr,jl_array_any_type)) { jl_array_t *a = (jl_array_t*)expr; size_t i, l = jl_array_len(a); jl_array_t *na = NULL; JL_GC_PUSH2(&na, &expr); na = jl_alloc_vec_any(l); for(i=0; i < l; i++) jl_array_ptr_set(na, i, jl_copy_ast(jl_array_ptr_ref(a,i))); JL_GC_POP(); return (jl_value_t*)na; } return expr; }
static jl_value_t *copy_ast(jl_value_t *expr, jl_tuple_t *sp, int do_sp) { if (jl_is_symbol(expr)) { if (!do_sp) return expr; // pre-evaluate certain static parameters to help type inference for(int i=0; i < jl_tuple_len(sp); i+=2) { assert(jl_is_typevar(jl_tupleref(sp,i))); if ((jl_sym_t*)expr == ((jl_tvar_t*)jl_tupleref(sp,i))->name) { jl_value_t *spval = jl_tupleref(sp,i+1); if (jl_is_long(spval)) return spval; } } } else if (jl_is_lambda_info(expr)) { jl_lambda_info_t *li = (jl_lambda_info_t*)expr; /* if (sp == jl_null && li->ast && jl_array_len(jl_lam_capt((jl_expr_t*)li->ast)) == 0) return expr; */ // TODO: avoid if above condition is true and decls have already // been evaluated. JL_GC_PUSH1(&li); li = jl_add_static_parameters(li, sp); // inner lambda does not need the "def" link. it leads to excess object // retention, for example pointing to the original uncompressed AST // of a top-level thunk that gets type inferred. li->def = li; li->ast = jl_prepare_ast(li, li->sparams); JL_GC_POP(); return (jl_value_t*)li; } else if (jl_typeis(expr,jl_array_any_type)) { jl_array_t *a = (jl_array_t*)expr; jl_array_t *na = jl_alloc_cell_1d(jl_array_len(a)); JL_GC_PUSH1(&na); size_t i; for(i=0; i < jl_array_len(a); i++) jl_cellset(na, i, copy_ast(jl_cellref(a,i), sp, do_sp)); JL_GC_POP(); return (jl_value_t*)na; } else if (jl_is_expr(expr)) { jl_expr_t *e = (jl_expr_t*)expr; jl_expr_t *ne = jl_exprn(e->head, jl_array_len(e->args)); JL_GC_PUSH1(&ne); if (e->head == lambda_sym) { jl_exprarg(ne, 0) = copy_ast(jl_exprarg(e,0), sp, 0); jl_exprarg(ne, 1) = copy_ast(jl_exprarg(e,1), sp, 0); jl_exprarg(ne, 2) = copy_ast(jl_exprarg(e,2), sp, 1); } else { for(size_t i=0; i < jl_array_len(e->args); i++) jl_exprarg(ne, i) = copy_ast(jl_exprarg(e,i), sp, 1); } JL_GC_POP(); return (jl_value_t*)ne; } return expr; }
static jl_value_t *jl_deserialize_value(ios_t *s) { int pos = ios_pos(s); int32_t tag = read_uint8(s); if (tag == Null_tag) return NULL; if (tag == 0) { tag = read_uint8(s); return (jl_value_t*)ptrhash_get(&deser_tag, (void*)(ptrint_t)tag); } if (tag == BackRef_tag) { assert(tree_literal_values == NULL); ptrint_t offs = read_int32(s); void **bp = ptrhash_bp(&backref_table, (void*)(ptrint_t)offs); assert(*bp != HT_NOTFOUND); return (jl_value_t*)*bp; } jl_value_t *vtag=(jl_value_t*)ptrhash_get(&deser_tag,(void*)(ptrint_t)tag); if (tag >= VALUE_TAGS) { return vtag; } int usetable = (tree_literal_values == NULL); size_t i; if (vtag == (jl_value_t*)jl_tuple_type || vtag == (jl_value_t*)LongTuple_tag) { size_t len; if (vtag == (jl_value_t*)jl_tuple_type) len = read_uint8(s); else len = read_int32(s); jl_tuple_t *tu = jl_alloc_tuple_uninit(len); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, (jl_value_t*)tu); for(i=0; i < len; i++) jl_tupleset(tu, i, jl_deserialize_value(s)); return (jl_value_t*)tu; } else if (vtag == (jl_value_t*)jl_symbol_type || vtag == (jl_value_t*)LongSymbol_tag) { size_t len; if (vtag == (jl_value_t*)jl_symbol_type) len = read_uint8(s); else len = read_int32(s); char *name = alloca(len+1); ios_read(s, name, len); name[len] = '\0'; jl_value_t *s = (jl_value_t*)jl_symbol(name); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, s); return s; } else if (vtag == (jl_value_t*)jl_array_type) { jl_value_t *aty = jl_deserialize_value(s); jl_value_t *elty = jl_tparam0(aty); int16_t ndims = jl_unbox_long(jl_tparam1(aty)); size_t *dims = alloca(ndims*sizeof(size_t)); for(i=0; i < ndims; i++) dims[i] = jl_unbox_long(jl_deserialize_value(s)); jl_array_t *a = jl_new_array_((jl_type_t*)aty, ndims, dims); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, (jl_value_t*)a); if (jl_is_bits_type(elty)) { size_t tot = a->length * a->elsize; ios_read(s, a->data, tot); } else { for(i=0; i < a->length; i++) { ((jl_value_t**)a->data)[i] = jl_deserialize_value(s); } } return (jl_value_t*)a; } else if (vtag == (jl_value_t*)jl_expr_type || vtag == (jl_value_t*)LongExpr_tag) { size_t len; if (vtag == (jl_value_t*)jl_expr_type) len = read_uint8(s); else len = read_int32(s); jl_expr_t *e = jl_exprn((jl_sym_t*)jl_deserialize_value(s), len); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, (jl_value_t*)e); e->etype = jl_deserialize_value(s); for(i=0; i < len; i++) { jl_cellset(e->args, i, jl_deserialize_value(s)); } return (jl_value_t*)e; } else if (vtag == (jl_value_t*)LiteralVal_tag) { return jl_cellref(tree_literal_values, read_uint16(s)); } else if (vtag == (jl_value_t*)jl_tvar_type) { jl_tvar_t *tv = (jl_tvar_t*)newobj((jl_type_t*)jl_tvar_type, 4); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, tv); tv->name = (jl_sym_t*)jl_deserialize_value(s); tv->lb = jl_deserialize_value(s); tv->ub = jl_deserialize_value(s); tv->bound = read_int8(s); return (jl_value_t*)tv; } else if (vtag == (jl_value_t*)jl_func_kind) { jl_value_t *ftype = jl_deserialize_value(s); jl_function_t *f = (jl_function_t*)newobj((jl_type_t*)ftype, 3); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, f); f->linfo = (jl_lambda_info_t*)jl_deserialize_value(s); f->env = jl_deserialize_value(s); f->fptr = jl_deserialize_fptr(s); if (f->fptr == NULL) { f->fptr = &jl_trampoline; } return (jl_value_t*)f; } else if (vtag == (jl_value_t*)jl_lambda_info_type) { jl_lambda_info_t *li = (jl_lambda_info_t*)newobj((jl_type_t*)jl_lambda_info_type, LAMBDA_INFO_NW); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, li); li->ast = jl_deserialize_value(s); li->sparams = (jl_tuple_t*)jl_deserialize_value(s); li->tfunc = jl_deserialize_value(s); li->name = (jl_sym_t*)jl_deserialize_value(s); li->specTypes = jl_deserialize_value(s); li->specializations = (jl_array_t*)jl_deserialize_value(s); li->inferred = jl_deserialize_value(s); li->file = jl_deserialize_value(s); li->line = jl_deserialize_value(s); li->module = (jl_module_t*)jl_deserialize_value(s); li->fptr = NULL; li->roots = NULL; li->functionObject = NULL; li->inInference = 0; li->inCompile = 0; li->unspecialized = NULL; return (jl_value_t*)li; } else if (vtag == (jl_value_t*)jl_module_type) { jl_module_t *m = jl_new_module(anonymous_sym); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, m); m->name = (jl_sym_t*)jl_deserialize_value(s); while (1) { jl_value_t *name = jl_deserialize_value(s); if (name == NULL) break; jl_binding_t *b = jl_get_binding_wr(m, (jl_sym_t*)name); b->value = jl_deserialize_value(s); b->type = (jl_type_t*)jl_deserialize_value(s); b->constp = read_int8(s); b->exportp = read_int8(s); } while (1) { jl_value_t *name = jl_deserialize_value(s); if (name == NULL) break; jl_set_expander(m, (jl_sym_t*)name, (jl_function_t*)jl_deserialize_value(s)); } return (jl_value_t*)m; } else if (vtag == (jl_value_t*)jl_methtable_type) { jl_methtable_t *mt = (jl_methtable_t*)allocobj(sizeof(jl_methtable_t)); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, mt); mt->type = (jl_type_t*)jl_methtable_type; mt->defs = jl_deserialize_methlist(s); mt->cache = jl_deserialize_methlist(s); mt->cache_1arg = (jl_array_t*)jl_deserialize_value(s); mt->max_args = read_int32(s); return (jl_value_t*)mt; } else if (vtag == (jl_value_t*)SmallInt64_tag) { jl_value_t *v = jl_box_int64(read_int32(s)); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, v); return v; } else if (vtag == (jl_value_t*)jl_bits_kind) { jl_bits_type_t *bt = (jl_bits_type_t*)jl_deserialize_value(s); int nby = bt->nbits/8; char *data = alloca(nby); ios_read(s, data, nby); jl_value_t *v=NULL; if (bt == jl_int32_type) v = jl_box_int32(*(int32_t*)data); else if (bt == jl_int64_type) v = jl_box_int64(*(int64_t*)data); else if (bt == jl_bool_type) v = jl_box_bool(*(int8_t*)data); else { switch (bt->nbits) { case 8: v = jl_box8 (bt, *(int8_t*) data); break; case 16: v = jl_box16(bt, *(int16_t*)data); break; case 32: v = jl_box32(bt, *(int32_t*)data); break; case 64: v = jl_box64(bt, *(int64_t*)data); break; default: v = (jl_value_t*)allocobj(sizeof(void*)+nby); v->type = (jl_type_t*)bt; memcpy(jl_bits_data(v), data, nby); } } if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, v); return v; } else if (vtag == (jl_value_t*)jl_struct_kind) { jl_struct_type_t *typ = (jl_struct_type_t*)jl_deserialize_value(s); if (typ == jl_struct_kind || typ == jl_bits_kind) return jl_deserialize_tag_type(s, typ, pos); size_t nf = typ->names->length; jl_value_t *v = jl_new_struct_uninit(typ); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, v); for(i=0; i < nf; i++) { ((jl_value_t**)v)[i+1] = jl_deserialize_value(s); } // TODO: put WeakRefs on the weak_refs list return v; } else if (vtag == (jl_value_t*)jl_tag_kind) { return jl_deserialize_tag_type(s, jl_tag_kind, pos); } assert(0); return NULL; }
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 jl_value_t *jl_expand_macros(jl_value_t *expr, jl_module_t *inmodule, struct macroctx_stack *macroctx, int onelevel) { if (!expr || !jl_is_expr(expr)) return expr; jl_expr_t *e = (jl_expr_t*)expr; if (e->head == inert_sym || e->head == module_sym || //e->head == toplevel_sym || // TODO: enable this once julia-expand-macroscope is fixed / removed e->head == meta_sym) { return expr; } if (e->head == quote_sym && jl_expr_nargs(e) == 1) { expr = jl_call_scm_on_ast("julia-bq-macro", jl_exprarg(e, 0), inmodule); JL_GC_PUSH1(&expr); if (macroctx) { // in a macro, `quote` also implies `escape` jl_expr_t *e2 = jl_exprn(escape_sym, 1); jl_array_ptr_set(e2->args, 0, expr); expr = (jl_value_t*)e2; } expr = jl_expand_macros(expr, inmodule, macroctx, onelevel); JL_GC_POP(); return expr; } if (e->head == hygienicscope_sym && jl_expr_nargs(e) == 2) { struct macroctx_stack newctx; newctx.m = (jl_module_t*)jl_exprarg(e, 1); JL_TYPECHK(hygienic-scope, module, (jl_value_t*)newctx.m); newctx.parent = macroctx; jl_value_t *a = jl_exprarg(e, 0); jl_value_t *a2 = jl_expand_macros(a, inmodule, &newctx, onelevel); if (a != a2) jl_array_ptr_set(e->args, 0, a2); return expr; } if (e->head == macrocall_sym) { struct macroctx_stack newctx; newctx.m = macroctx ? macroctx->m : inmodule; newctx.parent = macroctx; jl_value_t *result = jl_invoke_julia_macro(e->args, inmodule, &newctx.m); jl_value_t *wrap = NULL; JL_GC_PUSH3(&result, &wrap, &newctx.m); // copy and wrap the result in `(hygienic-scope ,result ,newctx) if (jl_is_expr(result) && ((jl_expr_t*)result)->head == escape_sym) result = jl_exprarg(result, 0); else wrap = (jl_value_t*)jl_exprn(hygienicscope_sym, 2); result = jl_copy_ast(result); if (!onelevel) result = jl_expand_macros(result, inmodule, wrap ? &newctx : macroctx, onelevel); if (wrap) { jl_exprargset(wrap, 0, result); jl_exprargset(wrap, 1, newctx.m); result = wrap; } JL_GC_POP(); return result; } if (e->head == escape_sym && macroctx) { macroctx = macroctx->parent; } size_t i; for (i = 0; i < jl_array_len(e->args); i++) { jl_value_t *a = jl_array_ptr_ref(e->args, i); jl_value_t *a2 = jl_expand_macros(a, inmodule, macroctx, onelevel); if (a != a2) jl_array_ptr_set(e->args, i, a2); } return expr; }
static jl_lambda_info_t *jl_instantiate_staged(jl_method_t *generator, jl_tupletype_t *tt, jl_svec_t *env) { size_t i, l; jl_expr_t *ex = NULL; jl_value_t *linenum = NULL; jl_svec_t *sparam_vals = env; jl_lambda_info_t *func = generator->lambda_template; JL_GC_PUSH4(&ex, &linenum, &sparam_vals, &func); int last_in = in_pure_callback; assert(jl_svec_len(func->sparam_syms) == jl_svec_len(sparam_vals)); JL_TRY { in_pure_callback = 1; ex = jl_exprn(lambda_sym, 2); int nargs = func->nargs; jl_array_t *argnames = jl_alloc_vec_any(nargs); jl_array_ptr_set(ex->args, 0, argnames); for (i = 0; i < nargs; i++) jl_array_ptr_set(argnames, i, jl_array_ptr_ref(func->slotnames, i)); jl_expr_t *scopeblock = jl_exprn(jl_symbol("scope-block"), 1); jl_array_ptr_set(ex->args, 1, scopeblock); jl_expr_t *body = jl_exprn(jl_symbol("block"), 2); jl_array_ptr_set(((jl_expr_t*)jl_exprarg(ex,1))->args, 0, body); linenum = jl_box_long(generator->line); jl_value_t *linenode = jl_new_struct(jl_linenumbernode_type, linenum); jl_array_ptr_set(body->args, 0, linenode); // invoke code generator assert(jl_nparams(tt) == jl_array_len(argnames) || (func->isva && (jl_nparams(tt) >= jl_array_len(argnames) - 1))); jl_array_ptr_set(body->args, 1, jl_call_staged(sparam_vals, func, jl_svec_data(tt->parameters), jl_nparams(tt))); if (func->sparam_syms != jl_emptysvec) { // mark this function as having the same static parameters as the generator size_t i, nsp = jl_svec_len(func->sparam_syms); jl_expr_t *newast = jl_exprn(jl_symbol("with-static-parameters"), nsp + 1); jl_exprarg(newast, 0) = (jl_value_t*)ex; // (with-static-parameters func_expr sp_1 sp_2 ...) for (i = 0; i < nsp; i++) jl_exprarg(newast, i+1) = jl_svecref(func->sparam_syms, i); ex = newast; } // need to eval macros in the right module, but not give a warning for the `eval` call unless that results in a call to `eval` func = (jl_lambda_info_t*)jl_toplevel_eval_in_warn(generator->module, (jl_value_t*)ex, 1); // finish marking this as a specialization of the generator func->isva = generator->lambda_template->isva; func->def = generator; jl_gc_wb(func, generator); func->sparam_vals = env; jl_gc_wb(func, env); func->specTypes = tt; jl_gc_wb(func, tt); jl_array_t *stmts = (jl_array_t*)func->code; for(i = 0, l = jl_array_len(stmts); i < l; i++) { jl_array_ptr_set(stmts, i, jl_resolve_globals(jl_array_ptr_ref(stmts, i), func)); } in_pure_callback = last_in; } JL_CATCH { in_pure_callback = last_in; jl_rethrow(); } JL_GC_POP(); return func; }
static jl_value_t *jl_deserialize_value(ios_t *s) { int pos = ios_pos(s); int32_t tag = read_uint8(s); if (tag == Null_tag) return NULL; if (tag == 0) { tag = read_uint8(s); jl_value_t *v = ptrhash_get(&deser_tag, (void*)(ptrint_t)tag); assert(v != HT_NOTFOUND); return v; } if (tag == BackRef_tag || tag == ShortBackRef_tag) { assert(tree_literal_values == NULL); ptrint_t offs = (tag == BackRef_tag) ? read_int32(s) : read_uint16(s); void **bp = ptrhash_bp(&backref_table, (void*)(ptrint_t)offs); assert(*bp != HT_NOTFOUND); return (jl_value_t*)*bp; } jl_value_t *vtag=(jl_value_t*)ptrhash_get(&deser_tag,(void*)(ptrint_t)tag); if (tag >= VALUE_TAGS) { return vtag; } int usetable = (tree_literal_values == NULL); size_t i; if (vtag == (jl_value_t*)jl_tuple_type || vtag == (jl_value_t*)LongTuple_tag) { size_t len; if (vtag == (jl_value_t*)jl_tuple_type) len = read_uint8(s); else len = read_int32(s); jl_tuple_t *tu = jl_alloc_tuple_uninit(len); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, (jl_value_t*)tu); for(i=0; i < len; i++) jl_tupleset(tu, i, jl_deserialize_value(s)); return (jl_value_t*)tu; } else if (vtag == (jl_value_t*)jl_symbol_type || vtag == (jl_value_t*)LongSymbol_tag) { size_t len; if (vtag == (jl_value_t*)jl_symbol_type) len = read_uint8(s); else len = read_int32(s); char *name = alloca(len+1); ios_read(s, name, len); name[len] = '\0'; jl_value_t *s = (jl_value_t*)jl_symbol(name); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, s); return s; } else if (vtag == (jl_value_t*)jl_array_type) { jl_value_t *aty = jl_deserialize_value(s); jl_value_t *elty = jl_tparam0(aty); int16_t ndims = jl_unbox_long(jl_tparam1(aty)); size_t *dims = alloca(ndims*sizeof(size_t)); for(i=0; i < ndims; i++) dims[i] = jl_unbox_long(jl_deserialize_value(s)); jl_array_t *a = jl_new_array_((jl_type_t*)aty, ndims, dims); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, (jl_value_t*)a); if (jl_is_bits_type(elty)) { size_t tot = jl_array_len(a) * a->elsize; ios_read(s, jl_array_data(a), tot); } else { for(i=0; i < jl_array_len(a); i++) { ((jl_value_t**)a->data)[i] = jl_deserialize_value(s); } } return (jl_value_t*)a; } else if (vtag == (jl_value_t*)jl_expr_type || vtag == (jl_value_t*)LongExpr_tag) { size_t len; if (vtag == (jl_value_t*)jl_expr_type) len = read_uint8(s); else len = read_int32(s); jl_expr_t *e = jl_exprn((jl_sym_t*)jl_deserialize_value(s), len); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, (jl_value_t*)e); e->etype = jl_deserialize_value(s); for(i=0; i < len; i++) { jl_cellset(e->args, i, jl_deserialize_value(s)); } return (jl_value_t*)e; } else if (vtag == (jl_value_t*)LiteralVal_tag) { return jl_cellref(tree_literal_values, read_uint16(s)); } else if (vtag == (jl_value_t*)jl_tvar_type) { jl_tvar_t *tv = (jl_tvar_t*)newobj((jl_type_t*)jl_tvar_type, 4); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, tv); tv->name = (jl_sym_t*)jl_deserialize_value(s); tv->lb = jl_deserialize_value(s); tv->ub = jl_deserialize_value(s); tv->bound = read_int8(s); return (jl_value_t*)tv; } else if (vtag == (jl_value_t*)jl_function_type) { jl_function_t *f = (jl_function_t*)newobj((jl_type_t*)jl_function_type, 3); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, f); f->linfo = (jl_lambda_info_t*)jl_deserialize_value(s); f->env = jl_deserialize_value(s); f->fptr = jl_deserialize_fptr(s); return (jl_value_t*)f; } else if (vtag == (jl_value_t*)jl_lambda_info_type) { jl_lambda_info_t *li = (jl_lambda_info_t*)newobj((jl_type_t*)jl_lambda_info_type, LAMBDA_INFO_NW); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, li); li->ast = jl_deserialize_value(s); li->sparams = (jl_tuple_t*)jl_deserialize_value(s); li->tfunc = jl_deserialize_value(s); li->name = (jl_sym_t*)jl_deserialize_value(s); li->specTypes = (jl_tuple_t*)jl_deserialize_value(s); li->specializations = (jl_array_t*)jl_deserialize_value(s); li->inferred = read_int8(s); li->file = jl_deserialize_value(s); li->line = read_int32(s); li->module = (jl_module_t*)jl_deserialize_value(s); li->roots = (jl_array_t*)jl_deserialize_value(s); li->def = (jl_lambda_info_t*)jl_deserialize_value(s); li->capt = jl_deserialize_value(s); li->fptr = &jl_trampoline; li->functionObject = NULL; li->cFunctionObject = NULL; li->inInference = 0; li->inCompile = 0; li->unspecialized = NULL; return (jl_value_t*)li; } else if (vtag == (jl_value_t*)jl_module_type) { jl_sym_t *mname = (jl_sym_t*)jl_deserialize_value(s); jl_module_t *m = jl_new_module(mname); if (usetable) ptrhash_put(&backref_table, (void*)(ptrint_t)pos, m); m->parent = (jl_module_t*)jl_deserialize_value(s); while (1) { jl_value_t *name = jl_deserialize_value(s); if (name == NULL) break; jl_binding_t *b = jl_get_binding_wr(m, (jl_sym_t*)name); b->value = jl_deserialize_value(s); b->type = (jl_type_t*)jl_deserialize_value(s); b->owner = (jl_module_t*)jl_deserialize_value(s); int8_t flags = read_int8(s); b->constp = (flags>>2) & 1; b->exportp = (flags>>1) & 1; b->imported = (flags) & 1; } size_t ni = read_int32(s); for(size_t i=0; i < ni; i++) { arraylist_push(&m->usings, jl_deserialize_value(s)); } return (jl_value_t*)m; }
static jl_value_t *scm_to_julia_(value_t e, int eo) { if (fl_isnumber(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); } if ( #ifdef _P64 jl_compileropts.int_literals==32 #else jl_compileropts.int_literals!=64 #endif ) { if (i64 > (int64_t)S32_MAX || i64 < (int64_t)S32_MIN) return (jl_value_t*)jl_box_int64(i64); return (jl_value_t*)jl_box_int32((int32_t)i64); } else { return (jl_value_t*)jl_box_int64(i64); } } if (issymbol(e)) { if (e == true_sym) return jl_true; else if (e == false_sym) return jl_false; return (jl_value_t*)scmsym_to_julia(e); } if (fl_isstring(e)) { return jl_pchar_to_string((char*)cvalue_data(e), cvalue_len(e)); } if (e == FL_F) { return jl_false; } if (e == FL_T) { return jl_true; } if (e == FL_NIL) { return (jl_value_t*)jl_null; } if (iscons(e)) { value_t hd = car_(e); if (issymbol(hd)) { jl_sym_t *sym = scmsym_to_julia(hd); /* tree node types: goto gotoifnot label return lambda call = quote null top method body file new line enter leave */ size_t n = llength(e)-1; size_t i; if (sym == null_sym && n == 0) return jl_nothing; if (sym == lambda_sym) { jl_expr_t *ex = jl_exprn(lambda_sym, n); e = cdr_(e); value_t largs = car_(e); jl_cellset(ex->args, 0, full_list(largs,eo)); e = cdr_(e); value_t ee = car_(e); jl_array_t *vinf = jl_alloc_cell_1d(3); jl_cellset(vinf, 0, full_list(car_(ee),eo)); ee = cdr_(ee); jl_cellset(vinf, 1, full_list_of_lists(car_(ee),eo)); ee = cdr_(ee); jl_cellset(vinf, 2, full_list_of_lists(car_(ee),eo)); assert(!iscons(cdr_(ee))); jl_cellset(ex->args, 1, vinf); e = cdr_(e); for(i=2; i < n; i++) { assert(iscons(e)); jl_cellset(ex->args, i, scm_to_julia_(car_(e), eo)); e = cdr_(e); } return (jl_value_t*)jl_new_lambda_info((jl_value_t*)ex, jl_null); } e = cdr_(e); if (!eo) { if (sym == line_sym && n==1) { return jl_new_struct(jl_linenumbernode_type, scm_to_julia_(car_(e),0)); } if (sym == label_sym) { return jl_new_struct(jl_labelnode_type, scm_to_julia_(car_(e),0)); } if (sym == goto_sym) { return jl_new_struct(jl_gotonode_type, scm_to_julia_(car_(e),0)); } if (sym == quote_sym) { return jl_new_struct(jl_quotenode_type, scm_to_julia_(car_(e),0)); } if (sym == top_sym) { return jl_new_struct(jl_topnode_type, scm_to_julia_(car_(e),0)); } if (sym == newvar_sym) { return jl_new_struct(jl_newvarnode_type, scm_to_julia_(car_(e),0)); } } jl_expr_t *ex = jl_exprn(sym, n); // allocate a fresh args array for empty exprs passed to macros if (eo && n == 0) ex->args = jl_alloc_cell_1d(0); for(i=0; i < n; i++) { assert(iscons(e)); jl_cellset(ex->args, i, scm_to_julia_(car_(e),eo)); e = cdr_(e); } return (jl_value_t*)ex; } else { jl_error("malformed tree"); } } if (iscprim(e) && cp_class((cprim_t*)ptr(e))==wchartype) { jl_value_t *wc = jl_box32(jl_char_type, *(int32_t*)cp_data((cprim_t*)ptr(e))); return wc; } if (iscvalue(e) && cv_class((cvalue_t*)ptr(e)) == jvtype) { return *(jl_value_t**)cv_data((cvalue_t*)ptr(e)); } jl_error("malformed tree"); return (jl_value_t*)jl_null; }
static jl_value_t *scm_to_julia_(value_t e) { if (fl_isnumber(e)) { if (iscprim(e)) { numerictype_t nt = cp_numtype((cprim_t*)ptr(e)); switch (nt) { case T_DOUBLE: return (jl_value_t*)jl_box_float64(*(double*)cp_data((cprim_t*)ptr(e))); case T_FLOAT: return (jl_value_t*)jl_box_float32(*(float*)cp_data((cprim_t*)ptr(e))); case T_INT64: return (jl_value_t*)jl_box_int64(*(int64_t*)cp_data((cprim_t*)ptr(e))); case T_UINT8: return (jl_value_t*)jl_box_uint8(*(uint8_t*)cp_data((cprim_t*)ptr(e))); case T_UINT16: return (jl_value_t*)jl_box_uint16(*(uint16_t*)cp_data((cprim_t*)ptr(e))); case T_UINT32: return (jl_value_t*)jl_box_uint32(*(uint32_t*)cp_data((cprim_t*)ptr(e))); case T_UINT64: return (jl_value_t*)jl_box_uint64(*(uint64_t*)cp_data((cprim_t*)ptr(e))); default: ; } } if (isfixnum(e)) { int64_t ne = numval(e); #ifdef __LP64__ return (jl_value_t*)jl_box_int64(ne); #else if (ne > S32_MAX || ne < S32_MIN) return (jl_value_t*)jl_box_int64(ne); return (jl_value_t*)jl_box_int32((int32_t)ne); #endif } uint64_t n = toulong(e, "scm_to_julia"); #ifdef __LP64__ return (jl_value_t*)jl_box_int64((int64_t)n); #else if (n > S32_MAX) return (jl_value_t*)jl_box_int64((int64_t)n); return (jl_value_t*)jl_box_int32((int32_t)n); #endif } if (issymbol(e)) { if (!fl_isgensym(e)) { char *sn = symbol_name(e); if (!strcmp(sn, "true")) return jl_true; else if (!strcmp(sn, "false")) return jl_false; } return (jl_value_t*)scmsym_to_julia(e); } if (fl_isstring(e)) { return jl_pchar_to_string(cvalue_data(e), cvalue_len(e)); } if (e == FL_F) { return jl_false; } if (e == FL_T) { return jl_true; } if (e == FL_NIL) { return (jl_value_t*)jl_null; } if (iscons(e)) { value_t hd = car_(e); if (issymbol(hd)) { jl_sym_t *sym = scmsym_to_julia(hd); /* tree node types: goto gotoifnot label return lambda call = quote null top method body file new line enter leave */ size_t n = llength(e)-1; size_t i; if (sym == lambda_sym) { jl_expr_t *ex = jl_exprn(lambda_sym, n); e = cdr_(e); value_t largs = car_(e); jl_cellset(ex->args, 0, full_list(largs)); e = cdr_(e); value_t ee = car_(e); jl_array_t *vinf = jl_alloc_cell_1d(3); jl_cellset(vinf, 0, full_list(car_(ee))); ee = cdr_(ee); jl_cellset(vinf, 1, full_list_of_lists(car_(ee))); ee = cdr_(ee); jl_cellset(vinf, 2, full_list_of_lists(car_(ee))); assert(!iscons(cdr_(ee))); jl_cellset(ex->args, 1, vinf); e = cdr_(e); for(i=2; i < n; i++) { assert(iscons(e)); jl_cellset(ex->args, i, scm_to_julia_(car_(e))); e = cdr_(e); } return (jl_value_t*)jl_new_lambda_info((jl_value_t*)ex, jl_null); } e = cdr_(e); if (sym == line_sym && n==1) { return jl_new_struct(jl_linenumbernode_type, scm_to_julia_(car_(e))); } if (sym == label_sym) { return jl_new_struct(jl_labelnode_type, scm_to_julia_(car_(e))); } if (sym == goto_sym) { return jl_new_struct(jl_gotonode_type, scm_to_julia_(car_(e))); } if (sym == quote_sym) { return jl_new_struct(jl_quotenode_type, scm_to_julia_(car_(e))); } if (sym == top_sym) { return jl_new_struct(jl_topnode_type, scm_to_julia_(car_(e))); } jl_expr_t *ex = jl_exprn(sym, n); for(i=0; i < n; i++) { assert(iscons(e)); jl_cellset(ex->args, i, scm_to_julia_(car_(e))); e = cdr_(e); } return (jl_value_t*)ex; } else { jl_error("malformed tree"); } } if (iscprim(e) && cp_class((cprim_t*)ptr(e))==wchartype) { jl_value_t *wc = jl_box32(jl_char_type, *(int32_t*)cp_data((cprim_t*)ptr(e))); return wc; } if (iscvalue(e) && cv_class((cvalue_t*)ptr(e)) == jvtype) { return *(jl_value_t**)cv_data((cvalue_t*)ptr(e)); } jl_error("malformed tree"); return (jl_value_t*)jl_null; }
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; }