From 3c8fe617bdf30b627998cdf3e1eb902919dd70b2 Mon Sep 17 00:00:00 2001 From: tiye Date: Sun, 25 Feb 2024 16:16:43 +0800 Subject: [PATCH] fix deref; fix %{} in custom formatter; tag 0.8.36 --- Cargo.lock | 2 +- Cargo.toml | 2 +- calcit/test.cirru | 7 +++ package.json | 2 +- src/data/cirru.rs | 7 ++- ts-src/calcit.procs.mts | 6 ++- ts-src/custom-formatter.mts | 91 +++++++++++++++++++++++-------------- ts-src/js-cirru.mts | 14 +++--- ts-src/js-list.mts | 16 ++++++- ts-src/js-map.mts | 22 ++++++++- ts-src/js-primes.mts | 2 +- 11 files changed, 121 insertions(+), 50 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6a23e879..08d6c57f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -62,7 +62,7 @@ checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" [[package]] name = "calcit" -version = "0.8.35" +version = "0.8.36" dependencies = [ "cirru_edn", "cirru_parser", diff --git a/Cargo.toml b/Cargo.toml index 41f21be4..b038dbe6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "calcit" -version = "0.8.35" +version = "0.8.36" authors = ["jiyinyiyong "] edition = "2021" license = "MIT" diff --git a/calcit/test.cirru b/calcit/test.cirru index 5367be0f..15c24abe 100644 --- a/calcit/test.cirru +++ b/calcit/test.cirru @@ -211,6 +211,13 @@ *l $ atom 1 reset! *l 2 assert= 2 @*l + + let + Deref $ defrecord! Deref + :deref $ fn (self) 2 + v $ %:: Deref :value 1 + assert= 2 @v + assert= (nth v 1) 1 |test-tag $ %{} :CodeEntry (:doc |) :code $ quote defn test-tag () diff --git a/package.json b/package.json index cca3b6ca..b05b32b1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@calcit/procs", - "version": "0.8.35", + "version": "0.8.36", "main": "./lib/calcit.procs.mjs", "devDependencies": { "@types/node": "^20.11.8", diff --git a/src/data/cirru.rs b/src/data/cirru.rs index f3362fb8..007a7b7d 100644 --- a/src/data/cirru.rs +++ b/src/data/cirru.rs @@ -73,7 +73,12 @@ pub fn code_to_calcit(xs: &Cirru, ns: &str, def: &str, coord: Vec) -> Result }, ]))), '@' => Ok(Calcit::from(CalcitList::from(&[ - Calcit::Proc(CalcitProc::AtomDeref), + // `deref` expands to `.deref` or `&atom:deref` + Calcit::Symbol { + sym: Arc::from("deref"), + info: symbol_info.to_owned(), + location: Some(coord.to_owned()), + }, Calcit::Symbol { sym: Arc::from(&s[1..]), info: symbol_info.to_owned(), diff --git a/ts-src/calcit.procs.mts b/ts-src/calcit.procs.mts index d009ac12..0cb396a0 100644 --- a/ts-src/calcit.procs.mts +++ b/ts-src/calcit.procs.mts @@ -161,7 +161,11 @@ export let peekDefatom = (path: string): CalcitRef => { }; export let _$n_atom_$o_deref = (x: CalcitRef): CalcitValue => { - return x.value; + if (x instanceof CalcitRef) { + return x.value; + } else { + throw new Error("Expected CalcitRef"); + } }; export let _$n__ADD_ = (x: number, y: number): number => { diff --git a/ts-src/custom-formatter.mts b/ts-src/custom-formatter.mts index 49bff342..e5e58de9 100644 --- a/ts-src/custom-formatter.mts +++ b/ts-src/custom-formatter.mts @@ -1,4 +1,4 @@ -import { CalcitValue, is_literal } from "./js-primes.mjs"; +import { CalcitValue, isLiteral } from "./js-primes.mjs"; import { CalcitRef, CalcitSymbol, CalcitTag } from "./calcit-data.mjs"; import { CalcitRecord } from "./js-record.mjs"; @@ -41,7 +41,10 @@ let styles = (o: any) => { let keys = Object.keys(o); for (let idx = 0; idx < keys.length; idx++) { let key = keys[idx]; - styleCode += `${kabab(key)}:${(o as any)[key]};`; + let value = (o as any)[key]; + if (value) { + styleCode += `${kabab(key)}:${value};`; + } } return { style: styleCode, @@ -72,6 +75,21 @@ let td = (style: any, ...children: any[]) => { return ["td", styles(style), ...children]; }; +/** handle null value in nested data */ +let saveString = (v: CalcitValue) => { + if (typeof v === "string") { + if (v.match(/[\s\"\n\t\,]/)) { + return `"|${v}"`; + } else { + return `|${v}`; + } + } else if (v != null && v.toString) { + return v.toString(); + } else { + return "nil"; + } +}; + export let load_console_formatter_$x_ = () => { if (typeof window === "object") { window["devtoolsFormatters"] = [ @@ -85,18 +103,20 @@ export let load_console_formatter_$x_ = () => { } if (obj instanceof CalcitList || obj instanceof CalcitSliceList) { let preview = ""; + let hasCollection = false; for (let idx = 0; idx < obj.len(); idx++) { preview += " "; - if (is_literal(obj.get(idx))) { - preview += obj.get(idx).toString(); + if (isLiteral(obj.get(idx))) { + preview += saveString(obj.get(idx)); } else { preview += ".."; + hasCollection = true; break; } } return div( { - color: hsl(280, 80, 60, 0.4), + color: hasCollection ? hsl(280, 80, 60, 0.4) : null, }, `[]`, span( @@ -113,16 +133,18 @@ export let load_console_formatter_$x_ = () => { } if (obj instanceof CalcitMap || obj instanceof CalcitSliceMap) { let preview = ""; + let hasCollection = false; for (let [k, v] of obj.pairs()) { preview += " "; - if (is_literal(k) && is_literal(v)) { - preview += `(${k.toString()} ${v.toString()})`; + if (isLiteral(k) && isLiteral(v)) { + preview += `(${saveString(k)} ${saveString(v)})`; } else { preview += ".."; + hasCollection = true; break; } } - return div({ color: hsl(280, 80, 60, 0.4) }, "{}", preview); + return div({ color: hasCollection ? hsl(280, 80, 60, 0.4) : undefined }, "{}", preview); } if (obj instanceof CalcitSet) { return div({ color: hsl(280, 80, 60, 0.4) }, obj.toString(true)); @@ -132,15 +154,28 @@ export let load_console_formatter_$x_ = () => { return ret; } if (obj instanceof CalcitTuple) { - let ret: any[] = div( - {}, - div({ display: "inline-block", color: hsl(300, 100, 40) }, "::"), - div({ marginLeft: "6px", display: "inline-block" }, embedObject(obj.tag)) - ); - for (let idx = 0; idx < obj.extra.length; idx++) { - ret.push(div({ marginLeft: "6px", display: "inline-block" }, embedObject(obj.extra[idx]))); + if (obj.klass) { + let ret: any[] = div( + {}, + div({ display: "inline-block", color: hsl(300, 100, 40) }, "%::"), + div({ marginLeft: "6px", display: "inline-block" }, embedObject(obj.klass)), + div({ marginLeft: "6px", display: "inline-block" }, embedObject(obj.tag)) + ); + for (let idx = 0; idx < obj.extra.length; idx++) { + ret.push(div({ marginLeft: "6px", display: "inline-block" }, embedObject(obj.extra[idx]))); + } + return ret; + } else { + let ret: any[] = div( + {}, + div({ display: "inline-block", color: hsl(300, 100, 40) }, "::"), + div({ marginLeft: "6px", display: "inline-block" }, embedObject(obj.tag)) + ); + for (let idx = 0; idx < obj.extra.length; idx++) { + ret.push(div({ marginLeft: "6px", display: "inline-block" }, embedObject(obj.extra[idx]))); + } + return ret; } - return ret; } if (obj instanceof CalcitRef) { return div( @@ -165,24 +200,12 @@ export let load_console_formatter_$x_ = () => { }, hasBody: (obj) => { if (obj instanceof CalcitList || obj instanceof CalcitSliceList) { - let has_collection = false; - for (let idx = 0; idx < obj.len(); idx++) { - if (!is_literal(obj.get(idx))) { - has_collection = true; - break; - } - } - return obj.len() > 0 && has_collection; + let hasCollection = obj.nestedDataInChildren(); + return obj.len() > 0 && hasCollection; } if (obj instanceof CalcitMap || obj instanceof CalcitSliceMap) { - let has_collection = false; - for (let [k, v] of obj.pairs()) { - if (!is_literal(k) || !is_literal(v)) { - has_collection = true; - break; - } - } - return obj.len() > 0 && has_collection; + let hasCollection = obj.nestedDataInChildren(); + return obj.len() > 0 && hasCollection; } if (obj instanceof CalcitSet) { return obj.len() > 0; @@ -228,8 +251,8 @@ export let load_console_formatter_$x_ = () => { let ret: any[] = table({ color: hsl(280, 80, 60), borderLeft: "1px solid #eee" }); let pairs = obj.pairs(); pairs.sort((pa, pb) => { - let ka = pa[0].toString(); - let kb = pb[0].toString(); + let ka = saveString(pa[0]); + let kb = saveString(pb[0]); if (ka < kb) { return -1; } else if (ka > kb) { diff --git a/ts-src/js-cirru.mts b/ts-src/js-cirru.mts index 1398df6f..29132f3b 100644 --- a/ts-src/js-cirru.mts +++ b/ts-src/js-cirru.mts @@ -1,7 +1,7 @@ import { overwriteComparator, initTernaryTreeMap } from "@calcit/ternary-tree"; import { CirruWriterNode, writeCirruCode } from "@cirru/writer.ts"; -import { CalcitValue, is_literal, _$n_compare } from "./js-primes.mjs"; +import { CalcitValue, isLiteral, _$n_compare } from "./js-primes.mjs"; import { CalcitList, CalcitSliceList } from "./js-list.mjs"; import { CalcitRecord } from "./js-record.mjs"; import { CalcitMap, CalcitSliceMap } from "./js-map.mjs"; @@ -99,10 +99,10 @@ export let to_cirru_edn = (x: CalcitValue): CirruEdnFormat => { pairs_buffer.push(pairs[idx]); } pairs_buffer.sort((a, b) => { - let a0_literal = is_literal(a[0]); - let a1_literal = is_literal(a[1]); - let b0_literal = is_literal(b[0]); - let b1_literal = is_literal(b[1]); + let a0_literal = isLiteral(a[0]); + let a1_literal = isLiteral(a[1]); + let b0_literal = isLiteral(b[0]); + let b1_literal = isLiteral(b[1]); if (a0_literal && b0_literal) { if (a1_literal && !b1_literal) { return -1; @@ -132,8 +132,8 @@ export let to_cirru_edn = (x: CalcitValue): CirruEdnFormat => { } // placed literals first buffer.sort((a, b) => { - let a1_literal = is_literal(a[1] as CalcitValue); - let b1_literal = is_literal(b[1] as CalcitValue); + let a1_literal = isLiteral(a[1] as CalcitValue); + let b1_literal = isLiteral(b[1] as CalcitValue); if (a1_literal && !b1_literal) { return -1; } else if (!a1_literal && b1_literal) { diff --git a/ts-src/js-list.mts b/ts-src/js-list.mts index d5f27c34..61b9e8a6 100644 --- a/ts-src/js-list.mts +++ b/ts-src/js-list.mts @@ -1,6 +1,6 @@ import * as ternaryTree from "@calcit/ternary-tree"; -import { CalcitValue } from "./js-primes.mjs"; +import { CalcitValue, isLiteral } from "./js-primes.mjs"; import { TernaryTreeList, @@ -106,6 +106,13 @@ export class CalcitList { reverse() { return new CalcitList(ternaryTree.reverse(this.value)); } + nestedDataInChildren(): boolean { + for (let idx = 0; idx < this.len(); idx++) { + if (!isLiteral(this.get(idx))) { + return true; + } + } + } } // represent append-only immutable list in Array slices @@ -254,6 +261,13 @@ export class CalcitSliceList { reverse() { return this.turnListMode().reverse(); } + nestedDataInChildren(): boolean { + for (let idx = 0; idx < this.len(); idx++) { + if (!isLiteral(this.get(idx))) { + return true; + } + } + } } function* sliceGenerator(xs: Array, start: number, end: number): Generator { diff --git a/ts-src/js-map.mts b/ts-src/js-map.mts index 84732b44..513c664e 100644 --- a/ts-src/js-map.mts +++ b/ts-src/js-map.mts @@ -1,6 +1,6 @@ import * as ternaryTree from "@calcit/ternary-tree"; -import { CalcitValue } from "./js-primes.mjs"; +import { CalcitValue, isLiteral } from "./js-primes.mjs"; import { CalcitSet } from "./js-set.mjs"; import { @@ -174,9 +174,18 @@ export class CalcitMap { } return new CalcitSet(ret); } + + /** detecthing in custom formatter */ + nestedDataInChildren() { + for (let [k, v] of this.pairs()) { + if (!isLiteral(k) || !isLiteral(v)) { + return true; + } + } + } } -// store small map in linear array to reduce cost of building tree +/* store small map in linear array to reduce cost of building tree */ export class CalcitSliceMap { cachedHash: Hash; /** in arrayMode, only flatten values, instead of tree structure */ @@ -369,4 +378,13 @@ export class CalcitSliceMap { } return new CalcitSet(ret); } + + /** detecthing in custom formatter */ + nestedDataInChildren() { + for (let [k, v] of this.pairs()) { + if (!isLiteral(k) || !isLiteral(v)) { + return true; + } + } + } } diff --git a/ts-src/js-primes.mts b/ts-src/js-primes.mts index 5249a565..be8bbcd5 100644 --- a/ts-src/js-primes.mts +++ b/ts-src/js-primes.mts @@ -25,7 +25,7 @@ export type CalcitValue = | CalcitCirruQuote | null; -export let is_literal = (x: CalcitValue): boolean => { +export let isLiteral = (x: CalcitValue): boolean => { if (x == null) return true; if (typeof x == "string") return true; if (typeof x == "boolean") return true;