From 2b03b74037e5844c4bc05e9febda45e560a46f42 Mon Sep 17 00:00:00 2001 From: Daniel Cerqueira Date: Thu, 29 May 2025 21:17:42 +0100 Subject: newNumber() with string argument and continue making numbers neutral - also update .gitignore --- .gitignore | 1 + README.md | 101 +++++++++++++------------- TAGS | 106 ---------------------------- TODO | 3 +- liblali.c | 192 ++++++++++++++++++++++++++++++-------------------- liblali.h | 9 ++- work-in-progress/TAGS | 104 --------------------------- 7 files changed, 176 insertions(+), 340 deletions(-) delete mode 100644 TAGS delete mode 100644 work-in-progress/TAGS diff --git a/.gitignore b/.gitignore index 7c502a1..10b49d1 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ lali liblali.a *.o README.html +TAGS diff --git a/README.md b/README.md index d193110..cb99cfc 100644 --- a/README.md +++ b/README.md @@ -51,23 +51,26 @@ mind. What you write, becomes part of who you are. ### Numeric operations -lali supports the five arithmetic operations `+`, `-`, `*`, `/`, `%` (with `%` the -operands are automatically converted to integer) as well as the relational +For lali to recognize numbers, numbers have to be prefixed or by `+` (for positive +numbers) or by `-` (for negative numbers). + +There is support for the five arithmetic operations `+`, `-`, `*`, `/`, `%` (with +`%` the operands are automatically converted to integer) as well as the relational operations `!` (different), `<`, `>`: - (- 5) ; -5 - (- 5 3.2 .6) ; 1.2 - (< 2 4 6.8) ; t - (> 4 8) ; f - (! 4 4) ; f + (- +5) ; -5 + (- +5 +3.2 +.6) ; +1.2 + (< +2 +4 +6.8) ; t + (> +4 +8) ; f + (! +4 +4) ; f #### Random number operation `(random [number])` takes no or one number argument, returns a random number below `number` until 0. - (random) ; 2.1442e+09 - (random 2) ; returns 0 or 1 + (random) ; +747528572 + (random 2) ; returns +0 or +1 ### Processing operations @@ -93,19 +96,19 @@ do something at the beginning, because other cons cells should never have `()` i `(list ...)` returns a list containing the supplied arguments: (list) ; () - (list 1 2 3) ; (1 2 3) - (list 1 2 (+ 1 2)) ; (1 2 3) + (list +1 +2 +3) ; (+1 +2 +3) + (list +1 +2 (+ +1 +2)) ; (+1 +2 +3) `(cons x y)` creates a new cons cell, the `car` of which is `x` and the `cdr` of which is `y`: - (cons 1 2) ; (1 . 2) - (cons 1 '(2)) ; (1 2) + (cons +1 +2) ; (+1 . +2) + (cons +1 '(+2)) ; (+1 +2) `(car x)`, `(cdr x)` return the `car` and `cdr` of a list respectively: - (car '(1 2 3)) ; 1 - (cdr '(1 2 3)) ; (2 3) + (car '(a b c)) ; a + (cdr '(a b c)) ; (b c) ### Predicates @@ -113,62 +116,62 @@ which is `y`: numbers with different values, or if they are string objects with different contents: - (dif 1 1) ; f - (dif 1 2) ; t + (dif +1 +1) ; f + (dif +1 +2) ; t (dif 'a 'a) ; f (dif 'a 'b) ; t (dif t t) ; f (dif t f) ; t - (dif '(1 2) '(1 2)) ; t + (dif '(a b) '(a b)) ; t `(differ x y)` returns `t` if `x` and `y` are objects of different structure and each of their elements satisfy the `dif` predicate, otherwise `f`: - (differ '(1 2) '(1)) ; t - (differ '(1 2) '(1 2)) ; f + (differ '(a b) '(a)) ; t + (differ '(a b) '(a b)) ; f `(space x)` returns `t` if `x` is an empty list `()`, otherwise `f`: (space ()) ; t - (space 1) ; f + (space +1) ; f (space t) ; f - (space '(1 2)) ; f + (space '(a b)) ; f `(ap x)` returns `t` if `x` is "an existing thing" (not an empty list `()`), otherwise `f`: (ap ()) ; f - (ap 1) ; t + (ap +1) ; t (ap t) ; t - (ap '(1 2)) ; t + (ap '(a b)) ; t `(atom x)` returns `t` if `x` is an atom (and not an empty list `()`), otherwise `f`: (atom ()) ; f - (atom 1) ; t + (atom +1) ; t (atom t) ; t - (atom '(1 2)) ; f + (atom '(a b)) ; f `(listp x)` returns `t` if `x` is either an empty list `()`, or a list with atom(s), otherwise `f`: (listp ()) ; t - (listp 1) ; f + (listp +1) ; f (listp t) ; f - (listp '(1 2)) ; t + (listp '(a b)) ; t `(consp x)` returns `t` if `x` is a list with atom(s), otherwise `f`: (consp ()) ; f - (consp 1) ; f + (consp +1) ; f (consp t) ; f - (consp '(1 2)) ; t + (consp '(a b)) ; t `(zerop x)` returns `t` if `x` is the number zero, otherwise `f`: - (zerop 0) ; t - (zerop 1) ; f + (zerop +0) ; t + (zerop +1) ; f (zerop t) ; error: t is not a number ### Logical operations @@ -182,16 +185,16 @@ arguments. Otherwise, it returns the value produced by evaluating its last argument. If no arguments are supplied, `and` returns `t`: (and) ; t - (and 1 2 3) ; 3 - (and 1 f 3) ; f + (and +1 +2 +3) ; +3 + (and +1 f +3) ; f `(or ...)` evaluates its arguments one at a time from left to right. As soon as any argument does not evaluate to `f`, `or` returns its value without evaluating the remaining arguments. Otherwise, it returns `f`: (or) ; f - (or 1 2 3) ; 1 - (or f f 3) ; 3 + (or +1 +2 +3) ; +1 + (or f f +3) ; +3 ### Conditionals @@ -255,10 +258,10 @@ evaluation of further expressions and returning the symbol of the evaluation of the symbol of `expr-var-A` evaluated. More than one `expr-var`-`expr-val` pair can be given. `set` returns the value bound to the last symbol: - (set 'a 1 - 'b 2) ; 2 - a ; 1 - b ; 2 + (set 'a +1 + 'b +2) ; +2 + a ; +1 + b ; +2 ### Defining functions @@ -270,18 +273,18 @@ variable number of arguments: ((lambda () 'Hello)) ; Hello ((lambda (a b) - (+ a b)) 1 2) ; 3 + (+ a b)) +1 +2) ; +3 ((lambda (a b . c) - c) 1 2 3 4 5) ; (3 4 5) + c) +1 +2 +3 +4 +5) ; (+3 +4 +5) ((lambda args - args) 1 2 3 4 5) ; (1 2 3 4 5) + args) +1 +2 +3 +4 +5) ; (+1 +2 +3 +4 +5) `(defun name params expr...)` creates a function and binds it to the symbol `name`: (defun plus1 (x) - (+ x 1)) ; # - (plus1 2) ; 3 + (+ x +1)) ; # + (plus1 +2) ; +3 ### Defining macros @@ -297,9 +300,9 @@ returning a new expression as output. Imagine we want to implement `(when test expr...)`: - (set 'x '(1 2 3)) ; (1 2 3) + (set 'x '(+1 +2 +3)) ; (+1 +2 +3) (when (consp x) - (car x)) ; 1 + (car x)) ; +1 (set 'x 'hello) (when (consp x) (car x)) ; n @@ -312,7 +315,7 @@ would be evaluated as soon as `when` is called: (car x)) ; error: Hello is not a list However, we can implement `when` as a macro that wraps `expr...` in a call to -`if`: +`cond`: (defmacro when (test . expr) (list cond (list test (cons 'prog expr)))) @@ -361,7 +364,7 @@ outputting them without the initial/ending parenthesis: `(time)` gives a timestamp in (sec minute hour day month year dow dst utcoff). - (time) ; (23 54 17 13 5 2025 2 t 3600) + (time) ; (+34 +22 +17 +29 +5 +2025 +4 t +3600) ## Copyright diff --git a/TAGS b/TAGS deleted file mode 100644 index 59105de..0000000 --- a/TAGS +++ /dev/null @@ -1,106 +0,0 @@ - -lali.c,85 -#define YEARS 37,1298 -void runFile(41,1416 -void runREPL(59,1816 -int main(87,2375 - -liblali.c,3583 -#define MEMORY_SIZE 37,1298 -static Memory *memory memory39,1338 -Object *symbols symbols41,1389 -Object *nil nil42,1413 -Object *n n43,1469 -Object *t t44,1522 -Object *f f45,1575 -static unsigned int seed 47,1629 -jmp_buf exceptionEnv;49,1660 -void exceptionWithObject(54,1765 -Object *gcMoveObject(gcMoveObject114,4107 -void gc(136,4806 -size_t memoryAlign(183,6199 -Object *memoryAllocObject(memoryAllocObject187,6306 -Object *newObject(newObject216,7294 -Object *newObjectFrom(newObjectFrom220,7399 -Object *newNumber(newNumber226,7586 -Object *newObjectWithString(newObjectWithString232,7731 -Object *newStringWithLength(newStringWithLength239,7974 -Object *newString(newString267,8904 -Object *newCons(newCons271,9015 -Object *newSymbolWithLength(newSymbolWithLength278,9186 -Object *newSymbol(newSymbol293,9696 -Object *newObjectWithClosure(newObjectWithClosure297,9807 -Object *newLambda(newLambda318,10483 -Object *newMacro(newMacro322,10635 -Object *newPrimitive(newPrimitive326,10785 -Object *newEnv(newEnv333,10977 -int streamGetc(372,12345 -Stream *streamSeek(streamSeek440,14380 -int streamPeek(448,14557 -int readNext(457,14763 -int initialReadNext(468,14980 -int peekForward(479,15217 -int peekNext(486,15393 -int readWhile(490,15464 -Object *readUnary(readUnary499,15640 -Object *readString(readString512,16017 -int isSymbolChar(528,16547 -Object *readNumberOrSymbol(readNumberOrSymbol533,16672 -Object *reverseList(reverseList565,17640 -Object *readList(readList578,17840 -Object *readExpr(readExpr610,18830 -void writeObject(633,19549 -#define CASE(635,19637 -#undef CASE642,19948 -#define CASE(678,20949 -#undef CASE687,21348 -Object *envLookup(envLookup713,22169 -Object *envAdd(envAdd728,22526 -Object *envSet(envSet738,22829 -Object *primitiveSpace(primitiveSpace760,23413 -Object *primitiveAtom(primitiveAtom764,23506 -Object *primitiveDif(primitiveDif782,24090 -Object *primitiveCar(primitiveCar793,24495 -Object *primitiveCdr(primitiveCdr804,24731 -Object *primitiveCons(primitiveCons815,24967 -Object *primitivePrint(primitivePrint822,25143 -Object *primitivePrinc(primitivePrinc828,25284 -Object *primitiveNewline(primitiveNewline834,25426 -Object *primitiveRead(primitiveRead839,25516 -Object *primitiveTime(primitiveTime850,25762 -Object *primitiveRandom(primitiveRandom877,26414 -#define DEFINE_PRIMITIVE_ARITHMETIC(890,26794 -DEFINE_PRIMITIVE_ARITHMETIC(920,28871 -#define DEFINE_PRIMITIVE_RELATIONAL(926,29182 -typedef struct Primitive 954,30979 - char *name;name955,31006 - int nMinArgs,956,31020 - int nMinArgs, nMaxArgs;956,31020 - Object *(* eval)957,31046 -} Primitive;958,31091 -Primitive primitives[primitives960,31105 - PRIMITIVE_EVAL,1000,32893 - PRIMITIVE_QUOTE,1001,32911 - PRIMITIVE_SAY,1002,32930 - PRIMITIVE_SET,1003,32947 - PRIMITIVE_PROG,1004,32964 - PRIMITIVE_PROGS,1005,32982 - PRIMITIVE_COND,1007,33023 - PRIMITIVE_FILL,1008,33041 - PRIMITIVE_LAMBDA,1009,33059 - PRIMITIVE_MACRO1010,33079 -Object *evalSet(evalSet1021,33432 -Object *evalProg(evalProg1047,34162 -Object *progs1(progs11067,34584 -Object *evalProgs(evalProgs1093,35277 -Object *evalCond(evalCond1119,36027 -Object *evalFill(evalFill1142,36609 -Object *evalLambda(evalLambda1165,37191 -Object *evalMacro(evalMacro1172,37378 -Object *expandMacro(expandMacro1179,37563 -Object *expandMacroTo(expandMacroTo1189,37845 -Object *evalList(evalList1203,38235 -Object *evalExpr(evalExpr1217,38607 -#define LISP(1293,41772 -static char *stdlib stdlib1295,41804 -Object *newRootEnv(newRootEnv1351,43430 diff --git a/TODO b/TODO index 0a55ffd..1fea73e 100644 --- a/TODO +++ b/TODO @@ -9,7 +9,8 @@ make unit testing. instead of returning "#number = number; + strcpy(object->string, number); return object; } @@ -545,15 +545,17 @@ Object *readNumberOrSymbol(Stream *stream, GC_PARAM) { if (isdigit(ch)) ch = readWhile(stream, isdigit); if (!isSymbolChar(ch)) - return newSymbolWithLength(TYPE_NUMBER, stream->buffer + offset, - stream->offset - offset, GC_ROOTS); + return newSymbolWithLength(TYPE_NUMBER, + stream->buffer + offset, + stream->offset - offset, GC_ROOTS); if (ch == '.') { ch = streamGetc(stream); if (isdigit(streamPeek(stream))) { ch = readWhile(stream, isdigit); if (!isSymbolChar(ch)) - return newSymbolWithLength(TYPE_NUMBER, stream->buffer + offset, - stream->offset - offset, GC_ROOTS); + return newSymbolWithLength(TYPE_NUMBER, + stream->buffer + offset, + stream->offset - offset, GC_ROOTS); } } } @@ -561,7 +563,8 @@ Object *readNumberOrSymbol(Stream *stream, GC_PARAM) { // non-numeric character encountered, read a symbol readWhile(stream, isSymbolChar); - return newSymbolWithLength(TYPE_SYMBOL, stream->buffer + offset, + return newSymbolWithLength(TYPE_SYMBOL, + (stream->buffer + offset), stream->offset - offset, GC_ROOTS); } @@ -670,14 +673,36 @@ Object *readExpr(Stream *stream, GC_PARAM) { // WRITING OBJECTS //////////////////////////////////////////////////////////// +char *removeZeroPadding(char *string) { + size_t length = 0; + bool floatingPoint = false; + for (; string[length] != '\0'; length++) + if (string[length] == '.') + floatingPoint = true; + + if (!floatingPoint) + return string; + + size_t i = length - 1; + for (; string[i] == '0'; i--) + ; + if (i == 1) + string[i] = '0'; + else if (string[i] == '.') + i--; + + string[i+1] = '\0'; + return string; +} + void writeObject(Object *object, bool readably, FILE *file) { switch (object->type) { #define CASE(type, ...) \ case type: \ fprintf(file, __VA_ARGS__); \ break + CASE(TYPE_NUMBER, "%s", removeZeroPadding(object->string)); /* CASE(TYPE_NUMBER, (object->number < 0) ? "%g" : "+%g", object->number); */ - CASE(TYPE_NUMBER, "%s", object->string); CASE(TYPE_SYMBOL, "%s", object->string); CASE(TYPE_PRIMITIVE, "#", object->name); #undef CASE @@ -901,8 +926,10 @@ Object *primitiveTime(Object **args, GC_PARAM) { GC_TRACE(gcSymbol, nil); GC_TRACE(gcCons, nil); + char number[7]; - *gcSymbol = newNumber(today->tm_gmtoff, GC_ROOTS); + sprintf(number, "+%ld", today->tm_gmtoff); + *gcSymbol = newNumber(number, GC_ROOTS); *gcCons = newCons(gcSymbol, gcCons, GC_ROOTS); *gcCons = newCons(today->tm_isdst ? &t : &f, gcCons, GC_ROOTS); @@ -912,7 +939,8 @@ Object *primitiveTime(Object **args, GC_PARAM) { }; for (int i = 0; i < 7; i++) { - *gcSymbol = newNumber(tmp[i], GC_ROOTS); + sprintf(number, "+%d", tmp[i]); + *gcSymbol = newNumber(number, GC_ROOTS); *gcCons = newCons(gcSymbol, gcCons, GC_ROOTS); } @@ -920,73 +948,83 @@ Object *primitiveTime(Object **args, GC_PARAM) { } Object *primitiveRandom(Object **args, GC_PARAM) { - srandom((unsigned int)(seed + time(NULL))); - double number = (double)random(); - seed = (unsigned int)number; + srandom((unsigned int)(seed + time(NULL))); + long nrandom = random(); + seed = (unsigned int)nrandom; + char string[22]; - if (*args == nil) - return newNumber(number, GC_ROOTS); - else - return - newNumber(((unsigned int)number % (unsigned int)(*args)->car->number), - GC_ROOTS); -} - -#define DEFINE_PRIMITIVE_ARITHMETIC(name, op, init, datatype) \ - Object *name(Object **args, GC_PARAM) { \ - if (*args == nil) \ - return newNumber(init, GC_ROOTS); \ - else if ((*args)->car->type != TYPE_NUMBER) \ - exceptionWithObject((*args)->car, "is not a number"); \ - else { \ - Object *object, *rest; \ - \ - if ((*args)->cdr == nil) { \ - object = newNumber(init, GC_ROOTS); \ - rest = *args; \ - } else { \ - GC_TRACE(gcFirst, (*args)->car); \ - object = newObjectFrom(gcFirst, GC_ROOTS); \ - rest = (*args)->cdr; \ - } \ - \ - for (; rest != nil; rest = rest->cdr) { \ - if (rest->car->type != TYPE_NUMBER) \ - exceptionWithObject(rest->car, "is not a number"); \ - \ - object->number = \ - (datatype)object->number op (datatype)rest->car->number; \ - } \ - \ - return object; \ - } \ + if (*args == nil) + sprintf(string, "+%ld", nrandom); + else + sprintf(string, "+%ld", nrandom % atol((*args)->car->string)); + + return newNumber(string, GC_ROOTS); +} + +#define DEFINE_PRIMITIVE_ARITHMETIC(name, op, init, converter, datatype, fmt, fmtpos) \ + Object *name(Object **args, GC_PARAM) { \ + if (*args == nil) \ + return newNumber(init, GC_ROOTS); \ + else if ((*args)->car->type != TYPE_NUMBER) \ + exceptionWithObject((*args)->car, "is not a number"); \ + else { \ + Object *object, *rest; \ + \ + if ((*args)->cdr == nil) { \ + object = newNumber(init, GC_ROOTS); \ + rest = *args; \ + } else { \ + GC_TRACE(gcFirst, (*args)->car); \ + object = newObjectFrom(gcFirst, GC_ROOTS); \ + rest = (*args)->cdr; \ + } \ + \ + datatype result = 0; \ + char resString[22]; \ + for (; rest != nil; rest = rest->cdr) { \ + if (rest->car->type != TYPE_NUMBER) \ + exceptionWithObject(rest->car, "is not a number"); \ + \ + result = \ + converter(object->string) op converter(rest->car->string); \ + \ + if (result < 0) \ + sprintf(resString, fmt, result); \ + else \ + sprintf(resString, fmtpos, result); \ + \ + object = newNumber(resString, GC_ROOTS); \ + } \ + \ + return object; \ + } \ } -DEFINE_PRIMITIVE_ARITHMETIC(primitiveAdd, +, 0, double) -DEFINE_PRIMITIVE_ARITHMETIC(primitiveSubtract, -, 0, double) -DEFINE_PRIMITIVE_ARITHMETIC(primitiveMultiply, *, 1, double) -DEFINE_PRIMITIVE_ARITHMETIC(primitiveDivide, /, 1, double) -DEFINE_PRIMITIVE_ARITHMETIC(primitiveRemainder, %, 1, int ) - -#define DEFINE_PRIMITIVE_RELATIONAL(name, op, until_the_end) \ - Object *name(Object **args, GC_PARAM) { \ - if ((*args)->car->type != TYPE_NUMBER) \ - exceptionWithObject((*args)->car, "is not a number"); \ - else { \ - Object *rest = *args; \ - bool result = until_the_end; \ - \ - for (; (result == until_the_end) && rest->cdr != nil; \ - rest = rest->cdr) { \ - if (rest->cdr->car->type != TYPE_NUMBER) \ - exceptionWithObject(rest->cdr->car, "is not a number"); \ - else if (until_the_end) \ - result &= rest->car->number op rest->cdr->car->number; \ - else \ - result = rest->car->number op rest->cdr->car->number; \ - } \ - return result ? t : f; \ - } \ +DEFINE_PRIMITIVE_ARITHMETIC(primitiveAdd, +, "+0", atof, double, "%lf", "+%lf") +DEFINE_PRIMITIVE_ARITHMETIC(primitiveSubtract, -, "+0", atof, double, "%lf", "+%lf") +DEFINE_PRIMITIVE_ARITHMETIC(primitiveMultiply, *, "+1", atof, double, "%lf", "+%lf") +DEFINE_PRIMITIVE_ARITHMETIC(primitiveDivide, /, "+1", atof, double, "%lf", "+%lf") +DEFINE_PRIMITIVE_ARITHMETIC(primitiveRemainder, %, "+1", atoi, int , "%d" , "+%d") + +#define DEFINE_PRIMITIVE_RELATIONAL(name, op, until_the_end) \ + Object *name(Object **args, GC_PARAM) { \ + if ((*args)->car->type != TYPE_NUMBER) \ + exceptionWithObject((*args)->car, "is not a number"); \ + else { \ + Object *rest = *args; \ + bool result = until_the_end; \ + \ + for (; (result == until_the_end) && rest->cdr != nil; \ + rest = rest->cdr) { \ + if (rest->cdr->car->type != TYPE_NUMBER) \ + exceptionWithObject(rest->cdr->car, "is not a number"); \ + else if (until_the_end) \ + result &= atol(rest->car->string) op atol(rest->cdr->car->string); \ + else \ + result = atol(rest->car->string) op atol(rest->cdr->car->string); \ + } \ + return result ? t : f; \ + } \ } DEFINE_PRIMITIVE_RELATIONAL(primitiveDifferent, !=, false) @@ -1404,7 +1442,7 @@ static char *stdlib = LISP( (defun listp (x) (not (atom x))) - (defun zerop (x) (not (! x 0))) + (defun zerop (x) (not (! x +0))) (defmacro and args (fill ((ap args) t) @@ -1433,8 +1471,8 @@ static char *stdlib = LISP( (differ (cdr x) (cdr y)))))) (defun nth (num xs) - (fill ((dif num 0) (car xs)) - (f (nth (- num 1) (cdr xs))))) + (fill ((dif num +0) (car xs)) + (f (nth (- num +1) (cdr xs))))) (defun append (xs y) (fill ((ap xs) y) diff --git a/liblali.h b/liblali.h index 9ffb63d..40b8859 100644 --- a/liblali.h +++ b/liblali.h @@ -70,8 +70,8 @@ struct Object { Type type; size_t size; union { - struct { double number; }; // number - struct { char string[sizeof (Object *[3])]; }; // string, symbol + /* struct { double number; }; // number */ + struct { char string[sizeof (Object *[3])]; }; // string, symbol, number struct { Object *car, *cdr; }; // cons struct { Object *params, *body, *env; }; // lambda, macro struct { int primitive; char *name; }; // primitive @@ -188,7 +188,8 @@ Object *newObject(Type type, GC_PARAM); Object *newObjectFrom(Object **from, GC_PARAM); -Object *newNumber(double number, GC_PARAM); +//Object *newNumber(double number, GC_PARAM); +Object *newNumber(char *string, GC_PARAM); Object *newObjectWithString(Type type, size_t size, GC_PARAM); @@ -255,6 +256,8 @@ Object *readList(Stream *stream, GC_PARAM); // WRITING OBJECTS //////////////////////////////////////////////////////////// +char *removeZeroPadding(char *string); + void writeObject(Object *object, bool readably, FILE *file); // ENVIRONMENT //////////////////////////////////////////////////////////////// diff --git a/work-in-progress/TAGS b/work-in-progress/TAGS deleted file mode 100644 index 16adb82..0000000 --- a/work-in-progress/TAGS +++ /dev/null @@ -1,104 +0,0 @@ - -lali.c,86 -#define YEARS 50,1540 -void runFile(54,1658 -void runREPL(72,2058 -int main(100,2617 - -liblali.c,3469 -#define MEMORY_SIZE 50,1540 -static Memory *memory memory52,1580 -Object *symbols symbols54,1631 -Object *nil nil55,1655 -Object *n n56,1711 -Object *t t57,1764 -Object *f f58,1817 -jmp_buf exceptionEnv;60,1871 -void exceptionWithObject(64,1975 -Object *gcMoveObject(gcMoveObject124,4317 -void gc(146,5016 -size_t memoryAlign(194,6464 -Object *memoryAllocObject(memoryAllocObject198,6571 -Object *newObject(newObject227,7559 -Object *newObjectFrom(newObjectFrom231,7664 -Object *newNumber(newNumber237,7851 -Object *newObjectWithString(newObjectWithString243,7996 -Object *newStringWithLength(newStringWithLength250,8239 -Object *newString(newString278,9169 -Object *newCons(newCons282,9280 -Object *newSymbolWithLength(newSymbolWithLength289,9451 -Object *newSymbol(newSymbol304,9961 -Object *newObjectWithClosure(newObjectWithClosure308,10072 -Object *newLambda(newLambda330,10796 -Object *newMacro(newMacro334,10975 -Object *newPrimitive(newPrimitive338,11152 -Object *newEnv(newEnv345,11344 -int streamGetc(384,12712 -Stream *streamSeek(streamSeek452,14747 -int streamPeek(460,14924 -int readNext(469,15130 -int initialReadNext(480,15347 -int peekForward(491,15584 -int peekNext(498,15760 -int readWhile(502,15831 -Object *readUnary(readUnary511,16007 -Object *readString(readString524,16384 -int isSymbolChar(540,16914 -Object *readNumberOrSymbol(readNumberOrSymbol545,17039 -Object *reverseList(reverseList577,18007 -Object *readList(readList590,18207 -Object *readExpr(readExpr622,19197 -void writeObject(645,19916 -#define CASE(647,20004 -#undef CASE654,20315 -#define CASE(692,21367 -#undef CASE699,21670 -Object *envLookup(envLookup725,22491 -Object *envAdd(envAdd740,22848 -Object *envSet(envSet750,23151 -Object *primitiveSpace(primitiveSpace772,23735 -Object *primitiveAtom(primitiveAtom776,23828 -Object *primitiveDif(primitiveDif794,24412 -Object *primitiveCar(primitiveCar805,24817 -Object *primitiveCdr(primitiveCdr817,25126 -Object *primitiveCons(primitiveCons828,25362 -Object *primitivePrint(primitivePrint835,25538 -Object *primitivePrinc(primitivePrinc841,25679 -Object *primitiveNewline(primitiveNewline847,25821 -Object *primitiveRead(primitiveRead852,25911 -#define DEFINE_PRIMITIVE_ARITHMETIC(865,26159 -DEFINE_PRIMITIVE_ARITHMETIC(894,27946 -#define DEFINE_PRIMITIVE_RELATIONAL(899,28159 -typedef struct Primitive 925,29771 - char *name;name926,29798 - int nMinArgs,927,29812 - int nMinArgs, nMaxArgs;927,29812 - Object *(* eval)928,29838 -} Primitive;929,29883 -Primitive primitives[primitives931,29897 - PRIMITIVE_EVAL,969,31590 - PRIMITIVE_QUOTE,970,31608 - PRIMITIVE_SAY,971,31627 - PRIMITIVE_SET,972,31644 - PRIMITIVE_PROG,973,31661 - PRIMITIVE_PROGS,974,31679 - PRIMITIVE_COND,976,31720 - PRIMITIVE_FILL,977,31738 - PRIMITIVE_LAMBDA,978,31756 - PRIMITIVE_MACRO,979,31776 - PRIMITIVE_TEST980,31795 -Object *evalSet(evalSet991,32147 -Object *evalProg(evalProg1017,32877 -Object *progs1(progs11031,33198 -Object *evalProgs(evalProgs1048,33601 -Object *evalCond(evalCond1072,34218 -Object *evalFill(evalFill1095,34800 -Object *evalLambda(evalLambda1118,35382 -Object *evalMacro(evalMacro1126,35627 -Object *expandMacro(expandMacro1134,35870 -Object *expandMacroTo(expandMacroTo1144,36152 -Object *evalList(evalList1158,36542 -Object *evalExpr(evalExpr1172,36914 -#define LISP(1249,40130 -static char *stdlib stdlib1251,40162 -Object *newRootEnv(newRootEnv1307,41788 -- cgit