View file src/lpian/lpia.c - Download
#include
#include
#include
typedef int sexpr;
#define NFLAGS 1
#define TYPESIZE 4
#define UTVAL(x) ((x)>>(NFLAGS+TYPESIZE))
#define TVAL(x) ((x)>>NFLAGS)
#define TYPE(x) (((x)>>NFLAGS)&((1<= strings_data + SIZESTRINGS)
error ("Strings overflow", 0);
else
{
strcpy (string_ptr, s);
strings[nstrings++] = string_ptr;
string_ptr += strlen(s) + 1;
r = nstrings-1;
defs[r] = nil;
/* printf (" new_string %d (%s) (%s) (%s) ", r, s, string_ptr, strings[r]); */
return r;
}
}
int new_string_length (int n)
{
int r;
int i;
if (string_ptr + n >= strings_data + SIZESTRINGS)
error ("Strings overflow", 0);
else
{
for (i=0; i<=n; i++)
string_ptr[i] = 0;
strings[nstrings++] = string_ptr;
string_ptr += n + 1;
r = nstrings-1;
defs[r] = nil;
/* printf (" new_string %d (%s) (%s) (%s) ", r, s, string_ptr, strings[r]); */
return r;
}
}
sexpr sexpr_string (char *s)
{
int i;
sexpr x;
i = new_string (s);
x = SEXPR(TYPE_STRING,i);
return x;
}
sexpr new_symbol (char *s)
{
int i;
sexpr x;
i = new_string (s);
x = SEXPR(TYPE_SYMBOL,i);
DEF(x) = SEXPR(TYPE_INSTR,i);
PROPS(x) = nil;
/*
printf ("\nnew_symbol %s DEF = ", s);
printstd (DEF(x));
printf ("\n");
*/
return x;
}
sexpr symbol (char *s)
{
int i;
sexpr x;
for (i=0; i= NNSEXPR-1)
error ("nsexpr overflow", x);
else
{
nsexpr[nnsexpr++] = x;
}
}
void clrnsexpr ()
{
nnsexpr = 0;
}
void mark (sexpr x)
{
if (pairp(x))
{
if (!ISOCC(UTVAL(x)))
{
SETOCC(UTVAL(x));
mark(car(x));
mark(cdr(x));
}
}
}
void gc ()
{
int i;
printf ("\n*** GC ***\n");
for (i=0; if))(out,c);
}
void pstr (output out, char *s)
{
while (*s)
pchar (out, *s++);
}
typedef struct input
{
int (*f) (struct input *in);
} *input;
struct input stdi[1];
int stdif (input in)
{
char c;
c=getchar();
return c;
}
typedef struct file_input
{
int (*f) (struct file_input *in);
FILE *fh;
} *file_input;
int fileif (file_input in)
{
int c;
c = fgetc (in->fh);
putchar (c);
return c;
}
int gchar (input in)
{
return (*(in->f))(in);
}
void init ()
{
int i;
nstrings = 0;
string_ptr = strings_data;
ngensym = 0;
pairptr = 0;
nnsexpr = 0;
npsexpr = 0;
for (i=0; if = stdof;
stdi->f = stdif;
nil = symbol ("nil");
tru = symbol ("t");
rc = ' ';
}
void print (output out, sexpr x, int l)
{
char buf[1000];
sexpr y;
if (l < 0)
pstr (out, "...");
else
switch (TYPE(x))
{
case TYPE_INT:
sprintf (buf, "%d", UTVAL(x));
pstr (out, buf);
break;
case TYPE_GENSYM:
pchar (out, '$');
sprintf (buf, "%d", UTVAL(x));
pstr (out, buf);
break;
case TYPE_SYMBOL:
/* printf (" print:symbol "); */
pstr (out, str_symbol(x));
break;
case TYPE_INSTR:
pchar (out, '#');
pstr (out, str_instr(x));
break;
case TYPE_STRING:
pchar (out, '"');
pstr (out, str_string(x));
pchar (out, '"');
break;
case TYPE_PAIR:
pchar (out, '(');
y = x;
for (;;)
{
l--;
if (l < -1)
{
pchar (out, ')');
break;
}
print (out, car(y), l);
if (TVAL(cdr(y)) == TVAL(nil))
{
pchar (out, ')');
break;
}
else if (!pairp(cdr(y)))
{
pstr (out, " . ");
print (out, cdr(y), l);
pchar (out, ')');
break;
}
else
{
pchar (out, ' ');
y = cdr(y);
}
}
break;
default:
sprintf (buf, "<%d:%d>", TYPE(x), UTVAL(x));
pstr (out, buf);
break;
}
}
void printstd (sexpr x)
{
print (stdo, x, 8);
}
void nextchar (input in)
{
rc = gchar (in);
if (rc == '{')
{
while (rc != '}')
rc = gchar (in);
rc = gchar (in);
}
/* putchar (rc); */
}
void space (input in)
{
while (rc == ' ' || rc == '\r' || rc == '\n' || rc == '\t')
nextchar(in);
}
sexpr readlist (input in, int c)
{
sexpr x, y, z;
space (in);
if (rc == ')')
{
if (!c)
nextchar(in);
return nil;
}
if (rc == '.')
{
nextchar (in);
x = read (in);
space (in);
if (rc != ')')
error ("expected only one expression between '.' and ')'", x);
if (!c)
nextchar (in);
return x;
}
x = read (in);
y = readlist (in, c);
z = cons (x, y);
return z;
}
sexpr read (input in)
{
char buf[1000];
int i;
int n;
sexpr x, y;
space (in);
if (rc == '-' || (rc >= '0' && rc <= '9'))
{
i = 0;
buf[i++] = rc;
nextchar (in);
while (rc >= '0' && rc <= '9')
{
buf[i++] = rc;
nextchar (in);
}
buf[i++] = 0;
sscanf (buf, "%d", &n);
x = SEXPR(TYPE_INT,n);
return x;
}
else if (rc == '(')
{
nextchar (in);
x = readlist (in, 0);
return x;
}
else if (rc == ':')
{
nextchar (in);
x = readlist (in, 1);
return x;
}
else if (rc == '\'')
{
nextchar(in);
x = read(in);
y = cons (symbol("QUOTE"), cons(x, nil));
return y;
}
else if (rc == '%')
{
nextchar(in);
x = read(in);
y = cons (symbol("GET"), cons(x, nil));
return y;
}
else if (rc == '&')
{
nextchar(in);
x = read(in);
y = cons (symbol("VAR"), cons(x, nil));
return y;
}
else if (rc == '\\')
{
nextchar(in);
x = read(in);
y = cons (symbol("DBL"), cons (x, nil));
return y;
}
else if (rc == '@')
{
nextchar (in);
x = read(in);
y = reverse(x);
return y;
}
else if (rc == '#')
{
i=0;
nextchar(in);
while (rc!=' ' && rc!='\n' && rc!='\r' && rc!='\t' && rc!=')' && rc!='.')
{
buf[i++] = rc;
nextchar(in);
}
buf[i++] = 0;
x = instruction (buf);
return x;
}
else if (rc == '"')
{
i=0;
nextchar(in);
while (rc != '"')
{
buf[i++] = rc;
nextchar(in);
}
buf[i++] = 0;
nextchar(in);
x = string (buf);
return x;
}
else
{
/* printf (" symbol "); */
i=0;
buf[i++] = rc;
nextchar(in);
while (rc!=' ' && rc!='\n' && rc!='\r' && rc!='\t' && rc!=')' && rc!='.')
{
buf[i++] = rc;
nextchar(in);
}
buf[i++] = 0;
/* printf ("buf=%s\n",buf); */
x = symbol (buf);
return x;
}
}
void test (void)
{
sexpr x;
init();
for (;;)
{
printf ("\n? ");
x = read (stdi);
printf ("\ntype %d, value %d = ", TYPE(x), UTVAL(x));
print (stdo, x, 8);
/* printf ("\nstring=%s ", strings[UTVAL(x)]); */
}
}
#define lctxs (psexpr[0])
#define strat (psexpr[1])
#define prog (psexpr[2])
#define stack (psexpr[3])
#define rstack (psexpr[4])
#define envir (psexpr[5])
int cont;
sexpr append (sexpr a, sexpr b)
{
if (pairp(a))
return cons (car(a), append (cdr(a), b));
return b;
}
int eq (sexpr x, sexpr y)
{
return (TVAL(x) == TVAL(y));
}
sexpr sexpr_eq (sexpr x, sexpr y)
{
if (TVAL(x) == TVAL(y))
return tru;
else
return nil;
}
sexpr not (sexpr x)
{
if (TVAL(x) == TVAL(nil))
return tru;
else
return nil;
}
int istrue (sexpr x)
{
if (TVAL(x) == TVAL(nil))
return 0;
else
return 1;
}
sexpr nth (sexpr x, int i)
{
if (!pairp(x))
{
error ("nth of non pair", x);
return nil;
}
else
{
if (i <= 0)
return car(x);
else
return nth (cdr(x), i-1);
}
}
int length (sexpr x)
{
if (!consp(x))
return 0;
return 1 + length(cdr(x));
}
sexpr last (sexpr x)
{
if (!consp(x))
return nil;
if (!consp(cdr(x)))
return x;
return last(cdr(x));
}
sexpr reverse (sexpr x)
{
if (!consp(x))
return x;
return append (reverse(cdr(x)), cons(car(x),nil));
}
sexpr memq (sexpr x, sexpr l)
{
if (!consp(l))
return nil;
if (eq(x,car(l)))
return l;
return memq(x,cdr(l));
}
int equal (sexpr x, sexpr y)
{
if (eq(x,y))
return 1;
if (!consp(x))
return 0;
if (!consp(y))
return 0;
if (!equal(car(x),car(y)))
return 0;
if (!equal(cdr(x),cdr(y)))
return 0;
return 1;
}
sexpr member (sexpr x, sexpr l)
{
if (!consp(l))
return nil;
if (equal(x,car(l)))
return l;
return member (x, cdr(l));
}
sexpr remq (sexpr x, sexpr l)
{
if (!consp(l))
return l;
if (eq(x,car(l)))
return cdr(l);
return cons (car(l), remq(x,cdr(l)));
}
sexpr remov (sexpr x, sexpr l)
{
if (!consp(l))
return l;
if (equal(x,car(l)))
return cdr(l);
return cons (car(l), remov(x,cdr(l)));
}
int inclq (sexpr a, sexpr b)
{
sexpr x;
if (!consp(a))
return 1;
x = memq (car(a), b);
return istrue(x) && inclq (cdr(a), b);
}
int incl (sexpr a, sexpr b)
{
sexpr x;
if (!consp(a))
return 1;
x = member (car(a), b);
return istrue(x) && incl (cdr(a), b);
}
sexpr getvenv (sexpr env, sexpr var)
{
sexpr x, y;
if (!consp(env))
return nil;
if (eq(car(car(env)),var))
return car(cdr(car(env)));
x = cdr(env);
y = getvenv (x, var);
return y;
// return getvenv (cdr(env), var);
}
sexpr setvenv (sexpr env, sexpr var, sexpr val)
{
if (!consp(env))
return cons (cons(var, cons(val,nil)), tru);
if (eq(car(car(env)),var))
return cons(cons(var,cons(val,cdr(cdr(car(env))))),cdr(env));
return cons (car(env), setvenv(cdr(env),var,val));
}
sexpr addvenv (sexpr env, sexpr var, sexpr val)
{
if (!consp(env))
return cons (cons(var, cons(val,nil)), tru);
if (eq(car(car(env)),var))
return cons(cons(var,cons(val,cdr(car(env)))),cdr(env));
return cons (car(env), addvenv(cdr(env),var,val));
}
sexpr remvenv (sexpr env, sexpr var)
{
if (!consp(env))
return env;
if (eq(car(car(env)),var))
{
sexpr x;
x = cdr(cdr(car(env)));
if (!consp(x))
return cdr(env);
return cons (cons(var,x), cdr(env));
}
return cons (car(env), remvenv (cdr(env), var));
}
sexpr getvsenv (sexpr env, sexpr vars)
{
if (!consp(vars))
return getvenv (env, vars);
if (eq (car(vars), symbol("QUOTE")) && consp(cdr(vars)))
return car(cdr(vars));
return cons (getvsenv(env,car(vars)), getvsenv(env,cdr(vars)));
}
sexpr bindvenv (sexpr env, sexpr vars, sexpr vals)
{
sexpr a, b;
if (!istrue(vars))
return env;
if (!consp(vars))
return addvenv (env, vars, vals);
a = consp(vals) ? car(vals) : vals;
b = consp(vals) ? cdr(vals) : vals;
return bindvenv (bindvenv(env,car(vars),a),cdr(vars),b);
}
sexpr unbindvenv (sexpr env, sexpr vars)
{
if (!istrue(vars))
return env;
if (!consp(vars))
return remvenv (env, vars);
return unbindvenv (unbindvenv(env,car(vars)), cdr(vars));
}
sexpr create_var (sexpr x)
{
return cons (symbol("VAR"), cons(x, nil));
}
sexpr var_name (sexpr x)
{
return car(cdr(x));
}
sexpr is_var (sexpr x)
{
return (consp(x) && eq(symbol("VAR"),car(x)));
}
sexpr is_anovar (sexpr x)
{
return is_var(x) && eq (nil, var_name(x));
}
int boundvenv (sexpr env, sexpr var)
{
if (!consp(env))
return 0;
if (eq(car(car(env)),var)
&& consp(cdr(car(env)))
&& !eq(car(cdr(car(env))),symbol("UNDEFINED")))
return 1;
return boundvenv (cdr(env), var);
}
sexpr getrecvenv (sexpr env, sexpr var)
{
sexpr val;
if (!boundvenv(env,var))
return create_var(var);
val = getvenv (env, var);
if (!is_var(val))
return val;
return getrecvenv (env, var_name(val));
}
sexpr set (sexpr l)
{
if (!consp(l))
return l;
if (istrue(memq(car(l),cdr(l))))
return set (cdr(l));
return cons (car(l), set(cdr(l)));
}
sexpr variables1 (sexpr x)
{
if (is_var(x))
return cons (var_name(x), nil);
if (!consp(x))
return nil;
return append (variables1(car(x)), variables1(cdr(x)));
}
sexpr variables (sexpr x)
{
return set (variables1(x));
}
sexpr subst (sexpr x, sexpr y, sexpr z)
{
if (eq(y,z))
return x;
if (!consp(z))
return z;
return cons (subst(x,y,car(z)), subst(x,y,cdr(z)));
}
sexpr rename1 (sexpr x, sexpr vars)
{
if (!consp(vars))
return x;
return rename1 (subst(gensym(),car(vars),x),cdr(vars));
}
sexpr renam (sexpr x)
{
return rename1 (x, variables(x));
}
sexpr build (sexpr env, sexpr x)
{
if (is_var(x))
return getrecvenv (env, var_name(x));
if (!consp(x))
return x;
return cons (build(env,car(x)), build(env,cdr(x)));
}
sexpr link (sexpr env, sexpr var, sexpr val)
{
return setvenv (env, var, val);
}
sexpr unify (sexpr env, sexpr x, sexpr y);
#define OCCUR_CHECK 1
sexpr unify1 (sexpr env, sexpr x, sexpr y)
{
if (is_anovar(x) || is_anovar(y) || equal(x,y))
return env;
if (is_var(x) && (!OCCUR_CHECK || !istrue(memq(var_name(x),variables(y)))))
return link (env, var_name(x), y);
if (is_var(y) && (!OCCUR_CHECK || !istrue(memq(var_name(y),variables(x)))))
return link (env, var_name(y), x);
if (!consp(x) || !consp(y))
return nil;
return unify (unify1(env,car(x),car(y)),cdr(x),cdr(y));
}
sexpr unify (sexpr env, sexpr x, sexpr y)
{
if (!istrue(env))
return env;
return unify1 (env, build(env,x), build(env,y));
}
#define PRIO(ctx) (int_sexpr(car(car(ctx))))
#define LINCR(ctx) (int_sexpr(car(cdr(car(ctx)))))
#define RINCR(ctx) (int_sexpr(car(cdr(cdr(car(ctx))))))
void setlincr (sexpr x)
{
strat = cons (car(strat), cons (x, cdr(cdr(strat))));
}
void setrincr (sexpr x)
{
strat = cons (car(strat), cons (car(cdr(strat)), cons (x, cdr(cdr(cdr(strat))))));
}
sexpr getctx (void)
{
sexpr ctx;
int i;
ctx = nil;
for (i=npsexpr-1; i>=1; i--)
ctx = cons (psexpr[i], ctx);
return ctx;
}
sexpr getctx_enlinstr (void)
{
sexpr ctx, x;
x = car(prog);
prog = cdr(prog);
ctx = getctx();
prog = cons (x, prog);
return ctx;
}
sexpr enlinstr (sexpr ctx)
{
return cons (car(ctx), cons (cdr(car(cdr(ctx))), cdr(cdr(ctx))));
}
sexpr preminstr (sexpr ctx)
{
return car(car(cdr(ctx)));
}
sexpr ajinstr (sexpr x, sexpr ctx)
{
return cons (car(ctx), cons (cons(x,car(cdr(ctx))), cdr(cdr(ctx))));
}
void setctx (sexpr ctx)
{
sexpr p;
int i;
for (p=ctx, i=1; i= PRIO(car(ctxs)))
return cons (ctx, ctxs);
return cons (car(ctxs), insctx (ctx, cdr(ctxs)));
}
sexpr inslctxs (sexpr l1, sexpr l2)
{
if (!pairp(l1))
return l2;
return insctx (car(l1), inslctxs (cdr(l1), l2));
}
void alt1 (void)
{
lctxs = insctx (getctx(), lctxs);
prog = cdr(prog);
}
void end (void);
void alt (void)
{
sexpr ctxl, ctxr, l, r;
int p, li, ri;
p = int_sexpr (car(strat));
li = int_sexpr(car(cdr(strat)));
ri = int_sexpr(car(cdr(cdr(strat))));
l = car(prog);
prog = cdr(prog);
strat = cons (sexpr_int(p+ri), cdr(strat));
ctxr = getctx();
prog = cons (l, cdr(prog));
strat = cons (sexpr_int(p+li), cdr(strat));
ctxl = getctx();
lctxs = insctx (ctxr, lctxs);
lctxs = insctx (ctxl, lctxs);
end ();
}
void init_ctx (int load_init);
void end (void)
{
sexpr ctx;
if (!pairp(lctxs))
{
init_ctx (0);
prog = cons (symbol("RESTART"), prog);
}
else
{
ctx = car(lctxs);
lctxs = cdr(lctxs);
setctx (ctx);
}
}
/*
void setctxs (sexpr ctxs)
{
if (!pairp(ctxs))
end();
else
{
lctxs = inslctxs (cdr(ctxs), lctxs);
setctx (car(ctxs));
}
}
*/
void setctxs (sexpr ctxs)
{
/*
lctxs = inslctxs (ctxs, lctxs);
end ();
*/
if (consp(ctxs))
{
lctxs = inslctxs (cdr(ctxs), lctxs);
setctx (car(ctxs));
}
else
{
end();
}
}
void step (void);
sexpr evol1 (sexpr ctx)
{
sexpr savectx, savelctxs, nctx, nctxs;
/*
printf ("\nevol: ctx=");
printstd (ctx);
printf ("\n");
*/
if (eq(car(car(cdr(ctx))),instruction("END")))
return nil;
savectx = getctx();
savelctxs = lctxs;
/*
printf ("\nevol: setctx ");
printstd (ctx);
*/
setctx (ctx);
/*
printf (" done\n");
*/
lctxs = nil;
step ();
nctx = getctx();
nctxs = cons (nctx, lctxs);
setctx (savectx);
lctxs = savelctxs;
return nctxs;
}
sexpr evol (sexpr ctx)
{
sexpr savectx, savelctxs, nctx, nctxs, ctx1, instr;
/*
printf ("\nevol: ctx=");
printstd (ctx);
printf ("\n");
*/
if (eq(car(car(cdr(ctx))),instruction("END")))
return nil;
savectx = getctx();
savelctxs = lctxs;
/*
printf ("\nevol: setctx ");
printstd (ctx);
*/
setctx (ctx);
/*
printf (" done\n");
*/
lctxs = nil;
instr = car(prog);
while (!consp(lctxs)
&& !eq(instr,instruction("END"))
&& !eq(instr,symbol("STOP"))
&& !eq(instr,symbol("META-APPLY"))
&& !eq(instr,symbol("META"))
&& !eq(instr,symbol("GETLCTXS"))
&& !eq(instr,symbol("LEVEL")))
{
step ();
instr = car(prog);
/*
printf ("instr=");
printstd (instr);
printf ("\n");
trace_step();
*/
}
if (eq(car(car(cdr(ctx))),instruction("END")))
{
setctx (savectx);
lctxs = savelctxs;
return nil;
}
nctx = getctx();
nctxs = cons (nctx, lctxs);
setctx (savectx);
lctxs = savelctxs;
return nctxs;
}
sexpr getgctxs (void)
{
return cons (getctx(), lctxs);
}
sexpr setgctxs (sexpr ctxs)
{
lctxs = cdr(ctxs);
setctx (car(ctxs));
}
sexpr gcut (void)
{
lctxs = nil;
}
sexpr depil (sexpr ctx)
{
return cons (car(ctx), cons (car(cdr(ctx)), cons (cdr(car(cdr(cdr(ctx)))), cdr(cdr(cdr(ctx))))));
}
sexpr sompil (sexpr ctx)
{
return car(car(cdr(cdr(ctx))));
}
sexpr empil (sexpr x, sexpr ctx)
{
return cons (car(ctx), cons(car(cdr(ctx)),
cons(cons(x,car(cdr(cdr(ctx)))), cdr(cdr(cdr(ctx))))));
}
#define STRAT(ctx) car(ctx)
#define PROG(ctx) car(cdr(ctx))
#define STACK(ctx) car(cdr(cdr(ctx)))
#define RSTACK(ctx) car(cdr(cdr(cdr(ctx))))
#define ENVIR(ctx) car(cdr(cdr(cdr(cdr(ctx)))))
sexpr mkcnl (sexpr x)
{
return cons (symbol("CNL"), cons (nil, cons (nil, cons (x, nil))));
}
sexpr enfiler (sexpr prio, sexpr ctx, sexpr file)
{
if (!istrue(prio))
{
sexpr x;
x = last(file);
rplacd (x, cons (ctx, nil));
return;
}
if (int_sexpr(car(STRAT(car(file)))) < int_sexpr(car(STRAT(ctx))))
{
rplacd (file, cons (car(file), cdr(file)));
rplaca (file, ctx);
return;
}
if (!istrue(cdr(file)))
{
rplacd (file, cons (ctx, nil));
return;
}
enfiler (prio, ctx, cdr(file));
}
sexpr instr_send (sexpr ctx)
{
sexpr canal, x, flag, file, prio, ctxc;
canal = car(STACK(ctx));
x = car(cdr(STACK(ctx)));
if (!istrue(car(cdr(cdr(canal)))))
{
rplacd (canal, cons(tru,cons(cons(ctx,nil),
cons(car(cdr(cdr(cdr(canal)))),nil))));
return tru;
}
flag = car(cdr(canal));
file = car(cdr(cdr(canal)));
prio = car(cdr(cdr(cdr(canal))));
if (istrue(flag))
{
enfiler (prio, ctx, file);
return tru;
}
rplaca (cdr(cdr(canal)), cdr(file));
ctxc = car(file);
return cons(
cons(STRAT(ctxc),
cons(PROG(ctxc),
cons(cons(x,cdr(STACK(ctxc))),
cdr(cdr(cdr(ctxc))) ))),
cons(
cons(STRAT(ctx),
cons(PROG(ctx),
cons(cdr(cdr(STACK(ctx))),
cdr(cdr(cdr(ctx))) ))),
nil ));
}
sexpr instr_receive (sexpr ctx)
{
sexpr canal, xc, flag, file, prio, ctxc;
canal=car(STACK(ctx));
if (!istrue(car(cdr(cdr(canal)))))
{
rplacd(canal,cons(nil,cons(cons(ctx,nil),
cons(car(cdr(cdr(cdr(canal)))),nil))));
return tru;
}
flag=car(cdr(canal));
file=car(cdr(cdr(canal)));
prio=car(cdr(cdr(cdr(canal))));
if (!istrue(flag))
{
enfiler(prio,ctx,file);
return tru;
}
rplaca(cdr(cdr(canal)),cdr(file));
ctxc=car(file);
xc=car(cdr(STACK(ctxc)));
return cons(
cons(STRAT(ctxc),
cons(PROG(ctxc),
cons(cdr(cdr(STACK(ctxc))),
cdr(cdr(cdr(ctxc))) ))),
cons(
cons(STRAT(ctx),
cons(PROG(ctx),
cons(cons(xc,cdr(STACK(ctx))),
cdr(cdr(cdr(ctx))) ))),
nil ));
}
#include "definstr.h"
/* #define DEFINSTR(str) } else if (!strcmp (str_sexpr(instr), str)) { */
#define INSTR0(f) stack = cons (f(), stack);
#define INSTR1(f) stack = cons (f(car(stack)), cdr(stack));
#define INSTR2(f) stack = cons (f(car(stack),car(cdr(stack))), cdr(cdr(stack)));
#define INSTR3(f) stack = cons (f(car(stack),car(cdr(stack)),car(cdr(cdr(stack)))), cdr(cdr(cdr(stack))));
void exec_instr (sexpr instr)
{
sexpr x;
int i;
if (0) {
/* Combinators */
DEFINSTR("I")
;
DEFINSTR("K")
prog = cons (car(prog), cdr(cdr(prog)));
DEFINSTR("S")
prog = cons (cons(car(prog),car(cdr(cdr(prog)))), cons(car(cdr(prog)), cons(car(cdr(cdr(prog))), cdr(cdr(cdr(prog))))));
DEFINSTR("Y")
prog = cons (car(prog), cons(cons(instr,cons(car(prog),nil)), cdr(prog)));
DEFINSTR("B")
prog = cons (car(prog), cons (cons(car(cdr(prog)), cons (car(cdr(cdr(prog))), nil)), cdr(cdr(cdr(prog)))));
DEFINSTR("C")
prog = cons (car(prog), cons (car(cdr(cdr(prog))), cons (car(cdr(prog)), cdr(cdr(cdr(prog))))));
DEFINSTR("W")
prog = cons (car(prog), cons (car(cdr(prog)), cons (car(cdr(prog)), cdr(cdr(prog)))));
DEFINSTR("APPLYTO")
prog = cons (car(cdr(prog)), cons (car(prog), cdr(cdr(prog))));
DEFINSTR("P")
prog = cons (car(cdr(cdr(prog))), cons (car(prog), cons (car(cdr(prog)), cdr(cdr(cdr(prog))))));
DEFINSTR("J")
prog = cdr(prog);
/* Quote */
DEFINSTR("QUOTE")
stack = cons (car(prog), stack);
prog = cdr(prog);
DEFINSTR("Q")
stack = cons (car(prog), stack);
prog = cdr(prog);
/* Stack manipulation */
DEFINSTR("DEP")
stack = cdr(stack);
DEFINSTR("REP")
stack = cons (car(stack), stack);
DEFINSTR("ECH")
stack = cons (car(cdr(stack)), cons (car(stack), cdr(cdr(stack))));
DEFINSTR("DES")
rstack = cons (car(stack), rstack);
stack = cdr(stack);
DEFINSTR("MON")
stack = cons (car(rstack), stack);
rstack = cdr(rstack);
DEFINSTR("MONDEP")
rstack = cdr(rstack);
DEFINSTR("GETH")
stack = cons (nth(rstack,int_sexpr(car(prog))), stack);
prog = cdr(prog);
/* Tests */
DEFINSTR("THEN")
if (istrue(car(stack)))
prog = cons (car(prog), cdr(cdr(prog)));
else
prog = cdr(prog);
stack = cdr(stack);
DEFINSTR("NCONSPTHEN")
if (!pairp(car(stack)))
prog = cons (car(prog), cdr(cdr(prog)));
else
prog = cdr(prog);
stack = cdr(stack);
DEFINSTR("CONSP")
if (consp(car(stack)))
stack = cons (tru, cdr(stack));
else
stack = cons (nil, cdr(stack));
/* Execution */
DEFINSTR("EXEC")
prog = cons (car(stack), prog);
stack = cdr(stack);
/* Definition */
DEFINSTR("GETDEF")
if (TYPE(car(stack))!=TYPE_SYMBOL)
error ("GETDEF of non symbol", car(stack));
else
stack = cons (DEF(car(stack)), cdr(stack));
DEFINSTR("SETDEF")
if (TYPE(car(stack))!=TYPE_SYMBOL)
error ("SETDEF of non symbol", car(stack));
else
{
DEF(car(stack)) = car(cdr(stack));
stack = cdr(cdr(stack));
}
DEFINSTR("def")
if (TYPE(car(prog))!=TYPE_SYMBOL)
error ("def of non symbol", car(prog));
else
{
DEF(car(prog)) = car(cdr(prog));
prog = cdr(cdr(prog));
}
DEFINSTR("DEF")
if (TYPE(car(prog))!=TYPE_SYMBOL)
error ("def of non symbol", car(prog));
else
{
DEF(car(prog)) = car(cdr(prog));
prog = cdr(cdr(prog));
}
DEFINSTR("GETPROPS")
if (TYPE(car(stack))==TYPE_GENSYM)
stack = cons (nil, cdr(stack));
if (TYPE(car(stack))!=TYPE_SYMBOL)
error ("GETPROPS of non symbol", car(stack));
else
{
stack = cons (PROPS(car(stack)), cdr(stack));
}
DEFINSTR("SETPROPS")
if (TYPE(car(stack))!=TYPE_SYMBOL)
error ("SETPROPS of non symbol", car(stack));
else
{
PROPS(car(stack)) = car(cdr(stack));
stack = cdr(cdr(stack));
}
/* Primitives */
DEFINSTR("CAR")
stack = cons (car(car(stack)), cdr(stack));
DEFINSTR("CDR")
stack = cons (cdr(car(stack)), cdr(stack));
DEFINSTR("CONS")
stack = cons (cons(car(stack),car(cdr(stack))), cdr(cdr(stack)));
DEFINSTR("EQ")
stack = cons (sexpr_eq(car(stack),car(cdr(stack))), cdr(cdr(stack)));
DEFINSTR("GETTYPE")
stack = cons (sexpr_int(TYPE(car(stack))), cdr(stack));
DEFINSTR("SETTYPE")
stack = cons (SEXPR(int_sexpr(car(stack)),UTVAL(car(cdr(stack)))), cdr(cdr(stack)));
DEFINSTR("RPLACA")
if (!pairp(car(stack)))
error ("RPLACA of non cons", car(stack));
else
{
CAR(car(stack)) = car(cdr(stack));
SETOCC(UTVAL(car(stack)));
stack = cdr(cdr(stack));
}
DEFINSTR("RPLACD")
if (!pairp(car(stack)))
error ("RPLACD of non cons", car(stack));
else
{
CDR(car(stack)) = car(cdr(stack));
stack = cdr(cdr(stack));
}
DEFINSTR("NOT")
stack = cons (not(car(stack)), cdr(stack));
DEFINSTR("PLUS")
stack = cons (sexpr_int(int_sexpr(car(cdr(stack)))+int_sexpr(car(stack))), cdr(cdr(stack)));
DEFINSTR("MOINS")
stack = cons (sexpr_int(int_sexpr(car(cdr(stack)))-int_sexpr(car(stack))), cdr(cdr(stack)));
DEFINSTR("FOIS")
stack = cons (sexpr_int(int_sexpr(car(cdr(stack)))*int_sexpr(car(stack))), cdr(cdr(stack)));
DEFINSTR("DIV")
stack = cons (sexpr_int(int_sexpr(car(cdr(stack)))/int_sexpr(car(stack))), cdr(cdr(stack)));
DEFINSTR("MOD")
stack = cons (sexpr_int(int_sexpr(car(cdr(stack)))%int_sexpr(car(stack))), cdr(cdr(stack)));
DEFINSTR("ETL")
stack = cons (sexpr_int(int_sexpr(car(cdr(stack)))&int_sexpr(car(stack))), cdr(cdr(stack)));
DEFINSTR("OUL")
stack = cons (sexpr_int(int_sexpr(car(cdr(stack)))|int_sexpr(car(stack))), cdr(cdr(stack)));
DEFINSTR("OXL")
stack = cons (sexpr_int(int_sexpr(car(cdr(stack)))^int_sexpr(car(stack))), cdr(cdr(stack)));
DEFINSTR("GENSYM")
stack = cons (gensym(), stack);
/* Strings */
DEFINSTR("NEWSTR")
stack = cons (new_string_length(int_sexpr(car(stack))), cdr(stack));
DEFINSTR("GETSTRCHAR")
sexpr str;
int pos;
char *s;
char c;
str = car(stack);
pos = int_sexpr(car(cdr(stack)));
s = str_sexpr (str);
c = s[pos];
stack = cons (sexpr_int(c), cdr(cdr(stack)));
DEFINSTR("SETSTRCHAR")
sexpr str;
int pos;
char c;
char *s;
str = car(stack);
pos = int_sexpr(car(cdr(stack)));
c = int_sexpr(car(cdr(cdr(stack))));
s = str_sexpr (str);
s[pos] = c;
stack = cdr(cdr(cdr(stack)));
/* Arithmetic tests */
DEFINSTR("ZEROP")
if ((TYPE(car(stack)) == TYPE_INT) && (UTVAL(car(stack)) == 0))
stack = cons (tru, cdr(stack));
else
stack = cons (nil, cdr(stack));
DEFINSTR("POSP")
if ((TYPE(car(stack)) == TYPE_INT) && (UTVAL(car(stack)) >= 0))
stack = cons (tru, cdr(stack));
else
stack = cons (nil, cdr(stack));
/* Input Output */
DEFINSTR("TYI")
i = getchar();
stack = cons (sexpr_int(i), stack);
DEFINSTR("TYO")
putchar (int_sexpr(car(stack)));
stack = cdr(stack);
DEFINSTR("READSTRING")
char buf[1000];
fgets (buf, sizeof(buf), stdin);
buf[strlen(buf)-1] = 0;
stack = cons (sexpr_string(buf), stack);
DEFINSTR("PRINTSTRING")
printf ("%s", str_string(car(stack)));
stack = cdr(stack);
DEFINSTR("READ")
x = read (stdi);
stack = cons (x, stack);
DEFINSTR("PRIN")
x = car(stack);
print (stdo, x, 32);
stack = cdr(stack);
DEFINSTR("PRINL")
x = car(cdr(stack));
print (stdo, x, int_sexpr(car(stack)));
stack = cdr(cdr(stack));
DEFINSTR("PRINT")
x = car(stack);
print (stdo, x, 32);
pstr (stdo, "\r\n");
stack = cdr(stack);
DEFINSTR("READFILE")
char *filename;
FILE *fh;
x = car(stack);
filename = str_sexpr(x);
fh = fopen (filename, "r");
if (fh == NULL)
{
printf ("\nREADFILE : Cannot open file \"%s\"\n", filename);
stack = cons (nil, cdr(stack));
}
else
{
struct file_input in[1];
in->f = fileif;
in->fh = fh;
x = read ((input)in);
stack = cons (x, cdr(stack));
}
DEFINSTR("LOAD1")
/* printf ("\nLOAD...\n"); */
char *filename;
FILE *fh;
x = car(stack);
filename = str_sexpr(x);
fh = fopen (filename, "r");
if (fh == NULL)
{
printf ("\nLOAD : Cannot open file \"%s\"\n", filename);
stack = cdr(stack);
}
else
{
struct file_input in[1];
in->f = fileif;
in->fh = fh;
x = read ((input)in);
/*
printf ("\nLOAD: read ");
print (stdo, x, 16);
printf ("\n");
*/
prog = cons (x, prog);
stack = cdr(stack);
}
/* Context access */
DEFINSTR("GETLCTXS")
stack = cons (lctxs, stack);
DEFINSTR("SETLCTXS")
lctxs = car(stack);
stack = cdr(stack);
DEFINSTR("GETSTRAT")
stack = cons (strat, stack);
DEFINSTR("SETSTRAT")
strat = car(stack);
stack = cdr(stack);
DEFINSTR("GETPROG")
stack = cons (prog, stack);
DEFINSTR("SETPROG")
prog = car(stack);
stack = cdr(stack);
DEFINSTR("GETSTACK")
stack = cons (stack, stack);
DEFINSTR("SETSTACK")
stack = car(stack);
DEFINSTR("GETENV")
stack = cons (envir, stack);
DEFINSTR("SETENV")
envir = car(stack);
stack = cdr(stack);
DEFINSTR("STEP")
step ();
DEFINSTR("GETPRIO")
stack = cons (car(strat), stack);
DEFINSTR("GETINCR")
stack = cons (car(cdr(strat)), stack);
DEFINSTR("GETLINCR")
stack = cons (car(cdr(strat)), stack);
DEFINSTR("GETRINCR")
stack = cons (car(cdr(cdr(strat))), stack);
DEFINSTR("SETPRIO")
strat = cons (car(stack), cdr(strat));
stack = cdr(stack);
DEFINSTR("SETINCR")
setlincr (car(stack));
setrincr (car(stack));
stack = cdr(stack);
DEFINSTR("SETLINCR")
setlincr (car(stack));
stack = cdr(stack);
DEFINSTR("SETRINCR")
setrincr (car(stack));
stack = cdr(stack);
DEFINSTR("GETCTX")
stack = cons (getctx(), stack);
DEFINSTR("GETCTX-ENLINSTR")
stack = cons (getctx_enlinstr(), stack);
DEFINSTR("ENLINSTR")
stack = cons (enlinstr(car(stack)), cdr(stack));
DEFINSTR("PREMINSTR") INSTR1(preminstr)
DEFINSTR("AJINSTR") INSTR2(ajinstr)
DEFINSTR("SETCTX")
setctx (car(stack));
DEFINSTR("SETCTXS")
setctxs (car(stack));
DEFINSTR("INSCTX") INSTR2(insctx)
DEFINSTR("INSLCTXS") INSTR2(inslctxs)
DEFINSTR("INSLCTX") INSTR2(inslctxs)
DEFINSTR("ALT1")
alt1 ();
DEFINSTR("ALT")
alt();
DEFINSTR("END")
end();
DEFINSTR("EVOL1") INSTR1(evol1)
DEFINSTR("EVOL") INSTR1(evol)
DEFINSTR("GETGCTXS") INSTR0(getgctxs)
DEFINSTR("GETCTXS") INSTR0(getgctxs)
DEFINSTR("SETGCTXS")
setgctxs (car(stack));
DEFINSTR("GCUT")
lctxs = nil;
DEFINSTR("DEPIL") INSTR1(depil)
DEFINSTR("SOMPIL") INSTR1(sompil)
DEFINSTR("EMPIL") INSTR2(empil)
/* Environment */
DEFINSTR("GETVENV")
stack = cons (getvenv(car(stack),car(cdr(stack))), cdr(cdr(stack)));
DEFINSTR("SETVENV")
stack = cons (setvenv(car(stack),car(cdr(stack)),car(cdr(cdr(stack)))), cdr(cdr(cdr(stack))));
DEFINSTR("ADDVENV")
stack = cons (addvenv(car(stack),car(cdr(stack)),car(cdr(cdr(stack)))), cdr(cdr(cdr(stack))));
DEFINSTR("REMVENV")
stack = cons (remvenv(car(stack),car(cdr(stack))), cdr(cdr(stack)));
DEFINSTR("GETVSENV")
stack = cons (getvsenv(car(stack),car(cdr(stack))), cdr(cdr(stack)));
DEFINSTR("BINDVEND")
stack = cons (bindvenv(car(stack),car(cdr(stack)),car(cdr(cdr(stack)))), cdr(cdr(cdr(stack))));
DEFINSTR("UNBINDVENV")
stack = cons (unbindvenv(car(stack),car(cdr(stack))), cdr(cdr(stack)));
DEFINSTR("GET")
stack = cons (getvsenv(envir,car(prog)), stack);
prog = cdr(prog);
DEFINSTR("GETVQ")
stack = cons (getvenv(envir,car(prog)), stack);
prog = cdr(prog);
DEFINSTR("GETVSQ")
stack = cons (getvsenv(envir,car(prog)), stack);
prog = cdr(prog);
DEFINSTR("SETVQ")
envir = setvenv (envir, car(prog), car(stack));
prog = cdr(prog);
stack = cdr(stack);
DEFINSTR("ARG")
envir = bindvenv (envir, car(prog), car(stack));
stack = cdr(stack);
prog = cons (car(cdr(prog)), cons(cons(instruction("UNBINDVQ"),cons(car(prog),nil)), cdr(cdr(prog))));
DEFINSTR("BINDVQ")
envir = bindvenv (envir, car(prog), car(stack));
stack = cdr(stack);
prog = cdr(prog);
DEFINSTR("UNBINDVQ")
envir = unbindvenv (envir, car(prog));
prog = cdr(prog);
/* List utilities */
DEFINSTR("LENGTH")
stack = cons (sexpr_int(length(car(stack))), cdr(stack));
DEFINSTR("LAST")
stack = cons (last(car(stack)), cdr(stack));
DEFINSTR("REVERSE")
stack = cons (reverse(car(stack)), cdr(stack));
DEFINSTR("EQUAL")
stack = cons (sexpr_logical(equal(car(stack),car(cdr(stack)))), cdr(cdr(stack)));
DEFINSTR("MEMQ")
stack = cons (memq(car(cdr(stack)),car(stack)), cdr(cdr(stack)));
DEFINSTR("MEMBER")
stack = cons (member(car(cdr(stack)),car(stack)), cdr(cdr(stack)));
DEFINSTR("REMQ")
stack = cons (remq(car(stack),car(cdr(stack))), cdr(cdr(stack)));
DEFINSTR("REMOVE")
stack = cons (remov(car(stack),car(cdr(stack))), cdr(cdr(stack)));
DEFINSTR("INCLQ")
stack = cons (sexpr_logical(inclq(car(stack),car(cdr(stack)))), cdr(cdr(stack)));
DEFINSTR("INCL")
stack = cons (sexpr_logical(incl(car(stack),car(cdr(stack)))), cdr(cdr(stack)));
DEFINSTR("APPEND") INSTR2(append)
DEFINSTR("BOUNDVENV") INSTR2(boundvenv)
DEFINSTR("GETRECVENV") INSTR2(getrecvenv)
DEFINSTR("ENSEMBLE") INSTR1(set)
DEFINSTR("VARIABLES") INSTR1(variables)
DEFINSTR("SUBST") INSTR3(subst)
DEFINSTR("RENAME") INSTR1(renam)
DEFINSTR("CONSTR") INSTR2(build)
DEFINSTR("UNIF") INSTR3(unify)
/* nil does nothing */
DEFINSTR("nil")
/* stack = cons (nil, stack); */
;
/* Predefined values */
DEFINSTR("t")
stack = cons (tru, stack);
DEFINSTR("true")
stack = cons (tru, stack);
/* GC */
DEFINSTR("GC")
gc();
/* Trace */
DEFINSTR("TRACESTEP")
trace_step_on = int_sexpr (car(stack));
stack = cdr(stack);
/* Compatibility */
DEFINSTR("DECLSYM") ;
/* Channels */
DEFINSTR("MKCNL") INSTR1(mkcnl)
DEFINSTR("ENFILER") INSTR3(enfiler)
DEFINSTR("INSTR-SEND") INSTR1(instr_send)
DEFINSTR("INSTR-RECEIVE") INSTR1(instr_receive)
/* Quit */
DEFINSTR("QUIT")
cont = 0;
}
else
{
error ("undefined instruction", instr);
}
}
#define TPL 16
void trace_step (void)
{
char buf[1000];
printf ("\n\tlctxs\t= ");
print (stdo, lctxs, TPL);
printf ("\n\tstrat\t= ");
print (stdo, strat, TPL);
printf ("\n\tprog\t= ");
print (stdo, prog, TPL);
printf ("\n\tstack\t= ");
print (stdo, stack, TPL);
printf ("\n\trstack\t= ");
print (stdo, rstack, TPL);
printf ("\n\tenvir\t= ");
print (stdo, envir, TPL);
/*
printf ("\n\tLOAD = ");
print (stdo, DEF(symbol("LOAD")), 16);
*/
printf ("\n");
if (trace_step_on & 2)
fgets (buf, sizeof(buf), stdin);
}
void step (void)
{
/* sexpr instr; */
sexpr d;
if (trace_step_on)
trace_step ();
instr = car(prog);
prog = cdr(prog);
switch (TYPE(instr))
{
case TYPE_INSTR:
exec_instr (instr);
break;
case TYPE_PAIR:
prog = append (instr, prog);
break;
case TYPE_SYMBOL:
d = def(instr);
prog = cons (d, prog);
break;
default:
stack = cons (instr, stack);
break;
}
}
void init_ctx (int load_init)
{
npsexpr = 6;
lctxs = nil;
strat = cons (sexpr_int(0), cons (sexpr_int(0), cons (sexpr_int(0), nil)));
prog = cons (instruction("Y"), cons (cons (instruction("READ"), cons (instruction("EXEC"), nil)), nil));
if (load_init)
prog = cons (sexpr_string("init.lpi"),
cons (instruction("LOAD1"),
cons (instruction("Y"),
cons (cons(instruction("READ"),cons(instruction("EXEC"),nil)),
nil))));
else
prog = cons (instruction("Y"),
cons (cons(instruction("READ"),cons(instruction("EXEC"),nil)), nil));
/*
prog = cons (instruction("Y"), cons (cons (instruction("READ"), cons (instruction("EXEC"), cons (sexpr_int(13), cons (instruction("TYO"),
cons (sexpr_int(10), cons (instruction("TYO"), nil)))))), nil));
*/
stack = nil;
rstack = nil;
envir = tru;
}
void init_interp (void)
{
init_ctx (1);
cont = 1;
trace_step_on = 0;
}
void interp (void)
{
sexpr x;
init();
init_interp();
/* x = symbol("LOAD"); */
while (cont)
{
step ();
clrnsexpr();
}
}
main ()
{
interp ();
}