mirror of
https://github.com/hanzoai/expr.git
synced 2026-09-24 16:58:58 +00:00
Add variables
This commit is contained in:
@@ -188,6 +188,17 @@ func TestLex(t *testing.T) {
|
||||
{Kind: EOF},
|
||||
},
|
||||
},
|
||||
{
|
||||
`let foo = bar;`,
|
||||
[]Token{
|
||||
{Kind: Operator, Value: "let"},
|
||||
{Kind: Identifier, Value: "foo"},
|
||||
{Kind: Operator, Value: "="},
|
||||
{Kind: Identifier, Value: "bar"},
|
||||
{Kind: Operator, Value: ";"},
|
||||
{Kind: EOF},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
||||
@@ -37,7 +37,7 @@ func root(l *lexer) stateFn {
|
||||
l.emit(Bracket)
|
||||
case strings.ContainsRune(")]}", r):
|
||||
l.emit(Bracket)
|
||||
case strings.ContainsRune("#,:%+-^", r): // single rune operator
|
||||
case strings.ContainsRune("#,:;%+-^", r): // single rune operator
|
||||
l.emit(Operator)
|
||||
case strings.ContainsRune("&!=*<>", r): // possible double rune operator
|
||||
l.accept("&=*")
|
||||
@@ -124,6 +124,8 @@ loop:
|
||||
return not
|
||||
case "in", "or", "and", "matches", "contains", "startsWith", "endsWith":
|
||||
l.emit(Operator)
|
||||
case "let":
|
||||
l.emit(Operator)
|
||||
default:
|
||||
l.emit(Identifier)
|
||||
}
|
||||
|
||||
@@ -110,6 +110,12 @@ func (p *parser) expect(kind Kind, values ...string) {
|
||||
// parse functions
|
||||
|
||||
func (p *parser) parseExpression(precedence int) Node {
|
||||
if precedence == 0 {
|
||||
if p.current.Is(Operator, "let") {
|
||||
return p.parseVariableDeclaration()
|
||||
}
|
||||
}
|
||||
|
||||
nodeLeft := p.parsePrimary()
|
||||
|
||||
prevOperator := ""
|
||||
@@ -179,6 +185,21 @@ func (p *parser) parseExpression(precedence int) Node {
|
||||
return nodeLeft
|
||||
}
|
||||
|
||||
func (p *parser) parseVariableDeclaration() Node {
|
||||
p.expect(Operator, "let")
|
||||
variableName := p.current
|
||||
p.expect(Identifier)
|
||||
p.expect(Operator, "=")
|
||||
value := p.parseExpression(0)
|
||||
p.expect(Operator, ";")
|
||||
node := p.parseExpression(0)
|
||||
return &VariableDeclaratorNode{
|
||||
Name: variableName.Value,
|
||||
Value: value,
|
||||
Expr: node,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *parser) parseConditional(node Node) Node {
|
||||
var expr1, expr2 Node
|
||||
for p.current.Is(Operator, "?") && p.err == nil {
|
||||
|
||||
@@ -452,6 +452,17 @@ func TestParse(t *testing.T) {
|
||||
Callee: &IdentifierNode{Value: "ok"},
|
||||
Arguments: []Node{
|
||||
&BoolNode{Value: true}}}},
|
||||
{
|
||||
`let foo = a + b; foo + c`,
|
||||
&VariableDeclaratorNode{
|
||||
Name: "foo",
|
||||
Value: &BinaryNode{Operator: "+",
|
||||
Left: &IdentifierNode{Value: "a"},
|
||||
Right: &IdentifierNode{Value: "b"}},
|
||||
Expr: &BinaryNode{Operator: "+",
|
||||
Left: &IdentifierNode{Value: "foo"},
|
||||
Right: &IdentifierNode{Value: "c"}}},
|
||||
},
|
||||
}
|
||||
for _, test := range parseTests {
|
||||
actual, err := parser.ParseWithConfig(test.input, &conf.Config{Pipes: true})
|
||||
|
||||
Reference in New Issue
Block a user