add basic support for tuples
This commit is contained in:
parent
7bb277045c
commit
e03d18c7db
7 changed files with 339 additions and 18 deletions
100
core/parser.go
100
core/parser.go
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue