diff --git a/demo/test-cases.html b/demo/test-cases.html index 4348358..df780a0 100644 --- a/demo/test-cases.html +++ b/demo/test-cases.html @@ -92,6 +92,7 @@

Operators

ı.^\^ x.^ \(n) <<< [] >>> + a o. b \`lim sup`._(n -> oo) diff --git a/src/compiler/tokenizer/scanners/alpha.js b/src/compiler/tokenizer/scanners/alpha.js index 37f561e..d45a60f 100644 --- a/src/compiler/tokenizer/scanners/alpha.js +++ b/src/compiler/tokenizer/scanners/alpha.js @@ -30,8 +30,8 @@ export default function alphaScanner(char, input, { start, grouping }) { [nextChar] = input.slice(i); } - // alpha may contain a period, but not never end with one. - if (value.endsWith(".")) { + // alpha may contain a period, but only known ops can end with one. + if (value.endsWith(".") && !KNOWN_OPS.has(value)) { value = value.slice(0, -1); } diff --git a/src/compiler/tokenizer/scanners/alpha.test.js b/src/compiler/tokenizer/scanners/alpha.test.js index e92485c..1926f44 100644 --- a/src/compiler/tokenizer/scanners/alpha.test.js +++ b/src/compiler/tokenizer/scanners/alpha.test.js @@ -138,6 +138,24 @@ test("can’t end with a period", (t) => { t.is(token?.split, true); }); +test("unless it is a known operator", (t) => { + const token = alpha("o", "o.", { start: 0, grouping: false }); + + t.is(token?.type, "operator"); + t.is(token?.value, "⊙"); + t.is(token?.end, 2); + t.falsy(token?.split); +}); + +test("known operator ends in period cannot be followed by an alphanum", (t) => { + const token = alpha("o", "o.o", { start: 0, grouping: false }); + + t.is(token?.type, "ident"); + t.is(token?.value, "o"); + t.is(token?.end, 1); + t.is(token?.split, true); +}); + test("known prefix", (t) => { const token = alpha("h", "hat a", { start: 0, grouping: false }); diff --git a/src/compiler/tokenizer/scanners/operator.test.js b/src/compiler/tokenizer/scanners/operator.test.js index acb37cf..b67e08a 100644 --- a/src/compiler/tokenizer/scanners/operator.test.js +++ b/src/compiler/tokenizer/scanners/operator.test.js @@ -30,6 +30,14 @@ test("known operator", (t) => { t.is(token?.end, 3); }); +test("known operator that ends with a period", (t) => { + const token = operator("o.", " o. b", { start: 1, grouping: false }); + + t.is(token?.type, "operator"); + t.is(token?.value, "⊙"); + t.is(token?.end, 3); +}); + test("emits the longest possible known operator", (t) => { const token = operator("^", "^^^ 1", { start: 0, grouping: false }); diff --git a/test/operators.js b/test/operators.js index 39b9996..7bc7044 100644 --- a/test/operators.js +++ b/test/operators.js @@ -33,6 +33,12 @@ test("i hat", (t) => { t.snapshot(render("ı.^\\^")); }); +test("circumpunct", (t) => { + t.is(render("o."), ""); + t.snapshot(render("a o. b")); + t.snapshot(render("a o.b")); +}); + test("Norm of two parallel lines", (t) => { t.snapshot(render("||a || b||")); }); diff --git a/test/snapshots/operators.js.md b/test/snapshots/operators.js.md index 271c68e..f7440dd 100644 --- a/test/snapshots/operators.js.md +++ b/test/snapshots/operators.js.md @@ -36,6 +36,16 @@ Generated by [AVA](https://avajs.dev). 'ı^' +## circumpunct + +> Snapshot 1 + + 'ab' + +> Snapshot 2 + + 'ao.b' + ## Norm of two parallel lines > Snapshot 1 diff --git a/test/snapshots/operators.js.snap b/test/snapshots/operators.js.snap index 63dab0c..1858c05 100644 Binary files a/test/snapshots/operators.js.snap and b/test/snapshots/operators.js.snap differ