The Pico Evaluator

(contents of the file Eval.pco)
general info

{ eval(Exp):
 error('evaluator not initialized');
 
 init_eval(Dct):
 { DCT: Dct;
 eval_variable (Exp):
 { nam: Exp[VAR_NAM_idx];
 get(nam, DCT) };
 call_function (Exp, Dct):
 { dct: DCT;
 DCT:= Dct;
 val: eval(Exp);
 DCT:= dct;
 val };
 bind_variable (Exp, Var, Dct):
 { nam: Var[VAR_NAM_idx];
 val: eval(Exp);
 add(nam, val, Dct) };
 bind_application (Exp, Apl, Dct):
 { nam: Apl[APL_NAM_idx];
 arg: Apl[APL_ARG_idx]; 
 fun: FUN(nam, arg, Exp, DCT);
 add(nam, fun, Dct) };
 bind_error(Tab, Err, Dct):
 error('illegal parameter');
 
 bind_case : case(VAR_tag => bind_variable,
 APL_tag => bind_application,
 else => bind_error);
 
 call_table (TbA, TbP, Dct):
 { tbA: TbA[TAB_TAB_idx];
 tbP: TbP[TAB_TAB_idx];
 siz: size(tbA);
 if(siz = size(tbP),
 for(k: 1, k:= k+1, not(k> siz),
 { arg: tbA[k];
 par: tbP[k];
 tag: par[TAG_idx];
 cas: bind_case(tag);
 Dct:= cas(arg, par, Dct) }),
 error('Illegal argument count'));
 Dct };
 call_variable (Tab, Var, Dct):
 { nam: Var[VAR_NAM_idx];
 tab: Tab[TAB_TAB_idx];
 siz: size(tab);
 exp: if(siz> 0,
 { idx: 0;
 arg[siz]: eval(tab[idx:= idx+1]);
 TAB(arg) },
 Empty);
 add(nam, exp, Dct) };
 
 call_error(Tab, Apl, Dct):
 error('illegal parameter');
 
 call_case : case(TAB_tag => call_table,
 VAR_tag => call_variable,
 else => call_error);
 
 eval_call (Fun, Tab):
 { par: Fun[FUN_PAR_idx];
 exp: Fun[FUN_EXP_idx];
 dct: Fun[FUN_DCT_idx];
 tag: par[TAG_idx];
 cas: call_case(tag);
 dct:= cas(Tab, par, dct);
 call_function(exp, dct) };
 eval_application (Exp):
 { nam: Exp[APL_NAM_idx];
 arg: Exp[APL_ARG_idx];
 exp: get(nam, DCT);
 if(exp[TAG_idx] = FUN_tag,
 if(arg[TAG_idx] = TAB_tag,
 eval_call(exp, arg),
 { val: eval(arg);
 if(val[TAG_idx] = TAB_tag,
 eval_call(exp, val),
 error('illegal argument')) }),
 if(exp[TAG_idx] = NAT_tag,
 { nat: exp[NAT_NAT_idx]; 
 nat@arg },
 error('(native) function required'))) };
 eval_tabulation (Exp):
 { nam: Exp[TBL_NAM_idx];
 exp: get(nam, DCT);
 if(exp[TAG_idx] = TAB_tag,
 { idx: Exp[TBL_IDX_idx];
 val: eval(idx);
 if(val[TAG_idx] = NBR_tag,
 { nbr: val[NBR_VAL_idx];
 if(nbr> 0, 
 { tab: exp[TAB_TAB_idx];
 if(nbr> size(tab),
 error('index beyond size'),
 tab[nbr]) },
 error('non-positive index')) },
 error('invalid index')) },
 error('table required')) };
 define_variable (Var, Exp):
 { nam: Var[VAR_NAM_idx];
 val: eval(Exp);
 DCT:= add(nam, val, DCT);
 val };
 
 define_application (Apl, Exp):
 { nam: Apl[APL_NAM_idx];
 arg: Apl[APL_ARG_idx];
 DCT:= add(nam, Void, DCT);
 fun: FUN(nam, arg, Exp, DCT);
 set(nam, fun, DCT);
 fun };
 
 define_tabulation (Tbl, Exp):
 { nam: Tbl[TBL_NAM_idx];
 idx: Tbl[TBL_IDX_idx];
 val: eval(idx);
 if(val[TAG_idx] = NBR_tag,
 { nbr: val[NBR_VAL_idx];
 if(nbr < 0, error('negative size'), { exp: if(nbr> 0,
 { tab[nbr]: eval(Exp);
 TAB(tab) },
 Empty );
 DCT:= add(nam, exp, DCT);
 exp }) },
 error('invalid size')) }; 
 
 define_error(Inv, Exp):
 error('invocation required');
 
 define_case : case(VAR_tag => define_variable,
 APL_tag => define_application,
 TBL_tag => define_tabulation,
 else => define_error);
 
 eval_definition (Exp):
 { inv: Exp[DEF_INV_idx];
 exp: Exp[DEF_EXP_idx];
 tag: inv[TAG_idx];
 cas: define_case(tag);
 cas(inv, exp) };
 assign_variable (Var, Exp):
 { nam: Var[VAR_NAM_idx];
 val: eval(Exp);
 set(nam, val, DCT);
 val };
 
 assign_application (Apl, Exp):
 { nam: Apl[APL_NAM_idx];
 arg: Apl[APL_ARG_idx];
 fun: FUN(nam, arg, Exp, DCT);
 set(nam, fun, DCT);
 fun };
 
 assign_tabulation (Tbl, Exp):
 { nam: Tbl[TBL_NAM_idx];
 exp: get(nam, DCT);
 if(exp[TAG_idx] = TAB_tag,
 { idx: Tbl[TBL_IDX_idx];
 val: eval(idx);
 if(val[TAG_idx] = NBR_tag,
 { nbr: val[NBR_VAL_idx];
 if(nbr> 0, 
 { tab: exp[TAB_TAB_idx];
 if(nbr> size(tab),
 error('index beyond size'),
 { tab[nbr]:= eval(Exp);
 exp }) },
 error('non-positive index')) },
 error('invalid index')) },
 error('table required')) };
 
 assign_error(Inv, Exp):
 error('invocation required');
 
 assign_case : case(VAR_tag => assign_variable,
 APL_tag => assign_application,
 TBL_tag => assign_tabulation,
 else => assign_error);
 
 eval_assignment (Exp):
 { inv: Exp[SET_INV_idx];
 exp: Exp[SET_EXP_idx];
 tag: inv[TAG_idx];
 cas: assign_case(tag);
 cas(inv, exp) };
 
 eval_identity (Exp):
 Exp;
 
 eval_case : case(VAR_tag => eval_variable,
 APL_tag => eval_application,
 TBL_tag => eval_tabulation,
 DEF_tag => eval_definition,
 SET_tag => eval_assignment,
 else => eval_identity);
 
 init_eval(Dct):=
 { DCT:= Dct;
 void };
 eval (Exp):=
 { tag: Exp[TAG_idx];
 cas: eval_case(tag);
 cas(Exp) };
 
 void };
 display('evaluator installed', eoln) }

Back to the metacircular evaluator

This page was made (with lots of hard work!) by Wolfgang De Meuter

AltStyle によって変換されたページ (->オリジナル) /