summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--README.md101
-rw-r--r--TAGS106
-rw-r--r--TODO3
-rw-r--r--liblali.c192
-rw-r--r--liblali.h9
-rw-r--r--work-in-progress/TAGS104
7 files changed, 176 insertions, 340 deletions
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)) ; #<Lambda (x)>
- (plus1 2) ; 3
+ (+ x +1)) ; #<Lambda (x)>
+ (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 "#<Lambda ..." it should return the expression.
remove lambda_type and macro_type.
-
+make numbers be symbols. (done)
+make number symbols neutral. (done)
fix a security bug of setting a primitive. (done)
improve performance of progs1. (done)
makes no sense to make progs accept a lambda argument. (because the evaluation of each step would require a fixing a symbol, such as fixing the symbol "t").
diff --git a/liblali.c b/liblali.c
index 78872fd..80d27fc 100644
--- a/liblali.c
+++ b/liblali.c
@@ -223,9 +223,9 @@ Object *newObjectFrom(Object **from, GC_PARAM) {
return object;
}
-Object *newNumber(double number, GC_PARAM) {
+Object *newNumber(char *number, GC_PARAM) {
Object *object = newObject(TYPE_NUMBER, GC_ROOTS);
- object->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, "#<Primitive %s>", 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