simplifying gc variable preservation

Adding sexp_gc_var1..6 and corresponding _preserve/release1..6
referring to fixed preservation variable names, to substantially
reduce the boilerplate on C functions which produce temporary sexp
values.  The fixed variable names are safe because we never nest
them within the same C function.  The original macros are still
available for manual naming, block local variables and cases of
more than 6 gc vars.

Consider combining var+preserve into a single macro, since splitting
them is rare.
This commit is contained in:
Alex Shinn 2009-11-01 19:48:30 +09:00
parent 445f8e9fa4
commit 576a20b3bc
4 changed files with 201 additions and 306 deletions

284
eval.c
View file

@ -31,16 +31,14 @@ static sexp sexp_make_standard_env (sexp ctx, sexp version);
static sexp sexp_compile_error(sexp ctx, char *message, sexp obj) {
sexp exn;
sexp_gc_var(ctx, irritants, s_irr);
sexp_gc_var(ctx, msg, s_msg);
sexp_gc_preserve(ctx, irritants, s_irr);
sexp_gc_preserve(ctx, msg, s_msg);
sexp_gc_var2(irritants, msg);
sexp_gc_preserve2(ctx, irritants, msg);
irritants = sexp_list1(ctx, obj);
msg = sexp_c_string(ctx, message, -1);
exn = sexp_make_exception(ctx, the_compile_error_symbol, msg, irritants,
SEXP_FALSE, (sexp_pairp(obj) ?
sexp_pair_source(obj) : SEXP_FALSE));
sexp_gc_release(ctx, irritants, s_irr);
sexp_gc_release2(ctx);
return exn;
}
@ -60,15 +58,15 @@ static sexp env_cell(sexp e, sexp key) {
}
static sexp env_cell_create(sexp ctx, sexp e, sexp key, sexp value) {
sexp_gc_var(ctx, cell, s_cell);
sexp_gc_var1(cell);
cell = env_cell(e, key);
if (! cell) {
sexp_gc_preserve(ctx, cell, s_cell);
sexp_gc_preserve1(ctx, cell);
cell = sexp_cons(ctx, key, value);
while (sexp_env_parent(e))
e = sexp_env_parent(e);
sexp_env_bindings(e) = sexp_cons(ctx, cell, sexp_env_bindings(e));
sexp_gc_release(ctx, cell, s_cell);
sexp_gc_release1(ctx);
}
return cell;
}
@ -83,26 +81,24 @@ static sexp env_global_ref(sexp e, sexp key, sexp dflt) {
void env_define(sexp ctx, sexp e, sexp key, sexp value) {
sexp cell = sexp_assq(ctx, key, sexp_env_bindings(e));
sexp_gc_var1(tmp);
if (sexp_immutablep(e)) {
fprintf(stderr, "ERROR: immutable environment\n");
} else {
sexp_gc_var(ctx, tmp, s_tmp);
sexp_gc_preserve(ctx, tmp, s_tmp);
sexp_gc_preserve1(ctx, tmp);
if (sexp_truep(cell))
sexp_cdr(cell) = value;
else {
tmp = sexp_cons(ctx, key, value);
sexp_push(ctx, sexp_env_bindings(e), tmp);
}
sexp_gc_release(ctx, tmp, s_tmp);
sexp_gc_release1(ctx);
}
}
static sexp extend_env (sexp ctx, sexp env, sexp vars, sexp value) {
sexp_gc_var(ctx, e, s_e);
sexp_gc_var(ctx, tmp, s_tmp);
sexp_gc_preserve(ctx, e, s_e);
sexp_gc_preserve(ctx, tmp, s_tmp);
sexp_gc_var2(e, tmp);
sexp_gc_preserve2(ctx, e, tmp);
e = sexp_alloc_type(ctx, env, SEXP_ENV);
sexp_env_parent(e) = env;
sexp_env_bindings(e) = SEXP_NULL;
@ -110,13 +106,13 @@ static sexp extend_env (sexp ctx, sexp env, sexp vars, sexp value) {
tmp = sexp_cons(ctx, sexp_car(vars), value);
sexp_push(ctx, sexp_env_bindings(e), tmp);
}
sexp_gc_release(ctx, e, s_e);
sexp_gc_release2(ctx);
return e;
}
static sexp sexp_chain_env (sexp ctx, sexp env1, sexp env2) {
sexp_gc_var(ctx, res, s_res);
sexp_gc_preserve(ctx, res, s_res);
sexp_gc_var1(res);
sexp_gc_preserve1(ctx, res);
res = env2;
if (env1 && sexp_envp(env1)) {
res = sexp_alloc_type(ctx, env, SEXP_ENV);
@ -124,16 +120,16 @@ static sexp sexp_chain_env (sexp ctx, sexp env1, sexp env2) {
sexp_env_bindings(res) = sexp_env_bindings(env1);
sexp_env_lambda(res) = sexp_env_lambda(env1);
}
sexp_gc_release(ctx, res, s_res);
sexp_gc_release1(ctx);
return res;
}
static sexp sexp_reverse_flatten_dot (sexp ctx, sexp ls) {
sexp_gc_var(ctx, res, s_res);
sexp_gc_preserve(ctx, res, s_res);
sexp_gc_var1(res);
sexp_gc_preserve1(ctx, res);
for (res=SEXP_NULL; sexp_pairp(ls); ls=sexp_cdr(ls))
sexp_push(ctx, res, sexp_car(ls));
sexp_gc_release(ctx, res, s_res);
sexp_gc_release1(ctx);
return (sexp_nullp(ls) ? res : sexp_cons(ctx, ls, res));
}
@ -285,8 +281,8 @@ static sexp sexp_make_lit(sexp ctx, sexp value) {
#define SEXP_STACK_SIZE (sexp_sizeof(stack)+sizeof(sexp)*INIT_STACK_SIZE)
sexp sexp_make_context(sexp ctx, sexp stack, sexp env) {
sexp_gc_var(ctx, res, save_res);
if (ctx) sexp_gc_preserve(ctx, res, save_res);
sexp_gc_var1(res);
if (ctx) sexp_gc_preserve1(ctx, res);
res = sexp_alloc_type(ctx, context, SEXP_CONTEXT);
if ((! stack) || (stack == SEXP_FALSE)) {
stack = sexp_alloc_tagged(ctx, SEXP_STACK_SIZE, SEXP_STACK);
@ -311,7 +307,7 @@ sexp sexp_make_context(sexp ctx, sexp stack, sexp env) {
sexp_context_top(res) = 0;
sexp_context_tailp(res) = 1;
sexp_context_tracep(res) = 0;
if (ctx) sexp_gc_release(ctx, res, save_res);
if (ctx) sexp_gc_release1(ctx);
return res;
}
@ -338,10 +334,8 @@ static sexp sexp_syntactic_closure_expr (sexp ctx, sexp x) {
static sexp sexp_strip_synclos (sexp ctx, sexp x) {
sexp res;
sexp_gc_var(ctx, kar, s_kar);
sexp_gc_var(ctx, kdr, s_kdr);
sexp_gc_preserve(ctx, kar, s_kar);
sexp_gc_preserve(ctx, kdr, s_kdr);
sexp_gc_var2(kar, kdr);
sexp_gc_preserve2(ctx, kar, kdr);
loop:
if (sexp_synclop(x)) {
x = sexp_synclo_expr(x);
@ -354,7 +348,7 @@ static sexp sexp_strip_synclos (sexp ctx, sexp x) {
} else {
res = x;
}
sexp_gc_release(ctx, kar, s_kar);
sexp_gc_release2(ctx);
return res;
}
@ -380,10 +374,8 @@ static sexp sexp_identifier_eq(sexp ctx, sexp e1, sexp id1, sexp e2, sexp id2) {
/************************* the compiler ***************************/
static sexp analyze_app (sexp ctx, sexp x) {
sexp_gc_var(ctx, res, s_res);
sexp_gc_var(ctx, tmp, s_tmp);
sexp_gc_preserve(ctx, res, s_res);
sexp_gc_preserve(ctx, tmp, s_tmp);
sexp_gc_var2(res, tmp);
sexp_gc_preserve2(ctx, res, tmp);
for (res=SEXP_NULL; sexp_pairp(x); x=sexp_cdr(x)) {
sexp_push(ctx, res, SEXP_FALSE);
tmp = analyze(ctx, sexp_car(x));
@ -394,15 +386,13 @@ static sexp analyze_app (sexp ctx, sexp x) {
sexp_car(res) = tmp;
}
}
sexp_gc_release(ctx, res, s_res);
sexp_gc_release2(ctx);
return (sexp_pairp(res) ? sexp_nreverse(ctx, res) : res);
}
static sexp analyze_seq (sexp ctx, sexp ls) {
sexp_gc_var(ctx, res, s_res);
sexp_gc_var(ctx, tmp, s_tmp);
sexp_gc_preserve(ctx, res, s_res);
sexp_gc_preserve(ctx, tmp, s_tmp);
sexp_gc_var2(res, tmp);
sexp_gc_preserve2(ctx, res, tmp);
if (sexp_nullp(ls))
res = SEXP_VOID;
else if (sexp_nullp(sexp_cdr(ls)))
@ -415,14 +405,14 @@ static sexp analyze_seq (sexp ctx, sexp ls) {
else
sexp_seq_ls(res) = tmp;
}
sexp_gc_release(ctx, res, s_res);
sexp_gc_release2(ctx);
return res;
}
static sexp analyze_var_ref (sexp ctx, sexp x) {
sexp env = sexp_context_env(ctx), res;
sexp_gc_var(ctx, cell, s_cell);
sexp_gc_preserve(ctx, cell, s_cell);
sexp_gc_var1(cell);
sexp_gc_preserve1(ctx, cell);
cell = env_cell(env, x);
if (! cell) {
if (sexp_synclop(x)) {
@ -436,16 +426,14 @@ static sexp analyze_var_ref (sexp ctx, sexp x) {
res = sexp_compile_error(ctx, "invalid use of syntax as value", x);
else
res = sexp_make_ref(ctx, x, cell);
sexp_gc_release(ctx, cell, s_cell);
sexp_gc_release1(ctx);
return res;
}
static sexp analyze_set (sexp ctx, sexp x) {
sexp res;
sexp_gc_var(ctx, ref, s_ref);
sexp_gc_var(ctx, value, s_value);
sexp_gc_preserve(ctx, ref, s_ref);
sexp_gc_preserve(ctx, value, s_value);
sexp_gc_var2(ref, value);
sexp_gc_preserve2(ctx, ref, value);
if (! (sexp_pairp(sexp_cdr(x)) && sexp_pairp(sexp_cddr(x))
&& sexp_nullp(sexp_cdddr(x)) && sexp_idp(sexp_cadr(x)))) {
res = sexp_compile_error(ctx, "bad set! syntax", x);
@ -461,7 +449,7 @@ static sexp analyze_set (sexp ctx, sexp x) {
else
res = sexp_make_set(ctx, ref, value);
}
sexp_gc_release(ctx, ref, s_ref);
sexp_gc_release2(ctx);
return res;
}
@ -469,18 +457,8 @@ static sexp analyze_set (sexp ctx, sexp x) {
static sexp analyze_lambda (sexp ctx, sexp x) {
sexp name, ls;
sexp_gc_var(ctx, res, s_res);
sexp_gc_var(ctx, body, s_body);
sexp_gc_var(ctx, tmp, s_tmp);
sexp_gc_var(ctx, value, s_value);
sexp_gc_var(ctx, defs, s_defs);
sexp_gc_var(ctx, ctx2, s_ctx2);
sexp_gc_preserve(ctx, res, s_res);
sexp_gc_preserve(ctx, body, s_body);
sexp_gc_preserve(ctx, tmp, s_tmp);
sexp_gc_preserve(ctx, value, s_value);
sexp_gc_preserve(ctx, defs, s_defs);
sexp_gc_preserve(ctx, ctx2, s_ctx2);
sexp_gc_var6(res, body, tmp, value, defs, ctx2);
sexp_gc_preserve6(ctx, res, body, tmp, value, defs, ctx2);
/* verify syntax */
if (! (sexp_pairp(sexp_cdr(x)) && sexp_pairp(sexp_cddr(x))))
sexp_return(res, sexp_compile_error(ctx, "bad lambda syntax", x));
@ -523,18 +501,14 @@ static sexp analyze_lambda (sexp ctx, sexp x) {
}
sexp_lambda_body(res) = body;
cleanup:
sexp_gc_release(ctx, res, s_res);
sexp_gc_release1(ctx);
return res;
}
static sexp analyze_if (sexp ctx, sexp x) {
sexp res, fail_expr;
sexp_gc_var(ctx, test, s_test);
sexp_gc_var(ctx, pass, s_pass);
sexp_gc_var(ctx, fail, s_fail);
sexp_gc_preserve(ctx, test, s_test);
sexp_gc_preserve(ctx, pass, s_pass);
sexp_gc_preserve(ctx, fail, s_fail);
sexp_gc_var3(test, pass, fail);
sexp_gc_preserve3(ctx, test, pass, fail);
if (! (sexp_pairp(sexp_cdr(x)) && sexp_pairp(sexp_cddr(x)))) {
res = sexp_compile_error(ctx, "bad if syntax", x);
} else {
@ -545,20 +519,14 @@ static sexp analyze_if (sexp ctx, sexp x) {
res = (sexp_exceptionp(test) ? test : sexp_exceptionp(pass) ? pass :
sexp_exceptionp(fail) ? fail : sexp_make_cnd(ctx, test, pass, fail));
}
sexp_gc_release(ctx, test, s_test);
sexp_gc_release3(ctx);
return res;
}
static sexp analyze_define (sexp ctx, sexp x) {
sexp name, res;
sexp_gc_var(ctx, ref, s_ref);
sexp_gc_var(ctx, value, s_value);
sexp_gc_var(ctx, tmp, s_tmp);
sexp_gc_var(ctx, env, s_env);
sexp_gc_preserve(ctx, ref, s_ref);
sexp_gc_preserve(ctx, value, s_value);
sexp_gc_preserve(ctx, tmp, s_tmp);
sexp_gc_preserve(ctx, env, s_env);
sexp_gc_var4(ref, value, tmp, env);
sexp_gc_preserve4(ctx, ref, value, tmp, env);
env = sexp_context_env(ctx);
if (! (sexp_pairp(sexp_cdr(x)) && sexp_pairp(sexp_cddr(x)))) {
res = sexp_compile_error(ctx, "bad define syntax", x);
@ -591,18 +559,14 @@ static sexp analyze_define (sexp ctx, sexp x) {
res = sexp_make_set(ctx, ref, value);
}
}
sexp_gc_release(ctx, ref, s_ref);
sexp_gc_release4(ctx);
return res;
}
static sexp analyze_bind_syntax (sexp ls, sexp eval_ctx, sexp bind_ctx) {
sexp res = SEXP_VOID, name;
sexp_gc_var(eval_ctx, proc, s_proc);
sexp_gc_var(eval_ctx, mac, s_mac);
sexp_gc_var(eval_ctx, tmp, s_tmp);
sexp_gc_preserve(eval_ctx, proc, s_proc);
sexp_gc_preserve(eval_ctx, mac, s_mac);
sexp_gc_preserve(eval_ctx, tmp, s_tmp);
sexp_gc_var3(proc, mac, tmp);
sexp_gc_preserve3(eval_ctx, proc, mac, tmp);
for ( ; sexp_pairp(ls); ls=sexp_cdr(ls)) {
if (! (sexp_pairp(sexp_car(ls)) && sexp_pairp(sexp_cdar(ls))
&& sexp_nullp(sexp_cddar(ls)))) {
@ -623,28 +587,24 @@ static sexp analyze_bind_syntax (sexp ls, sexp eval_ctx, sexp bind_ctx) {
}
}
}
sexp_gc_release(eval_ctx, proc, s_proc);
sexp_gc_release3(eval_ctx);
return res;
}
static sexp analyze_define_syntax (sexp ctx, sexp x) {
sexp res;
sexp_gc_var(ctx, tmp, s_tmp);
sexp_gc_preserve(ctx, tmp, s_tmp);
sexp_gc_var1(tmp);
sexp_gc_preserve1(ctx, tmp);
tmp = sexp_list1(ctx, sexp_cdr(x));
res = analyze_bind_syntax(tmp, ctx, ctx);
sexp_gc_release(ctx, tmp, s_tmp);
sexp_gc_release1(ctx);
return res;
}
static sexp analyze_let_syntax (sexp ctx, sexp x) {
sexp res;
sexp_gc_var(ctx, env, s_env);
sexp_gc_var(ctx, ctx2, s_ctx2);
sexp_gc_var(ctx, tmp, s_tmp);
sexp_gc_preserve(ctx, env, s_env);
sexp_gc_preserve(ctx, ctx2, s_ctx2);
sexp_gc_preserve(ctx, tmp, s_tmp);
sexp_gc_var3(env, ctx2, tmp);
sexp_gc_preserve3(ctx, env, ctx2, tmp);
if (! (sexp_pairp(sexp_cdr(x)) && sexp_pairp(sexp_cddr(x)))) {
res = sexp_compile_error(ctx, "bad let-syntax", x);
} else {
@ -656,34 +616,28 @@ static sexp analyze_let_syntax (sexp ctx, sexp x) {
tmp = analyze_bind_syntax(sexp_cadr(x), ctx, ctx2);
res = (sexp_exceptionp(tmp) ? tmp : analyze_seq(ctx2, sexp_cddr(x)));
}
sexp_gc_release(ctx, env, s_env);
sexp_gc_release3(ctx);
return res;
}
static sexp analyze_letrec_syntax (sexp ctx, sexp x) {
sexp res;
sexp_gc_var(ctx, tmp, s_tmp);
sexp_gc_preserve(ctx, tmp, s_tmp);
sexp_gc_var1(tmp);
sexp_gc_preserve1(ctx, tmp);
if (! (sexp_pairp(sexp_cdr(x)) && sexp_pairp(sexp_cddr(x)))) {
res = sexp_compile_error(ctx, "bad letrec-syntax", x);
} else {
tmp = analyze_bind_syntax(sexp_cadr(x), ctx, ctx);
res = (sexp_exceptionp(tmp) ? tmp : analyze_seq(ctx, sexp_cddr(x)));
}
sexp_gc_release(ctx, tmp, s_tmp);
sexp_gc_release1(ctx);
return res;
}
static sexp analyze (sexp ctx, sexp object) {
sexp op;
sexp_gc_var(ctx, res, s_res);
sexp_gc_var(ctx, tmp, s_tmp);
sexp_gc_var(ctx, x, s_x);
sexp_gc_var(ctx, cell, s_cell);
sexp_gc_preserve(ctx, res, s_res);
sexp_gc_preserve(ctx, tmp, s_tmp);
sexp_gc_preserve(ctx, x, s_x);
sexp_gc_preserve(ctx, cell, s_cell);
sexp_gc_var4(res, tmp, x, cell);
sexp_gc_preserve4(ctx, res, tmp, x, cell);
x = object;
loop:
if (sexp_pairp(x)) {
@ -771,7 +725,7 @@ static sexp analyze (sexp ctx, sexp object) {
} else {
res = x;
}
sexp_gc_release(ctx, res, s_res);
sexp_gc_release4(ctx);
return res;
}
@ -898,8 +852,8 @@ static void generate_set (sexp ctx, sexp set) {
static void generate_opcode_app (sexp ctx, sexp app) {
sexp op = sexp_car(app);
sexp_sint_t i, num_args;
sexp_gc_var(ctx, ls, s_ls);
sexp_gc_preserve(ctx, ls, s_ls);
sexp_gc_var1(ls);
sexp_gc_preserve1(ctx, ls);
num_args = sexp_unbox_integer(sexp_length(ctx, sexp_cdr(app)));
sexp_context_tailp(ctx) = 0;
@ -977,14 +931,14 @@ static void generate_opcode_app (sexp ctx, sexp app) {
emit(ctx, sexp_opcode_code(op));
sexp_context_depth(ctx) -= (num_args-1);
sexp_gc_release(ctx, ls, s_ls);
sexp_gc_release1(ctx);
}
static void generate_general_app (sexp ctx, sexp app) {
sexp_uint_t len = sexp_unbox_integer(sexp_length(ctx, sexp_cdr(app))),
tailp = sexp_context_tailp(ctx);
sexp_gc_var(ctx, ls, s_ls);
sexp_gc_preserve(ctx, ls, s_ls);
sexp_gc_var1(ls);
sexp_gc_preserve1(ctx, ls);
/* push the arguments onto the stack */
sexp_context_tailp(ctx) = 0;
@ -999,7 +953,7 @@ static void generate_general_app (sexp ctx, sexp app) {
emit_word(ctx, (sexp_uint_t)sexp_make_integer(len));
sexp_context_depth(ctx) -= len;
sexp_gc_release(ctx, ls, s_ls);
sexp_gc_release1(ctx);
}
static void generate_app (sexp ctx, sexp app) {
@ -1012,10 +966,8 @@ static void generate_app (sexp ctx, sexp app) {
static void generate_lambda (sexp ctx, sexp lambda) {
sexp ctx2, fv, ls, flags, len, ref, prev_lambda, prev_fv;
sexp_uint_t k;
sexp_gc_var(ctx, tmp, s_tmp);
sexp_gc_var(ctx, bc, s_bc);
sexp_gc_preserve(ctx, tmp, s_tmp);
sexp_gc_preserve(ctx, bc, s_bc);
sexp_gc_var2(tmp, bc);
sexp_gc_preserve2(ctx, tmp, bc);
prev_lambda = sexp_context_lambda(ctx);
prev_fv = sexp_lambdap(prev_lambda) ? sexp_lambda_fv(prev_lambda) : SEXP_NULL;
fv = sexp_lambda_fv(lambda);
@ -1073,7 +1025,7 @@ static void generate_lambda (sexp ctx, sexp lambda) {
emit_push(ctx, flags);
emit(ctx, OP_MAKE_PROCEDURE);
}
sexp_gc_release(ctx, tmp, s_tmp);
sexp_gc_release2(ctx);
}
static void generate (sexp ctx, sexp x) {
@ -1103,34 +1055,32 @@ static sexp insert_free_var (sexp ctx, sexp x, sexp fv) {
}
static sexp union_free_vars (sexp ctx, sexp fv1, sexp fv2) {
sexp_gc_var(ctx, res, s_res);
sexp_gc_var1(res);
if (sexp_nullp(fv2))
return fv1;
sexp_gc_preserve(ctx, res, s_res);
sexp_gc_preserve1(ctx, res);
for (res=fv2; sexp_pairp(fv1); fv1=sexp_cdr(fv1))
res = insert_free_var(ctx, sexp_car(fv1), res);
sexp_gc_release(ctx, res, s_res);
sexp_gc_release1(ctx);
return res;
}
static sexp diff_free_vars (sexp ctx, sexp lambda, sexp fv, sexp params) {
sexp_gc_var(ctx, res, s_res);
sexp_gc_preserve(ctx, res, s_res);
sexp_gc_var1(res);
sexp_gc_preserve1(ctx, res);
res = SEXP_NULL;
for ( ; sexp_pairp(fv); fv=sexp_cdr(fv))
if ((sexp_ref_loc(sexp_car(fv)) != lambda)
|| (sexp_memq(NULL, sexp_ref_name(sexp_car(fv)), params)
== SEXP_FALSE))
sexp_push(ctx, res, sexp_car(fv));
sexp_gc_release(ctx, res, s_res);
sexp_gc_release1(ctx);
return res;
}
static sexp free_vars (sexp ctx, sexp x, sexp fv) {
sexp_gc_var(ctx, fv1, s_fv1);
sexp_gc_var(ctx, fv2, s_fv2);
sexp_gc_preserve(ctx, fv1, s_fv1);
sexp_gc_preserve(ctx, fv2, s_fv2);
sexp_gc_var2(fv1, fv2);
sexp_gc_preserve2(ctx, fv1, fv2);
fv1 = fv;
if (sexp_lambdap(x)) {
fv1 = free_vars(ctx, sexp_lambda_body(x), SEXP_NULL);
@ -1157,34 +1107,26 @@ static sexp free_vars (sexp ctx, sexp x, sexp fv) {
} else if (sexp_synclop(x)) {
fv1 = free_vars(ctx, sexp_synclo_expr(x), fv);
}
sexp_gc_release(ctx, fv1, s_fv1);
sexp_gc_release2(ctx);
return fv1;
}
static sexp make_param_list(sexp ctx, sexp_uint_t i) {
sexp_gc_var(ctx, res, s_res);
sexp_gc_preserve(ctx, res, s_res);
sexp_gc_var1(res);
sexp_gc_preserve1(ctx, res);
res = SEXP_NULL;
for ( ; i>0; i--)
res = sexp_cons(ctx, sexp_make_integer(i), res);
sexp_gc_release(ctx, res, s_res);
sexp_gc_release1(ctx);
return res;
}
static sexp make_opcode_procedure (sexp ctx, sexp op, sexp_uint_t i) {
sexp ls, bc, res, env;
sexp_gc_var(ctx, params, s_params);
sexp_gc_var(ctx, ref, s_ref);
sexp_gc_var(ctx, refs, s_refs);
sexp_gc_var(ctx, lambda, s_lambda);
sexp_gc_var(ctx, ctx2, s_ctx2);
sexp_gc_var5(params, ref, refs, lambda, ctx2);
if (i == sexp_opcode_num_args(op) && sexp_opcode_proc(op))
return sexp_opcode_proc(op); /* return before preserving */
sexp_gc_preserve(ctx, params, s_params);
sexp_gc_preserve(ctx, ref, s_ref);
sexp_gc_preserve(ctx, refs, s_refs);
sexp_gc_preserve(ctx, lambda, s_lambda);
sexp_gc_preserve(ctx, ctx2, s_ctx2);
sexp_gc_preserve5(ctx, params, ref, refs, lambda, ctx2);
params = make_param_list(ctx, i);
lambda = sexp_make_lambda(ctx, params);
ctx2 = sexp_make_child_context(ctx, lambda);
@ -1203,7 +1145,7 @@ static sexp make_opcode_procedure (sexp ctx, sexp op, sexp_uint_t i) {
bc, SEXP_VOID);
if (i == sexp_opcode_num_args(op))
sexp_opcode_proc(op) = res;
sexp_gc_release(ctx, params, s_params);
sexp_gc_release5(ctx);
return res;
}
@ -1259,13 +1201,9 @@ sexp sexp_vm (sexp ctx, sexp proc) {
#if USE_BIGNUMS
sexp_lsint_t prod;
#endif
sexp_gc_var3(self, tmp1, tmp2);
sexp_gc_preserve3(ctx, self, tmp1, tmp2);
fp = top - 4;
sexp_gc_var(ctx, self, s_self);
sexp_gc_var(ctx, tmp1, s_tmp1);
sexp_gc_var(ctx, tmp2, s_tmp2);
sexp_gc_preserve(ctx, self, s_self);
sexp_gc_preserve(ctx, tmp1, s_tmp1);
sexp_gc_preserve(ctx, tmp2, s_tmp2);
self = proc;
loop:
@ -1954,7 +1892,7 @@ sexp sexp_vm (sexp ctx, sexp proc) {
goto loop;
end_loop:
sexp_gc_release(ctx, self, s_self);
sexp_gc_release3(ctx);
sexp_context_top(ctx) = top;
return _ARG1;
}
@ -2024,14 +1962,8 @@ void sexp_warn_undefs (sexp ctx, sexp from, sexp to, sexp out) {
sexp sexp_load (sexp ctx, sexp source, sexp env) {
sexp tmp, out;
sexp_gc_var(ctx, ctx2, s_ctx2);
sexp_gc_var(ctx, x, s_x);
sexp_gc_var(ctx, in, s_in);
sexp_gc_var(ctx, res, s_res);
sexp_gc_preserve(ctx, ctx2, s_ctx2);
sexp_gc_preserve(ctx, x, s_x);
sexp_gc_preserve(ctx, in, s_in);
sexp_gc_preserve(ctx, res, s_res);
sexp_gc_var4(ctx2, x, in, res);
sexp_gc_preserve4(ctx, ctx2, x, in, res);
res = SEXP_VOID;
in = sexp_open_input_file(ctx, source);
out = env_global_ref(env, the_cur_err_symbol, SEXP_FALSE);
@ -2061,7 +1993,7 @@ sexp sexp_load (sexp ctx, sexp source, sexp env) {
sexp_warn_undefs(ctx, sexp_env_bindings(env), tmp, out);
#endif
}
sexp_gc_release(ctx, ctx2, s_ctx2);
sexp_gc_release4(ctx);
return res;
}
@ -2222,14 +2154,8 @@ static sexp sexp_make_null_env (sexp ctx, sexp version) {
static sexp sexp_make_standard_env (sexp ctx, sexp version) {
sexp_uint_t i;
sexp ctx2, cell, sym, perr_cell, err_cell;
sexp_gc_var(ctx, e, s_e);
sexp_gc_var(ctx, op, s_op);
sexp_gc_var(ctx, tmp, s_tmp);
sexp_gc_var(ctx, err_handler, s_err);
sexp_gc_preserve(ctx, e, s_e);
sexp_gc_preserve(ctx, op, s_op);
sexp_gc_preserve(ctx, tmp, s_tmp);
sexp_gc_preserve(ctx, err_handler, s_err);
sexp_gc_var4(e, op, tmp, err_handler);
sexp_gc_preserve4(ctx, e, op, tmp, err_handler);
e = sexp_make_null_env(ctx, version);
for (i=0; i<(sizeof(opcodes)/sizeof(opcodes[0])); i++) {
op = sexp_copy_opcode(ctx, &opcodes[i]);
@ -2272,7 +2198,7 @@ static sexp sexp_make_standard_env (sexp ctx, sexp version) {
finalize_bytecode(ctx2),
tmp);
env_define(ctx2, e, the_err_handler_symbol, err_handler);
sexp_gc_release(ctx, e, s_e);
sexp_gc_release4(ctx);
return e;
}
@ -2314,14 +2240,8 @@ sexp sexp_apply (sexp ctx, sexp proc, sexp args) {
}
sexp sexp_compile (sexp ctx, sexp x) {
sexp_gc_var(ctx, ast, s_ast);
sexp_gc_var(ctx, ctx2, s_ctx2);
sexp_gc_var(ctx, vec, s_vec);
sexp_gc_var(ctx, res, s_res);
sexp_gc_preserve(ctx, ast, s_ast);
sexp_gc_preserve(ctx, ctx2, s_ctx2);
sexp_gc_preserve(ctx, vec, s_vec);
sexp_gc_preserve(ctx, res, s_res);
sexp_gc_var4(ast, ctx2, vec, res);
sexp_gc_preserve4(ctx, ast, ctx2, vec, res);
ast = analyze(ctx, x);
if (sexp_exceptionp(ast)) {
res = ast;
@ -2333,14 +2253,14 @@ sexp sexp_compile (sexp ctx, sexp x) {
res = sexp_make_procedure(ctx, sexp_make_integer(0), sexp_make_integer(0),
res, vec);
}
sexp_gc_release(ctx, ast, s_ast);
sexp_gc_release4(ctx);
return res;
}
sexp sexp_eval (sexp ctx, sexp obj, sexp env) {
sexp res, ctx2;
sexp_gc_var(ctx, thunk, s_thunk);
sexp_gc_preserve(ctx, thunk, s_thunk);
sexp_gc_var1(thunk);
sexp_gc_preserve1(ctx, thunk);
ctx2 = sexp_make_context(ctx, NULL, (env ? env : sexp_context_env(ctx)));
sexp_context_parent(ctx2) = ctx;
thunk = sexp_compile(ctx2, obj);
@ -2353,17 +2273,17 @@ sexp sexp_eval (sexp ctx, sexp obj, sexp env) {
} else {
res = sexp_apply(ctx2, thunk, SEXP_NULL);
}
sexp_gc_release(ctx, thunk, s_thunk);
sexp_gc_release1(ctx);
return res;
}
sexp sexp_eval_string (sexp ctx, char *str, sexp env) {
sexp res;
sexp_gc_var(ctx, obj, s_obj);
sexp_gc_preserve(ctx, obj, s_obj);
sexp_gc_var1(obj);
sexp_gc_preserve1(ctx, obj);
obj = sexp_read_from_string(ctx, str);
res = sexp_eval(ctx, obj, env);
sexp_gc_release(ctx, obj, s_obj);
sexp_gc_release1(ctx);
return res;
}

View file

@ -293,6 +293,27 @@ void *sexp_realloc(sexp ctx, sexp x, size_t size);
#endif
#endif
#define sexp_gc_var1(x) sexp_gc_var(ctx, x, __sexp_gc_preserver1)
#define sexp_gc_var2(x, y) sexp_gc_var1(x); sexp_gc_var(ctx, y, __sexp_gc_preserver2)
#define sexp_gc_var3(x, y, z) sexp_gc_var2(x, y); sexp_gc_var(ctx, z, __sexp_gc_preserver3)
#define sexp_gc_var4(x, y, z, w) sexp_gc_var3(x, y, z); sexp_gc_var(ctx, w, __sexp_gc_preserver4)
#define sexp_gc_var5(x, y, z, w, v) sexp_gc_var4(x, y, z, w); sexp_gc_var(ctx, v, __sexp_gc_preserver5)
#define sexp_gc_var6(x, y, z, w, v, u) sexp_gc_var5(x, y, z, w, v); sexp_gc_var(ctx, u, __sexp_gc_preserver6)
#define sexp_gc_preserve1(ctx, x) sexp_gc_preserve(ctx, x, __sexp_gc_preserver1)
#define sexp_gc_preserve2(ctx, x, y) sexp_gc_preserve1(ctx, x); sexp_gc_preserve(ctx, y, __sexp_gc_preserver2)
#define sexp_gc_preserve3(ctx, x, y, z) sexp_gc_preserve2(ctx, x, y); sexp_gc_preserve(ctx, z, __sexp_gc_preserver3)
#define sexp_gc_preserve4(ctx, x, y, z, w) sexp_gc_preserve3(ctx, x, y, z); sexp_gc_preserve(ctx, w, __sexp_gc_preserver4)
#define sexp_gc_preserve5(ctx, x, y, z, w, v) sexp_gc_preserve4(ctx, x, y, z, w); sexp_gc_preserve(ctx, v, __sexp_gc_preserver5)
#define sexp_gc_preserve6(ctx, x, y, z, w, v, u) sexp_gc_preserve5(ctx, x, y, z, w, v); sexp_gc_preserve(ctx, u, __sexp_gc_preserver6)
#define sexp_gc_release1(ctx) sexp_gc_release(ctx, NULL, __sexp_gc_preserver1)
#define sexp_gc_release2(ctx) sexp_gc_release(ctx, NULL, __sexp_gc_preserver1)
#define sexp_gc_release3(ctx) sexp_gc_release(ctx, NULL, __sexp_gc_preserver1)
#define sexp_gc_release4(ctx) sexp_gc_release(ctx, NULL, __sexp_gc_preserver1)
#define sexp_gc_release5(ctx) sexp_gc_release(ctx, NULL, __sexp_gc_preserver1)
#define sexp_gc_release6(ctx) sexp_gc_release(ctx, NULL, __sexp_gc_preserver1)
#define sexp_align(n, bits) (((n)+(1<<(bits))-1)&(((sexp_uint_t)-1)-((1<<(bits))-1)))
#define sexp_sizeof(x) (offsetof(struct sexp_struct, value) \

View file

@ -30,12 +30,8 @@ sexp sexp_fixnum_to_bignum (sexp ctx, sexp a) {
sexp sexp_double_to_bignum (sexp ctx, double f) {
int sign;
sexp_gc_var(ctx, res, s_res);
sexp_gc_var(ctx, scale, s_scale);
sexp_gc_var(ctx, tmp, s_tmp);
sexp_gc_preserve(ctx, res, s_res);
sexp_gc_preserve(ctx, scale, s_scale);
sexp_gc_preserve(ctx, tmp, s_tmp);
sexp_gc_var3(res, scale, tmp);
sexp_gc_preserve3(ctx, res, scale, tmp);
res = sexp_fixnum_to_bignum(ctx, sexp_make_integer(0));
scale = sexp_fixnum_to_bignum(ctx, sexp_make_integer(1));
sign = (f < 0 ? -1 : 1);
@ -45,7 +41,7 @@ sexp sexp_double_to_bignum (sexp ctx, double f) {
scale = sexp_bignum_fxmul(ctx, NULL, scale, 10, 0);
}
sexp_bignum_sign(res) = sign;
sexp_gc_release(ctx, res, s_res);
sexp_gc_release3(ctx);
return res;
}
@ -187,8 +183,8 @@ sexp_uint_t sexp_bignum_fxdiv (sexp ctx, sexp a, sexp_uint_t b, int offset) {
sexp sexp_read_bignum (sexp ctx, sexp in, sexp_uint_t init,
char sign, sexp_uint_t base) {
int c, digit;
sexp_gc_var(ctx, res, s_res);
sexp_gc_preserve(ctx, res, s_res);
sexp_gc_var1(res);
sexp_gc_preserve1(ctx, res);
res = sexp_make_bignum(ctx, SEXP_INIT_BIGNUM_SIZE);
sexp_bignum_sign(res) = sign;
sexp_bignum_data(res)[0] = init;
@ -209,7 +205,7 @@ sexp sexp_read_bignum (sexp ctx, sexp in, sexp_uint_t init,
sexp_make_character(c), in);
}
sexp_push_char(ctx, c, in);
sexp_gc_release(ctx, res, s_res);
sexp_gc_release1(ctx);
return sexp_bignum_normalize(res);
}
@ -224,10 +220,8 @@ static int log2i(int v) {
sexp sexp_write_bignum (sexp ctx, sexp a, sexp out, sexp_uint_t base) {
int i, str_len, lg_base = log2i(base);
char *data;
sexp_gc_var(ctx, b, s_b);
sexp_gc_var(ctx, str, s_str);
sexp_gc_preserve(ctx, b, s_b);
sexp_gc_preserve(ctx, str, s_str);
sexp_gc_var2(b, str);
sexp_gc_preserve2(ctx, b, str);
b = sexp_copy_bignum(ctx, NULL, a, 0);
sexp_bignum_sign(b) = 1;
i = str_len = (sexp_bignum_length(b)*sizeof(sexp_uint_t)*8 + lg_base - 1)
@ -242,31 +236,31 @@ sexp sexp_write_bignum (sexp ctx, sexp a, sexp out, sexp_uint_t base) {
else if (sexp_bignum_sign(a) == -1)
data[--i] = '-';
sexp_write_string(ctx, data + i, out);
sexp_gc_release(ctx, b, s_b);
sexp_gc_release2(ctx);
return SEXP_VOID;
}
/****************** bignum arithmetic *************************/
sexp sexp_bignum_add_fixnum (sexp ctx, sexp a, sexp b) {
sexp_gc_var(ctx, c, s_c);
sexp_gc_preserve(ctx, c, s_c);
sexp_gc_var1(c);
sexp_gc_preserve1(ctx, c);
c = sexp_copy_bignum(ctx, NULL, a, 0);
if (sexp_bignum_sign(c) == sexp_fx_sign(b))
c = sexp_bignum_fxadd(ctx, c, sexp_unbox_integer(sexp_fx_abs(b)));
else
c = sexp_bignum_fxsub(ctx, c, sexp_unbox_integer(sexp_fx_abs(b)));
sexp_gc_release(ctx, c, s_c);
sexp_gc_release1(ctx);
return c;
}
sexp sexp_bignum_sub_digits (sexp ctx, sexp dst, sexp a, sexp b) {
sexp_uint_t alen=sexp_bignum_hi(a), blen=sexp_bignum_hi(b),
borrow=0, i, *adata, *bdata, *cdata;
sexp_gc_var(ctx, c, s_c);
sexp_gc_var1(c);
if ((alen < blen) || ((alen == blen) && (sexp_bignum_compare_abs(a, b) < 0)))
return sexp_bignum_sub_digits(ctx, dst, b, a);
sexp_gc_preserve(ctx, c, s_c);
sexp_gc_preserve1(ctx, c);
c = ((dst && sexp_bignum_hi(dst) >= alen)
? dst : sexp_copy_bignum(ctx, NULL, a, 0));
adata = sexp_bignum_data(a);
@ -280,16 +274,16 @@ sexp sexp_bignum_sub_digits (sexp ctx, sexp dst, sexp a, sexp b) {
borrow = (cdata[i] == 0 ? 1 : 0);
cdata[i]--;
}
sexp_gc_release(ctx, c, s_c);
sexp_gc_release1(ctx);
return c;
}
sexp sexp_bignum_add_digits (sexp ctx, sexp dst, sexp a, sexp b) {
sexp_uint_t alen=sexp_bignum_hi(a), blen=sexp_bignum_hi(b),
carry=0, i, n, *adata, *bdata, *cdata;
sexp_gc_var(ctx, c, s_c);
sexp_gc_var1(c);
if (alen < blen) return sexp_bignum_add_digits(ctx, dst, b, a);
sexp_gc_preserve(ctx, c, s_c);
sexp_gc_preserve1(ctx, c);
c = ((dst && sexp_bignum_hi(dst) >= alen)
? dst : sexp_copy_bignum(ctx, NULL, a, 0));
adata = sexp_bignum_data(a);
@ -308,7 +302,7 @@ sexp sexp_bignum_add_digits (sexp ctx, sexp dst, sexp a, sexp b) {
c = sexp_copy_bignum(ctx, NULL, c, alen+1);
sexp_bignum_data(c)[alen] = 1;
}
sexp_gc_release(ctx, c, s_c);
sexp_gc_release1(ctx);
return c;
}
@ -342,11 +336,9 @@ sexp sexp_bignum_sub (sexp ctx, sexp dst, sexp a, sexp b) {
sexp sexp_bignum_mul (sexp ctx, sexp dst, sexp a, sexp b) {
sexp_uint_t alen=sexp_bignum_hi(a), blen=sexp_bignum_hi(b), i,
*bdata=sexp_bignum_data(b);
sexp_gc_var(ctx, c, s_c);
sexp_gc_var(ctx, d, s_d);
sexp_gc_var2(c, d);
if (alen < blen) return sexp_bignum_mul(ctx, dst, b, a);
sexp_gc_preserve(ctx, c, s_c);
sexp_gc_preserve(ctx, d, s_d);
sexp_gc_preserve2(ctx, c, d);
c = (dst ? dst : sexp_make_bignum(ctx, alen+blen+1));
d = sexp_make_bignum(ctx, alen+blen+1);
for (i=0; i<blen; i++) {
@ -355,7 +347,7 @@ sexp sexp_bignum_mul (sexp ctx, sexp dst, sexp a, sexp b) {
sexp_bignum_data(d)[i] = 0;
}
sexp_bignum_sign(c) = sexp_bignum_sign(a) * sexp_bignum_sign(b);
sexp_gc_release(ctx, c, s_c);
sexp_gc_release2(ctx);
return c;
}
@ -365,20 +357,12 @@ static sexp sexp_bignum_double (sexp ctx, sexp a) {
static sexp quot_step (sexp ctx, sexp *rem, sexp a, sexp b, sexp k, sexp i) {
sexp res;
sexp_gc_var(ctx, x, s_x);
sexp_gc_var(ctx, prod, s_prod);
sexp_gc_var(ctx, diff, s_diff);
sexp_gc_var(ctx, k2, s_k2);
sexp_gc_var(ctx, i2, s_i2);
sexp_gc_var5(x, prod, diff, k2, i2);
if (sexp_bignum_compare(k, a) > 0) {
*rem = a;
return sexp_fixnum_to_bignum(ctx, sexp_make_integer(0));
}
sexp_gc_preserve(ctx, x, s_x);
sexp_gc_preserve(ctx, prod, s_prod);
sexp_gc_preserve(ctx, diff, s_diff);
sexp_gc_preserve(ctx, k2, s_k2);
sexp_gc_preserve(ctx, i2, s_i2);
sexp_gc_preserve5(ctx, x, prod, diff, k2, i2);
k2 = sexp_bignum_double(ctx, k);
i2 = sexp_bignum_double(ctx, i);
x = quot_step(ctx, rem, a, b, k2, i2);
@ -391,20 +375,14 @@ static sexp quot_step (sexp ctx, sexp *rem, sexp a, sexp b, sexp k, sexp i) {
*rem = diff;
res = x;
}
sexp_gc_release(ctx, x, s_x);
sexp_gc_release5(ctx);
return res;
}
sexp sexp_bignum_quot_rem (sexp ctx, sexp *rem, sexp a, sexp b) {
sexp res;
sexp_gc_var(ctx, k, s_k);
sexp_gc_var(ctx, i, s_i);
sexp_gc_var(ctx, a1, s_a1);
sexp_gc_var(ctx, b1, s_b1);
sexp_gc_preserve(ctx, k, s_k);
sexp_gc_preserve(ctx, i, s_i);
sexp_gc_preserve(ctx, a1, s_a1);
sexp_gc_preserve(ctx, b1, s_b1);
sexp_gc_var4(k, i, a1, b1);
sexp_gc_preserve4(ctx, k, i, a1, b1);
a1 = sexp_copy_bignum(ctx, NULL, a, 0);
sexp_bignum_sign(a1) = 1;
b1 = sexp_copy_bignum(ctx, NULL, b, 0);
@ -416,16 +394,16 @@ sexp sexp_bignum_quot_rem (sexp ctx, sexp *rem, sexp a, sexp b) {
if (sexp_bignum_sign(a) < 0) {
sexp_negate(*rem);
}
sexp_gc_release(ctx, k, s_k);
sexp_gc_release4(ctx);
return res;
}
sexp sexp_bignum_quotient (sexp ctx, sexp a, sexp b) {
sexp res;
sexp_gc_var(ctx, rem, s_rem);
sexp_gc_preserve(ctx, rem, s_rem);
sexp_gc_var1(rem);
sexp_gc_preserve1(ctx, rem);
res = sexp_bignum_quot_rem(ctx, &rem, a, b);
sexp_gc_release(ctx, rem, s_rem);
sexp_gc_release1(ctx);
return res;
}
@ -437,16 +415,14 @@ sexp sexp_bignum_remainder (sexp ctx, sexp a, sexp b) {
sexp sexp_bignum_expt (sexp ctx, sexp a, sexp b) {
sexp_sint_t e = sexp_unbox_integer(sexp_fx_abs(b));
sexp_gc_var(ctx, res, s_res);
sexp_gc_var(ctx, acc, s_acc);
sexp_gc_preserve(ctx, res, s_res);
sexp_gc_preserve(ctx, acc, s_acc);
sexp_gc_var2(res, acc);
sexp_gc_preserve2(ctx, res, acc);
res = sexp_fixnum_to_bignum(ctx, sexp_make_integer(1));
acc = sexp_copy_bignum(ctx, NULL, a, 0);
for (; e; e>>=1, acc=sexp_bignum_mul(ctx, NULL, acc, acc))
if (e & 1)
res = sexp_bignum_mul(ctx, NULL, res, acc);
sexp_gc_release(ctx, res, s_res);
sexp_gc_release2(ctx);
return res;
}

112
sexp.c
View file

@ -120,48 +120,38 @@ sexp sexp_make_exception (sexp ctx, sexp kind, sexp message, sexp irritants,
sexp sexp_user_exception (sexp ctx, sexp self, char *message, sexp irritants) {
sexp res;
sexp_gc_var(ctx, sym, s_sym);
sexp_gc_var(ctx, str, s_str);
sexp_gc_var(ctx, irr, s_irr);
sexp_gc_preserve(ctx, sym, s_sym);
sexp_gc_preserve(ctx, str, s_str);
sexp_gc_preserve(ctx, irr, s_irr);
sexp_gc_var3(sym, str, irr);
sexp_gc_preserve3(ctx, sym, str, irr);
res = sexp_make_exception(ctx, sym = sexp_intern(ctx, "user"),
str = sexp_c_string(ctx, message, -1),
((sexp_pairp(irritants) || sexp_nullp(irritants))
? irritants : (irr = sexp_list1(ctx, irritants))),
self, SEXP_FALSE);
sexp_gc_release(ctx, sym, s_sym);
sexp_gc_release3(ctx);
return res;
}
sexp sexp_type_exception (sexp ctx, char *message, sexp obj) {
sexp res;
sexp_gc_var(ctx, sym, s_sym);
sexp_gc_var(ctx, str, s_str);
sexp_gc_var(ctx, irr, s_irr);
sexp_gc_preserve(ctx, sym, s_sym);
sexp_gc_preserve(ctx, str, s_str);
sexp_gc_preserve(ctx, irr, s_irr);
sexp_gc_var3(sym, str, irr);
sexp_gc_preserve3(ctx, sym, str, irr);
res = sexp_make_exception(ctx, sym = sexp_intern(ctx, "type"),
str = sexp_c_string(ctx, message, -1),
irr = sexp_list1(ctx, obj),
SEXP_FALSE, SEXP_FALSE);
sexp_gc_release(ctx, sym, s_sym);
sexp_gc_release3(ctx);
return res;
}
sexp sexp_range_exception (sexp ctx, sexp obj, sexp start, sexp end) {
sexp_gc_var(ctx, res, s_res);
sexp_gc_var(ctx, msg, s_msg);
sexp_gc_preserve(ctx, res, s_res);
sexp_gc_preserve(ctx, msg, s_msg);
sexp_gc_var2(res, msg);
sexp_gc_preserve2(ctx, res, msg);
msg = sexp_c_string(ctx, "bad index range", -1);
res = sexp_list2(ctx, start, end);
res = sexp_cons(ctx, obj, res);
res = sexp_make_exception(ctx, sexp_intern(ctx, "range"), msg, res,
SEXP_FALSE, SEXP_FALSE);
sexp_gc_release(ctx, res, s_res);
sexp_gc_release2(ctx);
return res;
}
@ -225,12 +215,8 @@ sexp sexp_print_exception (sexp ctx, sexp exn, sexp out) {
static sexp sexp_read_error (sexp ctx, char *msg, sexp irritants, sexp port) {
sexp res;
sexp_gc_var(ctx, name, s_name);
sexp_gc_var(ctx, str, s_str);
sexp_gc_var(ctx, irr, s_irr);
sexp_gc_preserve(ctx, name, s_name);
sexp_gc_preserve(ctx, str, s_str);
sexp_gc_preserve(ctx, irr, s_irr);
sexp_gc_var3(name, str, irr);
sexp_gc_preserve3(ctx, name, str, irr);
name = (sexp_port_name(port) ? sexp_port_name(port) : SEXP_FALSE);
name = sexp_cons(ctx, name, sexp_make_integer(sexp_port_line(port)));
str = sexp_c_string(ctx, msg, -1);
@ -238,7 +224,7 @@ static sexp sexp_read_error (sexp ctx, char *msg, sexp irritants, sexp port) {
? irritants : sexp_list1(ctx, irritants));
res = sexp_make_exception(ctx, the_read_error_symbol,
str, irr, SEXP_FALSE, name);
sexp_gc_release(ctx, name, s_name);
sexp_gc_release3(ctx);
return res;
}
@ -253,11 +239,11 @@ sexp sexp_cons (sexp ctx, sexp head, sexp tail) {
}
sexp sexp_list2 (sexp ctx, sexp a, sexp b) {
sexp_gc_var(ctx, res, s_res);
sexp_gc_preserve(ctx, res, s_res);
sexp_gc_var1(res);
sexp_gc_preserve1(ctx, res);
res = sexp_cons(ctx, b, SEXP_NULL);
res = sexp_cons(ctx, a, res);
sexp_gc_release(ctx, res, s_res);
sexp_gc_release1(ctx);
return res;
}
@ -294,11 +280,11 @@ sexp sexp_assq (sexp ctx, sexp x, sexp ls) {
}
sexp sexp_reverse (sexp ctx, sexp ls) {
sexp_gc_var(ctx, res, s_res);
sexp_gc_preserve(ctx, res, s_res);
sexp_gc_var1(res);
sexp_gc_preserve1(ctx, res);
for (res=SEXP_NULL; sexp_pairp(ls); ls=sexp_cdr(ls))
res = sexp_cons(ctx, sexp_car(ls), res);
sexp_gc_release(ctx, res, s_res);
sexp_gc_release1(ctx);
return res;
}
@ -321,14 +307,12 @@ sexp sexp_nreverse (sexp ctx, sexp ls) {
}
sexp sexp_append2 (sexp ctx, sexp a, sexp b) {
sexp_gc_var(ctx, a1, s_a1);
sexp_gc_var(ctx, b1, s_b1);
sexp_gc_preserve(ctx, a1, s_a1);
sexp_gc_preserve(ctx, b1, s_b1);
sexp_gc_var2(a1, b1);
sexp_gc_preserve2(ctx, a1, b1);
b1 = b;
for (a1=sexp_reverse(ctx, a); sexp_pairp(a1); a1=sexp_cdr(a1))
b1 = sexp_cons(ctx, sexp_car(a1), b1);
sexp_gc_release(ctx, a1, s_a1);
sexp_gc_release2(ctx);
return b1;
}
@ -493,7 +477,7 @@ sexp sexp_intern(sexp ctx, char *str) {
sexp_uint_t len, res=FNV_OFFSET_BASIS, space=3, newbits, bucket;
char c, *p=str;
sexp ls;
sexp_gc_var(ctx, sym, s_sym);
sexp_gc_var1(sym);
#if USE_HUFF_SYMS
res = 0;
@ -521,11 +505,11 @@ sexp sexp_intern(sexp ctx, char *str) {
return sexp_car(ls);
/* not found, make a new symbol */
sexp_gc_preserve(ctx, sym, s_sym);
sexp_gc_preserve1(ctx, sym);
sym = sexp_alloc_type(ctx, symbol, SEXP_SYMBOL);
sexp_symbol_string(sym) = sexp_c_string(ctx, str, len);
sexp_push(ctx, sexp_symbol_table[bucket], sym);
sexp_gc_release(ctx, sym, s_sym);
sexp_gc_release1(ctx);
return sym;
}
@ -625,8 +609,8 @@ off_t sstream_seek (void *vec, off_t offset, int whence) {
sexp sexp_make_input_string_port (sexp ctx, sexp str) {
FILE *in;
sexp res;
sexp_gc_var(ctx, cookie, s_cookie);
sexp_gc_preserve(ctx, cookie, s_cookie);
sexp_gc_var1(cookie);
sexp_gc_preserve1(ctx, cookie);
cookie = sexp_make_vector(ctx, sexp_make_integer(4), SEXP_VOID);
sexp_stream_ctx(cookie) = ctx;
sexp_stream_buf(cookie) = str;
@ -635,15 +619,15 @@ sexp sexp_make_input_string_port (sexp ctx, sexp str) {
in = funopen(cookie, &sstream_read, NULL, &sstream_seek, NULL);
res = sexp_make_input_port(ctx, in, SEXP_FALSE);
sexp_port_cookie(res) = cookie;
sexp_gc_release(ctx, cookie, s_cookie);
sexp_gc_release1(ctx);
return res;
}
sexp sexp_make_output_string_port (sexp ctx) {
FILE *out;
sexp res, size;
sexp_gc_var(ctx, cookie, s_cookie);
sexp_gc_preserve(ctx, cookie, s_cookie);
sexp_gc_var1(cookie);
sexp_gc_preserve1(ctx, cookie);
size = sexp_make_integer(SEXP_INIT_STRING_PORT_SIZE);
cookie = sexp_make_vector(ctx, sexp_make_integer(4), SEXP_VOID);
sexp_stream_ctx(cookie) = ctx;
@ -653,7 +637,7 @@ sexp sexp_make_output_string_port (sexp ctx) {
out = funopen(cookie, NULL, &sstream_write, &sstream_seek, NULL);
res = sexp_make_output_port(ctx, out, SEXP_FALSE);
sexp_port_cookie(res) = cookie;
sexp_gc_release(ctx, cookie, s_cookie);
sexp_gc_release1(ctx);
return res;
}
@ -727,7 +711,7 @@ sexp sexp_buffered_write_string (sexp ctx, char *str, sexp p) {
}
sexp sexp_buffered_flush (sexp ctx, sexp p) {
sexp_gc_var(ctx, tmp, s_tmp);
sexp_gc_var1(tmp);
if (! sexp_oportp(p))
return sexp_type_exception(ctx, "not an output-port", p);
else if (! sexp_port_openp(p))
@ -737,10 +721,10 @@ sexp sexp_buffered_flush (sexp ctx, sexp p) {
fwrite(sexp_port_buf(p), 1, sexp_port_offset(p), sexp_port_stream(p));
fflush(sexp_port_stream(p));
} else if (sexp_port_offset(p) > 0) {
sexp_gc_preserve(ctx, tmp, s_tmp);
sexp_gc_preserve1(ctx, tmp);
tmp = sexp_c_string(ctx, sexp_port_buf(p), sexp_port_offset(p));
sexp_push(ctx, sexp_port_cookie(p), tmp);
sexp_gc_release(ctx, tmp, s_tmp);
sexp_gc_release1(ctx);
}
sexp_port_offset(p) = 0;
return SEXP_VOID;
@ -767,10 +751,8 @@ sexp sexp_make_output_string_port (sexp ctx) {
sexp sexp_get_output_string (sexp ctx, sexp out) {
sexp res;
sexp_gc_var(ctx, ls, s_ls);
sexp_gc_var(ctx, tmp, s_tmp);
sexp_gc_preserve(ctx, ls, s_ls);
sexp_gc_preserve(ctx, tmp, s_tmp);
sexp_gc_var2(ls, tmp);
sexp_gc_preserve2(ctx, ls, tmp);
if (sexp_port_offset(out) > 0) {
tmp = sexp_c_string(ctx, sexp_port_buf(out), sexp_port_offset(out));
ls = sexp_cons(ctx, tmp, sexp_port_cookie(out));
@ -778,7 +760,7 @@ sexp sexp_get_output_string (sexp ctx, sexp out) {
ls = sexp_port_cookie(out);
}
res = sexp_string_concatenate(ctx, ls);
sexp_gc_release(ctx, ls, s_ls);
sexp_gc_release2(ctx);
return res;
}
@ -1109,10 +1091,8 @@ sexp sexp_read_raw (sexp ctx, sexp in) {
char *str;
int c1, c2, line;
sexp tmp2;
sexp_gc_var(ctx, res, s_res);
sexp_gc_var(ctx, tmp, s_tmp);
sexp_gc_preserve(ctx, res, s_res);
sexp_gc_preserve(ctx, tmp, s_tmp);
sexp_gc_var2(res, tmp);
sexp_gc_preserve2(ctx, res, tmp);
scan_loop:
switch (c1 = sexp_read_char(ctx, in)) {
@ -1355,7 +1335,7 @@ sexp sexp_read_raw (sexp ctx, sexp in) {
if (sexp_port_sourcep(in) && sexp_pointerp(res))
sexp_immutablep(res) = 1;
sexp_gc_release(ctx, res, s_res);
sexp_gc_release2(ctx);
return res;
}
@ -1370,25 +1350,23 @@ sexp sexp_read (sexp ctx, sexp in) {
sexp sexp_read_from_string(sexp ctx, char *str) {
sexp res;
sexp_gc_var(ctx, s, s_s);
sexp_gc_var(ctx, in, s_in);
sexp_gc_preserve(ctx, s, s_s);
sexp_gc_preserve(ctx, in, s_in);
sexp_gc_var2(s, in);
sexp_gc_preserve2(ctx, s, in);
s = sexp_c_string(ctx, str, -1);
in = sexp_make_input_string_port(ctx, s);
res = sexp_read(ctx, in);
sexp_gc_release(ctx, s, s_s);
sexp_gc_release2(ctx);
return res;
}
sexp sexp_write_to_string(sexp ctx, sexp obj) {
sexp str;
sexp_gc_var(ctx, out, s_out);
sexp_gc_preserve(ctx, out, s_out);
sexp_gc_var1(out);
sexp_gc_preserve1(ctx, out);
out = sexp_make_output_string_port(ctx);
sexp_write(ctx, obj, out);
str = sexp_get_output_string(ctx, out);
sexp_gc_release(ctx, out, s_out);
sexp_gc_release1(ctx);
return str;
}