Skip to content

Commit

Permalink
add &record:extend-as ; bump 0.4.15
Browse files Browse the repository at this point in the history
  • Loading branch information
tiye committed Aug 10, 2021
1 parent a5fb4a8 commit cf38fe6
Show file tree
Hide file tree
Showing 9 changed files with 110 additions and 5 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.4.14"
version = "0.4.15"
authors = ["jiyinyiyong <jiyinyiyong@gmail.com>"]
edition = "2018"
license = "MIT"
Expand Down
4 changes: 4 additions & 0 deletions calcit/snapshots/test-record.cirru
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,10 @@
[] :color :red
.nth kitty 0

&let
persian $ .extend kitty :Persian :age 10
assert= 10 $ .get persian :age
assert= |Persian $ .get-name persian

|main! $ quote
defn main! ()
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.4.14",
"version": "0.4.15",
"main": "./lib/calcit.procs.js",
"devDependencies": {
"@types/node": "^16.4.13",
Expand Down
2 changes: 2 additions & 0 deletions src/builtins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ pub fn is_proc_name(s: &str) -> bool {
| "&record:nth"
| "&record:get"
| "&record:assoc"
| "&record:extend-as"
)
}

Expand Down Expand Up @@ -355,6 +356,7 @@ pub fn handle_proc(name: &str, args: &CalcitItems) -> Result<Calcit, String> {
"&record:nth" => records::nth(args),
"&record:get" => records::get(args),
"&record:assoc" => records::assoc(args),
"&record:extend-as" => records::extend_as(args),
a => Err(format!("No such proc: {}", a)),
}
}
Expand Down
61 changes: 61 additions & 0 deletions src/builtins/records.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,3 +230,64 @@ pub fn assoc(xs: &CalcitItems) -> Result<Calcit, String> {
(None, ..) => Err(format!("record:assoc expected 3 arguments, got: {:?}", xs)),
}
}

pub fn extend_as(xs: &CalcitItems) -> Result<Calcit, String> {
if xs.len() != 4 {
return Err(format!("record:extend-as expected 4 arguments, got: {:?}", xs));
}
match (xs.get(0), xs.get(1), xs.get(2), xs.get(3)) {
(Some(Calcit::Record(_name, fields, values)), Some(n), Some(a), Some(new_value)) => match a {
Calcit::Str(s) | Calcit::Keyword(s) | Calcit::Symbol(s, ..) => match find_in_fields(fields, s) {
Some(_pos) => Err(format!("field `{}` already existed", s)),
None => {
let mut next_fields: Vec<String> = vec![];
let mut next_values: Vec<Calcit> = vec![];
let mut inserted: bool = false;

for (i, k) in fields.iter().enumerate() {
if inserted {
next_fields.push(k.to_owned());
next_values.push(values[i].to_owned());
} else {
match s.cmp(k) {
Ordering::Less => {
next_fields.push(s.to_owned());
next_values.push(new_value.to_owned());

next_fields.push(k.to_owned());
next_values.push(values[i].to_owned());
inserted = true;
}
Ordering::Greater => {
next_fields.push(k.to_owned());
next_values.push(values[i].to_owned());
}
Ordering::Equal => {
unreachable!("does not equal")
}
}
}
}
if !inserted {
next_fields.push(s.to_owned());
next_values.push(new_value.to_owned());
}

let new_name: Result<String, String> = match n {
Calcit::Str(s) | Calcit::Keyword(s) | Calcit::Symbol(s, ..) => Ok(s.to_owned()),
_ => Err(format!("")),
};

Ok(Calcit::Record(
new_name?.to_owned(),
next_fields.to_owned(),
next_values.to_owned(),
))
}
},
a => Err(format!("invalid field `{}` for {:?}", a, fields)),
},
(Some(a), ..) => Err(format!("record:extend-as expected a record, got: {}", a)),
(None, ..) => Err(format!("record:extend-as expected 4 arguments, got: {:?}", xs)),
}
}
1 change: 1 addition & 0 deletions src/cirru/calcit-core.cirru
Original file line number Diff line number Diff line change
Expand Up @@ -1310,6 +1310,7 @@
:nth &record:nth
:assoc &record:assoc
:from-map &record:from-map
:extend &record:extend-as

|&core-list-class $ quote
defrecord! &core-list-class
Expand Down
2 changes: 1 addition & 1 deletion ts-src/calcit.procs.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// CALCIT VERSION
export const calcit_version = "0.4.14";
export const calcit_version = "0.4.15";

import { overwriteComparator, initTernaryTreeMap } from "@calcit/ternary-tree";
import { parse } from "@cirru/parser.ts";
Expand Down
39 changes: 38 additions & 1 deletion ts-src/js-record.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { initTernaryTreeMap, Hash } from "@calcit/ternary-tree";
import { initTernaryTreeMap, Hash, insert } from "@calcit/ternary-tree";
import { CalcitValue } from "./js-primes";
import { kwd, toString, getStringName, findInFields } from "./calcit-data";

Expand Down Expand Up @@ -203,3 +203,40 @@ export let _$n_record_$o_matches_$q_ = (x: CalcitValue, y: CalcitValue): boolean
}
return fieldsEqual(x.fields, y.fields);
};

export function _$n_record_$o_extend_as(obj: CalcitValue, new_name: CalcitValue, new_key: CalcitValue, new_value: CalcitValue) {
if (arguments.length !== 4) throw new Error(`Expected 4 arguments, got ${arguments.length}`);
if (!(obj instanceof CalcitRecord)) throw new Error("Expected record");
let field = getStringName(new_key);
let new_name_string = getStringName(new_name);
let new_fields: string[] = [];
let new_values: CalcitValue[] = [];
let inserted = false;

for (let i in new_fields) {
let k = new_fields[i];
if (inserted) {
new_fields.push(k);
new_values.push(obj.values[i]);
} else {
if (field < k) {
new_fields.push(field);
new_values.push(new_value);

new_fields.push(k);
new_values.push(obj.values[i]);
} else if (field > k) {
new_fields.push(k);
new_values.push(obj.values[i]);
} else {
throw new Error("Does not extend existed record field");
}
}
}
if (!inserted) {
new_fields.push(field);
new_values.push(new_value);
}

return new CalcitRecord(new_name_string, new_fields, new_values);
}

0 comments on commit cf38fe6

Please sign in to comment.