Skip to content

Commit

Permalink
add with-js-log, foldl-shortcut; bump 0.3.4
Browse files Browse the repository at this point in the history
  • Loading branch information
tiye committed May 2, 2021
1 parent 9698bfe commit 1b7c00f
Show file tree
Hide file tree
Showing 10 changed files with 174 additions and 35 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "calcit_runner"
version = "0.3.3"
version = "0.3.4"
authors = ["jiyinyiyong <jiyinyiyong@gmail.com>"]
edition = "2018"
license = "MIT"
Expand Down
2 changes: 2 additions & 0 deletions calcit/snapshots/test-js.cirru
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@
raise (str "|error of math" 2 1)
raise "|base error"

with-js-log ({} (:a 1))

do true

:proc $ quote ()
Expand Down
4 changes: 4 additions & 0 deletions lib/calcit-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -751,4 +751,8 @@ export class CrDataSet {
});
return `(#{}${itemsCode})`;
}

values() {
return this.value.values();
}
}
48 changes: 48 additions & 0 deletions lib/calcit.procs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,54 @@ export let foldl = function (xs: CrDataValue, acc: CrDataValue, f: CrDataFn): Cr
}
};

export let foldl_shortcut = function (xs: CrDataValue, acc: CrDataValue, v0: CrDataValue, f: CrDataFn): CrDataValue {
if (arguments.length !== 4) {
throw new Error("foldl-shortcut takes 4 arguments");
}

if (f == null) {
debugger;
throw new Error("Expected function for folding");
}
if (xs instanceof CrDataList) {
var state = acc;
for (let idx = 0; idx < xs.len(); idx++) {
let item = xs.get(idx);
let pair = f(state, item);
if (pair instanceof CrDataList && pair.len() == 2) {
if (typeof pair.get(0) == "boolean") {
if (pair.get(0)) {
return pair.get(1);
} else {
state = pair.get(1);
}
}
} else {
throw new Error("Expected return value in `[bool, acc]` structure");
}
}
return v0;
}
if (xs instanceof CrDataSet) {
let state = acc;
for (let item of xs.values()) {
let pair = f(state, item);
if (pair instanceof CrDataList && pair.len() == 2) {
if (typeof pair.get(0) == "boolean") {
if (pair.get(0)) {
return pair.get(1);
} else {
state = pair.get(1);
}
}
} else {
throw new Error("Expected return value in `[bool, acc]` structure");
}
}
return v0;
}
};

export let _AND__ADD_ = (x: number, y: number): number => {
return x + y;
};
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@calcit/procs",
"version": "0.3.3",
"version": "0.3.4",
"main": "./lib/calcit.procs.js",
"devDependencies": {
"@types/node": "^15.0.1",
Expand Down
2 changes: 2 additions & 0 deletions src/builtins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ pub fn is_syntax_name(s: &str) -> bool {
| "macroexpand-1"
| "macroexpand-all"
| "foldl" // for performance
| "foldl-shortcut" // for performance
| "try"
| "sort" // TODO need better solution
| "defatom"
Expand All @@ -316,6 +317,7 @@ pub fn handle_syntax(
"if" => syntax::syntax_if(nodes, scope, file_ns, program),
"&let" => syntax::syntax_let(nodes, scope, file_ns, program),
"foldl" => lists::foldl(nodes, scope, file_ns, program),
"foldl-shortcut" => lists::foldl_shortcut(nodes, scope, file_ns, program),
"macroexpand" => syntax::macroexpand(nodes, scope, file_ns, program),
"macroexpand-1" => syntax::macroexpand_1(nodes, scope, file_ns, program),
"macroexpand-all" => syntax::macroexpand_all(nodes, scope, file_ns, program),
Expand Down
79 changes: 79 additions & 0 deletions src/builtins/lists.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,85 @@ pub fn foldl(
}
}

/// foldl-shortcut using syntax for performance, it's supposed to be a function
/// by returning `[bool, acc]`, bool indicates where performace a shortcut return
pub fn foldl_shortcut(
expr: &CalcitItems,
scope: &CalcitScope,
file_ns: &str,
program_code: &ProgramCodeData,
) -> Result<Calcit, String> {
if expr.len() == 4 {
let xs = runner::evaluate_expr(&expr[0], scope, file_ns, program_code)?;
let acc = runner::evaluate_expr(&expr[1], scope, file_ns, program_code)?;
let default_value = runner::evaluate_expr(&expr[2], scope, file_ns, program_code)?;
let f = runner::evaluate_expr(&expr[3], scope, file_ns, program_code)?;
match (&xs, &f) {
// dirty since only functions being call directly then we become fast
(Calcit::List(xs), Calcit::Fn(_, def_ns, _, def_scope, args, body)) => {
let mut state = acc;
for x in xs {
let values = im::vector![state, x.clone()];
let pair = runner::run_fn(&values, &def_scope, args, body, def_ns, program_code)?;
match pair {
Calcit::List(ys) if ys.len() == 2 => match &ys[0] {
Calcit::Bool(b) => {
if *b {
return Ok(ys[1].to_owned());
} else {
state = ys[1].to_owned()
}
}
a => return Err(format!("return value in foldl-shortcut should be a bool, got: {}", a)),
},
_ => {
return Err(format!(
"return value for foldl-shortcut should be `[bool, acc]`, got: {}",
pair
))
}
}
}
Ok(default_value)
}
// almost identical body, escept for the type
(Calcit::Set(xs), Calcit::Fn(_, def_ns, _, def_scope, args, body)) => {
let mut state = acc;
for x in xs {
let values = im::vector![state, x.clone()];
let pair = runner::run_fn(&values, &def_scope, args, body, def_ns, program_code)?;
match pair {
Calcit::List(ys) if ys.len() == 2 => match &ys[0] {
Calcit::Bool(b) => {
if *b {
return Ok(ys[1].to_owned());
} else {
state = ys[1].to_owned()
}
}
a => return Err(format!("return value in foldl-shortcut should be a bool, got: {}", a)),
},
_ => {
return Err(format!(
"return value for foldl-shortcut should be `[bool, acc]`, got: {}",
pair
))
}
}
}
Ok(default_value)
}

(_, _) => Err(format!("foldl-shortcut expected list... and fn, got: {} {}", xs, f)),
}
} else {
Err(format!(
"foldl-shortcut expected 4 arguments list,state,default,fn, got: {:?}",
expr
))
}
}

// TODO as SYNTAX at current, not supposed to be a syntax
pub fn sort(
expr: &CalcitItems,
Expand Down
64 changes: 34 additions & 30 deletions src/cirru/calcit-core.cirru
Original file line number Diff line number Diff line change
Expand Up @@ -215,26 +215,25 @@
fn (acc item) $ &intersection acc item

|index-of $ quote
defn index-of (xs0 item)
apply-args (0 xs0)
fn (idx xs)
if (empty? xs) nil
if (&= item (first xs)) idx
recur (&+ 1 idx) (rest xs)
defn index-of (xs item)
foldl-shortcut xs 0 nil $ fn (idx x)
if (&= item x)
[] true idx
[] false (&+ 1 idx)

|find-index $ quote
defn find-index (xs0 f)
apply-args (0 xs0)
fn (idx xs)
if (empty? xs) nil
if (f (first xs)) idx
recur (&+ 1 idx) (rest xs)
defn find-index (xs f)
foldl-shortcut xs 0 nil $ fn (idx x)
if (f x)
[] true idx
[] false (&+ 1 idx)

|find $ quote
defn find (xs f)
&let
idx (find-index xs f)
if (nil? idx) nil (get xs idx)
foldl-shortcut xs 0 nil $ fn (_acc x)
if (f x)
[] true x
[] false nil

|-> $ quote
defmacro -> (base & xs)
Expand Down Expand Up @@ -393,16 +392,17 @@

|every? $ quote
defn every? (xs f)
if (empty? xs) true
if (f (first xs))
recur (rest xs) f
, false
foldl-shortcut xs nil true $ fn (_acc x)
if (f x)
[] false nil
[] true false

|any? $ quote
defn any? (xs f)
if (empty? xs) false
if (f (first xs)) true
recur (rest xs) f
foldl-shortcut xs nil false $ fn (_acc x)
if (f x)
[] true true
[] false nil

|mapcat $ quote
defn mapcat (xs f)
Expand All @@ -421,14 +421,8 @@

|map-indexed $ quote
defn map-indexed (xs f)
apply-args
([]) 0 xs
fn (acc idx ys)
if (empty? ys) acc
recur
append acc (f idx (first ys))
&+ idx 1
rest ys
foldl xs ([]) $ fn (acc x)
append acc $ f (count acc) x

|filter $ quote
defn filter (xs f)
Expand Down Expand Up @@ -910,6 +904,16 @@
echo (format-to-lisp (quote ~x)) |=> ~v
~ v

|with-js-log $ quote
defmacro with-js-log (x)
&let
v $ gensym |v
quote-replace
&let
~v ~x
js/console.log (format-to-lisp (quote ~x)) |=> ~v
~ v

|{,} $ quote
defmacro {,} (& body)
&let
Expand Down
4 changes: 2 additions & 2 deletions src/runner/preprocess.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,8 @@ fn process_list_call(
preprocess_call_let(&name, &name_ns, args, scope_defs, file_ns, program_code)?,
None,
)),
"if" | "assert" | "do" | "try" | "macroexpand" | "macroexpand-all" | "macroexpand-1" | "foldl" | "sort"
| "reset!" => Ok((
"if" | "assert" | "do" | "try" | "macroexpand" | "macroexpand-all" | "macroexpand-1" | "foldl"
| "foldl-shortcut" | "sort" | "reset!" => Ok((
preprocess_each_items(&name, &name_ns, args, scope_defs, file_ns, program_code)?,
None,
)),
Expand Down

0 comments on commit 1b7c00f

Please sign in to comment.