diff --git a/DEVELOP.md b/DEVELOP.md index 807bfc0..df5d824 100644 --- a/DEVELOP.md +++ b/DEVELOP.md @@ -89,3 +89,4 @@ MShellObject [fish shell built in](https://github.com/fish-shell/fish-shell/tree/master/src/builtins) [Stroustrop's Rule](https://buttondown.com/hillelwayne/archive/stroustrops-rule/) +[WebAssembly Type Checking](https://binji.github.io/posts/webassembly-type-checking/) diff --git a/mshell/Evaluator.go b/mshell/Evaluator.go index 0c17018..f4ba04c 100644 --- a/mshell/Evaluator.go +++ b/mshell/Evaluator.go @@ -1324,9 +1324,16 @@ MainLoop: breakDiff := 0 + initialStackSize := len(*stack) + for loopCount < maxLoops { result := state.Evaluate(quotation.Tokens, stack, loopContext, definitions) + if len(*stack) != initialStackSize { + // If the stack size changed, we have an error. + return FailWithMessage(fmt.Sprintf("%d:%d: Stack size changed from %d to %d in loop.\n", t.Line, t.Column, initialStackSize, len(*stack))) + } + if !result.Success { return result } diff --git a/tests/loop_test.msh b/tests/loop_test.msh index 20cc179..8e9228a 100644 --- a/tests/loop_test.msh +++ b/tests/loop_test.msh @@ -1,7 +1,8 @@ [ echo - ( - hello world - [ (10 10 =) (break)] if - ) loop -] ; +] +( + hello append world append + [ (10 10 =) (break)] if +) loop +; diff --git a/tests/nested_loop.msh b/tests/nested_loop.msh index 012425e..46c5c4c 100644 --- a/tests/nested_loop.msh +++ b/tests/nested_loop.msh @@ -1,6 +1,6 @@ 0 outer-inc! ( - "Outer: " @outer-inc str wl + "Outer: " @outer-inc str + wl 0 inner-inc! ( " Inner: " w @inner-inc str wl diff --git a/tests/nested_loop.msh.stdout b/tests/nested_loop.msh.stdout index 675fdb5..c2dd640 100644 --- a/tests/nested_loop.msh.stdout +++ b/tests/nested_loop.msh.stdout @@ -1,19 +1,19 @@ -0 +Outer: 0 Inner: 0 Inner: 1 Inner: 2 Inner: 3 -1 +Outer: 1 Inner: 0 Inner: 1 Inner: 2 Inner: 3 -2 +Outer: 2 Inner: 0 Inner: 1 Inner: 2 Inner: 3 -3 +Outer: 3 Inner: 0 Inner: 1 Inner: 2 diff --git a/tests/while_read.msh b/tests/while_read.msh index d14dcf8..6c5521f 100644 --- a/tests/while_read.msh +++ b/tests/while_read.msh @@ -1,5 +1,5 @@ 1 ( - read [(not) (break)] if + read [(not) (drop break)] if linetext! num! "Line " @num str ": " + + @linetext + [echo] append ; @num 1 + ) "stdin_for_test.txt" < loop