Simplified block parsing

This commit is contained in:
Eduard Urbach 2024-07-16 12:01:38 +02:00
parent 448af0707a
commit d1ccd60139
Signed by: akyoto
GPG Key ID: C874F672B1AF20C0

View File

@ -27,12 +27,14 @@ 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:
if keywordHasBlock(word) {
blockStart := tokens.IndexKind(token.BlockStart)
blockEnd := tokens.LastIndexKind(token.BlockEnd)
@ -45,29 +47,20 @@ func toASTNode(tokens token.List) (Node, error) {
}
body, err := Parse(tokens[blockStart+1 : blockEnd])
return &Loop{Body: body}, err
switch word {
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)
case keyword.Loop:
return &Loop{Body: body}, err
}
}
return nil, errors.New(&errors.KeywordNotImplemented{Keyword: word}, nil, tokens[0].Position)
}
expr := expression.Parse(tokens)
if expr == nil {
@ -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
}