Simplified block parsing
This commit is contained in:
parent
448af0707a
commit
d1ccd60139
@ -27,45 +27,38 @@ func Parse(tokens token.List) (AST, error) {
|
||||
// toASTNode generates an AST node from an instruction.
|
||||
func toASTNode(tokens token.List) (Node, error) {
|
||||
if tokens[0].Kind == token.Keyword {
|
||||
switch tokens[0].Text() {
|
||||
case keyword.Return:
|
||||
word := tokens[0].Text()
|
||||
|
||||
if word == keyword.Return {
|
||||
value := expression.Parse(tokens[1:])
|
||||
return &Return{Value: value}, nil
|
||||
|
||||
case keyword.Loop:
|
||||
blockStart := tokens.IndexKind(token.BlockStart)
|
||||
blockEnd := tokens.LastIndexKind(token.BlockEnd)
|
||||
|
||||
if blockStart == -1 {
|
||||
return nil, errors.New(errors.MissingBlockStart, nil, tokens[0].End())
|
||||
}
|
||||
|
||||
if blockEnd == -1 {
|
||||
return nil, errors.New(errors.MissingBlockEnd, nil, tokens[len(tokens)-1].End())
|
||||
}
|
||||
|
||||
body, err := Parse(tokens[blockStart+1 : blockEnd])
|
||||
return &Loop{Body: body}, err
|
||||
|
||||
case keyword.If:
|
||||
blockStart := tokens.IndexKind(token.BlockStart)
|
||||
blockEnd := tokens.LastIndexKind(token.BlockEnd)
|
||||
|
||||
if blockStart == -1 {
|
||||
return nil, errors.New(errors.MissingBlockStart, nil, tokens[0].End())
|
||||
}
|
||||
|
||||
if blockEnd == -1 {
|
||||
return nil, errors.New(errors.MissingBlockEnd, nil, tokens[len(tokens)-1].End())
|
||||
}
|
||||
|
||||
condition := expression.Parse(tokens[1:blockStart])
|
||||
body, err := Parse(tokens[blockStart+1 : blockEnd])
|
||||
return &If{Condition: condition, Body: body}, err
|
||||
|
||||
default:
|
||||
return nil, errors.New(&errors.KeywordNotImplemented{Keyword: tokens[0].Text()}, nil, tokens[0].Position)
|
||||
}
|
||||
|
||||
if keywordHasBlock(word) {
|
||||
blockStart := tokens.IndexKind(token.BlockStart)
|
||||
blockEnd := tokens.LastIndexKind(token.BlockEnd)
|
||||
|
||||
if blockStart == -1 {
|
||||
return nil, errors.New(errors.MissingBlockStart, nil, tokens[0].End())
|
||||
}
|
||||
|
||||
if blockEnd == -1 {
|
||||
return nil, errors.New(errors.MissingBlockEnd, nil, tokens[len(tokens)-1].End())
|
||||
}
|
||||
|
||||
body, err := Parse(tokens[blockStart+1 : blockEnd])
|
||||
|
||||
switch word {
|
||||
case keyword.If:
|
||||
condition := expression.Parse(tokens[1:blockStart])
|
||||
return &If{Condition: condition, Body: body}, err
|
||||
|
||||
case keyword.Loop:
|
||||
return &Loop{Body: body}, err
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errors.New(&errors.KeywordNotImplemented{Keyword: word}, nil, tokens[0].Position)
|
||||
}
|
||||
|
||||
expr := expression.Parse(tokens)
|
||||
@ -115,3 +108,8 @@ func IsFunctionCall(expr *expression.Expression) bool {
|
||||
func IsVariableDefinition(expr *expression.Expression) bool {
|
||||
return expr.Token.Kind == token.Operator && expr.Token.Text() == ":="
|
||||
}
|
||||
|
||||
// keywordHasBlock returns true if the keyword requires a block.
|
||||
func keywordHasBlock(word string) bool {
|
||||
return word == keyword.If || word == keyword.Loop
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user