Esempio n. 1
0
        public override void Generate(ILProcessor il, SemanticEnvironment environment)
        {
            var list = new ExpList();

            if (ExpList is ExpList expList)
            {
                list = expList;
            }

            foreach (var node in list.Nodes)
            {
                node.Generate(il, environment);
            }

            PostfixNode.Generate(il, environment);

            if (PostfixNode is Id id) // Push null to stack if function return void.
            {
                var type = (environment.GetSymbol(id.IdName) as FuncSymbol).Type as FuncType;
                if (type.ReturnType.SymbolTypeKind == SymbolTypeKind.VOID)
                {
                    il.Emit(OpCodes.Ldnull);
                }
            }
            else
            {
                throw new NotImplementedException();
            }
        }
Esempio n. 2
0
        public override void Generate(ref Assembly assembly, ref SemanticEnvironment environment)
        {
            var funcType         = Type as FuncType;
            var retType          = funcType.ReturnType;
            var methodDefinition = new MethodDefinition(Id, MethodAttributes.Public | MethodAttributes.Static,
                                                        retType.ToTypeReference(ref assembly))
            {
                Body = { InitLocals = true }
            };

            Definition = methodDefinition;
            var mainModule         = assembly.AssemblyDefinition.MainModule;
            var writeLineInfo      = typeof(Console).GetMethod("Write", new Type[] { typeof(string), typeof(object) });
            var writeLineReference = mainModule.ImportReference(writeLineInfo);
            var il = methodDefinition.Body.GetILProcessor();

            foreach (var argument in funcType.GetArguments())
            {
                var parameterDefinition = new ParameterDefinition(argument.Id, ParameterAttributes.None,
                                                                  argument.Type.ToTypeReference(ref assembly));
                ((VarSymbol)argument).ParameterDefinition = parameterDefinition;
                methodDefinition.Parameters.Add(parameterDefinition);
            }

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Box, assembly.AssemblyDefinition.MainModule.TypeSystem.Int64);
            il.Emit(OpCodes.Call, writeLineReference);
            il.Emit(OpCodes.Ret);

            assembly.AddMethod(methodDefinition);
        }
Esempio n. 3
0
 public override void CheckSemantic(ref SemanticEnvironment environment)
 {
     foreach (var node in Nodes)
     {
         node.CheckSemantic(ref environment);
     }
 }
Esempio n. 4
0
        public override void Generate(ILProcessor il, SemanticEnvironment environment)
        {
            var symbol = environment.GetSymbol(IdName);

            switch (symbol)
            {
            case VarSymbol varSymbol:
                switch (varSymbol.VariableType)
                {
                case VarSymbol.VarType.VARIABLE:
                    il.Emit(OpCodes.Ldloc, varSymbol.VariableDefinition);
                    break;

                case VarSymbol.VarType.PARAMETER:
                    il.Emit(OpCodes.Ldarg, varSymbol.ParameterDefinition);
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
                break;

            case FuncSymbol funcSymbol:
                il.Emit(OpCodes.Call, funcSymbol.Definition);
                break;
            }
        }
Esempio n. 5
0
 public override void Generate(ILProcessor il, SemanticEnvironment environment)
 {
     if (!(ExpNode is ExpNode expNode))
     {
         return;
     }
     expNode.Generate(il, environment);
     il.Emit(OpCodes.Pop);
 }
Esempio n. 6
0
        public override void CheckSemantic(ref SemanticEnvironment environment)
        {
            var type = DeclSpecs.NodeToType(DeclSpec, ref environment);

            foreach (var node in InitDeclaratorList.Nodes)
            {
                environment.GetCurrentSnapshot()
                .PushSymbol((node as InitDeclarator).ParseSymbolByType(type, ref environment));
            }
        }
Esempio n. 7
0
 public override void Generate(ILProcessor il, SemanticEnvironment environment)
 {
     switch (UnaryOperator.Operator.Type)
     {
     case OperatorType.MULT:
         UnaryExpNode.Generate(il, environment);
         if (UnaryExpNode.GetType(ref environment) is PointerType {
             PointerToType : StructType structType
         })
         {
             il.Emit(OpCodes.Ldobj, structType.TypeReference);
         }
Esempio n. 8
0
        public Symbol ParseSymbol(SymbolType type, ref SemanticEnvironment environment)
        {
            if (Pointer is Pointer pointer)
            {
                type = pointer.ParseType(type, ref environment);
            }

            return(DirectDeclarator switch
            {
                Id id => new VarSymbol(id.IdName, type, id.StartNodePosition),
                Declarator declarator => declarator.ParseSymbol(type, ref environment),
                GenericDeclaration genericDeclaration => genericDeclaration.ParseSymbol(type, ref environment),
                _ => throw new ArgumentException()
            });
Esempio n. 9
0
        public override Symbol ParseSymbolByType(SymbolType type, ref SemanticEnvironment environment)
        {
            var symbol    = Declarator.ParseSymbol(type, ref environment) as VarSymbol;
            var valueType = Initializer.GetType(ref environment);

            symbol.Initializer = Initializer;
            if (symbol.Type.Equals(valueType))
            {
                return(symbol);
            }

            throw new SemanticException(
                      $"trying to assign to variable of type {symbol.Type.GetShortName()} value with type " +
                      $"{valueType.GetShortName()}",
                      Initializer.StartNodePosition);
        }
Esempio n. 10
0
        public override void Generate(ILProcessor il, SemanticEnvironment environment)
        {
            PostfixNode.Generate(il, environment);
            StructType structType;

            if (TypeOfCall == CallType.VALUE)
            {
                structType = PostfixNode.GetType(ref environment) as StructType;
            }
            else
            {
                structType = (PostfixNode.GetType(ref environment) as PointerType).PointerToType as StructType;
            }
            var id     = Id as Id;
            var member = structType.Members.Get(id.IdName) as VarSymbol;

            il.Emit(OpCodes.Ldfld, member.FieldDefinition);
        }
Esempio n. 11
0
        public override void Generate(ILProcessor il, SemanticEnvironment environment)
        {
            switch (Token.TokenType)
            {
            case TokenType.INT:
                il.Emit(OpCodes.Ldc_I8, (long)Token.Value);
                break;

            case TokenType.FLOAT:
                il.Emit(OpCodes.Ldc_R8, (double)Token.Value);
                break;

            case TokenType.CHAR:
                il.Emit(OpCodes.Ldc_I8, (long)Token.Value);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Esempio n. 12
0
 public override void Generate(ILProcessor il, SemanticEnvironment environment) =>
 il.Emit(OpCodes.Ldstr, Utils.ConvertCFormatToCsFormat(Str));
Esempio n. 13
0
 public virtual Symbol ParseSymbolByType(SymbolType type, ref SemanticEnvironment environment) =>
 Declarator.ParseSymbol(type, ref environment);
Esempio n. 14
0
        private static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                // TODO Display help info.
                return;
            }

            try
            {
                var tokenizer = new Tokenizer.Tokenizer(args[0]);
                if (args.Contains("-l"))
                {
                    var token = tokenizer.Get();
                    while (token.TokenType != TokenType.EOF)
                    {
                        Console.WriteLine(token);
                        token = tokenizer.Get();
                    }
                }

                if (args.Contains("-p"))
                {
                    var parser = new SyntaxParser(tokenizer, SyntaxParserType.EXP);
                    Console.WriteLine(parser.SyntaxTree);
                }

                if (args.Contains("-ps"))
                {
                    var parser = new SyntaxParser(tokenizer, SyntaxParserType.STAT);
                    Console.WriteLine(parser.SyntaxTree);
                }

                if (args.Contains("-pu"))
                {
                    var parser = new SyntaxParser(tokenizer, SyntaxParserType.UNIT);
                    Console.WriteLine(parser.SyntaxTree);
                }

                if (args.Contains("-s"))
                {
                    var parser      = new SyntaxParser(tokenizer, SyntaxParserType.UNIT);
                    var syntaxTree  = parser.SyntaxTree;
                    var environment = new SemanticEnvironment();
                    syntaxTree.CheckSemantic(ref environment);
                    Console.WriteLine(syntaxTree);
                    Console.WriteLine(environment.PopSnapshot());
                }

                if (args.Contains("-net"))
                {
                    var parser            = new SyntaxParser(tokenizer, SyntaxParserType.UNIT);
                    var syntaxTree        = parser.SyntaxTree;
                    var parserEnvironment = new SemanticEnvironment();
                    syntaxTree.CheckSemantic(ref parserEnvironment);

                    var fileName             = new FileInfo(args[0]);
                    var assembly             = new Assembly(fileName.Name.Replace(".c", ""));
                    var unitSnapshot         = parserEnvironment.PopSnapshot();
                    var generatorEnvironment = new SemanticEnvironment();
                    generatorEnvironment.PushSnapshot(unitSnapshot);

                    foreach (var structType in unitSnapshot.StructTable.GetData())
                    {
                        structType.Value.Generate(ref assembly, ref generatorEnvironment);
                    }

                    foreach (var symbol in unitSnapshot.SymbolTable.GetData())
                    {
                        symbol.Value.Generate(ref assembly, ref generatorEnvironment);
                    }

                    assembly.Save(fileName.DirectoryName + '\\');
                }
            }
            catch (FileNotFoundException e)
            {
                Console.WriteLine($"error: file {e.FileName} not found");
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }
Esempio n. 15
0
 public override Symbol ParseSymbolByType(SymbolType type, ref SemanticEnvironment environment) =>
 throw new NotImplementedException("initializing by InitializerList is not supported");
Esempio n. 16
0
        public static SymbolType NodeToType(Node declSpecs, ref SemanticEnvironment environment)
        {
            if (!(declSpecs is NullStat) && !(declSpecs is DeclSpecs))
            {
                throw new ArgumentException($"expected DeclSpecs, actual {declSpecs.GetType()}");
            }

            var storageClassSpecExist = false;
            var typeSpecExist         = false;

            var symbolType = new SymbolType(false, false, SymbolTypeKind.INT);

            while (!(declSpecs is NullStat))
            {
                var spec = (declSpecs as DeclSpecs).Spec;
                if (spec is StorageClassSpec storageClassSpec)
                {
                    if (storageClassSpecExist)
                    {
                        throw new SemanticException("multiple storage classes in declaration specifiers",
                                                    storageClassSpec.Token.Position);
                    }
                    storageClassSpecExist = true;
                }

                if (spec is TypeSpec typeSpec)
                {
                    if (typeSpecExist)
                    {
                        throw new SemanticException("two or more data types in declaration specifiers",
                                                    typeSpec.TokenType.Position);
                    }
                    typeSpecExist = true;

                    switch (typeSpec.TokenType.Type)
                    {
                    case KeywordType.INT:
                        symbolType.SymbolTypeKind = SymbolTypeKind.INT;
                        break;

                    case KeywordType.FLOAT:
                        symbolType.SymbolTypeKind = SymbolTypeKind.FLOAT;
                        break;

                    case KeywordType.VOID:
                        symbolType.SymbolTypeKind = SymbolTypeKind.VOID;
                        break;

                    default:
                        throw new SemanticException("this data type is not supported",
                                                    typeSpec.TokenType.Position);
                    }
                }

                if (spec is StructSpec structSpec)
                {
                    if (typeSpecExist)
                    {
                        throw new SemanticException("two or more data types in declaration specifiers",
                                                    structSpec.Id.StartNodePosition);
                    }
                    typeSpecExist = true;
                    symbolType    = structSpec.ParseType(ref environment);
                }

                if (spec is TypeQualifier typeQualifier)
                {
                    switch (typeQualifier.Token.Type)
                    {
                    case KeywordType.CONST:
                        symbolType.IsConst = true;
                        break;

                    case KeywordType.VOLATILE:
                        symbolType.IsVolatile = true;
                        break;
                    }
                }

                declSpecs = (declSpecs as DeclSpecs).NextSpec;
            }

            return(symbolType);
        }
Esempio n. 17
0
 public override void Generate(ILProcessor il, SemanticEnvironment environment)
 {
     Left.Store(il, environment, Right);
     Left.Generate(il, environment);
 }
Esempio n. 18
0
 public virtual void CheckSemantic(ref SemanticEnvironment environment) =>
 throw new NotImplementedException();
Esempio n. 19
0
 public new abstract SymbolType GetType(ref SemanticEnvironment environment);