Eval.borg
Eval.borg
`*-----------------------------------*`
`* >>>Pico v.1.1<<< *`
`* Theo D'Hondt *`
`* VUB Programming Technology Lab *`
`* (c)1999 *`
`*-----------------------------------*`
`* evaluator *`
`* (METACIRCULAR VERSION) *`
`*-----------------------------------*`
{ Eval(Exp):
Error('evaluator not initialized');
Apply(Fun, Tab):
Error('evaluator not initialized');
Capture():
Error('evaluator not initialized');
Init_Eval(Dct):
{ DCT: Dct;
eval_reference(Ref)::
{ nam: Ref[REF_NAM_idx];
Get_Any(nam, DCT) };
call_function(Exp, Dct)::
{ dct: DCT;
DCT:= Dct;
val: Eval(Exp);
DCT:= dct;
val };
bind_reference(Exp, Ref, Dct)::
{ nam: Ref[REF_NAM_idx];
val: Eval(Exp);
Add_Var(nam, val, Dct) };
bind_application(Exp, Apl, Dct)::
{ nam: Apl[APL_NAM_idx];
arg: Apl[APL_ARG_idx];
fun: Make_FUN(nam, arg, Exp, DCT);
Add_Var(nam, fun, Dct) };
bind_error(Tab, Err, Dct)::
Error('illegal parameter');
bind_case:: case(REF_tag <> bind_reference,
APL_tag <> bind_application,
void <> 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 <= siz, k:= k+1,
{ 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_reference(Tab, Ref, Dct)::
{ nam: Ref[REF_NAM_idx];
tab: Tab[TAB_TAB_idx];
siz: size(tab);
exp: if(siz > 0,
{ idx: 0;
arg[siz]: Eval(tab[idx:= idx+1]);
Make_TAB(arg) },
_EMPTY_);
Add_Var(nam, exp, Dct) };
call_error(Tab, Apl, Dct)::
Error('illegal parameter');
call_case:: case(TAB_tag <> call_table,
REF_tag <> call_reference,
void <> 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) };
application(Exp, Arg)::
{ if(Arg[TAG_idx] != TAB_tag,
Arg:= Eval(Arg));
if(Arg[TAG_idx] = TAB_tag,
if(Exp[TAG_idx] = FUN_tag,
eval_call(Exp, Arg),
if(Exp[TAG_idx] = NAT_tag,
{ nat: Exp[NAT_NAT_idx];
nat@Arg },
Error('(native) function required'))),
Error('illegal argument')) };
eval_application(Apl)::
{ nam: Apl[APL_NAM_idx];
arg: Apl[APL_ARG_idx];
exp: Get_Any(nam, DCT);
application(exp, arg) };
tabulation(Exp, Idx)::
if(Idx[TAG_idx] = TAB_tag,
{ itb: Idx[TAB_TAB_idx];
siz: size(itb);
loop(Tab, Cnt):
{ val: Eval(itb[Cnt]);
if(val[TAG_idx] = NBR_tag,
{ nbr: val[NBR_VAL_idx];
tag: Tab[TAG_idx];
if(nbr>0,
if(tag = TAB_tag,
{ tab: Tab[TAB_TAB_idx];
if(nbr > size(tab),
Error('index beyond size'),
if(Cnt < siz,
loop(tab[nbr], Cnt+1),
tab[nbr])) },
if(nbr > SIZ_tab(tag),
Error('index beyond size'),
if(Cnt < siz,
loop(Tab[nbr+1], Cnt+1),
Tab[nbr+1]))),
Error('non-positive index')) },
Error('invalid size')) };
loop(Exp, 1) },
Error('indexes required'));
eval_tabulation(Tbl)::
{ nam: Tbl[TBL_NAM_idx];
idx: Tbl[TBL_IDX_idx];
exp: Get_Any(nam, DCT);
tabulation(exp, idx) };
message_reference(Ref, Dct)::
{ nam: Ref[REF_NAM_idx];
Get_Cst(nam, Dct) };
message_application(Apl, Dct)::
{ nam: Apl[APL_NAM_idx];
arg: Apl[APL_ARG_idx];
fun: Get_Cst(nam, Dct);
application(fun, arg) };
message_tabulation(Tbl, Dct)::
{ nam: Tbl[TBL_NAM_idx];
idx: Tbl[TBL_IDX_idx];
exp: Get_Cst(nam, Dct);
tabulation(exp, idx) };
message_error(Nam, Inv)::
Error('abstract grammar violation');
message_case:: case(REF_tag <> message_reference,
APL_tag <> message_application,
TBL_tag <> message_tabulation,
void <> message_error);
eval_message(Mes)::
{ nam: Mes[MES_NAM_idx];
exp: Get_Any(nam, DCT);
if((exp[TAG_idx] != VAR_tag)&(exp[TAG_idx] != CST_tag),
Error('dictionary required'),
{ inv: Mes[MES_INV_idx];
tag: inv[TAG_idx];
cas: message_case(tag);
cas(inv, exp) }) };
add_reference(Ref, Exp, Add)::
{ nam: Ref[REF_NAM_idx];
val: Eval(Exp);
DCT:= Add(nam, val, DCT);
val };
add_application(Apl, Exp, Add)::
{ nam: Apl[APL_NAM_idx];
arg: Apl[APL_ARG_idx];
fun: Make_FUN(nam, arg, Exp, _VOID_);
DCT:= Add(nam, fun, DCT);
fun[FUN_DCT_idx]:= DCT;
fun };
add_tabulation(Tbl, Exp, Add)::
{ nam: Tbl[TBL_NAM_idx];
idx: Tbl[TBL_IDX_idx];
if(idx[TAG_idx] = TAB_tag,
{ itb: idx[TAB_TAB_idx];
siz: size(itb);
loop(cnt):
{ val: Eval(itb[cnt]);
if(val[TAG_idx] = NBR_tag,
{ nbr: val[NBR_VAL_idx];
if(nbr>0,
{ tab[nbr]: if(cnt1),
Eval(Exp));
Make_TAB(tab) },
Error('non-positive index')) },
Error('invalid size')) };
tab: loop(1);
DCT:= Add(nam, tab, DCT);
tab },
Error('indexes required')) };
add_error(Inv, Exp, Add)::
Error('abstract grammar violation');
add_case:: case(REF_tag <> add_reference,
APL_tag <> add_application,
TBL_tag <> add_tabulation,
void <> add_error);
eval_definition(Def)::
{ inv: Def[DEF_INV_idx];
exp: Def[DEF_EXP_idx];
tag: inv[TAG_idx];
cas: add_case(tag);
cas(inv, exp, Add_Var) };
eval_declaration(Dcl)::
{ inv: Dcl[DCL_INV_idx];
exp: Dcl[DCL_EXP_idx];
tag: inv[TAG_idx];
cas: add_case(tag);
cas(inv, exp, Add_Cst) };
assign_reference(Ref, Exp)::
{ nam: Ref[REF_NAM_idx];
val: Eval(Exp);
Set_Var(nam, val, DCT);
val };
assign_application(Apl, Exp)::
{ nam: Apl[APL_NAM_idx];
arg: Apl[APL_ARG_idx];
fun: Make_FUN(nam, arg, Exp, DCT);
Set_Var(nam, fun, DCT);
fun };
assign_tabulation(Tbl, Exp)::
{ nam: Tbl[TBL_NAM_idx];
exp: Get_Any(nam, DCT);
idx: Tbl[TBL_IDX_idx];
if(idx[TAG_idx] = TAB_tag,
{ itb: idx[TAB_TAB_idx];
siz: size(itb);
loop(Tab, Cnt):
{ val: Eval(itb[Cnt]);
if(val[TAG_idx] = NBR_tag,
{ nbr: val[NBR_VAL_idx];
tag: Tab[TAG_idx];
if(nbr>0,
if(tag = TAB_tag,
{ tab: Tab[TAB_TAB_idx];
if(nbr > size(tab),
Error('index beyond size'),
if(Cnt < siz,
loop(tab[nbr], Cnt+1),
tab[nbr]:= Eval(Exp))) },
if(nbr > AG_range(tag),
Error('index beyond size'),
if(Cnt < siz,
loop(Tab[nbr+1], Cnt+1),
Tab[nbr+1]:= Eval(Exp)))),
Error('non-positive index')) },
Error('invalid size')) };
loop(exp, 1) },
Error('indexes required')) };
assign_error(Inv, Exp)::
Error('abstract grammar violation');
assign_case:: case(REF_tag <> assign_reference,
APL_tag <> assign_application,
TBL_tag <> assign_tabulation,
void <> 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_error(Inv, Exp)::
Error('abstract grammar violation');
eval_case:: case(VOI_tag <> eval_identity,
NAT_tag <> eval_identity,
FRC_tag <> eval_identity,
TXT_tag <> eval_identity,
TAB_tag <> eval_identity,
FUN_tag <> eval_identity,
REF_tag <> eval_reference,
APL_tag <> eval_application,
TBL_tag <> eval_tabulation,
MES_tag <> eval_message,
DEF_tag <> eval_definition,
DCL_tag <> eval_declaration,
SET_tag <> eval_assignment,
VAR_tag <> eval_identity,
CST_tag <> eval_identity,
CTX_tag <> eval_identity,
NBR_tag <> eval_identity,
void <> eval_error);
Init_Eval(Dct):=
{ DCT:= Dct;
void };
Eval(Exp):=
{ tag: Exp[TAG_idx];
cas: eval_case(tag);
cas(Exp) };
Apply(Fun, Tab):=
if(Fun[TAG_idx] = FUN_tag,
eval_call(Fun, Tab),
{ nat: Fun[NAT_NAT_idx];
nat@Tab });
Capture():=
DCT;
void };
display('evaluator .... installed', eoln) }