diff --git a/test.ref b/test.ref index aa9e012..a0e9871 100644 --- a/test.ref +++ b/test.ref @@ -155,6 +155,49 @@ f 102 ( 40 ) 41 32 { 123 32 p 112 r 114 i 105 n 110 t 116 ( 40 _ 95 _ 95 e 1 42 6 * 7 MACRO table <> + | assert: <> + | | environment: nil + | | function: <> + | | | body: <> + | | | | 0: <> + | | | | | operation: 3 + | | | | | 0: <> + | | | | | | body: <> + | | | | | | | 0: <> + | | | | | | | | alternate: nil + | | | | | | | | condition: <> + | | | | | | | | | operation: 0 + | | | | | | | | | 0: <> + | | | | | | | | | | arguments: <> + | | | | | | | | | | | 0: <> + | | | | | | | | | | | | operation: 4 + | | | | | | | | | | | | 0: <> + | | | | | | | | | | | | | name: x + | | | | | | | | | | function: <> + | | | | | | | | | | | name: eval + | | | | | | | | consequent: <> + | | | | | | | | | body: <> + | | | | | | | | | | 0: <> + | | | | | | | | | | | arguments: <> + | | | | | | | | | | | | 0: "\nassertion failed: " + | | | | | | | | | | | | 1: <> + | | | | | | | | | | | | | operation: 4 + | | | | | | | | | | | | | 0: <> + | | | | | | | | | | | | | | arguments: <> + | | | | | | | | | | | | | | | 0: <> + | | | | | | | | | | | | | | | | name: x + | | | | | | | | | | | | | | function: <> + | | | | | | | | | | | | | | | name: codeString + | | | | | | | | | | | | 2: "\n" + | | | | | | | | | | | function: <> + | | | | | | | | | | | | name: print + | | | | | | | | | | 1: <> + | | | | | | | | | | | arguments: <> + | | | | | | | | | | | | 0: 1 + | | | | | | | | | | | function: <> + | | | | | | | | | | | | name: exit + | | | parameters: <> + | | | | 0: x | test: <> | | environment: nil | | function: <> @@ -204,17 +247,18 @@ AST eval => 42 0 1 2 3 4 5 6 7 8 9 65 66 67 68 69 1 two 3 four - -test.txt:381: *: illegal operand types Integer and String -11: n * factorial(n - 1) -10: if (n < 2) "1" else n * factorial(n - 1) - 9: factorial(n - 1) - 8: n * factorial(n - 1) - 7: if (n < 2) "1" else n * factorial(n - 1) - 6: factorial(n - 1) - 5: n * factorial(n - 1) - 4: if (n < 2) "1" else n * factorial(n - 1) - 3: factorial(n - 1) - 2: n * factorial(n - 1) - 1: if (n < 2) "1" else n * factorial(n - 1) - 0: factorial(5) +*: type error: illegal operand types: and + 13: n * factorial(n - 1) + 12: if (n < 2) nil else n * factorial(n - 1) + 11: factorial(n - 1) + 10: n * factorial(n - 1) + 9: if (n < 2) nil else n * factorial(n - 1) + 8: factorial(n - 1) + 7: n * factorial(n - 1) + 6: if (n < 2) nil else n * factorial(n - 1) + 5: factorial(n - 1) + 4: n * factorial(n - 1) + 3: if (n < 2) nil else n * factorial(n - 1) + 2: factorial(5) + 1: { factorial(5) } + 0: try { factorial(5) } catch (e) { { if (!eval(e.__function__ == "*")) { print("\nassertion failed: ", "e.__function__ == \"*\"", "\n"); exit(1) } }; { if (!eval(e.__kind__ == "type error")) { print("\nassertion failed: ", "e.__kind__ == \"type error\"", "\n"); exit(1) } }; { if (!eval(e.__message__ == "illegal operand types")) { print("\nassertion failed: ", "e.__message__ == \"illegal operand types\"", "\n"); exit(1) } }; { if (!eval(e.operand1 == 2)) { print("\nassertion failed: ", "e.operand1 == 2", "\n"); exit(1) } }; { if (!eval(e.operand2 == nil)) { print("\nassertion failed: ", "e.operand2 == nil", "\n"); exit(1) } }; print(e.__function__, ": ", e.__kind__, ": ", e.__message__, ": ", typeName(e.operand1), " and ", typeName(e.operand2), "\n"); let w = 2; let j = i; while (j /= 10 >= 0) { w += 1 }; for (i from len(e) - 1 to 0) print(pad(w, codeString(i)), ": ", codeString(e[i]), "\n") } diff --git a/test.txt b/test.txt index f63ea51..b204433 100644 --- a/test.txt +++ b/test.txt @@ -92,6 +92,7 @@ nfib(n) { if (n < 2) 1 else nfib(n-1) + nfib(n-2) + 1 } print(nfib(5), "\n"); print(nfib(15), "\n"); +/* assert(x) { if (!(eval(x))) { print("\nassertion failed: ", codeString(x), "\n"); @@ -100,6 +101,14 @@ assert(x) { } assert.fixed = #t; // do not evaluate arguments (x will be an AST suitable for eval()) +*/ + +Symbol.macros.assert = (x) { + `{if (!(eval(@x))) { + print("\nassertion failed: ", @codeString(x), "\n"); + exit(1); + }}; +}; refute(x) { if (eval(x)) { @@ -375,6 +384,35 @@ for (i in 10) print(i, " "); print("\n"); for (i in "ABCDE") print(i, " "); print("\n"); for (i in [1, "two", 3, "four"]) print(i, " "); print("\n"); -factorial(n) { if (n < 2) "1" else n * factorial(n-1) } +factorial(n) { if (n < 2) nil else n * factorial(n-1) } + +typeName(x) { + if (!x) return ""; + let name = "?"; + let level = 1; + while (x && !x.allKeys().includes(#__name__)) x = x.__delegate__; + if (x.allKeys().includes(#__name__)) name = x.__name__.asString(); + "<" * level + name + ">" * level; +} + +pad(w, i) { + while (len(i) < w) i = " " + i; + i; +} -factorial(5); +try { + factorial(5); +} +catch (e) { + assert(e.__function__ == "*"); + assert(e.__kind__ == "type error"); + assert(e.__message__ == "illegal operand types"); + assert(e.operand1 == 2); + assert(e.operand2 == nil); + print(e.__function__, ": ", e.__kind__, ": ", e.__message__, ": ", typeName(e.operand1), " and ", typeName(e.operand2), "\n"); + let w = 2; + let j = i; + while ( (j /= 10) > 0) { ++w; } + for (i from len(e) - 1 to 0) + print(pad(w, codeString(i)), ": ", codeString(e[i]), "\n"); +}