Skip to content

Commit d2b2fc4

Browse files
Add fix for ('print 'foo) bug
no fix yet for `('progn 'foo)` evaluating the form twice
1 parent 6ff1512 commit d2b2fc4

File tree

1 file changed

+35
-5
lines changed

1 file changed

+35
-5
lines changed

ulisp.hpp

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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
128129
enum token { UNUSED, OPEN_PAREN, CLOSE_PAREN, SINGLE_QUOTE, PERIOD, BACKTICK, COMMA, COMMA_AT };
129130
enum 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
225226
bool builtin_keywordp (object*);
227+
inline bool builtinp (symbol_t name);
226228
bool keywordp (object*);
227229
void pfstring (const char*, pfun_t);
228230
char 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

Comments
 (0)