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);
        }
Beispiel #3
0
        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));
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        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;
        }
Beispiel #7
0
        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);
                }
            }
        }
Beispiel #8
0
        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);
            }
        }
Beispiel #9
0
        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);
 }
Beispiel #12
0
        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);
        }
Beispiel #13
0
 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);
        }
Beispiel #15
0
        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;
            }
        }
Beispiel #16
0
 public virtual Constant Parse(Token input, NmProgram program)
 {
     return(null);
 }
Beispiel #17
0
        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);
        }