Ejemplo n.º 1
0
static Obj *apply_func(void *root, Obj **env, Obj **fn, Obj **args) {
    DEFINE3(params, newenv, body);
    *params = (*fn)->params;
    *newenv = (*fn)->env;
    *newenv = push_env(root, newenv, params, args);
    *body = (*fn)->body;
    return progn(root, newenv, body);
}
Ejemplo n.º 2
0
// (if expr expr expr ...)
static Obj *prim_if(void *root, Obj **env, Obj **list) {
    if (length(*list) < 2)
        error("Malformed if");
    DEFINE3(cond, then, els);
    *cond = (*list)->car;
    *cond = eval(root, env, cond);
    if (*cond != Nil) {
        *then = (*list)->cdr->car;
        return eval(root, env, then);
    }
    *els = (*list)->cdr->cdr;
    return *els == Nil ? Nil : progn(root, env, els);
}
Ejemplo n.º 3
0
Obj *prim_if(Env *env, Obj *root, Obj **list) {
    int len = list_length(*list);
    if (len < 2)
        error("malformed if");
    VAR(cond);
    VAR(then);
    VAR(els);
    *cond = (*list)->car;
    *then = (*list)->cdr->car;
    *cond = eval(env, root, cond);
    if (len == 2)
        return *cond != Nil ? eval(env, root, then) : Nil;
    *els = (*list)->cdr->cdr;
    return *cond != Nil
        ? eval(env, root, then)
        : progn(env, root, els);
}
Ejemplo n.º 4
0
Obj *macroexpand(Env *env, Obj *root, Obj **obj) {
    if ((*obj)->type != TCELL || (*obj)->car->type != TSYMBOL)
        return *obj;
    VAR(macro);
    VAR(args);
    VAR(body);
    VAR(params);
    *macro = find((*obj)->car->name, env);
    if (!*macro)
        return *obj;
    *macro = (*macro)->cdr;
    if ((*macro)->type != TMACRO)
        return *obj;
    *args = (*obj)->cdr;
    *body = (*macro)->body;
    *params = (*macro)->params;
    Env newenv;
    add_env(env, root, &newenv, params, args);
    return progn(&newenv, root, body);
}
Ejemplo n.º 5
0
Obj *apply(Env *env, Obj *root, Obj **fn, Obj **args) {
    if ((*fn)->type == TPRIMITIVE) {
        if ((*args) != Nil && (*args)->type != TCELL)
            error("argument must be a list");
        return (*fn)->fn(env, root, args);
    }
    if ((*fn)->type == TFUNCTION) {
        VAR(body);
        VAR(params);
        VAR(eargs);
        *body = (*fn)->body;
        *params = (*fn)->params;
        Env newenv;
        *eargs = eval_list(env, root, args);
        add_env(env, root, &newenv, params, eargs);
        return progn(&newenv, root, body);
    }
    error("not supported");
    return NULL;
}
Ejemplo n.º 6
0
LISPTR apply(LISPTR f, LISPTR args)
{
    if (symbolp(f)) {
        // get the function binding of f
        f = symbol_function(f);
        if (consp(f)) {
            // function defined as S-expr
            if (car(f) == LAMBDA) {
                LISPTR oldBindings = lexvars;
                // bind formal arguments to evaluated actual arguments:
                lexvars = bind_args(cadr(f), args, lexvars);
                f = progn(cddr(f));
                lexvars = oldBindings;
            }
        } else if (compiled_function_p(f)) {
            // call compiled function with args
            f = call_compiled_fn(f, args);
        }
    }
    return f;
}
Ejemplo n.º 7
0
Archivo: devprog.c Proyecto: 8l/inferno
static void
progclose(Chan *c)
{
	int i;
	Prog *f;
	Osenv *o;
	Progctl *ctl;

	switch(QID(c->qid)) {
	case Qns:
	case Qheap:
		free(c->aux);
		break;
	case Qdbgctl:
		if((c->flag & COPEN) == 0)
			return;
		ctl = c->aux;
		acquire();
		closedbgctl(ctl, progpid(PID(c->qid)));
		release();
		break;
	case Qwait:
		acquire();
		i = 0;
		for(;;) {
			f = progn(i++);
			if(f == nil)
				break;
			o = f->osenv;
			if(o->waitq == c->aux)
				o->waitq = nil;
			if(o->childq == c->aux)
				o->childq = nil;
		}
		release();
		qfree(c->aux);
	}
}
Ejemplo n.º 8
0
Archivo: devprog.c Proyecto: 8l/inferno
static int
proggen(Chan *c, char *name, Dirtab *tab, int ntab, int s, Dir *dp)
{
	Qid qid;
	Prog *p;
	char *e;
	Osenv *o;
	ulong pid, path, perm, len;

	USED(ntab);

	if(s == DEVDOTDOT){
		mkqid(&qid, Qdir, 0, QTDIR);
		devdir(c, qid, "#p", 0, eve, DMDIR|0555, dp);
		return 1;
	}

	if((ulong)c->qid.path == Qdir) {
		if(name != nil){
			/* ignore s and use name to find pid */
			pid = strtoul(name, &e, 0);
			if(pid == 0 || *e != '\0')
				return -1;
			acquire();
			p = progpid(pid);
			if(p == nil){
				release();
				return -1;
			}
		}else{
			acquire();
			p = progn(s);
			if(p == nil) {
				release();
				return -1;
			}
			pid = p->pid;
		}
		o = p->osenv;
		sprint(up->genbuf, "%lud", pid);
		if(name != nil && strcmp(name, up->genbuf) != 0){
			release();
			return -1;
		}
		mkqid(&qid, pid<<QSHIFT, pid, QTDIR);
		devdir(c, qid, up->genbuf, 0, o->user, DMDIR|0555, dp);
		release();
		return 1;
	}

	if(s >= nelem(progdir))
		return -1;
	tab = &progdir[s];
	path = PATH(c->qid);

	acquire();
	p = progpid(PID(c->qid));
	if(p == nil) {
		release();
		return -1;
	}

	o = p->osenv;

	perm = tab->perm;
	if((perm & 7) == 0)
		perm = (perm|(perm>>3)|(perm>>6)) & o->pgrp->progmode;

	len = tab->length;
	mkqid(&qid, path|tab->qid.path, c->qid.vers, QTFILE);
	devdir(c, qid, tab->name, len, o->user, perm, dp);
	release();
	return 1;
}
Ejemplo n.º 9
0
.5 -.5 -.5      # 1   \n\
.5  .5 -.5      # 2   \n\
-.5  .5 -.5     # 3   \n\
-.5 -.5  .5     # 4   \n\
.5 -.5  .5      # 5   \n\
.5  .5  .5      # 6   \n\
-.5  .5  .5     # 7   \n\
\n\
4 0 1 2 3\n\
4 4 5 6 7\n\
4 2 3 7 6\n\
4 0 1 5 4\n\
4 0 4 7 3\n\
4 1 2 6 5\n";

progn()
{
    printf("(progn\n");
}

endprogn()
{
    printf(")\n");
    fflush(stdout);
}

Initialize()
{
    extern LObject *Lpick();  /* This is defined by PICKFUNC below but must */
    /* be used in the following LDefun() call */
    LInit();