package parser_test import ( "testing" "git.sharkk.net/Sharkk/Mako/parser" ) func TestBasicEchoStatement(t *testing.T) { tests := []struct { input string expectedVal any isExpr bool desc string }{ {`echo 42`, 42.0, false, "echo number"}, {`echo "hello"`, "hello", false, "echo string"}, {`echo true`, true, false, "echo boolean"}, {`echo nil`, nil, false, "echo nil"}, {`echo x`, "x", false, "echo identifier"}, {`echo 1 + 2`, "(1.00 + 2.00)", true, "echo expression"}, } for _, tt := range tests { t.Run(tt.desc, func(t *testing.T) { l := parser.NewLexer(tt.input) p := parser.NewParser(l) program := p.ParseProgram() checkParserErrors(t, p) if len(program.Statements) != 1 { t.Fatalf("expected 1 statement, got %d", len(program.Statements)) } stmt, ok := program.Statements[0].(*parser.EchoStatement) if !ok { t.Fatalf("expected EchoStatement, got %T", program.Statements[0]) } if tt.isExpr { if stmt.Value.String() != tt.expectedVal.(string) { t.Errorf("expected %s, got %s", tt.expectedVal.(string), stmt.Value.String()) } } else { switch expected := tt.expectedVal.(type) { case float64: testNumberLiteral(t, stmt.Value, expected) case string: if expected == "x" { testIdentifier(t, stmt.Value, expected) } else { testStringLiteral(t, stmt.Value, expected) } case bool: testBooleanLiteral(t, stmt.Value, expected) case nil: testNilLiteral(t, stmt.Value) } } }) } } func TestEchoStringRepresentation(t *testing.T) { tests := []struct { input string expected string }{ {`echo "hello"`, `echo "hello"`}, {`echo 42`, `echo 42.00`}, {`echo x + y`, `echo (x + y)`}, } for _, tt := range tests { t.Run(tt.input, func(t *testing.T) { l := parser.NewLexer(tt.input) p := parser.NewParser(l) program := p.ParseProgram() checkParserErrors(t, p) stmt := program.Statements[0].(*parser.EchoStatement) if stmt.String() != tt.expected { t.Errorf("expected %s, got %s", tt.expected, stmt.String()) } }) } } func TestEchoWithComplexExpressions(t *testing.T) { tests := []struct { input string desc string }{ {`echo {1, 2, 3}`, "echo table array"}, {`echo {x = 1, y = 2}`, "echo table hash"}, {`echo 0xFF + 0b1010`, "echo extended numbers"}, {`echo [[multiline string]]`, "echo multiline string"}, } for _, tt := range tests { t.Run(tt.desc, func(t *testing.T) { l := parser.NewLexer(tt.input) p := parser.NewParser(l) program := p.ParseProgram() checkParserErrors(t, p) if len(program.Statements) != 1 { t.Fatalf("expected 1 statement, got %d", len(program.Statements)) } stmt, ok := program.Statements[0].(*parser.EchoStatement) if !ok { t.Fatalf("expected EchoStatement, got %T", program.Statements[0]) } if stmt.Value == nil { t.Error("expected non-nil echo value") } }) } }