/// <summary> /// Process Parameters /// </summary> /// <param name="identifierRecord"></param> /// <param name="procedureRecord"></param> /// <param name="parameterList"></param> internal void processParameters(IdentifierRecord identifierRecord, ref MethodRecord procedureRecord, ref List<Parameter> parameterList) { if (identifierRecord.symbol is ProcedureSymbol) { ProcedureSymbol pSymbol = identifierRecord.symbol as ProcedureSymbol; procedureRecord.parameterList = pSymbol.paramList; parameterList = new List<Parameter>(procedureRecord.parameterList); } }
/// <summary> /// Generates code for loading a delegate /// </summary> /// <param name="methodRecord"></param> internal void GenerateLoadDelegate(MethodRecord methodRecord) { SymbolTable table = symbolTableStack.Peek(); cilOutput.WriteLine(" ldloc.0"); cilOutput.WriteLine(" ldfld\tclass Program/" + methodRecord.name + "Delegate " + table.cilScope + "/c__" + table.name + "::d__" + methodRecord.name + Environment.NewLine); }
/// <summary> /// Process a method /// </summary> /// <param name="identifierRecord"></param> /// <param name="methodRecord"></param> internal void ProcessMethod(IdentifierRecord identifierRecord,ref MethodRecord methodRecord) { if (identifierRecord.symbol.symbolType == SymbolType.FunctionSymbol || identifierRecord.symbol.symbolType == SymbolType.ProcedureSymbol) { methodRecord.name = identifierRecord.lexeme; methodRecord.returnType = identifierRecord.symbol.variableType; methodRecord.symbolType = identifierRecord.symbol.symbolType; } }
/// <summary> /// inserts symbols into the symboltable /// </summary> /// <param name="idRecordList"></param> /// <param name="typeRecord"></param> public void SymbolTableInsert(MethodRecord methodRecord) { delegateList.Add(methodRecord); Symbol symbol = null; switch (methodRecord.symbolType) { case SymbolType.ProcedureSymbol: symbol = new ProcedureSymbol(methodRecord.name, SymbolType.ProcedureSymbol, nextLabel, methodRecord.parameterList); break; case SymbolType.FunctionSymbol: symbol = new FunctionSymbol(methodRecord.name,SymbolType.FunctionSymbol, nextLabel,methodRecord.parameterList,methodRecord.returnType); break; } symbolTableStack.Peek().Insert(symbol); }
/// <summary> /// Generates code for calling a method /// </summary> internal void GenerateCallMethod(MethodRecord methodRecord) { string parameterString = string.Empty; if (methodRecord.symbolType == SymbolType.FunctionSymbol || methodRecord.symbolType == SymbolType.ProcedureSymbol) { parameterString = GenerateParameterString(methodRecord.parameterList, false); cilOutput.WriteLine(" callvirt\tinstance " + Enumerations.GetDescription<VariableType> (methodRecord.returnType) + " Program/" + methodRecord.name + "Delegate::Invoke(" + parameterString + ")" + Environment.NewLine); } }
/// <summary> /// Parse FunctionHeading /// </summary> /// <param name="functionRecord"></param> private void FunctionHeading(MethodRecord functionRecord, ref IdentifierRecord identifierRecord) { TypeRecord typeRecord = new TypeRecord(SymbolType.FunctionSymbol, VariableType.Void); functionRecord.parameterList = new List<Parameter>(); switch (lookAheadToken.tag) { case Tags.MP_FUNCTION: UsedRules.WriteLine("18"); Match((int)Tags.MP_FUNCTION); Identifier(ref functionRecord); identifierRecord.lexeme = functionRecord.name; functionRecord.parameterList = OptionalFormalParameterList( functionRecord.parameterList); Type(ref typeRecord); functionRecord.returnType = typeRecord.variableType; analyzer.SymbolTableInsert(functionRecord); analyzer.ProcessId(ref identifierRecord); analyzer.CreateSymbolTable(functionRecord.name); //analyzer.ProcessMethod(identifierRecord, ref functionRecord); analyzer.SymbolTableInsert(functionRecord.parameterList); break; default: Error("Expecting FunctionHeading but found " + lookAheadToken.lexeme); break; } }
/// <summary> /// Parse Identifier /// </summary> /// <param name="programIdenentifierRecord"></param> private void Identifier(ref MethodRecord programIdenentifierRecord) { programIdenentifierRecord.name = lookAheadToken.lexeme; Match((int)Tags.MP_IDENTIFIER); }
/// <summary> /// Parse FunctionDeclaration /// </summary> private void FunctionDeclaration() { IdentifierRecord identifierRecord = new IdentifierRecord(); MethodRecord functionIdentifierRecord = new MethodRecord(SymbolType.FunctionSymbol); switch (lookAheadToken.tag) { case Tags.MP_FUNCTION: UsedRules.WriteLine("16"); FunctionHeading(functionIdentifierRecord,ref identifierRecord); Match(';'); Block(identifierRecord); analyzer.symbolTableStack.Pop(); Match(';'); break; default: Error("Expecting FunctionDeclaration but found " + lookAheadToken.lexeme); break; } }
/// <summary> /// Parse Factor /// </summary> /// <param name="factorRecord"></param> private void Factor(ref VariableRecord factorRecord) { IdentifierRecord idRecord = new IdentifierRecord(); LiteralRecord litRecord = new LiteralRecord(); VariableType tempType = VariableType.Void; List<Parameter> parameterList = new List<Parameter>(); MethodRecord methodRecord = new MethodRecord(); methodRecord.parameterList = new List<Parameter>(); string idRecName = null; switch (lookAheadToken.tag) { case Tags.MP_INTEGER_LIT: UsedRules.WriteLine("94"); litRecord.lexeme = lookAheadToken.lexeme; litRecord.type = VariableType.Integer; Match((int)Tags.MP_INTEGER_LIT); analyzer.GenerateLitPush(litRecord, ref tempType); factorRecord.variableType = tempType; break; case Tags.MP_NOT: UsedRules.WriteLine("95"); Match((int)Tags.MP_NOT); Factor(ref factorRecord); break; case Tags.MP_LPAREN: UsedRules.WriteLine("96"); Match((int)Tags.MP_LPAREN); Expression(ref factorRecord); Match((int)Tags.MP_RPAREN); break; case Tags.MP_IDENTIFIER: UsedRules.WriteLine("97"); Identifier(ref idRecName); idRecord.lexeme = idRecName; analyzer.ProcessId(ref idRecord); analyzer.GenerateIdPush(idRecord, ref factorRecord); analyzer.processParameters(idRecord,ref methodRecord,ref parameterList); OptionalActualParameterList(parameterList); analyzer.ProcessMethod(idRecord,ref methodRecord); analyzer.GenerateCallMethod(methodRecord); break; default: Error("Expecting Factor but found " + lookAheadToken.lexeme); break; } }
/// <summary> /// Parse ProcedureStatement /// </summary> private void ProcedureStatement() { MethodRecord procedureRecord = new MethodRecord(SymbolType.ProcedureSymbol); IdentifierRecord identifierRecord = new IdentifierRecord(); List<Parameter> parameterList = new List<Parameter>(); procedureRecord.parameterList = new List<Parameter>(); switch (lookAheadToken.tag) { case Tags.MP_IDENTIFIER: UsedRules.WriteLine("63"); Identifier(ref procedureRecord); identifierRecord.lexeme = procedureRecord.name; analyzer.ProcessId(ref identifierRecord); analyzer.GenerateLoadDelegate(procedureRecord); analyzer.processParameters(identifierRecord, ref procedureRecord, ref parameterList); OptionalActualParameterList(parameterList); analyzer.GenerateCallMethod(procedureRecord); break; default: Error("Expecting ProcedureStatement but found " + lookAheadToken.lexeme); break; } }
/// <summary> /// Parse ProcedureHeading /// </summary> /// <param name="procedureRecord"></param> private void ProcedureHeading(MethodRecord procedureRecord,ref IdentifierRecord identifierRecord) { procedureRecord.parameterList = new List<Parameter>(); switch(lookAheadToken.tag) { case Tags.MP_PROCEDURE: UsedRules.WriteLine("17"); Match((int)Tags.MP_PROCEDURE); Identifier(ref procedureRecord); identifierRecord.lexeme = procedureRecord.name; procedureRecord.parameterList = OptionalFormalParameterList( procedureRecord.parameterList); analyzer.SymbolTableInsert(procedureRecord); analyzer.ProcessId(ref identifierRecord); analyzer.CreateSymbolTable(procedureRecord.name); analyzer.ProcessMethod(identifierRecord, ref procedureRecord); analyzer.SymbolTableInsert(procedureRecord.parameterList); break; default: Error("Expecting ProcedureHeading but found " + lookAheadToken.lexeme); break; } }
/// <summary> /// Parse ProcedureDeclaration /// </summary> private void ProcedureDeclaration() { MethodRecord procedureIdentifierRecord = new MethodRecord(SymbolType.ProcedureSymbol); IdentifierRecord identifierRecord = new IdentifierRecord(); switch(lookAheadToken.tag) { case Tags.MP_PROCEDURE: UsedRules.WriteLine("15"); ProcedureHeading(procedureIdentifierRecord,ref identifierRecord); Match(';'); Block(identifierRecord); analyzer.symbolTableStack.Pop(); Match(';'); break; default: Error("Expecting ProcedureDeclaration but found " + lookAheadToken.lexeme); break; } }