{ "exercise": "forth", "version": "1.1.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": "empty input results in empty stack", "property": "evaluate", "input": [], "expected": [] }, { "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 the top value on the stack", "property": "evaluate", "input": ["1 DUP"], "expected": [1, 1] }, { "description": "is case-insensitive", "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": "cannot redefine numbers", "property": "evaluate", "input": [": 1 2 ;"], "expected": null }, { "description": "errors if executing a non-existent word", "property": "evaluate", "input": ["foo"], "expected": null } ] } ] }