add fnlet
This commit is contained in:
parent
b1451a2380
commit
cc6c9ed98b
3
bltin.c
3
bltin.c
@ -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
1
dat.h
@ -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
35
eval.c
@ -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
2
obj.c
@ -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];
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user