From a740c9af25df49524a8a08bdc5de35825c87dec5 Mon Sep 17 00:00:00 2001 From: Hojun Choi Date: Mon, 2 Sep 2024 19:15:21 +0900 Subject: [PATCH] add arithmetic operators --- README.md | 1 + bltin.c | 9 +++++++++ dat.h | 3 +++ eval.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ obj.c | 4 ++-- parser.c | 2 +- 6 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..a8620eb --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +(define fac (lambda (n) (if ((eq n 0) 1) (1 (* n (fac (+ n -1))))))) diff --git a/bltin.c b/bltin.c index 1c504d2..8fec558 100644 --- a/bltin.c +++ b/bltin.c @@ -4,6 +4,9 @@ Object Nil = (Object){.type=OSYMBOL, .sym="nil"}; Object Minus= (Object){.type=OBLTIN, .sym="-"}; 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 Lambda= (Object){.type=OBLTIN, .sym="lambda"}; Object Car = (Object){.type=OBLTIN, .sym="car"}; Object Cdr = (Object){.type=OBLTIN, .sym="cdr"}; @@ -15,6 +18,9 @@ Object Eq = (Object){.type=OBLTIN, .sym="eq"}; Object If = (Object){.type=OBLTIN, .sym="if"}; extern Object* fnplus(Object *, Object *); +extern Object* fnmul(Object *, Object *); +extern Object* fndiv(Object *, Object *); +extern Object* fnmod(Object *, Object *); extern Object* fnlambda(Object *, Object *); extern Object* fndefine(Object *, Object *); extern Object* fnsetq(Object *, Object *); @@ -37,6 +43,9 @@ bltinlookup(Object *obj) }bltins[] = { {&Lambda , fnlambda}, {&Plus , fnplus}, + {&Mul , fnmul}, + {&Mod , fnmod}, + {&Div , fndiv}, {&Define ,fndefine}, {&Setq ,fnsetq}, {&Quote ,fnquote}, diff --git a/dat.h b/dat.h index cd201f4..ed12710 100644 --- a/dat.h +++ b/dat.h @@ -84,6 +84,9 @@ extern GC *gc; extern Object Nil; extern Object Minus; extern Object Plus; +extern Object Mul; +extern Object Div; +extern Object Mod; extern Object Lambda; extern Object Car; extern Object Cdr; diff --git a/eval.c b/eval.c index ec6bdf3..6ca7241 100644 --- a/eval.c +++ b/eval.c @@ -160,6 +160,55 @@ fnplus(Object *env, Object *list) } } +Object* +fnmul(Object *env, Object *list) +{ + Object *p=evallist(env, list); + 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) + error("* take only [INT]"); + sum *= p->car->num; + } + return newint(gc, sum); +} + +Object* +fndiv(Object *env, Object *list) +{ + Object *p=evallist(env, list); + 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) + error("/ take only [INT]"); + if(p->car->num == 0) + error("Can't div zero"); + sum /= p->car->num; + } + return newint(gc, sum); +} + +Object* +fnmod(Object *env, Object *list) +{ + Object *p=evallist(env, list); + 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) + error("%% take only [INT]"); + if(p->car->num == 0) + error("Can't mod zero"); + sum %= p->car->num; + } + return newint(gc, sum); +} + long eq(Object *env, Object *a, Object *b) { diff --git a/obj.c b/obj.c index 631d42c..8017c27 100644 --- a/obj.c +++ b/obj.c @@ -51,8 +51,8 @@ Object* newsymbol(GC *gc, char *str, int len) { static Object *syms[] = { - &Nil, &Minus, &Plus, &Lambda, &Car, &Cdr, &Quote, &Cons, - &Define, &Setq, &Eq, &If, + &Nil, &Minus, &Plus, &Mul, &Mod, &Div, + &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 d3b543d..badedaf 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);