Пример #1
0
        private DefStatement ParseDef(Dictionary <string, int> varTable)
        {
            //Console.WriteLine(string.Join(", ", varTable.Keys));
            var def = new DefStatement(_enumerator.Current.row, _enumerator.Current.column, varTable)
            {
                Name = this.Match(TokenKind.NAME).data,
                Args = this.MatchDefArgs()
            };

            def.FuncList = new List <DefStatement>(_currentNameSpace.FuncList);
            _currentNameSpace.AddFunction(def);
            //def.Args.Reverse();
            foreach (var arg in def.Args)
            {
                if (def.varTable.Keys.Contains(arg))
                {
                    def.varTable.Remove(arg);
                }
                //def.AddVar(arg);
                def.AddArg(arg);
            }

            this.Match(TokenKind.COLON);

            if (MatchBool(TokenKind.NEWLINE))
            {
                var prevNameSpace = _currentNameSpace;
                _currentNameSpace = def;
                //ParseUntil(def, TokenKind.RETURN);
                ParseUntil(def, TokenKind.DEDENT);
                //Console.WriteLine(string.Join(", ", def.varTable.Keys.ToList()));
                //Console.WriteLine(string.Join(", ", _base.varTable.ToList()));
                //_enumerator.MovePrevious();
                //_enumerator.MovePrevious();
                //def.Return = this.MatchReturn();
                //this.MatchCurrent(TokenKind.NEWLINE);
                //this.Match(TokenKind.DEDENT);

                /*
                 * Console.WriteLine(def.Name);
                 * foreach (var kvp in def.varTable)
                 * {
                 *  Console.WriteLine($"{kvp.Key.ToString()} : {kvp.Value.ToString()}");
                 * }*/
                _currentNameSpace = prevNameSpace;
            }
            else
            {
                this.MatchCurrent(TokenKind.RETURN);
                def.Return = ParseExpr();
                MatchCurrent(TokenKind.NEWLINE);
            }
            return(def);
        }
Пример #2
0
        private void ParseUntil(RootNode baseNode, TokenKind?stopToken = null)
        {
            while (_enumerator.MoveNext())
            {
                var token = _enumerator.Current;
                if (token.Kind == stopToken)
                {
                    break;
                }
                switch (token.Kind)
                {
                case TokenKind.DEF:
                {
                    DefStatement temp = null;
                    switch (baseNode)
                    {
                    case IVariableTableContainer tableContainer:
                    {
                        temp = ParseDef(new Dictionary <string, int>(tableContainer.varTable));
                        break;
                    }

                    default:
                    {
                        temp = ParseDef(new Dictionary <string, int>(_base.varTable));
                        break;
                    }
                    }
                    baseNode.AddChild(temp);
                    break;
                }

                case TokenKind.NAME: {
                    //Console.WriteLine(_enumerator.Current.data);
                    if (_enumerator.MoveNext())
                    {
                        if (_enumerator.Current.Kind == TokenKind.EQUAL)
                        {
                            _enumerator.MovePrevious();
                            var name = _enumerator.Current.data;
                            _enumerator.MoveNext();
                            _enumerator.MoveNext();
                            var expr = ParseExpr();
                            baseNode.AddChild(new AssignStatement(
                                                  _enumerator.Current.row,
                                                  _enumerator.Current.column,
                                                  name, expr));
                            switch (baseNode)
                            {
                            case IVariableTableContainer tableContainer:
                            {
                                tableContainer.AddVar(name);
                                break;
                            }

                            default:
                            {
                                _currentNameSpace.AddVar(name);
                                break;
                            }
                            }
                        }
                        else if (_enumerator.Current.Kind == TokenKind.PLUSEQUAL ||
                                 _enumerator.Current.Kind == TokenKind.MINEQUAL ||
                                 _enumerator.Current.Kind == TokenKind.STAREQUAL ||
                                 _enumerator.Current.Kind == TokenKind.SLASHEQUAL)
                        {
                            _enumerator.MovePrevious();
                            var name = _enumerator.Current.data;
                            var row  = _enumerator.Current.row;
                            var col  = _enumerator.Current.column;
                            switch (baseNode)
                            {
                            case IVariableTableContainer tableContainer:
                            {
                                if (!tableContainer.HaveVariable(name))
                                {
                                    throw new CompilerException(
                                              $"Name {name} is not defined at {_enumerator.Current.row}:{_enumerator.Current.column}",
                                              _enumerator.Current.row, _enumerator.Current.column);
                                }
                                break;
                            }

                            default:
                            {
                                if (!_currentNameSpace.HaveVariable(name))
                                {
                                    throw new CompilerException(
                                              $"Name {name} is not defined at {_enumerator.Current.row}:{_enumerator.Current.column}",
                                              _enumerator.Current.row, _enumerator.Current.column);
                                }
                                break;
                            }
                            }
                            _enumerator.MoveNext();
                            //var op = _enumerator.Current.Kind;
                            var op = _enumerator.Current.Kind switch
                            {
                                TokenKind.PLUSEQUAL => TokenKind.PLUS,
                                TokenKind.MINEQUAL => TokenKind.MINUS,
                                TokenKind.STAREQUAL => TokenKind.STAR,
                                TokenKind.SLASHEQUAL => TokenKind.SLASH
                            };
                            if (_enumerator.MoveNext())
                            {
                                baseNode.AddChild(new AssignStatement(
                                                      _enumerator.Current.row,
                                                      _enumerator.Current.column,
                                                      name,
                                                      new BinOp(_enumerator.Current.row,
                                                                _enumerator.Current.column,
                                                                op,
                                                                new VarExpression(row,
                                                                                  col,
                                                                                  name),
                                                                ParseExpr()
                                                                )));
                            }
                        }
                        else if (_enumerator.Current.Kind == TokenKind.LPAR)
                        {
                            _enumerator.MovePrevious();
                            var tempEx = ParseExpr();
                            var temp   = new ExprStatement(tempEx.Row, tempEx.Column, tempEx);
                            //var temp = ParseName();
                            baseNode.AddChild(temp);
                            // if (!_base.root.GetChildren()
                            //     .Any(def =>
                            //         def is DefStatement d &&
                            //         d.Name == temp.Name))
                            // {
                            //     throw new SyntaxException(
                            //         $"Name {temp.Name} is not defined at {temp.Row + 1}:{temp.Column}",
                            //         temp.Row, temp.Column);
                            // }
                            this.MatchIndentation();
                            break;
                        }
                        else
                        {
                            _enumerator.MovePrevious();
                            baseNode.AddChild(new ExprStatement(
                                                  _enumerator.Current.row,
                                                  _enumerator.Current.column,
                                                  ParseExpr()));
                            ;
                        }
                    }
                    break;
                }

                case TokenKind.IF:
                {
                    var temp = ParseConditional();
                    baseNode.AddChild(temp);
                    //_enumerator.MovePrevious();
                    break;
                }

                case TokenKind.INT:
                case TokenKind.MINUS:
                case TokenKind.TILDE:
                case TokenKind.EXCLAMINATION:
                case TokenKind.LPAR:
                {
                    var temp = new ExprStatement(_enumerator.Current.row,
                                                 _enumerator.Current.column,
                                                 ParseExpr());
                    //Console.WriteLine(temp.ToString());
                    baseNode.AddChild(temp);
                    MatchIndentationCurrent();
                    break;
                }

                case TokenKind.WHILE:
                {
                    var temp = ParseWhileLoop();
                    baseNode.AddChild(temp);
                    break;
                }

                case TokenKind.BREAK:
                {
                    if (_currentLoop == null)
                    {
                        throw new CompilerException($"Break is outside of loop at {_enumerator.Current.row}:" +
                                                    $"{_enumerator.Current.column}",
                                                    _enumerator.Current.row,
                                                    _enumerator.Current.column);
                    }
                    baseNode.AddChild(new BreakStatement(_enumerator.Current.row,
                                                         _enumerator.Current.column));
                    break;
                }

                case TokenKind.CONTINUE:
                {
                    if (_currentLoop == null)
                    {
                        throw new CompilerException($"Continue is outside of loop at {_enumerator.Current.row}:" +
                                                    $"{_enumerator.Current.column}",
                                                    _enumerator.Current.row,
                                                    _enumerator.Current.column);
                    }
                    baseNode.AddChild(new ContinueStatement(_enumerator.Current.row,
                                                            _enumerator.Current.column));
                    break;
                }

                case TokenKind.PRINT:
                {
                    var temp = new Print(_enumerator.Current.row, _enumerator.Current.column);
                    Match(TokenKind.LPAR);
                    temp.expr = ParseExpr();
                    _enumerator.MovePrevious();
                    MatchCurrent(TokenKind.RPAR);
                    baseNode.AddChild(temp);
                    break;
                }

                case TokenKind.RETURN:
                {
                    if (_currentNameSpace.GetType() != typeof(DefStatement))
                    {
                        throw new CompilerException($"Return outside of function at {_enumerator.Current.row}:" +
                                                    $"{_enumerator.Current.column}",
                                                    _enumerator.Current.row,
                                                    _enumerator.Current.column);
                    }
                    var t = _enumerator.Current;
                    _enumerator.MovePrevious();
                    baseNode.AddChild(new ReturnStatement(t.row, t.column, MatchReturn()));
                    break;
                }

                default:
                {
                    break;
                }
                }
            }
        }