add type aliases, rework compiler, remove optimization
This commit is contained in:
parent
94b12f28ab
commit
d54249cffe
12 changed files with 869 additions and 1597 deletions
653
core/parser.go
653
core/parser.go
|
|
@ -178,7 +178,7 @@ func (p *Parser) Parse(path string) (*Program, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (p *Parser) accept(tokenType TokenType) bool {
|
||||
func (p *Parser) accept(tokenType TokenKind) bool {
|
||||
if p.curr == nil {
|
||||
log.Fatal("unexpected current token nil")
|
||||
return false
|
||||
|
|
@ -198,7 +198,7 @@ func (p *Parser) accept(tokenType TokenType) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (p *Parser) acceptAll(tokenTypes ...TokenType) bool {
|
||||
func (p *Parser) acceptAll(tokenTypes ...TokenKind) bool {
|
||||
if int(p.pos)+len(tokenTypes) > len(p.tokens) {
|
||||
return false
|
||||
}
|
||||
|
|
@ -213,7 +213,7 @@ func (p *Parser) acceptAll(tokenTypes ...TokenType) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func (p *Parser) expect(tokenType TokenType, reason string) error {
|
||||
func (p *Parser) expect(tokenType TokenKind, 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)
|
||||
}
|
||||
|
|
@ -291,6 +291,33 @@ func (p *Parser) expression(mustBeBlock bool) (Node, error) {
|
|||
|
||||
t := p.curr
|
||||
switch t.Type {
|
||||
case TokenType:
|
||||
p.advance()
|
||||
start := p.prev.Start
|
||||
|
||||
if err := p.expect(TokenName, "types must have a name"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
name := p.prev
|
||||
|
||||
if err := p.expect(TokenAssign, "type aliases must be defined with an assign"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sig, err := p.parseSignature()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &AliasNode{
|
||||
name,
|
||||
sig,
|
||||
|
||||
start,
|
||||
p.prev.End,
|
||||
}, nil
|
||||
|
||||
case TokenIf:
|
||||
p.advance()
|
||||
|
||||
|
|
@ -320,59 +347,6 @@ func (p *Parser) expression(mustBeBlock bool) (Node, error) {
|
|||
t.End,
|
||||
}, nil
|
||||
|
||||
case TokenFunc:
|
||||
p.advance()
|
||||
start := p.prev.Start
|
||||
|
||||
var name *Token
|
||||
if p.accept(TokenName) { // can be unnamed, but accept name if it is named
|
||||
name = p.prev
|
||||
}
|
||||
|
||||
params, err := p.parseParams()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var yield TypeSignature
|
||||
if p.accept(TokenArrow) {
|
||||
yield, err = p.parseSignature()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
logic, err := p.expression(true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
names := "*"
|
||||
if name != nil {
|
||||
names = name.Lexeme
|
||||
}
|
||||
|
||||
fn := &FunctionNode{
|
||||
names,
|
||||
params,
|
||||
yield,
|
||||
logic,
|
||||
start,
|
||||
p.prev.End,
|
||||
}
|
||||
|
||||
if name != nil {
|
||||
return &AssignNode{
|
||||
&ReferenceNode{name.Lexeme, name.Start, name.End},
|
||||
fn,
|
||||
true,
|
||||
start,
|
||||
p.prev.End,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return fn, nil
|
||||
|
||||
case TokenReturn:
|
||||
p.advance()
|
||||
start := p.prev.Start
|
||||
|
|
@ -440,7 +414,7 @@ func (p *Parser) expression(mustBeBlock bool) (Node, error) {
|
|||
}
|
||||
}
|
||||
|
||||
func isBinaryOperator(tokenType TokenType) bool {
|
||||
func isBinaryOperator(tokenType TokenKind) bool {
|
||||
switch tokenType {
|
||||
case TokenPlus, TokenMinus, TokenStar, TokenSlash, TokenPipe, TokenDoubleAmpersand, TokenDoublePipe, TokenEquals, TokenBangEquals, TokenLessThan, TokenLessThanOrEqual, TokenGreaterThan, TokenGreaterThanOrEqual:
|
||||
return true
|
||||
|
|
@ -449,7 +423,7 @@ func isBinaryOperator(tokenType TokenType) bool {
|
|||
}
|
||||
}
|
||||
|
||||
func binaryPrecedence(op TokenType) int {
|
||||
func binaryPrecedence(op TokenKind) int {
|
||||
switch op {
|
||||
case TokenDoubleAmpersand, TokenDoublePipe:
|
||||
return 1
|
||||
|
|
@ -464,7 +438,7 @@ func binaryPrecedence(op TokenType) int {
|
|||
}
|
||||
}
|
||||
|
||||
func tokenToBinaryOperation(tokenType TokenType) BinaryOperation {
|
||||
func tokenToBinaryOperation(tokenType TokenKind) BinaryOperation {
|
||||
switch tokenType {
|
||||
case TokenPlus:
|
||||
return BinaryAddition
|
||||
|
|
@ -477,9 +451,9 @@ func tokenToBinaryOperation(tokenType TokenType) BinaryOperation {
|
|||
case TokenPipe:
|
||||
panic("unimplemented bitwise ops")
|
||||
case TokenDoubleAmpersand:
|
||||
return BinaryAnd
|
||||
return BinaryBooleanAnd
|
||||
case TokenDoublePipe:
|
||||
return BinaryOr
|
||||
return BinaryBooleanOr
|
||||
|
||||
case TokenEquals:
|
||||
return BinaryEquality
|
||||
|
|
@ -509,22 +483,28 @@ func (p *Parser) binary() (Node, error) {
|
|||
values := NewStack[Node](256)
|
||||
values.pushItem(t)
|
||||
|
||||
reduce := func() {
|
||||
r := values.Pop()
|
||||
l := values.Pop()
|
||||
opToken := ops.Pop()
|
||||
op := tokenToBinaryOperation(opToken.Type)
|
||||
|
||||
start, _ := l.Bounds()
|
||||
_, end := r.Bounds()
|
||||
|
||||
values.Push(&BinaryNode{
|
||||
op,
|
||||
l,
|
||||
r,
|
||||
opToken,
|
||||
start,
|
||||
end,
|
||||
})
|
||||
}
|
||||
|
||||
for isBinaryOperator(p.curr.Type) {
|
||||
for ops.Current > 0 && binaryPrecedence(p.curr.Type) <= binaryPrecedence(ops.Peek().Type) {
|
||||
r := values.Pop()
|
||||
l := values.Pop()
|
||||
op := tokenToBinaryOperation(ops.Pop().Type)
|
||||
|
||||
start, _ := l.Bounds()
|
||||
_, end := r.Bounds()
|
||||
|
||||
values.Push(&BinaryNode{
|
||||
op,
|
||||
l,
|
||||
r,
|
||||
start,
|
||||
end,
|
||||
})
|
||||
reduce()
|
||||
}
|
||||
|
||||
ops.Push(p.curr)
|
||||
|
|
@ -539,20 +519,7 @@ func (p *Parser) binary() (Node, error) {
|
|||
}
|
||||
|
||||
for ops.Current > 0 {
|
||||
r := values.Pop()
|
||||
l := values.Pop()
|
||||
op := tokenToBinaryOperation(ops.Pop().Type)
|
||||
|
||||
start, _ := l.Bounds()
|
||||
_, end := l.Bounds()
|
||||
|
||||
values.Push(&BinaryNode{
|
||||
op,
|
||||
l,
|
||||
r,
|
||||
start,
|
||||
end,
|
||||
})
|
||||
reduce()
|
||||
}
|
||||
|
||||
return values.Pop(), nil
|
||||
|
|
@ -573,7 +540,7 @@ func (p *Parser) chain() (Node, error) {
|
|||
|
||||
f = &AccessNode{
|
||||
f,
|
||||
p.prev.Lexeme,
|
||||
p.prev,
|
||||
name.Start,
|
||||
name.End,
|
||||
}
|
||||
|
|
@ -602,6 +569,24 @@ func (p *Parser) chain() (Node, error) {
|
|||
f,
|
||||
args,
|
||||
|
||||
start,
|
||||
p.prev.End,
|
||||
}
|
||||
} else if p.accept(TokenOpenBracket) {
|
||||
start := p.prev.Start
|
||||
|
||||
index, err := p.expression(false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := p.expect(TokenCloseBracket, "opening bracket must be closed"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
f = &IndexNode{
|
||||
f,
|
||||
index,
|
||||
start,
|
||||
p.prev.End,
|
||||
}
|
||||
|
|
@ -716,7 +701,7 @@ func (p *Parser) factor() (Node, error) {
|
|||
}
|
||||
}
|
||||
|
||||
value, err := p.condition()
|
||||
value, err := p.expression(false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -736,7 +721,7 @@ func (p *Parser) factor() (Node, error) {
|
|||
// unary minus
|
||||
case TokenMinus:
|
||||
p.advance()
|
||||
first := p.prev
|
||||
op := p.prev
|
||||
|
||||
f, err := p.factor()
|
||||
if err != nil {
|
||||
|
|
@ -745,13 +730,14 @@ func (p *Parser) factor() (Node, error) {
|
|||
return &UnaryNode{
|
||||
UnaryNegate,
|
||||
f,
|
||||
first.Start,
|
||||
op,
|
||||
op.Start,
|
||||
p.prev.End,
|
||||
}, nil
|
||||
|
||||
case TokenBang:
|
||||
p.advance()
|
||||
start := p.prev.Start
|
||||
op := p.prev
|
||||
|
||||
v, err := p.factor()
|
||||
if err != nil {
|
||||
|
|
@ -761,7 +747,8 @@ func (p *Parser) factor() (Node, error) {
|
|||
return &UnaryNode{
|
||||
UnaryNot,
|
||||
v,
|
||||
start,
|
||||
op,
|
||||
op.Start,
|
||||
p.prev.End,
|
||||
}, nil
|
||||
|
||||
|
|
@ -799,32 +786,54 @@ func (p *Parser) factor() (Node, error) {
|
|||
p.advance()
|
||||
start := p.prev.Start
|
||||
|
||||
var name *Token
|
||||
if p.accept(TokenName) { // can be unnamed, but accept name if it is named
|
||||
name = p.prev
|
||||
}
|
||||
|
||||
params, err := p.parseParams()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var sig TypeSignature = &NilSignature{}
|
||||
var yield TypeSignature
|
||||
if p.accept(TokenArrow) {
|
||||
sig, err = p.parseSignature()
|
||||
yield, err = p.parseSignature()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
b, err := p.block(false)
|
||||
logic, err := p.expression(true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &FunctionNode{
|
||||
"*",
|
||||
names := "*"
|
||||
if name != nil {
|
||||
names = name.Lexeme
|
||||
}
|
||||
|
||||
fn := &FunctionNode{
|
||||
names,
|
||||
params,
|
||||
sig,
|
||||
b,
|
||||
yield,
|
||||
logic,
|
||||
start,
|
||||
p.prev.End,
|
||||
}, nil
|
||||
}
|
||||
|
||||
if name != nil {
|
||||
return &AssignNode{
|
||||
&ReferenceNode{name.Lexeme, name.Start, name.End},
|
||||
fn,
|
||||
true,
|
||||
start,
|
||||
p.prev.End,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return fn, nil
|
||||
|
||||
case TokenOpenParenthesis:
|
||||
p.advance()
|
||||
|
|
@ -889,440 +898,6 @@ func (p *Parser) factor() (Node, error) {
|
|||
}
|
||||
}
|
||||
|
||||
func (p *Parser) prop() (Node, error) {
|
||||
start := p.curr.Start
|
||||
|
||||
v, err := p.factor()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// parse chains of prop-getting ( "".split().join().length.round() )
|
||||
for p.accept(TokenDot) {
|
||||
if err := p.expect(TokenName, "property must be a name"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
property := (*p.prev).Lexeme
|
||||
|
||||
v = &AccessNode{
|
||||
v,
|
||||
property,
|
||||
start,
|
||||
p.prev.End,
|
||||
}
|
||||
|
||||
// if called, also add
|
||||
if (*p.curr).Type == TokenOpenParenthesis {
|
||||
args, err := p.parseArgs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
v = &InvokeNode{
|
||||
v,
|
||||
args,
|
||||
start,
|
||||
p.prev.End,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func (p *Parser) product() (Node, error) {
|
||||
start := p.curr.Start
|
||||
left, err := p.prop()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for p.accept(TokenStar) || p.accept(TokenSlash) {
|
||||
op := BinaryMultiplication
|
||||
|
||||
if (*p.prev).Type == TokenSlash {
|
||||
op = BinaryDivision
|
||||
}
|
||||
|
||||
f, err := p.prop()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
left = &BinaryNode{
|
||||
op,
|
||||
left,
|
||||
f,
|
||||
start,
|
||||
p.prev.End,
|
||||
}
|
||||
}
|
||||
|
||||
return left, nil
|
||||
}
|
||||
|
||||
func (p *Parser) term() (Node, error) {
|
||||
start := p.curr.Start
|
||||
|
||||
left, err := p.product()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for p.accept(TokenPlus) || p.accept(TokenMinus) {
|
||||
op := BinaryAddition
|
||||
|
||||
if (*p.prev).Type == TokenMinus {
|
||||
op = BinarySubtraction
|
||||
}
|
||||
|
||||
pr, err := p.product()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
left = &BinaryNode{
|
||||
op,
|
||||
left,
|
||||
pr,
|
||||
start,
|
||||
p.prev.End,
|
||||
}
|
||||
}
|
||||
|
||||
return left, nil
|
||||
}
|
||||
|
||||
func (p *Parser) comparison() (Node, error) {
|
||||
start := p.curr.Start
|
||||
left, err := p.term()
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
op := BinaryEquality
|
||||
|
||||
switch (*p.curr).Type {
|
||||
case TokenEquals:
|
||||
op = BinaryEquality
|
||||
case TokenBangEquals:
|
||||
op = BinaryInequality
|
||||
case TokenGreaterThan:
|
||||
op = BinaryGreater
|
||||
case TokenLessThan:
|
||||
op = BinaryLess
|
||||
case TokenLessThanOrEqual:
|
||||
op = BinaryLessEqual
|
||||
case TokenGreaterThanOrEqual:
|
||||
op = BinaryGreaterEqual
|
||||
default:
|
||||
return left, nil
|
||||
}
|
||||
|
||||
p.advance()
|
||||
|
||||
t, err := p.term()
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &BinaryNode{
|
||||
op,
|
||||
left,
|
||||
t,
|
||||
start,
|
||||
p.prev.End,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *Parser) condition() (Node, error) {
|
||||
start := p.curr.Start
|
||||
left, err := p.comparison()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
op := BinaryEquality
|
||||
|
||||
switch (*p.curr).Type {
|
||||
case TokenDoubleAmpersand:
|
||||
op = BinaryAnd
|
||||
case TokenDoublePipe:
|
||||
op = BinaryOr
|
||||
default:
|
||||
return left, nil
|
||||
}
|
||||
|
||||
p.advance()
|
||||
|
||||
c, err := p.condition()
|
||||
if err != nil {
|
||||
return left, err
|
||||
}
|
||||
|
||||
return &BinaryNode{
|
||||
op,
|
||||
left,
|
||||
c,
|
||||
start,
|
||||
p.prev.End,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *Parser) statement() (Node, error) {
|
||||
switch (*p.curr).Type {
|
||||
case TokenIf:
|
||||
start := p.curr.Start
|
||||
p.advance()
|
||||
|
||||
condition, err := p.condition()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
then, err := p.block(false)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var otherwise Node
|
||||
|
||||
if p.accept(TokenElse) {
|
||||
// allow else if
|
||||
if p.curr.Type == TokenIf {
|
||||
otherwise, err = p.statement()
|
||||
} else {
|
||||
otherwise, err = p.block(false)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &ConditionalNode{
|
||||
condition,
|
||||
then,
|
||||
otherwise,
|
||||
start,
|
||||
p.prev.End,
|
||||
}, nil
|
||||
|
||||
case TokenName:
|
||||
p.advance()
|
||||
name := p.prev
|
||||
|
||||
if (*p.curr).Type == TokenDot {
|
||||
var v Node = &ReferenceNode{
|
||||
name.Lexeme,
|
||||
name.Start,
|
||||
name.End,
|
||||
}
|
||||
|
||||
// parse chains of prop-getting ( "".split().join().length.round() )
|
||||
for p.accept(TokenDot) {
|
||||
if err := p.expect(TokenName, "property must be name"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
property := (*p.prev).Lexeme
|
||||
|
||||
v = &AccessNode{
|
||||
v,
|
||||
property,
|
||||
name.Start,
|
||||
p.prev.End,
|
||||
}
|
||||
|
||||
// if called, also add
|
||||
if (*p.curr).Type == TokenOpenParenthesis {
|
||||
args, err := p.parseArgs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
v = &InvokeNode{
|
||||
v,
|
||||
args,
|
||||
name.Start,
|
||||
p.prev.End,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return v, nil
|
||||
} else if p.curr.Type == TokenOpenParenthesis {
|
||||
args, err := p.parseArgs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &InvokeNode{
|
||||
&ReferenceNode{
|
||||
name.Lexeme,
|
||||
name.Start,
|
||||
name.End,
|
||||
},
|
||||
args,
|
||||
name.Start,
|
||||
p.prev.End,
|
||||
}, nil
|
||||
} else if p.accept(TokenAssign) || p.accept(TokenDeclare) {
|
||||
isDeclaration := p.prev.Type == TokenDeclare
|
||||
c, err := p.condition()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &AssignNode{ // THIS COULD BE MORE PERMISSIVE; its a new system
|
||||
&ReferenceNode{
|
||||
name.Lexeme,
|
||||
name.Start,
|
||||
name.End,
|
||||
},
|
||||
c,
|
||||
isDeclaration,
|
||||
name.Start,
|
||||
p.prev.End,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return nil, p.error("invalid statement", p.curr)
|
||||
|
||||
case TokenFunc:
|
||||
p.advance()
|
||||
|
||||
funcStart := p.prev.Start
|
||||
|
||||
if err := p.expect(TokenName, "function must have a name"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
name := p.prev
|
||||
|
||||
params, err := p.parseParams()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var yield TypeSignature = &NilSignature{}
|
||||
if p.accept(TokenArrow) {
|
||||
yield, err = p.parseSignature()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
b, err := p.block(false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &AssignNode{
|
||||
&ReferenceNode{
|
||||
name.Lexeme,
|
||||
name.Start,
|
||||
name.End,
|
||||
},
|
||||
&FunctionNode{
|
||||
name.Lexeme,
|
||||
params,
|
||||
yield,
|
||||
b,
|
||||
funcStart,
|
||||
p.prev.End,
|
||||
},
|
||||
true,
|
||||
funcStart,
|
||||
p.prev.End,
|
||||
}, nil
|
||||
|
||||
case TokenWhile:
|
||||
p.advance()
|
||||
start := p.prev.Start
|
||||
|
||||
c, err := p.condition()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
b, err := p.block(false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &LoopNode{
|
||||
c,
|
||||
b,
|
||||
start,
|
||||
p.prev.End,
|
||||
}, nil
|
||||
|
||||
case TokenReturn:
|
||||
p.advance()
|
||||
start := p.prev.Start
|
||||
|
||||
c, err := p.condition()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &ReturnNode{
|
||||
c,
|
||||
start,
|
||||
p.prev.End,
|
||||
}, nil
|
||||
|
||||
case TokenBreakpoint:
|
||||
p.advance()
|
||||
|
||||
return &BreakpointNode{}, nil
|
||||
|
||||
case TokenImport:
|
||||
defer p.advance()
|
||||
return nil, p.error("import statements must be top-level", p.curr)
|
||||
|
||||
default:
|
||||
defer p.advance()
|
||||
return nil, p.error("invalid statement", p.curr)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Parser) block(canBeStatement bool) (Node, error) {
|
||||
if canBeStatement {
|
||||
if !p.accept(TokenOpenBrace) {
|
||||
if p.curr.Type == TokenEOF {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return p.statement()
|
||||
}
|
||||
} else {
|
||||
if err := p.expect(TokenOpenBrace, "a block is required"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
start := p.prev.Start
|
||||
|
||||
statements := make([]Node, 0)
|
||||
|
||||
for !p.accept(TokenCloseBrace) {
|
||||
s, err := p.statement()
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
statements = append(statements, s)
|
||||
}
|
||||
|
||||
return &BlockNode{
|
||||
statements,
|
||||
start,
|
||||
p.prev.End,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseArgs() ([]Node, error) {
|
||||
args := make([]Node, 0)
|
||||
|
||||
|
|
@ -1514,7 +1089,9 @@ func (p *Parser) parseSignature() (TypeSignature, error) {
|
|||
s = &AnySignature{}
|
||||
|
||||
default:
|
||||
return nil, p.error("unsupported type: "+name, p.prev)
|
||||
s = &NamedSignature{
|
||||
name,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue