History

more work

* don't treat undefined variables as nil, hide nil instead and produce errors properly * print → display & newline * prelude * aa_symbol_find

Sigrid Haflínudóttir committed 6 years ago

Commit 181e1b01 parent 3802e352 files · +49 −13Browse files

Unified · Split

2 files
  1. aa.c +48 −13
  2. aa.h +1 −0
aa.c+48−13
@@ -40,7 +40,7 @@ typedef struct { · 39 unmodified lines
4040
4141 enum {
4242 P_LET, P_SET, P_IF, P_LAMBDA, P_MAC, P_WHILE, P_QUOTE, P_AND, P_OR, P_BEGIN, P_CONS,
43− P_CAR, P_CDR, P_SETCAR, P_SETCDR, P_LIST, P_NOT, P_EQ, P_PRINT,
43+ P_CAR, P_CDR, P_SETCAR, P_SETCDR, P_LIST, P_NOT, P_EQ, P_DISPLAY,
4444 P_ATOM, P_NUMBER, P_BOOLEAN,
4545 P_EQN, P_LT, P_GT, P_LTE, P_GTE, P_ADD, P_SUB, P_MUL, P_DIV,
4646
@@ -49,13 +49,13 @@ enum { · 2 unmodified lines
4949
5050 static const char *primnames[P_MAX] = {
5151 "let", "define", "if", "lambda", "mac", "while", "quote", "and", "or", "begin", "cons",
52− "car", "cdr", "setcar", "setcdr", "list", "not", "eq?", "print",
52+ "car", "cdr", "setcar", "setcdr", "list", "not", "eq?", "display",
5353 "atom?", "number?", "boolean?",
5454 "=", "<", ">", "<=", ">=", "+", "-", "*", "/",
5555 };
5656
5757 static const char *typenames[AA_TMAX] = {
58− "pair", "free", "nil", "number", "symbol", "string",
58+ "pair", "free", "()", "number", "symbol", "string",
5959 "func", "macro", "prim", "cfunc", "ptr", "bool",
6060 };
6161
@@ -64,6 +64,10 @@ aaObject False = {{ (void*)(AA_TBOOL << 2 | 1) }, { nil }}; · 2 unmodified lines
6464 aaObject True = {{ (void*)(AA_TBOOL << 2 | 1) }, { nil }};
6565 static aaObject rparen;
6666
67+static char prelude[] = "\
68+(define newline (lambda () (display \"\\n\")))\
69+";
70+
6771 static aaObject *eval(aaContext *ctx, aaObject *obj, aaObject *env, aaObject **bind);
6872
6973 aaHandlers *
@@ -350,16 +354,27 @@ aa_string(aaContext *ctx, const char *str) · 280 unmodified lines
350354 }
351355
352356 aaObject *
353−aa_symbol(aaContext *ctx, const char *name)
357+aa_symbol_find(aaContext *ctx, const char *name)
354358 {
355359 aaObject *obj;
356360
357− /* try to find in symlist */
358361 for(obj = ctx->symlist; !ISNIL(obj); obj = CDR(obj)){
359362 if(streq(CAR(CDR(CAR(obj))), name))
360363 return CAR(obj);
361364 }
362365
366+ return nil;
367+}
368+
369+aaObject *
370+aa_symbol(aaContext *ctx, const char *name)
371+{
372+ aaObject *obj;
373+
374+ /* try to find it first */
375+ if((obj = aa_symbol_find(ctx, name)) != nil)
376+ return obj;
377+
363378 /* create new object, push to symlist and return */
364379 obj = object(ctx);
365380 SETTYPE(obj, AA_TSYMBOL);
@@ -429,7 +444,7 @@ aa_write(aaContext *ctx, aaObject *obj, aaWriteFn fn, void *udata, int qt) · 63 unmodified lines
429444
430445 switch(TYPE(obj)){
431446 case AA_TNIL:
432− writestr(ctx, fn, udata, "nil");
447+ writestr(ctx, fn, udata, "()");
433448 break;
434449
435450 case AA_TNUMBER:
@@ -641,8 +656,6 @@ read_(aaContext *ctx, aaReadFn fn, void *udata) · 205 unmodified lines
641656 n = strtod(buf, &p); /* try to read as number */
642657 if(p != buf && strchr(delimiter, *p))
643658 return aa_number(ctx, n);
644− if(!strcmp(buf, "nil"))
645− return &Nil;
646659 return aa_symbol(ctx, buf);
647660 }
648661 }
@@ -725,8 +738,13 @@ eval(aaContext *ctx, aaObject *obj, aaObject *env, aaObject **newenv) · 76 unmodified lines
725738 aaObject cl, *va, *vb;
726739 int n, gc;
727740
728− if(TYPE(obj) == AA_TSYMBOL)
729− return CDR(getbound(obj, env));
741+ if(TYPE(obj) == AA_TSYMBOL){
742+ arg = getbound(obj, env);
743+ res = CDR(arg);
744+ if(ISNIL(res))
745+ aa_error(ctx, "unbound variable: %s", STRBUF(CAR(arg)));
746+ return res;
747+ }
730748 if(TYPE(obj) != AA_TPAIR)
731749 return obj;
732750
@@ -832,7 +850,9 @@ eval(aaContext *ctx, aaObject *obj, aaObject *env, aaObject **newenv) · 99 unmodified lines
832850 break;
833851
834852 case P_EQ:
835− res = aa_bool(ctx, aa_nextarg(ctx, &arg, 0) == aa_nextarg(ctx, &arg, 0));
853+ va = evalarg();
854+ vb = evalarg();
855+ res = aa_bool(ctx, va == vb);
836856 break;
837857
838858 case P_ATOM:
@@ -847,13 +867,12 @@ eval(aaContext *ctx, aaObject *obj, aaObject *env, aaObject **newenv) · 8 unmodified lines
847867 res = aa_bool(ctx, aa_type(ctx, evalarg()) == AA_TBOOL);
848868 break;
849869
850− case P_PRINT:
870+ case P_DISPLAY:
851871 while(!ISNIL(arg)){
852872 aa_writefp(ctx, evalarg(), &ctx->fd[1]);
853873 if(!ISNIL(arg))
854874 Bputc(&ctx->fd[1], ' ');
855875 }
856− Bputc(&ctx->fd[1], '\n');
857876 break;
858877
859878 case P_EQN: numcmpop(==); break;
@@ -907,12 +926,19 @@ aa_eval(aaContext *ctx, aaObject *obj) · 47 unmodified lines
907926 return eval(ctx, obj, &Nil, nil);
908927 }
909928
929+static int
930+eof(Biobufhdr *, void *, long)
931+{
932+ return 0;
933+}
934+
910935 aaContext *
911936 aa_open(void *ptr, int size, int flags)
912937 {
913938 int i, save;
914939 aaContext *ctx;
915940 aaObject *v;
941+ Biobuf b;
916942
917943 /* init context struct */
918944 ctx = ptr;
@@ -956,6 +982,15 @@ aa_open(void *ptr, int size, int flags) · 37 unmodified lines
956982 Binit(&ctx->fd[2], 2, OWRITE);
957983 }
958984
985+ i = strlen(prelude);
986+ Binits(&b, -1, OREAD, (uchar*)prelude, i);
987+ b.icount = -i;
988+ Biofn(&b, eof);
989+ while((v = aa_readfp(ctx, &b)) != nil){
990+ aa_eval(ctx, v);
991+ aa_restoregc(ctx, save);
992+ }
993+
959994 return ctx;
960995 }
961996
aa.h+1−0
@@ -84,6 +84,7 @@ aaObject *aa_cons(aaContext *ctx, aaObject *car, aaObject *cdr); · 83 unmodified lines
8484 aaObject *aa_bool(aaContext *ctx, int b);
8585 aaObject *aa_number(aaContext *ctx, aaNumber n);
8686 aaObject *aa_string(aaContext *ctx, const char *str);
87+aaObject *aa_symbol_find(aaContext *ctx, const char *name);
8788 aaObject *aa_symbol(aaContext *ctx, const char *name);
8889 aaObject *aa_cfunc(aaContext *ctx, aaCFunc fn);
8990 aaObject *aa_ptr(aaContext *ctx, void *ptr);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t