Example #1
0
        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)));
        }
Example #2
0
        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);
        }
Example #3
0
        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));
        }
Example #4
0
        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));
        }
Example #5
0
        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));
        }
Example #6
0
        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));
        }
Example #7
0
        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));
        }
Example #8
0
        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);
        }