umx_compiler

UMX virtual machine "Monkey" interpreter / bytecode compiler
git clone git://bsandro.tech/umx_compiler
Log | Files | Refs

commit 7d6e6f37956eefb874d3032c48a625271e259cc2
parent 6632cd6350f82b751a0f6c4e720b8c216e1d4dad
Author: bsandro <email@bsandro.tech>
Date:   Thu, 16 Jun 2022 01:56:50 +0300

Parser tests improvement

Diffstat:
Mparser/parser_test.go | 64++++++++++++++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 50 insertions(+), 14 deletions(-)

diff --git a/parser/parser_test.go b/parser/parser_test.go @@ -239,20 +239,7 @@ func TestParsingInfixExpressions(t *testing.T) { t.Fatalf("statement is not ExpressionStatement but %T", prg.Statements[0]) } - expr, ok := statement.Expression.(*ast.InfixExpression) - if !ok { - t.Fatalf("Statement.Expression is not Infix but %T", statement.Expression) - } - - if !testIntegerLiteral(t, expr.Left, tt.leftValue) { - return - } - if expr.Operator != tt.operator { - t.Fatalf("expr.Operator is not %s but %s", tt.operator, expr.Operator) - } - if !testIntegerLiteral(t, expr.Right, tt.rightValue) { - return - } + testInfixExpression(t, statement.Expression, tt.leftValue, tt.operator, tt.rightValue) } } @@ -273,6 +260,55 @@ func testIntegerLiteral(t *testing.T, il ast.Expression, value int64) bool { return true } +func testIdentifier(t *testing.T, expr ast.Expression, value string) bool { + ident, ok := expr.(*ast.Identifier) + if !ok { + t.Errorf("expr is not *ast.Identifier but %T", expr) + return false + } + if ident.Value != value { + t.Errorf("ident.Value is not %s but %s", value, ident.Value) + return false + } + if ident.TokenLiteral() != value { + t.Errorf("ident.TokenLiteral() is not %s but %s", value, ident.TokenLiteral()) + return false + } + return true +} + +func testLiteralExpression(t *testing.T, expr ast.Expression, expected interface{}) bool { + switch v := expected.(type) { + case int: + return testIntegerLiteral(t, expr, int64(v)) + case int64: + return testIntegerLiteral(t, expr, v) + case string: + return testIdentifier(t, expr, v) + } + t.Errorf("expr type is not handled: %T", expr) + return false +} + +func testInfixExpression(t *testing.T, expr ast.Expression, left interface{}, operator string, right interface{}) bool { + opExpr, ok := expr.(*ast.InfixExpression) + if !ok { + t.Errorf("expr is not *ast.InfixExpression but %T", expr) + return false + } + if !testLiteralExpression(t, opExpr.Left, left) { + return false + } + if opExpr.Operator != operator { + t.Errorf("opExpr.Operator is not %q but %q", operator, opExpr.Operator) + return false + } + if !testLiteralExpression(t, opExpr.Right, right) { + return false + } + return true +} + func TestOperatorPrecedenceParsing(t *testing.T) { tests := []struct { input string