expps
but more compact.
As with expuniq
, we try to ensure two representations of the same
function map to the same string.
<bytecode.spec>= fields of op (8) op3 0:2 lit5 3:7 op4 3 lit4 4:7 op6 4:5 lit2 6:7 op7 6 lit1 7 op8 7 fields of lit (8) lit8 0:7 <patterns> <constructors> constructors <synthetics>
<patterns>= (<-U) [D->] # operators for 0..31 patterns u5 is any of [ narrows_lit narrowu_lit loslice ], which is op3 = [0 1 2]
<synthetics>= (<-U) [D->] narrows n! when {n != 0} is narrows_lit & lit5 = n otherwise is sint(n); narrows halt is narrows_lit & lit5 = 0 narrowu n! when {n != 0} is narrowu_lit & lit5 = n otherwise is sint(n); narrowu unsat is narrowu_lit & lit5 = 0 bitslice lo! hi! when {lo = 0, lit5 = hi} is loslice & lit5 when {} is sint(lo); sint(hi); bitslice # lo <= hi fails!
<patterns>+= (<-U) [<-D->] # operators for -8..7 --- can have at most 13 patterns s4 is any of [ intlit addlit emitlocplus bitshiftlit ], which is op3 = [3 4] & op4 = [0 1]
<synthetics>+= (<-U) [<-D->] addlit n! when {n != 0, lit4! = n} is addlit & lit4 otherwise is sint(n); add cl_loc_force is addlit & lit4 = 0 # emitlocplus n when {lit4! = n} is emitlocplus & lit4 # otherwise is cl_loc; force; sint(n); add; emit_at bitshift n! when {lit4! = n} is bitshiftlit & lit4 otherwise is sint(n); bitshift
<patterns>+= (<-U) [<-D->] # operators for 1 2 4 8 patterns emit_at_loc is op3 = 5 & op4 = 0 & op6 = 0
<synthetics>+= (<-U) [<-D->] emit_at_loc n when {n = 1} is emit_at_loc & lit2 = 0 when {n = 2} is emit_at_loc & lit2 = 1 when {n = 4} is emit_at_loc & lit2 = 2 when {n = 8} is emit_at_loc & lit2 = 3 otherwise is cl_loc; force; sint(n); emit_at
<patterns>+= (<-U) [<-D->] # operators for 1..2 patterns lit1.2 is any of [ cla_force_lit clv_lit clv_orb_lit ], which is op3 = 5 & op4 = 0 & op6 = [1 2 3] & op7 = 0
<synthetics>+= (<-U) [<-D] cla n is sint(n); cla cla_force n when {} is cla_force_lit & lit1 = n-1 otherwise is sint(n); cla; force clv n when { n <= 2 } is clv_lit & lit1 = n-1 # condition shouldn't be needed otherwise is sint(n); clv clv_orb n when {} is clv_orb_lit & lit1 = n-1 otherwise is sint(n); clv; orb
<patterns>+= (<-U) [<-D] # raw operations patterns [ sint8 sint16 sint32 ] is op3 = 5 & op4 = 0 & op6 = [1 2 3] & op7 = 1 [ mark array set procmark proc stringlit null uint64 ] is op3 = 5 & op4 = 1 & op6 = [0 1 2 3] & op7 = [0 1] [ bitslice bitshift narrowu narrows widen fitsu fitss failmsg lt le gt ge ne eq false true orb and not add sub mul idiv mod cl_loc cla clv force known emit_at if_guard neg ] is op3 = [6 7] & op4 = [0 1] & op6 = [0 1 2 3] & op7 = [0 1] patterns nullary is mark | array | set | procmark | proc | stringlit | null | lt | le | gt | ge | ne | eq | false | true | orb | and | not | add | sub | mul | idiv | mod | cl_loc | force | known | if_guard | neg | failmsg unary is emit_at | widen | fitsu | fitss
<constructors>= (<-U) constructors nullary sint n! when {lit4! = n} is intlit & lit4 when {lit8! = n} is sint8; lit8 when {lit8! = n@[8:31]!} is sint16; lit8 = n@[0:7]; lit8 when {lit8! = n@[24:31]!} is sint32; lit8 = n@[0:7]; lit8 = n@[8:15]; lit8 = n@[16:23]; lit8 unary n! is sint(n); unary
<*>= [D->]
procedure expbc(e)
local leadingsign, prefix
static psopstab
initial {<init>}
return case type(e) of {
<cases for expbc
>
default : &fail
} | impossible("postfix expression ", image(e), " : ", type(e))
end
Definesexpbc
(links are to index).
<cases for expbc
>= (<-U) [D->]
"list" : bc_mark() || commaseparate(maplist(expbc, e), "") || bc_array()
"set" : bc_mark() || commaseparate(sort(maplist(expbc, sort(e))), "") || bc_set()
"eqn" : expbc(e.left) || expbc(e.right) || \psopstab[e.op]
<init>= (<-U) psopstab := table() psopstab["<"] := bc_lt() psopstab["<="] := bc_le() psopstab[">"] := bc_gt() psopstab[">="] := bc_ge() psopstab["!="] := bc_ne() psopstab["="] := bc_eq()
<cases forexpbc
>+= (<-U) [<-D->] "table" : { # standard normal form <makes
represent tablee
> s } "string" : bc_stringout(e) "literal" : bc_stringout(e.s) || bc_lit() "integer" : bc_sint(e) "null" : bc_null()
<*>+= [<-D->] procedure bc_stringout(s) return bc_stringlit() || bc_sint(*s) || s end
Definesbc_stringout
(links are to index).
Be sure to omit multiplicative and additive units. Otherwise, it doesn't matter.
<makes
represent tablee
>= (<-U) { s := ""; firstterm := 1 t := table(0) l := [] every e[k := 1 ~=== key(e)] do { type(k) ~== "integer" | impossible("key ", k, " in ", expimage(e)) put(l, x := expbc(k)) t[x] +:= e[k] } l := sort(l) every x := !l & t[x] > 0 do { s ||:= bcx(x, t[x], firstterm) firstterm := &null } every x := !l & t[x] < 0 do { s ||:= bcx(x, t[x], firstterm) firstterm := &null } if \firstterm then s ||:= bc_sint(e[1]) else if e[1] ~= 0 then s ||:= bc_addlit(e[1]) }
<*>+= [<-D->] procedure bcx(x, mul, firstterm) return if \firstterm then case mul of { 1 : x -1 : x || bc_neg() default : x || bc_sint(mul) || bc_mul() } else case mul of { 1 : x || bc_add() -1 : x || bc_sub() default : x || bc_sint(mul) || bc_mul() || bc_add() } end
Definesbcx
(links are to index).
<cases for expbc
>+= (<-U) [<-D->]
"Eorb" : { l := sort(maplist(expbc, flatten(e, type(e))))
s := l[1]
every s ||:= l[2 to *l] || bc_orb()
s
}
"Eand" : { l := sort(maplist(expbc, flatten(e, type(e))))
s := l[1]
every s ||:= l[2 to *l] || bc_and()
s
}
<cases for expbc
>+= (<-U) [<-D->]
"Eslice" : expbc(e.x) || bc_bitslice(e.lo, e.lo + e.n - 1)
"Eshift" : expbc(e.x) || bc_bitshift(e.n)
<cases for expbc
>+= (<-U) [<-D->]
"Enarrowu" : expbc(e.x) || bc_narrowu(e.n)
"Enarrows" : expbc(e.x) || bc_narrows(e.n)
"Ewiden" : expbc(e.x) || bc_widen(e.n)
<cases for expbc
>+= (<-U) [<-D->]
"Ediv" : expbc(e.x) || bc_sint(e.n) || bc_idiv()
"Emod" : expbc(e.x) || bc_sint(e.n) || bc_mod()
<cases for expbc
>+= (<-U) [<-D->]
"Semit" : commaseparate(maplist(expbc, e.x), "")
"Stoken" : expbc(e.x) ||
if e.offset = 0 then bc_emit_at_loc(e.n)
else bc_cl_loc() || bc_force() || bc_addlit(e.offset) || bc_emit_at(e.n)
<cases for expbc
>+= (<-U) [<-D->]
"Efitsu" : expbc(e.x) || bc_fitsu(e.n)
"Efitss" : expbc(e.x) || bc_fitss(e.n)
<cases for expbc
>+= (<-U) [<-D->]
"Epatlabel" : &fail
<cases for expbc
>+= (<-U) [<-D->]
"Eforce" :
case type(e.x) of {
"Eclosure_addr" : bc_cla_force(e.x.n)
"Eclosure_loc" : bc_cl_loc_force()
default : expbc(e.x) || bc_force()
}
"Eforceable": expbc(e.x) || bc_known()
<cases for expbc
>+= (<-U) [<-D->]
"Epc" : &fail
"Epc_known" : &fail
<cases for expbc
>+= (<-U) [<-D->]
"Enot" : expbc(e.x) || bc_not()
<cases for expbc
>+= (<-U) [<-D->]
"Enosimp" : expbc(e.x)
<cases for expbc
>+= (<-U) [<-D->]
"Sstmts" : commaseparate(maplist(expbc, e.x), "")
<cases for expbc
>+= (<-U) [<-D->]
"Einstance" : &fail
"Einstance_input" : &fail
"Einstance_tagged" : &fail
"Ebinding_instance" : &fail
<cases for expbc
>+= (<-U) [<-D->]
"Sif" : { s := bc_mark()
every s ||:= expbc(!e.arms)
s || bc_array() || bc_if_guard()
}
"Sguarded" : bcguard(e.guard) || bc_procmark() || expbc(e.x) || bc_proc()
<*>+= [<-D] procedure bcguard(e) return case type(e) of { "integer" : case e of { 0 : bc_false(); 1 : bc_true() default: impossible("condition") } "null" : bc_true() "set" : { l := sort(maplist(expbc, sort(e))) s := l[1] every s ||:= l[2 to *l] || bc_and() if *l = 0 then bc_true() else s } default : expbc(e) } end
Definesbcguard
(links are to index).
<cases for expbc
>+= (<-U) [<-D->]
"Stagcase" : &fail
<cases for expbc
>+= (<-U) [<-D->]
"Sfail" : if e.fmt ~== "Conditions not satisfied for unnamed constructor" |
\(e.a1|e.a2|e.a3)
then {
s := bc_stringout(e.fmt) || bc_mark()
every a := e.a1 | e.a2 | e.a3 do
s ||:= expbc(\a)
s ||:= bc_array() || bc_failmsg()
} else
bc_unsat()
"Sepsilon" : ""
<cases for expbc
>+= (<-U) [<-D->]
"Efail" : &fail
<cases for expbc
>+= (<-U) [<-D->]
"Glines" : commaseparate(maplist2(expbc, e.x), "")
"Gresynch" : ""
"Gblock" : &fail
"Gdecl" : &fail
<cases for expbc
>+= (<-U) [<-D->]
"Gcase" : &fail
"Gcasearm" : &fail
"Ginrange" : &fail
<cases for expbc
>+= (<-U) [<-D->]
"Gasgn" : &fail
"Gsetname" : &fail
"Gnomatch" : &fail
"Tunsigned" : &fail
<cases for expbc
>+= (<-U) [<-D->]
"Eapp" : &fail
<cases for expbc
>+= (<-U) [<-D->]
"Eclosure_loc" : bc_cl_loc()
"Eclosure_addr" : bc_cla(e.n)
"Eclosure_val" : bc_clv(e.n)
<cases for expbc
>+= (<-U) [<-D]
"Eclosure" : &fail
"Elambda" : &fail
expbc
>: U1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26
s
represent table e
>: U1, D2