add arithmetic operators

This commit is contained in:
Hojun Choi 2024-09-02 19:15:21 +09:00
parent 701bf84d66
commit a740c9af25
6 changed files with 65 additions and 3 deletions

1
README.md Normal file
View File

@ -0,0 +1 @@
(define fac (lambda (n) (if ((eq n 0) 1) (1 (* n (fac (+ n -1)))))))

View File

@ -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},

3
dat.h
View File

@ -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;

49
eval.c
View File

@ -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)
{

4
obj.c
View File

@ -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];

View File

@ -6,7 +6,7 @@
#define SYMBOL_LEN 64
const char symbolchars[] = "*-=+<>'";
const char symbolchars[] = "*/%-=+<>'";
static Object* lparlist(void);
static Object* list(void);