Skip to content

Commit

Permalink
*1 +0 rotate interleave -nc; misc fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
phunanon committed Oct 1, 2023
1 parent 2454a4d commit 54b8a49
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 11 deletions.
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ $ ix . #execute entry.ix in the working directory
$ ix file.ix #execute file.ix in the working directory
$ ix -e "PI" #execute provided string
$ ix -b #disable REPL budgets (loops, recur, etc)
$ ix -nc #turn off "colour mode" for REPL errors, etc
$ ix [args] -r #… then open a REPL session
$ ix [...] -- [...] #seperation between ix args and program args (e.g. %0)
Most arguments/switches can be mixed with one another.
Expand Down Expand Up @@ -294,6 +295,17 @@ etc
(round 3.5) → 4
(round 2 PI) → 3.14

;Various arithmetic operators which return a number or their sole argument when
; underloaded
(*1) → 1
(*1 10) → 10
(*1 10 10) → 100
etc
(+0) → 0
(+0 10) → 10
(+0 10 10) → 20
etc

;Various arithmetic and test functions which take fixed arguments
(neg 10) → -10
(inc 100) → 101
Expand Down Expand Up @@ -757,6 +769,18 @@ etc
(.. distinct [0 1] [0 1] [2]) → [0 1 2]
(distinct [1 1 :a :a]) → [1 :a]

;Rotates vector or string by certain offset
(rotate 1 [0 1 2 3]) → [1 2 3 0]
(rotate -1 [0 1 2 3]) → [3 0 1 2]
(rotate 10 "hello") → "ohell"
(rotate -10 "hello") → "elloh"
(rotate 0 [0 1 2 3]) → [0 1 2 3]

;Interleaves vectors or strings so that one item of each appears after the other
(interleave [0 1 2] [3 4 5]) → [0 3 1 4 2 5]
(interleave "hello" "hey") → "hheely"
(interleave [1 2] [9 8 7 6]) → [1 9 2 8]

;Generates a range of numbers
;Note: the first argument is always inclusive, second exclusive
(range 5) → [0 1 2 3 4]
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "insitux",
"version": "23.9.29",
"version": "23.9.30",
"description": "Extensible scripting language written in portable TypeScript.",
"main": "dist/invoker.js",
"types": "dist/invoker.d.ts",
Expand Down
38 changes: 35 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const insituxVersion = 230929;
export const insituxVersion = 230930;
import { asBoo } from "./checks";
import { arityCheck, keyOpErr, numOpErr, typeCheck, typeErr } from "./checks";
import { isLetter, isDigit, isSpace, isPunc } from "./checks";
Expand Down Expand Up @@ -48,8 +48,13 @@ function exeOp(op: string, args: Val[], ctx: Ctx, errCtx: ErrCtx): Val {
return _vec(args);
case "dict":
return toDict(args);
case "kv-dict":
return _dic({ keys: vec(args[0]), vals: vec(args[1]) });
case "kv-dict": {
const shortest = min(...args.map(vec).map(len));
return _dic({
keys: slice(vec(args[0]), 0, shortest),
vals: slice(vec(args[1]), 0, shortest),
});
}
case "len":
return _num(
args[0].t === "str"
Expand Down Expand Up @@ -99,6 +104,10 @@ function exeOp(op: string, args: Val[], ctx: Ctx, errCtx: ErrCtx): Val {
return _num(args.map(num).reduce((sum, n) => sum / n));
case "//":
return _num(args.map(num).reduce((sum, n) => floor(sum / n)));
case "+0":
return _num(args.map(num).reduce((sum, n) => sum + n, 0));
case "*1":
return _num(args.map(num).reduce((sum, n) => sum * n, 1));
case "fast=":
case "fast!=":
return _boo(isEqual(args[0], args[1]) === (op === "fast="));
Expand Down Expand Up @@ -931,6 +940,29 @@ function exeOp(op: string, args: Val[], ctx: Ctx, errCtx: ErrCtx): Val {
});
return _vec(distinct);
}
case "rotate":
case "interleave": {
let result: Val[] = [];
if (op === "rotate") {
const by = num(args[0]);
const coll = asArray(args[1]);
const l = len(coll);
const n = ((by % l) + l) % l;
result = concat(slice(coll, n), slice(coll, 0, n));
} else {
const colls = args.map(asArray);
const shortest = min(...colls.map(len));
for (let i = 0; i < shortest; ++i) {
for (let c = 0, max = len(colls); c < max; ++c) {
result.push(colls[c][i]);
}
}
}
if (args[1].t === "vec") {
return _vec(result);
}
return _str(result.map(val2str).join(""));
}
case "range": {
const [a, b, s] = args.map(num);
const edgeCase = s && s < 0 && a < b; //e.g. 1 4 -1
Expand Down
1 change: 1 addition & 0 deletions src/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ export function tokenise(
if (inString && c === "\n") {
++line;
col = 0;
tokens[len(tokens) - 1].text += c;
continue;
}
if (!inString && c === ";") {
Expand Down
4 changes: 1 addition & 3 deletions src/repl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -497,8 +497,6 @@ async function processCliArguments(args: string[]) {
return;
}

colourMode = false;

const programArgs: string[] = [];
if (args.includes("--")) {
const programArgsIdx = args.indexOf("--");
Expand All @@ -522,6 +520,7 @@ async function processCliArguments(args: string[]) {

const openReplAfter = extractSwitch(args, "-r");
const disableBudgets = extractSwitch(args, "-b");
colourMode = !extractSwitch(args, "-nc");

if (disableBudgets) {
ctx.callBudget = Infinity;
Expand Down Expand Up @@ -584,7 +583,6 @@ async function processCliArguments(args: string[]) {
}

if (openReplAfter) {
colourMode = true;
startRepl();
}
}
Expand Down
11 changes: 7 additions & 4 deletions src/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ const tests: {
{
name: "For destructure",
code: `(for [x y] [[1 2]] [x y])`,
out: `[[1 2]]`
out: `[[1 2]]`,
},
{
name: "Filter by integer",
Expand Down Expand Up @@ -576,13 +576,16 @@ export function doTests(
okErr,
okOut,
elapsedMs,
display: `${tNum} ${tName} ${tElapsed} ${tOutput} ${tErrors}`,
display: `${tNum} ${tName} ${tElapsed} ${tOutput} ${tErrors}`,
});
}
const totalMs = results.reduce((sum, { elapsedMs }) => sum + elapsedMs, 0);
const numPassed = len(results.filter(({ okOut, okErr }) => okOut && okErr));
return concat(
const withHeader = concat(
terse ? [] : ["# Name Time OK-out OK-err"],
results.filter(r => !terse || !r.okOut || !r.okErr).map(r => r.display),
[`---- ${numPassed}/${len(results)} tests passed in ${round(totalMs)}ms.`],
);
return concat(withHeader, [
`---- ${numPassed}/${len(results)} tests passed in ${round(totalMs)}ms.`,
]);
}
12 changes: 12 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ export const ops: {
"*": { minArity: 2, numeric: true },
"/": { minArity: 2, numeric: true },
"//": { minArity: 2, numeric: true },
"+0": { numeric: true },
"*1": { numeric: true },
"**": { minArity: 1, maxArity: 2, numeric: true },
"<": { minArity: 2, numeric: "in only", returns: ["bool"] },
">": { minArity: 2, numeric: "in only", returns: ["bool"] },
Expand Down Expand Up @@ -444,6 +446,16 @@ export const ops: {
returns: ["vec"],
},
distinct: { returns: ["vec"] },
rotate: {
exactArity: 2,
params: ["num", ["vec", "str"]],
returns: ["vec", "str"],
},
interleave: {
minArity: 2,
params: [["vec", "str"]],
returns: ["vec", "str"],
},
"group-by": {
exactArity: 2,
params: ["any", ["vec", "dict", "str"]],
Expand Down

0 comments on commit 54b8a49

Please sign in to comment.