예제 #1
0
        private void CompileIf(IfBlock data)
        {
            CompileExpr(data.leftExpr);
            CompileExpr(data.rightExpr);

            Write($"if{CompileSymbol(data.op)}");

            CompileStmtList(data.statements);
        }
예제 #2
0
        private void CompileWhile(WhileBlock data)
        {
            string name = ".repeat" + repeats.ToString();

            repeats++;

            Write(name);

            IfBlock ifBlock = new IfBlock(data.leftExpr, data.op, data.rightExpr);

            ifBlock.statements.AddRange(data.statements);
            ifBlock.statements.Add(new Goto(name));
            ifBlock.statements.Add(new EndIf());

            CompileStmtList(new List <Stmt>()
            {
                ifBlock
            });
        }
예제 #3
0
        public Parser(TokenList tokenList)
        {
            Tree = new List <Stmt>();

            _tokens       = tokenList;
            _currentBlock = null;
            _blockstack   = new Stack <Block>();
            _isRunning    = true;
            Token token = null;

            while (_isRunning)
            {
                try
                {
                    token = _tokens.Next();
                }
                catch { }

                if (token.Name == Lexer.TokenType.Import)
                {
                    Program.Imports.Add(ParseImport());
                }
                else if (token.Name == Lexer.TokenType.Global)
                {
                    if (_tokens.Peek().Name == Lexer.TokenType.Ident)
                    {
                        string ident = _tokens.Next().Value.ToString();

                        // Standard assign, could be string, int, or array
                        if (_tokens.Peek().Name == Lexer.TokenType.Equal)
                        {
                            _tokens.Move();

                            // Assign an array
                            if (_tokens.Peek().Name == Lexer.TokenType.LeftBracket)
                            {
                                // Go back two tokens to get ident
                                _tokens.Move(-2);

                                foreach (GlobalAssign assign in ParseGlobalAssignArray())
                                {
                                    Tree.Add(assign);
                                }
                            }
                            // Assign an expr
                            else
                            {
                                Tree.Add(new GlobalAssign(ident, ParseExpr()));
                            }
                        }
                    }
                }
                else if (token.Name == Lexer.TokenType.Function)
                {
                    Func func = ParseFunc();

                    if (_currentBlock == null)
                    {
                        _currentBlock = func;
                    }
                    else
                    {
                        _currentBlock.AddStmt(new Return(null));
                        Tree.Add(_currentBlock);
                        _currentBlock = func;
                    }
                }
                else if (token.Name == Lexer.TokenType.Event)
                {
                    Evnt evnt = ParseEvnt();

                    if (_currentBlock == null)
                    {
                        _currentBlock = evnt;
                    }
                    else
                    {
                        _currentBlock.AddStmt(new Return(null));
                        Tree.Add(_currentBlock);
                        _currentBlock = evnt;
                    }
                }
                else if (token.Name == Lexer.TokenType.If)
                {
                    IfBlock ifblock = ParseIf();

                    if (_currentBlock != null)
                    {
                        _blockstack.Push(_currentBlock);
                        _currentBlock = ifblock;
                    }
                }
                else if (token.Name == Lexer.TokenType.ElseIf)
                {
                    ElseIfBlock elseifblock = ParseElseIf();

                    if (_currentBlock != null)
                    {
                        _blockstack.Push(_currentBlock);
                        _currentBlock = elseifblock;
                    }
                }
                else if (token.Name == Lexer.TokenType.Else)
                {
                    if (_currentBlock != null)
                    {
                        _blockstack.Push(_currentBlock);
                        _currentBlock = new ElseBlock();
                    }
                }
                else if (token.Name == Lexer.TokenType.Repeat)
                {
                    if (_currentBlock != null)
                    {
                        _blockstack.Push(_currentBlock);
                        _currentBlock = new RepeatBlock();
                    }
                }
                else if (token.Name == Lexer.TokenType.While)
                {
                    WhileBlock whileblock = ParseWhile();

                    if (_currentBlock != null)
                    {
                        _blockstack.Push(_currentBlock);
                        _currentBlock = whileblock;
                    }
                }
                else if (token.Name == Lexer.TokenType.Ident)
                {
                    // Standard assign, could be string, int, or array
                    if (_tokens.Peek().Name == Lexer.TokenType.Equal)
                    {
                        _tokens.Move();

                        // Assign an array
                        if (_tokens.Peek().Name == Lexer.TokenType.LeftBracket)
                        {
                            // Go back two tokens to get ident
                            _tokens.Move(-2);

                            foreach (Assign assign in ParseAssignArray())
                            {
                                _currentBlock.AddStmt(assign);
                            }
                        }
                        // Assign an expr
                        else
                        {
                            // Go back two tokens to ident
                            _tokens.Move(-2);
                            _currentBlock.AddStmt(ParseAssign());
                        }
                    }
                    // Reference to a function call
                    else if (_tokens.Peek().Name == Lexer.TokenType.LeftParan)
                    {
                        _tokens.pos--;
                        Call c = ParseCall();
                        _currentBlock.AddStmt(c);
                    }
                }
                else if (token.Name == Lexer.TokenType.Return)
                {
                    Return r = ParseReturn();
                    _currentBlock.AddStmt(r);
                }
                else if (token.Name == Lexer.TokenType.RightBrace)
                {
                    if (_currentBlock is Func)
                    {
                        _currentBlock.AddStmt(new Return(null));
                        Tree.Add(_currentBlock);
                        _currentBlock = null;
                    }
                    else if (_currentBlock is IfBlock || _currentBlock is ElseIfBlock || _currentBlock is ElseBlock)
                    {
                        _currentBlock.AddStmt(new EndIf());
                        Block block = _currentBlock;

                        if (_blockstack.Count > 0)
                        {
                            _currentBlock = _blockstack.Pop();
                            _currentBlock.AddStmt(block);
                        }
                    }
                    else if (_currentBlock is RepeatBlock || _currentBlock is WhileBlock)
                    {
                        Block block = _currentBlock;

                        if (_blockstack.Count > 0)
                        {
                            _currentBlock = _blockstack.Pop();
                            _currentBlock.AddStmt(block);
                        }
                    }
                }
                else if (token.Name == Lexer.TokenType.EOF)
                {
                    Tree.Add(_currentBlock);
                    _isRunning = false;
                }
            }
        }