override public (string, object) Evaluate(SymbolTable symbolTable) { //get func node FuncDec node = (FuncDec)symbolTable.GetFromMain((string)this.value).Item2; //create the new symbol table for the new escope SymbolTable inferiorST = new SymbolTable(); inferiorST.parent = symbolTable; if (node.type != "none") { //create a var with the same name as the func to return inferiorST.Set((string)node.value, null, node.type); } //get number of arguments if (node.varList.Count != varList.Count) { throw new SystemException($"Function {node.value.ToString()} receives {node.varList.Count} arguments, but {varList.Count} where given. [Line: {Parser.CurrentLine}]"); } Node[] valueNodeList = new Node[varList.Count]; int counter = 0; foreach (Node n in varList) { valueNodeList[counter++] = n; } //dec vars and set values counter = 0; foreach (BinOp dec in node.varList) { dec.Evaluate(inferiorST); (string, object)retVal = valueNodeList[counter++].Evaluate(symbolTable); inferiorST.Set((string)dec.children[0].value, retVal.Item2, retVal.Item1); } //call function node.children[0].Evaluate(inferiorST); if (node.type == "none") { return("none", null); } //return the value by the name return(inferiorST.Get(node.value.ToString())); }
public static Node ParseFunction() { FuncDec root = new FuncDec(); bool sub = tokens.actual.type == "SUB"; if (sub) { Expect("SUB", true); root.type = "none"; } else { Expect("FUNCTION", true);; } Expect("IDENTIFIER", false); root.value = tokens.actual.value; tokens.SelectNext(); Expect("POPEN", true); if (tokens.actual.type != "PCLOSE") { do { if (tokens.actual.type == "COMMA") { tokens.SelectNext(); } Expect("IDENTIFIER", false); BinOp dim = new BinOp(); dim.value = "vardec"; dim.children[0] = new NoOp(); dim.children[0].value = (string)tokens.actual.value; tokens.SelectNext(); Expect("AS", true); dim.children[1] = parseType(); root.Add(dim); } while(tokens.actual.type == "COMMA"); } Expect("PCLOSE", true); if (!sub) { Expect("AS", true); switch (tokens.actual.type) { case "INTEGER": root.type = "integer"; break; case "BOOLEAN": root.type = "boolean"; break; default: throw new SystemException($"Expecting a VARTYPE token, got a {tokens.actual.type} (position {tokens.position}) [Line: {CurrentLine}]"); } tokens.SelectNext(); } Expect("LINEBREAK", true); CurrentLine++; root.children[0] = ParseStatements(sub ? "sub":"func"); if (sub) { Expect("SUB", true); } else { Expect("FUNCTION", true); } Expect("LINEBREAK", true); CurrentLine++; return(root); }