Continuation Semantics Expressed in Algol-68
See L. Allison, A Practical Introduction to Denotational Semantics, CUP, Cambridge Computer Science Texts V23, 1986.
Note proc eee,
proc ddd and
proc ccc in particular.
( print((newline," progch7.a68:Continuation Semantics 19/4/85 L.A.", newline));
#-----------------------------------------------------------------------------#
#lexical domains#
MODE ALFA = [1:10]CHAR;
INT plussy = 0, minussy = 1, timessy = 2, oversy = 3,
eqsy = 4, nesy = 5, ltsy = 6, lesy = 7, gtsy = 8, gesy = 9,
ident = 10, numeral = 11,
ifsy = 12, thensy = 13, elsesy = 14,
whilesy = 15, dosy = 16,
beginsy = 17, endsy = 18,
skipsy = 19,
semisy = 20, becomessy = 21, open = 22, close = 23,
varsy = 24, constsy = 25, procsy = 26,
gotosy = 27,
valofsy = 28, resultissy = 29,
stopsy = 30,
colon = 31,
writesy = 32;
#-----------------------------------------------------------------------------#
#syntactic domains#
INT plus = 0, minus = 1, times = 2, over = 3,
eq = 4, ne = 5, lt = 6, le = 7, gt = 8, ge = 9,
neg = 10;
MODE OPR = INT; # = {plus..neg} #
MODE BEXP = STRUCT(OPR opr, EXP left,right), # $e $W $e #
UEXP = STRUCT(OPR opr, EXP son), # $W $e #
VAR = ALFA, # $c #
IFEXP= STRUCT(EXP e1, e2, e3); # if $e then $e else $e #
MODE EXPNODE = UNION(BEXP, UEXP, VAR, INT, IFEXP, #valof#CMD);
MODE EXP = REF EXPNODE;
MODE LABEL = INT;
MODE ASSIGN = STRUCT(EXP lhs, rhs), # $e:=$e #
SEMI = STRUCT(CMD left, right), # $g;$g #
IFSTAT = STRUCT(EXP b, CMD gtrue, gfalse),# if $e then $g else $g #
WHILES = STRUCT(EXP b, CMD g), # while $e do $g #
BLOCK = STRUCT(DEC d, CMD g), # begin $d;$g end #
LABCMD = STRUCT(LABEL l, CMD g), # $n:$g #
G0T0 = LABEL, # goto $n #
ONEEXP = STRUCT(INT tag, EXP e); # resultis $e or write $e #
MODE CMDNODE = UNION(ASSIGN, SEMI, IFSTAT, WHILES, BLOCK,
#call# ALFA, LABCMD, G0T0, ONEEXP);
MODE CMD = REF CMDNODE;
MODE VARDEC = ALFA, # var $c #
CONSTDEC= STRUCT(ALFA id, EXP e), # const $c=$e #
PROCDEC = STRUCT(ALFA id, CMD g), # proc $c=$g #
DECLIST = STRUCT(DEC left, right); # $d;$d #
MODE DECNODE = UNION(VARDEC, CONSTDEC, PROCDEC, DECLIST);
MODE DEC = REF DECNODE;
#-------------------------------------------------------------------------#
# I/O #
LOC INT line no := 1;
LOC BOOL end of input := FALSE;
print((newline, line no, "->"));
OP = =(ALFA a, b)BOOL:
(LOC BOOL eq:=TRUE;
FOR i TO UPB a WHILE eq DO eq:=a[i]=b[i] OD;
eq
);
PROC getch = CHAR:
(LOC CHAR ch; LOC FILE si:=stand in;
PROC gc = CHAR:
(LOC FILE si2 := si;
PROC eof = (REF FILE f)BOOL:
(print((" [EOF]", newline)); ch:=".";
end of input := TRUE; GOTO eoflab
);
on logical file end(si2, eof);
get(si2, ch); print(ch);
eoflab: ch
);
PROC eol = (REF FILE f)BOOL:
(ch:=" "; newline(f); line no +:=1;
print((newline, line no, "->")); GOTO eolnlab
);
on line end(si, eol);
ch:=gc;
eolnlab: ch
) # getch #;
#-----------------------------------------------------------------------------#
LOC CHAR ch:=getch; #current character#
LOC INT sy; # current symbol code #
LOC ALFA word; # holds characters of a var or ident #
LOC INT n; # value if sy=numeral #
PROC error = (STRING m)VOID:
(print((newline, " error:", m, " lineno=", whole(line no,0),
" ch=", ch, " sy=", sy, " n=", n));
IF end of input THEN print(" end of input file") FI;
GOTO stop
);
PROC check = (INT sym, STRING message)VOID:
IF sy=sym THEN insymbol ELSE error(message) FI;
PROC insymbol = VOID:
(PROC letter = (CHAR ch)BOOL:
(ch >= "a" AND ch <= "z") OR (ch >= "A" AND ch <= "Z");
PROC digit = (CHAR ch)BOOL:
ch >= "0" AND ch <= "9";
LOC BOOL looked ahead := FALSE;
WHILE ch=" " DO ch:=getch OD; # ch~=" " #
FOR i FROM LWB word TO UPB word DO word[i]:=" " OD;
IF letter(ch) THEN
looked ahead := TRUE; word[1]:=ch; ch:=getch; LOC INT l:=1;
WHILE letter(ch) OR digit(ch) DO
l+:=1;
IF l <= UPB word THEN word[l]:=ch FI;
ch:=getch
OD;
IF word=ALFA("i","f"," "," "," "," "," "," "," "," ") THEN sy:=ifsy
ELIF word=ALFA("t","h","e","n"," "," "," "," "," "," ") THEN sy:=thensy
ELIF word=ALFA("e","l","s","e"," "," "," "," "," "," ") THEN sy:=elsesy
ELIF word=ALFA("w","h","i","l","e"," "," "," "," "," ") THEN sy:=whilesy
ELIF word=ALFA("d","o"," "," "," "," "," "," "," "," ") THEN sy:=dosy
ELIF word=ALFA("b","e","g","i","n"," "," "," "," "," ") THEN sy:=beginsy
ELIF word=ALFA("e","n","d"," "," "," "," "," "," "," ") THEN sy:=endsy
ELIF word=ALFA("s","k","i","p"," "," "," "," "," "," ") THEN sy:=skipsy
ELIF word=ALFA("v","a","r"," "," "," "," "," "," "," ") THEN sy:=varsy
ELIF word=ALFA("c","o","n","s","t"," "," "," "," "," ") THEN sy:=constsy
ELIF word=ALFA("p","r","o","c"," "," "," "," "," "," ") THEN sy:=procsy
ELIF word=ALFA("w","r","i","t","e"," "," "," "," "," ") THEN sy:=writesy
ELIF word=ALFA("g","o","t","o"," "," "," "," "," "," ") THEN sy:=gotosy
ELIF word=ALFA("r","e","s","u","l","t","i","s"," "," ") THEN sy:=resultissy
ELIF word=ALFA("v","a","l","o","f"," "," "," "," "," ") THEN sy:=valofsy
ELSE sy:=ident
FI
ELIF digit(ch) THEN
looked ahead := TRUE; n:=0;
WHILE digit(ch) DO
n:=n*10+ ABS ch - ABS "0"; ch:=getch
OD;
sy:=numeral
ELIF ch=":" THEN
ch:=getch;
IF ch="=" THEN sy:=becomessy
ELSE sy:=colon; looked ahead := TRUE
FI
ELIF ch=";" THEN sy:=semisy
ELIF ch="." THEN sy:=stopsy
ELIF ch="(" THEN sy:=open
ELIF ch=")" THEN sy:=close
ELIF ch="+" THEN sy:=plussy
ELIF ch="-" THEN sy:=minussy
ELIF ch="*" THEN sy:=timessy
ELIF ch="/" THEN sy:=oversy
ELIF ch="=" THEN sy:=eqsy
ELIF ch="<" THEN # < #
ch:=getch;
IF ch=">" THEN # ...> # sy:=nesy
ELIF ch="=" THEN sy:=lesy
ELSE sy:=ltsy; looked ahead:=TRUE
FI
ELIF ch=">" THEN # > #
ch:=getch;
IF ch="=" THEN sy:=gesy
ELSE sy:=gtsy; looked ahead:=TRUE
FI
ELSE error("in insymbol")
FI;
IF NOT looked ahead THEN ch:=getch FI
) # insymbol #;
#-----------------------------------------------------------------------------#
#syntax#
PROC parser = CMD:
BEGIN
PROC pexp = EXP:
( PROC pexp3 = EXP:
IF sy=open THEN insymbol; EXP e:=pexp;
check(close, ") "); e
ELIF sy=minussy THEN insymbol; HEAP EXPNODE:=UEXP(neg,pexp3)
ELIF sy=ident THEN
EXP e = HEAP EXPNODE:=word;
insymbol;
e
ELIF sy=numeral THEN
EXP e = HEAP EXPNODE:=n;
insymbol;
e
ELIF sy=valofsy THEN
insymbol;
HEAP EXPNODE := pcmd
ELIF sy=ifsy THEN
insymbol; EXP e1:=pexp;
check(thensy, "then in Conditional expn"); EXP e2:=pexp;
check(elsesy, "else in Conditional expn"); EXP e3:=pexp;
HEAP EXPNODE := IFEXP(e1, e2, e3)
ELSE error("in pexp3"); SKIP
FI;
PROC pexp2 = EXP:
( LOC EXP e:=pexp3;
WHILE sy=timessy OR sy=oversy DO
OPR o = IF sy=timessy THEN times ELSE over FI;
insymbol;
e:= HEAP EXPNODE := BEXP(o, e, pexp3)
OD;
e
);
PROC pexp1 = EXP:
( LOC EXP e := pexp2;
WHILE sy=plussy OR sy=minussy DO
OPR o = IF sy=plussy THEN plus ELSE minus FI;
insymbol;
e:=HEAP EXPNODE:=BEXP(o, e, pexp2)
OD;
e
);
IF EXP e=pexp1;
sy=eqsy OR sy=nesy OR sy=lesy
OR sy=ltsy OR sy=gesy OR sy=gtsy
THEN OPR o = IF sy=eqsy THEN eq ELIF sy=nesy THEN ne
ELIF sy=lesy THEN le ELIF sy=ltsy THEN lt
ELIF sy=gesy THEN ge ELSE gtsy FI;
insymbol;
HEAP EXPNODE := BEXP(o, e, pexp1)
ELSE e
FI
) # pexp #;
PROC pdec = DEC:
( PROC pdec1 = DEC:
IF sy=varsy THEN
insymbol;
IF sy=ident THEN DEC d=HEAP DECNODE:=word;
insymbol; d
ELSE error("no ident after var"); SKIP
FI
ELIF sy=constsy THEN
insymbol;
IF sy=ident THEN
ALFA id=word;
insymbol;
check(eqsy, "no = after const ident");
HEAP DECNODE := CONSTDEC(id,pexp)
ELSE error("no ident after const"); SKIP
FI
ELIF sy=procsy THEN
insymbol;
IF sy=ident THEN
ALFA id=word;
insymbol;
check(eqsy,"no = after proc ident");
HEAP DECNODE := PROCDEC(id,pcmd)
ELSE error("no id after proc"); SKIP
FI
ELSE NIL
FI;
IF sy=varsy OR sy=constsy OR sy=procsy THEN
DEC d=pdec1;
check(semisy, "no ; after declaration");
HEAP DECNODE := DECLIST(d,pdec)
ELSE NIL
FI
) # pdec #;
PROC pcmd = CMD:
IF sy=numeral THEN #labelled#
LABEL label=n;
insymbol;
check(colon, "no : after label");
HEAP CMDNODE := LABCMD(label, pcmd)
ELIF sy=ifsy THEN
insymbol; EXP b=pexp;
check(thensy,"then in parse cmd"); CMD g1=pcmd;
check(elsesy,"else in parse cmd"); CMD g2=pcmd;
HEAP CMDNODE := IFSTAT(b, g1, g2)
ELIF sy=whilesy THEN
insymbol; EXP b=pexp;
check(dosy,"no do after while");
HEAP CMDNODE := WHILES(b,pcmd)
ELIF sy=beginsy THEN
PROC pcmd list = CMD:
(LOC CMD g:=HEAP CMDNODE := SEMI(NIL,pcmd);
WHILE sy=semisy DO
insymbol;
g:=HEAP CMDNODE := SEMI(g,pcmd)
OD;
g
);
insymbol;
DEC d=pdec;
CMD blk = HEAP CMDNODE := BLOCK(d, pcmd list);
check(endsy, "no end to block");
blk
ELIF sy=skipsy THEN insymbol; NIL
ELIF sy=resultissy THEN
insymbol;
HEAP CMDNODE := ONEEXP(resultissy,pexp)
ELIF sy=writesy THEN
insymbol;
HEAP CMDNODE := ONEEXP(writesy,pexp)
ELIF sy=gotosy THEN
insymbol;
CMD g = HEAP CMDNODE := n;
insymbol;
g
ELIF sy=open THEN
EXP lhs=pexp;
check(becomessy, "no := after expn in pcmd");
HEAP CMDNODE := ASSIGN(lhs, pexp)
ELIF sy=ident THEN
ALFA id=word;
insymbol;
IF sy=becomessy THEN
insymbol;
HEAP CMDNODE := ASSIGN( HEAP EXPNODE := id, pexp)
ELSE #a call #
HEAP CMDNODE := id
FI
FI # pcmd #;
insymbol;
CMD c = pcmd;
check(stopsy, "no . at end of program");
c
END #parser#;
#-----------------------------------------------------------------------------#
# semantic domains #
MODE EV = UNION( INT, LOCN ), # = Int + Locn #
SV = INT,
CONT = PROC( INT,STORE)ANS, # = IntxStore -> Ans #
KONT = PROC(EV, INT,STORE)ANS, # = Ev -> IntxStore -> Ans #
DCONT = PROC(ENV, INT,STORE)ANS; # = Env -> IntxStore -> Ans #
MODE DV = EV, # it so happens #
LOCN = STRUCT(INT l, dont care);
OP = = (LOCN m,n)BOOL: l OF m = l OF n;
MODE ANS = UNION( ALFA, REF ANSCELL); # Ans = Int x Ans + {wrong,finish}#
MODE ANSCELL=STRUCT(INT v, ANS next);
MODE STORE = PROC(LOCN)SV; # = Locn -> Sv #
MODE VNV = PROC(ALFA)DV; # Ide -> Dv #
MODE PNV = PROC(ALFA,CONT, INT,STORE)ANS; # Ide -> Cont -> IntxStore ->Ans #
MODE LNV = PROC(LABEL, INT,STORE)ANS; # Numeral -> IntxStore -> Ans #
MODE ENV = STRUCT( VNV vnv, PNV pnv, LNV lnv, KONT kont );
#-----------------------------------------------------------------------------#
# semantics #
PROC show = (ANS a)VOID:
CASE a IN
(ALFA w):FOR i TO UPB w DO print(w[i]) OD,
(REF ANSCELL r): IF r ISNT NIL THEN
print((" ",whole(v OF r,0),",")); show(next OF r) FI
ESAC;
PROC wrong = (STRING m)ANS:
( print((newline, m, newline));
ALFA("w", "r", "o", "n", "g", " ", " ", " ", " ", " ")
);
PROC undefined = VOID:
error(" undefined");
PROC eee = (EXP ex, KONT k, ENV e, INT f,STORE s)ANS:
( # : EXP -> KONT -> ENV -> INT x STORE -> ANS #
#debug # print(" E[");
CASE ex IN
(BEXP b):(KONT rhs = (EV v1, INT f,STORE s)ANS:
(KONT opr = (EV v2, INT f,STORE s)ANS:
k( CASE v1 IN
(INT i1):CASE v2 IN
(INT i2):IF opr OF b = plus THEN i1+i2
ELIF opr OF b = minus THEN i1-i2
ELIF opr OF b = times THEN i1*i2
ELIF opr OF b = over THEN i1%i2
ELIF opr OF b = ne THEN
IF i1=i2 THEN 0 ELSE 1 FI
ELIF opr OF b = eq THEN
IF i1=i2 THEN 1 ELSE 0 FI
ELIF opr OF b = lt THEN
IF i1 < i2 THEN 1 ELSE 0 FI
ELIF opr OF b = le THEN
IF i1 <= i2 THEN 1 ELSE 0 FI
ELIF opr OF b = gt THEN
IF i1 > i2 THEN 1 ELSE 0 FI
ELIF opr OF b = ge THEN
IF i1 >= i2 THEN 1 ELSE 0 FI
ELSE error(" bad operator");SKIP
FI
OUT wrong(" int OPR non-int"); SKIP
ESAC
OUT wrong(" non-int OPR ???"); SKIP
ESAC,
f,s
)# opr #;
rrr(right OF b, opr, e, f,s)
)# rhs #;
#debug# print((" bopr",whole(opr OF b,0) ));
rrr(left OF b, rhs, e, f,s)
),
(UEXP u):(KONT opr = (EV v, INT f, STORE s)ANS:
CASE v IN
(INT i): k(-i, f, s)
OUT wrong(" - nonInt")
ESAC;
#debug# print(" -");
rrr(son OF u, opr, e, f,s)
),
(VAR v):k( (vnv OF e)(v), f, s),
(INT n):k( n, f, s),
(IFEXP if):(KONT cond = (EV v, INT f, STORE s)ANS:
CASE v IN
(INT i): IF i=1 THEN eee(e2 OF if, k, e, f, s)
ELSE eee(e3 OF if, k, e, f, s)
FI
OUT wrong(" CondExp non-int")
ESAC;
#debug#print(" CondExp");
rrr(e1 OF if, cond, e, f, s)
),
(CMD g):(KONT new rnv = (EV v, INT f, STORE s)ANS:
# valof $g # k(v, f, s);
CONT fail = (INT f, STORE s)ANS:
wrong(" fail: fell out of valof");
#debug#print(" valof");
ENV new e=(vnv OF e, pnv OF e, lnv OF e, new rnv);
ccc(g, fail, new e, f, s)
)
ESAC
) # eee #;
PROC lll = (EXP ex, KONT k, ENV e, INT f, STORE s)ANS:
( # EXP -> KONT -> ENV -> INT x STORE -> ANS #
#debug# print(" L[");
KONT check = (EV v, INT f, STORE s)ANS:
CASE v IN
(LOCN l): k(l, f, s)
OUT wrong(" not left-value")
ESAC;
eee( ex, check, e, f, s)
) # lll #;
PROC rrr = (EXP ex, KONT k, ENV e, INT f, STORE s)ANS:
( # EXP -> KONT -> ENV -> INT x STORE -> ANS #
#debug# print(" R[");
KONT deref = (EV v, INT f, STORE s)ANS:
CASE v IN
(INT i): k(i, f, s),
(LOCN l): k( s(l), f, s)
ESAC;
eee( ex, deref, e, f, s)
)# rrr #;
PROC ddd = (DEC d, DCONT dc, ENV e, INT f, STORE s)ANS:
( # DEC -> DCONT -> ENV -> INT x STORE -> ANS #
#debug# print(" D[");
IF d IS NIL THEN dc(e, f, s)
ELSE CASE d IN
(VARDEC vd):(VNV new vnv = (ALFA id)DV:
IF id = vd THEN LOCN(f,0) ELSE (vnv OF e)(id) FI;
ENV new e = (new vnv, pnv OF e, lnv OF e, kont OF e);
#debug# print(( " VAR ", vd[1]));
dc( new e, f+1, s)
),
(CONSTDEC cd):(KONT update env = (EV v, INT f, STORE s)ANS:
( CASE v IN
(INT i):(VNV new vnv = (ALFA id)DV:
IF id = id OF cd THEN i
ELSE (vnv OF e)(id) FI;
ENV new e = (new vnv, pnv OF e, lnv OF e,
kont OF e);
dc( new e, f, s)
)
OUT wrong(" const id=non-int")
ESAC
) # update env # ;
# debug # print(" CONST");
rrr(e OF cd, update env, e, f, s)
),
(PROCDEC pd):(PNV new pnv = (ALFA id, CONT ra, INT f, STORE s)ANS:
IF id = id OF pd THEN
ccc(g OF pd, ra, new e #recursion#, f, s)
ELSE (pnv OF e)(id, ra, f, s)
FI;
ENV new e = (vnv OF e, new pnv, lnv OF e, kont OF e);
#debug#print(" PROC");
dc( new e, f, s)
),
(DECLIST l):(DCONT d2 = (ENV e, INT f, STORE s)ANS:
ddd(right OF l, dc, e, f, s);
#debug#print(" ;");
ddd(left OF l, d2, e, f, s)
)
ESAC
FI
) # ddd #;
PROC ccc = (CMD g, CONT t, ENV e, INT f, STORE s)ANS:
( # : CMD -> CONT -> ENV -> INT x STORE -> ANS #
# debug # print( " C[" );
IF g IS NIL #SKIP# THEN t(f,s)
ELSE
CASE g IN
(ASSIGN a):(KONT do rhs = (EV v1, INT f,STORE s)ANS:
( KONT update = (EV v2, INT f,STORE s)ANS:
( CASE v1 IN
(LOCN l):CASE v2 IN
(SV v):(STORE new s =(LOCN ll)SV:
IF ll=l THEN v ELSE s(ll) FI;
t(f, new s)
)
OUT wrong("try to store bad value")
ESAC
OUT wrong("try to update non-location")
ESAC
);
rrr(rhs OF a, update, e, f, s)
);
# debug # print(":=");
lll(lhs OF a, do rhs, e, f, s)
),
(SEMI g1g2):(CONT g2 = (INT f, STORE s)ANS:
ccc(right OF g1g2, t, e, f, s);
#debug# print(";");
ccc(left OF g1g2, g2, e, f, s)
),
(IFSTAT if):(KONT cond = (EV b, INT f,STORE s)ANS:
CASE b IN
(INT i): ccc(IF i=1 THEN gtrue OF if ELSE gfalse OF if FI,
t, e, f, s)
OUT wrong("if-cmd, non-int expn")
ESAC;
#debug#print(" IF");
rrr(b OF if, cond, e, f,s)
),
(WHILES w):(KONT cond = (EV b, INT f,STORE s)ANS:
( CONT again = (INT f, STORE s)ANS:
ccc(g, t, e, f,s);
CASE b IN
(INT i): IF i=1 THEN ccc(g OF w, again, e, f,s)
ELSE t(f,s)
FI
OUT wrong("while, non-int expn")
ESAC
);
#debug# print(" WHILE");
rrr(b OF w, cond, e, f,s)
),
(BLOCK b):(DCONT body = (ENV e, INT f,STORE s)ANS:
# begin $d;$g end # ( LNV new lnv = (LABEL n, INT f,STORE s)ANS:
( PROC search=(CMD g, CONT t2)ANS:
IF g IS NIL THEN (lnv OF e)(n,f,s)
ELSE
CASE g IN
(SEMI g):
( CONT t1=(INT f,STORE s)ANS:
ccc(right OF g,t2,new e,f,s);
CASE right OF g IN
(LABCMD lg):IF n=(l OF lg) THEN
ccc(g OF lg,t2,new e,f,s)
ELSE search(left OF g,t1)
FI
OUT search(left OF g, t1)
ESAC
)
OUT wrong("knotted cmd in block")
ESAC
FI # search #;
#debug# print((" lnv(", whole(n,0), ")" ));
search(g OF b, t)
)# new lnv#;
ENV new e=(vnv OF e, pnv OF e, new lnv, kont OF e);
ccc(g OF b, t, new e, f, s)
)# body #;
#debug# print(( newline," block"));
ddd(d OF b, body, e, f,s)
),
(ALFA proc):(pnv OF e)(proc, t, f,s), # $r\*<2\*>[procid]$t #
(LABCMD l):ccc(g OF l, t, e, f,s),
(G0T0 n):(lnv OF e)(n, f,s), # $r[$n] #
(ONEEXP eg): # resultis $e or write $e #
IF tag OF eg = resultissy THEN
rrr( e OF eg, kont OF e, e, f,s)
ELIF tag OF eg = writesy THEN
KONT do output = (EV v, INT f, STORE s)ANS:
CASE v IN
(INT i): HEAP ANSCELL := (i, t(f,s))
OUT wrong("write a non-int")
ESAC;
rrr( e OF eg, do output, e, f,s)
ELSE error(" bad tag in ccc< tag,exp>"); SKIP
FI
ESAC
FI
) # ccc #;
CONT finish = (INT f, STORE s)ANS:
ALFA("f", "i", "n", "i", "s", "h", " ", " ", " ", " ");
VNV start vnv = (ALFA a)DV:
(undefined; SKIP);
PNV start pnv = (ALFA a, CONT ra, INT f, STORE s)ANS:
(undefined; SKIP);
LNV start lnv = (LABEL l, INT f, STORE s)ANS:
(undefined; SKIP);
KONT start kont = (EV v, INT f, STORE s)ANS:
(undefined; SKIP);
ENV start env = (start vnv, start pnv, start lnv, start kont);
STORE empty store = (LOCN n)SV:
(undefined; SKIP);
show( ccc(parser, finish, start env, 0, empty store) )
)