@@ -223,6 +223,7 @@ volatile flags_t Flags = 0b00001; // PRINTREADABLY set by default
223
223
224
224
// Forward references
225
225
object* tee;
226
+ bool builtin_keywordp (object*);
226
227
bool keywordp (object*);
227
228
void pfstring (PGM_P, pfun_t );
228
229
char nthchar (object*, int );
@@ -875,7 +876,7 @@ bool builtinp (symbol_t name) {
875
876
}
876
877
877
878
int checkkeyword (object* obj) {
878
- if (!keywordp (obj)) error (PSTR (" argument is not a keyword" ), obj);
879
+ if (!builtin_keywordp (obj)) error (PSTR (" argument is not a keyword" ), obj);
879
880
builtin_t kname = builtin (obj->name );
880
881
minmax_t context = getminmax (kname);
881
882
if (context != 0 && context != (minmax_t )Context) error (invalidkey, obj);
@@ -1628,7 +1629,7 @@ object* findvalue (object* var, object* env) {
1628
1629
1629
1630
// Handling closures
1630
1631
1631
- object* closure (int tc, symbol_t name, object* function, object* args, object** env) {
1632
+ object* closure (bool tc, symbol_t name, object* function, object* args, object** env) {
1632
1633
object* state = car (function);
1633
1634
function = cdr (function);
1634
1635
int trace = 0 ;
@@ -1702,12 +1703,12 @@ object* apply (object* function, object* args, object* env) {
1702
1703
} else function = eval (function, env);
1703
1704
}
1704
1705
if (consp (function) && isbuiltin (car (function), LAMBDA)) {
1705
- object* result = closure (0 , sym (NIL), function, args, &env);
1706
+ object* result = closure (false , sym (NIL), function, args, &env);
1706
1707
return eval (result, env);
1707
1708
}
1708
1709
if (consp (function) && isbuiltin (car (function), CLOSURE)) {
1709
1710
function = cdr (function);
1710
- object* result = closure (0 , sym (NIL), function, args, &env);
1711
+ object* result = closure (false , sym (NIL), function, args, &env);
1711
1712
return eval (result, env);
1712
1713
}
1713
1714
error (PSTR (" illegal function" ), function);
@@ -6773,14 +6774,24 @@ void testescape () {
6773
6774
}
6774
6775
6775
6776
/*
6776
- keywordp - check that obj is a keyword
6777
+ builtin_keywordp - check that obj is a built-in keyword
6777
6778
*/
6778
- bool keywordp (object* obj) {
6779
+ bool builtin_keywordp (object* obj) {
6779
6780
if (!(symbolp (obj) && builtinp (obj->name ))) return false ;
6780
6781
builtin_t name = builtin (obj->name );
6781
6782
PGM_P s = (char *)pgm_read_ptr (&(getentry (name)->string ));
6782
6783
char c = pgm_read_byte (&s[0 ]);
6783
- return (c == ' :' );
6784
+ return c == ' :' ;
6785
+ }
6786
+
6787
+ bool keywordp (object* obj) {
6788
+ if (obj == nil) return false ;
6789
+ if (builtin_keywordp (obj)) return true ;
6790
+ symbol_t name = obj->name ;
6791
+ if ((name & 3 ) != 0 ) return false ; // Packed symbols are never keywords
6792
+ object* first_chunk = (object*)name;
6793
+ if (!first_chunk) return false ;
6794
+ return (((first_chunk->chars ) >> ((sizeof (int ) - 1 ) * 8 )) & 255 ) == ' :' ;
6784
6795
}
6785
6796
6786
6797
// Main evaluator
@@ -6789,22 +6800,22 @@ bool keywordp (object* obj) {
6789
6800
eval - the main Lisp evaluator
6790
6801
*/
6791
6802
object* eval (object* form, object* env) {
6792
- int TC= 0 ;
6803
+ bool tailcall = false ;
6793
6804
EVAL:
6794
6805
// Enough space?
6795
6806
if (Freespace <= WORKSPACESIZE>>4 ) gc (form, env);
6796
6807
// Escape
6797
6808
if (tstflag (ESCAPE)) { clrflag (ESCAPE); error2 (PSTR (" escape!" ));}
6798
6809
if (!tstflag (NOESC)) testescape ();
6799
6810
// Stack overflow check
6800
- if (abs (static_cast <int *>(StackBottom) - &TC ) > MAX_STACK) error (PSTR (" C stack overflow" ), form);
6811
+ if (abs (static_cast <bool *>(StackBottom) - &tailcall ) > MAX_STACK) error (PSTR (" C stack overflow" ), form);
6801
6812
6802
6813
if (form == NULL ) return nil;
6803
6814
6804
- if (form->type >= NUMBER && form->type <= STRING) return form;
6815
+ if (form->type >= NUMBER && form->type <= STRING) return form; // Literal
6805
6816
6806
6817
if (symbolp (form)) {
6807
- if (nthchar ( princtostring ( form), 0 ) == ' : ' ) return form; // Keyword
6818
+ if (keywordp ( form)) return form; // Keyword
6808
6819
symbol_t name = form->name ;
6809
6820
object* pair = value (name, env);
6810
6821
if (pair != NULL ) return cdr (pair);
@@ -6829,7 +6840,7 @@ object* eval (object* form, object* env) {
6829
6840
builtin_t name = builtin (function->name );
6830
6841
6831
6842
if ((name == LET) || (name == LETSTAR)) {
6832
- int TCstart = TC ;
6843
+ bool old_tailcall = tailcall ;
6833
6844
if (args == NULL ) error2 (noargument);
6834
6845
object* assigns = first (args);
6835
6846
if (!listp (assigns)) error (notalist, assigns);
@@ -6838,17 +6849,17 @@ object* eval (object* form, object* env) {
6838
6849
protect (newenv);
6839
6850
while (assigns != NULL ) {
6840
6851
object* assign = car (assigns);
6841
- if (!consp (assign)) push (cons (assign,nil), newenv);
6842
- else if (cdr (assign) == NULL ) push (cons (first (assign),nil), newenv);
6843
- else push (cons (first (assign),eval (second (assign),env)), newenv);
6852
+ if (!consp (assign)) push (cons (assign, nil), newenv);
6853
+ else if (cdr (assign) == NULL ) push (cons (first (assign), nil), newenv);
6854
+ else push (cons (first (assign), eval (second (assign), env)), newenv);
6844
6855
car (GCStack) = newenv;
6845
6856
if (name == LETSTAR) env = newenv;
6846
6857
assigns = cdr (assigns);
6847
6858
}
6848
6859
env = newenv;
6849
6860
unprotect ();
6850
6861
form = tf_progn (forms,env);
6851
- TC = TCstart ;
6862
+ tailcall = old_tailcall ;
6852
6863
goto EVAL;
6853
6864
}
6854
6865
@@ -6861,7 +6872,7 @@ object* eval (object* form, object* env) {
6861
6872
if (pair != NULL ) push (pair, envcopy);
6862
6873
env = cdr (env);
6863
6874
}
6864
- return cons (bsymbol (CLOSURE), cons (envcopy,args));
6875
+ return cons (bsymbol (CLOSURE), cons (envcopy, args));
6865
6876
}
6866
6877
uint8_t ft = fntype (getminmax (name));
6867
6878
@@ -6875,23 +6886,23 @@ object* eval (object* form, object* env) {
6875
6886
Context = name;
6876
6887
checkargs (args);
6877
6888
form = ((fn_ptr_type)lookupfn (name))(args, env);
6878
- TC = 1 ;
6889
+ tailcall = true ;
6879
6890
goto EVAL;
6880
6891
}
6881
6892
if (ft == OTHER_FORMS) error (PSTR (" can't be used as a function" ), function);
6882
6893
}
6883
6894
6884
6895
// Evaluate the parameters - result in head
6885
6896
object* fname = car (form);
6886
- int TCstart = TC ;
6897
+ bool old_tailcall = tailcall ;
6887
6898
object* head = cons (eval (fname, env), NULL );
6888
6899
protect (head); // Don't GC the result list
6889
6900
object* tail = head;
6890
6901
form = cdr (form);
6891
6902
int nargs = 0 ;
6892
6903
6893
6904
while (form != NULL ){
6894
- object* obj = cons (eval (car (form),env),NULL );
6905
+ object* obj = cons (eval (car (form), env), NULL );
6895
6906
cdr (tail) = obj;
6896
6907
tail = obj;
6897
6908
form = cdr (form);
@@ -6903,7 +6914,7 @@ object* eval (object* form, object* env) {
6903
6914
6904
6915
if (symbolp (function)) {
6905
6916
builtin_t bname = builtin (function->name );
6906
- if (!builtinp (function->name )) error (PSTR (" not valid here " ), fname);
6917
+ if (!builtinp (function->name )) error (PSTR (" can't call a symbol " ), fname);
6907
6918
Context = bname;
6908
6919
checkminmax (bname, nargs);
6909
6920
object* result = ((fn_ptr_type)lookupfn (bname))(args, env);
@@ -6916,7 +6927,7 @@ object* eval (object* form, object* env) {
6916
6927
if (!listp (fname)) name = fname->name ;
6917
6928
6918
6929
if (isbuiltin (car (function), LAMBDA)) {
6919
- form = closure (TCstart , name, function, args, &env);
6930
+ form = closure (old_tailcall , name, function, args, &env);
6920
6931
unprotect ();
6921
6932
int trace = tracing (fname->name );
6922
6933
if (trace) {
@@ -6928,21 +6939,23 @@ object* eval (object* form, object* env) {
6928
6939
printobject (result, pserial); pln (pserial);
6929
6940
return result;
6930
6941
} else {
6931
- TC = 1 ;
6942
+ tailcall = true ;
6932
6943
goto EVAL;
6933
6944
}
6934
6945
}
6935
6946
6936
6947
if (isbuiltin (car (function), CLOSURE)) {
6937
6948
function = cdr (function);
6938
- form = closure (TCstart , name, function, args, &env);
6949
+ form = closure (old_tailcall , name, function, args, &env);
6939
6950
unprotect ();
6940
- TC = 1 ;
6951
+ tailcall = true ;
6941
6952
goto EVAL;
6942
6953
}
6943
6954
6944
6955
}
6945
- error (PSTR (" illegal function" ), fname); return nil;
6956
+ error (PSTR (" illegal function" ), fname);
6957
+ // unreachable
6958
+ return nil;
6946
6959
}
6947
6960
6948
6961
// Print functions
0 commit comments