diff options
Diffstat (limited to 'subex/main_test.go')
-rw-r--r-- | subex/main_test.go | 122 |
1 files changed, 111 insertions, 11 deletions
diff --git a/subex/main_test.go b/subex/main_test.go index fb6f152..938e5cb 100644 --- a/subex/main_test.go +++ b/subex/main_test.go @@ -36,7 +36,64 @@ func TestSubexMain(t *testing.T) { tests := []test { { - subex: `..+`, + // Keep only 5 + subex: `(5|(.>_))*`, + input: []walk.Value { + walk.NumberValue(0), + walk.NumberValue(1), + walk.NumberValue(2), + walk.NumberValue(3), + walk.NumberValue(4), + walk.NumberValue(5), + walk.NumberValue(9), + walk.NumberValue(10), + walk.NumberValue(11), + walk.NumberValue(2.5), + walk.NumberValue(7.0), + walk.NumberValue(-3), + }, + expected: []walk.Value { + walk.NumberValue(5), + }, + }, + { + // Keep only odd numbers between 0 and 10 + subex: `([0<=n&n<=10&n%2=1]|(.>_))*`, + input: []walk.Value { + walk.NumberValue(0), + walk.NumberValue(1), + walk.NumberValue(2), + walk.NumberValue(3), + walk.NumberValue(4), + walk.NumberValue(5), + walk.NumberValue(9), + walk.NumberValue(10), + walk.NumberValue(11), + walk.NumberValue(2.5), + walk.NumberValue(7.0), + walk.NumberValue(-3), + }, + expected: []walk.Value { + walk.NumberValue(1), + walk.NumberValue(3), + walk.NumberValue(5), + walk.NumberValue(9), + walk.NumberValue(7), + }, + }, + { + // Collatz + subex: "[1]*[n%2=0:n,n/2]|[n%2=1:n,n*3+1]", + input: []walk.Value { + walk.NumberValue(32), + }, + expected: []walk.Value { + walk.NumberValue(32), + walk.NumberValue(16), + }, + }, + { + subex: `(..)%+`, input: []walk.Value { walk.NumberValue(12), walk.NumberValue(34), @@ -70,7 +127,7 @@ func TestSubexMain(t *testing.T) { }, }, { - subex: `~(.$_(.{-0}))~`, + subex: `~(.>_(.*))~`, input: []walk.Value { walk.StringValue("hello"), }, @@ -79,7 +136,7 @@ func TestSubexMain(t *testing.T) { }, }, { - subex: `#(".".{-0})-`, + subex: `#(".".*)-`, input: []walk.Value { walk.MapValue { { @@ -94,7 +151,7 @@ func TestSubexMain(t *testing.T) { }, }, { - subex: "@(..$a`$a$a`{-0})@", + subex: "@(((..)%a<a)*)@", input: []walk.Value { walk.ArrayValue { walk.ArrayElement { @@ -221,7 +278,7 @@ func TestSubexMain(t *testing.T) { }, }, { - subex: `@(.$_~(.{-0})-{-0})~`, + subex: `@((.>_~(.{-0})-){-0})~`, input: []walk.Value { walk.ArrayValue { { @@ -265,7 +322,7 @@ func TestSubexMain(t *testing.T) { }, }, { - subex: ":(.{-0}+)-", + subex: ":(.{-0}%+)-", input: []walk.Value { walk.ArrayValue { { @@ -287,7 +344,7 @@ func TestSubexMain(t *testing.T) { }, }, { - subex: "~(-(.)~{-0}):", + subex: "~(-(.)~*):", input: []walk.Value { walk.StringValue("abc"), }, @@ -309,7 +366,7 @@ func TestSubexMain(t *testing.T) { }, }, { - subex: "#(.(.$_){-0}):", + subex: "#((..>_)*):", input: []walk.Value { walk.MapValue { { @@ -344,7 +401,7 @@ func TestSubexMain(t *testing.T) { }, }, { - subex: ":(.`null`{-0})#", + subex: ":((.`null`)*)#", input: []walk.Value { walk.ArrayValue { { @@ -379,7 +436,7 @@ func TestSubexMain(t *testing.T) { }, }, { - subex: `#(".$_(.{-0})".{-0})#`, + subex: `#((".>_.*".)*)#`, input: []walk.Value { walk.MapValue { { @@ -406,7 +463,7 @@ func TestSubexMain(t *testing.T) { }, }, { - subex: ".{-0}`\"hello\"`", + subex: ".*`\"hello\"`", input: []walk.Value { walk.NumberValue(1), walk.NumberValue(2), @@ -437,3 +494,46 @@ func TestSubexMain(t *testing.T) { } } } + +func doCollatzTest(t *testing.T, init int) { + input := []walk.Value { + walk.NumberValue(init), + } + last := init + + lexer := NewStringRuneReader("[1]*([n%2=0:n,n/2]|[n%2=1&n>1:n,n*3+1])") + ast := Parse(lexer) + transducer := CompileTransducer(ast) + + for last != 1 { + output, err := RunTransducer(transducer, input) + + if err { + t.Errorf("Collatz rejected %v", input) + return + } + + if last % 2 == 0 { + last = last / 2 + } else { + last = last * 3 + 1 + } + + if !reflect.DeepEqual(append(input, walk.NumberValue(last)), output) { + t.Errorf("Collatz took input: %v and produced output %v", input, output) + return + } + + input = output + } + + output, err := RunTransducer(transducer, input) + if !err { + t.Errorf("Collatz accepted input %v. Produced output: %v", input, output) + } +} + +func TestSubexCollatz(t *testing.T) { + doCollatzTest(t, 32) + doCollatzTest(t, 7) +} |