add basic support for tuples

This commit is contained in:
Neemek 2026-07-11 12:37:15 +02:00
parent 7bb277045c
commit e03d18c7db
Signed by: neemek
GPG key ID: 84FFE4D7D40AB25E
7 changed files with 339 additions and 18 deletions

View file

@ -198,6 +198,21 @@ func (p *Parser) accept(tokenType TokenType) bool {
return false
}
func (p *Parser) acceptAll(tokenTypes ...TokenType) bool {
if int(p.pos)+len(tokenTypes) > len(p.tokens) {
return false
}
for i, tokenType := range tokenTypes {
if p.tokens[int(p.pos)+i].Type != tokenType {
return false
}
}
p.pos += Pos(len(tokenTypes))
return true
}
func (p *Parser) expect(tokenType TokenType, reason string) error {
if !p.accept(tokenType) {
return p.error(fmt.Sprintf("Expected token %s, got %s; %s", tokenType, p.curr.Type, reason), p.curr)
@ -813,15 +828,50 @@ func (p *Parser) factor() (Node, error) {
case TokenOpenParenthesis:
p.advance()
v, err := p.condition()
start := p.prev.Start
// we're inside an object
if p.acceptAll(TokenName, TokenColon) {
return nil, p.error("objects are not implemented yet (TBD)", p.prev)
}
v, err := p.expression(false)
if err != nil {
return nil, err
}
if err := p.expect(TokenCloseParenthesis, "an opened parenthesis must be closed"); err != nil {
return nil, err
if !p.accept(TokenComma) {
if err := p.expect(TokenCloseParenthesis, "parenthesis must be closed"); err != nil {
return nil, err
}
return v, nil
}
return v, nil
items := []Node{v}
for !p.accept(TokenCloseParenthesis) {
i, err := p.expression(false)
if err != nil {
return nil, err
}
items = append(items, i)
if !p.accept(TokenComma) {
if err := p.expect(TokenCloseParenthesis, "tuples must be closed"); err != nil {
return nil, err
}
break
}
}
return &TupleNode{
items,
start,
p.prev.End,
}, nil
case TokenBreakpoint:
p.advance()
@ -831,6 +881,9 @@ func (p *Parser) factor() (Node, error) {
p.prev.End,
}, nil
case TokenOpenBrace:
return p.expression(true)
default:
return nil, p.error(fmt.Sprintf("invalid factor %s", p.curr), p.curr)
}
@ -1355,15 +1408,44 @@ func (p *Parser) parseSignature() (TypeSignature, error) {
var s TypeSignature
if p.accept(TokenOpenParenthesis) {
is, err := p.parseSignature()
// we're inside an object
if p.acceptAll(TokenName, TokenColon) {
return nil, p.error("objects are not implemented yet (TBD)", p.prev)
}
v, err := p.parseSignature()
if err != nil {
return nil, err
}
if err := p.expect(TokenCloseParenthesis, "expected closing parenthesis"); err != nil {
return nil, err
}
s = is
if !p.accept(TokenComma) {
if err := p.expect(TokenCloseParenthesis, "parenthesis must be closed"); err != nil {
return nil, err
}
s = v
} else {
items := []TypeSignature{v}
for !p.accept(TokenCloseParenthesis) {
i, err := p.parseSignature()
if err != nil {
return nil, err
}
items = append(items, i)
if !p.accept(TokenComma) {
if err := p.expect(TokenCloseParenthesis, "tuples must be closed"); err != nil {
return nil, err
}
break
}
}
s = &TupleSignature{
items,
}
}
} else if p.accept(TokenFunc) {
if err := p.expect(TokenOpenParenthesis, "func signature must have parentheses for parameters"); err != nil {
return nil, err