java/ch/wlkl/wsm/CompilerWSM.java
package ch.wlkl.wsm;
import static ch.wlkl.env.Env.*;
import java.util.ArrayList;
public class CompilerWSM extends AbstractCompiler {
private Ex compSeq = null;
public CompilerWSM() {
super();
}
public CompilerWSM(ExFactory f) {
super(f);
}
Ex seq() {
if (compSeq == null)
ini();
Flow fl = compSeq.exe(new Frame());
if (! fl.isNormal())
err("seq: seq not normal: " + fl + ": source: " + src);
Ex c = (Ex) fl.u();
return c;
}
void ini() {
ExFactory y = factory;
y.jFunAdd("null", new JFun<Object>(Object.class) {
public Object eval() {
return null;
};});
y.jFunAdd("isNull", new JFun<Object>(Object.class) {
public Object eval() {
return a[0] == null;
};});
y.jFunAdd("notNull", new JFun<Object>(Object.class) {
public Object eval() {
return a[0] != null;
};});
y.jFunAdd("equals", new JFun<Object>(Object.class) {
public Object eval() {
return a[0].equals(a[1]);
};});
y.jFunAdd("skip", new JFun<Object>(Object.class) {
public Object eval() {
return skip();
};});
y.jFunAdd("const", new JFun<Object>(Object.class) {
public Object eval() {
return exConst();
};});
y.jFunAdd("lit", new JFun<String>(String.class) {
public Object eval() {
return lit(a[0]);
};});
y.jFunAdd("name", new JFun<String>(String.class) {
public Object eval() {
return name(a);
};});
y.jFunAdd("nextName", new JFun<String>(String.class) {
public Object eval() {
return next(Parser.name) ? tok : null;
};});
y.jFunAdd("back", new JFun<String>(String.class) {
public Object eval() {
back();
return null;
};});
y.jFunAdd("fail", new JFun<String>(String.class) {
public Object eval() {
fail(a[0]);
return null;
};});
/* Ex ex = y.seq(y.jFun("skip"), y.jFun("const"));
out("ex ==>\n" + ex.toString());
compSeq = y.seq(
y.ass(y.cf(), y.cnst(1), ex),
y.jFun("skip"),
y.get(y.cf(), y.cnst(1)));
out("ini compSeq ==>\n" + compSeq.toString()); */
compSeq = new Compiler(y).compile("cf[" +
"\"checkName\" := fun if name(cf[\"name\"]) then return cf[\"val\"] else ifEnd funEnd," +
"\"one\" := fun skip(); " +
"cf[2 := const()]; if notNull(cf[2]) then return cf[2] else ifEnd;" +
"cf[1 := nextName()];" +
"if isNull(cf[1]) then null(); " +
"elif equals(\"if\", cf[1]) then det cf detEnd[\"checkName\"](\"val\" := det cf detEnd[\"if\"](), \"name\" := \"ifEnd\")" +
"else back() " +
"ifEnd " +
"funEnd," +
"\"seq\" := fun cf[1 := det cf detEnd[\"one\"]()]; " +
"skip();" +
"if lit(\";\") then else return cf[1] ifEnd;" +
"cf[2 := det cf detEnd [\"seq\"] ()]; " +
"if isNull(cf[1]) then cf[2] elif isNull(cf[2]) then cf[1] " +
"else fun exe det cf[1] detEnd exeEnd; exe det cf[2] detEnd exeEnd funEnd ifEnd " +
"funEnd, " +
"\"if\" := fun " +
"skip();" +
"cf[1 := det cf detEnd [\"seq\"] ()]; if isNull(cf[1]) then fail(\"if condition expected\") else ifEnd;" +
"cf[2 := det cf detEnd [\"seq\"] ()]; " +
"if notNull(name(\"else\")) " +
"then return fun if exe det cf[1] detEnd exeEnd then exe det cf[2] detEnd exeEnd else exe det det cf detEnd [\"seq\"] detEnd exeEnd ifEnd funEnd;" +
"else fail(\"else expected\")" +
"ifEnd; funEnd, " +
"\"jfun\" := fun " +
"if skip(); notNull(lit(\"(\")) " +
"then cf[2 := 0, 3 := 1];" +
"while equals(cf[3], 1) " +
"do" +
/* Ex jfun(String fun) {
List<Ex> exs = new ArrayList<Ex>();
if (skip().lit("(")) {
do {
skip();
Ex e1 = ex();
if (e1 == null)
fail("expression expected");
exs.add(e1);
} while (skip().lit(","));
checkLit(null, ")");
}
return factory.jFun(fun, exs.toArray(new Ex[exs.size()]));
} */
"] ;" +
"cf[\"seq\"]()"
);
out("ini compile compSeq ==>\n" + compSeq.format());
}
Ex ex() {
Ex map = exOne();
while (true) {
if (skip().lit("["))
map = checkLit(assOrGet(map, false), "]");
else if (lit("(("))
map = factory.call(map, checkLit(ex(), "))"));
else if (lit("("))
map = checkLit(assOrGet(map, true), ")");
else
return map;
}
}
Ex assOrGet(Ex map, boolean isAss) {
ArrayList<Ex> al = null;
do {
Ex val = null, ix = ex();
if (ix == null)
break;
else if (skip().lit(":="))
val = ex();
else if (isAss || al != null)
fail(":= in assignment expected");
else
return factory.get(map, ix);
if (al == null)
(al = new ArrayList<Ex>()).add(map);
al.add(ix);
al.add(val);
map = factory.ass(map, ix, ex());
} while (skip().lit(","));
implement("factory return" /*
return isAss ? factory.call(al.toArray(Ex.a0)) : factory.ass(al.toArray(Ex.a0)); */ );
return null;
}
Ex exOne() {
skip();
if (! next(name)) {
Ex e = exConst();
if (e != null)
return e;
} else if ("begin".equals(tok)) {
return checkName(seq(), "end");
} else if ("cf".equals(tok)) {
return factory.cf();
} else { implement("missing factory methodss"); return null; /*
} else if ("det".equals(tok)) {
return factory.det(checkName(seq(), "detEnd"));
} else if ("exe".equals(tok)) {
return factory.exExe(checkName(seq(), "exeEnd"));
} else if ("for".equals(tok)) {
return factory.exFor(checkName(ex(), "in"), checkName(ex(), "do"), checkName(seq(), "forEnd"));
} else if ("fun".equals(tok)) {
return factory.fun(checkName(seq(), "funEnd"));
} else if ("if".equals(tok)) {
// return compIf();
} else if ("new".equals(tok)) {
return factory.exNew();
} else if ("return".equals(tok)) {
return factory.ret(ex());
} else if ("throw".equals(tok)) {
return factory.thrw(ex());
} else if ("try".equals(tok)) {
return factory.exTry(checkName(seq(), "catch"), checkName(ex(), "handle"), checkName(seq(), "tryEnd"));
} else if ("while".equals(tok)) {
return factory.whl(checkName(seq(), "do"), checkName(seq(), "wEnd"));
} else if (resWords.matcher(tok).matches()) { // ignore, for later usage!
} else if (factory.jFunExists(tok)) {
// return jfun(tok); */
}
back();
return null;
}
}