protected ObjectDef EmitIfBranch(ITree expressionNode) { // Возможна оптимизация (Brtrue, Brfalse_S). var checkObjectDef = EmitExpression(expressionNode.GetChild(0)); checkObjectDef.Load(); checkObjectDef.Remove(); if (checkObjectDef.Type != BoolType) { CompilerErrors.Add(new IfOperatorError(checkObjectDef.Type, CompilerErrors.Count, expressionNode.GetChild(0).Line, expressionNode.GetChild(0).CharPositionInLine)); } var exitLabel = CurrentILGenerator_.DefineLabel(); var elseLabel = CurrentILGenerator_.DefineLabel(); CurrentILGenerator_.Emit(OpCodes.Brfalse, elseLabel); var ifObjectDef = EmitExpression(expressionNode.GetChild(1)); ifObjectDef.Load(); ifObjectDef.Remove(); CurrentILGenerator_.Emit(OpCodes.Br, exitLabel); CurrentILGenerator_.MarkLabel(elseLabel); var elseObjectDef = EmitExpression(expressionNode.GetChild(2)); elseObjectDef.Load(); elseObjectDef.Remove(); CurrentILGenerator_.MarkLabel(exitLabel); return(LocalObjectDef.AllocateLocal(GetMostNearestAncestor(ifObjectDef.Type, elseObjectDef.Type))); }
protected ObjectDef EmitLetOperation(ITree expressionNode) { List <ObjectDef> localObjectDefs = new List <ObjectDef>(); for (int i = 0; i < expressionNode.GetChild(0).ChildCount; i++) { var localOrFieldInitNode = expressionNode.GetChild(0).GetChild(i); var type = GetType(localOrFieldInitNode.GetChild(1).Text); ObjectDef localReturnObjectDef; if (localOrFieldInitNode.ChildCount == 3) { localReturnObjectDef = EmitExpression(localOrFieldInitNode.GetChild(2)); } else { localReturnObjectDef = EmitDefaultValue(type); } localReturnObjectDef.Load(); //localReturnObjectDef.Remove(); var localObjectDef = LocalObjectDef.AllocateLocal(type, localOrFieldInitNode.GetChild(0).Text); localObjectDefs.Add(localObjectDef); } var returnObjectDef = EmitExpression(expressionNode.GetChild(1)); foreach (var localObjectDef in localObjectDefs) { localObjectDef.Free(); } return(returnObjectDef); }
protected ObjectDef EmitNegOperation(ITree expressionNode) { var returnObject = EmitExpression(expressionNode.GetChild(0)); if (IsStaticType(returnObject.Type)) { CompilerErrors.Add(new NegOperationError(returnObject.Type, CompilerErrors.Count, expressionNode.GetChild(0).Line, expressionNode.GetChild(0).CharPositionInLine)); } else { returnObject.Load(); CurrentILGenerator_.Emit(OpCodes.Not); returnObject.Load(); } return(LocalObjectDef.AllocateLocal(IntegerType)); }
protected ObjectDef EmitIsVoidChecking(ITree expressionNode) { var returnObject = EmitExpression(expressionNode.GetChild(0)); if (IsStaticType(returnObject.Type)) { CompilerErrors.Add(new IsVoidCheckingError(CompilerErrors.Count, expressionNode.GetChild(0).Line, expressionNode.GetChild(0).CharPositionInLine)); } else { returnObject.Load(); CurrentILGenerator_.Emit(OpCodes.Ldnull); CurrentILGenerator_.Emit(OpCodes.Ceq); returnObject.Remove(); } return(LocalObjectDef.AllocateLocal(BoolType)); }
protected ObjectDef EmitComparsionOperation(ITree expressionNode) { var returnObject2 = EmitExpression(expressionNode.GetChild(1)); var returnObject1 = EmitExpression(expressionNode.GetChild(0)); if (returnObject1.Type != IntegerType || returnObject1.Type != returnObject2.Type) { CompilerErrors.Add(new ComparsionOperatorError(returnObject1.Type, returnObject2.Type, CompilerErrors.Count, expressionNode.Line, expressionNode.GetChild(0).CharPositionInLine, expressionNode.GetChild(1).CharPositionInLine)); } else { returnObject1.Load(); returnObject2.Load(); if (expressionNode.Type == CoolGrammarLexer.LT) { CurrentILGenerator_.Emit(OpCodes.Clt); } else if (expressionNode.Type == CoolGrammarLexer.LE) { CurrentILGenerator_.Emit(OpCodes.Cgt); CurrentILGenerator_.Emit(OpCodes.Ldc_I4_0); CurrentILGenerator_.Emit(OpCodes.Ceq); } else if (expressionNode.Type == CoolGrammarLexer.GT) { CurrentILGenerator_.Emit(OpCodes.Cgt); } else if (expressionNode.Type == CoolGrammarLexer.GE) { CurrentILGenerator_.Emit(OpCodes.Clt); CurrentILGenerator_.Emit(OpCodes.Ldc_I4_0); CurrentILGenerator_.Emit(OpCodes.Ceq); } returnObject1.Remove(); returnObject2.Remove(); } return(LocalObjectDef.AllocateLocal(BoolType)); }
protected ObjectDef EmitNotOperation(ITree expressionNode) { var returnObject = EmitExpression(expressionNode.GetChild(0)); if (returnObject.Type != BoolType) { CompilerErrors.Add(new NotOperationError(returnObject.Type, CompilerErrors.Count, expressionNode.GetChild(0).Line, expressionNode.GetChild(0).CharPositionInLine)); } else { returnObject.Load(); CurrentILGenerator_.Emit(OpCodes.Ldc_I4_0); CurrentILGenerator_.Emit(OpCodes.Ceq); returnObject.Remove(); } return(LocalObjectDef.AllocateLocal(BoolType)); }
protected ObjectDef EmitArithmeticOperation(ITree expressionNode) { var returnObject1 = EmitExpression(expressionNode.GetChild(0)); var returnObject2 = EmitExpression(expressionNode.GetChild(1)); if (returnObject1.Type != IntegerType || returnObject1.Type != returnObject2.Type) { CompilerErrors.Add(new ArithmeticOperatorError( returnObject1.Type, returnObject2.Type, CompilerErrors.Count, expressionNode.Line, expressionNode.GetChild(1).CharPositionInLine, expressionNode.GetChild(0).CharPositionInLine)); } else { returnObject1.Load(); returnObject2.Load(); if (expressionNode.Type == CoolGrammarLexer.PLUS) { CurrentILGenerator_.Emit(OpCodes.Add); } else if (expressionNode.Type == CoolGrammarLexer.MINUS) { CurrentILGenerator_.Emit(OpCodes.Sub); } else if (expressionNode.Type == CoolGrammarLexer.MULT) { CurrentILGenerator_.Emit(OpCodes.Mul); } else if (expressionNode.Type == CoolGrammarLexer.DIV) { CurrentILGenerator_.Emit(OpCodes.Div); } returnObject1.Remove(); returnObject2.Remove(); } return(LocalObjectDef.AllocateLocal(IntegerType)); }
protected ObjectDef EmitInvoke(ITree invokeExpressionNode, ITree atSignNode, ITree functionNode, ITree argsExpressionNode) { var functionName = functionNode.Text; ObjectDef invokeObjectDef; MethodBuilder methodBuilder; string invokeObjectName; if (invokeExpressionNode != null) { invokeObjectDef = EmitExpression(invokeExpressionNode); invokeObjectName = invokeObjectDef.Type.Name; } else { invokeObjectDef = new ArgObjectDef(CurrentTypeBuilder_, 0, "this"); invokeObjectName = CurrentTypeBuilder_.Name; } ObjectDef result; if (!Functions_.ContainsKey(invokeObjectName) || !Functions_[invokeObjectName].ContainsKey(functionName)) { CompilerErrors.Add(new UndefinedFunctionError(functionName, invokeObjectName, CompilerErrors.Count, functionNode.Line, functionNode.CharPositionInLine)); result = LocalObjectDef.AllocateLocal(typeof(object)); } else { methodBuilder = Functions_[invokeObjectName][functionName].MethodBuilder; var args = new List <ObjectDef>(); args.Add(invokeObjectDef); if (argsExpressionNode != null) { for (int i = 0; i < argsExpressionNode.ChildCount; i++) { var objectDef = EmitExpression(argsExpressionNode.GetChild(i)); args.Add(objectDef); } List <ArgObjectDef> args2 = new List <ArgObjectDef>(); foreach (var arg in Functions_[invokeObjectDef.Type.Name][functionName].Args) { args2.Add(arg.Value); } if (!CheckTypes(args, args2)) { var args2types = new List <Type>(); foreach (var arg in args2) { args2types.Add(arg.Type); } CompilerErrors.Add(new FunctionArgumentsError(functionName, args2types, CompilerErrors.Count, functionNode.Line, functionNode.CharPositionInLine)); } } foreach (var arg in args) { arg.Load(); } if (invokeExpressionNode == null) { CurrentILGenerator_.Emit(OpCodes.Call, methodBuilder); } else { CurrentILGenerator_.Emit(OpCodes.Callvirt, methodBuilder); } foreach (var arg in args) { arg.Remove(); } invokeObjectDef.Remove(); if (functionNode.Parent.Parent.Type == CoolGrammarLexer.Exprs && functionNode.Parent.ChildIndex != functionNode.Parent.Parent.ChildCount - 1) { CurrentILGenerator_.Emit(OpCodes.Pop); result = new ValueObjectDef(Functions_[invokeObjectDef.Type.Name][functionName].MethodBuilder.ReturnType, null); } else { result = LocalObjectDef.AllocateLocal(Functions_[invokeObjectDef.Type.Name][functionName].MethodBuilder.ReturnType); } } return(result); }