Skip to content

Commit

Permalink
Implement either; fix destruct-param capture
Browse files Browse the repository at this point in the history
  • Loading branch information
phunanon committed Dec 5, 2023
1 parent 0398c05 commit 89fb08d
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 18 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ node_modules/
dist/
node/
*.ix
!corpus/**/*.ix
unvisited.txt
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -355,12 +355,6 @@ etc
(str<= "a" "a" "b") → true
(str>= "A" "b") → false

;Negates boolean value
(! true) → false
(! false) → true
(! null) → true
(! 123) → false

;Creates a vector (list) of values in two different ways
[1 "hello" :c]
(vec 1 "hello" :c)
Expand Down Expand Up @@ -969,12 +963,18 @@ etc
((toggle :cozy :compact) :compact) → :cozy
((toggle :cozy :compact) :hello) → :hello

;Returns a closure which returns true or false based on multiple criteria
;Returns a closure that returns true by AND of multiple criteria
;Note: the evalution short-circuits on falsy values
((criteria num? (< 5) odd?) 11) → true
((criteria [0 1 2] [1 2 3]) 2) → true
((criteria [0 1 2] [3 4 5]) 10) → false

;Returns a closure that returns truthy by OR of multiple criteria
;Note: the evalution short-circuits on truthy values
((either (< 5) odd?) 11) → true
((either [0 1 2] [3 4 5]) 2) → 2
((either [0 1 2] [3 4 5]) 10) → false

;Calls its first argument with each of its subsequent arguments, returning
; results as a vector
(proj char-code "a" "b" "c") → [97 98 99]
Expand Down Expand Up @@ -1607,5 +1607,5 @@ Check out our [Rosetta Code entries](https://rosettacode.org/wiki/Insitux) for
**Known bugs I put here to make sure I can't lose them,**
**and to shame myself that they still exist.**
⚠️ syntax highlighter omits commas
⚠️ ((let x) 1) x - doesn't work
⚠️ (((vec))) crashes
⚠️ `((let x) 1) x` doesn't work
⚠️ `(((vec)))` crashes
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.11.17",
"version": "23.12.5",
"description": "Extensible scripting language written in portable TypeScript.",
"main": "dist/invoker.js",
"types": "dist/invoker.d.ts",
Expand Down
8 changes: 5 additions & 3 deletions src/closure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ export function makeClosure(
cloParams: string[],
cins: Ins[],
): Closure {
const captures: boolean[] = [];
const derefs: Ins[] = [];
const exclusions: string[] = cloParams;
//First scan for any let/var declarations to be excluded throughout
for (const cin of cins) {
Expand All @@ -21,6 +19,9 @@ export function makeClosure(
push(exclusions, names);
}
}
//Calculate captures and derefs
const captures: boolean[] = [];
const derefs: Ins[] = [];
for (let i = 0, lim = len(cins); i < lim; ++i) {
const cin = cins[i];
let capture = false;
Expand Down Expand Up @@ -88,7 +89,8 @@ function canCapture(exclusions: string[], ins0: Ins, ins1: false | Ins) {
ins1 && ins0.typ === "val" && ins0.value.t === "str" && ins1.typ === "exe";
return (
isExeVal ||
(ins0.typ === "npa" && !has(exclusions, ins0.text)) ||
((ins0.typ === "npa" || ins0.typ === "dpa") &&
!has(exclusions, ins0.text)) ||
(ins0.typ === "ref" && !has(exclusions, ins0.value))
);
}
20 changes: 19 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const insituxVersion = 231117;
export const insituxVersion = 231205;
import { asBoo } from "./checks";
import { arityCheck, keyOpErr, numOpErr, typeCheck, typeErr } from "./checks";
import { isLetter, isDigit, isSpace, isPunc } from "./checks";
Expand Down Expand Up @@ -430,6 +430,24 @@ function exeOp(op: string, args: Val[], ctx: Ctx, errCtx: ErrCtx): Val {
];
return { t: "clo", v: <Func>{ name, ins } };
}
case "either": {
const name = `(either ${args.map(val2str).join(" ")})`;
const ins: Ins[] = [
...flat(
args.map((value, i) => {
const jmp = (len(args) - 1 - i) * 4 + 1;
return [
{ typ: "upa", value: 0, text: "x", errCtx },
{ typ: "val", value, errCtx },
{ typ: "exe", value: 1, errCtx },
{ typ: "or", value: jmp, errCtx },
] as Ins[];
}),
),
{ typ: "val", value: _boo(false), errCtx },
];
return { t: "clo", v: <Func>{ name, ins } };
}
case "map": {
const collections = slice(args, 1);
const badArg = collections.findIndex(
Expand Down
8 changes: 4 additions & 4 deletions src/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -735,11 +735,11 @@ function parseArg(node: Node, params: ParamsShape): ParserIns[] {
}
return [{ typ: "upa", value, text, errCtx }];
} else if (has(paramNames, text)) {
const param = params.find(({ name }) => name === text)!;
if (len(param.position) === 1 && !param.rest) {
return [{ typ: "npa", value: param.position[0], text, errCtx }];
const { position, rest } = params.find(({ name }) => name === text)!;
if (len(position) === 1 && !rest) {
return [{ typ: "npa", value: position[0], text, errCtx }];
}
return [{ typ: "dpa", value: param.position, rest: param.rest, errCtx }];
return [{ typ: "dpa", value: position, rest, text, errCtx }];
} else if (text === "args") {
return [{ typ: "upa", value: -1, text: "args", errCtx }];
} else if (text === "err-ctx") {
Expand Down
5 changes: 5 additions & 0 deletions src/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,11 @@ const tests: {
code: `(let f (fn a [b [c]] d [d c b a])) (f 0 [1 [2]] 3)`,
out: `[3 2 1 0]`,
},
{
name: "Destruct closure capture",
code: `(((fn [x] #(val x)) [1]))`,
out: `1`,
},
{
name: "Destructuring fn decoy",
code: `(let f (fn a [a [a]])) (f 0)`,
Expand Down
2 changes: 2 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ export type Ins = { errCtx: ErrCtx } & (
value: number[];
/** Is rest? */
rest?: true;
text?: string;
}
| {
/** Execute last stack value */
Expand Down Expand Up @@ -336,6 +337,7 @@ export const ops: {
comp: { minArity: 2, returns: ["clo"] },
toggle: { exactArity: 2, returns: ["clo"] },
criteria: { minArity: 2, returns: ["clo"] },
either: { minArity: 2, returns: ["clo"] },
map: { minArity: 2, returns: ["vec"] },
"flat-map": { minArity: 2, returns: ["vec"] },
xmap: {
Expand Down

0 comments on commit 89fb08d

Please sign in to comment.