summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--package.json2
-rw-r--r--src/lang/js-lang/builtin/builtin.ts14
-rw-r--r--src/lang/ts-lang/util/string.ts5
-rw-r--r--tests/type-consistency/harness.ts2
-rw-r--r--tests/type-consistency/spec/index.ts3
-rw-r--r--tests/type-consistency/spec/tostring.ts41
6 files changed, 60 insertions, 7 deletions
diff --git a/package.json b/package.json
index 96d70b6..f4d09b8 100644
--- a/package.json
+++ b/package.json
@@ -4,7 +4,7 @@
"version": "0.2.4",
"repository": {
"type": "git",
- "url": "git+https://git.aberrantflux.xyz/kai-script.git/"
+ "url": "https://git.aberrantflux.xyz/kai-script.git/"
},
"scripts": {
"build": "tsc --declaration",
diff --git a/src/lang/js-lang/builtin/builtin.ts b/src/lang/js-lang/builtin/builtin.ts
index bc40794..a984ca8 100644
--- a/src/lang/js-lang/builtin/builtin.ts
+++ b/src/lang/js-lang/builtin/builtin.ts
@@ -2,9 +2,17 @@ type BUILTIN = (args: any[]) => any;
export const V_BUILTIN_Arr: BUILTIN = (args) => args;
-// FIXME actually implement this properly
-export const V_BUILTIN_ToString: BUILTIN = (args) =>
- args.length === 1 ? JSON.stringify(args[0]) : JSON.stringify(args);
+const toStringInner = (o: any): string => {
+ if (Array.isArray(o)) {
+ return `[${o.map(toStringInner).join(", ")}]`;
+ }
+
+ return o.toString();
+};
+
+export const V_BUILTIN_ToString: BUILTIN = (args) => {
+ return args.length === 1 ? toStringInner(args[0]) : toStringInner(args);
+};
export const V_BUILTIN_Add: BUILTIN = (args) => {
if (args.every((arg) => ["string", "number"].includes(typeof arg))) {
diff --git a/src/lang/ts-lang/util/string.ts b/src/lang/ts-lang/util/string.ts
index 5772f40..ae17c2c 100644
--- a/src/lang/ts-lang/util/string.ts
+++ b/src/lang/ts-lang/util/string.ts
@@ -5,7 +5,10 @@ export type AddStrings<
? AddStrings<Tail, `${Carry}${Head}`>
: Carry;
-export type ToString<T, Carry extends string = ""> = T extends string | number
+export type ToString<T, Carry extends string = ""> = T extends
+ | string
+ | number
+ | boolean
? `${T}`
: T extends readonly any[]
? T extends readonly [infer Head, ...infer Tail]
diff --git a/tests/type-consistency/harness.ts b/tests/type-consistency/harness.ts
index a08e397..0102387 100644
--- a/tests/type-consistency/harness.ts
+++ b/tests/type-consistency/harness.ts
@@ -64,13 +64,13 @@ describe(\`${harnessName}\`, () => {
}) {
tests.push(`describe(\`${name}\`, () => {
const PROGRAM = \`${program}\` as const;
+ const fn = createFn()(PROGRAM)
${cases.map(
({ input, output }) => `test(\`${JSON.stringify(
input
)} -> ${JSON.stringify(output)}\`, () => {
const input: ${JSON.stringify(input)} = ${JSON.stringify(input)};
const expected: ${JSON.stringify(output)} = ${JSON.stringify(output)};
- const fn = createFn()(PROGRAM)
const result = fn(input)
expect(result).toStrictEqual(expected);
diff --git a/tests/type-consistency/spec/index.ts b/tests/type-consistency/spec/index.ts
index 4532493..b2da682 100644
--- a/tests/type-consistency/spec/index.ts
+++ b/tests/type-consistency/spec/index.ts
@@ -1,5 +1,6 @@
import array from "./array";
import functions from "./function";
import types from "./types";
+import tostring from "./tostring";
-export default [array, functions, types];
+export default [array, functions, types, tostring];
diff --git a/tests/type-consistency/spec/tostring.ts b/tests/type-consistency/spec/tostring.ts
new file mode 100644
index 0000000..4fcb803
--- /dev/null
+++ b/tests/type-consistency/spec/tostring.ts
@@ -0,0 +1,41 @@
+import path from "path";
+import { createTestHarness } from "../harness";
+
+export default createTestHarness({
+ harnessName: "ToString",
+ generatedPath: path.join(__dirname, "..", "generated"),
+})
+ .createFunctionTest({
+ name: "Passes through strings literally",
+ program: "fn(x, tostring(x))",
+ cases: [
+ { input: "hello", output: "hello" },
+ { input: "1", output: "1" },
+ { input: "[1,2,3]", output: "[1,2,3]" },
+ ],
+ })
+ .createFunctionTest({
+ name: "Is idempotent",
+ program: "fn(x, tostring(tostring(x)))",
+ cases: [
+ { input: "hello", output: "hello" },
+ { input: "1", output: "1" },
+ { input: "[1,2,3]", output: "[1,2,3]" },
+ ],
+ })
+ .createFunctionTest({
+ name: "Handles primitives",
+ program: "fn(x, tostring(x))",
+ cases: [
+ { input: 5, output: "5" },
+ { input: true, output: "true" },
+ ],
+ })
+ .createFunctionTest({
+ name: "Handles arrays and nested arrays",
+ program: "fn(x, tostring(x))",
+ cases: [
+ { input: [1, 2, 3], output: "[1, 2, 3]" },
+ { input: [1, 2, [3, 4, 5]], output: "[1, 2, [3, 4, 5]]" },
+ ],
+ });