Exemple #1
0
        void IfHeader()
        {
            Expect((int)TokenEnum.If);
            Expect((int)TokenEnum.LeftParenthesis);
            Expression();
            try {
                GraphicFooType type = Quadruple.typeStack.Pop();
                if (Semantics.ExpectType(type, GraphicFooType.Boolean))
                {
                    string id = Quadruple.operandStack.Pop();
                    Quadruple.CreateGotoFalseQuadruple(id);
                    Quadruple.PushJump();
                }
                else
                {
                    SemErr(
                        (int)SemanticEnum.TypeMismatch,
                        "expected boolean, found " + type
                        );
                }
            } catch (InvalidOperationException) {
                SynErr((int)TokenEnum.NoExpression);
            }

            Expect((int)TokenEnum.RightParenthesis);
        }
Exemple #2
0
 void EndIf()
 {
     Expect((int)TokenEnum.EndIf);
     if (!Quadruple.PopJump())
     {
         SynErr((int)TokenEnum.EndIf);
     }
 }
        /// <summary>
        /// Executes a goto operation.
        /// </summary>
        /// <returns><c>true</c>, if goto operation was executed, <c>false</c> otherwise.</returns>
        /// <param name="q">Q.</param>
        /// <param name="condition">If set to <c>true</c> condition.</param>
        private static bool ExecuteGotoOperation(Quadruple q, bool condition)
        {
            bool?v1Value = CastToBoolean(q.v1);
            bool v1;

            v1 = v1Value ?? default(bool);
            return(v1 == condition);
        }
Exemple #4
0
        /// <summary>
        /// Creates a jump quadruple.
        /// </summary>
        /// <param name="goTo">Go to.</param>
        /// <param name="condition">Condition.</param>
        private static void CreateJumpQuadruple(
            Operators goTo,
            Variable condition = null)
        {
            Quadruple quadruple = new Quadruple(goTo, condition);

            PushQuadruple(quadruple);
        }
Exemple #5
0
        /// <summary>
        /// Creates an expression quadruple.
        /// </summary>
        /// <param name="operators">Operators.</param>
        private static void CreateExpressionQuadruple(
            Operators[] operators)
        {
            // Get index of fake bottom
            int index = (hierarchyStack.Count > 0) ? hierarchyStack.Peek() : 0;

            if (operatorStack.Count > index &&
                operators.Contains(operatorStack.Peek()))
            {
                // Pop types
                GraphicFooType t2 = typeStack.Pop();
                GraphicFooType t1 = typeStack.Pop();

                if (t1 != GraphicFooType.Invalid &&
                    t2 != GraphicFooType.Invalid)
                {
                    // Pop operands
                    string id2 = operandStack.Pop();
                    string id1 = operandStack.Pop();

                    // Find variables
                    Variable v1 = ProgramMemory.FindVariable(scope, id1);
                    Variable v2 = ProgramMemory.FindVariable(scope, id2);

                    // Pop operator
                    Operators op = operatorStack.Pop();

                    // Check association rules
                    GraphicFooType resultingType =
                        AssociationRules.GetOperationType(op, t1, t2);

                    // Create new temporary variable
                    Variable temp;
                    if (scope == null)
                    {
                        temp = ProgramMemory.AddGlobalTemporary(resultingType);
                    }
                    else
                    {
                        temp = scope.AddTemporaryVariable(resultingType);
                    }
                    // Push temp
                    operandStack.Push(temp.name);
                    typeStack.Push(temp.type);

                    // Create quadruple
                    Quadruple qudruple = new Quadruple(
                        op,
                        v1,
                        v2,
                        temp
                        );
                    PushQuadruple(qudruple);
                }
            }
        }
Exemple #6
0
        public Parser(Scanner scanner)
        {
            this.scanner = scanner;
            errors       = new Errors();

            // Memory
            ProgramMemory.Initialize();
            // Stacks
            Quadruple.Initialize();
        }
Exemple #7
0
        /// <summary>
        /// Creates an assignation quadruple.
        /// </summary>
        /// <param name="variableId">Variable identifier.</param>
        /// <param name="targetId">Target identifier.</param>
        public static void CreateAssignationQuadruple(
            string variableId,
            string targetId)
        {
            Variable  variable  = ProgramMemory.FindVariable(scope, variableId);
            Variable  target    = ProgramMemory.FindVariable(scope, targetId);
            Quadruple quadruple =
                new Quadruple(Operators.Assignation, variable, target);

            PushQuadruple(quadruple);
        }
Exemple #8
0
        /// <summary>
        /// Creates a return assignation quadruple.
        /// </summary>
        /// <param name="variableId">Variable identifier.</param>
        /// <param name="targetId">Target identifier.</param>
        public static void CreateReturnAssignationQuadruple(
            string variableId,
            string targetId)
        {
            Procedure variable  = ProgramMemory.ReadProcedure(variableId);
            Variable  target    = ProgramMemory.FindVariable(scope, targetId);
            Quadruple quadruple =
                new Quadruple(Operators.ReturnAssignation, target, variable);

            PushQuadruple(quadruple);
        }
Exemple #9
0
        /// <summary>
        /// Matchs the function parameters.
        /// </summary>
        /// <param name="procedure">Procedure.</param>
        /// <param name="parameters">Parameters.</param>
        private static void MatchParameters(
            Procedure procedure,
            VariableBlock parameters)
        {
            // Check parameter count consistency
            int procedureParameterCount = procedure.GetParameterCount();
            int parameterCallCount      = parameters.GetCount();

            if (procedureParameterCount != parameterCallCount)
            {
                Console.WriteLine(
                    "Call to {1}, with wrong numer of parameters ({2})",
                    procedure.name,
                    parameterCallCount
                    );
                return;
            }

            List <Variable> parameterList          = parameters.ToList();
            List <Variable> procedureParameterList =
                procedure.GetParameters().ToList();

            // Assign parameters
            for (int i = 0; i < parameterCallCount; i++)
            {
                if (parameterList [i].type == procedureParameterList [i].type)
                {
                    // TODO define paramX
                    Quadruple param =
                        new Quadruple(
                            Operators.Param,
                            ProgramMemory.FindVariable(
                                scope,
                                parameterList [i].name
                                ),
                            procedure.GetParameters().GetVariableAt(i)
                            );
                    PushQuadruple(param);
                }
                else
                {
                    Console.WriteLine(
                        "On call to {1}, parameter [{2}] {3} does not match the expected type {4}",
                        procedure.name,
                        i,
                        procedureParameterList [i].name,
                        procedureParameterList [i].type.ToString()
                        );
                    return;
                }
            }
        }
Exemple #10
0
        /// <summary>
        /// Executes a relational operation.
        /// </summary>
        /// <param name="q">Q.</param>
        private static void ExecuteRelationalOperation(Quadruple q)
        {
            float?v1Value = CastToNumeric(q.v1);
            float?v2Value = CastToNumeric(q.v2);

            switch (q.op)
            {
            case Operators.Greater:
                q.target.value = v1Value > v2Value;
                break;

            case Operators.Lesser:
                q.target.value = v1Value < v2Value;
                break;
            }
        }
Exemple #11
0
        /// <summary>
        /// Creates the function call quadruples.
        /// </summary>
        /// <param name="id">Identifier.</param>
        /// <param name="parameters">Parameters.</param>
        public static void CreateFunctionCallQuadruples(
            string id,
            VariableBlock parameters)
        {
            Procedure procedure = ProgramMemory.ReadProcedure(id);
            // Expand procedure
            Quadruple expand = new Quadruple(Operators.Expand, procedure);

            PushQuadruple(expand);
            // Assign parameters
            MatchParameters(procedure, parameters);
            // Go subroutine
            Quadruple goSub = new Quadruple(Operators.GoSub, procedure);

            PushQuadruple(goSub);
        }
Exemple #12
0
        void Print()
        {
            Expect((int)TokenEnum.Print);
            Expect((int)TokenEnum.LeftParenthesis);
            Expression();
            Expect((int)TokenEnum.RightParenthesis);
            Expect((int)TokenEnum.Semicolon);
            string temp = string.Empty;

            try {
                temp = Quadruple.operandStack.Pop();
            } catch (InvalidOperationException) {
                SynErr((int)TokenEnum.NoExpression);
            }

            Quadruple.CreatePrintQuadruple(temp);
        }
Exemple #13
0
        /// <summary>
        /// Parser function that generates function call quadruples.
        /// While checking semantics.
        /// </summary>
        void CallFunction()
        {
            Expect((int)TokenEnum.Function);
            Expect((int)TokenEnum.Id);
            string id = GetLastTokenValue();

            Expect((int)TokenEnum.LeftParenthesis);
            VariableBlock parameters = new VariableBlock();

            if (StartOf((int)TokenEnum.String))
            {
                Expression();
                string         paramId   = Quadruple.operandStack.Pop();
                GraphicFooType type      = Quadruple.typeStack.Pop();
                Variable       parameter = new Variable(paramId, type);
                if (parameter.type == GraphicFooType.Invalid)
                {
                    SemErr((int)SemanticEnum.Variable);
                }
                parameters.AddVariable(parameter);
                while (la.kind == (int)TokenEnum.Comma)
                {
                    Get();
                    Expression();
                    paramId   = Quadruple.operandStack.Pop();
                    type      = Quadruple.typeStack.Pop();
                    parameter = new Variable(paramId, type);
                    if (parameter.type == GraphicFooType.Invalid)
                    {
                        SemErr((int)SemanticEnum.Variable);
                    }
                    parameters.AddVariable(parameter);
                }
            }
            Expect((int)TokenEnum.RightParenthesis);
            Quadruple.CreateFunctionCallQuadruples(id, parameters);

            if (la.kind == (int)TokenEnum.Assignation)
            {
                Get();
                Expect((int)TokenEnum.Id);
                string varId = GetLastTokenValue();
                Quadruple.CreateReturnAssignationQuadruple(id, varId);
            }
            Expect((int)TokenEnum.Semicolon);
        }
Exemple #14
0
        void Assignation(string type = "")
        {
            bool assign = false;

            Expect((int)TokenEnum.Id);
            string   id       = GetLastTokenValue();
            Variable variable = ProgramMemory.FindVariable(scope, id);

            if (variable == null && type == "")
            {
                SemErr((int)SemanticEnum.NotDeclared);
            }
            if (la.kind == (int)TokenEnum.Assignation)
            {
                Get();
                Expression();
                assign = true;
            }
            Expect((int)TokenEnum.Semicolon);

            if (type != "")
            {
                if (scope == null)
                {
                    ProgramMemory.AddGlobalVariable(id, type);
                }
                else
                {
                    scope.AddVariable(id, type);
                }
            }

            if (assign)
            {
                try {
                    string temp = Quadruple.operandStack.Pop();
                    Quadruple.CreateAssignationQuadruple(temp, id);
                } catch (InvalidOperationException) {
                    SynErr((int)TokenEnum.NoExpression);
                }
            }
        }
Exemple #15
0
        /// <summary>
        /// Prints program output.
        /// </summary>
        /// <param name="q">Q.</param>
        private static void Print(Quadruple q)
        {
            Type printType = q.v1.GetNativeType();

            if (printType == typeof(float))
            {
                output += "Program Output: " + (q.v1.value as float?) + "\n";
                Console.WriteLine("Program Output: " + (q.v1.value as float?));
            }
            else if (printType == typeof(bool))
            {
                output += "Program Output: " + (q.v1.value as bool?) + "\n";
                Console.WriteLine("Program Output: " + (q.v1.value as bool?));
            }
            else if (printType == typeof(string))
            {
                Console.WriteLine("Program Output: " + (q.v1.value as string));
                output += "Program Output: " + (q.v1.value as string) + "\n";
            }
        }
Exemple #16
0
 void Condition()
 {
     IfHeader();
     while (StartOf((int)TokenEnum.Number))
     {
         Statute();
     }
     if (la.kind == (int)TokenEnum.Else)
     {
         Get();
         Quadruple.PopJump(1);
         Quadruple.CreateGotoQuadruple();
         Quadruple.PushJump();
         while (StartOf((int)TokenEnum.Number))
         {
             Statute();
         }
     }
     EndIf();
 }
Exemple #17
0
        /// <summary>
        /// Creates a return quadruple.
        /// </summary>
        /// <returns>The return quadruple.</returns>
        /// <param name="id">Identifier.</param>
        public static SemanticEnum CreateReturnQuadruple(string id)
        {
            Variable returnVariable = null;

            if (id != "")
            {
                returnVariable = ProgramMemory.FindVariable(scope, id);
            }
            // Validate return type
            SemanticEnum returnStatus = Semantics.ValidateReturn(scope.type, returnVariable);

            if (returnStatus == SemanticEnum.ValidReturn)
            {
                scope.SetEnd(Quadruple.quadruples.Count);
                Quadruple quadruple =
                    new Quadruple(Operators.Return, returnVariable);
                PushQuadruple(quadruple);
            }
            return(returnStatus);
        }
        /// <summary>
        /// Sends plain code to compile .
        /// </summary>
        /// <returns>The plain code to compile .</returns>
        /// <param name="stringToCompile">String to compile.</param>
        public static string SendToCompilePlainCode(string stringToCompile)
        {
            Scanner scanner = new Scanner(stringToCompile);
            Parser  parser  = new Parser(scanner);

            parser.Parse();
            Quadruple.DebugQuadruples();
            //				ProgramMemory.DebugProgramMemory ();
            string errorMessage =
                (!string.IsNullOrEmpty(parser.errors.errorMessage)) ?
                parser.errors.errorMessage :
                "None";

            if (errorMessage == "None")
            {
                VirtualMachine.Execute();
                errorMessage = VirtualMachine.output;
            }
            return(errorMessage);
        }
Exemple #19
0
 void Expression()
 {
     Exp();
     if (StartOf((int)TokenEnum.True))
     {
         Operators op;
         if (la.kind == (int)TokenEnum.Greater)
         {
             Get();
             op = Operators.Greater;
         }
         else if (la.kind == (int)TokenEnum.Lesser)
         {
             Get();
             op = Operators.Lesser;
         }
         else if (la.kind == (int)TokenEnum.Unequal)
         {
             Get();
             op = Operators.Unequal;
         }
         else if (la.kind == (int)TokenEnum.Equals)
         {
             Get();
             op = Operators.Equal;
         }
         else if (la.kind == (int)TokenEnum.Concatenation)
         {
             Get();
             op = Operators.Concatenation;
         }
         else
         {
             op = Operators.InvalidOperator;
             SynErr((int)TokenEnum.InvalidOperator);
         }
         Quadruple.operatorStack.Push(op);
         Exp();
         Quadruple.CreateRelationalQuadruple();
     }
 }
Exemple #20
0
        /// <summary>
        /// Executes a logical operation.
        /// </summary>
        /// <param name="q">Q.</param>
        private static void ExecuteLogicalOperation(Quadruple q)
        {
            bool?v1Value = CastToBoolean(q.v1);
            bool?v2Value = CastToBoolean(q.v2);

            bool v1, v2;

            v1 = v1Value ?? default(bool);
            v2 = v2Value ?? default(bool);

            switch (q.op)
            {
            case Operators.Or:
                q.target.value = v1 || v2;
                break;

            case Operators.And:
                q.target.value = v1 && v2;
                break;
            }
        }
Exemple #21
0
        /// <summary>
        /// Executes an equality operation.
        /// </summary>
        /// <param name="q">Q.</param>
        private static void ExecuteEqualityOperation(Quadruple q)
        {
            if (q.v1.GetNativeType() == typeof(float))
            {
                q.target.value =
                    (q.v1.value as float?) == (q.v2.value as float?);
            }
            else if (q.v1.GetNativeType() == typeof(bool))
            {
                q.target.value =
                    (q.v1.value as bool?) == (q.v2.value as bool?);
            }
            else if (q.v1.GetNativeType() == typeof(string))
            {
                q.target.value =
                    (q.v1.value as string).Equals(q.v2.value as string);
            }

            if (q.op == Operators.Unequal)
            {
                q.target.value = !(q.target.value as bool?);
            }
        }
Exemple #22
0
        void Function()
        {
            scope           = FunctionHeader();
            Quadruple.scope = scope;
            while (StartOf((int)TokenEnum.Id))
            {
                Declaration();
            }
            while (StartOf((int)TokenEnum.Number))
            {
                Statute();
            }
            string id = "";

            id = Return();
            SemanticEnum returnStatus = Quadruple.CreateReturnQuadruple(id);

            if (returnStatus != SemanticEnum.ValidReturn)
            {
                SemErr((int)returnStatus);
            }
            EndFunction();
        }
Exemple #23
0
        /// <summary>
        /// Executes a procedure expansion.
        /// </summary>
        /// <param name="q">Q.</param>
        private static void ExecuteProcedureExpansion(Quadruple q)
        {
            Procedure p = q.call;
            Dictionary <int, Quadruple> quadruples = new Dictionary <int, Quadruple> ();
            VariableBlock block = new VariableBlock();

            clones.Push(block);

            for (int i = p.index; i <= p.end; i++)
            {
                Quadruple original = Quadruple.quadruples [i];
                Quadruple clone    = new Quadruple(
                    original.op,
                    CloneOrFindVariable(original.v1),
                    CloneOrFindVariable(original.v2),
                    CloneOrFindVariable(original.target),
                    original.call,
                    original.jumpIndex
                    );
                quadruples.Add(i, clone);
            }
            programStack.Push(quadruples);
            return;
        }
Exemple #24
0
        /// <summary>
        /// Run the specified quadruples at start.
        /// </summary>
        /// <param name="quadruples">Quadruples.</param>
        /// <param name="start">Start.</param>
        private static void Run(
            Dictionary <int, Quadruple> quadruples,
            int start)
        {
            end = false;
            int index = start;

            while (true)
            {
                if (!quadruples.ContainsKey(index))
                {
                    return;
                }
                Quadruple q = quadruples [index];
                Console.WriteLine(
                    "Executing [" + index + "/" + (quadruples.Count - 1) + "]"
                    );
                switch (q.op)
                {
                case Operators.Assignation:
                    q.target.value = q.v1.value;
                    index++;
                    break;

                case Operators.ReturnAssignation:
                    try {
                        q.v1.value = returns.Pop().value;
                        Console.WriteLine(q.v1.value as float?);
                    } catch (InvalidOperationException) {
                    }
                    index++;
                    break;

                case Operators.Param:
                    clones.Peek().ReadVariable(q.target.name).value = q.v1.value;
                    index++;
                    break;

                case Operators.Plus:
                case Operators.Minus:
                case Operators.Multiplication:
                case Operators.Division:
                    ExecuteArithmeticOperation(q);
                    index++;
                    break;

                case Operators.Greater:
                case Operators.Lesser:
                    ExecuteRelationalOperation(q);
                    index++;
                    break;

                case Operators.Equal:
                case Operators.Unequal:
                    ExecuteEqualityOperation(q);
                    index++;
                    break;

                case Operators.Or:
                case Operators.And:
                    ExecuteLogicalOperation(q);
                    index++;
                    break;

                case Operators.Goto:
                    index = q.jumpIndex;
                    break;

                case Operators.GotoT:
                    index =
                        (ExecuteGotoOperation(q, true)) ?
                        q.jumpIndex :
                        index + 1;
                    break;

                case Operators.GotoF:
                    index =
                        (ExecuteGotoOperation(q, false)) ?
                        q.jumpIndex :
                        index + 1;
                    break;

                case Operators.Expand:
                    ExecuteProcedureExpansion(q);
                    index++;
                    break;

                case Operators.GoSub:
                    goSubJumps.Push(index);
                    exec = programStack.Peek();
                    Run(exec, q.call.index);
                    index++;
                    break;

                case Operators.Return:
                    if (q.v1 != null)
                    {
                        returns.Push(q.v1);
                    }

                    if (goSubJumps.Count == 0)
                    {
                        end = true;
                        index++;
                        return;
                    }
                    else
                    {
                        index = goSubJumps.Pop() + 1;
                        Run(programStack.Pop(), index);
                    }
                    break;

                case Operators.Print:
                    Print(q);
                    index++;
                    break;

                default:
                    index++;
                    break;
                }
                if (end && index == (quadruples.Count))
                {
                    Console.WriteLine("kill switch");
                    return;
                }
            }
        }
Exemple #25
0
 void EndLoop()
 {
     Expect((int)TokenEnum.EndWhile);
     Quadruple.CreateGotoQuadruple();
     Quadruple.PopTwoJumps();
 }
Exemple #26
0
 /// <summary>
 /// Pushes a quadruple to the main dictionary.
 /// </summary>
 /// <param name="quaduple">Quaduple.</param>
 public static void PushQuadruple(Quadruple quaduple)
 {
     quadruples.Add(quadruples.Count, quaduple);
 }