diff --git a/README.md b/README.md index 346184a..ed4e980 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ -* (define fac (lambda (n) (if ((eq n 0) 1) (1 (* n (fac (+ n -1))))))) -* (if ((eq 0 1) 0) ((eq 1 1) 1)) -* (if ((eq 0 1) 0) ((eq 0 2) 0) (1 (+ 1 2 3 4))) +* (define fac (lambda (n) (if ((== n 0) 1) (1 (* n (fac (+ n -1))))))) +* (if ((== 0 1) 0) ((== 1 1) 1)) +* (if ((== 0 1) 0) ((== 0 2) 0) (1 (+ 1 2 3 4))) diff --git a/bltin.c b/bltin.c index 8fec558..483995b 100644 --- a/bltin.c +++ b/bltin.c @@ -7,6 +7,14 @@ Object Plus = (Object){.type=OBLTIN, .sym="+"}; Object Mul = (Object){.type=OBLTIN, .sym="*"}; Object Div = (Object){.type=OBLTIN, .sym="/"}; Object Mod = (Object){.type=OBLTIN, .sym="%"}; + +Object Ge = (Object){.type=OBLTIN, .sym= ">="}; +Object Le = (Object){.type=OBLTIN, .sym= "<="}; +Object Lt = (Object){.type=OBLTIN, .sym= "<"}; +Object Gt = (Object){.type=OBLTIN, .sym= ">"}; +Object Ne = (Object){.type=OBLTIN, .sym= "!="}; +Object Eq = (Object){.type=OBLTIN, .sym= "=="}; + Object Lambda= (Object){.type=OBLTIN, .sym="lambda"}; Object Car = (Object){.type=OBLTIN, .sym="car"}; Object Cdr = (Object){.type=OBLTIN, .sym="cdr"}; @@ -14,7 +22,6 @@ Object Quote= (Object){.type=OBLTIN, .sym="'"}; Object Cons = (Object){.type=OBLTIN, .sym="cons"}; Object Define= (Object){.type=OBLTIN, .sym="define"}; Object Setq = (Object){.type=OBLTIN, .sym="setq"}; -Object Eq = (Object){.type=OBLTIN, .sym="eq"}; Object If = (Object){.type=OBLTIN, .sym="if"}; extern Object* fnplus(Object *, Object *); @@ -31,6 +38,11 @@ extern Object* fncdr(Object *, Object *); extern Object* fncons(Object *, Object *); extern Object* fneq(Object *, Object *); extern Object* fnif(Object *, Object *); +extern Object* fnge(Object *env, Object *list); +extern Object* fngt(Object *env, Object *list); +extern Object* fnle(Object *env, Object *list); +extern Object* fnlt(Object *env, Object *list); +extern Object* fnne(Object *env, Object *list); /*extern Object* fnminus(Object *, Object *);*/ Bltinfn @@ -53,7 +65,12 @@ bltinlookup(Object *obj) {&Cdr ,fncdr}, {&Cons ,fncons}, {&Eq, fneq}, + {&Ne, fnne}, {&If, fnif}, + {&Ge, fnge}, + {&Le, fnle}, + {&Gt, fngt}, + {&Lt, fnlt}, {&Minus ,0}, {0}, }; diff --git a/dat.h b/dat.h index ed12710..f0dfe62 100644 --- a/dat.h +++ b/dat.h @@ -68,10 +68,10 @@ typedef struct /* objects */ struct{ Object *objs; + Object *freed; u64 ob; u64 oe; u64 op; - Object *freed; }; /* string */ struct{ @@ -95,4 +95,9 @@ extern Object Cons; extern Object Define; extern Object Setq; extern Object Eq; +extern Object Ne; extern Object If; +extern Object Ge; +extern Object Le; +extern Object Lt; +extern Object Gt; diff --git a/eval.c b/eval.c index 6ca7241..f5a7cd4 100644 --- a/eval.c +++ b/eval.c @@ -163,9 +163,9 @@ fnplus(Object *env, Object *list) Object* fnmul(Object *env, Object *list) { - Object *p=evallist(env, list); + Object *p = evallist(env, list); if(p->car->type != OINT) - error("* take only [INT]"); + error("* take only [INT]"); long sum = p->car->num; for(p=p->cdr;p!=&Nil; p=p->cdr){ if(p->car->type != OINT) @@ -180,7 +180,7 @@ fndiv(Object *env, Object *list) { Object *p=evallist(env, list); if(p->car->type != OINT) - error("/ take only [INT]"); + error("/ take only [INT]"); long sum = p->car->num; for(p=p->cdr;p!=&Nil; p=p->cdr){ if(p->car->type != OINT) @@ -196,8 +196,8 @@ Object* fnmod(Object *env, Object *list) { Object *p=evallist(env, list); - if(p->car->type != OINT) - error("%% take only [INT]"); + if(p->car->type != OINT) + error("%% take only [INT]"); long sum = p->car->num; for(p=p->cdr;p!=&Nil; p=p->cdr){ if(p->car->type != OINT) @@ -210,36 +210,56 @@ fnmod(Object *env, Object *list) } long -eq(Object *env, Object *a, Object *b) +cmp(Object *env, Object *list) { - if(a == b) - return 1; - if(a->type != b->type) - return 0; - switch(a->type){ - default: error("eq only compare [INT]"); - case OSTRING: return strequal(a, b); - case OINT: return a->num == b->num; - } + Object *a = eval(env, list->car); + Object *b = eval(env, list->cdr->car); + if(a->type != OINT || b->type != OINT) + error("cmp only take [INT]"); + return a->num - b->num; } Object* fneq(Object *env, Object *list) { - Object *a = eval(env, list->car); - Object *b = eval(env, list->cdr->car); - return newint(gc, eq(env, a, b)); + return newint(gc, cmp(env, list) == 0); +} + +Object* +fnge(Object *env, Object *list) +{ + return newint(gc, cmp(env, list) >= 0); +} + +Object* +fngt(Object *env, Object *list) +{ + return newint(gc, cmp(env, list) > 0); +} + +Object* +fnle(Object *env, Object *list) +{ + return newint(gc, cmp(env, list) <= 0); +} + +Object* +fnlt(Object *env, Object *list) +{ + return newint(gc, cmp(env, list) < 0); +} + +Object* +fnne(Object *env, Object *list) +{ + return newint(gc, cmp(env, list) != 0); } -/* - * (if ((cond) val)* ) - * (if ((eq x y) 0) ((eq x z ) 1) (default)) - */ Object* fnif(Object *env, Object *list) { if(list == 0 || list == &Nil) - return newint(gc, 0); + error("Malformed if stmt"); Object *t = eval(env, list->car->car); if(istrue(t)) return eval(env, list->car->cdr->car); diff --git a/gc.c b/gc.c index bc3a796..a8798ae 100644 --- a/gc.c +++ b/gc.c @@ -273,7 +273,9 @@ gcrun(GC *src) } gcmark(src); gcsweep(src); - gccompact(src->cap + 500, src); + if(src->using >= src->cap * 0.5){ + gccompact(src->cap * 2, src); + } longjmp(reg, 1); } @@ -309,9 +311,9 @@ newgc(void *top, int cap) gc->using = 0; gc->op = gc->ob = (u64)gc->memory; - gc->oe = gc->op + (float)cap * 0.64; + gc->oe = gc->op + (float)cap * 0.75; - gc->sb = (u64)gc->memory + (float)cap * 0.64; + gc->sb = (u64)gc->memory + (float)cap * 0.75; gc->se = (u64)gc->memory + cap; return gc; } diff --git a/obj.c b/obj.c index 8017c27..ded5054 100644 --- a/obj.c +++ b/obj.c @@ -51,8 +51,9 @@ Object* newsymbol(GC *gc, char *str, int len) { static Object *syms[] = { - &Nil, &Minus, &Plus, &Mul, &Mod, &Div, - &Lambda, &Car, &Cdr, &Quote, &Cons, &Define, &Setq, &Eq, &If, + &Nil, &Minus, &Plus, &Mul, &Mod, &Div, &Ge, &Le, + &Lt, &Gt, &Ne, &Lambda, &Car, &Cdr, &Quote, &Cons, + &Define, &Setq, &Eq, &If, }; for(int i = 0; i < sizeof(syms)/sizeof(syms[0]); ++i){ Object *c = syms[i]; diff --git a/parser.c b/parser.c index badedaf..c4c824a 100644 --- a/parser.c +++ b/parser.c @@ -6,7 +6,7 @@ #define SYMBOL_LEN 64 -const char symbolchars[] = "*/%-=+<>'"; +const char symbolchars[] = "!*/%-=+<>'"; static Object* lparlist(void); static Object* list(void);