{ "exercise": "forth", "version": "1.4.0", "comments": [ "The cases are split into multiple sections, all with the same structure.", "In all cases, the `expected` key is the resulting stack", "after executing the Forth program contained in the `input` key." ], "cases": [ { "description": "parsing and numbers", "cases": [ { "description": "numbers just get pushed onto the stack", "property": "evaluate", "input": ["1 2 3 4 5"], "expected": [1, 2, 3, 4, 5] } ] }, { "description": "addition", "cases": [ { "description": "can add two numbers", "property": "evaluate", "input": ["1 2 +"], "expected": [3] }, { "description": "errors if there is nothing on the stack", "property": "evaluate", "input": ["+"], "expected": null }, { "description": "errors if there is only one value on the stack", "property": "evaluate", "input": ["1 +"], "expected": null } ] }, { "description": "subtraction", "cases": [ { "description": "can subtract two numbers", "property": "evaluate", "input": ["3 4 -"], "expected": [-1] }, { "description": "errors if there is nothing on the stack", "property": "evaluate", "input": ["-"], "expected": null }, { "description": "errors if there is only one value on the stack", "property": "evaluate", "input": ["1 -"], "expected": null } ] }, { "description": "multiplication", "cases": [ { "description": "can multiply two numbers", "property": "evaluate", "input": ["2 4 *"], "expected": [8] }, { "description": "errors if there is nothing on the stack", "property": "evaluate", "input": ["*"], "expected": null }, { "description": "errors if there is only one value on the stack", "property": "evaluate", "input": ["1 *"], "expected": null } ] }, { "description": "division", "cases": [ { "description": "can divide two numbers", "property": "evaluate", "input": ["12 3 /"], "expected": [4] }, { "description": "performs integer division", "property": "evaluate", "input": ["8 3 /"], "expected": [2] }, { "description": "errors if dividing by zero", "property": "evaluate", "input": ["4 0 /"], "expected": null }, { "description": "errors if there is nothing on the stack", "property": "evaluate", "input": ["/"], "expected": null }, { "description": "errors if there is only one value on the stack", "property": "evaluate", "input": ["1 /"], "expected": null } ] }, { "description": "combined arithmetic", "cases": [ { "description": "addition and subtraction", "property": "evaluate", "input": ["1 2 + 4 -"], "expected": [-1] }, { "description": "multiplication and division", "property": "evaluate", "input": ["2 4 * 3 /"], "expected": [2] } ] }, { "description": "dup", "cases": [ { "description": "copies a value on the stack", "property": "evaluate", "input": ["1 dup"], "expected": [1, 1] }, { "description": "copies the top value on the stack", "property": "evaluate", "input": ["1 2 dup"], "expected": [1, 2, 2] }, { "description": "errors if there is nothing on the stack", "property": "evaluate", "input": ["dup"], "expected": null } ] }, { "description": "drop", "cases": [ { "description": "removes the top value on the stack if it is the only one", "property": "evaluate", "input": ["1 drop"], "expected": [] }, { "description": "removes the top value on the stack if it is not the only one", "property": "evaluate", "input": ["1 2 drop"], "expected": [1] }, { "description": "errors if there is nothing on the stack", "property": "evaluate", "input": ["drop"], "expected": null } ] }, { "description": "swap", "cases": [ { "description": "swaps the top two values on the stack if they are the only ones", "property": "evaluate", "input": ["1 2 swap"], "expected": [2, 1] }, { "description": "swaps the top two values on the stack if they are not the only ones", "property": "evaluate", "input": ["1 2 3 swap"], "expected": [1, 3, 2] }, { "description": "errors if there is nothing on the stack", "property": "evaluate", "input": ["swap"], "expected": null }, { "description": "errors if there is only one value on the stack", "property": "evaluate", "input": ["1 swap"], "expected": null } ] }, { "description": "over", "cases": [ { "description": "copies the second element if there are only two", "property": "evaluate", "input": ["1 2 over"], "expected": [1, 2, 1] }, { "description": "copies the second element if there are more than two", "property": "evaluate", "input": ["1 2 3 over"], "expected": [1, 2, 3, 2] }, { "description": "errors if there is nothing on the stack", "property": "evaluate", "input": ["over"], "expected": null }, { "description": "errors if there is only one value on the stack", "property": "evaluate", "input": ["1 over"], "expected": null } ] }, { "description": "user-defined words", "cases": [ { "description": "can consist of built-in words", "property": "evaluate", "input": [ ": dup-twice dup dup ;", "1 dup-twice" ], "expected": [1, 1, 1] }, { "description": "execute in the right order", "property": "evaluate", "input": [ ": countup 1 2 3 ;", "countup" ], "expected": [1, 2, 3] }, { "description": "can override other user-defined words", "property": "evaluate", "input": [ ": foo dup ;", ": foo dup dup ;", "1 foo" ], "expected": [1, 1, 1] }, { "description": "can override built-in words", "property": "evaluate", "input": [ ": swap dup ;", "1 swap" ], "expected": [1, 1] }, { "description": "can override built-in operators", "property": "evaluate", "input": [ ": + * ;", "3 4 +" ], "expected": [12] }, { "description": "cannot redefine numbers", "property": "evaluate", "input": [": 1 2 ;"], "expected": null }, { "description": "errors if executing a non-existent word", "property": "evaluate", "input": ["foo"], "expected": null } ] }, { "description": "case-insensitivity", "cases": [ { "description": "DUP is case-insensitive", "property": "evaluate", "input": ["1 DUP Dup dup"], "expected": [1, 1, 1, 1] }, { "description": "DROP is case-insensitive", "property": "evaluate", "input": ["1 2 3 4 DROP Drop drop"], "expected": [1] }, { "description": "SWAP is case-insensitive", "property": "evaluate", "input": ["1 2 SWAP 3 Swap 4 swap"], "expected": [2, 3, 4, 1] }, { "description": "OVER is case-insensitive", "property": "evaluate", "input": ["1 2 OVER Over over"], "expected": [1, 2, 1, 2, 1] }, { "description": "user-defined words are case-insensitive", "property": "evaluate", "input": [ ": foo dup ;", "1 FOO Foo foo" ], "expected": [1, 1, 1, 1] }, { "description": "definitions are case-insensitive", "property": "evaluate", "input": [ ": SWAP DUP Dup dup ;", "1 swap" ], "expected": [1, 1, 1, 1] } ] } ] }