Skip to content

Commit

Permalink
Merge pull request #210 from calcit-lang/tag-edn
Browse files Browse the repository at this point in the history
fix edn and tuple issues
  • Loading branch information
NoEgAm committed Jun 5, 2023
2 parents ae1753e + a4ebf59 commit 4c8d1ef
Show file tree
Hide file tree
Showing 11 changed files with 89 additions and 21 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"
version = "0.7.0-a3"
version = "0.7.0-a7"
authors = ["jiyinyiyong <[email protected]>"]
edition = "2021"
license = "MIT"
Expand Down
11 changes: 11 additions & 0 deletions calcit/test.cirru
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,17 @@
assert= (:: 0 1 0) $ update (:: 0 0 0) 1 inc
assert= (:: 0 0 1) $ update (:: 0 0 0) 2 inc

assert= 1 $ count $ :: :none
assert-detect tuple? $ parse-cirru-edn "|:: :none"

assert= false $ =
:: :t 1
:: :t 2

assert= false $ =
:: :t 1
:: :t 1 2

|test-effect $ quote
fn ()
log-title "|Testing effect"
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.7.0-a3",
"version": "0.7.0-a7",
"main": "./lib/calcit.procs.mjs",
"devDependencies": {
"@types/node": "^20.2.5",
Expand Down
46 changes: 35 additions & 11 deletions src/builtins/meta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,17 +308,41 @@ pub fn invoke_method(name: &str, invoke_args: &CalcitItems, call_stack: &CallSta
}
let value = invoke_args[0].to_owned();
let s0 = CalcitScope::default();
let class: Calcit = match &invoke_args[0] {
Calcit::Tuple(_tag, _extra, class) => (**class).to_owned(),
let (tag, class): (String, Calcit) = match &invoke_args[0] {
Calcit::Tuple(tag, _extra, class) => (tag.to_string(), (**class).to_owned()),
// classed should already be preprocessed
Calcit::List(..) => runner::evaluate_symbol("&core-list-class", &s0, primes::CORE_NS, None, call_stack)?,
Calcit::Map(..) => runner::evaluate_symbol("&core-map-class", &s0, primes::CORE_NS, None, call_stack)?,
Calcit::Number(..) => runner::evaluate_symbol("&core-number-class", &s0, primes::CORE_NS, None, call_stack)?,
Calcit::Str(..) => runner::evaluate_symbol("&core-string-class", &s0, primes::CORE_NS, None, call_stack)?,
Calcit::Set(..) => runner::evaluate_symbol("&core-set-class", &s0, primes::CORE_NS, None, call_stack)?,
Calcit::Record(..) => runner::evaluate_symbol("&core-record-class", &s0, primes::CORE_NS, None, call_stack)?,
Calcit::Nil => runner::evaluate_symbol("&core-nil-class", &s0, primes::CORE_NS, None, call_stack)?,
Calcit::Fn { .. } | Calcit::Proc(..) => runner::evaluate_symbol("&core-fn-class", &s0, primes::CORE_NS, None, call_stack)?,
Calcit::List(..) => (
"&core-list-class".to_owned(),
runner::evaluate_symbol("&core-list-class", &s0, primes::CORE_NS, None, call_stack)?,
),
Calcit::Map(..) => (
"&core-map-class".to_owned(),
runner::evaluate_symbol("&core-map-class", &s0, primes::CORE_NS, None, call_stack)?,
),
Calcit::Number(..) => (
"&core-number-class".to_owned(),
runner::evaluate_symbol("&core-number-class", &s0, primes::CORE_NS, None, call_stack)?,
),
Calcit::Str(..) => (
"&core-string-class".to_owned(),
runner::evaluate_symbol("&core-string-class", &s0, primes::CORE_NS, None, call_stack)?,
),
Calcit::Set(..) => (
"&core-set-class".to_owned(),
runner::evaluate_symbol("&core-set-class", &s0, primes::CORE_NS, None, call_stack)?,
),
Calcit::Record(..) => (
"&core-record-class".to_owned(),
runner::evaluate_symbol("&core-record-class", &s0, primes::CORE_NS, None, call_stack)?,
),
Calcit::Nil => (
"&core-nil-class".to_owned(),
runner::evaluate_symbol("&core-nil-class", &s0, primes::CORE_NS, None, call_stack)?,
),
Calcit::Fn { .. } | Calcit::Proc(..) => (
"&core-fn-class".to_owned(),
runner::evaluate_symbol("&core-fn-class", &s0, primes::CORE_NS, None, call_stack)?,
),
x => {
return Err(CalcitErr::use_msg_stack_location(
format!("cannot decide a class from: {x}"),
Expand Down Expand Up @@ -353,7 +377,7 @@ pub fn invoke_method(name: &str, invoke_args: &CalcitItems, call_stack: &CallSta
None => {
let content = fields.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(" ");
Err(CalcitErr::use_msg_stack(
format!("unknown field `{name}` in: {content}"),
format!("unknown method `.{name}` for {tag}.\navailable methods: {content}"),
call_stack,
))
}
Expand Down
2 changes: 1 addition & 1 deletion src/cirru/calcit-core.cirru
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@
defmacro &tag-match-internal (value & body)
if (&list:empty? body)
quasiquote
eprintln "|[Warn] tag-match found no matched case, missing `_` case?" ~value
raise $ str-spaced "|tag-match found no matched case, missing `_` for" ~value
&let
pair (&list:first body)
if
Expand Down
7 changes: 7 additions & 0 deletions src/data/edn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,13 @@ pub fn calcit_to_edn(x: &Calcit) -> Result<Edn, String> {
}
Ok(Edn::tuple(Edn::Tag(name.to_owned()), extra_values))
}
Calcit::Tag(tag) => {
let mut extra_values = vec![];
for item in extra {
extra_values.push(calcit_to_edn(item)?);
}
Ok(Edn::tuple(Edn::Tag(tag.to_owned()), extra_values))
}
v => {
Err(format!("EDN tuple expected 'quote or record, unknown tag: {v}"))
// TODO more types to handle
Expand Down
2 changes: 1 addition & 1 deletion ts-src/calcit-data.mts
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@ export let _$n__$e_ = (x: CalcitValue, y: CalcitValue): boolean => {
}
if (x instanceof CalcitTuple) {
if (y instanceof CalcitTuple) {
return _$n__$e_(x.tag, y.tag) && _$n__$e_(x.get(1), y.get(1));
return x.eq(y);
}
return false;
}
Expand Down
16 changes: 14 additions & 2 deletions ts-src/calcit.procs.mts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// CALCIT VERSION
export const calcit_version = "0.7.0-a3";
export const calcit_version = "0.7.0-a7";

import { parse, ICirruNode } from "@cirru/parser.ts";
import { writeCirruCode } from "@cirru/writer.ts";
Expand Down Expand Up @@ -1300,28 +1300,38 @@ export function invoke_method_closure(p: string) {

export function invoke_method(p: string, obj: CalcitValue, ...args: CalcitValue[]) {
let klass: CalcitRecord;
let tag: string;
let value = obj;
if (obj == null) {
tag = "&core-nil-class";
klass = calcit_builtin_classes.nil;
} else if (obj instanceof CalcitTuple) {
if (obj.klass instanceof CalcitRecord) {
tag = obj.tag.toString();
klass = obj.klass;
} else {
throw new Error("Method invoking expected a record as class");
}
} else if (typeof obj === "number") {
tag = "&core-number-class";
klass = calcit_builtin_classes.number;
} else if (typeof obj === "string") {
tag = "&core-string-class";
klass = calcit_builtin_classes.string;
} else if (typeof obj === "function") {
tag = "&core-fn-class";
klass = calcit_builtin_classes.fn;
} else if (obj instanceof CalcitSet) {
tag = "&core-set-class";
klass = calcit_builtin_classes.set;
} else if (obj instanceof CalcitList || obj instanceof CalcitSliceList) {
tag = "&core-list-class";
klass = calcit_builtin_classes.list;
} else if (obj instanceof CalcitRecord) {
tag = "&core-record-class";
klass = calcit_builtin_classes.record;
} else if (obj instanceof CalcitMap || obj instanceof CalcitSliceMap) {
tag = "&core-map-class";
klass = calcit_builtin_classes.map;
} else {
if ((obj as any)[p] == null) {
Expand All @@ -1331,7 +1341,9 @@ export function invoke_method(p: string, obj: CalcitValue, ...args: CalcitValue[
}
if (klass == null) throw new Error("Cannot find class for this object for invoking");

if (!klass.contains(p)) throw new Error(`Missing method '${p}' for object: ${obj}`);
if (!klass.contains(p)) {
throw new Error(`Missing method '.${p}' for '${tag}' object '${obj}'.\navailable fields are: ${klass.fields.map((fd: CalcitTag) => fd.value).join(" ")}`);
}

let method = klass.get(p);
if (typeof method === "function") {
Expand Down
4 changes: 2 additions & 2 deletions ts-src/js-cirru.mts
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,8 @@ export let extract_cirru_edn = (x: CirruEdnFormat): CalcitValue => {
return new CalcitCirruQuote(x[1]);
}
if (x[0] === "::") {
if (x.length < 3) {
throw new Error("tuple expects at least 2 values");
if (x.length < 2) {
throw new Error("tuple expects at least 1 value1");
}
let baseClass = new CalcitRecord(newTag("base-class"), [], []);
return new CalcitTuple(extract_cirru_edn(x[1]), x.slice(2).map(extract_cirru_edn), baseClass);
Expand Down
16 changes: 15 additions & 1 deletion ts-src/js-tuple.mts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Hash } from "@calcit/ternary-tree";

import { CalcitValue } from "./js-primes.mjs";
import { newTag, toString } from "./calcit-data.mjs";
import { _$n__$e_, newTag, toString } from "./calcit-data.mjs";
import { CalcitRecord } from "./js-record.mjs";

export class CalcitTuple {
Expand Down Expand Up @@ -38,6 +38,20 @@ export class CalcitTuple {
count() {
return 1 + this.extra.length;
}
eq(y: CalcitTuple): boolean {
if (!_$n__$e_(this.tag, y.tag)) {
return false;
}
if (this.extra.length !== y.extra.length) {
return false;
}
for (let idx = 0; idx < this.extra.length; idx++) {
if (!_$n__$e_(this.extra[idx], y.extra[idx])) {
return false;
}
}
return true;
}
toString(disableJsDataWarning: boolean = false): string {
let args = [this.tag, ...this.extra];
let content = "";
Expand Down

0 comments on commit 4c8d1ef

Please sign in to comment.