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.
|
// toASTNode generates an AST node from an instruction.
|
||||||
func toASTNode(tokens token.List) (Node, error) {
|
func toASTNode(tokens token.List) (Node, error) {
|
||||||
if tokens[0].Kind == token.Keyword {
|
if tokens[0].Kind == token.Keyword {
|
||||||
switch tokens[0].Text() {
|
word := tokens[0].Text()
|
||||||
case keyword.Return:
|
|
||||||
|
if word == keyword.Return {
|
||||||
value := expression.Parse(tokens[1:])
|
value := expression.Parse(tokens[1:])
|
||||||
return &Return{Value: value}, nil
|
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)
|
expr := expression.Parse(tokens)
|
||||||
@ -115,3 +108,8 @@ func IsFunctionCall(expr *expression.Expression) bool {
|
|||||||
func IsVariableDefinition(expr *expression.Expression) bool {
|
func IsVariableDefinition(expr *expression.Expression) bool {
|
||||||
return expr.Token.Kind == token.Operator && expr.Token.Text() == ":="
|
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