Skip to content

Commit

Permalink
Merge pull request #21 from chrehall68/20-bug-indexed-assigns-are-mar…
Browse files Browse the repository at this point in the history
…ked-as-errors

[Fix] indexed assigns
  • Loading branch information
chrehall68 authored Nov 21, 2024
2 parents c731d54 + 893347f commit 557fcec
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 4 deletions.
8 changes: 8 additions & 0 deletions server/internal/lang/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,14 @@ func (i *Interpreter) diagnoseAssignmentNode(node AssignmentNode, curSymbols map
if !ok {
i.addUnknownDiagnostic(variable.Identifier, "variable")
}
for _, selector := range variable.Selectors {
if selector.IndexNode != nil {
i.diagnoseExpression(selector.IndexNode.Index, curSymbols)
} else if selector.RangeNode != nil {
i.diagnoseExpression(selector.RangeNode.From, curSymbols)
i.diagnoseExpression(selector.RangeNode.To, curSymbols)
}
}
}
// also check the right hand side
i.diagnoseExpression(node.Value, knownSymbols)
Expand Down
32 changes: 28 additions & 4 deletions server/internal/lang/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,15 @@ type DirectiveNode struct {
DefineNode *DefineNode
}
type AssignmentNode struct {
Variables []VariableNode
Variables []AssignmentVariableNode
Value ExprNode
IsAssign bool
IsDelayedAssign bool // true if used <= instead of =
}
type AssignmentVariableNode struct {
Identifier Token
Selectors []SelectorNode
}
type IndexNode struct {
Index ExprNode
}
Expand Down Expand Up @@ -697,7 +701,7 @@ func (p *Parser) parseVariableNode(tokens []Token, pos int) (result VariableNode
newPos = pos
return
}
func (p *Parser) parseAssignables(tokens []Token, pos int) (result []VariableNode, newPos int, err error) {
func (p *Parser) parseAssignables(tokens []Token, pos int) (result []AssignmentVariableNode, newPos int, err error) {
// <assignable> -> [LCURL] <single_var> {COMMA <single_var>} [RCURL]
potentialPos, e := p.checkToken("assignables", []string{"lcurl"}, pos, tokens)
// it's ok if it fails since it's optional
Expand All @@ -708,7 +712,7 @@ func (p *Parser) parseAssignables(tokens []Token, pos int) (result []VariableNod
}

// get the first assignable
assignable, potentialPos, e := p.parseVariableNode(tokens, pos)
assignable, potentialPos, e := p.parseAssignableVariable(tokens, pos)
if e != nil { // first must succeed
err = e
return
Expand All @@ -718,7 +722,7 @@ func (p *Parser) parseAssignables(tokens []Token, pos int) (result []VariableNod
// now try taking the rest
potentialPos, e = p.checkToken("assignables", []string{"comma"}, pos, tokens)
for e == nil {
assignable, potentialPos, e = p.parseVariableNode(tokens, potentialPos+1)
assignable, potentialPos, e = p.parseAssignableVariable(tokens, potentialPos+1)
if e != nil {
err = e
return
Expand All @@ -740,6 +744,25 @@ func (p *Parser) parseAssignables(tokens []Token, pos int) (result []VariableNod
return

}
func (p *Parser) parseAssignableVariable(tokens []Token, pos int) (result AssignmentVariableNode, newPos int, err error) {
// <assignable_variable> -> <identifier> {<selector>}
pos, err = p.checkToken("assignmentvariable", []string{"identifier"}, pos, tokens)
if err != nil {
return
}
result.Identifier = tokens[pos]
pos++

// take selectors
selector, potentialPos, e := p.parseSelectorNode(tokens, pos)
for e == nil {
result.Selectors = append(result.Selectors, selector)
pos = potentialPos
selector, potentialPos, e = p.parseSelectorNode(tokens, pos)
}
newPos = pos
return
}
func (p *Parser) parseAssignmentNodeWithoutSemicolon(tokens []Token, pos int) (result AssignmentNode, newPos int, err error) {
//<assignment_without_semicolon> -> [ASSIGN] <assignable> (EQUAL | <=) <expr>
potentialPos, e := p.checkToken("assignment", []string{"assign"}, pos, tokens)
Expand Down Expand Up @@ -2046,6 +2069,7 @@ Grammar:
<task> -> TASK <identifier> SEMICOLON <always_statement> ENDTASK [SEMICOLON]
<assignable> -> [LCURL] <single_var> {COMMA <single_var>} [RCURL]
<assignable_var> -> <identifier> {<selector>}
<assignment_without_semicolon> -> [ASSIGN] <assignable> (EQUAL | <=) <expr>
<assignment> -> <assignment_without_semicolon> SEMICOLON
<single_var> -> <identifier> {<range>}
Expand Down

0 comments on commit 557fcec

Please sign in to comment.