Eval.pco
)
{ 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) }
This page was made (with lots of hard work!) by Wolfgang De Meuter