override public (string, object) Evaluate(SymbolTable symbolTable) { //one set to dim the func, the other one assign it symbolTable.Set(this.value.ToString(), null, "function"); symbolTable.Set(this.value.ToString(), this, "function"); return("none", null); }
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())); }
override public object Evaluate(SymbolTable symbolTable) { switch ((char)value) { case '+': return((int)children[0].Evaluate(symbolTable) + (int)children[1].Evaluate(symbolTable)); case '-': return((int)children[0].Evaluate(symbolTable) - (int)children[1].Evaluate(symbolTable)); case '*': return((int)children[0].Evaluate(symbolTable) * (int)children[1].Evaluate(symbolTable)); case '/': return((int)children[0].Evaluate(symbolTable) / (int)children[1].Evaluate(symbolTable)); case '=': object val = children[1].Evaluate(symbolTable); symbolTable.Set((string)children[0].value, val); return(null); default: throw new SystemException($"Invalid Binary Operator ( {value} was received at node on integer operation )"); } }
override public object Evaluate(SymbolTable symbolTable) { switch (value.ToString()) { case "+": return((int)children[0].Evaluate(symbolTable) + (int)children[1].Evaluate(symbolTable)); case "-": return((int)children[0].Evaluate(symbolTable) - (int)children[1].Evaluate(symbolTable)); case "*": return((int)children[0].Evaluate(symbolTable) * (int)children[1].Evaluate(symbolTable)); case "/": return((int)children[0].Evaluate(symbolTable) / (int)children[1].Evaluate(symbolTable)); case "=": object val = children[1].Evaluate(symbolTable); symbolTable.Set((string)children[0].value, val); return(null); case ">": return((int)children[0].Evaluate(symbolTable) > (int)children[1].Evaluate(symbolTable)); case "<": return((int)children[0].Evaluate(symbolTable) < (int)children[1].Evaluate(symbolTable)); case "==": return((int)children[0].Evaluate(symbolTable) == (int)children[1].Evaluate(symbolTable)); default: throw new SystemException($"Invalid Binary Operator ( {value} was received at node on integer operation )"); } }
override public (string, object) Evaluate(SymbolTable symbolTable) { if (value.ToString() == "=") { (string, object)val = children[1].Evaluate(symbolTable); symbolTable.Set((string)children[0].value, val.Item2, val.Item1); return("none", null); } (string, object)ret1 = children[0].Evaluate(symbolTable); (string, object)ret2 = children[1].Evaluate(symbolTable); switch (value.ToString()) { case "+": God.VerifyType("integer", ret1); God.VerifyType("integer", ret2); return("integer", ((int)ret1.Item2 + (int)ret2.Item2)); case "-": God.VerifyType("integer", ret1); God.VerifyType("integer", ret2); return("integer", ((int)ret1.Item2 - (int)ret2.Item2)); case "*": God.VerifyType("integer", ret1); God.VerifyType("integer", ret2); return("integer", ((int)ret1.Item2 * (int)ret2.Item2)); case "/": God.VerifyType("integer", ret1); God.VerifyType("integer", ret2); return("integer", ((int)ret1.Item2 / (int)ret2.Item2)); case ">": God.VerifyType("integer", ret1); God.VerifyType("integer", ret2); return("boolean", ((int)ret1.Item2 > (int)ret2.Item2)); case "<": God.VerifyType("integer", ret1); God.VerifyType("integer", ret2); return("boolean", ((int)ret1.Item2 < (int)ret2.Item2)); case "&": God.VerifyType("boolean", ret1); God.VerifyType("boolean", ret2); return("boolean", ((bool)ret1.Item2 && (bool)ret2.Item2)); case "|": God.VerifyType("boolean", ret1); God.VerifyType("boolean", ret2); return("boolean", ((bool)ret1.Item2 || (bool)ret2.Item2)); case "==": if (ret1.Item1 != ret2.Item1) { throw new SystemException($"Invalid relative operation == between variables of types {ret1.Item1} and {ret2.Item1}."); } switch (ret1.Item1) { case "boolean": return("boolean", (bool)ret1.Item2 == (bool)ret2.Item2); case "integer": return("boolean", (int)ret1.Item2 == (int)ret2.Item2); default: throw new SystemException($"Invalid variable type for == operation. {ret1.Item1}."); } case "vardec": //get value of type node and interact with ident node to sabe the var type //string type = (string)children[1].value; string key = (string)children[0].value; symbolTable.Set(key, null, "none"); return("none", null); default: throw new SystemException($"Invalid Binary Operator ( {value} was received at node on integer operation )"); } }
override public (string, object) Evaluate(SymbolTable symbolTable) { if (value.ToString() == "=") { (string, object)assign = children[1].Evaluate(symbolTable); Writer.assign(children[0].value.ToString()); return("none", null); } if (value.ToString() == "vardec") { // get value of type node and interact with ident node to sabe the var type string type = (string)children[1].value; string key = (string)children[0].value; symbolTable.Set(key, null, type); Writer.declare(key); return("none", null); } (string, object)ret1 = children[0].Evaluate(symbolTable); Writer.write("PUSH EBX"); (string, object)ret2 = children[1].Evaluate(symbolTable); Writer.write("POP EAX"); switch (value.ToString()) { case "+": God.VerifyType("integer", ret1); God.VerifyType("integer", ret2); Writer.write("ADD EAX, EBX"); Writer.write("MOV EBX, EAX"); return("integer", null); case "-": God.VerifyType("integer", ret1); God.VerifyType("integer", ret2); Writer.write("SUB EAX, EBX"); Writer.write("MOV EBX, EAX"); return("integer", null); case "*": God.VerifyType("integer", ret1); God.VerifyType("integer", ret2); Writer.write("IMUL EBX"); Writer.write("MOV EBX, EAX"); return("integer", null); case "/": God.VerifyType("integer", ret1); God.VerifyType("integer", ret2); Writer.write("IDIV EBX"); Writer.write("MOV EBX, EAX"); return("integer", null); case ">": God.VerifyType("integer", ret1); God.VerifyType("integer", ret2); Writer.write("CMP EAX, EBX"); Writer.write("CALL binop_jg"); return("boolean", null); case "<": God.VerifyType("integer", ret1); God.VerifyType("integer", ret2); Writer.write("CMP EAX, EBX"); Writer.write("CALL binop_jl"); return("boolean", null); case "&": God.VerifyType("boolean", ret1); God.VerifyType("boolean", ret2); Writer.write("AND EAX, EBX"); return("boolean", null); case "|": God.VerifyType("boolean", ret1); God.VerifyType("boolean", ret2); Writer.write("OR EAX, EBX"); return("boolean", null); case "==": if (ret1.Item1 != ret2.Item1) { throw new SystemException($"Invalid relative operation == between variables of types {ret1.Item1} and {ret2.Item1}."); } Writer.write("CMP EAX, EBX"); Writer.write("CALL binop_je"); switch (ret1.Item1) { case "boolean": return("boolean", null); case "integer": return("boolean", null); default: throw new SystemException($"Invalid variable type for == operation. {ret1.Item1}."); } default: throw new SystemException($"Invalid Binary Operator ( {value} was received at node on integer operation )"); } }