public override Constant Parse(Token input, NmProgram program) { var literal = GetLiteral(input.StringValue); var number = input.StringValue.Substring(0, input.StringValue.Length - literal.Length); return(new Constant(input, program, Convert.ToInt64(number, 8), literal)); }
public CompileError ToFunc(NmProgram program, out Function func) { CompileError error; Type returnType = null; List <FunctionParameter> parameters; func = null; if (ReturnType != null) { if ((error = ByteCode.Types.Type.GetType(program, ReturnType, out returnType)) != null) { return(error); } } if ((error = GetParameterList(program, out parameters)) != null) { return(error); } func = new Function(program, Name.StringValue, Modifier, returnType, Block.Scope, parameters, Block) { Token = Name }; return(null); }
public override Constant Parse(Token input, NmProgram program) { var literal = GetLiteral(input.StringValue); var number = input.StringValue.Substring(0, input.StringValue.Length - literal.Length); var str = number.ToLower().Split('b')[1]; return(new Constant(input, program, Convert.ToInt64(str, 2), literal)); }
public void Draw(object sender, OpenGLEventArgs args) { GL.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT); // Add gradient background. SetVerticalGradientBackground(GL, new ColorF(255, 146, 134, 188), new ColorF(1f, 0, 1, 0)); NmProgram.BindAll(GL); }
internal CompileError Parse(NmProgram program, Token token) { var source = NmSource.FromFile(FileName); source.ModuleNames = program.Source.ModuleNames; var newProgram = new NmProgram(source) { Verbose = program.Verbose, MeasureTime = false, IncludeDirectories = program.IncludeDirectories, ParentProgram = program }; if (program.Verbose) { Console.WriteLine("Compiling {0}", FileName); } CompileError error; if ((error = newProgram.Parse()) != null) { Console.WriteLine(error); return(new CompileError(CompileErrorType.InnerCompileException, token)); } if ((error = newProgram.Expand()) != null) { Console.WriteLine(error); return(new CompileError(CompileErrorType.InnerCompileException, token)); } if (!newProgram.IsModule) { return(new CompileError(CompileErrorType.NotModuleImport, token)); } Library = newProgram.Module.IsLibrary; //todo: library modules /*if (newProgram.Module.IsLibrary) * { * newProgram.ByteCode.SaveToFile(compilerBinaryName); * if (program.Verbose) * Console.WriteLine("File saved {0}", compilerBinaryName); * }*/ LinkedModule = newProgram.Module; return(null); }
public Function(NmProgram program, string name, FunctionModifier modifier, Type returnType, int scope, List <FunctionParameter> parameters = null, BlockLexeme rawLexeme = null) { Program = program; Name = name; Modifier = modifier; ReturnType = returnType; Parameters = parameters ?? new List <FunctionParameter>(); RawLexeme = rawLexeme; Scope = scope; IsVariadic = false; OriginalName = name; }
public static bool HasModuleInStack(string name, NmProgram parent) { while (true) { if (parent.Imports.Find(p => p.Name == name) != null) { return(true); } parent = parent.ParentProgram; if (parent == null) { return(false); } } }
public static CompileError GetType(NmProgram program, List <Token> tokens, out Type type) { type = null; if (tokens[tokens.Count - 1].Type == TokenType.SquareBracketClosed && tokens[tokens.Count - 2].Type == TokenType.SquareBracketOpen) { Type innerType; CompileError error; var counter = tokens.Count; var dimensions = 0; while (tokens[counter - 1].Type == TokenType.SquareBracketClosed && tokens[counter - 2].Type == TokenType.SquareBracketOpen) { counter -= 2; dimensions++; } if ((error = GetType(program, tokens.Take(tokens.Count - counter).ToList(), out innerType)) != null) { return(error); } type = new ArrayType(innerType, dimensions) { Program = program }; program.UsedTypes.Add(type); return(null); } else { type = BuiltInTypes.Get().Find(p => p.Name == tokens[0].StringValue)?.Type; if (type != null) { program.UsedTypes.Add(type); } type.Program = program; return(type == null ? new CompileError(CompileErrorType.UnknownTypeName, tokens[0]) : null); } }
public ByteCodeHeader(NmProgram program) { Program = program; var typeIndex = 0; var constIndex = 0; UsedConstants = program.Constants.Distinct().Select(p => new NumeratedConstant(constIndex++, p)).ToList(); program.UsedTypes.AddRange(UsedConstants.Select(p => p.Constant.ToProgramType())); UsedTypes = program.UsedTypes.Distinct().Select(p => new NumeratedType(typeIndex++, p)).ToList(); var varCounter = 0; program.ProgramGlobals.ForEach(p => p.Index = varCounter++); EmbeddedFunctions = new List <FunctionInstructions>(); }
private CompileError GetParameterList(NmProgram program, out List <FunctionParameter> parameters) { parameters = new List <FunctionParameter>(); CompileError error = null; foreach (var parameter in Parameters) { Type t; if ((error = ByteCode.Types.Type.GetType(program, parameter.Type, out t)) != null) { return(error); } parameters.Add(new FunctionParameter(t, parameter.Name.StringValue, parameter.Name)); } return(error); }
public ByteCode(NmProgram program) { Program = program; Header = new ByteCodeHeader(program); }
public static List <Token> Tokenize(string input, string fileName, NmProgram program) { var rawTokens = new List <RawToken>(); var currentToken = ""; var lastContains = false; var lineCount = 0; var charCount = 0; var collectingString = false; var collectingComment = false; var collectingMlComment = false; var lastSymbolIsEscapeSymbol = false; var slCommentIndex = 0; var mlCommentIndex = 0; var str = ""; foreach (var c in input) { if (!collectingComment) { if (c == SingleLineComment[slCommentIndex]) { slCommentIndex++; if (slCommentIndex == SingleLineComment.Length) { collectingComment = true; currentToken = ""; slCommentIndex = 0; collectingMlComment = false; } } else { slCommentIndex = 0; } if (c == MultilineCommentStart[mlCommentIndex]) { mlCommentIndex++; if (mlCommentIndex == MultilineCommentStart.Length) { collectingComment = true; currentToken = ""; mlCommentIndex = 0; collectingMlComment = true; } } else { mlCommentIndex = 0; } } if (collectingComment) { if (collectingMlComment) { if (c == MultilineCommentEnd[mlCommentIndex]) { mlCommentIndex++; if (mlCommentIndex == MultilineCommentEnd.Length) { collectingComment = false; mlCommentIndex = 0; } } else { mlCommentIndex = 0; } } else { if (c == '\n') { collectingComment = false; } } } else { if (c == '"') { if (collectingString) { if (!lastSymbolIsEscapeSymbol) { rawTokens.Add(new RawToken(str, lineCount, charCount)); rawTokens.Last().IsString = true; str = ""; collectingString = false; } else { str += '"'; } } else { if (lastContains) { rawTokens.Add(new RawToken(currentToken, lineCount, charCount)); currentToken = ""; } collectingString = true; } } else { if (collectingString) { str += c; } else if (_tokenSplitCharacters.Contains(c)) { rawTokens.Add(new RawToken(currentToken, lineCount, charCount)); currentToken = c.ToString(); lastContains = true; } else { if (lastContains) { rawTokens.Add(new RawToken(currentToken, lineCount, charCount)); currentToken = ""; } lastContains = false; currentToken += c; } } } lastSymbolIsEscapeSymbol = c == EscapeSymbolToken.EscapeSymbol; if (c == '\n') { lineCount++; charCount = 0; } else { charCount++; } } if (lastContains) { rawTokens.Add(new RawToken(currentToken, lineCount, charCount)); } rawTokens = rawTokens.FindAll(p => !string.IsNullOrWhiteSpace(p.Token.Trim())); var tokens = new List <Token>(); foreach (var token in rawTokens) { tokens.Add(new Token(token.Token, fileName, token.LineIndex, token.CharIndex, program, token.IsString)); } return(tokens); }
public static List <Token> Tokenize(string input, NmProgram program) { return(Tokenize(input, null, program)); }
public static CompileError Parse(NmProgram program, bool prototypesOnly) { CompileError error; var moduleLexeme = (ModuleLexeme)program.Lexemes.Find(p => p.Type == LexemeType.Module); if (moduleLexeme != null) { if (!IdentifierFormat.Match(moduleLexeme.ModuleName.StringValue)) { return(new CompileError(CompileErrorType.WrongModuleNameFormat, moduleLexeme.ModuleName)); } program.IsModule = true; program.Module = new Module(moduleLexeme.ModuleName.StringValue, program); } var attributes = new List <Attribute>(); var functionIndex = 0; foreach (var lex in program.Lexemes) { if (lex.Type == LexemeType.Function) { var lexeme = (FunctionLexeme)lex; if (!IdentifierFormat.Match(lexeme.Name.StringValue)) { return(new CompileError(CompileErrorType.WrongFunctionNameFormat, lexeme.Name)); } foreach (var parameter in lexeme.Parameters) { if (!IdentifierFormat.Match(parameter.Name.StringValue)) { return(new CompileError(CompileErrorType.WrongFunctionParameterNameFormat, parameter.Name)); } } if (program.Functions.Count(p => p.Name == lexeme.Name.StringValue) != 0) { return(new CompileError(CompileErrorType.MultipleFunctionsWithSameName, lexeme.Name)); } Function func; if ((error = lexeme.ToFunc(program, out func)) != null) { return(error); } func.Index = functionIndex++; program.Functions.Add(func); func.Attributes = attributes.ToList(); attributes.Clear(); if (!prototypesOnly) { if ((error = program.Functions.Last().ResolveLexemes()) != null) { return(error); } } if (lexeme.Modifier == FunctionModifier.Initialization) { if (program.Module.InitializationFunc != null) { return(new CompileError(CompileErrorType.MultipleInitializationFunctions, lexeme.Name)); } program.Module.InitializationFunc = program.Functions.Last(); } if (lexeme.Modifier == FunctionModifier.Finalization) { if (program.Module.FinalizationFunc != null) { return(new CompileError(CompileErrorType.MultipleFinalizationFunctions, lexeme.Name)); } program.Module.FinalizationFunc = program.Functions.Last(); } if (lexeme.Modifier == FunctionModifier.Entrypoint) { if (program.EntrypointFunction != null) { return(new CompileError(CompileErrorType.MultipleEntrypointFunctions, lexeme.Name)); } program.EntrypointFunction = program.Functions.Last(); } } else if (lex.Type == LexemeType.Var) { var lexeme = (VarLexeme)lex; if (!IdentifierFormat.Match(lexeme.VarName.StringValue)) { return(new CompileError(CompileErrorType.WrongIdentifierFormat, lexeme.VarName)); } if (program.ProgramGlobals.Find(p => p.Name == lexeme.VarName.StringValue) != null) { return(new CompileError(CompileErrorType.VariableRedeclaration, lexeme.VarName)); } Type t; if ((error = Type.GetType(program, lexeme.TypeTokens, out t)) != null) { return(error); } program.ProgramGlobals.Add(new Variable(t, lexeme.VarName.StringValue, -1, lexeme.VarName, -1, VariableType.Variable)); } else if (lex.Type == LexemeType.Import) { var importName = (lex as ImportLexeme).ImportName.StringValue; var matchedFile = program.Source.ModuleNames.Find(p => new FileInfo(p).Name == importName + ".nmm"); if (matchedFile == null) { return(new CompileError(CompileErrorType.UnknownModuleName, lex.Tokens?[0])); } Import import; if ((error = Import.CreateImport(out import, importName, matchedFile, program, lex.Tokens[0])) != null) { return(error); } program.Imports.Add(import); if ((error = import.Parse(program, lex.Tokens[0])) != null) { return(error); } } else if (lex.Type == LexemeType.Module) { program.IsModule = true; program.Module = new Module((lex as ModuleLexeme).ModuleName.StringValue, program) { IsLibrary = (lex as ModuleLexeme).IsLibrary }; } else if (lex.Type == LexemeType.Attribute) { Attribute attribute; if ((error = Attribute.CreateAttribute(lex.Tokens, out attribute)) != null) { return(error); } attributes.Add(attribute); } else { return(new CompileError(CompileErrorType.UnexpectedLexeme, lex.Tokens?[0])); } } if (program.IsModule) { if (program.Module.InitializationFunc == null) { return(new CompileError(CompileErrorType.NoInitializationFunction, new Token(program.Source.FileName))); } if (program.Module.FinalizationFunc == null) { return(new CompileError(CompileErrorType.NoFinalizationFunction, new Token(program.Source.FileName))); } if (program.EntrypointFunction != null) { return(new CompileError(CompileErrorType.ModuleWithEntrypointFunction, new Token(program.Source.FileName))); } } else { if (program.EntrypointFunction == null) { return(new CompileError(CompileErrorType.NoEntrypointFunction, new Token(program.Source.FileName))); } } return(null); }
public Token(string str, string fileName, int lineIndex, int lineOffset, NmProgram program, bool isString = false) { FileName = fileName; LineIndex = lineIndex; LineOffset = lineOffset; StringValue = str; if (!isString) { if (!TokenDict.TryGetValue(str, out Type)) { if (LineIndex == -1) { Type = TokenType.Identifier; return; } bool found = false; foreach (var constantFormat in ConstantFormats) { if (constantFormat.Verify(StringValue)) { Constant = constantFormat.Parse(this, program); if (!constantFormat.VerifyBounds(Constant)) { throw new CompileException(CompileErrorType.OutOfBoundsConstant, this); } Type = Constant.ToTokenType(); found = true; break; } } if (!found) { if (IdentifierFormat.Match(StringValue)) { Type = TokenType.Identifier; } else { throw new CompileException(CompileErrorType.WrongIdentifierFormat, this); } } } } else { var chars = new List <int>(); CompileErrorType error; if ((error = StringFormat.CheckEscapeSymbols(StringValue, out chars)) != 0) { throw new CompileException(error, this); } Constant = new Constant(this, program, chars); Type = TokenType.StringToken; } }
public virtual Constant Parse(Token input, NmProgram program) { return(null); }
public static CompileError CreateImport(out Import import, string name, string fileName, NmProgram program, Token token) { //todo: library modules /* * var compilerBinaryName = new FileInfo(fileName).Directory.FullName + Path.DirectorySeparatorChar + * new FileInfo(fileName).Name + "b"; * if (File.Exists(compilerBinaryName)) * { * //load needed data from binary * } */ import = null; if (HasModuleInStack(name, program)) { return(new CompileError(CompileErrorType.RecursiveImport, token)); } import = new Import { Name = name, FileName = fileName, }; return(null); }