/// <summary> /// Initialize this instance. /// </summary> public static void Initialize() { constants = new VariableBlock(); globalTemporary = new VariableBlock(); globalVariables = new VariableBlock(); procedures = new Dictionary <string, Procedure> (); }
/// <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; } } }
/// <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); }
/// <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); }
/// <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); }
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)); }
/// <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(); }
/// <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; }