private static ArrayList<String> pushVariable(Token t) throws Exception { ArrayList<String> res = new ArrayList<>(); Variable v = Alzheimer.variables.get(t.valueWithoutIndex()); if (v == null) { if (!t.isNumber() && !t.isString() && !t.isCharacter()) { if (!t.isType()) { throw new CompilerException("Unknown variable " + t.value, t.file, t.line); } else { Type T = Alzheimer.types.get(t.valueBeforeFirstDot()); if (T == null) { throw new CompilerException("Unknown type " + t.valueBeforeFirstDot(), t.file, t.line); } else { switch (t.valueAfterFirstDot()) { case "size": exec("push " + T.size() + "; " + t.value, res); break; default: throw new CompilerException( "Type '" + t.valueBeforeFirstDot() + "' does not have property '" + t.valueAfterFirstDot() + "' ", t.file, t.line); } } } } else { exec("push " + t.value + ";", res); } } else { if (v.isArray && !t.isArray()) { res.addAll(pushArray(v, t.file, t.line)); } else { if (t.isArray()) { v = new Variable(); v.name = t.value; String alz = "" + v.accessVarName() + "=( " + v.arrayIndex() + " );\n"; res.addAll(Alzheimer.compile(alz)); res.addAll(v.type.push(v.nameWithoutIndex() + "[" + v.accessVarName() + "]")); } else { res.addAll(v.type.push(t.value)); } } } return res; }
private ArrayList<String> expression(ArrayList<Token> tokens) throws Exception { ArrayList<String> res = new ArrayList<>(); Token opTok = tokens.remove(0); if (tokens.size() < 1) { Variable v = Alzheimer.variables.get(opTok.valueWithoutIndex()); if (v == null && !opTok.isType()) { if (!opTok.isNumber()) { throw new CompilerException( "Number, variable or type property expected", opTok.file, opTok.line); } res.add("push " + opTok.value + ";"); return res; } res.addAll(pushVariable(opTok)); return res; } if (!opTok.value.equals("(")) { if (tokens.size() != 0) { Token tmp = tokens.remove(0); if (!tmp.value.equals("(")) { throw new CompilerException("( expected", tmp.file, tmp.line); } } else { throw new CompilerException("Something is wrong!", opTok.file, opTok.line); } } ArrayList<String> args = new ArrayList<>(); while (tokens.size() != 0) { Token t; if (tokens.size() > 1) { t = tokens.get(1); if (t.value.equals("(")) { res.addAll(expression(tokens)); args.add(""); } else { t = tokens.remove(0); if (t.value.equals(")")) { break; } if (t.isString()) { exec(t.pushString(), res); } else { res.addAll(pushVariable(t)); } } } else { t = tokens.remove(0); if (t.value.equals(")")) { break; } if (t.isString()) { exec(t.pushString(), res); } else { res.addAll(pushVariable(t)); } } } switch (opTok.value) { case "(": break; case "+": case "add": exec("add", res); break; case "-": case "sub": exec("sub", res); break; case "*": case "mul": exec("mul", res); break; case "/": case "div": exec("div", res); break; case "floor": exec("floor", res); break; case "ceil": exec("ceil", res); break; default: exec("call $" + opTok.value, res); } return res; }
/** * exprA(0) ::= integer | float | variable | atom | atom( exprA(1200) { , exprA(1200) }* ) | '[' * exprA(1200) { , exprA(1200) }* [ | exprA(1200) ] ']' | '{' [ exprA(1200) ] '}' | '(' * exprA(1200) ')' */ private Term expr0() throws InvalidTermException, IOException { Token t1 = tokenizer.readToken(); /*Castagna 06/2011*/ /* if (t1.isType(Tokenizer.INTEGER)) return Parser.parseInteger(t1.seq); //todo moved method to Number if (t1.isType(Tokenizer.FLOAT)) return Parser.parseFloat(t1.seq); //todo moved method to Number if (t1.isType(Tokenizer.VARIABLE)) return new Var(t1.seq); //todo switched to use the internal check for "_" in Var(String) */ int tempStart = tokenizer.tokenStart(); if (t1.isType(Tokenizer.INTEGER)) { Term i = Parser.parseInteger(t1.seq); map(i, tokenizer.tokenStart()); return i; // todo moved method to Number } if (t1.isType(Tokenizer.FLOAT)) { Term f = Parser.parseFloat(t1.seq); map(f, tokenizer.tokenStart()); return f; // todo moved method to Number } if (t1.isType(Tokenizer.VARIABLE)) { Term v = new Var(t1.seq); map(v, tokenizer.tokenStart()); return v; // todo switched to use the internal check for "_" in Var(String) } /**/ if (t1.isType(Tokenizer.ATOM) || t1.isType(Tokenizer.SQ_SEQUENCE) || t1.isType(Tokenizer.DQ_SEQUENCE)) { if (!t1.isFunctor()) /*Castagna 06/2011*/ { // return new Struct(t1.seq); Term f = new Struct(t1.seq); map(f, tokenizer.tokenStart()); return f; } /**/ String functor = t1.seq; Token t2 = tokenizer.readToken(); // reading left par if (!t2.isType(Tokenizer.LPAR)) throw new InvalidTermException( "Something identified as functor misses its first left parenthesis"); // todo check can // be skipped LinkedList<Term> a = expr0_arglist(); // reading arguments Token t3 = tokenizer.readToken(); if (t3.isType(Tokenizer.RPAR)) // reading right par /*Castagna 06/2011*/ { // return new Struct(functor, a); Term c = new Struct(functor, a); map(c, tempStart); return c; } /**/ /*Castagna 06/2011*/ // throw new InvalidTermException("Missing right parenthesis: ("+a + " -> here <-"); throw new InvalidTermException( "Missing right parenthesis '(" + a + "' -> here <-", tokenizer.offsetToRowColumn(getCurrentOffset())[0], tokenizer.offsetToRowColumn(getCurrentOffset())[1] - 1); /**/ } if (t1.isType(Tokenizer.LPAR)) { Term term = expr(false); if (tokenizer.readToken().isType(Tokenizer.RPAR)) return term; /*Castagna 06/2011*/ // throw new InvalidTermException("Missing right parenthesis: ("+term + " -> here <-"); throw new InvalidTermException( "Missing right parenthesis '(" + term + "' -> here <-", tokenizer.offsetToRowColumn(getCurrentOffset())[0], tokenizer.offsetToRowColumn(getCurrentOffset())[1] - 1); /**/ } if (t1.isType(Tokenizer.LBRA)) { Token t2 = tokenizer.readToken(); if (t2.isType(Tokenizer.RBRA)) return new Struct(); tokenizer.unreadToken(t2); Term term = expr0_list(); if (tokenizer.readToken().isType(Tokenizer.RBRA)) return term; /*Castagna 06/2011*/ // throw new InvalidTermException("Missing right bracket: ["+term + " -> here <-"); throw new InvalidTermException( "Missing right bracket '[" + term + " ->' here <-", tokenizer.offsetToRowColumn(getCurrentOffset())[0], tokenizer.offsetToRowColumn(getCurrentOffset())[1] - 1); /**/ } if (t1.isType(Tokenizer.LBRA2)) { Token t2 = tokenizer.readToken(); if (t2.isType(Tokenizer.RBRA2)) /*Castagna 06/2011*/ { // return new Struct("{}"); Term b = new Struct("{}"); map(b, tempStart); return b; } /**/ tokenizer.unreadToken(t2); Term arg = expr(false); t2 = tokenizer.readToken(); if (t2.isType(Tokenizer.RBRA2)) /*Castagna 06/2011*/ { // return new Struct("{}", arg); Term b = new Struct("{}", arg); map(b, tempStart); return b; } /*Castagna 06/2011*/ // throw new InvalidTermException("Missing right braces: {"+arg + " -> here <-"); throw new InvalidTermException( "Missing right braces '{" + arg + "' -> here <-", tokenizer.offsetToRowColumn(getCurrentOffset())[0], tokenizer.offsetToRowColumn(getCurrentOffset())[1] - 1); /**/ } /*Castagna 06/2011*/ // throw new InvalidTermException("The following token could not be identified: "+t1.seq); throw new InvalidTermException( "Unexpected token '" + t1.seq + "'", tokenizer.offsetToRowColumn(getCurrentOffset())[0], tokenizer.offsetToRowColumn(getCurrentOffset())[1] - 1); /**/ }