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(); } }
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); }
public override void CheckSemantic(ref SemanticEnvironment environment) { foreach (var node in Nodes) { node.CheckSemantic(ref environment); } }
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; } }
public override void Generate(ILProcessor il, SemanticEnvironment environment) { if (!(ExpNode is ExpNode expNode)) { return; } expNode.Generate(il, environment); il.Emit(OpCodes.Pop); }
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)); } }
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); }
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() });
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); }
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); }
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(); } }
public override void Generate(ILProcessor il, SemanticEnvironment environment) => il.Emit(OpCodes.Ldstr, Utils.ConvertCFormatToCsFormat(Str));
public virtual Symbol ParseSymbolByType(SymbolType type, ref SemanticEnvironment environment) => Declarator.ParseSymbol(type, ref environment);
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); } }
public override Symbol ParseSymbolByType(SymbolType type, ref SemanticEnvironment environment) => throw new NotImplementedException("initializing by InitializerList is not supported");
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); }
public override void Generate(ILProcessor il, SemanticEnvironment environment) { Left.Store(il, environment, Right); Left.Generate(il, environment); }
public virtual void CheckSemantic(ref SemanticEnvironment environment) => throw new NotImplementedException();
public new abstract SymbolType GetType(ref SemanticEnvironment environment);