Stisp/Lisp interpreter

From Esolang
Jump to navigation Jump to search

The following is an attempt at implementing Lisp in Stisp. It's completely untested (since, as of August 2022, Stisp hasn't been implemented yet), but it should work with only minor changes.

# Evaluating things which behave as built-in functions:

(CAR x) -> eval[env] = x -> eval[env] -> car[];
(CDR x) -> eval[env] = x -> eval[env] -> cdr[];
(CONS xh xt) -> eval[env] = xh -> eval_cons[xt];
(EQP x1 x2) -> eval[env] = x1 -> eval_eqp[x2, env];
(ATOMP x) -> eval[env] = x -> eval[env] -> atomp[];
(EVAL xx xe) -> eval[env] = xx -> eval_eval[xe, env];

# Evaluating special forms:

(IF cond xt xf) -> eval[env] = cond -> eval[env] -> eval_if[xt, xf, env];
(LAMBDA params body) -> eval[env] = (CLOSURE params body env);
(QUOTE x) -> eval[env] = x;
(LIST . xs) -> eval[env] = xs -> eval_each[env];
(ENV) -> eval[env] = env;

# Evaluating applications and variables:

(xf . xa) -> eval[env] = xf -> eval_apply[xa, env];
var -> eval[((var value) . envt)] = value;
var -> eval[(envh . envt)] = var -> eval[envt];

# Implementations of built-in functions:

(h . t) -> car[] = h;
(h . t) -> cdr[] = t;

xh -> eval_cons[xt] = xh -> eval[env] -> eval_cons_2[xt];
h -> eval_cons_2[xt] = xt -> eval[env] -> swapped_cons[h];

t -> swapped_cons[h] = (h . t);

x1 -> eval_eqp[x2, env] = x1 -> eval[env] -> eval_eqp_2[x2, env];
v1 -> eval_eqp_2[x2, env] = x2 -> eval[env] -> eqp[v1];

v -> eqp[v] = TRUE;
v1 -> eqp[v2] = FALSE;

(h . t) -> atomp[] = FALSE;
v -> atomp[] = TRUE;

xx -> eval_eval[xe, env] = xx -> eval[env] -> eval_env_2[xe, env];
x -> eval_env_2[xe, env] = xe -> eval[env] -> eval_env_3[x];
e -> eval_env_3[x] = x -> eval[e];

# Implementation of IF:

FALSE -> eval_if[xt, xf, env] = xf -> eval[env];
v -> eval_if[xt, xf, env] = xt -> eval[env];

# Implementation of application:

xf -> eval_apply[xargs, env] = xf -> eval[env] -> eval_apply_2[xargs, env];
f -> eval_apply_2[xargs, env] = xargs -> eval_each[env] -> swapped_apply[f];

args -> swapped_apply[(CLOSURE params body env)] = params -> zip[args] -> append[env] -> swapped_eval[body];

env -> swapped_eval[x] = x -> eval[env];

# eval_each:

xs -> eval_each[env] = xs -> eval_each_2[(), env];
(xh . xt) -> eval_each_2[vs, env] = xh -> eval[env] -> eval_each_3[xt, vs, env];
() -> eval_each_2[vs, env] = vs -> reverse[];
vh -> eval_each_3[xt, vs, env] = xt -> eval_each_2[(vh . vs), env];

# Utility functions for lists:

vs1 -> zip[vs2] = vs1 -> zip_2[vs2, ()];
(h1 . t1) -> zip_2[(h2 . t2), vs] = t1 -> zip_2[t2, ((h1 h2) . vs)];
() -> zip_2[(), vs] = vs -> reverse[];

vs1 -> append[vs2] = vs1 -> reverse[] -> reverse_and_append[vs2];

(h . t) -> reverse_and_append[vs] = t -> reverse_and_append[(h . vs)];
() -> reverse_and_append[vs] = vs;

vs -> reverse[] = vs -> reverse_2[()];
(h . t) -> reverse[vs] = t -> reverse[(h . vs)];
() -> reverse[vs] = vs;