java/ch/wlkl/wsm/Compiler.java
package ch.wlkl.wsm;
import java.util.ArrayList;
import java.util.List;
/**
* @author walter
*
*/
public class Compiler extends AbstractCompiler {
public Compiler() {
super();
}
public Compiler(ExFactory f) {
super(f);
}
Ex seq() {
final ArrayList<Ex> eles = new ArrayList<Ex>();
Ex e1;
do {
if ((e1 = ex()) != null)
eles.add(e1);
} while (skip().lit(";"));
return eles.size() == 1 ? eles.get(0) : factory.seq(eles.toArray(Ex.a0));
}
Ex ex() {
Ex map = exOne();
while (true) {
if (skip().lit("["))
map = checkLit(assOrGet(map, false), "]");
else if (lit("("))
map = factory.call(map, checkLit(assOrGet(map, true), ")"));
else
return map;
}
}
Ex assOrGet(Ex map, boolean isCall) {
Ex cur = null;
do {
Ex ky = ex();
if (ky == null) {
if (isCall && cur == null)
return factory.nf();
fail("ass or get expected");
}
if (! skip().lit(":=")) {
if (cur == null)
return isCall ? ky : factory.get(map, ky);
fail(":= in call arguments expected");
}
Ex val = ex();
if (cur == null)
cur = isCall ? factory.nf(): map;
cur = factory.ass(cur, ky, val);
} while (skip().lit(","));
return cur;
}
Ex exOne() {
skip();
if (! next(name)) {
return exConst();
} else if ("begin".equals(tok)) {
return checkName(seq(), "end");
} else if ("cf".equals(tok)) {
return factory.cf();
/* } 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.cnst(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;
}
Ex compIf() {
Ex eIf = checkName(seq(), "then");
Ex eTh = seq();
return factory.exIf(eIf, eTh, name("else", "elif").equals("else") ? checkName(seq(), "ifEnd") : compIf());
}
Ex jfun(String fun) {
List<Ex> exs = new ArrayList<Ex>();
if (skip().lit("(")) {
do {
skip();
Ex e1 = ex();
if (e1 == null) {
if (exs.size() == 0)
break;
else
fail("expression expected");
}
exs.add(e1);
} while (skip().lit(","));
checkLit(null, ")");
}
return factory.jFun(fun, exs.toArray(new Ex[exs.size()]));
}
}