static int sexp_object_compare (sexp ctx, sexp a, sexp b) { int res; if (a == b) return 0; if (sexp_pointerp(a)) { if (sexp_pointerp(b)) { if (sexp_pointer_tag(a) != sexp_pointer_tag(b)) { res = sexp_pointer_tag(a) - sexp_pointer_tag(b); } else { switch (sexp_pointer_tag(a)) { case SEXP_FLONUM: res = sexp_flonum_value(a) - sexp_flonum_value(b); break; case SEXP_BIGNUM: res = sexp_bignum_compare(a, b); break; case SEXP_STRING: res = strcmp(sexp_string_data(a), sexp_string_data(b)); break; case SEXP_SYMBOL: res = strcmp(sexp_symbol_data(a), sexp_symbol_data(b)); break; default: res = 0; break; } } #if SEXP_USE_HUFF_SYMS } else if (sexp_lsymbolp(a) && sexp_isymbolp(b)) { res = strcmp(sexp_symbol_data(a), sexp_string_data(sexp_write_to_string(ctx, b))); #endif } else { res = 1; } } else if (sexp_pointerp(b)) { #if SEXP_USE_HUFF_SYMS if (sexp_isymbolp(a) && sexp_lsymbolp(b)) res = strcmp(sexp_string_data(sexp_write_to_string(ctx, a)), sexp_symbol_data(b)); else #endif res = -1; } else { #if SEXP_USE_HUFF_SYMS if (sexp_isymbolp(a) && sexp_isymbolp(b)) return sexp_isymbol_compare(ctx, a, b); else #endif res = (sexp_sint_t)a - (sexp_sint_t)b; } return res; }
static sexp sexp_set_time_of_day_x_stub (sexp ctx, sexp self, sexp_sint_t n, sexp arg0, sexp arg1) { int err; sexp res; if (! (sexp_pointerp(arg0) && (sexp_pointer_tag(arg0) == sexp_unbox_fixnum(sexp_opcode_arg1_type(self))))) return sexp_type_exception(ctx, self, sexp_unbox_fixnum(sexp_opcode_arg1_type(self)), arg0); if (! ((sexp_pointerp(arg1) && (sexp_pointer_tag(arg1) == sexp_unbox_fixnum(sexp_opcode_arg2_type(self)))) || sexp_not(arg1))) return sexp_type_exception(ctx, self, sexp_unbox_fixnum(sexp_opcode_arg2_type(self)), arg1); err = settimeofday((struct timeval*)sexp_cpointer_value(arg0), (struct timezone*)sexp_cpointer_maybe_null_value(arg1)); if (err) { res = SEXP_FALSE; } else { res = SEXP_TRUE; } return res; }
static int usedp (sexp lambda, sexp var, sexp x) { sexp ls; loop: switch (sexp_pointerp(x) ? sexp_pointer_tag(x) : 0) { case SEXP_REF: return sexp_ref_name(x) == var && sexp_ref_loc(x) == lambda; case SEXP_SET: x = sexp_set_value(x); goto loop; case SEXP_LAMBDA: x = sexp_lambda_body(x); goto loop; case SEXP_CND: if (usedp(lambda, var, sexp_cnd_test(x)) || usedp(lambda, var, sexp_cnd_pass(x))) return 1; x = sexp_cnd_fail(x); goto loop; case SEXP_SEQ: x = sexp_seq_ls(x); case SEXP_PAIR: for (ls=x; sexp_pairp(ls); ls=sexp_cdr(ls)) if (usedp(lambda, var, sexp_car(ls))) return 1; } return 0; }
static sexp sexp_time_3e_seconds_stub (sexp ctx, sexp self, sexp_sint_t n, sexp arg0) { sexp res; if (! (sexp_pointerp(arg0) && (sexp_pointer_tag(arg0) == sexp_unbox_fixnum(sexp_opcode_arg1_type(self))))) return sexp_type_exception(ctx, self, sexp_unbox_fixnum(sexp_opcode_arg1_type(self)), arg0); res = sexp_make_integer(ctx, sexp_shift_epoch(mktime((struct tm*)sexp_cpointer_value(arg0)))); return res; }
static sexp sexp_player_delete_stub (sexp ctx, sexp self, sexp_sint_t n, sexp arg0) { sexp res; if (! (sexp_pointerp(arg0) && (sexp_pointer_tag(arg0) == sexp_unbox_fixnum(sexp_opcode_arg1_type(self))))) return sexp_type_exception(ctx, self, sexp_unbox_fixnum(sexp_opcode_arg1_type(self)), arg0); res = ((player_delete((struct player**)sexp_cpointer_value(arg0))), SEXP_VOID); return res; }
static sexp sexp_readdir_stub (sexp ctx, sexp self, sexp_sint_t n, sexp arg0) { sexp res; if (! (sexp_pointerp(arg0) && (sexp_pointer_tag(arg0) == sexp_unbox_fixnum(sexp_opcode_arg1_type(self))))) return sexp_type_exception(ctx, self, sexp_unbox_fixnum(sexp_opcode_arg1_type(self)), arg0); res = sexp_make_cpointer(ctx, sexp_unbox_fixnum(sexp_opcode_return_type(self)), readdir((DIR*)sexp_cpointer_value(arg0)), arg0, 0); return res; }
static void sexp_print_simple (sexp ctx, sexp x, sexp out, int depth) { int i; if ((!sexp_pointerp(x)) || sexp_symbolp(x) || sexp_stringp(x) || sexp_flonump(x) || sexp_bignump(x)) { sexp_write(ctx, x, out); } else if (depth <= 0) { goto print_name; } else if (sexp_synclop(x)) { sexp_write_string(ctx, "#<sc ", out); sexp_print_simple(ctx, sexp_synclo_expr(x), out, depth); sexp_write_string(ctx, ">", out); } else if (sexp_pairp(x)) { sexp_write_char(ctx, '(', out); sexp_print_simple(ctx, sexp_car(x), out, depth-1); sexp_write_string(ctx, " . ", out); sexp_print_simple(ctx, sexp_cdr(x), out, depth-1); sexp_write_char(ctx, ')', out); } else if (sexp_vectorp(x)) { sexp_write_string(ctx, "#(", out); for (i=0; i<SEXP_HEAP_VECTOR_DEPTH && i<(int)sexp_vector_length(x); i++) { if (i>0) sexp_write_char(ctx, ' ', out); sexp_print_simple(ctx, sexp_vector_ref(x, i), out, depth-1); } if (i<(int)sexp_vector_length(x)) sexp_write_string(ctx, " ...", out); sexp_write_char(ctx, ')', out); } else { print_name: sexp_write_string(ctx, "#<", out); sexp_write(ctx, sexp_object_type_name(ctx, x), out); sexp_write_string(ctx, ">", out); } }
static sexp sexp_integer_to_immediate (sexp ctx, sexp self, sexp_sint_t n, sexp i, sexp dflt) { sexp x = (sexp)sexp_unbox_fixnum(i); sexp_assert_type(ctx, sexp_fixnump, SEXP_FIXNUM, i); if (sexp_pointerp(x)) return dflt; return x; }
static sexp sexp_object_size (sexp ctx, sexp self, sexp_sint_t n, sexp x) { sexp t; if ((! sexp_pointerp(x)) || (sexp_pointer_tag(x) >= sexp_context_num_types(ctx))) return SEXP_ZERO; t = sexp_object_type(ctx, x); return sexp_make_fixnum(sexp_type_size_of_object(t, x)); }
static sexp sexp_player_move_stub (sexp ctx, sexp self, sexp_sint_t n, sexp arg0, sexp arg1, sexp arg2) { sexp res; if (! (sexp_pointerp(arg0) && (sexp_pointer_tag(arg0) == sexp_unbox_fixnum(sexp_opcode_arg1_type(self))))) return sexp_type_exception(ctx, self, sexp_unbox_fixnum(sexp_opcode_arg1_type(self)), arg0); if (! sexp_exact_integerp(arg1)) return sexp_type_exception(ctx, self, SEXP_FIXNUM, arg1); if (! sexp_exact_integerp(arg2)) return sexp_type_exception(ctx, self, SEXP_FIXNUM, arg2); res = ((player_move((struct player**)sexp_cpointer_value(arg0), sexp_uint_value(arg1), sexp_uint_value(arg2))), SEXP_VOID); return res; }
sexp_uint_t sexp_allocated_bytes (sexp ctx, sexp x) { sexp_uint_t res; sexp t; if (!sexp_pointerp(x) || (sexp_pointer_tag(x) >= sexp_context_num_types(ctx))) return sexp_heap_align(1); t = sexp_object_type(ctx, x); res = sexp_type_size_of_object(t, x) + SEXP_GC_PAD; #if SEXP_USE_DEBUG_GC if (res == 0) { fprintf(stderr, SEXP_BANNER("%p zero-size object: %p"), ctx, x); return 1; } #endif return res; }
static sexp sexp_last_context (sexp ctx, sexp *cstack) { sexp res=SEXP_FALSE; #if ! SEXP_USE_BOEHM sexp p; sexp_sint_t i; sexp_heap h = sexp_context_heap(ctx); for (i=0; i<SEXP_LAST_CONTEXT_CHECK_LIMIT; i++) { p = cstack[i]; if (p && (p != ctx) && sexp_pointerp(p) && in_heap_p(h, p) && (sexp_pointer_tag(p) == SEXP_CONTEXT) && (sexp_context_heap(p) == h)) { res = p; break; } } #endif return res; }
static sexp sexp_time_3e_string_stub (sexp ctx, sexp self, sexp_sint_t n, sexp arg0) { char *err; char tmp1[64]; sexp res; sexp_gc_var1(res1); if (! (sexp_pointerp(arg0) && (sexp_pointer_tag(arg0) == sexp_unbox_fixnum(sexp_opcode_arg1_type(self))))) return sexp_type_exception(ctx, self, sexp_unbox_fixnum(sexp_opcode_arg1_type(self)), arg0); sexp_gc_preserve1(ctx, res1); err = asctime_r((struct tm*)sexp_cpointer_value(arg0), tmp1); if (!err) { res = SEXP_FALSE; } else { res1 = sexp_c_string(ctx, tmp1, -1); res = res1; } sexp_gc_release1(ctx); return res; }
static sexp sexp_type_of (sexp ctx, sexp self, sexp_sint_t n, sexp x) { if (sexp_pointerp(x)) return sexp_object_type(ctx, x); else if (sexp_fixnump(x)) return sexp_type_by_index(ctx, SEXP_FIXNUM); else if (sexp_booleanp(x)) return sexp_type_by_index(ctx, SEXP_BOOLEAN); else if (sexp_charp(x)) return sexp_type_by_index(ctx, SEXP_CHAR); #if SEXP_USE_HUFF_SYMS else if (sexp_symbolp(x)) return sexp_type_by_index(ctx, SEXP_SYMBOL); #endif #if SEXP_USE_IMMEDIATE_FLONUMS else if (sexp_flonump(x)) return sexp_type_by_index(ctx, SEXP_FLONUM); #endif else return sexp_type_by_index(ctx, SEXP_OBJECT); }
static sexp simplify (sexp ctx, sexp ast, sexp init_substs, sexp lambda) { int check; sexp ls1, ls2, p1, p2, sv; sexp_gc_var5(res, substs, tmp, app, ctx2); sexp_gc_preserve5(ctx, res, substs, tmp, app, ctx2); res = ast; /* return the ast as-is by default */ substs = init_substs; loop: switch (sexp_pointerp(res) ? sexp_pointer_tag(res) : 0) { case SEXP_PAIR: /* don't simplify the operator if it's a lambda because we simplify that as a special case below, with the appropriate substs list */ app = sexp_list1(ctx, sexp_lambdap(sexp_car(res)) ? sexp_car(res) : (tmp=simplify(ctx, sexp_car(res), substs, lambda))); sexp_pair_source(app) = sexp_pair_source(res); for (ls1=sexp_cdr(res); sexp_pairp(ls1); ls1=sexp_cdr(ls1)) { sexp_push(ctx, app, tmp=simplify(ctx, sexp_car(ls1), substs, lambda)); if (sexp_pairp(app)) sexp_pair_source(app) = sexp_pair_source(ls1); } app = sexp_nreverse(ctx, app); /* app now holds a copy of the list, and is the default result (res = app below) if we don't replace it with a simplification */ if (sexp_opcodep(sexp_car(app))) { /* opcode app - right now we just constant fold arithmetic */ if (sexp_opcode_class(sexp_car(app)) == SEXP_OPC_ARITHMETIC) { for (check=1, ls1=sexp_cdr(app); sexp_pairp(ls1); ls1=sexp_cdr(ls1)) { if (sexp_pointerp(sexp_car(ls1)) && ! sexp_litp(sexp_car(ls1))) { check = 0; break; } } if (check) { ctx2 = sexp_make_eval_context(ctx, NULL, sexp_context_env(ctx), 0, 0); sexp_generate(ctx2, 0, 0, 0, app); res = sexp_complete_bytecode(ctx2); if (! sexp_exceptionp(res)) { tmp = sexp_make_vector(ctx2, 0, SEXP_VOID); tmp = sexp_make_procedure(ctx2, SEXP_ZERO, SEXP_ZERO, res, tmp); if (! sexp_exceptionp(tmp)) { tmp = sexp_apply(ctx2, tmp, SEXP_NULL); if (! sexp_exceptionp(tmp)) app = sexp_make_lit(ctx2, tmp); } } } } } else if (lambda && sexp_lambdap(sexp_car(app))) { /* let */ p1 = NULL; p2 = sexp_lambda_params(sexp_car(app)); ls1 = app; ls2 = sexp_cdr(app); sv = sexp_lambda_sv(sexp_car(app)); if (sexp_length(ctx, p2) == sexp_length(ctx, ls2)) { for ( ; sexp_pairp(ls2); ls2=sexp_cdr(ls2), p2=sexp_cdr(p2)) { if (sexp_not(sexp_memq(ctx, sexp_car(p2), sv)) && (! sexp_pointerp(sexp_car(ls2)) || sexp_litp(sexp_car(ls2)) || (sexp_refp(sexp_car(ls2)) && sexp_lambdap(sexp_ref_loc(sexp_car(ls2))) && sexp_not(sexp_memq(ctx, sexp_ref_name(sexp_car(ls2)), sexp_lambda_sv(sexp_ref_loc(sexp_car(ls2)))))))) { tmp = sexp_cons(ctx, sexp_car(app), sexp_car(ls2)); tmp = sexp_cons(ctx, sexp_car(p2), tmp); sexp_push(ctx, substs, tmp); sexp_cdr(ls1) = sexp_cdr(ls2); if (p1) sexp_cdr(p1) = sexp_cdr(p2); else sexp_lambda_params(sexp_car(app)) = sexp_cdr(p2); } else { p1 = p2; ls1 = ls2; } } sexp_lambda_body(sexp_car(app)) = simplify(ctx, sexp_lambda_body(sexp_car(app)), substs, sexp_car(app)); if (sexp_nullp(sexp_cdr(app)) && sexp_nullp(sexp_lambda_params(sexp_car(app))) && sexp_nullp(sexp_lambda_defs(sexp_car(app)))) app = sexp_lambda_body(sexp_car(app)); } } res = app; break; case SEXP_LAMBDA: sexp_lambda_body(res) = simplify(ctx, sexp_lambda_body(res), substs, res); break; case SEXP_CND: tmp = simplify(ctx, sexp_cnd_test(res), substs, lambda); if (sexp_litp(tmp) || ! sexp_pointerp(tmp)) { res = sexp_not((sexp_litp(tmp) ? sexp_lit_value(tmp) : tmp)) ? sexp_cnd_fail(res) : sexp_cnd_pass(res); goto loop; } else { sexp_cnd_test(res) = tmp; simplify_it(sexp_cnd_pass(res)); simplify_it(sexp_cnd_fail(res)); } break; case SEXP_REF: tmp = sexp_ref_name(res); for (ls1=substs; sexp_pairp(ls1); ls1=sexp_cdr(ls1)) if ((sexp_caar(ls1) == tmp) && (sexp_cadar(ls1) == sexp_ref_loc(res))) { res = sexp_cddar(ls1); break; } break; case SEXP_SET: simplify_it(sexp_set_value(res)); break; case SEXP_SEQ: app = SEXP_NULL; for (ls2=sexp_seq_ls(res); sexp_pairp(ls2); ls2=sexp_cdr(ls2)) { tmp = simplify(ctx, sexp_car(ls2), substs, lambda); if (! (sexp_pairp(sexp_cdr(ls2)) && (sexp_litp(tmp) || ! sexp_pointerp(tmp) || sexp_refp(tmp) || sexp_lambdap(tmp)))) sexp_push(ctx, app, tmp); } if (sexp_pairp(app) && sexp_nullp(sexp_cdr(app))) res = sexp_car(app); else sexp_seq_ls(res) = sexp_nreverse(ctx, app); break; } sexp_gc_release5(ctx); return res; }
static sexp sexp_stat_get_st_blocks (sexp ctx, sexp self, sexp_sint_t n, sexp x) { if (! (sexp_pointerp(x) && (sexp_pointer_tag(x) == sexp_unbox_fixnum(sexp_opcode_arg1_type(self))))) return sexp_type_exception(ctx, self, sexp_unbox_fixnum(sexp_opcode_arg1_type(self)), x); return sexp_make_unsigned_integer(ctx, ((struct stat*)sexp_cpointer_value(x))->st_blocks); }
static sexp sexp_dirent_get_d_name (sexp ctx, sexp self, sexp_sint_t n, sexp x) { if (! (sexp_pointerp(x) && (sexp_pointer_tag(x) == sexp_unbox_fixnum(sexp_opcode_arg1_type(self))))) return sexp_type_exception(ctx, self, sexp_unbox_fixnum(sexp_opcode_arg1_type(self)), x); return sexp_c_string(ctx, ((struct dirent*)sexp_cpointer_value(x))->d_name, -1); }
static sexp sexp_tm_get_tm_gmtoff (sexp ctx, sexp self, sexp_sint_t n, sexp x) { if (! (sexp_pointerp(x) && (sexp_pointer_tag(x) == sexp_unbox_fixnum(sexp_opcode_arg1_type(self))))) return sexp_type_exception(ctx, self, sexp_unbox_fixnum(sexp_opcode_arg1_type(self)), x); return sexp_make_integer(ctx, ((struct tm*)sexp_cpointer_value(x))->tm_gmtoff); }
static sexp sexp_timeval_get_tv_sec (sexp ctx, sexp self, sexp_sint_t n, sexp x) { if (! (sexp_pointerp(x) && (sexp_pointer_tag(x) == sexp_unbox_fixnum(sexp_opcode_arg1_type(self))))) return sexp_type_exception(ctx, self, sexp_unbox_fixnum(sexp_opcode_arg1_type(self)), x); return sexp_make_integer(ctx, sexp_shift_epoch(((struct timeval*)sexp_cpointer_value(x))->tv_sec)); }
static sexp sexp_timezone_get_tz_minuteswest (sexp ctx, sexp self, sexp_sint_t n, sexp x) { if (! (sexp_pointerp(x) && (sexp_pointer_tag(x) == sexp_unbox_fixnum(sexp_opcode_arg1_type(self))))) return sexp_type_exception(ctx, self, sexp_unbox_fixnum(sexp_opcode_arg1_type(self)), x); return sexp_make_integer(ctx, ((struct timezone*)sexp_cpointer_value(x))->tz_minuteswest); }