From 964c4bc0df95ea59bd79d9739ddb0fdb83ebeafc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanis=C5=82aw=20Barzowski?= Date: Fri, 28 Jul 2017 17:23:27 -0400 Subject: [PATCH 1/2] Allow adding strings --- interpreter.go | 25 +++++++++++++++++++++---- main_test.go | 1 + 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/interpreter.go b/interpreter.go index 8cb948c..5cbbe83 100644 --- a/interpreter.go +++ b/interpreter.go @@ -360,6 +360,21 @@ func (i *interpreter) objectIndex(loc *LocationRange, obj value, f string, offse } } +func (i *interpreter) evalAdd(leftVal, rightVal value) (value, error) { + switch leftVal := leftVal.(type) { + case *valueNumber: + left := leftVal.value + right := rightVal.(*valueNumber).value + return makeValueNumber(left + right), nil + case *valueString: + left := leftVal.value + right := rightVal.(*valueString).value + return makeValueString(left + right), nil + } + // TODO(sbarzowski) More types and more graceful error handling + panic("unknown type") +} + func (i *interpreter) evaluate(a astNode) (value, error) { // TODO(dcunnin): All the other cases... switch ast := a.(type) { @@ -374,19 +389,21 @@ func (i *interpreter) evaluate(a astNode) (value, error) { return &valueArray{elements}, nil case *astBinary: - // TODO(dcunnin): Assume it's + on numbers for now + // TODO(dcunnin): Assume it's + for now leftVal, err := i.evaluate(ast.left) if err != nil { return nil, err } // TODO(dcunnin): Check the type properly. The following code just panics. - leftNum := leftVal.(*valueNumber).value rightVal, err := i.evaluate(ast.right) if err != nil { return nil, err } - rightNum := rightVal.(*valueNumber).value - return makeValueNumber(leftNum + rightNum), nil + result, err := i.evalAdd(leftVal, rightVal) + if err != nil { + return nil, err + } + return result, nil case *astDesugaredObject: // Evaluate all the field names. Check for null, dups, etc. diff --git a/main_test.go b/main_test.go index 074e9a2..a13f9d1 100644 --- a/main_test.go +++ b/main_test.go @@ -36,6 +36,7 @@ var mainTests = []mainTest{ {"simple_arith1", "3 + 3", "6", ""}, {"simple_arith2", "3 + 3 + 3", "9", ""}, {"simple_arith3", "(3 + 3) + (3 + 3)", "12", ""}, + {"simple_arith_string", "\"aaa\" + \"bbb\"", "\"aaabbb\"", ""}, {"empty_array", "[]", "[ ]", ""}, {"array", "[1, 2, 1 + 2]", "[\n 1,\n 2,\n 3\n]", ""}, {"empty_object", "{}", "{ }", ""}, From badeb833bbe0a824ab294a9e51961bdc4f14437c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanis=C5=82aw=20Barzowski?= Date: Mon, 31 Jul 2017 11:36:52 -0400 Subject: [PATCH 2/2] Tests + default + better panic message --- interpreter.go | 5 +++-- main_test.go | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/interpreter.go b/interpreter.go index 5cbbe83..6f39f5e 100644 --- a/interpreter.go +++ b/interpreter.go @@ -361,6 +361,7 @@ func (i *interpreter) objectIndex(loc *LocationRange, obj value, f string, offse } func (i *interpreter) evalAdd(leftVal, rightVal value) (value, error) { + // TODO(sbarzowski) More types and more graceful error handling switch leftVal := leftVal.(type) { case *valueNumber: left := leftVal.value @@ -370,9 +371,9 @@ func (i *interpreter) evalAdd(leftVal, rightVal value) (value, error) { left := leftVal.value right := rightVal.(*valueString).value return makeValueString(left + right), nil + default: + panic(fmt.Sprintf("INTERNAL ERROR: Unrecognised value type: %T", leftVal)) } - // TODO(sbarzowski) More types and more graceful error handling - panic("unknown type") } func (i *interpreter) evaluate(a astNode) (value, error) { diff --git a/main_test.go b/main_test.go index a13f9d1..8b77ade 100644 --- a/main_test.go +++ b/main_test.go @@ -37,6 +37,9 @@ var mainTests = []mainTest{ {"simple_arith2", "3 + 3 + 3", "9", ""}, {"simple_arith3", "(3 + 3) + (3 + 3)", "12", ""}, {"simple_arith_string", "\"aaa\" + \"bbb\"", "\"aaabbb\"", ""}, + {"simple_arith_string2", "\"aaa\" + \"\"", "\"aaa\"", ""}, + {"simple_arith_string3", "\"\" + \"bbb\"", "\"bbb\"", ""}, + {"simple_arith_string_empty", "\"\" + \"\"", "\"\"", ""}, {"empty_array", "[]", "[ ]", ""}, {"array", "[1, 2, 1 + 2]", "[\n 1,\n 2,\n 3\n]", ""}, {"empty_object", "{}", "{ }", ""},