コード例 #1
0
        public override void CheckSemantics(TigerScope scope, Report report)
        {
            ContainingScope = scope;

            //Check children
            IdNode.CheckSemantics(scope, report);
            ExpressionNode.CheckSemantics(scope, report);

            if (!IdNode.IsOK || !ExpressionNode.IsOK)
            {
                return;
            }

            //Check use of variable name
            if (!scope.VariableNameAvailable(IdNode.Name))
            {
                report.AddError(SemanticErrors.VariableNameAlreadyInUse(IdNode, IdNode.Name));
                return;
            }

            //Check children types
            if (TigerType.AreOfSameType(ExpressionNode.TigerType, TigerType.Nil) || TigerType.AreOfSameType(ExpressionNode.TigerType, TigerType.Void))

            {
                report.AddError(SemanticErrors.InvalidImplicitVariableDeclaration(ExpressionNode, ExpressionNode.TigerType));
                return;
            }
            //Add variable to scope
            VariableInfo = scope.DefineVariable(IdNode.Name, ExpressionNode.TigerType, scope);

            IsOK = true;
        }
コード例 #2
0
        public void CheckBodySemantics(TigerScope scope, Report report)
        {
            //If CheckSemantics failed (FunctionInfo was not created) return
            if (!IsOK)
            {
                return;
            }

            IsOK = false;

            //Create function scope
            FunctionBodyNode.CheckSemantics(FunctionScope, report);

            if (!FunctionBodyNode.IsOK)
            {
                return;
            }

            IsOK = true;

            if (ReturnTypeNode != null && !ReturnTypeNode.TigerType.Assignable(FunctionBodyNode.TigerType))
            {
                report.AddError(SemanticErrors.IncompatibleFunctionReturnTypeBody(FunctionBodyNode, ReturnTypeNode.TigerType, FunctionBodyNode.TigerType));
            }
            else if (ReturnTypeNode == null && !TigerType.AreOfSameType(TigerType.Void, FunctionBodyNode.TigerType))
            {
                report.AddError(SemanticErrors.IncompatibleFunctionReturnTypeBody(FunctionBodyNode, TigerType.Void, FunctionBodyNode.TigerType));
            }
        }
コード例 #3
0
        public override void GenerateCode(ILGenerator generator)
        {
            var saveFields = ContainingScope.FieldsToFunctionDeclaration(FunctionInfo);

            foreach (var fieldBuilder in saveFields)
            {
                generator.Emit(OpCodes.Ldsfld, fieldBuilder);
            }
            foreach (var expressionNode in Arguments)
            {
                expressionNode.GenerateCode(generator);
            }
            var method = FunctionInfo.MethodBuilder;

            generator.Emit(OpCodes.Call, method);
            LocalBuilder methodResult = null;

            if (!TigerType.AreOfSameType(FunctionInfo.ReturnType, TigerType.Void))
            {
                methodResult = generator.DeclareLocal(FunctionInfo.ReturnType.Type);
                generator.Emit(OpCodes.Stloc, methodResult);
            }
            foreach (var t in saveFields)
            {
                generator.Emit(OpCodes.Stsfld, t);
            }
            if (!TigerType.AreOfSameType(FunctionInfo.ReturnType, TigerType.Void))
            {
                generator.Emit(OpCodes.Ldloc, methodResult);
            }
        }
コード例 #4
0
        public override void GenerateCode(ILGenerator generator)
        {
            if (InstructionNodes.Length == 0)
            {
                return;
            }

            for (var i = 0; i < InstructionNodes.Length - 1; i++)
            {
                InstructionNodes[i].GenerateCode(generator);
                if (!TigerType.AreOfSameType(InstructionNodes[i].TigerType, TigerType.Void))
                {
                    generator.Emit(OpCodes.Pop);
                }
            }

            InstructionNodes.Last().GenerateCode(generator);
        }
コード例 #5
0
        public override void CheckSemantics(TigerScope scope, Report report)
        {
            ContainingScope = scope;

            //Check children
            LeftOperandNode.CheckSemantics(scope, report);
            RightOperandNode.CheckSemantics(scope, report);
            if (!LeftOperandNode.IsOK || !RightOperandNode.IsOK)
            {
                return;
            }

            TigerType = TigerType.Int;

            //Check children types
            if (!TigerType.AreCompatible(LeftOperandNode.TigerType, RightOperandNode.TigerType) ||
                (TigerType.AreOfSameType(LeftOperandNode.TigerType, TigerType.Nil) && TigerType.AreOfSameType(RightOperandNode.TigerType, TigerType.Nil)))
            {
                report.AddError(SemanticErrors.InvalidIdentityComparison(this, LeftOperandNode.TigerType,
                                                                         RightOperandNode.TigerType));
            }
        }
コード例 #6
0
        private static int Main(string[] args)
        {
            Console.WriteLine("Tiger Compiler version 1.0");
            Console.WriteLine(@"Copyright (C) 2015-2016 Laila González Fernández & Mario César Muñiz Jiménez");

            //Creating report, parser and lexer
            var arg        = args[0];
            var report     = new Report();
            var characters = new ANTLRFileStream(arg);
            var lexer      = new TigerLexer(report, characters);
            var tokens     = new CommonTokenStream(lexer);
            var parser     = new TigerParser(report, tokens)
            {
                TraceDestination = Console.Out,
                TreeAdaptor      = new TreeAdaptor()
            };

            //Syntactic analysis
            var ret = (ProgramNode)parser.program().Tree;

            if (!report.IsOk)
            {
                foreach (var message in report)
                {
                    Console.WriteLine($"({message.Line}, {message.Column}): {message.Text}");
                }
                return(1);
            }

            //Preparing assembly
            var name          = Path.GetFileNameWithoutExtension(arg);
            var filename      = name + ".exe";
            var assemblyName  = new AssemblyName(name);
            var assembly      = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
            var moduleBuilder = assembly.DefineDynamicModule(name, filename);
            var programType   = moduleBuilder.DefineType(name + ".Program", TypeAttributes.Public);
            var mainMethod    = programType.DefineMethod("Main", MethodAttributes.Static | MethodAttributes.Public, typeof(void), Type.EmptyTypes);
            var generator     = mainMethod.GetILGenerator();

            assembly.SetEntryPoint(mainMethod);

            ProgramNode.Module  = moduleBuilder;
            ProgramNode.Program = programType;

            //Semantic analysis
            ret.CheckSemantics(new TigerScope(programType), report);

            if (!report.IsOk)
            {
                foreach (var message in report)
                {
                    Console.WriteLine($"({message.Line}, {message.Column}): {message.Text}");
                }
                return(1);
            }

            generator.BeginExceptionBlock();
            //Code generation
            ret.GenerateCode(generator);

            if (!TigerType.AreOfSameType(ret.TigerType, TigerType.Void))
            {
                generator.Emit(OpCodes.Pop);
            }

            generator.BeginCatchBlock(typeof(Exception));
            generator.BeginScope();
            LocalBuilder exception           = generator.DeclareLocal(typeof(Exception));
            MethodInfo   writeLineSO         = typeof(TextWriter).GetMethod("WriteLine", new Type[] { typeof(string), typeof(object) });
            MethodInfo   writeLineS          = typeof(TextWriter).GetMethod("WriteLine", new Type[] { typeof(string) });
            MethodInfo   standardErrorOutput = typeof(Console).GetProperty("Error").GetGetMethod();

            generator.Emit(OpCodes.Stloc, exception);
            generator.Emit(OpCodes.Call, standardErrorOutput);
            generator.Emit(OpCodes.Ldstr, "Exception of type '{0}' was thrown.");
            generator.Emit(OpCodes.Ldloc, exception);
            generator.Emit(OpCodes.Callvirt, typeof(Exception).GetMethod("GetType", Type.EmptyTypes));
            generator.Emit(OpCodes.Callvirt, typeof(Type).GetProperty("Name").GetGetMethod());
            generator.Emit(OpCodes.Callvirt, writeLineSO);

            generator.Emit(OpCodes.Call, standardErrorOutput);
            generator.Emit(OpCodes.Ldloc, exception);
            generator.Emit(OpCodes.Callvirt, typeof(Exception).GetProperty("Message").GetGetMethod());
            generator.Emit(OpCodes.Callvirt, writeLineS);

            generator.EndScope();

            generator.Emit(OpCodes.Ldc_I4_1);
            generator.Emit(OpCodes.Call, typeof(Environment).GetMethod("Exit"));

            generator.EndExceptionBlock();

            generator.Emit(OpCodes.Ret);
            programType.CreateType();
            assembly.Save(filename);

            return(0);
        }