|
|
@@ -264,6 +264,31 @@ func TestGlobalLetStatements(t *testing.T) {
|
|
|
runCompilerTests(t, tests)
|
|
|
}
|
|
|
|
|
|
+func TestStringExpression(t *testing.T) {
|
|
|
+ tests := []compilerTestCase{
|
|
|
+ {
|
|
|
+ input: `"monkey"`,
|
|
|
+ expectedConstants: []interface{}{"monkey"},
|
|
|
+ expectedInstructions: []code.Instructions{
|
|
|
+ code.Make(code.OpConstant, 0),
|
|
|
+ code.Make(code.OpPop),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ input: `"monkey" + "language"`,
|
|
|
+ expectedConstants: []interface{}{"monkey", "language"},
|
|
|
+ expectedInstructions: []code.Instructions{
|
|
|
+ code.Make(code.OpConstant, 0),
|
|
|
+ code.Make(code.OpConstant, 1),
|
|
|
+ code.Make(code.OpAdd),
|
|
|
+ code.Make(code.OpPop),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ }
|
|
|
+
|
|
|
+ runCompilerTests(t, tests)
|
|
|
+}
|
|
|
+
|
|
|
func runCompilerTests(t *testing.T, tests []compilerTestCase) {
|
|
|
t.Helper()
|
|
|
|
|
|
@@ -308,11 +333,28 @@ func testConstants(
|
|
|
return fmt.Errorf("constant %d -- testIntegerObject failed: %s",
|
|
|
i, err)
|
|
|
}
|
|
|
+ case string:
|
|
|
+ err := testStringObject(constant, actual[i])
|
|
|
+ if err != nil {
|
|
|
+ return fmt.Errorf("constant %d - testStringObject failed: %s", i, err)
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
+func testStringObject(expected string, actual object.Object) error {
|
|
|
+ result, ok := actual.(*object.String)
|
|
|
+ if !ok {
|
|
|
+ return fmt.Errorf("object is not String. got=%T (%+v)", actual, actual)
|
|
|
+ }
|
|
|
+ if result.Value != expected {
|
|
|
+ return fmt.Errorf("object has wrong value. got=%s, want=%q", result.Value, expected)
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
func testIntegerObject(expected int64, actual object.Object) error {
|
|
|
result, ok := actual.(*object.Integer)
|
|
|
if !ok {
|