mirror of
https://github.com/ashinn/chibi-scheme.git
synced 2025-05-19 13:49:17 +02:00
raising exceptions on primitive cons cell accessors
This commit is contained in:
parent
c0da696c67
commit
a094fb3ff8
3 changed files with 23 additions and 42 deletions
50
eval.c
50
eval.c
|
@ -21,7 +21,7 @@ static sexp continuation_resumer;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/********************** environment utilities ***************************/
|
/********************** environment utilities ***************************/
|
||||||
sexp env_cell(env e, sexp key) {
|
static sexp env_cell(env e, sexp key) {
|
||||||
sexp ls, res=NULL;
|
sexp ls, res=NULL;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
@ -37,7 +37,7 @@ sexp env_cell(env e, sexp key) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int env_global_p (env e, sexp id) {
|
static int env_global_p (env e, sexp id) {
|
||||||
while (e->parent) {
|
while (e->parent) {
|
||||||
if (sexp_assq(id, e->bindings) != SEXP_FALSE)
|
if (sexp_assq(id, e->bindings) != SEXP_FALSE)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -47,7 +47,7 @@ int env_global_p (env e, sexp id) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void env_define(env e, sexp key, sexp value) {
|
static void env_define(env e, sexp key, sexp value) {
|
||||||
sexp cell = env_cell(e, key);
|
sexp cell = env_cell(e, key);
|
||||||
if (cell) {
|
if (cell) {
|
||||||
SEXP_CDR(cell) = value;
|
SEXP_CDR(cell) = value;
|
||||||
|
@ -56,7 +56,7 @@ void env_define(env e, sexp key, sexp value) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
env extend_env_closure (env e, sexp fv) {
|
static env extend_env_closure (env e, sexp fv) {
|
||||||
int i;
|
int i;
|
||||||
env e2 = (env) SEXP_ALLOC(sizeof(struct env));
|
env e2 = (env) SEXP_ALLOC(sizeof(struct env));
|
||||||
e2->tag = SEXP_ENV;
|
e2->tag = SEXP_ENV;
|
||||||
|
@ -71,7 +71,7 @@ env extend_env_closure (env e, sexp fv) {
|
||||||
|
|
||||||
/************************* bytecode utilities ***************************/
|
/************************* bytecode utilities ***************************/
|
||||||
|
|
||||||
void shrink_bcode(bytecode *bc, unsigned int i) {
|
static void shrink_bcode(bytecode *bc, unsigned int i) {
|
||||||
bytecode tmp;
|
bytecode tmp;
|
||||||
if ((*bc)->len != i) {
|
if ((*bc)->len != i) {
|
||||||
/* fprintf(stderr, "shrinking to %d\n", i); */
|
/* fprintf(stderr, "shrinking to %d\n", i); */
|
||||||
|
@ -84,7 +84,7 @@ void shrink_bcode(bytecode *bc, unsigned int i) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void emit(bytecode *bc, unsigned int *i, char c) {
|
static void emit(bytecode *bc, unsigned int *i, char c) {
|
||||||
bytecode tmp;
|
bytecode tmp;
|
||||||
if ((*bc)->len < (*i)+1) {
|
if ((*bc)->len < (*i)+1) {
|
||||||
/* fprintf(stderr, "expanding (%d < %d)\n", (*bc)->len, (*i)+1); */
|
/* fprintf(stderr, "expanding (%d < %d)\n", (*bc)->len, (*i)+1); */
|
||||||
|
@ -97,7 +97,7 @@ void emit(bytecode *bc, unsigned int *i, char c) {
|
||||||
(*bc)->data[(*i)++] = c;
|
(*bc)->data[(*i)++] = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
void emit_word(bytecode *bc, unsigned int *i, sexp_uint_t val) {
|
static void emit_word(bytecode *bc, unsigned int *i, sexp_uint_t val) {
|
||||||
bytecode tmp;
|
bytecode tmp;
|
||||||
if ((*bc)->len < (*i)+4) {
|
if ((*bc)->len < (*i)+4) {
|
||||||
tmp = (bytecode) SEXP_ALLOC(sizeof(unsigned int) + (*bc)->len*2);
|
tmp = (bytecode) SEXP_ALLOC(sizeof(unsigned int) + (*bc)->len*2);
|
||||||
|
@ -112,7 +112,7 @@ void emit_word(bytecode *bc, unsigned int *i, sexp_uint_t val) {
|
||||||
|
|
||||||
#define emit_push(bc,i,obj) (emit(bc,i,OP_PUSH), emit_word(bc,i,(sexp_uint_t)obj))
|
#define emit_push(bc,i,obj) (emit(bc,i,OP_PUSH), emit_word(bc,i,(sexp_uint_t)obj))
|
||||||
|
|
||||||
sexp sexp_make_procedure(sexp bc, sexp vars) {
|
static sexp sexp_make_procedure(sexp bc, sexp vars) {
|
||||||
sexp proc = SEXP_NEW();
|
sexp proc = SEXP_NEW();
|
||||||
if (! proc) return SEXP_ERROR;
|
if (! proc) return SEXP_ERROR;
|
||||||
proc->tag = SEXP_PROCEDURE;
|
proc->tag = SEXP_PROCEDURE;
|
||||||
|
@ -426,22 +426,6 @@ bytecode compile(sexp params, sexp obj, env e, sexp fv, sexp sv, int done_p) {
|
||||||
|
|
||||||
/************************ library functions ***************************/
|
/************************ library functions ***************************/
|
||||||
|
|
||||||
sexp sexp_set_car(sexp obj, sexp val) {
|
|
||||||
if (SEXP_PAIRP(obj))
|
|
||||||
return SEXP_CAR(obj) = val;
|
|
||||||
else {
|
|
||||||
sexp_debug("error: set-car! not a pair: ", obj);
|
|
||||||
return SEXP_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sexp sexp_set_cdr(sexp obj, sexp val) {
|
|
||||||
if (SEXP_PAIRP(obj))
|
|
||||||
return SEXP_CDR(obj) = val;
|
|
||||||
else
|
|
||||||
return SEXP_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************** the virtual machine **************************/
|
/*********************** the virtual machine **************************/
|
||||||
|
|
||||||
sexp sexp_save_stack(sexp *stack, unsigned int to) {
|
sexp sexp_save_stack(sexp *stack, unsigned int to) {
|
||||||
|
@ -462,6 +446,8 @@ unsigned int sexp_restore_stack(sexp saved, sexp *current) {
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define sexp_raise(exn) {stack[top-1]=(exn); goto call_error_handler;}
|
||||||
|
|
||||||
sexp vm(bytecode bc, env e, sexp* stack, unsigned int top) {
|
sexp vm(bytecode bc, env e, sexp* stack, unsigned int top) {
|
||||||
unsigned char *ip=bc->data;
|
unsigned char *ip=bc->data;
|
||||||
sexp cp=SEXP_UNDEF, tmp1, tmp2;
|
sexp cp=SEXP_UNDEF, tmp1, tmp2;
|
||||||
|
@ -579,16 +565,20 @@ sexp vm(bytecode bc, env e, sexp* stack, unsigned int top) {
|
||||||
case OP_EOFP:
|
case OP_EOFP:
|
||||||
stack[top-1]=(stack[top-1] == SEXP_EOF) ? SEXP_TRUE : SEXP_FALSE; break;
|
stack[top-1]=(stack[top-1] == SEXP_EOF) ? SEXP_TRUE : SEXP_FALSE; break;
|
||||||
case OP_CAR:
|
case OP_CAR:
|
||||||
stack[top-1]=sexp_car(stack[top-1]); break;
|
if (! SEXP_PAIRP(stack[top-1])) sexp_raise(sexp_intern("not-a-pair"));
|
||||||
|
stack[top-1]=SEXP_CAR(stack[top-1]); break;
|
||||||
case OP_CDR:
|
case OP_CDR:
|
||||||
stack[top-1]=sexp_cdr(stack[top-1]); break;
|
if (! SEXP_PAIRP(stack[top-1])) sexp_raise(sexp_intern("not-a-pair"));
|
||||||
|
stack[top-1]=SEXP_CDR(stack[top-1]); break;
|
||||||
case OP_SET_CAR:
|
case OP_SET_CAR:
|
||||||
sexp_set_car(stack[top-1], stack[top-2]);
|
if (! SEXP_PAIRP(stack[top-1])) sexp_raise(sexp_intern("not-a-pair"));
|
||||||
|
SEXP_CAR(stack[top-1]) = stack[top-2];
|
||||||
stack[top-2]=SEXP_UNDEF;
|
stack[top-2]=SEXP_UNDEF;
|
||||||
top--;
|
top--;
|
||||||
break;
|
break;
|
||||||
case OP_SET_CDR:
|
case OP_SET_CDR:
|
||||||
sexp_set_cdr(stack[top-1], stack[top-2]);
|
if (! SEXP_PAIRP(stack[top-1])) sexp_raise(sexp_intern("not-a-pair"));
|
||||||
|
SEXP_CDR(stack[top-1]) = stack[top-2];
|
||||||
stack[top-2]=SEXP_UNDEF;
|
stack[top-2]=SEXP_UNDEF;
|
||||||
top--;
|
top--;
|
||||||
break;
|
break;
|
||||||
|
@ -902,8 +892,8 @@ void scheme_init() {
|
||||||
void repl (env e, sexp *stack) {
|
void repl (env e, sexp *stack) {
|
||||||
sexp obj, res;
|
sexp obj, res;
|
||||||
while (1) {
|
while (1) {
|
||||||
fprintf(stdout, "> ");
|
sexp_write_string("> ", cur_output_port);
|
||||||
fflush(stdout);
|
sexp_flush(cur_output_port);
|
||||||
obj = sexp_read(cur_input_port);
|
obj = sexp_read(cur_input_port);
|
||||||
if (obj == SEXP_EOF)
|
if (obj == SEXP_EOF)
|
||||||
break;
|
break;
|
||||||
|
|
10
sexp.c
10
sexp.c
|
@ -85,14 +85,6 @@ sexp sexp_cons(sexp head, sexp tail) {
|
||||||
return pair;
|
return pair;
|
||||||
}
|
}
|
||||||
|
|
||||||
sexp sexp_car(sexp obj) {
|
|
||||||
return (SEXP_PAIRP(obj)) ? SEXP_CAR(obj) : SEXP_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
sexp sexp_cdr(sexp obj) {
|
|
||||||
return (SEXP_PAIRP(obj)) ? SEXP_CDR(obj) : SEXP_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sexp_listp (sexp obj) {
|
int sexp_listp (sexp obj) {
|
||||||
while (SEXP_PAIRP(obj))
|
while (SEXP_PAIRP(obj))
|
||||||
obj = SEXP_CDR(obj);
|
obj = SEXP_CDR(obj);
|
||||||
|
@ -444,7 +436,7 @@ void sexp_write (sexp obj, sexp out) {
|
||||||
i = sexp_symbol_length(obj);
|
i = sexp_symbol_length(obj);
|
||||||
str = sexp_symbol_data(obj);
|
str = sexp_symbol_data(obj);
|
||||||
}
|
}
|
||||||
for ( ; i>=0; str++, i--) {
|
for ( ; i>0; str++, i--) {
|
||||||
if (str[0] == '\\')
|
if (str[0] == '\\')
|
||||||
sexp_write_char('\\', out);
|
sexp_write_char('\\', out);
|
||||||
sexp_write_char(str[0], out);
|
sexp_write_char(str[0], out);
|
||||||
|
|
5
sexp.h
5
sexp.h
|
@ -76,6 +76,7 @@ enum sexp_types {
|
||||||
SEXP_IPORT,
|
SEXP_IPORT,
|
||||||
SEXP_OPORT,
|
SEXP_OPORT,
|
||||||
/* the following are used only by the evaluator */
|
/* the following are used only by the evaluator */
|
||||||
|
SEXP_EXCEPTION,
|
||||||
SEXP_PROCEDURE,
|
SEXP_PROCEDURE,
|
||||||
SEXP_ENV,
|
SEXP_ENV,
|
||||||
SEXP_BYTECODE,
|
SEXP_BYTECODE,
|
||||||
|
@ -167,6 +168,7 @@ int sstream_close(void *vec);
|
||||||
#define sexp_write_char(c, p) (putc(c, sexp_port_stream(p)))
|
#define sexp_write_char(c, p) (putc(c, sexp_port_stream(p)))
|
||||||
#define sexp_write_string(s, p) (fputs(s, sexp_port_stream(p)))
|
#define sexp_write_string(s, p) (fputs(s, sexp_port_stream(p)))
|
||||||
#define sexp_printf(p, s, ...) (fprintf(sexp_port_stream(p), s, __VA_ARGS__))
|
#define sexp_printf(p, s, ...) (fprintf(sexp_port_stream(p), s, __VA_ARGS__))
|
||||||
|
#define sexp_flush(p) (fflush(sexp_port_stream(p)))
|
||||||
#else
|
#else
|
||||||
sexp sexp_read_char(sexp port);
|
sexp sexp_read_char(sexp port);
|
||||||
void sexp_push_char(sexp ch, sexp port);
|
void sexp_push_char(sexp ch, sexp port);
|
||||||
|
@ -204,9 +206,6 @@ void sexp_printf(sexp port, sexp fmt, ...);
|
||||||
#define SEXP_CDDDDR(x) (SEXP_CDDR(SEXP_CDDR(x)))
|
#define SEXP_CDDDDR(x) (SEXP_CDDR(SEXP_CDDR(x)))
|
||||||
|
|
||||||
sexp sexp_cons(sexp head, sexp tail);
|
sexp sexp_cons(sexp head, sexp tail);
|
||||||
sexp sexp_car(sexp obj);
|
|
||||||
sexp sexp_cdr(sexp obj);
|
|
||||||
|
|
||||||
int sexp_listp(sexp obj);
|
int sexp_listp(sexp obj);
|
||||||
int sexp_list_index(sexp ls, sexp elt);
|
int sexp_list_index(sexp ls, sexp elt);
|
||||||
sexp sexp_lset_diff(sexp a, sexp b);
|
sexp sexp_lset_diff(sexp a, sexp b);
|
||||||
|
|
Loading…
Add table
Reference in a new issue