Parse dereferences and subscripts

This commit is contained in:
Sasha Koshka 2024-02-08 00:14:52 -05:00
parent 7697bab51a
commit c347add41c
1 changed files with 45 additions and 4 deletions

View File

@ -22,8 +22,8 @@ import "git.tebibyte.media/sashakoshka/fspl/entity"
// | | | 'break' =Break
// | | | 'return' =Return
// | |
// | | +Dot +Expression =Dereference *
// | | | +Expression =Subscript *
// | | +Dot +Expression =Dereference
// | | | +Expression =Subscript
// | | +Symbol X
// | | '\' =Slice *
// | | '#' =Length *
@ -134,7 +134,7 @@ func (this *Parser) parseExpressionRootLBracket () (entity.Expression, error) {
if err != nil { return nil, err }
switch this.kind() {
case lexer.Ident: return this.parseExpressionRootLBracketIdent(pos)
case lexer.Dot: // TODO return this.parseExpressionRootLBracketDot(pos)
case lexer.Dot: return this.parseDereferenceOrSubscriptCore(pos)
case lexer.Symbol: return this.parseExpressionRootLBracketSymbol(pos)
}
panic(this.bug())
@ -158,7 +158,7 @@ func (this *Parser) parseReturnOrBreakCore (pos errors.Position) (entity.Express
name := this.value()
err = this.expectNextDesc (
"Expression or end of " + name,
"expression or end of " + name,
appendCopy(startTokensExpression, lexer.RBracket)...)
if err != nil { return nil, err }
var value entity.Expression
@ -188,6 +188,47 @@ func (this *Parser) parseReturnOrBreakCore (pos errors.Position) (entity.Express
panic(this.bug())
}
func (this *Parser) parseDereferenceOrSubscriptCore (pos errors.Position) (entity.Expression, error) {
err := this.expect(lexer.Dot)
if err != nil { return nil, err }
this.next()
argument, err := this.parseExpression()
if err != nil { return nil, err }
err = this.expectDesc (
"element offset expression or end of dereference",
appendCopy(startTokensExpression, lexer.RBracket)...)
if err != nil { return nil, err }
if this.token.Is(lexer.RBracket) {
// RBracket: dereference
pos = pos.Union(this.pos())
this.next()
return &entity.Dereference {
Position: pos,
Pointer: argument,
}, nil
} else {
// startTokensExpression...: subscript
offset, err := this.parseExpression()
if err != nil { return nil, err }
err = this.expect(lexer.RBracket)
if err != nil { return nil, err }
pos = pos.Union(this.pos())
this.next()
return &entity.Subscript {
Position: pos,
Slice: argument,
Offset: offset,
}, nil
}
}
func (this *Parser) parseCallCore (pos errors.Position) (*entity.Call, error) {
err := this.expect(lexer.Ident)
if err != nil { return nil, err }