Skip to content

Commit

Permalink
feat: Cyclic detection and update from upstream
Browse files Browse the repository at this point in the history
  • Loading branch information
hedyhli committed Sep 4, 2024
1 parent ebddb57 commit 25af1f8
Show file tree
Hide file tree
Showing 14 changed files with 220 additions and 18 deletions.
3 changes: 1 addition & 2 deletions builtins.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ function _compare(x, y) {
return l1.every((a1, i) => _compare(a1, l2[i]));
}
case 'block':
// XXX: Cognac errors
return false;
return x == y;
case 'box':
return _compare(x.value[0], y.value[0]);
case 'number':
Expand Down
30 changes: 23 additions & 7 deletions cognate.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,10 @@ export function initPrelude(preludeText) {
try {
result = runner.process(result.rootBlock, [], []);
} catch (err) {
if (!(err instanceof StopSignal))
if (!(err instanceof StopSignal)) {
console.error(err);
result.error = result.error || err.message;
}
}
if (result.error != '') {
throw new PreludeError(`failed to execute prelude: ${result.error}`);
Expand Down Expand Up @@ -149,11 +151,15 @@ function reprString(str) {
}

// Object to string for the output
function cognate2string(item, quotedString) {
function cognate2string(item, quotedString, checkedBoxes) {
if (item == undefined) {
return undefined;
}

if (!checkedBoxes) {
checkedBoxes = [];
}

switch (item.type) {
case 'block':
return value2object.string('(block)');
Expand All @@ -171,13 +177,17 @@ function cognate2string(item, quotedString) {
case 'boolean':
return value2object.string(item.value ? 'True' : 'False');
case 'box': {
let s = cognate2string(item.value[0], quotedString);
s.value = `<${s.value}>`;
if (checkedBoxes.find((check) => check == item)) {
return value2object.string('...');
}
checkedBoxes.push(item);
let s = cognate2string(item.value[0], quotedString, checkedBoxes);
s.value = `[${s.value}]`;
return s;
}
case 'list':
// XXX: Does not support unknown item type within the map call.
return value2object.string(`(${[...item.list].reverse().map(item => cognate2string(item, true).value).join(', ')})`);
return value2object.string(`(${[...item.list].reverse().map(item => cognate2string(item, true).value).join(' ')})`);
default:
return {
error: `unknown item of type ${escape(item.type)}, value ${escape(item)}`,
Expand Down Expand Up @@ -500,8 +510,10 @@ export class Runner {
try {
result = this.process(result.rootBlock, [], []);
} catch (err) {
if (!(err instanceof StopSignal))
if (!(err instanceof StopSignal)) {
console.error(err);
result.error = result.error || err.message;
}
}
if (result.stack !== undefined) this.$stack.innerHTML = this.reprArr(result.stack);
if (result.error != '') {
Expand Down Expand Up @@ -642,6 +654,7 @@ export class Runner {
} catch (err) {
if (beginSignals.includes(err) || err instanceof StopSignal)
throw err;
console.error(err);
result.error = result.error || err.message;
}
if (result.error != "") {
Expand Down Expand Up @@ -713,6 +726,7 @@ export class Runner {
} catch (err) {
if (beginSignals.includes(err) || err instanceof StopSignal)
throw err;
console.error(err);
result.error = result.error || err.message;
}
if (result.error != "") {
Expand Down Expand Up @@ -863,8 +877,10 @@ export class Runner {
} catch (err) {
if (beginSignals.includes(err) || err instanceof StopSignal)
throw err;
if (err !== beginSignal)
if (err !== beginSignal) {
console.error(err);
result.error = result.error || err.message;
}
}

if (result.error != "") {
Expand Down
2 changes: 1 addition & 1 deletion test.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ describe("runner", () => {
if (line.startsWith("XFAIL")) {
console.log(line);
} else {
assert.match(line, /^PASS:/);
assert.doesNotMatch(line, /^FAIL/);
}
}
}
Expand Down
15 changes: 15 additions & 0 deletions tests/ack.cog
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Def Ack (
Let X;
Let Y;

Do
If Zero? X ( + 1 Y )
If Zero? Y ( Ack of - 1 X and 1 )
else ( Ack of - 1 X and Ack X and - 1 Y )
);

Print If == 253 Ack 3 5
"PASS: Ackermann function"
else
"FAIL: Ackermann function";

14 changes: 14 additions & 0 deletions tests/block.cog
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,17 @@ Do (
then ( Print X ; Print Y )
else ( )
);

Let H be 5;
Let B1 be ( Print H );
Let B2 be ( Print H );

Print If != B1 B2
"PASS: Comparing different blocks"
else
"FAIL: Comparing different blocks";

Print If == B1 B1
"PASS: Comparing the same block"
else
"FAIL: Comparing the same block";
49 changes: 49 additions & 0 deletions tests/box.cog
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
Let X be Box 10;

Print If == 10 Unbox X
"PASS: Boxing and unboxing"
else
"FAIL: Boxing and unboxing";

Set X to 11;

Print If == 11 Unbox X
"PASS: Setting box to different value"
else
"FAIL: Setting box to different value";

Let L be Map (Box) over Range 1 to 100;

For each in L ( Let X ; Set X to + 1 Unbox X );

Print If == 49 Unbox Index 47 L
"PASS: Setting each element in list of boxes"
else
"FAIL: Setting each element in list of boxes";

Print If == "[11]" Show X
"PASS: Printing simple box to string"
else
"FAIL: Printing simple box to string";


Let C be Box \waow;
Set C to C;

Print If == "[[...]]" Show Box C
"PASS: Printing cyclic box"
else
"FAIL: Printing cyclic box";

Let B1 be Box 0;
Let B2 be Box 1;
Let B3 be Box 2;

Set B1 to B2;
Set B2 to B3;
Set B3 to B1;

Print If == "[[[...]]]" Show B1
"PASS: Printing doubly cyclic box"
else
"FAIL: Printing doubly cyclic box";
29 changes: 23 additions & 6 deletions tests/io.cog
Original file line number Diff line number Diff line change
@@ -1,7 +1,24 @@
Print "PASS: Skipping I/O";
~~ Let S be With "tests/io.txt" "r" ( Read-file );
Print "XFAIL: IO"
~~ With \read "tests/io.txt" (
~~
~~ Print If == "foo\nbar\n" S
~~ "PASS: Reading multi-line file to string"
~~ else
~~ "FAIL: Reading multi-line file to string";
~~ Let F be the file;
~~
~~
~~ Let S be Read-file F;
~~
~~ Print If == "foo\nbar\n" S
~~ "PASS: Reading multi-line file to string"
~~ else
~~ "FAIL: Reading multi-line file to string";
~~
~~ Seek from \start to position 0 in F;
~~
~~ Let L be Read-line F;
~~
~~ Print If == "foo\n" L
~~ "PASS: Reading first line of file to string"
~~ else
~~ "FAIL: Reading first line of file to string";
~~
~~
~~ );
2 changes: 2 additions & 0 deletions tests/io.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
foo
bar
4 changes: 4 additions & 0 deletions tests/lists.cog
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,7 @@ Print If == 4 Index 3 of List (1 2 3 4 5)
Print If == 3 Length of List (1 2 3)
"PASS: Getting length of list"
"FAIL: Getting length of list";

Print If == "(1 2 3)" Print Twin Show List (1 2 3)
"PASS: Printing list to string"
"FAIL: Printing list to string";
5 changes: 5 additions & 0 deletions tests/maths.cog
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ Print If == 5 Round 4.7
else
"FAIL: Round";

Print If And == 5 Abs -5 == 2.17 Abs Abs -2.17
"PASS: Abs"
else
"FAIL: Abs";

Print If == 0.3 + 0.1 0.2
"PASS: Floating point error"
else
Expand Down
19 changes: 19 additions & 0 deletions tests/prime2.cog
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Print "XFAIL: Table";
~Def Factor (Zero? Modulo Swap);

Def Primes (
Let U is upper bound;
initially Table ();
For Range 2 to U (
Let I be our potential prime;
Let To-check be Range 2 to Floor + 1 Sqrt I;
Insert I None (Factor of I) To-check;
)
);

Let P be Primes up to 100;

Print If And Not . 50 P . 37 P
"PASS: Prime numbers using a table"
else
"FAIL: Prime numbers using a table";~
4 changes: 2 additions & 2 deletions tests/regex.cog
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ Print If And Do Regex R1 "12EFab" and Not Do Regex R1 "foo123"
else
"FAIL: Simple regex to identify hex integers";

Print "XFAIL: Posix character classes";
~~ Same regex as before; but with POSIX character classes
Print "XFAIL: Posix character classes";
~~ Let R2 be "^[[:xdigit:]]*$";
~~ Print If And Do Regex R2 "12EFab" and Not Do Regex R2 "foo123"
~~ "PASS: Regex to identify hex integers (character class)"
Expand All @@ -28,7 +28,7 @@ Print If == List (Do Regex-match R4 "13.37") List (True "13" ".37")
else
"FAIL: Capture sub-expressions for integer and fractional parts";

Print "XFAIL: Regex-match POSIX character groups";
Print "XFAIL: Posix character classes";
~~ Let R5 be "([[:alnum:]]+)";
~~ Let B Do Regex-match R5 "[->+<]";
~~ Print If B
Expand Down
4 changes: 4 additions & 0 deletions tests/symbols.cog
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@ Print If != \foo \bar
Print If == \foo \foo
"PASS: Comparing the same symbol"
"FAIL: Comparing the same symbol";

Print If == "foo" Show \foo
"PASS: Printing a symbol"
"FAIL: Printing a symbol";
58 changes: 58 additions & 0 deletions tests/table.cog
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
Print "XFAIL: Table";
~~ Let T be Table (
~~ \foo is "bar";
~~ "bar" is \foo;
~~ 12 is 13;
~~ );
~~
~~ Print If == "bar" . \foo T
~~ "PASS: Table lookup 1"
~~ else
~~ "FAIL: Table lookup 1";
~~
~~ Print If == \foo . "bar" T
~~ "PASS: Table lookup 2"
~~ else
~~ "FAIL: Table lookup 2";
~~
~~ Print If == 13 . 12 T
~~ "PASS: Table lookup 3"
~~ else
~~ "FAIL: Table lookup 3";
~~
~~ Let T2 be Insert \foo is "baz" into T;
~~
~~ Print If And == "baz" . \foo T2 and == "bar" . \foo T
~~ "PASS: Table insertion"
~~ else
~~ "FAIL: Table insertion";
~~
~~ Print If == "{ foo:\"bar\" \"foo\":bar }" Show Table ( \foo "bar" and "foo" \bar )
~~ "PASS: Printing a table"
~~ else
~~ "FAIL: Printing a table";
~~
~~ Print If And Has \foo T Not Has \bar T
~~ "PASS: Has"
~~ else
~~ "FAIL: Has";
~~
~~ ~
~~ Let T3 be Remove \foo from T;
~~
~~ Print If Not Has \foo T3
~~ "PASS: Removing keys"
~~ else
~~ "FAIL: Removing keys";
~~ ~
~~
~~ Print If == List (12 \foo "bar") Keys T
~~ "PASS: Getting list of keys in table"
~~ else
~~ "FAIL: Getting list of keys in table";
~~
~~ Print If == List (13 "bar" \foo) Values T
~~ "PASS: Getting list of values in table"
~~ else
~~ "FAIL: Getting list of values in table";
~~

0 comments on commit 25af1f8

Please sign in to comment.