Skip to content

Commit

Permalink
-b REPL switch to disable budgets; many misc
Browse files Browse the repository at this point in the history
  • Loading branch information
phunanon committed Sep 29, 2023
1 parent bfd69bd commit 2454a4d
Show file tree
Hide file tree
Showing 12 changed files with 118 additions and 70 deletions.
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@ $ ix #open a REPL session (exit with Ctrl+D or Ctrl+C)
$ 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 [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.

$ ix i #installs dependencies listed in deps.txt
$ ix r #remove dependencies listed in deps
Expand Down Expand Up @@ -673,9 +675,11 @@ etc
(sample 5 (range 10)) → [5 1 0 7 8]
(-> 100 range (sample 50) distinct len) → 50

;Returns a random item from a vector
;Returns a random item from a vector, string, or dictionary
(rand-pick [0 1 2 3 4 5]) → 3
(rand-pick []) → null
(rand-pick "hello") → "l"
(rand-pick {:a 1 :b 2}) → [:a 1]

;Returns a vector of vector items or string characters sorted
;Note: will only sort all number or all string
Expand Down Expand Up @@ -805,12 +809,14 @@ etc
;Note: has a maximum of 1000
(str* "x" 6) → "xxxxxx"

;Returns a string or number padded to a particular length
;Returns a strigified value padded to a particular length
;Note: has a maximum of 1000
(pad-left " " 10 "hello") → " hello"
(pad-right "." 10 "hello") → "hello....."
(pad-left "x" 5 "Hello!") → "Hello!"
(pad-left " " 5 10) → " 10"
(pad-right "." 10 {:a 1}) → "{:a 1}...."
etc

;Returns the code associated with a string's first or Nth character, or null
;Or returns a string with the associated supplied character code
Expand Down Expand Up @@ -1461,4 +1467,3 @@ vector item or string character is "destructured" into.
⚠️ (= {:a 1 :b 2} {:b 2 :a 1}) -> false
⚠️ syntax highlighter omits commas
⚠️ ((let x) 1) x - doesn't work
⚠️ ((fn x x) (let x 1))
9 changes: 5 additions & 4 deletions corpus/4th.ix
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
(reduce reducer [[]] parts))

(function 4th code
(when (empty? code) (return stack))
(return-when (empty? code) stack)

(let parts (if (vec? code) code (-> code (replace "\n" " ") (split " ")))
parts (map @(or (to-num %)) parts))
Expand All @@ -32,7 +32,7 @@
(let groups (split-parts parts)
defs (skip-each 1 (skip 1 groups))
sentence (flatten (skip-each 1 groups)))
(loop-over defs def
(for def defs
(var! words assoc (0 def) (skip 1 def)))

;Print new word definitions
Expand All @@ -42,7 +42,7 @@
(unless (empty? defs) (print names)))

(let if-depth 0)
(loop-over sentence word
(for word sentence
(if (< 0 if-depth)
(do (let! if-depth (match word "if" inc "else" dec "then" dec val))
stack)
Expand Down Expand Up @@ -70,7 +70,8 @@
(append (crop 1 1 word) stack)
(criteria str? (starts? "'"))
(append (skip 1 word) stack)
(append word stack))))))
(append word stack)))))
stack)

(print "pick pop")
(while (let input (prompt "> "))
Expand Down
18 changes: 3 additions & 15 deletions corpus/cobs-encoding.ix
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,10 @@
length (len chunk)
encoded (append (first 254 chunk) (or %1 []))
more? (< length (len unencoded)))
(if (or (and (= length 254) more?) (> length 254))
(recur (skip 254 unencoded) encoded)
(if more?
(recur (skip (inc length) unencoded) encoded)
(append 0 (flat-map @(.. vec (inc (len %))) encoded)))))
(when (or (< 254 length) (and (= length 254) more?) more?)
(recur (skip (min 254 (inc length)) unencoded) encoded))
(append 0 (flat-map @(.. vec (inc (len %))) encoded)))

; A more compact but probably wobbly version:
; (function COBS unencoded
; (let chunk (take-until [0] unencoded)
; [c-len u-len] (proj len chunk unencoded)
; encoded (append (first 254 chunk) (or %1 [])))
; (if (<= 253 c-len 255 u-len)
; (recur (skip 254 unencoded) encoded)
; (if (< c-len u-len)
; (recur (skip (inc c-len) unencoded) encoded)
; (append 0 (flat-map @(.. vec (inc (len %))) encoded)))))

(for [a b] [
[[0x00] [0x01 0x01 0x00]]
Expand Down
8 changes: 4 additions & 4 deletions corpus/discord-ur.ix
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@

(function render-board again?
(let segment (juxt (first 4) (crop 4 2) (last 2))
reverses (pos-juxt reverse val reverse)
reverses (adj reverse val reverse)
prepare #(reverses (segment %))
;Slice and orient the player's positions for rendering
[[a1 a2 a3] [b1 b2 b3]] (map prepare positions)
Expand All @@ -80,7 +80,7 @@
(function move player which by
;Calculate old position, new position, and if stones are already there
(let other-p (abs (dec player))
old-pos (idx which (player positions))
old-pos (idx (player positions) which)
new-pos (+ (or old-pos -1) by)
at-new (-> positions player new-pos)
at-other (-> positions other-p new-pos))
Expand Down Expand Up @@ -165,7 +165,7 @@ See the source code for this app:
(let move-by (.. + dice)
is-p0 (substr? cmd "1234567"))

(when (!= is-p0 (= turn 0))
(when (not= is-p0 (= turn 0))
(print "🙅‍♀️ It's not your turn")
(return (render-board)))

Expand All @@ -178,7 +178,7 @@ See the source code for this app:

;Roll dice for next player
(var dice (roll) prev-turn turn)
(when (!= result :again)
(when (not= result :again)
(next-turn))

;Keep rolling until non-zero
Expand Down
1 change: 1 addition & 0 deletions corpus/donut.ix
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
;FIXME: this program no longer works (and never fully worked anyway)

(var W 80 H 25
chars ".,-~:;=!*#$@"
Expand Down
29 changes: 15 additions & 14 deletions corpus/mandelbrot-speed-test.ix
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
(function mandelbrot width height depth
(.. str (for #(do
(let c_re (/ (* (- % (/ width 2)) 4) width)
c_im (/ (* (- %1 (/ height 2)) 4) width))
(let x 0 y 0 i 0)
(while (and (<= (+ (** x) (** y)) 4)
(< i depth))
(let x2 (+ (- (** x) (** y)) c_re)
y (+ (* 2 x y) c_im)
x x2
i (inc i)))
(str ((zero? %) "\n" "") (i "ABCDEFGHIJ ")))
(range width) (range height))))
(.. str
(for yy (range height)
xx (range width)
(let c_re (/ (* (- xx (/ width 2)) 4) width)
c_im (/ (* (- yy (/ height 2)) 4) width)
x 0 y 0 i 0)
(while (and (<= (+ (** x) (** y)) 4)
(< i depth))
(let x2 (+ c_re (- (** x) (** y)))
y (+ c_im (* 2 x y))
x x2
i (inc i)))
(strn ((zero? xx) "\n") (i "ABCDEFGHIJ ")))))


(var results [])
(var top 10)
(function best-avg
(when (< (len results) 2)
(return (0 results)))
(let tops (sect (sort results) 0 top))
(let tops (first top (sort results)))
(floor (/ (.. + tops) (len tops))))

(function measure n
Expand All @@ -30,4 +31,4 @@

(map measure (range 50))

(str "Average of top " top " results: " (best-avg) "ms")
(str "Average of top " top " results: " (best-avg) "ms")
13 changes: 7 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
{
"name": "insitux",
"version": "23.9.25",
"version": "23.9.29",
"description": "Extensible scripting language written in portable TypeScript.",
"main": "dist/invoker.js",
"types": "dist/invoker.d.ts",
"bin": {
"ix": "./dist/repl.js"
},
"scripts": {
"start": "node dist/repl.js",
"build": "webpack",
"watch": "webpack --watch",
"build-npm": "webpack && tsc -p tsconfig.json"
},
"dependencies": {
"cross-fetch": "^3.1.5",
"git-clone": "^0.2.0",
Expand All @@ -21,11 +27,6 @@
"webpack": "^5.52.1",
"webpack-cli": "^4.8.0"
},
"scripts": {
"build": "webpack",
"watch": "webpack --watch",
"build-npm": "webpack && tsc -p tsconfig.json"
},
"repository": {
"type": "git",
"url": "git+https://github.com/phunanon/Insitux.git"
Expand Down
4 changes: 2 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const insituxVersion = 230925;
export const insituxVersion = 230929;
import { asBoo } from "./checks";
import { arityCheck, keyOpErr, numOpErr, typeCheck, typeErr } from "./checks";
import { isLetter, isDigit, isSpace, isPunc } from "./checks";
Expand Down Expand Up @@ -751,7 +751,7 @@ function exeOp(op: string, args: Val[], ctx: Ctx, errCtx: ErrCtx): Val {
return _vec(slice(shuffled, minimum));
}
case "rand-pick": {
const arr = vec(args[0]);
const arr = asArray(args[0]);
const l = len(arr);
return l ? arr[randInt(0, l)] : _nul();
}
Expand Down
34 changes: 27 additions & 7 deletions src/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ export function tokenise(
}
continue;
}
if (inString && c === "\n") {
++line;
col = 0;
continue;
}
if (!inString && c === ";") {
const nl = subIdx(substr(code, ++i), "\n");
const text = substr(code, i, nl > 0 ? nl : l - i);
Expand Down Expand Up @@ -158,7 +163,12 @@ function treeise(tokens: Token[]): Node[] {
const nodes: Node[] = [];
const _treeise = (tokens: Token[]): Node => {
let prefix: Token | undefined;
if (tokens[0].typ === "sym" && sub("@#", tokens[0].text)) {
if (
len(tokens) > 1 &&
tokens[0].typ === "sym" &&
sub("@#", tokens[0].text) &&
tokens[1].typ === "("
) {
prefix = tokens.shift()!;
}
const token = tokens.shift();
Expand Down Expand Up @@ -223,8 +233,9 @@ function parseForm(
if (!len(nodes)) {
return [];
}
const formParams = slice(params);

const nodeParser = (node: Node) => parseNode(node, params);
const nodeParser = (node: Node) => parseNode(node, formParams);
let firstNode = nodes.shift()!;
let head = nodeParser(firstNode);
const { errCtx } = head[0];
Expand Down Expand Up @@ -264,6 +275,15 @@ function parseForm(
}
if (isToken(def)) {
const [defIns] = nodeParser(def);
if (defIns.typ === "val" && defIns.value.t === "wild") {
return { val: okValIns, def: { typ: op, value: "_", errCtx } };
}
if (defIns.typ === "val" && defIns.value.t === "str") {
return err(
`${op} name must be a symbol, not a literal string`,
defIns.errCtx,
);
}
if (defIns.typ === "ref") {
if (has(syntaxes, defIns.value)) {
return err(`"${defIns.value}" cannot be redefined: already exists`);
Expand Down Expand Up @@ -499,15 +519,15 @@ function parseForm(
const pins: ParserIns[] = [];
const name = node2str([firstNode, ...nodes]);
const cloParams: string[] = [];
const outerParams = slice(params).map(p => p.name);
const outerParams = formParams.map(p => p.name);
let monoFnBody = false;
if (op === "fn") {
const parsedParams = parseParams(nodes, false);
push(
cloParams,
parsedParams.shape.map(p => p.name),
);
push(params, parsedParams.shape);
push(formParams, parsedParams.shape);
push(pins, parsedParams.errors);
if (!len(nodes)) {
return err("provide a body");
Expand All @@ -531,7 +551,7 @@ function parseForm(
{ typ: "sym", text: "args", errCtx },
];
}
push(pins, parseForm(nodes, params, op !== "@"));
push(pins, parseForm(nodes, formParams, op !== "@"));
const cins = <Ins[]>pins.filter(i => i.typ !== "err");
const errors = pins.filter(i => i.typ === "err");
if (len(errors)) {
Expand All @@ -549,7 +569,7 @@ function parseForm(
return err(`missing body`, errCtx);
}
const newNodes = nodes.reduce((acc, node) => [node, acc]) as Node[];
const parsed = parseForm(newNodes, params);
const parsed = parseForm(newNodes, formParams);
return parsed;
} else if (op === "for") {
const defAndVals: DefAndValIns[] = [];
Expand Down Expand Up @@ -720,7 +740,7 @@ function parseParams(
const { typ, errCtx } = param;
if (typ === "sym") {
shape.push({ name: param.text, position: [...position, n] });
} else {
} else if (typ !== "str") {
errs.push({ typ: "err", value: "provide parameter name", errCtx });
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/poly-fills.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const splice = <T>(arr: T[], start: number, numDel?: number): T[] =>
export const len = <T>(arr: T[]): number => arr.length;
export const slen = (str: string): number => str.length;
export const isNum = (x: unknown): x is number =>
x !== "" && !Number.isNaN(Number(x));
x !== "" && x !== null && !Number.isNaN(Number(x));
export const isArray = <T>(x: unknown): x is T[] => Array.isArray(x);
export const substr = (str: string, start: number, length?: number): string =>
str.substring(start, start + (length ?? str.length));
Expand Down
Loading

0 comments on commit 2454a4d

Please sign in to comment.