コード例 #1
0
ファイル: Interpreter.cs プロジェクト: YohanSandun/Sigiri
        private RuntimeResult VisitLoadNode(LoadNode node, Context context)
        {
            string fname    = node.Token.Value.ToString();
            string fileName = "";

            if (File.Exists(Program.FileDirectory + fname + Program.LibraryExt))
            {
                fileName = Program.FileDirectory + fname + Program.LibraryExt;
            }
            else if (File.Exists(Program.FileDirectory + "libs\\" + fname + Program.LibraryExt))
            {
                fileName = Program.FileDirectory + "libs\\" + fname + Program.LibraryExt;
            }
            else if (File.Exists(Program.FileDirectory + fname + ".si"))
            {
                fileName = Program.FileDirectory + fname + ".si";
            }
            else if (File.Exists(Program.FileDirectory + "libs\\" + fname + ".si"))
            {
                fileName = Program.FileDirectory + "libs\\" + fname + ".si";
            }
            else if (File.Exists(Program.BaseDirectory + fname + Program.LibraryExt))
            {
                fileName = Program.BaseDirectory + fname + Program.LibraryExt;
            }
            else if (File.Exists(Program.BaseDirectory + "libs\\" + fname + Program.LibraryExt))
            {
                fileName = Program.BaseDirectory + fname + "libs\\" + Program.LibraryExt;
            }
            else if (File.Exists(Program.BaseDirectory + fname + ".si"))
            {
                fileName = Program.BaseDirectory + fname + ".si";
            }
            else if (File.Exists(Program.BaseDirectory + "libs\\" + fname + ".si"))
            {
                fileName = Program.BaseDirectory + "libs\\" + fname + ".si";
            }

            if (fileName.Equals(""))
            {
                return(new RuntimeResult(new RuntimeError(node.Token.Position, "Assembly '" + fname + "' not found!", context)));
            }

            if (fileName.EndsWith(Program.LibraryExt))
            {
                if (node.ClassToken != null)
                {
                    Values.AssemblyValue value = new Values.AssemblyValue();
                    value.SetPositionAndContext(node.Token.Position, context);
                    value.LoadAsm("libs\\" + fname + Program.LibraryExt, fname, node.ClassToken.Value.ToString());
                    context.AddSymbol(node.ClassToken.Value.ToString(), value);
                    return(new RuntimeResult(value));
                }
                else
                {
                    //todo fix this system
                    Assembly asm   = Assembly.LoadFile(fileName);
                    Type[]   types = asm.GetTypes();
                    for (int i = 0; i < types.Length; i++)
                    {
                        Console.WriteLine(types[i].Name);
                    }
                    for (int i = 0; i < types.Length; i++)
                    {
                        Values.AssemblyValue value = new Values.AssemblyValue();
                        value.Assembly = asm;
                        value.AsmType  = types[i];
                        FieldInfo[] fields = types[i].GetFields();
                        for (int j = 0; j < fields.Length; j++)
                        {
                            context.AddSymbol(fields[j].Name, Values.AssemblyValue.ParseValue(fields[j].GetValue(null), node.Token.Position, context));
                        }
                        value.SetPositionAndContext(node.Token.Position, context);
                        context.AddSymbol(types[i].Name, value);
                        if (i == types.Length - 1)
                        {
                            return(new RuntimeResult(value));
                        }
                    }
                }
            }
            else
            {
                string          code            = File.ReadAllText(fileName).Replace("\r\n", "\n");
                Tokenizer       tokenizer       = new Tokenizer(fname, code);
                TokenizerResult tokenizerResult = tokenizer.GenerateTokens();
                if (!tokenizerResult.HasError)
                {
                    Parser       parser       = new Parser(tokenizerResult.Tokens);
                    ParserResult parserResult = parser.Parse();
                    if (!parserResult.HasError)
                    {
                        Interpreter interpreter = new Interpreter();
                        return(interpreter.Visit(parserResult.Node, context));
                    }
                    else
                    {
                        return(new RuntimeResult(parserResult.Error));
                    }
                }
                else
                {
                    return(new RuntimeResult(tokenizerResult.Error));
                }
            }
            return(new RuntimeResult(new RuntimeError(node.Token.Position, "Library " + fname + " not found!", context)));
        }
コード例 #2
0
ファイル: Parser.cs プロジェクト: YohanSandun/Sigiri
        private ParserResult Atom(bool byPassDot = false)
        {
            Token token = currentToken;

            if (token.Type == TokenType.INTEGER || token.Type == TokenType.LONG || token.Type == TokenType.FLOAT || token.Type == TokenType.BIGINTEGER || token.Type == TokenType.COMPLEX || token.Type == TokenType.BYTE_ARRAY)
            {
                Advance();
                return(new ParserResult(new NumberNode(token)));
            }
            else if (token.Type == TokenType.STRING)
            {
                Advance();
                if (currentToken.Type == TokenType.LEFT_SQB)
                {
                    return(Subscript(new StringNode(token)));
                }
                return(new ParserResult(new StringNode(token)));
            }
            else if (token.Type == TokenType.IDENTIFIER)
            {
                Advance();
                if (currentToken.Type == TokenType.LEFT_SQB)
                {
                    return(Subscript(new VarAccessNode(token)));
                }
                if (!byPassDot && currentToken.Type == TokenType.DOT)
                {
                    return(Attribute(new VarAccessNode(token)));
                }
                if (currentToken.Type == TokenType.EQUALS)
                {
                    Advance();
                    ParserResult exprResult = Expr();
                    if (exprResult.HasError)
                    {
                        return(exprResult);
                    }
                    return(new ParserResult(new VarAssignNode(token, exprResult.Node)));
                }
                if (currentToken.Type == TokenType.COLON && Peek(2).Type == TokenType.EQUALS)
                {
                    Advance();
                    Token typeToken = currentToken; //todo check is it a valid keyword
                    Advance(2);
                    ParserResult exprResult = Expr();
                    if (exprResult.HasError)
                    {
                        return(exprResult);
                    }
                    return(new ParserResult(new VarAssignNode(token, exprResult.Node, typeToken)));
                }
                return(new ParserResult(new VarAccessNode(token)));
            }
            else if (token.Type == TokenType.LEFT_PAREN)
            {
                Advance();
                ParserResult exprResult = Expr();
                if (exprResult.HasError)
                {
                    return(exprResult);
                }
                if (currentToken.Type != TokenType.RIGHT_PAREN)
                {
                    return(new ParserResult(new InvalidSyntaxError(token.Position, "Expected ')'")));
                }
                Advance();
                return(exprResult);
            }
            else if (token.Type == TokenType.LEFT_SQB)
            {
                return(ListExpr());
            }
            else if (token.Type == TokenType.LEFT_BRA)
            {
                return(DictionaryExpr());
            }
            else if (token.CheckKeyword("if"))
            {
                return(IfStmt());
            }
            else if (token.CheckKeyword("for"))
            {
                if (Peek().CheckKeyword("each"))
                {
                    return(ForEachStmt());
                }
                return(ForStmt());
            }
            else if (token.CheckKeyword("while"))
            {
                return(WhileStmt());
            }
            else if (token.CheckKeyword("do"))
            {
                return(DoStmt());
            }
            else if (token.CheckKeyword("when"))
            {
                return(WhenStmt());
            }
            else if (token.CheckKeyword("method"))
            {
                return(Method());
            }
            else if (token.CheckKeyword("class"))
            {
                return(Class());
            }
            else if (token.CheckKeyword("load"))
            {
                return(LoadStmt());
            }
            else if (token.CheckKeyword("return"))
            {
                return(ReturnStmt());
            }
            else if (token.CheckKeyword("break"))
            {
                Advance();
                return(new ParserResult(new BreakNode().SetPosition(currentToken.Position)));
            }
            else if (token.CheckKeyword("continue"))
            {
                Advance();
                return(new ParserResult(new ContinueNode().SetPosition(currentToken.Position)));
            }
            return(new ParserResult(new InvalidSyntaxError(token.Position, "Expected int or float")));
        }
コード例 #3
0
ファイル: Parser.cs プロジェクト: YohanSandun/Sigiri
        private ParserResult Method()
        {
            //todo avoid use true,false,null as param names
            Advance();
            Token                     token         = null;
            List <string>             parameters    = new List <string>();
            Dictionary <string, Node> defaUltValues = new Dictionary <string, Node>();

            if (currentToken.Type == TokenType.IDENTIFIER ||
                currentToken.Type == TokenType.PLUS || currentToken.Type == TokenType.MINUS ||
                currentToken.Type == TokenType.MULTIPLY || currentToken.Type == TokenType.DIVIDE || currentToken.Type == TokenType.MODULUS ||
                currentToken.Type == TokenType.EXPONENT || currentToken.Type == TokenType.STRING || currentToken.Type == TokenType.IN ||
                currentToken.Type == TokenType.LESS_THAN || currentToken.Type == TokenType.LESS_TOE ||
                currentToken.Type == TokenType.GREATER_THAN || currentToken.Type == TokenType.GREATER_TOE ||
                currentToken.Type == TokenType.EQUALS_EQUALS || currentToken.Type == TokenType.NOT_EQUALS ||
                currentToken.Type == TokenType.BITWISE_AND || currentToken.Type == TokenType.BITWISE_OR || currentToken.Type == TokenType.BITWISE_XOR || currentToken.Type == TokenType.COMPLEMENT ||
                currentToken.Type == TokenType.LEFT_SHIFT || currentToken.Type == TokenType.RIGHT_SHIFT ||
                currentToken.Type == TokenType.BOOLEAN_AND || currentToken.Type == TokenType.BOOLEAN_OR || currentToken.Type == TokenType.BOOLEAN_NOT)
            {
                token = currentToken;
                Advance();
            }
            else if (currentToken.Type == TokenType.LEFT_SQB && Peek().Type == TokenType.RIGHT_SQB)
            {
                token = currentToken;
                Advance(2);
            }
            else if (currentToken.Type == TokenType.LEFT_SQB && Peek().Type == TokenType.EQUALS && Peek(2).Type == TokenType.RIGHT_SQB)
            {
                Advance();
                token = currentToken;
                Advance(2);
            }
            if (currentToken.Type != TokenType.LEFT_PAREN)
            {
                return(new ParserResult(new InvalidSyntaxError(currentToken.Position, "Expected '('")));
            }
            Advance();
            if (currentToken.Type == TokenType.RIGHT_PAREN)
            {
                Advance();
            }
            else
            {
                if (currentToken.Type != TokenType.IDENTIFIER)
                {
                    return(new ParserResult(new InvalidSyntaxError(currentToken.Position, "Expected an identifer")));
                }
                string paramName = currentToken.Value.ToString();
                parameters.Add(paramName);
                Advance();
                if (currentToken.Type == TokenType.EQUALS)
                {
                    Advance();
                    ParserResult result = BitwiseOr();
                    if (result.HasError)
                    {
                        return(result);
                    }
                    defaUltValues.Add(paramName, result.Node);
                }
                while (currentToken.Type == TokenType.COMMA)
                {
                    Advance();
                    if (currentToken.Type != TokenType.IDENTIFIER)
                    {
                        return(new ParserResult(new InvalidSyntaxError(currentToken.Position, "Expected an identifer or ')'")));
                    }
                    paramName = currentToken.Value.ToString();
                    parameters.Add(paramName);
                    Advance();
                    if (currentToken.Type == TokenType.EQUALS)
                    {
                        Advance();
                        ParserResult result = BitwiseOr();
                        if (result.HasError)
                        {
                            return(result);
                        }
                        defaUltValues.Add(paramName, result.Node);
                    }
                }
                if (currentToken.Type != TokenType.RIGHT_PAREN)
                {
                    return(new ParserResult(new InvalidSyntaxError(currentToken.Position, "Expected ')'")));
                }
                Advance();
            }
            if (currentToken.Type == TokenType.COLON)
            {
                Advance();
                SkipNewLines();
                ParserResult parserResult = Expr();
                if (parserResult.HasError)
                {
                    return(parserResult);
                }
                return(new ParserResult(new MethodNode(token, parameters, parserResult.Node, defaUltValues).SetPosition(currentToken.Position)));
            }
            else
            {
                SkipNewLines();
                if (currentToken.Type == TokenType.LEFT_BRA)
                {
                    Advance();
                    SkipNewLines();
                    ParserResult parserResult = Block();
                    if (parserResult.HasError)
                    {
                        return(parserResult);
                    }
                    Advance();
                    return(new ParserResult(new MethodNode(token, parameters, parserResult.Node, defaUltValues).SetPosition(currentToken.Position)));
                }
                else
                {
                    return(new ParserResult(new InvalidSyntaxError(currentToken.Position, "Expected '{' or ':'")));
                }
            }
        }
コード例 #4
0
ファイル: Parser.cs プロジェクト: YohanSandun/Sigiri
        private ParserResult ForStmt()
        {
            Node start, end;
            Node step = null;

            Advance();
            Token token = currentToken;

            if (token.Type != TokenType.IDENTIFIER)
            {
                return(new ParserResult(new InvalidSyntaxError(token.Position, "Expected an identifier")));
            }
            Advance();
            if (currentToken.Type != TokenType.EQUALS)
            {
                return(new ParserResult(new InvalidSyntaxError(token.Position, "Expected '='")));
            }
            Advance();
            ParserResult startResult = BitwiseOr();

            if (startResult.HasError)
            {
                return(startResult);
            }
            start = startResult.Node;
            if (!currentToken.CheckKeyword("to"))
            {
                return(new ParserResult(new InvalidSyntaxError(token.Position, "Expected keyword 'to'")));
            }
            Advance();
            ParserResult endResult = BitwiseOr();

            if (endResult.HasError)
            {
                return(endResult);
            }
            end = endResult.Node;
            if (currentToken.CheckKeyword("step"))
            {
                Advance();
                ParserResult stepResult = BitwiseOr();
                if (stepResult.HasError)
                {
                    return(stepResult);
                }
                step = stepResult.Node;
            }
            if (currentToken.Type == TokenType.COLON)
            {
                Advance();
                SkipNewLines();
                ParserResult parserResult = Expr();
                if (parserResult.HasError)
                {
                    return(parserResult);
                }
                return(new ParserResult(new ForNode(token, start, end, step, parserResult.Node)));
            }
            else
            {
                SkipNewLines();
                if (currentToken.Type == TokenType.LEFT_BRA)
                {
                    Advance();
                    SkipNewLines();
                    ParserResult parserResult = Block();
                    if (parserResult.HasError)
                    {
                        return(parserResult);
                    }
                    Advance();
                    return(new ParserResult(new ForNode(token, start, end, step, parserResult.Node)));
                }
                else
                {
                    return(new ParserResult(new InvalidSyntaxError(token.Position, "Expected ':' or '{'")));
                }
            }
        }
コード例 #5
0
ファイル: Parser.cs プロジェクト: YohanSandun/Sigiri
        private ParserResult IfStmt()
        {
            Advance();

            List <(Node, Node)> cases = new List <(Node, Node)>();
            Node elseCase             = null;

            ParserResult condResult = Expr();

            if (condResult.HasError)
            {
                return(condResult);
            }

            if (currentToken.Type == TokenType.COLON)
            {
                Advance();
                SkipNewLines();
                ParserResult caseResult = Expr();
                if (caseResult.HasError)
                {
                    return(caseResult);
                }
                cases.Add((condResult.Node, caseResult.Node));

                SkipNewLines();
                while (currentToken.CheckKeyword("elif"))
                {
                    Advance();
                    condResult = Expr();
                    if (condResult.HasError)
                    {
                        return(condResult);
                    }
                    if (currentToken.Type == TokenType.COLON)
                    {
                        Advance();
                        SkipNewLines();
                        caseResult = Expr();
                        if (caseResult.HasError)
                        {
                            return(caseResult);
                        }
                        cases.Add((condResult.Node, caseResult.Node));
                        SkipNewLines();
                    }
                    else
                    {
                        SkipNewLines();
                        if (currentToken.Type == TokenType.LEFT_BRA)
                        {
                            Advance();
                            SkipNewLines();
                            caseResult = Block();
                            if (caseResult.HasError)
                            {
                                return(caseResult);
                            }
                            cases.Add((condResult.Node, caseResult.Node));
                            Advance();
                            SkipNewLines();
                        }
                        else
                        {
                            return(new ParserResult(new InvalidSyntaxError(currentToken.Position, "Expected ':' or '{'")));
                        }
                    }
                }

                SkipNewLines();
                if (currentToken.CheckKeyword("else"))
                {
                    Advance();
                    if (currentToken.Type == TokenType.COLON)
                    {
                        Advance();
                        SkipNewLines();
                        ParserResult elseResult = Expr();
                        if (elseResult.HasError)
                        {
                            return(elseResult);
                        }
                        elseCase = elseResult.Node;
                    }
                    else
                    {
                        SkipNewLines();
                        if (currentToken.Type == TokenType.LEFT_BRA)
                        {
                            Advance();
                            SkipNewLines();
                            ParserResult elseResult = Block();
                            if (elseResult.HasError)
                            {
                                return(elseResult);
                            }
                            elseCase = elseResult.Node;
                            Advance();
                            SkipNewLines();
                        }
                        else
                        {
                            return(new ParserResult(new InvalidSyntaxError(currentToken.Position, "Expected ':' or '{'")));
                        }
                    }
                }
            }
            else
            {
                SkipNewLines();
                if (currentToken.Type == TokenType.LEFT_BRA)
                {
                    Advance();
                    ParserResult caseResult = Block();
                    if (caseResult.HasError)
                    {
                        return(caseResult);
                    }
                    cases.Add((condResult.Node, caseResult.Node));
                    Advance();
                    SkipNewLines();
                    while (currentToken.CheckKeyword("elif"))
                    {
                        Advance();
                        condResult = Expr();
                        if (condResult.HasError)
                        {
                            return(condResult);
                        }
                        if (currentToken.Type == TokenType.COLON)
                        {
                            Advance();
                            SkipNewLines();
                            caseResult = Expr();
                            if (caseResult.HasError)
                            {
                                return(caseResult);
                            }
                            cases.Add((condResult.Node, caseResult.Node));
                            SkipNewLines();
                        }
                        else
                        {
                            SkipNewLines();
                            if (currentToken.Type == TokenType.LEFT_BRA)
                            {
                                Advance();
                                SkipNewLines();
                                caseResult = Block();
                                if (caseResult.HasError)
                                {
                                    return(caseResult);
                                }
                                cases.Add((condResult.Node, caseResult.Node));
                                Advance();
                                SkipNewLines();
                            }
                            else
                            {
                                return(new ParserResult(new InvalidSyntaxError(currentToken.Position, "Expected ':' or '{'")));
                            }
                        }
                    }

                    SkipNewLines();
                    if (currentToken.CheckKeyword("else"))
                    {
                        Advance();
                        if (currentToken.Type == TokenType.COLON)
                        {
                            Advance();
                            SkipNewLines();
                            ParserResult elseResult = Expr();
                            if (elseResult.HasError)
                            {
                                return(elseResult);
                            }
                            elseCase = elseResult.Node;
                        }
                        else
                        {
                            SkipNewLines();
                            if (currentToken.Type == TokenType.LEFT_BRA)
                            {
                                Advance();
                                SkipNewLines();
                                ParserResult elseResult = Block();
                                if (elseResult.HasError)
                                {
                                    return(elseResult);
                                }
                                elseCase = elseResult.Node;
                                Advance();
                                SkipNewLines();
                            }
                            else
                            {
                                return(new ParserResult(new InvalidSyntaxError(currentToken.Position, "Expected ':' or '{'")));
                            }
                        }
                    }
                }
                else
                {
                    return(new ParserResult(new InvalidSyntaxError(currentToken.Position, "Expected ':' or '{'")));
                }
            }
            return(new ParserResult(new IfNode(cases, elseCase).SetPosition(currentToken.Position)));
        }
コード例 #6
0
ファイル: Parser.cs プロジェクト: YohanSandun/Sigiri
        private ParserResult Call(bool byPassDot = false)
        {
            ParserResult atomResult = Atom(byPassDot);

            if (atomResult.HasError)
            {
                return(atomResult);
            }
            if (currentToken.Type == TokenType.LEFT_PAREN)
            {
                Advance();
                List <(string, Node)> arguments = new List <(string, Node)>();
                if (currentToken.Type == TokenType.RIGHT_PAREN)
                {
                    Advance();
                }
                else
                {
                    string paramName = "";
                    if (currentToken.Type == TokenType.IDENTIFIER && Peek().Type == TokenType.COLON)
                    {
                        paramName = currentToken.Value.ToString();
                        Advance(2);
                    }
                    ParserResult exprResult = Expr();
                    if (exprResult.HasError)
                    {
                        return(exprResult);
                    }
                    arguments.Add((paramName, exprResult.Node));
                    while (currentToken.Type == TokenType.COMMA)
                    {
                        paramName = "";
                        Advance();
                        if (currentToken.Type == TokenType.IDENTIFIER && Peek().Type == TokenType.COLON)
                        {
                            paramName = currentToken.Value.ToString();
                            Advance(2);
                        }
                        exprResult = Expr();
                        if (exprResult.HasError)
                        {
                            return(exprResult);
                        }
                        arguments.Add((paramName, exprResult.Node));
                    }
                    if (currentToken.Type != TokenType.RIGHT_PAREN)
                    {
                        return(new ParserResult(new InvalidSyntaxError(currentToken.Position, "Expected ')' or ','")));
                    }
                    Advance();
                }
                if (currentToken.Type == TokenType.LEFT_SQB)
                {
                    return(Subscript(new CallNode(atomResult.Node, arguments).SetPosition(currentToken.Position)));
                }
                else
                {
                    return(new ParserResult(new CallNode(atomResult.Node, arguments).SetPosition(currentToken.Position)));
                }
            }
            return(atomResult);
        }