private void EmitVarStatement(NonTerm nonTerm) { BaseSymbol varStat; BaseSymbol expression; NonTermFactory.GetAssignVarStatement(nonTerm, out varStat, out expression); if (expression != null) { Token varType; Token varToken; NonTermFactory.GetVarDecl(varStat, out varType, out varToken); if (varType.TypeToken == TokenType.ID) { _currentOperand = _g.Local(Exp.New(_classesTable[varType.Value])); _currentOperandTempResult = _g.Local(_currentOperand); } else { _currentOperand = _g.Local(varType.TypeOf); _currentOperandTempResult = _g.Local(_currentOperand.Type); } if (!(expression is Token)) { Generate(expression); _g.Assign(GetOperandValue(varToken.Value, varToken), _currentOperandTempResult); } else { _g.Assign(GetOperandValue(varToken.Value, varToken), OperandTokenInit(expression, GetOperandValue(varToken.Value, varToken))); } } }
private void EmitNewStatement(NonTerm nonTerm) { Token typeToken; NonTermFactory.GetNewStatement(nonTerm, out typeToken); _currentOperandTempResult = Exp.New(_classesTable[typeToken.Value]); }
private void LoadClassesMethods(BaseSymbol root, AssemblyGen ag) { root.Symbols.ForEach(s => { if (s.GrammarMember == GrammarMemberType.NonTerm) { NonTerm nonTerm = s as NonTerm; switch (nonTerm.TypeNonTerm) { case NonTermType.Class: Token termClassId; List <BaseSymbol> declarations; NonTermFactory.GetClassDecl(nonTerm, out termClassId, out declarations); string classId = termClassId.Value; TypeGen cl = _classesTable[classId]; Dictionary <string, MethodGen> methodsDictionary = new Dictionary <string, MethodGen>(); foreach (var declaration in declarations) { if ((declaration as NonTerm).TypeNonTerm == NonTermType.Method) { KeyValuePair <string, MethodGen> method = GenerateMethodSignature(cl, declaration, ag); methodsDictionary.Add(method.Key, method.Value); } } _methodsTables.Add(cl.Name, methodsDictionary); break; } } }); }
private void EmitIdStatement(NonTerm nonTerm) { Token idToken; BaseSymbol expression; NonTermFactory.GetAssignIdStatement(nonTerm, out idToken, out expression); Operand operand; if (_currentFormalArgumentList.Contains(idToken.Value)) { operand = _g.Arg(idToken.Value); } else if (_localVariablesTable.ContainsKey(idToken.Value)) { operand = _localVariablesTable[idToken.Value]; } else { operand = _g.This().Field(idToken.Value); } _currentOperandTempResult = EmitExpression(expression, operand.Type, idToken.Value); try { _g.Assign(operand, _currentOperandTempResult); } catch (InvalidCastException ex) { throw new CodeGenerationException(MessagesHelper.AssignTypeMismatchEx, expression.ToStringInfo(), ex); } }
private void EmitArrayIndiciesStatement(NonTerm nonTerm) { Token arrayNameToken; List <BaseSymbol> expressionSymbolList; NonTermFactory.GetArrayIndiciesStatement(nonTerm, out arrayNameToken, out expressionSymbolList); List <Operand> arrayIndicesBracketsExpressions = new List <Operand>(); foreach (var expressionSymbol in expressionSymbolList) { string nameArrayIndexTempVariable = AddArrayLocalVariable(); Operand expr = EmitExpression(expressionSymbol, typeof(int), nameArrayIndexTempVariable); arrayIndicesBracketsExpressions.Add(expr); } try { if (_localVariablesTable.ContainsKey(arrayNameToken.Value)) { _currentOperandTempResult = _localVariablesTable[arrayNameToken.Value][arrayIndicesBracketsExpressions.ToArray()]; } else { _currentOperandTempResult = _g.This().Field(arrayNameToken.Value)[arrayIndicesBracketsExpressions.ToArray()]; } } catch (ArgumentException ex) { throw new CodeGenerationException(MessagesHelper.IndexCountMismatchEx, arrayNameToken.ToStringInfo(), ex); } }
/// <summary> /// Загрузка всех классов (наследование учитывается). /// Допущение - классы-наследники должны располагаться после базовых классов /// и иерархий наследования должно быть не более 1. /// </summary> /// <param name="root">Базовый символ</param> /// <param name="ag">Сборка</param> private void LoadClassesExtends(BaseSymbol root, AssemblyGen ag) { root.Symbols.ForEach(s => { if (s.GrammarMember == GrammarMemberType.NonTerm) { NonTerm nonTerm = s as NonTerm; switch (nonTerm.TypeNonTerm) { case NonTermType.Class: Token termClassId; NonTerm extends; NonTermFactory.GetClassDecl(nonTerm, out termClassId, out extends); string classId = termClassId.Value; if (extends == null) { TypeGen cl = ag.Class(classId); _classesTable.Add(cl.Name, cl); } else { Token baseClassId; NonTermFactory.GetClassId(extends, out baseClassId); TypeGen cl = _classesTable[baseClassId.Value]; cl = ag.Class(classId, cl); _classesTable.Add(cl.Name, cl); } break; } } }); }
private void EmitWhileStatement(NonTerm nonTerm) { BaseSymbol expressionWhile; BaseSymbol statementWhile; NonTermFactory.GetWhileStatement(nonTerm, out expressionWhile, out statementWhile); string nameWhile = AddWhileLocalVariable(); GeneratePreInitLocalVariables(statementWhile); _g.Assign(_localVariablesTable[nameWhile], EmitBoolExpression(expressionWhile, nameWhile)); try { _g.While(_localVariablesTable[nameWhile]); } catch (InvalidOperationException ex) { throw new CodeGenerationException(MessagesHelper.TypeMismatchEx, expressionWhile.ToStringInfo(), ex); } Generate(statementWhile); _g.Assign(_localVariablesTable[nameWhile], EmitBoolExpression(expressionWhile, nameWhile)); ClearCurrentBlockLocalVariables(); _g.End(); }
private void EmitLengthFunctionExpression(NonTerm nonTerm) { Token lengthFunction; NonTermFactory.GetLengthFunctionExpression(nonTerm, out lengthFunction); _currentOperandTempResult = GetOperandValue(lengthFunction.Value, lengthFunction).ArrayLength(); }
private void EmitClass(NonTerm nonTerm) { Token termClassId; List <BaseSymbol> declarations; NonTermFactory.GetClassDecl(nonTerm, out termClassId, out declarations); _currentClass = _classesTable[termClassId.Value]; declarations.ForEach(symbol => Generate(symbol)); }
private void EmitClassVar(NonTerm nonTerm) { Token typeClassVarDeclSimple; Token idClassVar; NonTermFactory.GetClassVarDecl(nonTerm, out typeClassVarDeclSimple, out idClassVar); Type classVarType = GetVariableType(typeClassVarDeclSimple); _currentClass.Private.Field(classVarType, idClassVar.Value); }
private void EmitMethodCallExpression(NonTerm nonTerm) { Token idMethodName; List <BaseSymbol> methodArguments; string nameIdVariable = string.Empty; if (nonTerm.TypeNonTerm == NonTermType.MethodCallExpression) { BaseSymbol symbol; NonTermFactory.GetMethodCallExpression(nonTerm, out symbol, out idMethodName, out methodArguments); if (symbol is Token) { Token idVariable = symbol as Token; nameIdVariable = idVariable.Value; } else { NonTerm nonTermVariable = symbol as NonTerm; Generate(nonTermVariable); string nameNew = AddTempLocalVariable(_currentOperandTempResult.Type); _localVariablesTable[nameNew] = _currentOperandTempResult; nameIdVariable = nameNew; } } else { NonTermFactory.GetMethodCallExpression(nonTerm, out idMethodName, out methodArguments); } List <Operand> methodArgumentsExpressions = new List <Operand>(); foreach (var expressionSymbol in methodArguments) { string nameTempVariable = AddTempLocalVariable(); Operand expr = EmitExpression(expressionSymbol, typeof(object), nameTempVariable); methodArgumentsExpressions.Add(expr); } try { if (nonTerm.TypeNonTerm == NonTermType.MethodCallExpression) { _currentOperandTempResult = GetOperandValue(nameIdVariable, null).Invoke(idMethodName.Value, methodArgumentsExpressions.ToArray()); } else { _currentOperandTempResult = _g.This().Invoke(idMethodName.Value, methodArgumentsExpressions.ToArray()); } } catch (MissingMethodException ex) { throw new CodeGenerationException(MessagesHelper.MissingMethodEx, idMethodName.ToStringInfo(), ex); } }
private void EmitUnaryExpression(NonTerm nonTerm) { BaseSymbol unaryExpression; NonTermFactory.GetUnaryExpression(nonTerm, out unaryExpression); //_compilerLogger.PrintGenerateNonTerm(nonTerm); try { if (unaryExpression.GrammarMember == GrammarMemberType.Token) { Operand operandFirst = OperandTokenInitLocal(unaryExpression); _stackOperandFirst.Push(_g.Local(operandFirst)); } else { Generate(unaryExpression); _stackOperandFirst.Push(_g.Local(_currentOperandTempResult)); } } catch (InvalidCastException ex) { throw new CodeGenerationException(MessagesHelper.TypeMismatchEx, unaryExpression.ToStringInfo(), ex); } Operand currentOperandFirst = _stackOperandFirst.Pop(); try { Operand unaryExpr = null; switch (nonTerm.TypeNonTerm) { case NonTermType.UnaryMinusExpression: unaryExpr = -currentOperandFirst; break; case NonTermType.UnaryNotExpression: unaryExpr = !currentOperandFirst; break; } _currentOperandTempResult = unaryExpr; } catch (InvalidOperationException ex) { throw new CodeGenerationException(MessagesHelper.InvalidOperationEx, nonTerm.ToStringInfo(), ex); } catch (InvalidCastException ex) { throw new CodeGenerationException(MessagesHelper.TypeMismatchEx, nonTerm.ToStringInfo(), ex); } }
private void EmitMethod(NonTerm nonTerm) { Token typeMethodDeclSimple; Token methodName; List <BaseSymbol> formalParametersList; BaseSymbol methodStatementList; BaseSymbol returnStatement; NonTermFactory.GetMethodDecl(nonTerm, out typeMethodDeclSimple, out methodName, out formalParametersList, out methodStatementList, out returnStatement); _currentFormalArgumentList.Clear(); foreach (BaseSymbol symbol in formalParametersList) { Token type; Token id; NonTermFactory.GetFormalArgumentDeclaration(symbol, out type, out id); _currentFormalArgumentList.Add(id.Value); } _compilerLogger.PrintRefreshFormalArgumentList(_currentFormalArgumentList); _currentMethod = _methodsTables[_currentClass.Name][methodName.Value]; _g = _currentMethod; GeneratePreInitLocalVariables(methodStatementList); Generate(methodStatementList); Type resultType = GetVariableType(typeMethodDeclSimple); string nameResult = AddTempLocalVariable(resultType); EmitExpression(returnStatement, resultType, nameResult); try { _g.Return(_currentOperandTempResult); } catch (InvalidCastException ex) { throw new CodeGenerationException(MessagesHelper.TypeMismatchEx, returnStatement.ToStringInfo(), ex); } ClearCurrentBlockLocalVariables(); }
private void EmitMainClass(NonTerm nonTerm) { Token termClassId; List <BaseSymbol> declarations; NonTermFactory.GetMainClassDecl(nonTerm, out termClassId, out declarations); _currentClass = _asm.Class(termClassId.Value); _classesTable.Add(_currentClass.Name, _currentClass); _g = _currentClass.Public.Static.Method(typeof(void), "Main"); GeneratePreInitLocalVariables(nonTerm); declarations.ForEach(symbol => Generate(symbol)); ClearCurrentBlockLocalVariables(); }
private void AddPreInitLocalVariables(BaseSymbol root) { if (root == null) { return; } if (root.GrammarMember == GrammarMemberType.NonTerm) { NonTerm nonTerm = root as NonTerm; // заносим в список переменные только текущего блока if (GrammarHelper.BlockVariablesList.Contains(nonTerm.TypeNonTerm)) { return; } switch (nonTerm.TypeNonTerm) { case NonTermType.Variable: case NonTermType.ArrayVariable: Token typeDeclSimple; Token idVar; NonTermFactory.GetVarDecl(nonTerm, out typeDeclSimple, out idVar); _currentOperand = _g.Local(GetVariableType(typeDeclSimple)); try { _localVariablesTable.Add(idVar.Value, _currentOperand); _currentBlockVariableList.Add(idVar.Value); } catch (ArgumentException ex) { throw new CodeGenerationException(MessagesHelper.LocalVariableIsAlreadyDefinedEx, idVar.ToStringInfo(), ex); } break; } } if (root.GrammarMember == GrammarMemberType.NonTerm) { root.Symbols.ForEach(x => AddPreInitLocalVariables(x)); } }
/// <summary> /// Загрузка всех классов (наследование не учитывается). /// </summary> /// <param name="root">Базовый символ</param> /// <param name="ag">Сборка</param> private void LoadClasses(BaseSymbol root, AssemblyGen ag) { root.Symbols.ForEach(s => { if (s.GrammarMember == GrammarMemberType.NonTerm) { NonTerm nonTerm = s as NonTerm; switch (nonTerm.TypeNonTerm) { case NonTermType.Class: Token termClassId; NonTermFactory.GetClassId(nonTerm, out termClassId); string classId = termClassId.Value; TypeGen cl = ag.Class(classId); _classesTable.Add(cl.Name, cl); break; } } }); }
private void EmitIfStatement(NonTerm nonTerm) { BaseSymbol expressionIf; BaseSymbol statementIf; NonTermFactory.GetIfStatement(nonTerm, out expressionIf, out statementIf); string nameIf = AddIfLocalVariable(); _currentOperandTempResult = EmitExpression(expressionIf, _localVariablesTable[nameIf].Type, nameIf); _g.Assign(_localVariablesTable[nameIf], _currentOperandTempResult); try { _g.If(_currentOperandTempResult); } catch (InvalidOperationException ex) { throw new CodeGenerationException(MessagesHelper.TypeMismatchEx, expressionIf.ToStringInfo(), ex); } GeneratePreInitLocalVariables(statementIf); Generate(statementIf); ClearCurrentBlockLocalVariables(); if (nonTerm.TypeNonTerm == NonTermType.IfElseStatement) { BaseSymbol statementElse; NonTermFactory.GetElseStatement(nonTerm, out statementElse); _g.Else(); GeneratePreInitLocalVariables(statementElse); Generate(statementElse); ClearCurrentBlockLocalVariables(); } _g.End(); }
/// <summary> /// Главный метод генерации IL-кода /// </summary> /// <param name="root">символ грамматики</param> private void Generate(BaseSymbol root) { if (root == null) { return; } if (root.GrammarMember == GrammarMemberType.NonTerm) { NonTerm nonTerm = root as NonTerm; _compilerLogger.PrintGenerateNonTerm(nonTerm); if (_emitTableDictionary.ContainsKey(nonTerm.TypeNonTerm)) { _emitTableDictionary[nonTerm.TypeNonTerm](nonTerm); } else { root.Symbols.ForEach(Generate); } } }
private void EmitArrayIdStatement(NonTerm nonTerm) { Token arrayIdToken; BaseSymbol expression; List <BaseSymbol> bracketExpressionList; NonTermFactory.GetArrayAssignIdStatement(nonTerm, out arrayIdToken, out expression, out bracketExpressionList); List <Operand> arrayIndicesExpressions = GenerateArrayIndiciesExpression(bracketExpressionList); _currentOperandTempResult = EmitExpression(expression, GetOperandValue(arrayIdToken.Value, arrayIdToken)[arrayIndicesExpressions.ToArray()].Type, arrayIdToken.Value); try { _g.Assign(GetOperandValue(arrayIdToken.Value, arrayIdToken)[arrayIndicesExpressions.ToArray()], _currentOperandTempResult); } catch (InvalidOperationException ex) { throw new CodeGenerationException(MessagesHelper.ArrayUsingWithoutInitializingEx, arrayIdToken.ToStringInfo(), ex); } }
private void EmitNewArrayStatement(NonTerm nonTerm) { Token arrayTypeToken; List <BaseSymbol> bracketExpressionList; NonTermFactory.GetNewArrayStatement(nonTerm, out arrayTypeToken, out bracketExpressionList); Operand tempOperand = _currentOperandTempResult; List <Operand> arrayIndicesExpressions = GenerateArrayIndiciesExpression(bracketExpressionList); _currentOperandTempResult = tempOperand; try { _g.Assign(_currentOperandTempResult, Exp.NewArray(arrayTypeToken.TypeOfWithoutArray, arrayIndicesExpressions.ToArray())); } catch (InvalidOperationException ex) { throw new CodeGenerationException(MessagesHelper.VariableUsingWithoutInitializing, arrayTypeToken.ToStringInfo(), ex); } }
private void EmitPrintStatement(NonTerm nonTerm) { BaseSymbol expressionPrint; NonTermFactory.GetPrintStatement(nonTerm, out expressionPrint); string namePrint = AddTempLocalVariable(); if (!(expressionPrint is Token)) { _currentOperandTempResult = _g.Local(_localVariablesTable[namePrint].Type); Generate(expressionPrint); } else { _currentOperandTempResult = OperandTokenInit(expressionPrint, _localVariablesTable[namePrint]); } _g.WriteLine(_currentOperandTempResult); _g.Invoke(typeof(Console), "ReadKey"); }
public void PrintGenerateNonTerm(NonTerm nonTerm) { _stream.WriteLine("Генерация инструкций для {0}", nonTerm); }
private void EmitBinaryExpression(NonTerm nonTerm) { BaseSymbol first; BaseSymbol second; NonTermFactory.GetBinaryExpression(nonTerm, out first, out second); //_compilerLogger.PrintGenerateNonTerm(nonTerm); try { if (first.GrammarMember == GrammarMemberType.Token) { _stackOperandFirst.Push(OperandTokenInitLocal(first)); } else { Generate(first); _stackOperandFirst.Push(_g.Local(_currentOperandTempResult)); } } catch (InvalidCastException ex) { throw new CodeGenerationException(MessagesHelper.TypeMismatchEx, first.ToStringInfo(), ex); } try { if (second.GrammarMember == GrammarMemberType.Token) { _stackOperandSecond.Push(OperandTokenInitLocal(second)); } else { Generate(second); _stackOperandSecond.Push(_g.Local(_currentOperandTempResult)); } } catch (InvalidCastException ex) { throw new CodeGenerationException(MessagesHelper.TypeMismatchEx, second.ToStringInfo(), ex); } Operand currentOperandFirst = _stackOperandFirst.Pop(); Operand currentOperandSecond = _stackOperandSecond.Pop(); try { switch (nonTerm.TypeNonTerm) { case NonTermType.EqualExpression: _currentOperandTempResult = currentOperandFirst == currentOperandSecond; break; case NonTermType.NotEqualExpression: _currentOperandTempResult = currentOperandFirst != currentOperandSecond; break; case NonTermType.LessExpression: _currentOperandTempResult = currentOperandFirst < currentOperandSecond; break; case NonTermType.LessEqExpression: _currentOperandTempResult = currentOperandFirst <= currentOperandSecond; break; case NonTermType.MoreExpression: _currentOperandTempResult = currentOperandFirst > currentOperandSecond; break; case NonTermType.MoreEqExpression: _currentOperandTempResult = currentOperandFirst >= currentOperandSecond; break; case NonTermType.LogicalAndExpression: _currentOperandTempResult = currentOperandFirst && currentOperandSecond; break; case NonTermType.LogicalOrExpression: _currentOperandTempResult = currentOperandFirst || currentOperandSecond; break; case NonTermType.PlusExpression: _currentOperandTempResult = currentOperandFirst + currentOperandSecond; break; case NonTermType.MinusExpression: _currentOperandTempResult = currentOperandFirst - currentOperandSecond; break; case NonTermType.MultiplyExpression: _currentOperandTempResult = currentOperandFirst * currentOperandSecond; break; case NonTermType.DivisionExpression: _currentOperandTempResult = currentOperandFirst / currentOperandSecond; break; } } catch (InvalidOperationException ex) { throw new CodeGenerationException(MessagesHelper.InvalidOperationEx, nonTerm.ToStringInfo(), ex); } catch (InvalidCastException ex) { throw new CodeGenerationException(MessagesHelper.TypeMismatchEx, nonTerm.ToStringInfo(), ex); } }