int n=form.count();
if (n==0) return Constant.create(form);
Object first=form.first();
if (first instanceof Symbol) {
Symbol s=(Symbol)first;
if (s.equals(Symbols.LET)) {
IPersistentVector v=KissUtils.expectVector(RT.second(form));
int vc=v.count();
if ((vc&1)!=0) throw new KissException("let requires an even number of binding forms");
// start with expression body
Expression e = analyse(RT.nth(form, 2));
for (int i=vc-2; i>=0; i-=2) {
Symbol sym=KissUtils.expectSymbol(v.nth(i));
Expression exp=analyse(v.nth(i+1));
e= Let.create(sym, exp, e);
}
return e;
}
if (s.equals(Symbols.LOOP)) {
IPersistentVector v=KissUtils.expectVector(RT.second(form));
int vc=v.count();
if ((vc&1)!=0) throw new KissException("let requires an even number of binding forms");
Symbol[] syms=new Symbol[vc/2];
Expression[] initials=new Expression[vc/2];
for (int i=0; i<vc; i+=2) {
syms[i]=KissUtils.expectSymbol(v.nth(i));
initials[i+i]=analyse(v.nth(i+1));
}
Expression body = analyse(RT.nth(form, 2));
return Loop.create(syms, initials, body);
}
if (s.equals(Symbols.RECUR)) {
int vc=n-1;
Expression[] values=new Expression[vc];
for (int i=0; i<vc; i++) {
values[i]=analyse(RT.nth(form,(i+1)));
}
return Recur.create(values);
}
if (s.equals(Symbols.RETURN)) {
Expression value=analyse(RT.nth(form,1));
return Return.create(value);
}
if (s.equals(Symbols.IF)) {
switch (n) {
case 4:
return If.create(analyse(RT.nth(form, 1)), analyse(RT.nth(form, 2)), analyse(RT.nth(form, 3)));
case 3:
return If.create(analyse(RT.nth(form, 1)), analyse(RT.nth(form, 2)),Constant.NULL);
default:
throw new KissException("Wrong number of forms in if expression: "+n);
}
}
if (s.equals(Symbols.INSTANCE)) {
switch (n) {
case 3:
return InstanceOf.create(analyseType(RT.nth(form, 1)), analyse(RT.nth(form, 2)));
default:
throw new KissException("Wrong number of forms in instance? expression: "+n);
}
}
if (s.equals(Symbols.DEF)) {
if (n!=3) throw new KissException("Wrong number of forms in def expression: "+n);
Symbol sym=(Symbol)RT.nth(form,1);
return Def.create(sym,analyse(RT.nth(form, 2)));
}
if (s.equals(Symbols.DO)) {
Expression[] exps=new Expression[n-1];
for (int i=1; i<n; i++) {
exps[i-1]=analyse(RT.nth(form, i));
}
return Do.create(exps);
}
if (s.equals(Symbols.FN)) {
IPersistentVector v=KissUtils.expectVector(RT.second(form));
int arity=v.count();
Symbol[] syms=new Symbol[arity];
Type[] types=new Type[arity];
for (int i=0; i<arity; i++) {
Symbol paramSym=(Symbol)v.nth(i);
syms[i]=paramSym;
Type paramType=Type.resolveTag(s);
types[i]=paramType;
}
Expression body=analyse(RT.nth(form, 2));