override public (string, object) Evaluate(SymbolTable symbolTable) { int myLabelId = Writer.labelIndex; Writer.labelIndex++; Writer.write($"LOOP_{myLabelId}:"); (string, object)ret = children[0].Evaluate(symbolTable); God.VerifyType("boolean", ret); Writer.write($"CMP EBX, False"); Writer.write($"JE EXIT_{myLabelId}"); children[1].Evaluate(symbolTable); Writer.write($"JMP LOOP_{myLabelId}"); Writer.write($"EXIT_{myLabelId}:"); /* * while(whileCheck(symbolTable)){ * children[1].Evaluate(symbolTable); * } */ return("none", null); }
override public (string, object) Evaluate(SymbolTable symbolTable) { (string, object)ret = children[0].Evaluate(symbolTable); switch (value) { case '+': God.VerifyType("integer", ret); return(ret); case '-': God.VerifyType("integer", ret); Writer.write("MOV EAX, EBX"); Writer.write("MOV EBX, 0"); Writer.write("SUB EBX, EAX"); return("integer", -(int)ret.Item2); case "not": God.VerifyType("boolean", ret); Writer.write("MOV EAX, EBX"); Writer.write("NEG EBX"); return("boolean", !(bool)ret.Item2); case "print": //Console.WriteLine(children[0].Evaluate(symbolTable).Item2); Writer.write("PUSH EBX"); Writer.write("CALL print"); Writer.write("POP EBX"); return("none", null); case "input": Console.Write("input:"); string inputed = Console.ReadLine(); if (inputed.ToUpper() == "TRUE") { return("boolean", true); } if (inputed.ToUpper() == "FALSE") { return("boolean", false); } if (int.TryParse(inputed, out int parsed)) { return("integer", parsed); } throw new SystemException($"Unparsable input. {parsed}."); case "false": Writer.write("MOV EBX, False"); return("boolean", false); case "true": Writer.write("MOV EBX, True"); return("boolean", true); default: throw new SystemException($"Invalid operation. cannot make unary op on variable of type: {ret.Item1}."); } }
override public (string, object) Evaluate(SymbolTable symbolTable) { (string, object)condition = children[0].Evaluate(symbolTable); God.VerifyType("boolean", condition); if ((bool)condition.Item2) { children[1].Evaluate(symbolTable); return("none", null); } else { children[2].Evaluate(symbolTable); return("none", null); } }
bool whileCheck(SymbolTable symbolTable) { (string, object)ret = children[0].Evaluate(symbolTable); God.VerifyType("boolean", ret); return((bool)ret.Item2); }
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 )"); } }