diff --git a/parser/parser.go b/parser/parser.go new file mode 100644 index 0000000..3af6d79 --- /dev/null +++ b/parser/parser.go @@ -0,0 +1,58 @@ +package parser + +import ( + "io" + + "github.com/brettlangdon/gython/ast" + "github.com/brettlangdon/gython/errorcode" + "github.com/brettlangdon/gython/scanner" + "github.com/brettlangdon/gython/token" +) + +type Parser struct { + tokenizer *scanner.Scanner + + tokenBuffer []*token.Token +} + +func (parser *Parser) nextToken() *token.Token { + if len(parser.tokenBuffer) > 0 { + last := len(parser.tokenBuffer) - 1 + next := parser.tokenBuffer[last] + parser.tokenBuffer = parser.tokenBuffer[:last] + return next + } + + return parser.tokenizer.NextToken() +} + +func (parser *Parser) unreadToken(tok *token.Token) { + parser.tokenBuffer = append(parser.tokenBuffer, tok) +} + +func (parser *Parser) parseFileInput() *ast.FileInput { + root := ast.NewFileInput() + for parser.tokenizer.State() == errorcode.E_OK { + next := parser.nextToken() + if next.ID == token.NEWLINE { + root.AppendToken(next) + } else if next.ID == token.ENDMARKER { + break + } else { + parser.unreadToken(next) + // TODO: parser.parseStatement() + break + } + } + + return root +} + +func ParseReader(r io.Reader) *ast.FileInput { + parser := &Parser{ + tokenizer: scanner.NewScanner(r), + tokenBuffer: make([]*token.Token, 0), + } + + return parser.parseFileInput() +}