Skip to content

Commit

Permalink
Merge pull request #258 from calcit-lang/atom-in-edn
Browse files Browse the repository at this point in the history
extend edn to include atom
  • Loading branch information
NoEgAm authored Jan 10, 2025
2 parents 7c510a2 + d497957 commit 8653149
Show file tree
Hide file tree
Showing 14 changed files with 120 additions and 87 deletions.
36 changes: 21 additions & 15 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "calcit"
version = "0.9.6"
version = "0.9.7"
authors = ["jiyinyiyong <[email protected]>"]
edition = "2021"
license = "MIT"
Expand All @@ -15,11 +15,11 @@ exclude = ["lib/*", "calcit/*", "js-out/*", "scripts/*"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
cirru_edn = "0.6.12"
cirru_edn = "0.6.13"
# cirru_edn = { path = "/Users/chenyong/repo/cirru/edn.rs" }
cirru_parser = "0.1.31"
# cirru_parser = { path = "/Users/chenyong/repo/cirru/parser.rs" }
argh = "0.1.12"
argh = "0.1.13"
dirs = "5.0.1"
notify = "7.0.0"
notify-debouncer-mini = "0.5.0"
Expand All @@ -28,12 +28,12 @@ hex = "0.4.3"
rpds = "1.1.0"
im_ternary_tree = "0.0.18"
# im_ternary_tree = { path = "/Users/chenyong/repo/calcit-lang/ternary-tree.rs" }
colored = "2.1.0"
colored = "3.0.0"
strum = "0.25"
strum_macros = "0.25"

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
libloading = "0.8.5"
libloading = "0.8.6"
ctrlc = "3.4.5"

[lib]
Expand Down
12 changes: 12 additions & 0 deletions calcit/test-edn.cirru
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
test-edn-comment
inside-eval:
test-symbol
test-atom
|test-edn $ %{} :CodeEntry (:doc |)
:code $ quote
defn test-edn ()
Expand Down Expand Up @@ -126,6 +127,17 @@
code $ quote $ + 1 2
assert= code
eval $ &data-to-code code
|test-atom $ %{} :CodeEntry (:doc |)
:code $ quote
defn test-atom ()
log-title "|Testing atom to edn"
let
a $ parse-cirru-edn "|atom 1"
println "|Check a" a
assert= true $ ref? a
assert= 1 $ deref a
assert= "|atom 1"
trim $ format-cirru-edn a

:ns $ %{} :CodeEntry (:doc |)
:code $ quote
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"name": "@calcit/procs",
"version": "0.9.6",
"version": "0.9.7",
"main": "./lib/calcit.procs.mjs",
"devDependencies": {
"@types/node": "^22.8.7",
"typescript": "^5.6.3"
"@types/node": "^22.10.5",
"typescript": "^5.7.2"
},
"scripts": {
"compile": "rm -rfv lib/* && tsc",
Expand Down
2 changes: 1 addition & 1 deletion src/builtins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::calcit::{Calcit, CalcitErr, CalcitList, CalcitProc, CalcitScope, Calc
use crate::call_stack::{using_stack, CallStackList};

use im_ternary_tree::TernaryTreeList;
pub(crate) use refs::ValueAndListeners;
pub(crate) use refs::{quick_build_atom, ValueAndListeners};

pub type FnType = fn(xs: Vec<Calcit>, call_stack: &CallStackList) -> Result<Calcit, CalcitErr>;
pub type SyntaxType = fn(expr: &TernaryTreeList<Calcit>, scope: &CalcitScope, file_ns: &str) -> Result<Calcit, CalcitErr>;
Expand Down
23 changes: 13 additions & 10 deletions src/builtins/refs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,18 +117,21 @@ static ATOM_ID_GEN: AtomicUsize = AtomicUsize::new(0);
/// proc
pub fn atom(xs: &[Calcit]) -> Result<Calcit, CalcitErr> {
match xs.first() {
Some(value) => {
let atom_idx = ATOM_ID_GEN.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
let path: String = format!("atom-{atom_idx}");
Some(value) => Ok(quick_build_atom(value.to_owned())),
_ => CalcitErr::err_str("atom expected 1 node"),
}
}

let path_info: Arc<str> = path.into();
// println!("atom {:?}", path_info);
/// this is a internal helper for `atom`, not exposed to Calcit
pub fn quick_build_atom(v: Calcit) -> Calcit {
let atom_idx = ATOM_ID_GEN.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
let path: String = format!("atom-{atom_idx}");

let pair_value = Arc::new(Mutex::new((value.to_owned(), HashMap::new())));
Ok(Calcit::Ref(path_info, pair_value))
}
_ => CalcitErr::err_str("atom expected 2 nodes"),
}
let path_info: Arc<str> = path.into();
// println!("atom {:?}", path_info);

let pair_value = Arc::new(Mutex::new((v, HashMap::new())));
Calcit::Ref(path_info, pair_value)
}

/// previously `deref`, but `deref` now turned into a function calling `&atom:deref`
Expand Down
5 changes: 5 additions & 0 deletions src/data/edn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ pub fn calcit_to_edn(x: &Calcit) -> Result<Edn, String> {
MethodKind::InvokeNativeOptional => Ok(Edn::Symbol(format!(".?!{name}").into())),
},
Calcit::AnyRef(r) => Ok(Edn::AnyRef(r.to_owned())),
Calcit::Ref(_p, pair) => {
let pair = pair.lock().expect("read ref");
Ok(Edn::Atom(Box::new(calcit_to_edn(&pair.0)?)))
}
a => Err(format!("not able to generate EDN: {a:?}")), // TODO more types to handle
}
}
Expand Down Expand Up @@ -183,6 +187,7 @@ pub fn edn_to_calcit(x: &Edn, options: &Calcit) -> Calcit {
}
Edn::Buffer(buf) => Calcit::Buffer(buf.to_owned()),
Edn::AnyRef(r) => Calcit::AnyRef(r.to_owned()),
Edn::Atom(a) => crate::builtins::quick_build_atom(edn_to_calcit(a, options)),
}
}
/// find a record field in options
Expand Down
17 changes: 1 addition & 16 deletions ts-src/calcit-data.mts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { CalcitSet, overwriteSetComparator } from "./js-set.mjs";
import { CalcitTuple } from "./js-tuple.mjs";
import { CalcitCirruQuote, cirru_deep_equal } from "./js-cirru.mjs";
import { CirruWriterNode } from "@cirru/writer.ts";
import { CalcitRef } from "./js-ref.mjs";

// we have to inject cache in a dirty way in some cases
const calcit_dirty_hash_key = "_calcit_cached_hash";
Expand Down Expand Up @@ -100,22 +101,6 @@ export let tipNestedCalcitData = (x: CalcitValue): string => {
return x.toString();
};

export class CalcitRef {
value: CalcitValue;
path: string;
listeners: Map<CalcitValue, CalcitFn>;
cachedHash: Hash;
constructor(x: CalcitValue, path: string) {
this.value = x;
this.path = path;
this.listeners = new Map();
this.cachedHash = null;
}
toString(): string {
return `(&ref ${this.value.toString()})`;
}
}

export type CalcitFn = (...xs: CalcitValue[]) => CalcitValue;

export let getStringName = (x: CalcitValue): string => {
Expand Down
24 changes: 3 additions & 21 deletions ts-src/calcit.procs.mts
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,9 @@ import { parse, ICirruNode } from "@cirru/parser.ts";
import { writeCirruCode } from "@cirru/writer.ts";

import { CalcitValue } from "./js-primes.mjs";
import {
CalcitSymbol,
CalcitTag,
CalcitRef,
CalcitFn,
CalcitRecur,
newTag,
refsRegistry,
toString,
getStringName,
to_js_data,
_$n__$e_,
hashFunction,
} from "./calcit-data.mjs";
import { CalcitSymbol, CalcitTag, CalcitFn, CalcitRecur, newTag, refsRegistry, toString, getStringName, _$n__$e_, hashFunction } from "./calcit-data.mjs";

import { CalcitRef } from "./js-ref.mjs";
import { fieldsEqual, CalcitRecord } from "./js-record.mjs";

export * from "./calcit-data.mjs";
Expand Down Expand Up @@ -148,13 +136,7 @@ export let defatom = (path: string, x: CalcitValue): CalcitValue => {
return v;
};

var atomCounter = 0;

export let atom = (x: CalcitValue): CalcitValue => {
atomCounter = atomCounter + 1;
let v = new CalcitRef(x, `atom-${atomCounter}`);
return v;
};
export { atom } from "./js-ref.mjs";

export let peekDefatom = (path: string): CalcitRef => {
return refsRegistry.get(path);
Expand Down
3 changes: 2 additions & 1 deletion ts-src/custom-formatter.mts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { CalcitValue, isLiteral } from "./js-primes.mjs";
import { CalcitRef, CalcitSymbol, CalcitTag } from "./calcit-data.mjs";
import { CalcitSymbol, CalcitTag } from "./calcit-data.mjs";
import { CalcitRef } from "./js-ref.mjs";

import { CalcitRecord } from "./js-record.mjs";
import { CalcitMap, CalcitSliceMap } from "./js-map.mjs";
Expand Down
13 changes: 12 additions & 1 deletion ts-src/js-cirru.mts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ import { CalcitList, CalcitSliceList } from "./js-list.mjs";
import { CalcitRecord } from "./js-record.mjs";
import { CalcitMap, CalcitSliceMap } from "./js-map.mjs";
import { CalcitSet } from "./js-set.mjs";
import { CalcitTag, CalcitSymbol, CalcitRecur, CalcitRef, newTag } from "./calcit-data.mjs";
import { CalcitTag, CalcitSymbol, CalcitRecur, newTag } from "./calcit-data.mjs";
import { CalcitTuple } from "./js-tuple.mjs";
import { CalcitRef } from "./js-ref.mjs";
import { deepEqual } from "@calcit/ternary-tree/lib/utils.mjs";
import { atom } from "./js-ref.mjs";

type CirruEdnFormat = string | CirruEdnFormat[];

Expand Down Expand Up @@ -165,6 +167,9 @@ export let to_cirru_edn = (x: CalcitValue): CirruEdnFormat => {
throw new Error(`Unsupported tag for EDN: ${x.tag}`);
}
}
if (x instanceof CalcitRef) {
return ["atom", to_cirru_edn(x.value)];
}
console.error(x);
throw new Error("Unexpected data to to-cirru-edn");
};
Expand Down Expand Up @@ -335,6 +340,12 @@ export let extract_cirru_edn = (x: CirruEdnFormat, options: CalcitValue): Calcit
undefined
);
}
if (x[0] === "atom") {
if (x.length !== 2) {
throw new Error(`atom expects 1 argument, got: ${x}`);
}
return atom(extract_cirru_edn(x[1], options));
}
}
console.error(x);
throw new Error(`Unexpected data from EDN: ${x}`);
Expand Down
3 changes: 2 additions & 1 deletion ts-src/js-primes.mts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { CalcitTag, CalcitSymbol, CalcitRef, CalcitFn, CalcitRecur } from "./calcit-data.mjs";
import { CalcitTag, CalcitSymbol, CalcitFn, CalcitRecur } from "./calcit-data.mjs";
import { CalcitRef } from "./js-ref.mjs";
import { CalcitList, CalcitSliceList } from "./js-list.mjs";
import { CalcitRecord } from "./js-record.mjs";
import { CalcitMap, CalcitSliceMap } from "./js-map.mjs";
Expand Down
27 changes: 27 additions & 0 deletions ts-src/js-ref.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Hash } from "@calcit/ternary-tree";
import type { CalcitFn } from "./calcit-data.mjs";
import type { CalcitValue } from "./js-primes.mts";

export class CalcitRef {
value: CalcitValue;
path: string;
listeners: Map<CalcitValue, CalcitFn>;
cachedHash: Hash;
constructor(x: CalcitValue, path: string) {
this.value = x;
this.path = path;
this.listeners = new Map();
this.cachedHash = null;
}
toString(): string {
return `(&ref ${this.value.toString()})`;
}
}

var atomCounter = 0;

export let atom = (x: CalcitValue): CalcitValue => {
atomCounter = atomCounter + 1;
let v = new CalcitRef(x, `atom-${atomCounter}`);
return v;
};
Loading

0 comments on commit 8653149

Please sign in to comment.