mirror of
https://github.com/ashinn/chibi-scheme.git
synced 2025-05-20 06:09:18 +02:00
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:
parent
445f8e9fa4
commit
576a20b3bc
4 changed files with 201 additions and 306 deletions
284
eval.c
284
eval.c
|
@ -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) {
|
static sexp sexp_compile_error(sexp ctx, char *message, sexp obj) {
|
||||||
sexp exn;
|
sexp exn;
|
||||||
sexp_gc_var(ctx, irritants, s_irr);
|
sexp_gc_var2(irritants, msg);
|
||||||
sexp_gc_var(ctx, msg, s_msg);
|
sexp_gc_preserve2(ctx, irritants, msg);
|
||||||
sexp_gc_preserve(ctx, irritants, s_irr);
|
|
||||||
sexp_gc_preserve(ctx, msg, s_msg);
|
|
||||||
irritants = sexp_list1(ctx, obj);
|
irritants = sexp_list1(ctx, obj);
|
||||||
msg = sexp_c_string(ctx, message, -1);
|
msg = sexp_c_string(ctx, message, -1);
|
||||||
exn = sexp_make_exception(ctx, the_compile_error_symbol, msg, irritants,
|
exn = sexp_make_exception(ctx, the_compile_error_symbol, msg, irritants,
|
||||||
SEXP_FALSE, (sexp_pairp(obj) ?
|
SEXP_FALSE, (sexp_pairp(obj) ?
|
||||||
sexp_pair_source(obj) : SEXP_FALSE));
|
sexp_pair_source(obj) : SEXP_FALSE));
|
||||||
sexp_gc_release(ctx, irritants, s_irr);
|
sexp_gc_release2(ctx);
|
||||||
return exn;
|
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) {
|
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);
|
cell = env_cell(e, key);
|
||||||
if (! cell) {
|
if (! cell) {
|
||||||
sexp_gc_preserve(ctx, cell, s_cell);
|
sexp_gc_preserve1(ctx, cell);
|
||||||
cell = sexp_cons(ctx, key, value);
|
cell = sexp_cons(ctx, key, value);
|
||||||
while (sexp_env_parent(e))
|
while (sexp_env_parent(e))
|
||||||
e = sexp_env_parent(e);
|
e = sexp_env_parent(e);
|
||||||
sexp_env_bindings(e) = sexp_cons(ctx, cell, sexp_env_bindings(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;
|
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) {
|
void env_define(sexp ctx, sexp e, sexp key, sexp value) {
|
||||||
sexp cell = sexp_assq(ctx, key, sexp_env_bindings(e));
|
sexp cell = sexp_assq(ctx, key, sexp_env_bindings(e));
|
||||||
|
sexp_gc_var1(tmp);
|
||||||
if (sexp_immutablep(e)) {
|
if (sexp_immutablep(e)) {
|
||||||
fprintf(stderr, "ERROR: immutable environment\n");
|
fprintf(stderr, "ERROR: immutable environment\n");
|
||||||
} else {
|
} else {
|
||||||
sexp_gc_var(ctx, tmp, s_tmp);
|
sexp_gc_preserve1(ctx, tmp);
|
||||||
sexp_gc_preserve(ctx, tmp, s_tmp);
|
|
||||||
if (sexp_truep(cell))
|
if (sexp_truep(cell))
|
||||||
sexp_cdr(cell) = value;
|
sexp_cdr(cell) = value;
|
||||||
else {
|
else {
|
||||||
tmp = sexp_cons(ctx, key, value);
|
tmp = sexp_cons(ctx, key, value);
|
||||||
sexp_push(ctx, sexp_env_bindings(e), tmp);
|
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) {
|
static sexp extend_env (sexp ctx, sexp env, sexp vars, sexp value) {
|
||||||
sexp_gc_var(ctx, e, s_e);
|
sexp_gc_var2(e, tmp);
|
||||||
sexp_gc_var(ctx, tmp, s_tmp);
|
sexp_gc_preserve2(ctx, e, tmp);
|
||||||
sexp_gc_preserve(ctx, e, s_e);
|
|
||||||
sexp_gc_preserve(ctx, tmp, s_tmp);
|
|
||||||
e = sexp_alloc_type(ctx, env, SEXP_ENV);
|
e = sexp_alloc_type(ctx, env, SEXP_ENV);
|
||||||
sexp_env_parent(e) = env;
|
sexp_env_parent(e) = env;
|
||||||
sexp_env_bindings(e) = SEXP_NULL;
|
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);
|
tmp = sexp_cons(ctx, sexp_car(vars), value);
|
||||||
sexp_push(ctx, sexp_env_bindings(e), tmp);
|
sexp_push(ctx, sexp_env_bindings(e), tmp);
|
||||||
}
|
}
|
||||||
sexp_gc_release(ctx, e, s_e);
|
sexp_gc_release2(ctx);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
static sexp sexp_chain_env (sexp ctx, sexp env1, sexp env2) {
|
static sexp sexp_chain_env (sexp ctx, sexp env1, sexp env2) {
|
||||||
sexp_gc_var(ctx, res, s_res);
|
sexp_gc_var1(res);
|
||||||
sexp_gc_preserve(ctx, res, s_res);
|
sexp_gc_preserve1(ctx, res);
|
||||||
res = env2;
|
res = env2;
|
||||||
if (env1 && sexp_envp(env1)) {
|
if (env1 && sexp_envp(env1)) {
|
||||||
res = sexp_alloc_type(ctx, env, SEXP_ENV);
|
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_bindings(res) = sexp_env_bindings(env1);
|
||||||
sexp_env_lambda(res) = sexp_env_lambda(env1);
|
sexp_env_lambda(res) = sexp_env_lambda(env1);
|
||||||
}
|
}
|
||||||
sexp_gc_release(ctx, res, s_res);
|
sexp_gc_release1(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static sexp sexp_reverse_flatten_dot (sexp ctx, sexp ls) {
|
static sexp sexp_reverse_flatten_dot (sexp ctx, sexp ls) {
|
||||||
sexp_gc_var(ctx, res, s_res);
|
sexp_gc_var1(res);
|
||||||
sexp_gc_preserve(ctx, res, s_res);
|
sexp_gc_preserve1(ctx, res);
|
||||||
for (res=SEXP_NULL; sexp_pairp(ls); ls=sexp_cdr(ls))
|
for (res=SEXP_NULL; sexp_pairp(ls); ls=sexp_cdr(ls))
|
||||||
sexp_push(ctx, res, sexp_car(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));
|
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)
|
#define SEXP_STACK_SIZE (sexp_sizeof(stack)+sizeof(sexp)*INIT_STACK_SIZE)
|
||||||
|
|
||||||
sexp sexp_make_context(sexp ctx, sexp stack, sexp env) {
|
sexp sexp_make_context(sexp ctx, sexp stack, sexp env) {
|
||||||
sexp_gc_var(ctx, res, save_res);
|
sexp_gc_var1(res);
|
||||||
if (ctx) sexp_gc_preserve(ctx, res, save_res);
|
if (ctx) sexp_gc_preserve1(ctx, res);
|
||||||
res = sexp_alloc_type(ctx, context, SEXP_CONTEXT);
|
res = sexp_alloc_type(ctx, context, SEXP_CONTEXT);
|
||||||
if ((! stack) || (stack == SEXP_FALSE)) {
|
if ((! stack) || (stack == SEXP_FALSE)) {
|
||||||
stack = sexp_alloc_tagged(ctx, SEXP_STACK_SIZE, SEXP_STACK);
|
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_top(res) = 0;
|
||||||
sexp_context_tailp(res) = 1;
|
sexp_context_tailp(res) = 1;
|
||||||
sexp_context_tracep(res) = 0;
|
sexp_context_tracep(res) = 0;
|
||||||
if (ctx) sexp_gc_release(ctx, res, save_res);
|
if (ctx) sexp_gc_release1(ctx);
|
||||||
return res;
|
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) {
|
static sexp sexp_strip_synclos (sexp ctx, sexp x) {
|
||||||
sexp res;
|
sexp res;
|
||||||
sexp_gc_var(ctx, kar, s_kar);
|
sexp_gc_var2(kar, kdr);
|
||||||
sexp_gc_var(ctx, kdr, s_kdr);
|
sexp_gc_preserve2(ctx, kar, kdr);
|
||||||
sexp_gc_preserve(ctx, kar, s_kar);
|
|
||||||
sexp_gc_preserve(ctx, kdr, s_kdr);
|
|
||||||
loop:
|
loop:
|
||||||
if (sexp_synclop(x)) {
|
if (sexp_synclop(x)) {
|
||||||
x = sexp_synclo_expr(x);
|
x = sexp_synclo_expr(x);
|
||||||
|
@ -354,7 +348,7 @@ static sexp sexp_strip_synclos (sexp ctx, sexp x) {
|
||||||
} else {
|
} else {
|
||||||
res = x;
|
res = x;
|
||||||
}
|
}
|
||||||
sexp_gc_release(ctx, kar, s_kar);
|
sexp_gc_release2(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,10 +374,8 @@ static sexp sexp_identifier_eq(sexp ctx, sexp e1, sexp id1, sexp e2, sexp id2) {
|
||||||
/************************* the compiler ***************************/
|
/************************* the compiler ***************************/
|
||||||
|
|
||||||
static sexp analyze_app (sexp ctx, sexp x) {
|
static sexp analyze_app (sexp ctx, sexp x) {
|
||||||
sexp_gc_var(ctx, res, s_res);
|
sexp_gc_var2(res, tmp);
|
||||||
sexp_gc_var(ctx, tmp, s_tmp);
|
sexp_gc_preserve2(ctx, res, tmp);
|
||||||
sexp_gc_preserve(ctx, res, s_res);
|
|
||||||
sexp_gc_preserve(ctx, tmp, s_tmp);
|
|
||||||
for (res=SEXP_NULL; sexp_pairp(x); x=sexp_cdr(x)) {
|
for (res=SEXP_NULL; sexp_pairp(x); x=sexp_cdr(x)) {
|
||||||
sexp_push(ctx, res, SEXP_FALSE);
|
sexp_push(ctx, res, SEXP_FALSE);
|
||||||
tmp = analyze(ctx, sexp_car(x));
|
tmp = analyze(ctx, sexp_car(x));
|
||||||
|
@ -394,15 +386,13 @@ static sexp analyze_app (sexp ctx, sexp x) {
|
||||||
sexp_car(res) = tmp;
|
sexp_car(res) = tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sexp_gc_release(ctx, res, s_res);
|
sexp_gc_release2(ctx);
|
||||||
return (sexp_pairp(res) ? sexp_nreverse(ctx, res) : res);
|
return (sexp_pairp(res) ? sexp_nreverse(ctx, res) : res);
|
||||||
}
|
}
|
||||||
|
|
||||||
static sexp analyze_seq (sexp ctx, sexp ls) {
|
static sexp analyze_seq (sexp ctx, sexp ls) {
|
||||||
sexp_gc_var(ctx, res, s_res);
|
sexp_gc_var2(res, tmp);
|
||||||
sexp_gc_var(ctx, tmp, s_tmp);
|
sexp_gc_preserve2(ctx, res, tmp);
|
||||||
sexp_gc_preserve(ctx, res, s_res);
|
|
||||||
sexp_gc_preserve(ctx, tmp, s_tmp);
|
|
||||||
if (sexp_nullp(ls))
|
if (sexp_nullp(ls))
|
||||||
res = SEXP_VOID;
|
res = SEXP_VOID;
|
||||||
else if (sexp_nullp(sexp_cdr(ls)))
|
else if (sexp_nullp(sexp_cdr(ls)))
|
||||||
|
@ -415,14 +405,14 @@ static sexp analyze_seq (sexp ctx, sexp ls) {
|
||||||
else
|
else
|
||||||
sexp_seq_ls(res) = tmp;
|
sexp_seq_ls(res) = tmp;
|
||||||
}
|
}
|
||||||
sexp_gc_release(ctx, res, s_res);
|
sexp_gc_release2(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static sexp analyze_var_ref (sexp ctx, sexp x) {
|
static sexp analyze_var_ref (sexp ctx, sexp x) {
|
||||||
sexp env = sexp_context_env(ctx), res;
|
sexp env = sexp_context_env(ctx), res;
|
||||||
sexp_gc_var(ctx, cell, s_cell);
|
sexp_gc_var1(cell);
|
||||||
sexp_gc_preserve(ctx, cell, s_cell);
|
sexp_gc_preserve1(ctx, cell);
|
||||||
cell = env_cell(env, x);
|
cell = env_cell(env, x);
|
||||||
if (! cell) {
|
if (! cell) {
|
||||||
if (sexp_synclop(x)) {
|
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);
|
res = sexp_compile_error(ctx, "invalid use of syntax as value", x);
|
||||||
else
|
else
|
||||||
res = sexp_make_ref(ctx, x, cell);
|
res = sexp_make_ref(ctx, x, cell);
|
||||||
sexp_gc_release(ctx, cell, s_cell);
|
sexp_gc_release1(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static sexp analyze_set (sexp ctx, sexp x) {
|
static sexp analyze_set (sexp ctx, sexp x) {
|
||||||
sexp res;
|
sexp res;
|
||||||
sexp_gc_var(ctx, ref, s_ref);
|
sexp_gc_var2(ref, value);
|
||||||
sexp_gc_var(ctx, value, s_value);
|
sexp_gc_preserve2(ctx, ref, value);
|
||||||
sexp_gc_preserve(ctx, ref, s_ref);
|
|
||||||
sexp_gc_preserve(ctx, value, s_value);
|
|
||||||
if (! (sexp_pairp(sexp_cdr(x)) && sexp_pairp(sexp_cddr(x))
|
if (! (sexp_pairp(sexp_cdr(x)) && sexp_pairp(sexp_cddr(x))
|
||||||
&& sexp_nullp(sexp_cdddr(x)) && sexp_idp(sexp_cadr(x)))) {
|
&& sexp_nullp(sexp_cdddr(x)) && sexp_idp(sexp_cadr(x)))) {
|
||||||
res = sexp_compile_error(ctx, "bad set! syntax", x);
|
res = sexp_compile_error(ctx, "bad set! syntax", x);
|
||||||
|
@ -461,7 +449,7 @@ static sexp analyze_set (sexp ctx, sexp x) {
|
||||||
else
|
else
|
||||||
res = sexp_make_set(ctx, ref, value);
|
res = sexp_make_set(ctx, ref, value);
|
||||||
}
|
}
|
||||||
sexp_gc_release(ctx, ref, s_ref);
|
sexp_gc_release2(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -469,18 +457,8 @@ static sexp analyze_set (sexp ctx, sexp x) {
|
||||||
|
|
||||||
static sexp analyze_lambda (sexp ctx, sexp x) {
|
static sexp analyze_lambda (sexp ctx, sexp x) {
|
||||||
sexp name, ls;
|
sexp name, ls;
|
||||||
sexp_gc_var(ctx, res, s_res);
|
sexp_gc_var6(res, body, tmp, value, defs, ctx2);
|
||||||
sexp_gc_var(ctx, body, s_body);
|
sexp_gc_preserve6(ctx, res, body, tmp, value, defs, ctx2);
|
||||||
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);
|
|
||||||
/* verify syntax */
|
/* verify syntax */
|
||||||
if (! (sexp_pairp(sexp_cdr(x)) && sexp_pairp(sexp_cddr(x))))
|
if (! (sexp_pairp(sexp_cdr(x)) && sexp_pairp(sexp_cddr(x))))
|
||||||
sexp_return(res, sexp_compile_error(ctx, "bad lambda syntax", 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;
|
sexp_lambda_body(res) = body;
|
||||||
cleanup:
|
cleanup:
|
||||||
sexp_gc_release(ctx, res, s_res);
|
sexp_gc_release1(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static sexp analyze_if (sexp ctx, sexp x) {
|
static sexp analyze_if (sexp ctx, sexp x) {
|
||||||
sexp res, fail_expr;
|
sexp res, fail_expr;
|
||||||
sexp_gc_var(ctx, test, s_test);
|
sexp_gc_var3(test, pass, fail);
|
||||||
sexp_gc_var(ctx, pass, s_pass);
|
sexp_gc_preserve3(ctx, test, pass, fail);
|
||||||
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);
|
|
||||||
if (! (sexp_pairp(sexp_cdr(x)) && sexp_pairp(sexp_cddr(x)))) {
|
if (! (sexp_pairp(sexp_cdr(x)) && sexp_pairp(sexp_cddr(x)))) {
|
||||||
res = sexp_compile_error(ctx, "bad if syntax", x);
|
res = sexp_compile_error(ctx, "bad if syntax", x);
|
||||||
} else {
|
} else {
|
||||||
|
@ -545,20 +519,14 @@ static sexp analyze_if (sexp ctx, sexp x) {
|
||||||
res = (sexp_exceptionp(test) ? test : sexp_exceptionp(pass) ? pass :
|
res = (sexp_exceptionp(test) ? test : sexp_exceptionp(pass) ? pass :
|
||||||
sexp_exceptionp(fail) ? fail : sexp_make_cnd(ctx, test, pass, fail));
|
sexp_exceptionp(fail) ? fail : sexp_make_cnd(ctx, test, pass, fail));
|
||||||
}
|
}
|
||||||
sexp_gc_release(ctx, test, s_test);
|
sexp_gc_release3(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static sexp analyze_define (sexp ctx, sexp x) {
|
static sexp analyze_define (sexp ctx, sexp x) {
|
||||||
sexp name, res;
|
sexp name, res;
|
||||||
sexp_gc_var(ctx, ref, s_ref);
|
sexp_gc_var4(ref, value, tmp, env);
|
||||||
sexp_gc_var(ctx, value, s_value);
|
sexp_gc_preserve4(ctx, ref, value, tmp, env);
|
||||||
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);
|
|
||||||
env = sexp_context_env(ctx);
|
env = sexp_context_env(ctx);
|
||||||
if (! (sexp_pairp(sexp_cdr(x)) && sexp_pairp(sexp_cddr(x)))) {
|
if (! (sexp_pairp(sexp_cdr(x)) && sexp_pairp(sexp_cddr(x)))) {
|
||||||
res = sexp_compile_error(ctx, "bad define syntax", 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);
|
res = sexp_make_set(ctx, ref, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sexp_gc_release(ctx, ref, s_ref);
|
sexp_gc_release4(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static sexp analyze_bind_syntax (sexp ls, sexp eval_ctx, sexp bind_ctx) {
|
static sexp analyze_bind_syntax (sexp ls, sexp eval_ctx, sexp bind_ctx) {
|
||||||
sexp res = SEXP_VOID, name;
|
sexp res = SEXP_VOID, name;
|
||||||
sexp_gc_var(eval_ctx, proc, s_proc);
|
sexp_gc_var3(proc, mac, tmp);
|
||||||
sexp_gc_var(eval_ctx, mac, s_mac);
|
sexp_gc_preserve3(eval_ctx, proc, mac, tmp);
|
||||||
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);
|
|
||||||
for ( ; sexp_pairp(ls); ls=sexp_cdr(ls)) {
|
for ( ; sexp_pairp(ls); ls=sexp_cdr(ls)) {
|
||||||
if (! (sexp_pairp(sexp_car(ls)) && sexp_pairp(sexp_cdar(ls))
|
if (! (sexp_pairp(sexp_car(ls)) && sexp_pairp(sexp_cdar(ls))
|
||||||
&& sexp_nullp(sexp_cddar(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;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static sexp analyze_define_syntax (sexp ctx, sexp x) {
|
static sexp analyze_define_syntax (sexp ctx, sexp x) {
|
||||||
sexp res;
|
sexp res;
|
||||||
sexp_gc_var(ctx, tmp, s_tmp);
|
sexp_gc_var1(tmp);
|
||||||
sexp_gc_preserve(ctx, tmp, s_tmp);
|
sexp_gc_preserve1(ctx, tmp);
|
||||||
tmp = sexp_list1(ctx, sexp_cdr(x));
|
tmp = sexp_list1(ctx, sexp_cdr(x));
|
||||||
res = analyze_bind_syntax(tmp, ctx, ctx);
|
res = analyze_bind_syntax(tmp, ctx, ctx);
|
||||||
sexp_gc_release(ctx, tmp, s_tmp);
|
sexp_gc_release1(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static sexp analyze_let_syntax (sexp ctx, sexp x) {
|
static sexp analyze_let_syntax (sexp ctx, sexp x) {
|
||||||
sexp res;
|
sexp res;
|
||||||
sexp_gc_var(ctx, env, s_env);
|
sexp_gc_var3(env, ctx2, tmp);
|
||||||
sexp_gc_var(ctx, ctx2, s_ctx2);
|
sexp_gc_preserve3(ctx, env, ctx2, tmp);
|
||||||
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);
|
|
||||||
if (! (sexp_pairp(sexp_cdr(x)) && sexp_pairp(sexp_cddr(x)))) {
|
if (! (sexp_pairp(sexp_cdr(x)) && sexp_pairp(sexp_cddr(x)))) {
|
||||||
res = sexp_compile_error(ctx, "bad let-syntax", x);
|
res = sexp_compile_error(ctx, "bad let-syntax", x);
|
||||||
} else {
|
} else {
|
||||||
|
@ -656,34 +616,28 @@ static sexp analyze_let_syntax (sexp ctx, sexp x) {
|
||||||
tmp = analyze_bind_syntax(sexp_cadr(x), ctx, ctx2);
|
tmp = analyze_bind_syntax(sexp_cadr(x), ctx, ctx2);
|
||||||
res = (sexp_exceptionp(tmp) ? tmp : analyze_seq(ctx2, sexp_cddr(x)));
|
res = (sexp_exceptionp(tmp) ? tmp : analyze_seq(ctx2, sexp_cddr(x)));
|
||||||
}
|
}
|
||||||
sexp_gc_release(ctx, env, s_env);
|
sexp_gc_release3(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static sexp analyze_letrec_syntax (sexp ctx, sexp x) {
|
static sexp analyze_letrec_syntax (sexp ctx, sexp x) {
|
||||||
sexp res;
|
sexp res;
|
||||||
sexp_gc_var(ctx, tmp, s_tmp);
|
sexp_gc_var1(tmp);
|
||||||
sexp_gc_preserve(ctx, tmp, s_tmp);
|
sexp_gc_preserve1(ctx, tmp);
|
||||||
if (! (sexp_pairp(sexp_cdr(x)) && sexp_pairp(sexp_cddr(x)))) {
|
if (! (sexp_pairp(sexp_cdr(x)) && sexp_pairp(sexp_cddr(x)))) {
|
||||||
res = sexp_compile_error(ctx, "bad letrec-syntax", x);
|
res = sexp_compile_error(ctx, "bad letrec-syntax", x);
|
||||||
} else {
|
} else {
|
||||||
tmp = analyze_bind_syntax(sexp_cadr(x), ctx, ctx);
|
tmp = analyze_bind_syntax(sexp_cadr(x), ctx, ctx);
|
||||||
res = (sexp_exceptionp(tmp) ? tmp : analyze_seq(ctx, sexp_cddr(x)));
|
res = (sexp_exceptionp(tmp) ? tmp : analyze_seq(ctx, sexp_cddr(x)));
|
||||||
}
|
}
|
||||||
sexp_gc_release(ctx, tmp, s_tmp);
|
sexp_gc_release1(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static sexp analyze (sexp ctx, sexp object) {
|
static sexp analyze (sexp ctx, sexp object) {
|
||||||
sexp op;
|
sexp op;
|
||||||
sexp_gc_var(ctx, res, s_res);
|
sexp_gc_var4(res, tmp, x, cell);
|
||||||
sexp_gc_var(ctx, tmp, s_tmp);
|
sexp_gc_preserve4(ctx, res, tmp, x, cell);
|
||||||
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);
|
|
||||||
x = object;
|
x = object;
|
||||||
loop:
|
loop:
|
||||||
if (sexp_pairp(x)) {
|
if (sexp_pairp(x)) {
|
||||||
|
@ -771,7 +725,7 @@ static sexp analyze (sexp ctx, sexp object) {
|
||||||
} else {
|
} else {
|
||||||
res = x;
|
res = x;
|
||||||
}
|
}
|
||||||
sexp_gc_release(ctx, res, s_res);
|
sexp_gc_release4(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -898,8 +852,8 @@ static void generate_set (sexp ctx, sexp set) {
|
||||||
static void generate_opcode_app (sexp ctx, sexp app) {
|
static void generate_opcode_app (sexp ctx, sexp app) {
|
||||||
sexp op = sexp_car(app);
|
sexp op = sexp_car(app);
|
||||||
sexp_sint_t i, num_args;
|
sexp_sint_t i, num_args;
|
||||||
sexp_gc_var(ctx, ls, s_ls);
|
sexp_gc_var1(ls);
|
||||||
sexp_gc_preserve(ctx, ls, s_ls);
|
sexp_gc_preserve1(ctx, ls);
|
||||||
|
|
||||||
num_args = sexp_unbox_integer(sexp_length(ctx, sexp_cdr(app)));
|
num_args = sexp_unbox_integer(sexp_length(ctx, sexp_cdr(app)));
|
||||||
sexp_context_tailp(ctx) = 0;
|
sexp_context_tailp(ctx) = 0;
|
||||||
|
@ -977,14 +931,14 @@ static void generate_opcode_app (sexp ctx, sexp app) {
|
||||||
emit(ctx, sexp_opcode_code(op));
|
emit(ctx, sexp_opcode_code(op));
|
||||||
|
|
||||||
sexp_context_depth(ctx) -= (num_args-1);
|
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) {
|
static void generate_general_app (sexp ctx, sexp app) {
|
||||||
sexp_uint_t len = sexp_unbox_integer(sexp_length(ctx, sexp_cdr(app))),
|
sexp_uint_t len = sexp_unbox_integer(sexp_length(ctx, sexp_cdr(app))),
|
||||||
tailp = sexp_context_tailp(ctx);
|
tailp = sexp_context_tailp(ctx);
|
||||||
sexp_gc_var(ctx, ls, s_ls);
|
sexp_gc_var1(ls);
|
||||||
sexp_gc_preserve(ctx, ls, s_ls);
|
sexp_gc_preserve1(ctx, ls);
|
||||||
|
|
||||||
/* push the arguments onto the stack */
|
/* push the arguments onto the stack */
|
||||||
sexp_context_tailp(ctx) = 0;
|
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));
|
emit_word(ctx, (sexp_uint_t)sexp_make_integer(len));
|
||||||
|
|
||||||
sexp_context_depth(ctx) -= 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) {
|
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) {
|
static void generate_lambda (sexp ctx, sexp lambda) {
|
||||||
sexp ctx2, fv, ls, flags, len, ref, prev_lambda, prev_fv;
|
sexp ctx2, fv, ls, flags, len, ref, prev_lambda, prev_fv;
|
||||||
sexp_uint_t k;
|
sexp_uint_t k;
|
||||||
sexp_gc_var(ctx, tmp, s_tmp);
|
sexp_gc_var2(tmp, bc);
|
||||||
sexp_gc_var(ctx, bc, s_bc);
|
sexp_gc_preserve2(ctx, tmp, bc);
|
||||||
sexp_gc_preserve(ctx, tmp, s_tmp);
|
|
||||||
sexp_gc_preserve(ctx, bc, s_bc);
|
|
||||||
prev_lambda = sexp_context_lambda(ctx);
|
prev_lambda = sexp_context_lambda(ctx);
|
||||||
prev_fv = sexp_lambdap(prev_lambda) ? sexp_lambda_fv(prev_lambda) : SEXP_NULL;
|
prev_fv = sexp_lambdap(prev_lambda) ? sexp_lambda_fv(prev_lambda) : SEXP_NULL;
|
||||||
fv = sexp_lambda_fv(lambda);
|
fv = sexp_lambda_fv(lambda);
|
||||||
|
@ -1073,7 +1025,7 @@ static void generate_lambda (sexp ctx, sexp lambda) {
|
||||||
emit_push(ctx, flags);
|
emit_push(ctx, flags);
|
||||||
emit(ctx, OP_MAKE_PROCEDURE);
|
emit(ctx, OP_MAKE_PROCEDURE);
|
||||||
}
|
}
|
||||||
sexp_gc_release(ctx, tmp, s_tmp);
|
sexp_gc_release2(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void generate (sexp ctx, sexp x) {
|
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) {
|
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))
|
if (sexp_nullp(fv2))
|
||||||
return fv1;
|
return fv1;
|
||||||
sexp_gc_preserve(ctx, res, s_res);
|
sexp_gc_preserve1(ctx, res);
|
||||||
for (res=fv2; sexp_pairp(fv1); fv1=sexp_cdr(fv1))
|
for (res=fv2; sexp_pairp(fv1); fv1=sexp_cdr(fv1))
|
||||||
res = insert_free_var(ctx, sexp_car(fv1), res);
|
res = insert_free_var(ctx, sexp_car(fv1), res);
|
||||||
sexp_gc_release(ctx, res, s_res);
|
sexp_gc_release1(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static sexp diff_free_vars (sexp ctx, sexp lambda, sexp fv, sexp params) {
|
static sexp diff_free_vars (sexp ctx, sexp lambda, sexp fv, sexp params) {
|
||||||
sexp_gc_var(ctx, res, s_res);
|
sexp_gc_var1(res);
|
||||||
sexp_gc_preserve(ctx, res, s_res);
|
sexp_gc_preserve1(ctx, res);
|
||||||
res = SEXP_NULL;
|
res = SEXP_NULL;
|
||||||
for ( ; sexp_pairp(fv); fv=sexp_cdr(fv))
|
for ( ; sexp_pairp(fv); fv=sexp_cdr(fv))
|
||||||
if ((sexp_ref_loc(sexp_car(fv)) != lambda)
|
if ((sexp_ref_loc(sexp_car(fv)) != lambda)
|
||||||
|| (sexp_memq(NULL, sexp_ref_name(sexp_car(fv)), params)
|
|| (sexp_memq(NULL, sexp_ref_name(sexp_car(fv)), params)
|
||||||
== SEXP_FALSE))
|
== SEXP_FALSE))
|
||||||
sexp_push(ctx, res, sexp_car(fv));
|
sexp_push(ctx, res, sexp_car(fv));
|
||||||
sexp_gc_release(ctx, res, s_res);
|
sexp_gc_release1(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static sexp free_vars (sexp ctx, sexp x, sexp fv) {
|
static sexp free_vars (sexp ctx, sexp x, sexp fv) {
|
||||||
sexp_gc_var(ctx, fv1, s_fv1);
|
sexp_gc_var2(fv1, fv2);
|
||||||
sexp_gc_var(ctx, fv2, s_fv2);
|
sexp_gc_preserve2(ctx, fv1, fv2);
|
||||||
sexp_gc_preserve(ctx, fv1, s_fv1);
|
|
||||||
sexp_gc_preserve(ctx, fv2, s_fv2);
|
|
||||||
fv1 = fv;
|
fv1 = fv;
|
||||||
if (sexp_lambdap(x)) {
|
if (sexp_lambdap(x)) {
|
||||||
fv1 = free_vars(ctx, sexp_lambda_body(x), SEXP_NULL);
|
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)) {
|
} else if (sexp_synclop(x)) {
|
||||||
fv1 = free_vars(ctx, sexp_synclo_expr(x), fv);
|
fv1 = free_vars(ctx, sexp_synclo_expr(x), fv);
|
||||||
}
|
}
|
||||||
sexp_gc_release(ctx, fv1, s_fv1);
|
sexp_gc_release2(ctx);
|
||||||
return fv1;
|
return fv1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static sexp make_param_list(sexp ctx, sexp_uint_t i) {
|
static sexp make_param_list(sexp ctx, sexp_uint_t i) {
|
||||||
sexp_gc_var(ctx, res, s_res);
|
sexp_gc_var1(res);
|
||||||
sexp_gc_preserve(ctx, res, s_res);
|
sexp_gc_preserve1(ctx, res);
|
||||||
res = SEXP_NULL;
|
res = SEXP_NULL;
|
||||||
for ( ; i>0; i--)
|
for ( ; i>0; i--)
|
||||||
res = sexp_cons(ctx, sexp_make_integer(i), res);
|
res = sexp_cons(ctx, sexp_make_integer(i), res);
|
||||||
sexp_gc_release(ctx, res, s_res);
|
sexp_gc_release1(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static sexp make_opcode_procedure (sexp ctx, sexp op, sexp_uint_t i) {
|
static sexp make_opcode_procedure (sexp ctx, sexp op, sexp_uint_t i) {
|
||||||
sexp ls, bc, res, env;
|
sexp ls, bc, res, env;
|
||||||
sexp_gc_var(ctx, params, s_params);
|
sexp_gc_var5(params, ref, refs, lambda, ctx2);
|
||||||
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);
|
|
||||||
if (i == sexp_opcode_num_args(op) && sexp_opcode_proc(op))
|
if (i == sexp_opcode_num_args(op) && sexp_opcode_proc(op))
|
||||||
return sexp_opcode_proc(op); /* return before preserving */
|
return sexp_opcode_proc(op); /* return before preserving */
|
||||||
sexp_gc_preserve(ctx, params, s_params);
|
sexp_gc_preserve5(ctx, params, ref, refs, lambda, ctx2);
|
||||||
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);
|
|
||||||
params = make_param_list(ctx, i);
|
params = make_param_list(ctx, i);
|
||||||
lambda = sexp_make_lambda(ctx, params);
|
lambda = sexp_make_lambda(ctx, params);
|
||||||
ctx2 = sexp_make_child_context(ctx, lambda);
|
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);
|
bc, SEXP_VOID);
|
||||||
if (i == sexp_opcode_num_args(op))
|
if (i == sexp_opcode_num_args(op))
|
||||||
sexp_opcode_proc(op) = res;
|
sexp_opcode_proc(op) = res;
|
||||||
sexp_gc_release(ctx, params, s_params);
|
sexp_gc_release5(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1259,13 +1201,9 @@ sexp sexp_vm (sexp ctx, sexp proc) {
|
||||||
#if USE_BIGNUMS
|
#if USE_BIGNUMS
|
||||||
sexp_lsint_t prod;
|
sexp_lsint_t prod;
|
||||||
#endif
|
#endif
|
||||||
|
sexp_gc_var3(self, tmp1, tmp2);
|
||||||
|
sexp_gc_preserve3(ctx, self, tmp1, tmp2);
|
||||||
fp = top - 4;
|
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;
|
self = proc;
|
||||||
|
|
||||||
loop:
|
loop:
|
||||||
|
@ -1954,7 +1892,7 @@ sexp sexp_vm (sexp ctx, sexp proc) {
|
||||||
goto loop;
|
goto loop;
|
||||||
|
|
||||||
end_loop:
|
end_loop:
|
||||||
sexp_gc_release(ctx, self, s_self);
|
sexp_gc_release3(ctx);
|
||||||
sexp_context_top(ctx) = top;
|
sexp_context_top(ctx) = top;
|
||||||
return _ARG1;
|
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 sexp_load (sexp ctx, sexp source, sexp env) {
|
||||||
sexp tmp, out;
|
sexp tmp, out;
|
||||||
sexp_gc_var(ctx, ctx2, s_ctx2);
|
sexp_gc_var4(ctx2, x, in, res);
|
||||||
sexp_gc_var(ctx, x, s_x);
|
sexp_gc_preserve4(ctx, ctx2, x, in, res);
|
||||||
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);
|
|
||||||
res = SEXP_VOID;
|
res = SEXP_VOID;
|
||||||
in = sexp_open_input_file(ctx, source);
|
in = sexp_open_input_file(ctx, source);
|
||||||
out = env_global_ref(env, the_cur_err_symbol, SEXP_FALSE);
|
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);
|
sexp_warn_undefs(ctx, sexp_env_bindings(env), tmp, out);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
sexp_gc_release(ctx, ctx2, s_ctx2);
|
sexp_gc_release4(ctx);
|
||||||
return res;
|
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) {
|
static sexp sexp_make_standard_env (sexp ctx, sexp version) {
|
||||||
sexp_uint_t i;
|
sexp_uint_t i;
|
||||||
sexp ctx2, cell, sym, perr_cell, err_cell;
|
sexp ctx2, cell, sym, perr_cell, err_cell;
|
||||||
sexp_gc_var(ctx, e, s_e);
|
sexp_gc_var4(e, op, tmp, err_handler);
|
||||||
sexp_gc_var(ctx, op, s_op);
|
sexp_gc_preserve4(ctx, e, op, tmp, err_handler);
|
||||||
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);
|
|
||||||
e = sexp_make_null_env(ctx, version);
|
e = sexp_make_null_env(ctx, version);
|
||||||
for (i=0; i<(sizeof(opcodes)/sizeof(opcodes[0])); i++) {
|
for (i=0; i<(sizeof(opcodes)/sizeof(opcodes[0])); i++) {
|
||||||
op = sexp_copy_opcode(ctx, &opcodes[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),
|
finalize_bytecode(ctx2),
|
||||||
tmp);
|
tmp);
|
||||||
env_define(ctx2, e, the_err_handler_symbol, err_handler);
|
env_define(ctx2, e, the_err_handler_symbol, err_handler);
|
||||||
sexp_gc_release(ctx, e, s_e);
|
sexp_gc_release4(ctx);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2314,14 +2240,8 @@ sexp sexp_apply (sexp ctx, sexp proc, sexp args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
sexp sexp_compile (sexp ctx, sexp x) {
|
sexp sexp_compile (sexp ctx, sexp x) {
|
||||||
sexp_gc_var(ctx, ast, s_ast);
|
sexp_gc_var4(ast, ctx2, vec, res);
|
||||||
sexp_gc_var(ctx, ctx2, s_ctx2);
|
sexp_gc_preserve4(ctx, ast, ctx2, vec, res);
|
||||||
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);
|
|
||||||
ast = analyze(ctx, x);
|
ast = analyze(ctx, x);
|
||||||
if (sexp_exceptionp(ast)) {
|
if (sexp_exceptionp(ast)) {
|
||||||
res = 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 = sexp_make_procedure(ctx, sexp_make_integer(0), sexp_make_integer(0),
|
||||||
res, vec);
|
res, vec);
|
||||||
}
|
}
|
||||||
sexp_gc_release(ctx, ast, s_ast);
|
sexp_gc_release4(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
sexp sexp_eval (sexp ctx, sexp obj, sexp env) {
|
sexp sexp_eval (sexp ctx, sexp obj, sexp env) {
|
||||||
sexp res, ctx2;
|
sexp res, ctx2;
|
||||||
sexp_gc_var(ctx, thunk, s_thunk);
|
sexp_gc_var1(thunk);
|
||||||
sexp_gc_preserve(ctx, thunk, s_thunk);
|
sexp_gc_preserve1(ctx, thunk);
|
||||||
ctx2 = sexp_make_context(ctx, NULL, (env ? env : sexp_context_env(ctx)));
|
ctx2 = sexp_make_context(ctx, NULL, (env ? env : sexp_context_env(ctx)));
|
||||||
sexp_context_parent(ctx2) = ctx;
|
sexp_context_parent(ctx2) = ctx;
|
||||||
thunk = sexp_compile(ctx2, obj);
|
thunk = sexp_compile(ctx2, obj);
|
||||||
|
@ -2353,17 +2273,17 @@ sexp sexp_eval (sexp ctx, sexp obj, sexp env) {
|
||||||
} else {
|
} else {
|
||||||
res = sexp_apply(ctx2, thunk, SEXP_NULL);
|
res = sexp_apply(ctx2, thunk, SEXP_NULL);
|
||||||
}
|
}
|
||||||
sexp_gc_release(ctx, thunk, s_thunk);
|
sexp_gc_release1(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
sexp sexp_eval_string (sexp ctx, char *str, sexp env) {
|
sexp sexp_eval_string (sexp ctx, char *str, sexp env) {
|
||||||
sexp res;
|
sexp res;
|
||||||
sexp_gc_var(ctx, obj, s_obj);
|
sexp_gc_var1(obj);
|
||||||
sexp_gc_preserve(ctx, obj, s_obj);
|
sexp_gc_preserve1(ctx, obj);
|
||||||
obj = sexp_read_from_string(ctx, str);
|
obj = sexp_read_from_string(ctx, str);
|
||||||
res = sexp_eval(ctx, obj, env);
|
res = sexp_eval(ctx, obj, env);
|
||||||
sexp_gc_release(ctx, obj, s_obj);
|
sexp_gc_release1(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -293,6 +293,27 @@ void *sexp_realloc(sexp ctx, sexp x, size_t size);
|
||||||
#endif
|
#endif
|
||||||
#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_align(n, bits) (((n)+(1<<(bits))-1)&(((sexp_uint_t)-1)-((1<<(bits))-1)))
|
||||||
|
|
||||||
#define sexp_sizeof(x) (offsetof(struct sexp_struct, value) \
|
#define sexp_sizeof(x) (offsetof(struct sexp_struct, value) \
|
||||||
|
|
90
opt/bignum.c
90
opt/bignum.c
|
@ -30,12 +30,8 @@ sexp sexp_fixnum_to_bignum (sexp ctx, sexp a) {
|
||||||
|
|
||||||
sexp sexp_double_to_bignum (sexp ctx, double f) {
|
sexp sexp_double_to_bignum (sexp ctx, double f) {
|
||||||
int sign;
|
int sign;
|
||||||
sexp_gc_var(ctx, res, s_res);
|
sexp_gc_var3(res, scale, tmp);
|
||||||
sexp_gc_var(ctx, scale, s_scale);
|
sexp_gc_preserve3(ctx, res, scale, tmp);
|
||||||
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);
|
|
||||||
res = sexp_fixnum_to_bignum(ctx, sexp_make_integer(0));
|
res = sexp_fixnum_to_bignum(ctx, sexp_make_integer(0));
|
||||||
scale = sexp_fixnum_to_bignum(ctx, sexp_make_integer(1));
|
scale = sexp_fixnum_to_bignum(ctx, sexp_make_integer(1));
|
||||||
sign = (f < 0 ? -1 : 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);
|
scale = sexp_bignum_fxmul(ctx, NULL, scale, 10, 0);
|
||||||
}
|
}
|
||||||
sexp_bignum_sign(res) = sign;
|
sexp_bignum_sign(res) = sign;
|
||||||
sexp_gc_release(ctx, res, s_res);
|
sexp_gc_release3(ctx);
|
||||||
return res;
|
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,
|
sexp sexp_read_bignum (sexp ctx, sexp in, sexp_uint_t init,
|
||||||
char sign, sexp_uint_t base) {
|
char sign, sexp_uint_t base) {
|
||||||
int c, digit;
|
int c, digit;
|
||||||
sexp_gc_var(ctx, res, s_res);
|
sexp_gc_var1(res);
|
||||||
sexp_gc_preserve(ctx, res, s_res);
|
sexp_gc_preserve1(ctx, res);
|
||||||
res = sexp_make_bignum(ctx, SEXP_INIT_BIGNUM_SIZE);
|
res = sexp_make_bignum(ctx, SEXP_INIT_BIGNUM_SIZE);
|
||||||
sexp_bignum_sign(res) = sign;
|
sexp_bignum_sign(res) = sign;
|
||||||
sexp_bignum_data(res)[0] = init;
|
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_make_character(c), in);
|
||||||
}
|
}
|
||||||
sexp_push_char(ctx, c, in);
|
sexp_push_char(ctx, c, in);
|
||||||
sexp_gc_release(ctx, res, s_res);
|
sexp_gc_release1(ctx);
|
||||||
return sexp_bignum_normalize(res);
|
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) {
|
sexp sexp_write_bignum (sexp ctx, sexp a, sexp out, sexp_uint_t base) {
|
||||||
int i, str_len, lg_base = log2i(base);
|
int i, str_len, lg_base = log2i(base);
|
||||||
char *data;
|
char *data;
|
||||||
sexp_gc_var(ctx, b, s_b);
|
sexp_gc_var2(b, str);
|
||||||
sexp_gc_var(ctx, str, s_str);
|
sexp_gc_preserve2(ctx, b, str);
|
||||||
sexp_gc_preserve(ctx, b, s_b);
|
|
||||||
sexp_gc_preserve(ctx, str, s_str);
|
|
||||||
b = sexp_copy_bignum(ctx, NULL, a, 0);
|
b = sexp_copy_bignum(ctx, NULL, a, 0);
|
||||||
sexp_bignum_sign(b) = 1;
|
sexp_bignum_sign(b) = 1;
|
||||||
i = str_len = (sexp_bignum_length(b)*sizeof(sexp_uint_t)*8 + lg_base - 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)
|
else if (sexp_bignum_sign(a) == -1)
|
||||||
data[--i] = '-';
|
data[--i] = '-';
|
||||||
sexp_write_string(ctx, data + i, out);
|
sexp_write_string(ctx, data + i, out);
|
||||||
sexp_gc_release(ctx, b, s_b);
|
sexp_gc_release2(ctx);
|
||||||
return SEXP_VOID;
|
return SEXP_VOID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************** bignum arithmetic *************************/
|
/****************** bignum arithmetic *************************/
|
||||||
|
|
||||||
sexp sexp_bignum_add_fixnum (sexp ctx, sexp a, sexp b) {
|
sexp sexp_bignum_add_fixnum (sexp ctx, sexp a, sexp b) {
|
||||||
sexp_gc_var(ctx, c, s_c);
|
sexp_gc_var1(c);
|
||||||
sexp_gc_preserve(ctx, c, s_c);
|
sexp_gc_preserve1(ctx, c);
|
||||||
c = sexp_copy_bignum(ctx, NULL, a, 0);
|
c = sexp_copy_bignum(ctx, NULL, a, 0);
|
||||||
if (sexp_bignum_sign(c) == sexp_fx_sign(b))
|
if (sexp_bignum_sign(c) == sexp_fx_sign(b))
|
||||||
c = sexp_bignum_fxadd(ctx, c, sexp_unbox_integer(sexp_fx_abs(b)));
|
c = sexp_bignum_fxadd(ctx, c, sexp_unbox_integer(sexp_fx_abs(b)));
|
||||||
else
|
else
|
||||||
c = sexp_bignum_fxsub(ctx, c, sexp_unbox_integer(sexp_fx_abs(b)));
|
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;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
sexp sexp_bignum_sub_digits (sexp ctx, sexp dst, sexp a, sexp b) {
|
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),
|
sexp_uint_t alen=sexp_bignum_hi(a), blen=sexp_bignum_hi(b),
|
||||||
borrow=0, i, *adata, *bdata, *cdata;
|
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)))
|
if ((alen < blen) || ((alen == blen) && (sexp_bignum_compare_abs(a, b) < 0)))
|
||||||
return sexp_bignum_sub_digits(ctx, dst, b, a);
|
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)
|
c = ((dst && sexp_bignum_hi(dst) >= alen)
|
||||||
? dst : sexp_copy_bignum(ctx, NULL, a, 0));
|
? dst : sexp_copy_bignum(ctx, NULL, a, 0));
|
||||||
adata = sexp_bignum_data(a);
|
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);
|
borrow = (cdata[i] == 0 ? 1 : 0);
|
||||||
cdata[i]--;
|
cdata[i]--;
|
||||||
}
|
}
|
||||||
sexp_gc_release(ctx, c, s_c);
|
sexp_gc_release1(ctx);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
sexp sexp_bignum_add_digits (sexp ctx, sexp dst, sexp a, sexp b) {
|
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),
|
sexp_uint_t alen=sexp_bignum_hi(a), blen=sexp_bignum_hi(b),
|
||||||
carry=0, i, n, *adata, *bdata, *cdata;
|
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);
|
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)
|
c = ((dst && sexp_bignum_hi(dst) >= alen)
|
||||||
? dst : sexp_copy_bignum(ctx, NULL, a, 0));
|
? dst : sexp_copy_bignum(ctx, NULL, a, 0));
|
||||||
adata = sexp_bignum_data(a);
|
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);
|
c = sexp_copy_bignum(ctx, NULL, c, alen+1);
|
||||||
sexp_bignum_data(c)[alen] = 1;
|
sexp_bignum_data(c)[alen] = 1;
|
||||||
}
|
}
|
||||||
sexp_gc_release(ctx, c, s_c);
|
sexp_gc_release1(ctx);
|
||||||
return c;
|
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 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,
|
sexp_uint_t alen=sexp_bignum_hi(a), blen=sexp_bignum_hi(b), i,
|
||||||
*bdata=sexp_bignum_data(b);
|
*bdata=sexp_bignum_data(b);
|
||||||
sexp_gc_var(ctx, c, s_c);
|
sexp_gc_var2(c, d);
|
||||||
sexp_gc_var(ctx, d, s_d);
|
|
||||||
if (alen < blen) return sexp_bignum_mul(ctx, dst, b, a);
|
if (alen < blen) return sexp_bignum_mul(ctx, dst, b, a);
|
||||||
sexp_gc_preserve(ctx, c, s_c);
|
sexp_gc_preserve2(ctx, c, d);
|
||||||
sexp_gc_preserve(ctx, d, s_d);
|
|
||||||
c = (dst ? dst : sexp_make_bignum(ctx, alen+blen+1));
|
c = (dst ? dst : sexp_make_bignum(ctx, alen+blen+1));
|
||||||
d = sexp_make_bignum(ctx, alen+blen+1);
|
d = sexp_make_bignum(ctx, alen+blen+1);
|
||||||
for (i=0; i<blen; i++) {
|
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_data(d)[i] = 0;
|
||||||
}
|
}
|
||||||
sexp_bignum_sign(c) = sexp_bignum_sign(a) * sexp_bignum_sign(b);
|
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;
|
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) {
|
static sexp quot_step (sexp ctx, sexp *rem, sexp a, sexp b, sexp k, sexp i) {
|
||||||
sexp res;
|
sexp res;
|
||||||
sexp_gc_var(ctx, x, s_x);
|
sexp_gc_var5(x, prod, diff, k2, i2);
|
||||||
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);
|
|
||||||
if (sexp_bignum_compare(k, a) > 0) {
|
if (sexp_bignum_compare(k, a) > 0) {
|
||||||
*rem = a;
|
*rem = a;
|
||||||
return sexp_fixnum_to_bignum(ctx, sexp_make_integer(0));
|
return sexp_fixnum_to_bignum(ctx, sexp_make_integer(0));
|
||||||
}
|
}
|
||||||
sexp_gc_preserve(ctx, x, s_x);
|
sexp_gc_preserve5(ctx, x, prod, diff, k2, i2);
|
||||||
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);
|
|
||||||
k2 = sexp_bignum_double(ctx, k);
|
k2 = sexp_bignum_double(ctx, k);
|
||||||
i2 = sexp_bignum_double(ctx, i);
|
i2 = sexp_bignum_double(ctx, i);
|
||||||
x = quot_step(ctx, rem, a, b, k2, i2);
|
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;
|
*rem = diff;
|
||||||
res = x;
|
res = x;
|
||||||
}
|
}
|
||||||
sexp_gc_release(ctx, x, s_x);
|
sexp_gc_release5(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
sexp sexp_bignum_quot_rem (sexp ctx, sexp *rem, sexp a, sexp b) {
|
sexp sexp_bignum_quot_rem (sexp ctx, sexp *rem, sexp a, sexp b) {
|
||||||
sexp res;
|
sexp res;
|
||||||
sexp_gc_var(ctx, k, s_k);
|
sexp_gc_var4(k, i, a1, b1);
|
||||||
sexp_gc_var(ctx, i, s_i);
|
sexp_gc_preserve4(ctx, k, i, a1, b1);
|
||||||
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);
|
|
||||||
a1 = sexp_copy_bignum(ctx, NULL, a, 0);
|
a1 = sexp_copy_bignum(ctx, NULL, a, 0);
|
||||||
sexp_bignum_sign(a1) = 1;
|
sexp_bignum_sign(a1) = 1;
|
||||||
b1 = sexp_copy_bignum(ctx, NULL, b, 0);
|
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) {
|
if (sexp_bignum_sign(a) < 0) {
|
||||||
sexp_negate(*rem);
|
sexp_negate(*rem);
|
||||||
}
|
}
|
||||||
sexp_gc_release(ctx, k, s_k);
|
sexp_gc_release4(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
sexp sexp_bignum_quotient (sexp ctx, sexp a, sexp b) {
|
sexp sexp_bignum_quotient (sexp ctx, sexp a, sexp b) {
|
||||||
sexp res;
|
sexp res;
|
||||||
sexp_gc_var(ctx, rem, s_rem);
|
sexp_gc_var1(rem);
|
||||||
sexp_gc_preserve(ctx, rem, s_rem);
|
sexp_gc_preserve1(ctx, rem);
|
||||||
res = sexp_bignum_quot_rem(ctx, &rem, a, b);
|
res = sexp_bignum_quot_rem(ctx, &rem, a, b);
|
||||||
sexp_gc_release(ctx, rem, s_rem);
|
sexp_gc_release1(ctx);
|
||||||
return res;
|
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 sexp_bignum_expt (sexp ctx, sexp a, sexp b) {
|
||||||
sexp_sint_t e = sexp_unbox_integer(sexp_fx_abs(b));
|
sexp_sint_t e = sexp_unbox_integer(sexp_fx_abs(b));
|
||||||
sexp_gc_var(ctx, res, s_res);
|
sexp_gc_var2(res, acc);
|
||||||
sexp_gc_var(ctx, acc, s_acc);
|
sexp_gc_preserve2(ctx, res, acc);
|
||||||
sexp_gc_preserve(ctx, res, s_res);
|
|
||||||
sexp_gc_preserve(ctx, acc, s_acc);
|
|
||||||
res = sexp_fixnum_to_bignum(ctx, sexp_make_integer(1));
|
res = sexp_fixnum_to_bignum(ctx, sexp_make_integer(1));
|
||||||
acc = sexp_copy_bignum(ctx, NULL, a, 0);
|
acc = sexp_copy_bignum(ctx, NULL, a, 0);
|
||||||
for (; e; e>>=1, acc=sexp_bignum_mul(ctx, NULL, acc, acc))
|
for (; e; e>>=1, acc=sexp_bignum_mul(ctx, NULL, acc, acc))
|
||||||
if (e & 1)
|
if (e & 1)
|
||||||
res = sexp_bignum_mul(ctx, NULL, res, acc);
|
res = sexp_bignum_mul(ctx, NULL, res, acc);
|
||||||
sexp_gc_release(ctx, res, s_res);
|
sexp_gc_release2(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
112
sexp.c
112
sexp.c
|
@ -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 sexp_user_exception (sexp ctx, sexp self, char *message, sexp irritants) {
|
||||||
sexp res;
|
sexp res;
|
||||||
sexp_gc_var(ctx, sym, s_sym);
|
sexp_gc_var3(sym, str, irr);
|
||||||
sexp_gc_var(ctx, str, s_str);
|
sexp_gc_preserve3(ctx, sym, str, irr);
|
||||||
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);
|
|
||||||
res = sexp_make_exception(ctx, sym = sexp_intern(ctx, "user"),
|
res = sexp_make_exception(ctx, sym = sexp_intern(ctx, "user"),
|
||||||
str = sexp_c_string(ctx, message, -1),
|
str = sexp_c_string(ctx, message, -1),
|
||||||
((sexp_pairp(irritants) || sexp_nullp(irritants))
|
((sexp_pairp(irritants) || sexp_nullp(irritants))
|
||||||
? irritants : (irr = sexp_list1(ctx, irritants))),
|
? irritants : (irr = sexp_list1(ctx, irritants))),
|
||||||
self, SEXP_FALSE);
|
self, SEXP_FALSE);
|
||||||
sexp_gc_release(ctx, sym, s_sym);
|
sexp_gc_release3(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
sexp sexp_type_exception (sexp ctx, char *message, sexp obj) {
|
sexp sexp_type_exception (sexp ctx, char *message, sexp obj) {
|
||||||
sexp res;
|
sexp res;
|
||||||
sexp_gc_var(ctx, sym, s_sym);
|
sexp_gc_var3(sym, str, irr);
|
||||||
sexp_gc_var(ctx, str, s_str);
|
sexp_gc_preserve3(ctx, sym, str, irr);
|
||||||
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);
|
|
||||||
res = sexp_make_exception(ctx, sym = sexp_intern(ctx, "type"),
|
res = sexp_make_exception(ctx, sym = sexp_intern(ctx, "type"),
|
||||||
str = sexp_c_string(ctx, message, -1),
|
str = sexp_c_string(ctx, message, -1),
|
||||||
irr = sexp_list1(ctx, obj),
|
irr = sexp_list1(ctx, obj),
|
||||||
SEXP_FALSE, SEXP_FALSE);
|
SEXP_FALSE, SEXP_FALSE);
|
||||||
sexp_gc_release(ctx, sym, s_sym);
|
sexp_gc_release3(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
sexp sexp_range_exception (sexp ctx, sexp obj, sexp start, sexp end) {
|
sexp sexp_range_exception (sexp ctx, sexp obj, sexp start, sexp end) {
|
||||||
sexp_gc_var(ctx, res, s_res);
|
sexp_gc_var2(res, msg);
|
||||||
sexp_gc_var(ctx, msg, s_msg);
|
sexp_gc_preserve2(ctx, res, msg);
|
||||||
sexp_gc_preserve(ctx, res, s_res);
|
|
||||||
sexp_gc_preserve(ctx, msg, s_msg);
|
|
||||||
msg = sexp_c_string(ctx, "bad index range", -1);
|
msg = sexp_c_string(ctx, "bad index range", -1);
|
||||||
res = sexp_list2(ctx, start, end);
|
res = sexp_list2(ctx, start, end);
|
||||||
res = sexp_cons(ctx, obj, res);
|
res = sexp_cons(ctx, obj, res);
|
||||||
res = sexp_make_exception(ctx, sexp_intern(ctx, "range"), msg, res,
|
res = sexp_make_exception(ctx, sexp_intern(ctx, "range"), msg, res,
|
||||||
SEXP_FALSE, SEXP_FALSE);
|
SEXP_FALSE, SEXP_FALSE);
|
||||||
sexp_gc_release(ctx, res, s_res);
|
sexp_gc_release2(ctx);
|
||||||
return res;
|
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) {
|
static sexp sexp_read_error (sexp ctx, char *msg, sexp irritants, sexp port) {
|
||||||
sexp res;
|
sexp res;
|
||||||
sexp_gc_var(ctx, name, s_name);
|
sexp_gc_var3(name, str, irr);
|
||||||
sexp_gc_var(ctx, str, s_str);
|
sexp_gc_preserve3(ctx, name, str, irr);
|
||||||
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);
|
|
||||||
name = (sexp_port_name(port) ? sexp_port_name(port) : SEXP_FALSE);
|
name = (sexp_port_name(port) ? sexp_port_name(port) : SEXP_FALSE);
|
||||||
name = sexp_cons(ctx, name, sexp_make_integer(sexp_port_line(port)));
|
name = sexp_cons(ctx, name, sexp_make_integer(sexp_port_line(port)));
|
||||||
str = sexp_c_string(ctx, msg, -1);
|
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));
|
? irritants : sexp_list1(ctx, irritants));
|
||||||
res = sexp_make_exception(ctx, the_read_error_symbol,
|
res = sexp_make_exception(ctx, the_read_error_symbol,
|
||||||
str, irr, SEXP_FALSE, name);
|
str, irr, SEXP_FALSE, name);
|
||||||
sexp_gc_release(ctx, name, s_name);
|
sexp_gc_release3(ctx);
|
||||||
return res;
|
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 sexp_list2 (sexp ctx, sexp a, sexp b) {
|
||||||
sexp_gc_var(ctx, res, s_res);
|
sexp_gc_var1(res);
|
||||||
sexp_gc_preserve(ctx, res, s_res);
|
sexp_gc_preserve1(ctx, res);
|
||||||
res = sexp_cons(ctx, b, SEXP_NULL);
|
res = sexp_cons(ctx, b, SEXP_NULL);
|
||||||
res = sexp_cons(ctx, a, res);
|
res = sexp_cons(ctx, a, res);
|
||||||
sexp_gc_release(ctx, res, s_res);
|
sexp_gc_release1(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,11 +280,11 @@ sexp sexp_assq (sexp ctx, sexp x, sexp ls) {
|
||||||
}
|
}
|
||||||
|
|
||||||
sexp sexp_reverse (sexp ctx, sexp ls) {
|
sexp sexp_reverse (sexp ctx, sexp ls) {
|
||||||
sexp_gc_var(ctx, res, s_res);
|
sexp_gc_var1(res);
|
||||||
sexp_gc_preserve(ctx, res, s_res);
|
sexp_gc_preserve1(ctx, res);
|
||||||
for (res=SEXP_NULL; sexp_pairp(ls); ls=sexp_cdr(ls))
|
for (res=SEXP_NULL; sexp_pairp(ls); ls=sexp_cdr(ls))
|
||||||
res = sexp_cons(ctx, sexp_car(ls), res);
|
res = sexp_cons(ctx, sexp_car(ls), res);
|
||||||
sexp_gc_release(ctx, res, s_res);
|
sexp_gc_release1(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,14 +307,12 @@ sexp sexp_nreverse (sexp ctx, sexp ls) {
|
||||||
}
|
}
|
||||||
|
|
||||||
sexp sexp_append2 (sexp ctx, sexp a, sexp b) {
|
sexp sexp_append2 (sexp ctx, sexp a, sexp b) {
|
||||||
sexp_gc_var(ctx, a1, s_a1);
|
sexp_gc_var2(a1, b1);
|
||||||
sexp_gc_var(ctx, b1, s_b1);
|
sexp_gc_preserve2(ctx, a1, b1);
|
||||||
sexp_gc_preserve(ctx, a1, s_a1);
|
|
||||||
sexp_gc_preserve(ctx, b1, s_b1);
|
|
||||||
b1 = b;
|
b1 = b;
|
||||||
for (a1=sexp_reverse(ctx, a); sexp_pairp(a1); a1=sexp_cdr(a1))
|
for (a1=sexp_reverse(ctx, a); sexp_pairp(a1); a1=sexp_cdr(a1))
|
||||||
b1 = sexp_cons(ctx, sexp_car(a1), b1);
|
b1 = sexp_cons(ctx, sexp_car(a1), b1);
|
||||||
sexp_gc_release(ctx, a1, s_a1);
|
sexp_gc_release2(ctx);
|
||||||
return b1;
|
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;
|
sexp_uint_t len, res=FNV_OFFSET_BASIS, space=3, newbits, bucket;
|
||||||
char c, *p=str;
|
char c, *p=str;
|
||||||
sexp ls;
|
sexp ls;
|
||||||
sexp_gc_var(ctx, sym, s_sym);
|
sexp_gc_var1(sym);
|
||||||
|
|
||||||
#if USE_HUFF_SYMS
|
#if USE_HUFF_SYMS
|
||||||
res = 0;
|
res = 0;
|
||||||
|
@ -521,11 +505,11 @@ sexp sexp_intern(sexp ctx, char *str) {
|
||||||
return sexp_car(ls);
|
return sexp_car(ls);
|
||||||
|
|
||||||
/* not found, make a new symbol */
|
/* 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);
|
sym = sexp_alloc_type(ctx, symbol, SEXP_SYMBOL);
|
||||||
sexp_symbol_string(sym) = sexp_c_string(ctx, str, len);
|
sexp_symbol_string(sym) = sexp_c_string(ctx, str, len);
|
||||||
sexp_push(ctx, sexp_symbol_table[bucket], sym);
|
sexp_push(ctx, sexp_symbol_table[bucket], sym);
|
||||||
sexp_gc_release(ctx, sym, s_sym);
|
sexp_gc_release1(ctx);
|
||||||
return sym;
|
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) {
|
sexp sexp_make_input_string_port (sexp ctx, sexp str) {
|
||||||
FILE *in;
|
FILE *in;
|
||||||
sexp res;
|
sexp res;
|
||||||
sexp_gc_var(ctx, cookie, s_cookie);
|
sexp_gc_var1(cookie);
|
||||||
sexp_gc_preserve(ctx, cookie, s_cookie);
|
sexp_gc_preserve1(ctx, cookie);
|
||||||
cookie = sexp_make_vector(ctx, sexp_make_integer(4), SEXP_VOID);
|
cookie = sexp_make_vector(ctx, sexp_make_integer(4), SEXP_VOID);
|
||||||
sexp_stream_ctx(cookie) = ctx;
|
sexp_stream_ctx(cookie) = ctx;
|
||||||
sexp_stream_buf(cookie) = str;
|
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);
|
in = funopen(cookie, &sstream_read, NULL, &sstream_seek, NULL);
|
||||||
res = sexp_make_input_port(ctx, in, SEXP_FALSE);
|
res = sexp_make_input_port(ctx, in, SEXP_FALSE);
|
||||||
sexp_port_cookie(res) = cookie;
|
sexp_port_cookie(res) = cookie;
|
||||||
sexp_gc_release(ctx, cookie, s_cookie);
|
sexp_gc_release1(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
sexp sexp_make_output_string_port (sexp ctx) {
|
sexp sexp_make_output_string_port (sexp ctx) {
|
||||||
FILE *out;
|
FILE *out;
|
||||||
sexp res, size;
|
sexp res, size;
|
||||||
sexp_gc_var(ctx, cookie, s_cookie);
|
sexp_gc_var1(cookie);
|
||||||
sexp_gc_preserve(ctx, cookie, s_cookie);
|
sexp_gc_preserve1(ctx, cookie);
|
||||||
size = sexp_make_integer(SEXP_INIT_STRING_PORT_SIZE);
|
size = sexp_make_integer(SEXP_INIT_STRING_PORT_SIZE);
|
||||||
cookie = sexp_make_vector(ctx, sexp_make_integer(4), SEXP_VOID);
|
cookie = sexp_make_vector(ctx, sexp_make_integer(4), SEXP_VOID);
|
||||||
sexp_stream_ctx(cookie) = ctx;
|
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);
|
out = funopen(cookie, NULL, &sstream_write, &sstream_seek, NULL);
|
||||||
res = sexp_make_output_port(ctx, out, SEXP_FALSE);
|
res = sexp_make_output_port(ctx, out, SEXP_FALSE);
|
||||||
sexp_port_cookie(res) = cookie;
|
sexp_port_cookie(res) = cookie;
|
||||||
sexp_gc_release(ctx, cookie, s_cookie);
|
sexp_gc_release1(ctx);
|
||||||
return res;
|
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 sexp_buffered_flush (sexp ctx, sexp p) {
|
||||||
sexp_gc_var(ctx, tmp, s_tmp);
|
sexp_gc_var1(tmp);
|
||||||
if (! sexp_oportp(p))
|
if (! sexp_oportp(p))
|
||||||
return sexp_type_exception(ctx, "not an output-port", p);
|
return sexp_type_exception(ctx, "not an output-port", p);
|
||||||
else if (! sexp_port_openp(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));
|
fwrite(sexp_port_buf(p), 1, sexp_port_offset(p), sexp_port_stream(p));
|
||||||
fflush(sexp_port_stream(p));
|
fflush(sexp_port_stream(p));
|
||||||
} else if (sexp_port_offset(p) > 0) {
|
} 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));
|
tmp = sexp_c_string(ctx, sexp_port_buf(p), sexp_port_offset(p));
|
||||||
sexp_push(ctx, sexp_port_cookie(p), tmp);
|
sexp_push(ctx, sexp_port_cookie(p), tmp);
|
||||||
sexp_gc_release(ctx, tmp, s_tmp);
|
sexp_gc_release1(ctx);
|
||||||
}
|
}
|
||||||
sexp_port_offset(p) = 0;
|
sexp_port_offset(p) = 0;
|
||||||
return SEXP_VOID;
|
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 sexp_get_output_string (sexp ctx, sexp out) {
|
||||||
sexp res;
|
sexp res;
|
||||||
sexp_gc_var(ctx, ls, s_ls);
|
sexp_gc_var2(ls, tmp);
|
||||||
sexp_gc_var(ctx, tmp, s_tmp);
|
sexp_gc_preserve2(ctx, ls, tmp);
|
||||||
sexp_gc_preserve(ctx, ls, s_ls);
|
|
||||||
sexp_gc_preserve(ctx, tmp, s_tmp);
|
|
||||||
if (sexp_port_offset(out) > 0) {
|
if (sexp_port_offset(out) > 0) {
|
||||||
tmp = sexp_c_string(ctx, sexp_port_buf(out), sexp_port_offset(out));
|
tmp = sexp_c_string(ctx, sexp_port_buf(out), sexp_port_offset(out));
|
||||||
ls = sexp_cons(ctx, tmp, sexp_port_cookie(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);
|
ls = sexp_port_cookie(out);
|
||||||
}
|
}
|
||||||
res = sexp_string_concatenate(ctx, ls);
|
res = sexp_string_concatenate(ctx, ls);
|
||||||
sexp_gc_release(ctx, ls, s_ls);
|
sexp_gc_release2(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1109,10 +1091,8 @@ sexp sexp_read_raw (sexp ctx, sexp in) {
|
||||||
char *str;
|
char *str;
|
||||||
int c1, c2, line;
|
int c1, c2, line;
|
||||||
sexp tmp2;
|
sexp tmp2;
|
||||||
sexp_gc_var(ctx, res, s_res);
|
sexp_gc_var2(res, tmp);
|
||||||
sexp_gc_var(ctx, tmp, s_tmp);
|
sexp_gc_preserve2(ctx, res, tmp);
|
||||||
sexp_gc_preserve(ctx, res, s_res);
|
|
||||||
sexp_gc_preserve(ctx, tmp, s_tmp);
|
|
||||||
|
|
||||||
scan_loop:
|
scan_loop:
|
||||||
switch (c1 = sexp_read_char(ctx, in)) {
|
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))
|
if (sexp_port_sourcep(in) && sexp_pointerp(res))
|
||||||
sexp_immutablep(res) = 1;
|
sexp_immutablep(res) = 1;
|
||||||
sexp_gc_release(ctx, res, s_res);
|
sexp_gc_release2(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1370,25 +1350,23 @@ sexp sexp_read (sexp ctx, sexp in) {
|
||||||
|
|
||||||
sexp sexp_read_from_string(sexp ctx, char *str) {
|
sexp sexp_read_from_string(sexp ctx, char *str) {
|
||||||
sexp res;
|
sexp res;
|
||||||
sexp_gc_var(ctx, s, s_s);
|
sexp_gc_var2(s, in);
|
||||||
sexp_gc_var(ctx, in, s_in);
|
sexp_gc_preserve2(ctx, s, in);
|
||||||
sexp_gc_preserve(ctx, s, s_s);
|
|
||||||
sexp_gc_preserve(ctx, in, s_in);
|
|
||||||
s = sexp_c_string(ctx, str, -1);
|
s = sexp_c_string(ctx, str, -1);
|
||||||
in = sexp_make_input_string_port(ctx, s);
|
in = sexp_make_input_string_port(ctx, s);
|
||||||
res = sexp_read(ctx, in);
|
res = sexp_read(ctx, in);
|
||||||
sexp_gc_release(ctx, s, s_s);
|
sexp_gc_release2(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
sexp sexp_write_to_string(sexp ctx, sexp obj) {
|
sexp sexp_write_to_string(sexp ctx, sexp obj) {
|
||||||
sexp str;
|
sexp str;
|
||||||
sexp_gc_var(ctx, out, s_out);
|
sexp_gc_var1(out);
|
||||||
sexp_gc_preserve(ctx, out, s_out);
|
sexp_gc_preserve1(ctx, out);
|
||||||
out = sexp_make_output_string_port(ctx);
|
out = sexp_make_output_string_port(ctx);
|
||||||
sexp_write(ctx, obj, out);
|
sexp_write(ctx, obj, out);
|
||||||
str = sexp_get_output_string(ctx, out);
|
str = sexp_get_output_string(ctx, out);
|
||||||
sexp_gc_release(ctx, out, s_out);
|
sexp_gc_release1(ctx);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue