add fnlet

This commit is contained in:
yoyo 2024-09-11 13:44:56 +09:00
parent b1451a2380
commit cc6c9ed98b
4 changed files with 30 additions and 11 deletions

View File

@ -20,6 +20,7 @@ Object Not = (Object){.type=OBLTIN, .beg= "not"};
Object Bquote= (Object){.type=OBLTIN, .beg="`"}; Object Bquote= (Object){.type=OBLTIN, .beg="`"};
Object Lambda= (Object){.type=OBLTIN, .beg="lambda"}; Object Lambda= (Object){.type=OBLTIN, .beg="lambda"};
Object Let= (Object){.type=OBLTIN, .beg="let"};
Object Progn=(Object){.type=OBLTIN, .beg="progn"}; Object Progn=(Object){.type=OBLTIN, .beg="progn"};
Object Car = (Object){.type=OBLTIN, .beg="car"}; Object Car = (Object){.type=OBLTIN, .beg="car"};
Object Cdr = (Object){.type=OBLTIN, .beg="cdr"}; Object Cdr = (Object){.type=OBLTIN, .beg="cdr"};
@ -35,6 +36,7 @@ extern Object* fnmul(Object *, Object *);
extern Object* fndiv(Object *, Object *); extern Object* fndiv(Object *, Object *);
extern Object* fnmod(Object *, Object *); extern Object* fnmod(Object *, Object *);
extern Object* fnlambda(Object *, Object *); extern Object* fnlambda(Object *, Object *);
extern Object* fnlet(Object *, Object *);
extern Object* fnprogn(Object *, Object *); extern Object* fnprogn(Object *, Object *);
extern Object* fndefine(Object *, Object *); extern Object* fndefine(Object *, Object *);
extern Object* fnmacro(Object *, Object *); extern Object* fnmacro(Object *, Object *);
@ -72,6 +74,7 @@ bltinlookup(Object *obj)
{&Define ,fndefine}, {&Define ,fndefine},
{&Macro ,fnmacro}, {&Macro ,fnmacro},
{&Setq ,fnsetq}, {&Setq ,fnsetq},
{&Let ,fnlet},
{&Quote ,fnquote}, {&Quote ,fnquote},
{&Bquote, fnbquote}, {&Bquote, fnbquote},
{&Car ,fncar}, {&Car ,fncar},

1
dat.h
View File

@ -69,6 +69,7 @@ extern Object Define;
extern Object Progn; extern Object Progn;
extern Object Macro; extern Object Macro;
extern Object Setq; extern Object Setq;
extern Object Let;
extern Object Eq; extern Object Eq;
extern Object Not; extern Object Not;
extern Object Ne; extern Object Ne;

35
eval.c
View File

@ -130,26 +130,41 @@ fnprogn(Object *env, Object *list)
Object* Object*
fnsetq(Object *env, Object *list) fnsetq(Object *env, Object *list)
{ {
if(exprlen(list)!=2 || list->car->type!=OIDENT) if(list->type != OCELL || exprlen(list)!=2 || list->car->type!=OIDENT)
error("Malformed setq"); error("Malformed setq");
Object *cur = env; Object *cur = env;
Object *p = 0; Object *p = &Nil;
for(; cur!=&Nil; cur=cur->up) for(; cur!=&Nil; cur=cur->up)
for(p=cur->vars; p!=&Nil; p=p->cdr) for(p=cur->vars; p!=&Nil; p=cdr(p))
if(strequal(list->car, p->car->car)) if(strequal(list->car, car(car(p))))
goto found; return p->car->cdr = eval(env, car(cdr(list)));
error("setq not exist variable"); error("setq not exist variable");
found:; return 0;
return p->car->cdr = eval(env, list->cdr->car); }
Object*
fnlet(Object *env, Object *list)
{
if(exprlen(list) < 2)
error("let (vars) bodys");
Object *nenv = newenv(gc, &Nil, &Nil, env) ;
for(Object *p=list->car; p!=&Nil; p=cdr(p)){
Object *var = car(car(p));
if(var->type != OIDENT)
error("expected ident");
Object *val = eval(env, car(cdr(car(p))));
nenv->vars = newacons(gc, var, val, nenv->vars);
}
return progn(nenv, cdr(list));
} }
Object* Object*
fndefine(Object *env, Object *list) fndefine(Object *env, Object *list)
{ {
if(exprlen(list)!=2 || list->car->type!=OIDENT) if(exprlen(list)!=2 || car(list)->type!=OIDENT)
error("Malformed define"); error("Malformed define");
Object *val = eval(env, list->cdr->car); Object *val = eval(env, car(cdr(list)));
env->vars = defvar(env, list->car, val); env->vars = defvar(env, car(list), val);
return val; return val;
} }

2
obj.c
View File

@ -63,7 +63,7 @@ newsymbol(GC *gc, char *str, int len)
&Nil, &Minus, &Plus, &Mul, &Mod, &Div, &Ge, &Le, &Nil, &Minus, &Plus, &Mul, &Mod, &Div, &Ge, &Le,
&Lt, &Gt, &Ne, &Lambda, &Car, &Cdr, &Quote, &Cons, &Lt, &Gt, &Ne, &Lambda, &Car, &Cdr, &Quote, &Cons,
&Define, &Setq, &Eq, &If, &Macro, &Progn, &Bquote, &Define, &Setq, &Eq, &If, &Macro, &Progn, &Bquote,
&Comma, &Not, &Splice, &Comma, &Not, &Splice, &Let,
}; };
for(int i = 0; i < sizeof(syms)/sizeof(syms[0]); ++i){ for(int i = 0; i < sizeof(syms)/sizeof(syms[0]); ++i){
Object *c = syms[i]; Object *c = syms[i];