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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy