// ***************************** lmn metalanguage back end ********************************
// ******* (c) Copyright Peri Hankey 2005. Distribution licensed under GNU GPLv2 *****************
.lmn2x(B) // lmn backend to wrap frontend with own variables as required
- var Is = 0;
var Ir = 0;
var If = 0;
var Sy = [];
Sy.func = [];
prelude generate units postlude generate
<- outer ;
- <- prelude
say
"import lm.lmd;\n"
"import lm.licenseGnuGPLv2;\n"
"import lm.application;\n"
"import lm.engine;\n"
"import lm.element;\n"
"import lm.extension;\n"
"import std.stdio;\n\n"
output
lmn;
- var I = 0; <- postlude
compile
"extern (C) mode lmdInit(inout stream s){\n"
"needft(s, " If ");\n"
{for(I = 0; I < If; I++) { "makeft(s, "I ", &fun"I");\n" }}
{for(I = 0; I < Ir; I++) { "define(s, rul" I ");\n" }}
"return null;\n"
"}\n"
code
lmn
;
.lmn2x(1010R)
// internal to this backend
eof <- generate eof;
- lmn <- generate ;
- uri <- lmn - ;
say output <- lmn - ;
- out <- output - ;
compile code <- lmn - ;
- out <- code - ;
// internally generated within this backend
w <- lmn - 'w' sp ;
g <- lmn - 'g' sp ;
gx <- lmn - 'G' sp ;
vx <- lmn - 'V' sp ;
sx :X <- lmn - '(' sp X ')' sp gx;
// backend interface
zzz lineNo :A <- lmn - say "ERROR (feature not implemented) near line " A "\n" output ;
eoc <- lmn - ;
eox <- lmn - '.' sp ;
lu :X <- lmn - X ;
top :X <- lmn - lm :X 'T' nl;
rdef :A :G :P :N :I :L :J :R <- lmn -
say "static char[] rul"$(Ir++)" = \"" output m :G P n:N lm :{ I L } lm :{ J R } "r" say " \";" output nl ;
rval rdef :A :G :P :N :I :L :J :R <- lmn - G P nm:N sx :{ I L } sx :{ J R } op:'rule' ;
fd :fname :F :B var N = 0; <- lmn - fcode fN B eoc :F :B ;
fN var N = 0; arglist <- numargs :N;
arg :X ++N; <- arglist - ;
eoc <- arglist ;
fcode numargs :N :F :B var I = 0; var V = 0; <- lmn -
say {
if(!Sy.func[F]) {
Sy.func[F] = [];
"extern (C) element " F "(inout stream, ...)" eoc
}
if(Sy.func[F][N] == null) {
Sy.func[F][N] = I = If++;
"extern (C) element fun" I "(inout stream s){\n" ga :{$(V++)} B eoc "return " F "(s" ca :{$(--V)} B eoc ");\n}\n"
}
}
output;
sy :X <- fname :X ;
va :X <- fname :X ;
ga :I arg :X <- output - "element a" I "= pop(s);\n" ga :I ;
ga :I eoc <- output - ;
ca :I arg :X <- output - ", a" I ca :I ;
ca :I eoc <- output - ;
arg :X <- argdecl ;
da argdecl <- output - ", element" da;
da ")" <- output - ")";
eoc <- output - ";\n";
sd :I :B <- lmn - ;
ad :I :B <- lmn - ;
ij :I :X <- lmn - sx:X op:'inj' ;
lm :X <- lmn - '(' sp X ')' sp ;
bx :X <- lmn - X ;
void <- lmn - 'z' sp ;
c :X <- lmn - 'c:' X sp ;
d :X <- lmn - 'm:' X sp ;
m :X <- lmn - 'm:' X sp ;
n :X <- lmn - 'n:' X sp ;
v :X <- lmn - 'v:' X sp ;
x :X <- lmn - 'l:['X']' sp ;
lp :X <- lmn - 'L:' X sp ;
rp :X <- lmn - 'R:' X sp ;
bp :X <- lmn - 'B:' X sp ;
mp :X <- lmn - 'M:' X sp ;
ac :I :X <- lmn - X ;
sv :I :X <- lmn - '(' sp X ')' sp gx;
sq :I :X <- lmn - '(' sp X ')' sp gx;
dq :X <- lmn - 'd:' X sp gx;
ty :X <- lmn - 'v:' X sp gx;
vr :X <- lmn - 'v:' X sp gx;
va :X <- lmn - 'v:' X sp vx;
sy :X <- lmn - 'v:' X sp gx;
nm :X <- lmn - 'n:' X sp gx;
ax :X <- lmn - X 'B' sp ;
al :X <- lmn - X 'A' sp ;
ex :X <- lmn - X 'E' sp ;
ea :X <- lmn - X 'e' sp ;
t <- lmn - 't' sp ;
pp :X <- lmn - X 'p' sp ;
pq :I :B <- lmn - lm :B 'p' sp ;
pb :X <- lmn - X 'b' sp ;
ap :X <- lmn - X op:'apply' ;
op :X <- lmn - 'f:' X sp ;
uf :X <- lmn - 'F:' X sp ;
ou :X <- lmn - X op:"append" sp ;
r1 :I :B <- lmn - m:"option" B ;
rz :I :B <- lmn - m:"repeat" B ;
rn :X :I :B <- lmn - X m:"repeatN" B ;
idx :A :B <- lmn - A B op:'idx' ;
dot :A :B <- lmn - A d :B gx op:'idt' ;
truth :V <- lmn - op :V ;
arrayinit :A <- lmn - args :A op:'array' ;
cellN :X <- lmn - X ;
cellV :N :X <- lmn - N X op:'cell' ;
inits :A <- lmn - A eox ;
initz :A <- lmn - sy :A sy:"null" w ;
initv :A :B <- lmn - sy :A B w ;
xif :E :A :B <- lmn - E sx:A B op:'if' ;
xelsif :E :B :C <- lmn - sx :{ iff :B :C :A };
xelse :B <- lmn - sx :B ;
xelsez <- lmn - sx :{} ;
xnext :E <- lmn - E ;
xtest :E <- lmn - E op:test ;
xdo :E :B <- lmn - sx :{ B E } op:'loop';
xwhile :E :B <- lmn - sx :{ E B } op:'loop';
xfor :I :E :N :B <- lmn - I sx :{ E B N } op:'loop';
xcont0 <- lmn - op :"continue";
xbreak0 <- lmn - op :"break" ;
//fn :F :A <- lmn - F op:'args' A op:'fun' ;
arg :A <- lmn - A ;
fcall numargs :N :F :A <- lmn - A uf :(Sy.func[F][N]);
fn :fname :F :A <- lmn - fcall fN A eoc :F :A ;
args :A <- lmn - op:'args' A ;
br :A <- lmn - A ;
"," :A :B <- lmn - A eox B ;
"?" :A :B :C <- lmn - A sx :{ B } sx:{ C } op:'sel' ;
fl :F :A :B <- lmn - A sx :{ B } op:F ;
fA :F :A :B <- lmn - A B op :F ;
fa :F :A :B <- lmn - A B op :F ;
fb :F :A :B <- lmn - A B op :F ;
fc :F :A :B <- lmn - A B op :F ;
fe :F :A :B <- lmn - A B op :F ;
fq :F :A :B <- lmn - A B op :F ;
fx :F :A :B <- lmn - A B op :F ;
fs :F :A :B <- lmn - A B op :F ;
ur :unary :F :A <- lmn - A op :F ;
ux :unary :F :A <- lmn - A op :F ;
ub :unary :F :A <- lmn - A op :F ;
aa :unary :F :A <- lmn - A op :F ;
"-" <- unary :"neg" ;
"~" <- unary :"inv" ;
"!" <- unary :"not" ;
pre :preop :F :A <- lmn - A F;
post :postop :F :A <- lmn - A F;
"--" <- postop :{ op:'postdec' };
"++" <- postop :{ op:'postinc' };
"--" <- preop :{ op:'predec' };
"++" <- preop :{ op:'preinc' };