예제 #1
0
 /// <summary>
 /// Initialize this instance.
 /// </summary>
 public static void Initialize()
 {
     constants       = new VariableBlock();
     globalTemporary = new VariableBlock();
     globalVariables = new VariableBlock();
     procedures      = new Dictionary <string, Procedure> ();
 }
예제 #2
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;
                }
            }
        }
예제 #3
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);
        }
예제 #4
0
        /// <summary>
        /// Adds a procedure.
        /// </summary>
        /// <returns>The procedure.</returns>
        /// <param name="id">Identifier.</param>
        /// <param name="type">Type.</param>
        /// <param name="parameterBlock">Parameter block.</param>
        public static Procedure AddProcedure(
            string id,
            string type,
            VariableBlock parameterBlock)
        {
            if (procedures.ContainsKey(id))
            {
                // TODO sem error
                return(null);
            }

            Procedure procedure = new Procedure(id, type, parameterBlock);

            procedures.Add(procedure.name, procedure);
            return(procedure);
        }
예제 #5
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);
        }
예제 #6
0
        Procedure FunctionHeader()
        {
            Expect((int)TokenEnum.Function);
            Expect((int)TokenEnum.Id);
            string id = GetLastTokenValue();

            Expect((int)TokenEnum.LeftParenthesis);

            VariableBlock parameters = null;

            if (StartOf((int)TokenEnum.Id))
            {
                parameters = new VariableBlock();
                Type();
                string varType = GetLastTokenValue();
                Expect((int)TokenEnum.Id);
                string   varId     = GetLastTokenValue();
                Variable parameter = new Variable(varId, varType);
                if (parameter.type == GraphicFooType.Invalid)
                {
                    SemErr((int)SemanticEnum.Variable);
                }
                parameters.AddVariable(parameter);
                while (la.kind == (int)TokenEnum.Comma)
                {
                    Get();
                    Type();
                    varType = GetLastTokenValue();
                    Expect((int)TokenEnum.Id);
                    varId     = GetLastTokenValue();
                    parameter = new Variable(varId, varType);
                    parameters.AddVariable(parameter);
                }
            }
            Expect((int)TokenEnum.RightParenthesis);
            Expect((int)TokenEnum.Colon);
            Type();
            string type = GetLastTokenValue();

            return(ProgramMemory.AddProcedure(id, type, parameters));
        }
예제 #7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="GraphicFoo.Procedure"/> class.
        /// </summary>
        /// <param name="name">Name.</param>
        /// <param name="rawType">Raw type.</param>
        /// <param name="parameters">Parameters.</param>
        public Procedure(
            string name,
            string rawType,
            VariableBlock parameters)
        {
            this.name   = name;
            this.type   = ParseType(rawType);
            this.index  = Quadruple.quadruples.Count;
            this.end    = -1;
            this.isMain = name == "main";

            if (isMain)
            {
                VirtualMachine.startOfMain = index;
            }

            this.parameters =
                (parameters == null) ? new VariableBlock() : parameters;
            this.procedureVariables = new VariableBlock();
            this.temporaryVariables = new VariableBlock();
        }
예제 #8
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;
        }