Skip to content

Commit

Permalink
handle with array in parser (#19)
Browse files Browse the repository at this point in the history
  • Loading branch information
JunNishimura committed Sep 29, 2024
1 parent 4cc2411 commit ac79785
Show file tree
Hide file tree
Showing 2 changed files with 151 additions and 139 deletions.
121 changes: 45 additions & 76 deletions parser/parser.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package parser

import (
"errors"
"fmt"
"strconv"

Expand Down Expand Up @@ -30,94 +29,26 @@ func New(l *lexer.Lexer) *Parser {
return p
}

func (p *Parser) Errors() []string {
out := []string{}

if errs, ok := p.errors.(interface{ Unwrap() []error }); ok {
for _, err := range errs.Unwrap() {
out = append(out, err.Error())
}
} else {
out = append(out, p.errors.Error())
}

return out
}

func (p *Parser) appendError(err error) {
p.errors = errors.Join(p.errors, err)
}

func (p *Parser) nextToken() {
p.curToken = p.peekToken
p.peekToken = p.l.NextToken()
}

func (p *Parser) ParseProgram() (*ast.Program, error) {
func (p *Parser) ParseProgram() (ast.Expression, error) {
if p.curTokenIs(token.EOF) {
return nil, nil
}

var err error
program := &ast.Program{
Expressions: []ast.Expression{},
}

if p.curTokenIs(token.LBRACKET) {
program, err = p.parseMultipleExpressions()
if err != nil {
p.appendError(err)
}
} else {
exp, err := p.parseExpression()
if err != nil {
p.appendError(err)
}

program.Expressions = append(program.Expressions, exp)
}

if !p.curTokenIs(token.EOF) {
p.appendError(fmt.Errorf("expected EOF, got %s instead", p.curToken.Type))
}

if p.errors != nil {
return nil, p.errors
}

return program, nil
}

func (p *Parser) parseMultipleExpressions() (*ast.Program, error) {
if err := p.expectCurToken(token.LBRACKET); err != nil {
p.appendError(err)
}

program := &ast.Program{
Expressions: []ast.Expression{},
exp, err := p.parseExpression()
if err != nil {
return nil, err
}

for {
exp, err := p.parseExpression()
if err != nil {
p.appendError(err)
}

program.Expressions = append(program.Expressions, exp)

if p.curTokenIs(token.COMMA) {
// if the program still has more expressions, skip the comma and continue
p.nextToken()
} else {
// if the program has no more expressions, break the loop
if err := p.expectCurToken(token.RBRACKET); err != nil {
p.appendError(err)
}
break
}
if err := p.expectCurToken(token.EOF); err != nil {
return nil, err
}

return program, nil
return exp, nil
}

func (p *Parser) curTokenIs(t token.TokenType) bool {
Expand Down Expand Up @@ -252,6 +183,7 @@ func (p *Parser) parseCommand() (*ast.CommandObject, error) {
}, nil
}

// TODO: parseArgs should be able to parse only one argument without brackets
func (p *Parser) parseArgs() ([]ast.Expression, error) {
args := []ast.Expression{}

Expand Down Expand Up @@ -426,6 +358,8 @@ func (p *Parser) parseAtom() (ast.Expression, error) {
return p.parseBoolean()
case token.DOUBLE_QUOTE:
return p.parseDoubleQuotedString()
case token.LBRACKET:
return p.parseArray()
default:
err := fmt.Errorf("unexpected token type %s", p.curToken.Type)
p.nextToken()
Expand Down Expand Up @@ -495,6 +429,41 @@ func (p *Parser) parseDoubleQuotedString() (ast.Expression, error) {
return nil, fmt.Errorf("unexpected token type %s", p.curToken.Type)
}

func (p *Parser) parseArray() (*ast.Array, error) {
if !p.curTokenIs(token.LBRACKET) {
return nil, fmt.Errorf("expected LBRACKET, got %s instead", p.curToken.Type)
}
arrayToken := p.curToken
p.nextToken()

elements := []ast.Expression{}

// empty array
if p.curTokenIs(token.RBRACKET) {
p.nextToken()
return &ast.Array{Token: arrayToken, Elements: elements}, nil
}

for {
element, err := p.parseExpression()
if err != nil {
return nil, err
}
elements = append(elements, element)

if p.curTokenIs(token.COMMA) {
p.nextToken()
} else {
if err := p.expectCurToken(token.RBRACKET); err != nil {
return nil, err
}
break
}
}

return &ast.Array{Token: arrayToken, Elements: elements}, nil
}

func (p *Parser) parseSymbol() (*ast.Symbol, error) {
if err := p.expectCurToken(token.DOUBLE_QUOTE); err != nil {
return nil, err
Expand Down
Loading

0 comments on commit ac79785

Please sign in to comment.