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
40 40
41enum {41enum {
42 P_LET, P_SET, P_IF, P_LAMBDA, P_MAC, P_WHILE, P_QUOTE, P_AND, P_OR, P_BEGIN, P_CONS,42 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,
44 P_ATOM, P_NUMBER, P_BOOLEAN,44 P_ATOM, P_NUMBER, P_BOOLEAN,
45 P_EQN, P_LT, P_GT, P_LTE, P_GTE, P_ADD, P_SUB, P_MUL, P_DIV,45 P_EQN, P_LT, P_GT, P_LTE, P_GTE, P_ADD, P_SUB, P_MUL, P_DIV,
46 46
@@ -49,13 +49,13 @@ enum { · 2 unmodified lines
49 49
50static const char *primnames[P_MAX] = {50static const char *primnames[P_MAX] = {
51 "let", "define", "if", "lambda", "mac", "while", "quote", "and", "or", "begin", "cons",51 "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",
53 "atom?", "number?", "boolean?",53 "atom?", "number?", "boolean?",
54 "=", "<", ">", "<=", ">=", "+", "-", "*", "/",54 "=", "<", ">", "<=", ">=", "+", "-", "*", "/",
55};55};
56 56
57static const char *typenames[AA_TMAX] = {57static const char *typenames[AA_TMAX] = {
58 "pair", "free", "nil", "number", "symbol", "string",58 "pair", "free", "()", "number", "symbol", "string",
59 "func", "macro", "prim", "cfunc", "ptr", "bool",59 "func", "macro", "prim", "cfunc", "ptr", "bool",
60};60};
61 61
@@ -64,6 +64,10 @@ aaObject False = {{ (void*)(AA_TBOOL << 2 | 1) }, { nil }}; · 2 unmodified lines
64aaObject True = {{ (void*)(AA_TBOOL << 2 | 1) }, { nil }};64aaObject True = {{ (void*)(AA_TBOOL << 2 | 1) }, { nil }};
65static aaObject rparen;65static aaObject rparen;
66 66
67static char prelude[] = "\
68(define newline (lambda () (display \"\\n\")))\
69";
70
67static aaObject *eval(aaContext *ctx, aaObject *obj, aaObject *env, aaObject **bind);71static aaObject *eval(aaContext *ctx, aaObject *obj, aaObject *env, aaObject **bind);
68 72
69aaHandlers *73aaHandlers *
@@ -350,16 +354,27 @@ aa_string(aaContext *ctx, const char *str) · 280 unmodified lines
350}354}
351 355
352aaObject *356aaObject *
353aa_symbol(aaContext *ctx, const char *name)357aa_symbol_find(aaContext *ctx, const char *name)
354{358{
355 aaObject *obj;359 aaObject *obj;
356 360
357 /* try to find in symlist */
358 for(obj = ctx->symlist; !ISNIL(obj); obj = CDR(obj)){361 for(obj = ctx->symlist; !ISNIL(obj); obj = CDR(obj)){
359 if(streq(CAR(CDR(CAR(obj))), name))362 if(streq(CAR(CDR(CAR(obj))), name))
360 return CAR(obj);363 return CAR(obj);
361 }364 }
362 365
366 return nil;
367}
368
369aaObject *
370aa_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
363 /* create new object, push to symlist and return */378 /* create new object, push to symlist and return */
364 obj = object(ctx);379 obj = object(ctx);
365 SETTYPE(obj, AA_TSYMBOL);380 SETTYPE(obj, AA_TSYMBOL);
@@ -429,7 +444,7 @@ aa_write(aaContext *ctx, aaObject *obj, aaWriteFn fn, void *udata, int qt) · 63 unmodified lines
429 444
430 switch(TYPE(obj)){445 switch(TYPE(obj)){
431 case AA_TNIL:446 case AA_TNIL:
432 writestr(ctx, fn, udata, "nil");447 writestr(ctx, fn, udata, "()");
433 break;448 break;
434 449
435 case AA_TNUMBER:450 case AA_TNUMBER:
@@ -641,8 +656,6 @@ read_(aaContext *ctx, aaReadFn fn, void *udata) · 205 unmodified lines
641 n = strtod(buf, &p); /* try to read as number */656 n = strtod(buf, &p); /* try to read as number */
642 if(p != buf && strchr(delimiter, *p))657 if(p != buf && strchr(delimiter, *p))
643 return aa_number(ctx, n);658 return aa_number(ctx, n);
644 if(!strcmp(buf, "nil"))
645 return &Nil;
646 return aa_symbol(ctx, buf);659 return aa_symbol(ctx, buf);
647 }660 }
648}661}
@@ -725,8 +738,13 @@ eval(aaContext *ctx, aaObject *obj, aaObject *env, aaObject **newenv) · 76 unmodified lines
725 aaObject cl, *va, *vb;738 aaObject cl, *va, *vb;
726 int n, gc;739 int n, gc;
727 740
728 if(TYPE(obj) == AA_TSYMBOL)741 if(TYPE(obj) == AA_TSYMBOL){
729 return CDR(getbound(obj, env));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 }
730 if(TYPE(obj) != AA_TPAIR)748 if(TYPE(obj) != AA_TPAIR)
731 return obj;749 return obj;
732 750
@@ -832,7 +850,9 @@ eval(aaContext *ctx, aaObject *obj, aaObject *env, aaObject **newenv) · 99 unmodified lines
832 break;850 break;
833 851
834 case P_EQ:852 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);
836 break;856 break;
837 857
838 case P_ATOM:858 case P_ATOM:
@@ -847,13 +867,12 @@ eval(aaContext *ctx, aaObject *obj, aaObject *env, aaObject **newenv) · 8 unmodified lines
847 res = aa_bool(ctx, aa_type(ctx, evalarg()) == AA_TBOOL);867 res = aa_bool(ctx, aa_type(ctx, evalarg()) == AA_TBOOL);
848 break;868 break;
849 869
850 case P_PRINT:870 case P_DISPLAY:
851 while(!ISNIL(arg)){871 while(!ISNIL(arg)){
852 aa_writefp(ctx, evalarg(), &ctx->fd[1]);872 aa_writefp(ctx, evalarg(), &ctx->fd[1]);
853 if(!ISNIL(arg))873 if(!ISNIL(arg))
854 Bputc(&ctx->fd[1], ' ');874 Bputc(&ctx->fd[1], ' ');
855 }875 }
856 Bputc(&ctx->fd[1], '\n');
857 break;876 break;
858 877
859 case P_EQN: numcmpop(==); break;878 case P_EQN: numcmpop(==); break;
@@ -907,12 +926,19 @@ aa_eval(aaContext *ctx, aaObject *obj) · 47 unmodified lines
907 return eval(ctx, obj, &Nil, nil);926 return eval(ctx, obj, &Nil, nil);
908}927}
909 928
929static int
930eof(Biobufhdr *, void *, long)
931{
932 return 0;
933}
934
910aaContext *935aaContext *
911aa_open(void *ptr, int size, int flags)936aa_open(void *ptr, int size, int flags)
912{937{
913 int i, save;938 int i, save;
914 aaContext *ctx;939 aaContext *ctx;
915 aaObject *v;940 aaObject *v;
941 Biobuf b;
916 942
917 /* init context struct */943 /* init context struct */
918 ctx = ptr;944 ctx = ptr;
@@ -956,6 +982,15 @@ aa_open(void *ptr, int size, int flags) · 37 unmodified lines
956 Binit(&ctx->fd[2], 2, OWRITE);982 Binit(&ctx->fd[2], 2, OWRITE);
957 }983 }
958 984
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
959 return ctx;994 return ctx;
960}995}
961 996
aa.h+1−0
@@ -84,6 +84,7 @@ aaObject *aa_cons(aaContext *ctx, aaObject *car, aaObject *cdr); · 83 unmodified lines
84aaObject *aa_bool(aaContext *ctx, int b);84aaObject *aa_bool(aaContext *ctx, int b);
85aaObject *aa_number(aaContext *ctx, aaNumber n);85aaObject *aa_number(aaContext *ctx, aaNumber n);
86aaObject *aa_string(aaContext *ctx, const char *str);86aaObject *aa_string(aaContext *ctx, const char *str);
87aaObject *aa_symbol_find(aaContext *ctx, const char *name);
87aaObject *aa_symbol(aaContext *ctx, const char *name);88aaObject *aa_symbol(aaContext *ctx, const char *name);
88aaObject *aa_cfunc(aaContext *ctx, aaCFunc fn);89aaObject *aa_cfunc(aaContext *ctx, aaCFunc fn);
89aaObject *aa_ptr(aaContext *ctx, void *ptr);90aaObject *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