Пример #1
0
        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);
        }
Пример #2
0
        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}.");
            }
        }
Пример #3
0
 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);
     }
 }
Пример #4
0
 bool whileCheck(SymbolTable symbolTable)
 {
     (string, object)ret = children[0].Evaluate(symbolTable);
     God.VerifyType("boolean", ret);
     return((bool)ret.Item2);
 }
Пример #5
0
        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 )");
            }
        }
Пример #6
0
        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 )");
            }
        }