Add variables

This commit is contained in:
Anton Medvedev
2023-08-22 22:30:07 +02:00
parent 0ffe62c02f
commit ed5f9bfbcb
15 changed files with 179 additions and 16 deletions
+11
View File
@@ -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 {
+3 -1
View File
@@ -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)
}
+21
View File
@@ -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 {
+11
View File
@@ -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})