selectors support for hash
Some checks failed
Build / build (push) Successful in 10m20s
Test / build (push) Failing after 16m7s

This commit is contained in:
Chuck Smith
2024-03-21 16:39:31 -04:00
parent d3471af03d
commit 66d5453ecc
8 changed files with 98 additions and 2 deletions

View File

@@ -35,6 +35,7 @@ var precedences = map[token.TokenType]int{
token.ASTERISK: PRODUCT,
token.LPAREN: CALL,
token.LBRACKET: INDEX,
token.DOT: INDEX,
}
type (
@@ -89,6 +90,7 @@ func New(l *lexer.Lexer) *Parser {
p.registerInfix(token.LPAREN, p.parseCallExpression)
p.registerInfix(token.LBRACKET, p.parseIndexExpression)
p.registerInfix(token.ASSIGN, p.parseAssignmentExpression)
p.registerInfix(token.DOT, p.parseSelectorExpression)
// Read two tokens, so curToken and peekToken are both set
p.nextToken()
@@ -570,3 +572,9 @@ func (p *Parser) parseComment() ast.Statement {
func (p *Parser) parseNull() ast.Expression {
return &ast.Null{Token: p.curToken}
}
func (p *Parser) parseSelectorExpression(expression ast.Expression) ast.Expression {
p.expectPeek(token.IDENT)
index := &ast.StringLiteral{Token: p.curToken, Value: p.curToken.Literal}
return &ast.IndexExpression{Left: expression, Index: index}
}

View File

@@ -358,6 +358,10 @@ func TestOperatorPrecedenceParsing(t *testing.T) {
"add(a * b[2], b[1], 2 * [1, 2][1])",
"add((a * (b[2])), (b[1]), (2 * ([1, 2][1])))",
},
{
"d.foo * d.bar",
"((d[foo]) * (d[bar]))",
},
}
for _, tt := range tests {
@@ -831,6 +835,40 @@ func TestParsingArrayLiterals(t *testing.T) {
testInfixExpression(t, array.Elements[2], 3, "+", 3)
}
func TestParsingSelectorExpressions(t *testing.T) {
input := "myHash.foo"
l := lexer.New(input)
p := New(l)
program := p.ParseProgram()
checkParserErrors(t, p)
stmt, ok := program.Statements[0].(*ast.ExpressionStatement)
t.Logf("stmt: %#v", stmt)
exp, ok := stmt.Expression.(*ast.IndexExpression)
if !ok {
t.Fatalf("exp not *ast.IndexExpression. got=%T", stmt.Expression)
}
ident, ok := exp.Left.(*ast.Identifier)
if !ok {
t.Fatalf("exp.Left not *ast.Identifier. got=%T", stmt.Expression)
}
if !testIdentifier(t, ident, "myHash") {
return
}
index, ok := exp.Index.(*ast.StringLiteral)
if !ok {
t.Fatalf("exp.Index not *ast.StringLiteral. got=%T", stmt.Expression)
}
if index.Value != "foo" {
t.Fatalf("index.Value != \"foo\"")
}
}
func TestParsingIndexExpressions(t *testing.T) {
input := "myArray[1 + 1]"