Skip to content

Commit f7fce19

Browse files
committed
experimental shorthand of method calling; tag 0.9.15
1 parent bb5477e commit f7fce19

File tree

6 files changed

+78
-6
lines changed

6 files changed

+78
-6
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
[package]
33
name = "calcit"
4-
version = "0.9.14"
4+
version = "0.9.15"
55
authors = ["jiyinyiyong <jiyinyiyong@gmail.com>"]
66
edition = "2024"
77
license = "MIT"

calcit/test-js.cirru

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,8 @@
189189
js/console.log pattern
190190
assert= true $ .!test pattern "|12"
191191
assert= false $ .!test pattern "|xy"
192+
assert= true $ pattern.!test |12
193+
assert= false $ pattern.!test |xy
192194
|test-property $ %{} :CodeEntry (:doc "|try property ops")
193195
:code $ quote
194196
fn ()

calcit/test-list.cirru

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
:code $ quote (defatom *counted 0)
1010
|main! $ %{} :CodeEntry (:doc |)
1111
:code $ quote
12-
defn main! () (log-title "|Testing list") (test-list) (log-title "|Testing foldl") (test-foldl) (log-title "|Testing every/any") (test-every) (log-title "|Testing groups") (test-groups) (log-title "|Testing apply") (test-apply) (log-title "|Testing join") (test-join) (log-title "|Testing repeat") (test-repeat) (log-title "|Testing sort") (test-sort) (test-alias) (test-doseq) (test-let[]) (test-methods) (test-pair) (test-match) (do true)
12+
defn main! () (log-title "|Testing list") (test-list) (log-title "|Testing foldl") (test-foldl) (log-title "|Testing every/any") (test-every) (log-title "|Testing groups") (test-groups) (log-title "|Testing apply") (test-apply) (log-title "|Testing join") (test-join) (log-title "|Testing repeat") (test-repeat) (log-title "|Testing sort") (test-sort) (test-alias) (test-doseq) (test-let[]) (test-methods) (test-methods-shorthand) (test-pair) (test-match) (do true)
1313
|test-alias $ %{} :CodeEntry (:doc |)
1414
:code $ quote
1515
fn () (log-title "|Testing alias")
@@ -427,6 +427,13 @@
427427
.dissoc ([] :a :b :c) 2
428428
assert= ([] 1 2 3)
429429
distinct $ [] 1 2 3 1 2
430+
|test-methods-shorthand $ %{} :CodeEntry (:doc "|test shorthand")
431+
:code $ quote
432+
fn ()
433+
&let
434+
xs $ [] 1 2 3 4
435+
assert= 1 $ xs.get 0
436+
assert= true $ xs.any? $ fn (x) (&> x 3)
430437
|test-pair $ %{} :CodeEntry (:doc |)
431438
:code $ quote
432439
fn ()

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@calcit/procs",
3-
"version": "0.9.14",
3+
"version": "0.9.15",
44
"main": "./lib/calcit.procs.mjs",
55
"devDependencies": {
66
"@types/node": "^22.15.24",

src/data/cirru.rs

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,9 @@ pub fn code_to_calcit(xs: &Cirru, ns: &str, def: &str, coord: Vec<u8>) -> Result
104104
Cirru::List(ys) => {
105105
let mut zs: Vec<Calcit> = vec![];
106106
for (idx, y) in ys.iter().enumerate() {
107-
let mut next_coord: Vec<u8> = (*coord).to_owned();
108-
next_coord.push(idx as u8); // code not supposed to be fatter than 256 children
107+
if idx > 255 {
108+
return Err(format!("Cirru code too large, index: {idx}"));
109+
}
109110

110111
if let Cirru::List(ys) = y
111112
&& ys.len() > 1
@@ -122,6 +123,24 @@ pub fn code_to_calcit(xs: &Cirru, ns: &str, def: &str, coord: Vec<u8>) -> Result
122123
return Err(format!("expected 1 argument, got: {ys:?}"));
123124
}
124125
}
126+
let mut next_coord: Vec<u8> = (*coord).to_owned();
127+
next_coord.push(idx as u8); // clamp to prevent overflow, code not supposed to be larger than 256 children
128+
129+
if idx == 0
130+
&& let Cirru::Leaf(s) = y
131+
{
132+
// dirty hack to support shorthand of method calling,
133+
// this feature is EXPERIMENTAL and might change in future
134+
if let Some((obj, method)) = split_leaf_to_method_call(s) {
135+
zs.push(method);
136+
zs.push(Calcit::Symbol {
137+
sym: Arc::from(obj),
138+
info: symbol_info.to_owned(),
139+
location: Some(next_coord.into()),
140+
});
141+
continue;
142+
}
143+
}
125144

126145
zs.push(code_to_calcit(y, ns, def, next_coord)?);
127146
}
@@ -130,6 +149,50 @@ pub fn code_to_calcit(xs: &Cirru, ns: &str, def: &str, coord: Vec<u8>) -> Result
130149
}
131150
}
132151

152+
/// split `a.b` into `.b` and `a`, `a.-b` into `.-b` and `a`, `a.!b` into `.!b` and `a`, etc.
153+
/// some characters available for variables are okey here, for example `-`, `!`, `?`, `*``, etc.
154+
fn split_leaf_to_method_call(s: &str) -> Option<(String, Calcit)> {
155+
if let Some((obj, method)) = s.split_once(".-") {
156+
if is_valid_symbol(obj) && is_valid_symbol(method) {
157+
return Some((obj.to_owned(), Calcit::Method(method.into(), MethodKind::Access)));
158+
}
159+
}
160+
if let Some((obj, method)) = s.split_once(".!") {
161+
if is_valid_symbol(obj) && is_valid_symbol(method) {
162+
return Some((obj.to_owned(), Calcit::Method(method.into(), MethodKind::InvokeNative)));
163+
}
164+
}
165+
if let Some((obj, method)) = s.split_once(".") {
166+
if is_valid_symbol(obj) && is_valid_symbol(method) {
167+
return Some((obj.to_owned(), Calcit::Method(method.into(), MethodKind::Invoke)));
168+
}
169+
}
170+
171+
None
172+
}
173+
174+
fn is_valid_symbol(s: &str) -> bool {
175+
// empty space is not valid symbol
176+
if s.is_empty() {
177+
return false;
178+
}
179+
// symbol should not start with a digit
180+
if s.chars().next().unwrap().is_ascii_digit() {
181+
return false;
182+
}
183+
// every character should be valid, a-z, A-Z, 0-9, -, _, ?, !, *, etc.
184+
for c in s.chars() {
185+
if c.is_alphabetic() {
186+
continue;
187+
}
188+
if c.is_ascii_digit() || c == '-' || c == '_' || c == '?' || c == '!' || c == '*' {
189+
continue;
190+
}
191+
return false;
192+
}
193+
true
194+
}
195+
133196
/// transform Cirru to Calcit data directly
134197
pub fn cirru_to_calcit(xs: &Cirru) -> Calcit {
135198
match xs {

0 commit comments

Comments
 (0)