Add structured coroutines and explicit error handling
This commit is contained in:
parent
de1262b4cf
commit
fe62e81152
31 changed files with 1701 additions and 325 deletions
|
|
@ -137,7 +137,7 @@ func (p *parser) parseProgram() (*Program, error) {
|
|||
return nil, err
|
||||
}
|
||||
prog.Workers = append(prog.Workers, decl)
|
||||
case p.check(tokenFun):
|
||||
case p.check(tokenFun) || p.check(tokenSuspend):
|
||||
fn, err := p.parseFunction()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -320,7 +320,7 @@ func (p *parser) parseClass() (ClassDecl, error) {
|
|||
var methods []FunctionDecl
|
||||
for !p.check(tokenRBrace) && !p.check(tokenEOF) {
|
||||
p.match(tokenOverride)
|
||||
if !p.check(tokenFun) {
|
||||
if !p.check(tokenFun) && !p.check(tokenSuspend) {
|
||||
tok := p.peek()
|
||||
return ClassDecl{}, fmt.Errorf("expected class member at %d, found %q", tok.pos, tok.lexeme)
|
||||
}
|
||||
|
|
@ -538,10 +538,12 @@ func (p *parser) parseFunction() (FunctionDecl, error) {
|
|||
Params: signature.Params,
|
||||
ReturnType: signature.ReturnType,
|
||||
Body: body,
|
||||
Suspend: signature.Suspend,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *parser) parseFunctionSignature() (FunctionSignature, error) {
|
||||
suspend := p.match(tokenSuspend)
|
||||
if _, err := p.expect(tokenFun, "expected 'fun'"); err != nil {
|
||||
return FunctionSignature{}, err
|
||||
}
|
||||
|
|
@ -573,6 +575,7 @@ func (p *parser) parseFunctionSignature() (FunctionSignature, error) {
|
|||
Name: name.lexeme,
|
||||
Params: params,
|
||||
ReturnType: returnType,
|
||||
Suspend: suspend,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
@ -620,6 +623,9 @@ func (p *parser) parseBlock() ([]Stmt, error) {
|
|||
}
|
||||
|
||||
func (p *parser) parseStmt() (Stmt, error) {
|
||||
if p.check(tokenIdent) && p.peek().lexeme == "go" {
|
||||
return nil, fmt.Errorf("bare go is removed; use launch inside a coroutine scope")
|
||||
}
|
||||
switch {
|
||||
case p.match(tokenVal):
|
||||
return p.parseVarDecl(false)
|
||||
|
|
@ -1105,6 +1111,16 @@ func (p *parser) parsePostfix(expr Expr) (Expr, error) {
|
|||
return nil, fmt.Errorf("expected selector name at %d, found %q", name.pos, name.lexeme)
|
||||
}
|
||||
expr = SelectorExpr{Receiver: expr, Name: name.lexeme}
|
||||
case p.match(tokenSafeDot):
|
||||
name := p.advance()
|
||||
if !selectorName(name.lexeme) {
|
||||
return nil, fmt.Errorf("expected selector name at %d, found %q", name.pos, name.lexeme)
|
||||
}
|
||||
expr = SafeSelectorExpr{Receiver: expr, Name: name.lexeme}
|
||||
case p.match(tokenDoubleBang):
|
||||
expr = NonNullExpr{Value: expr}
|
||||
case p.match(tokenQuestion):
|
||||
expr = TryExpr{Value: expr}
|
||||
case p.match(tokenLBracket):
|
||||
index, err := p.parseExpr(0)
|
||||
if err != nil {
|
||||
|
|
@ -1122,6 +1138,10 @@ func (p *parser) parsePostfix(expr Expr) (Expr, error) {
|
|||
if !hasTypeArgs {
|
||||
return expr, nil
|
||||
}
|
||||
if p.check(tokenLBrace) {
|
||||
expr = CallExpr{Callee: expr, TypeArgs: typeArgs}
|
||||
continue
|
||||
}
|
||||
if _, err := p.expect(tokenLParen, "expected '(' after generic type arguments"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -1149,6 +1169,8 @@ func (p *parser) parsePostfix(expr Expr) (Expr, error) {
|
|||
call = current
|
||||
case SelectorExpr:
|
||||
call = CallExpr{Callee: current}
|
||||
case IdentExpr:
|
||||
call = CallExpr{Callee: current}
|
||||
default:
|
||||
return expr, nil
|
||||
}
|
||||
|
|
@ -1236,7 +1258,7 @@ func (p *parser) tryParseCallTypeArgs() ([]string, bool, error) {
|
|||
p.pos = saved
|
||||
return nil, false, nil
|
||||
}
|
||||
if !p.check(tokenLParen) {
|
||||
if !p.check(tokenLParen) && !p.check(tokenLBrace) {
|
||||
p.pos = saved
|
||||
return nil, false, nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue