@@ -87,6 +87,7 @@ Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, MOSI, SCK, TFT_RST);
8787#define integerp (x ) ((x) != NULL && (x)->type == NUMBER)
8888#define floatp (x ) ((x) != NULL && (x)->type == FLOAT)
8989#define symbolp (x ) ((x) != NULL && (x)->type == SYMBOL)
90+ #define bfunctionp (x ) ((x) != NULL && (x)->type == BFUNCTION)
9091#define stringp (x ) ((x) != NULL && (x)->type == STRING)
9192#define characterp (x ) ((x) != NULL && (x)->type == CHARACTER)
9293#define arrayp (x ) ((x) != NULL && (x)->type == ARRAY)
@@ -124,7 +125,7 @@ Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, MOSI, SCK, TFT_RST);
124125// Constants
125126
126127#define TRACEMAX 3 // Number of traced functions
127- enum type { ZZERO=0 , SYMBOL=2 , CODE=4 , NUMBER=6 , STREAM =8 , CHARACTER =10 , FLOAT =12 , ARRAY =14 , STRING =16 , PAIR =18 }; // ARRAY STRING and PAIR must be last
128+ enum type { ZZERO=0 , SYMBOL=2 , CODE=4 , NUMBER=6 , BFUNCTION =8 , STREAM =10 , CHARACTER =12 , FLOAT =14 , ARRAY =16 , STRING =18 , PAIR= 20 }; // ARRAY, STRING, and PAIR must be last
128129enum token { UNUSED, OPEN_PAREN, CLOSE_PAREN, SINGLE_QUOTE, PERIOD, BACKTICK, COMMA, COMMA_AT };
129130enum fntypes_t { OTHER_FORMS, SPECIAL_FORMS, FUNCTIONS, SPECIAL_SYMBOLS };
130131
@@ -223,6 +224,7 @@ volatile flags_t Flags = 1; // PRINTREADABLY set by default
223224
224225// Forward references
225226bool builtin_keywordp (object*);
227+ inline bool builtinp (symbol_t name);
226228bool keywordp (object*);
227229void pfstring (const char *, pfun_t );
228230char nthchar (object*, int );
@@ -505,6 +507,19 @@ object* symbol (symbol_t name) {
505507 return ptr;
506508}
507509
510+ object* bfunction_from_symbol (object* symbol) {
511+ if (!(symbolp (symbol) && builtinp (symbol->name ))) return nil;
512+ symbol_t nm = symbol->name ;
513+ for (int i=0 ; i<WORKSPACESIZE; i++) {
514+ object* obj = &Workspace[i];
515+ if (obj->type == BFUNCTION && obj->name == nm) return obj;
516+ }
517+ object* ptr = myalloc ();
518+ ptr->type = BFUNCTION;
519+ ptr->name = nm;
520+ return ptr;
521+ }
522+
508523/*
509524 bsymbol - make a built-in symbol
510525*/
@@ -7279,6 +7294,7 @@ object* eval (object* form, object* env) {
72797294 if (form->type >= NUMBER && form->type <= STRING) return form; // Literal
72807295
72817296 if (symbolp (form)) {
7297+ if (form == tee) return form;
72827298 if (keywordp (form)) return form; // Keyword
72837299 symbol_t name = form->name ;
72847300 object* pair = value (name, env);
@@ -7289,7 +7305,7 @@ object* eval (object* form, object* env) {
72897305 else if (builtinp (name)) {
72907306 builtin_t bname = builtin (name);
72917307 if (fntype (getminmax (bname)) == SPECIAL_SYMBOLS) return ((fn_ptr_type)lookupfn (bname))(NULL , env);
7292- return form;
7308+ return bfunction_from_symbol ( form) ;
72937309 }
72947310 Context = NIL;
72957311 error (" undefined" , form);
@@ -7304,7 +7320,7 @@ object* eval (object* form, object* env) {
73047320 if (function == NULL ) error2 (" can't call nil" );
73057321 if (!listp (args)) error (" can't evaluate a dotted pair" , args);
73067322
7307- // List starts with a builtin symbol ?
7323+ // List starts with a builtin special form ?
73087324 if (symbolp (function) && builtinp (function->name )) {
73097325 builtin_t name = builtin (function->name );
73107326
@@ -7381,10 +7397,15 @@ object* eval (object* form, object* env) {
73817397
73827398 function = car (head);
73837399 args = cdr (head);
7384-
7400+
7401+ // fail early on calling a symbol
73857402 if (symbolp (function)) {
7403+ Context = NIL;
7404+ error (" can't call a symbol" , function);
7405+ }
7406+ if (bfunctionp (function)) {
73867407 builtin_t bname = builtin (function->name );
7387- if (!builtinp (function->name )) error (" can't call a symbol" , fname );
7408+ if (!builtinp (function->name )) error (" can't call a symbol" , function );
73887409 Context = bname;
73897410 checkminmax (bname, nargs);
73907411 object* result = ((fn_ptr_type)lookupfn (bname))(args, env);
@@ -7688,6 +7709,15 @@ void printobject (object* form, pfun_t pfun) {
76887709 else if (integerp (form)) pint (form->integer , pfun);
76897710 else if (floatp (form)) pfloat (form->single_float , pfun);
76907711 else if (symbolp (form)) { if (form->name != sym (NOTHING)) printsymbol (form, pfun); }
7712+ else if (bfunctionp (form)) {
7713+ pfstring (" <built-in " , pfun);
7714+ switch (fntype (getminmax (builtin (form->name )))) {
7715+ case FUNCTIONS: pfstring (" function " , pfun); break ;
7716+ case SPECIAL_FORMS: pfstring (" special form " , pfun); break ;
7717+ }
7718+ printsymbol (form, pfun);
7719+ pfun (' >' );
7720+ }
76917721 else if (characterp (form)) pcharacter (form->chars , pfun);
76927722 else if (stringp (form)) printstring (form, pfun);
76937723 else if (arrayp (form)) printarray (form, pfun);
0 commit comments