// ***************************** lmn metalanguage back end ********************************
// ******* (c) Copyright Peri Hankey 2005. Distribution licensed under GNU GPLv2 *****************
.lmn2x(B) // lmn backend
- var File = "rules";
var Rule = 0 ;
var Side = "str" ;
var Line = 0;
// var Rule = [];
var Ix = 0;
var Si = 0;
var Sx = 0;
var Iloop = 0;
var Icond = 0;
var Iz = 0;
var Nw = 0;
var Is = 0;
var Ic = 0;
var Ir = 0;
var It = 0;
var Iq = 0;
var Fn = []; var Ft = []; var Fi = 0;
var Nn = []; var Nt = []; var Ni = 0;
var Mn = []; var Mt = []; var Mi = 0;
var Tn = []; var Tt = []; var Ti = 0;
var Dn = []; var Dt = []; var Di = 0;
var Vn = []; var Vt = []; var Vi = 0;
var Xn = []; var Xt = []; var Xi = 0;
var Sn = [];
prelude generate units postlude generate
<- outer ;
- <- prelude
"import lm.lmd;\n"
"import lm.licenseGnuGPLv2;\n\n"
"import lm.application;\n"
"import lm.engine;\n"
"import lm.element;\n"
"import lm.extension;\n"
"import std.stdio;\n\n"
lmn;
- var I = 0; <- postlude
"extern (C) mode lmdInit(inout stream s){" indent nl
table :"mt" :Mi {for(I = 0; I < Mi; I++) { defq :mt :I :(Mn[I]) eoc }} nl
table :"dt" :Di {for(I = 0; I < Di; I++) { defq :dt :I :(Dn[I]) eoc }} nl
table :"tt" :Ti {for(I = 0; I < Ti; I++) { defq :tt :I :(Tn[I]) eoc }} nl
table :"xt" :Xi {for(I = 0; I < Xi; I++) { defx :xt :I :(Xn[I]) eoc }} nl
table :"vt" :Vi {for(I = 0; I < Vi; I++) { defq :vt :I :(Vn[I]) eoc }} nl
table :"nt" :Ni {for(I = 0; I < Ni; I++) { defn :nt :I :(Nn[I]) eoc }} nl
table :"st" :Is {for(I = 0; I < Is; I++) { defs :st :I :I eoc }} nl
{for(I = 0; I < Ir; I++) { defr :ru :I :I eoc }} nl
"return " pt "sm(s)" eoc
"}" lmn nl2
lmn
;
.lmn2x(1010R) // lmn backend
eof <- generate eof;
- lmn <- generate ;
- out <- lmn - ;
- out <- output - ;
say eom <- lmn - ;
- out <- eom - ;
eol <- lmn - nl ;
eoc <- lmn - "; " nl ;
note :I :X <- lmn - say "; // ["I":"X"] " eom nl ;
nl <- lmn - '\n' Sp ;
nl2 <- lmn - "\n\n" Sp ;
sp checks <- lmn - ;
comma checkc <- lmn - ;
- <- checks "; ";
eoc <- checks eoc ;
// ";" <- checks ";" ;
// "; " <- checks "; ";
"}" <- checks ";}";
"]" <- checks "]" ;
")" <- checks ")" ;
- <- checkc ", ";
";" <- checkc ";";
"; " <- checkc ";";
"]" <- checkc "]";
"}" <- checkc "}";
")" <- checkc ")";
eox <- checkc eox ;
eoc <- checkc eoc ;
top :X
<- lmn - "void t"$(Iz++) sb :X nl;
rdef :A :G :P :N :I :L :J :R
Line = A;
Rule = Ir;
var K = Ir++;
var Lh = K;
var Rh = K;
<- lmn -
define :K :A :G :P :N
{ Side = "lhs"; re ls :Lh :{ I li 1 L eolh }}
{ Side = "rhs"; re rs :Rh :{ J ri N R eorh }}
:Lh
:Rh
;
define :K :A :G :P :N lmn counters :W :L :Lx lmn counters :X :R :Rx :Lh :Rh
// Rule[K] = Is++;
<- lmn -
rd :K :{
"def(s, "
sy :G comma P comma W comma N comma L comma R comma Lx comma Rx comma "&"lr :Lh comma "&"rr :Rh comma q:File comma A
")" eoc
Side = "str" ;
};
rval rdef :G :P :N :L :R
<- lmn - G P nm:N sx:L sx:R op:'rule' ;
tail var I; <- lmn - lz sw "{" indent nl { for(I = 0; I < Ix; I++) {"case "I": goto L"I eoc }} df lmn nl "}" ;
eolh Ix = Ic+1; <- lmn - xe :"rT" :Ix tail ;
eorh Ix = Ic+1; <- lmn - xe :"rT" :Ix tail ;
eos Ix = Ic+1; <- lmn - xe :"rT" :Ix tail ;
fd :fname :F :B <- lmn - { if(!Fn[F]) { Fn[F] = 1; "extern (C) element " F "(inout stream, ...)" eoc nl }};
arg :X <- argdecl ;
dc argdecl <- lmn - ", element" dc;
dc ")" <- lmn - ")";
sd :I :B; Sn[I] = Ic-1; <- lmn - re sr :I sh"{" indent nl jz lmn inner indent B eos lmn nl "}" nl2 lmn;
ls :I :B; Sn[I] = Ic-1; <- lmn - lr :I sh"{" indent nl jz lmn count indent B lmn nl "}" nl2 lmn;
rs :I :B; Sn[I] = Ic-1; <- lmn - rr :I sh"{" indent nl jz lmn count indent B lmn nl "}" nl2 lmn;
rd :I :B; Sn[I] = Ic-1; <- lmn - re ru :I sh"{" indent nl B lmn "return " pt "sm(s)" eoc "}" nl2 ;
jz <- lmn - "goto Lz" eoc;
lz <- lmn - "Lz: " nl ;
re <- lmn - "mode ";
sh <- lmn - "(inout stream s)";
sw <- lmn - "switch(sci(s))";
df <- lmn - "default: " nl "return zZ(s, 0, null);";
sb :B <- lmn - indent nl xb :"eN" B lmn nl;
sn :I <- lmn - "case " I ":" ;
ru :I <- lmn - "rul" I ;
lr :I <- lmn - "lhs" I ;
rr :I <- lmn - "rhs" I ;
sr :I <- lmn - "str" I ;
light var Nw = 0; lmn <- lmn - ;
count var Nw = 0; Ic = 0; var Ix = Ic+0; var Si; var Sx; lmn <- lmn counters :Nw :Ix :{ Si :Sx };
inner var Nw = 0; Ic = 0; var Ix = Ic+0; var Si; var Sx; lmn <- lmn - ;
indent var Sp = " "; lmn <- lmn - ;
lm :X <- lmn - light X lmn;
bx :X <- lmn - light X lmn;
eox <- lmn - ";" nl ;
xloop var It = Iloop++; lmn <- lmn - ;
xcond var Iq = Icond++; lmn <- lmn - ;
xnext :E <- lmn - ic E eoc ;
xtest :E <- lmn - "if(!(" bool E ")) goto rz"$(It) eoc;
xra <- lmn - 'ra'$(It)":" eoc ;
xrn :X <- lmn - 'ra'$(It)":" eoc ;
xrb <- lmn - ;
xrz <- lmn - "goto ra"$(It) eoc 'rz'$(It) ":" eoc;
xqtest :E <- lmn - "if(!(" bool E ")) goto qa"$(Iq) eoc;
xqa <- lmn - "goto qz"$(Iq) eoc 'qa'$(Iq)":" eoc;
xqb <- lmn - ;
xqe <- lmn - 'qz'$(Iq)":" eoc ;
xqz <- lmn - 'qa'$(Iq)":" eoc 'qz'$(Iq)":" eoc ;
sz <- lmn - ;
sz zz <- lmn - ;
xz <- lmn - ;
xz zz <- lmn - ;
zz <- lmn - ;
xb :F <- lmn - "switch(i){" nl "default: " nl ;
xe :F :I <- lmn - ie :I tr :F sf :{ F"(s, " $(Ic++) ", null)" } eoc ;
ic ic <- lmn - ic ;
ic <- lmn - "L" $(Ic++) ": ";
ie :I <- lmn - "L" $(Ic++) ": ";
tr :X <- lmn - X"tr(s, \"" Side "\", " Rule ", " Line "); " ;
sf :X <- lmn - "return " X ;
mf :X <- lmn - ;
lu :X <- lmn - ic X xz ;
- <- zi :mv ;
ri 0 <- zi :iv ;
ri 1 <- zi :zv ;
li 1 <- zi :zv ;
void zi :F <- lmn - F :mi :"null";
n :X zi :F <- lmn - F :ni :X ;
c :X zi :F <- lmn - ch F X lmn ;
d :X zi :F <- lmn - F :di :X ;
m :X zi :F <- lmn - F :mi :X ;
x :X zi :F <- lmn - F :xi :X ;
v :X <- lmn - vv :vi :X ;
zv :I :X Nw++; Si = I; Sx = X; <- lmn - ic tr :zV sf :{ "zV(s, "Ic ", " I :X ")" } note :I :X sz ;
iv :I :X Nw++; Si = I; Sx = X; <- lmn - ic tr :mV sf :{ "mV(s, "Ic ", " I :X ")" } note :I :X sz ;
mv :I :X Nw++; <- lmn - ic tr :mV sf :{ "mV(s, "Ic ", " I :X ")" } note :I :X sz ;
vv :I :X <- lmn - ic tr :vR sf :{"vR(s, "Ic ", " I :X ")" } note :I :X sz ;
xs :F <- lmn - ic tr :F sf :{ F"(s, "Ic ", null)" } eoc sz ;
xs :F :X <- lmn - ic tr :F sf :{ F"(s, "Ic ", " X ")" } eoc sz ;
xv :F :X <- lmn - ic tr :F sf :{ F"(s, "Ic ", " X ")" } eoc sz ;
ch iv chr mv <- lmn - iv ;
ch zv chr mv <- lmn - zv ;
ch mv <- lmn - mc ;
mc chr <- lmn - ;
- anything % toUrn: X <- chr mv :ti :X mc;
"\\" escape % % toUrn: X <- chr mv :ti :X mc;
lmn <- chr ;
ax :X <- lmn - ic tr :aL sf :{"aL(s, "Ic ", " X ")" } eoc sz;
al :X <- lmn - ic tr :aL sf :{"aL(s, "Ic ", " rx X ")" } eoc sz;
ex :X <- lmn - ic tr :eA sf :{"eA(s, "Ic ", " X ")" } eoc sz;
ea :X <- lmn - ic tr :eA sf :{"eA(s, "Ic ", " rx X ")" } eoc sz;
pp :X Nw++; <- lmn - ic tr :bV sf :{"bV(s, "Ic ", " rx X ")" } eoc sz;
pq :X :B Nw++; <- lmn - ic tr :bV sf :{"bV(s, "Ic ", " si :X ")" } eoc sz;
pb :X <- lmn - ic tr :bV sf :{"bV(s, "Ic ", " X ")" } eoc sz;
ij :X :B <- lmn - ic tr :iN sf :{"iN(s, "Ic ", " si :X ")" } eoc sz;
ou :X Nw++; <- lmn - ic tr :oU sf :{"oU(s, "Ic ", " rx X ")" } eoc sz;
ap :X <- lmn - xv :"aP" :X ;
t Nw++; <- lmn - xs :"tV" ;
op :opcode :X <- lmn - xs :X ;
"done" <- opcode :"dN";
table :X :N <- lmn - "need" X "(s, " N ")" eoc;
defq :X :I :V <- lmn - "make" X "(s, " I ", \"" V "\")";
defx :X :I :V <- lmn - "make" X "(s, " I ", \"[" V "]\")";
defn :X :I :V <- lmn - "make" X "(s, " I ", " V ")";
defs :X :I :V <- lmn - "make" X "(s, " I ", &" sr :I ")";
defr :X :I :V <- lmn - "ru" :I "(s)";
pt <- lmn - "s" ;
ni :X if(!Nt[X]) { Nt[X] = Ni; Nn[Ni++] = X; } <- lmn - pt "nt(s, "$(Nt[X])")";
mi :X if(!Mt[X]) { Mt[X] = Mi; Mn[Mi++] = X; } <- lmn - pt "mt(s, "$(Mt[X])")";
bi :X if(!Mt[X]) { Mt[X] = Mi; Mn[Mi++] = X; } <- lmn - pt "mt(s, "$(Mt[X])")";
vi :X if(!Vt[X]) { Vt[X] = Vi; Vn[Vi++] = X; } <- lmn - pt "vt(s, "$(Vt[X])")";
di :X if(!Dt[X]) { Dt[X] = Di; Dn[Di++] = X; } <- lmn - pt "dt(s, "$(Dt[X])")";
ti :X if(!Tt[X]) { Tt[X] = Ti; Tn[Ti++] = X; } <- lmn - pt "tt(s, "$(Tt[X])")";
xi :X if(!Xt[X]) { Xt[X] = Xi; Xn[Xi++] = X; } <- lmn - pt "xt(s, "$(Xt[X])")";
si :X <- lmn - pt "st(s, " X ")";
q :X <- lmn - '\"' X '\"' ;
rx <- lmn - ;
rx sr :X <- lmn - si :X ;
rx n :X <- lmn - nm :X ;
rx d :X <- lmn - di :X ;
rx b :X <- lmn - bi :X ;
rx m :X <- lmn - mi :X ;
rx v :X <- lmn - vi :X ;
rx x :X <- lmn - xi :X ;
rf <- lmn - ;
rf sr <- lmn - sq ;
rf n <- lmn - nm ;
rf d <- lmn - dq ;
rf b <- lmn - sy ;
rf m <- lmn - sy ;
rf v <- lmn - va ;
rf x <- lmn - sy ;
sv :X :B <- lmn - mf "gs(s, " si :X ')' ;
sq :X :B <- lmn - mf "gs(s, " si :X ')' ;
dq :X <- lmn - mf "gd(s, " di :X ')' ;
ty :X <- lmn - mf "gt(s, " mi :X ')' ;
vr :X <- lmn - mf "vr(s, " vi :X ')' ;
va :X <- lmn - mf "gv(s, " vi :X ')' ;
sy :X <- lmn - mf "gm(s, " mi :X ')' ;
nm :X <- lmn - mf "gn(s, cast(lmNumber) " X ')' ;
lp :X <- lmn - mf 'L(' X ')' ;
rp :X <- lmn - mf 'R(' X ')' ;
bp :X <- lmn - mf 'B(' X ')' ;
mp :X <- lmn - mf 'M(' X ')' ;
rz :I :B <- lmn - xs :"rX" :{ sv :I :B } ;
r1 :I :B <- lmn - xs :"o1" :{ sv :I :B } ;
rn :X :I :B <- lmn - xs :"rN" :{ sv :I :B comma X } ;
dParam <- lmn - ;
idx :A :B <- lmn - "idx(s, " A comma B ")" ;
dot :A :B <- lmn - "dot(s, " A comma dq :B ")" ;
truth :V <- lmn - sy :V ;
arrayinit :A <- lmn - mf "(mark(s), " A "array(s))" ;
cellN :A <- lmn - "push(s, " A ")" comma ;
cellV :N :X <- lmn - mf "push(s, cell(s, " N comma X "))" comma ;
regex :A :B <- lmn - ;
inits :A <- lmn - A xz eoc ;
initz :A <- lmn - mf "newvar(s, " vi :A comma vi:"null" ")" ; // sy:A comma ;
initv :A :B <- lmn - mf "newvar(s, " vi :A comma B ")" ; // sy:A "=" B comma ;
xif :E :A :B <- lmn - xcond xqtest :E xqb A B lmn ;
xelsif :E :B :C <- lmn - xqa xcond xqtest :E xqb B C lmn ;
xelse :B <- lmn - xqa B xqe ;
xelsez <- lmn - xqz;
xdo :E :B <- lmn - xloop xra xrb B xtest :E xrz lmn ;
xwhile :E :B <- lmn - xloop xra xtest :E xrb B xrz lmn ;
xfor :I :E :N :B <- lmn - I xloop xra E xrb B N xrz lmn ;
xforeach :I :E :B <- lmn - zzz ;
xcont0 <- lmn - "continue" sz ;
xbreak0 <- lmn - "break" sz ;
xreturnZ <- lmn - op :"retZ";
xreturnE :E <- lmn - E op :"retV";
args :A <- lmn - A ;
arg :A <- lmn - A comma ;
fn :fname :F :A <- lmn - mf F "(s, " A ")" ;
sy :X <- fname :X ;
va :X <- fname :{sy :X };
br :A <- lmn - "(" A ")";
"," :A :B <- lmn - A ',' B ;
"?" :A :B :C <- lmn - bool A '?' B " : " C ;
fx : arith <- lmn - ;
fb : bitop <- lmn - ;
fl : logic <- lmn - ;
fA : assoc <- lmn - ;
fa : assign <- lmn - ;
fc : compare <- lmn - ;
fs : string <- lmn - ;
ux : unary <- lmn - ;
ub : unary <- lmn - ;
ur : unary <- lmn - ;
aa : unary <- lmn - ;
pre : preop <- lmn - ;
post : postop <- lmn - ;
fl :F :A :B <- lmn - bool A F B ;
bool <- lmn - ;
bool ub :F :A <- lmn - F "(" bool A ")" ;
bool fl :F :A :B <- lmn - bool A F B ;
bool truth :X <- lmn - X ;
bool sy :X <- lmn - "tf(" sy :X ")";
bool va :X <- lmn - "tf(" va :X ")";
bool nm :X <- lmn - "tf(" nm :X ")";
bool fc :F :A :B <- lmn - "tf(" fc :F :A :B ")";
bool fA :F :A :B <- lmn - "tf(" fA :F :A :B ")";
bool idx :A :B <- lmn - "tf(" idx :A :B ")";
bool idt :A :B <- lmn - "tf(" idt :A :B ")";
"in" :A :B <- assoc mf "inA(s, " A comma B ")";
"+" :A :B <- arith mf "add(s, " A comma B ")";
"-" :A :B <- arith mf "sub(s, " A comma B ")";
"*" :A :B <- arith mf "mul(s, " A comma B ")";
"/" :A :B <- arith mf "div(s, " A comma B ")";
"%" :A :B <- arith mf "mod(s, " A comma B ")";
"&" :A :B <- bitop mf "and(s, " A comma B ")";
"|" :A :B <- bitop mf "or(s, " A comma B ")";
"^" :A :B <- bitop mf "xor(s, " A comma B ")";
"&&" :A :B <- logic mf bool A "&&" B ;
"||" :A :B <- logic mf bool A "||" B ;
"=" :A :B <- assign mf "assign(s, " A comma B ")" ;
"+=" :A :B <- assign mf "addassign(s, " A comma B ")" ;
"-=" :A :B <- assign mf "subassign(s, " A comma B ")" ;
"*=" :A :B <- assign mf "mulassign(s, " A comma B ")" ;
"/=" :A :B <- assign mf "divassign(s, " A comma B ")" ;
"%=" :A :B <- assign mf "modassign(s, " A comma B ")" ;
"&=" :A :B <- assign mf "andassign(s, " A comma B ")" ;
"|=" :A :B <- assign mf "orassign(s, " A comma B ")" ;
"^=" :A :B <- assign mf "xorassign(s, " A comma B ")" ;
"<<=" :A :B <- assign mf "shlassign(s, " A comma B ")" ;
">>=" :A :B <- assign mf "shrassign(s, " A comma B ")" ;
"==" :A :B <- compare mf "eq(s, " A comma B ")";
"!=" :A :B <- compare mf "ne(s, " A comma B ")";
"<" :A :B <- compare mf "lt(s, " A comma B ")";
">" :A :B <- compare mf "gt(s, " A comma B ")";
"<=" :A :B <- compare mf "le(s, " A comma B ")";
">=" :A :B <- compare mf "ge(s, " A comma B ")";
"+" :A <- unary mf "pos(s, " A ")";
"-" :A <- unary mf "neg(s, " A ")";
"!" :A <- unary mf "not(s, " A ")";
"~" :A <- unary mf "inv(s, " A ")";
"++" :A <- postop mf "postinc(s, " A ")" ;
"--" :A <- postop mf "postdec(s, " A ")" ;
"++" :A <- preop mf "preinc(s, " A ")" ;
"--" :A <- preop mf "predec(s, " A ")" ;