diff --git a/fungll.kp b/fungll.kp index 359977f..4437b5b 100644 --- a/fungll.kp +++ b/fungll.kp @@ -38,8 +38,9 @@ altStart (lambda (t s k c) id) altOp (lambda (p q) (lambda (t s k c) (lcompose (p t s k c) (q t s [] k c)))) term_parser (lambda (t [X b i] l k c) (lambda (sigma) - (if (= (idx b (- i 1)) (idx t k)) ((c [[X b i] l (+ 1 k)]) sigma) - sigma))) + (let (this_term (idx b (- i 1))) + (if (= this_term (slice t k (+ k (len this_term)))) ((c [[X b i] l (+ (len this_term) k)]) sigma) + sigma)))) term (lambda (s) [ s term_parser ]) continue (lambda (BSR_element c) (lambda ([U G P Y]) diff --git a/fungll_test.kp b/fungll_test.kp index 60ec7d6..997fb2b 100644 --- a/fungll_test.kp +++ b/fungll_test.kp @@ -1,6 +1,48 @@ (with_import "./fungll.kp" (let ( - just_a_parser (parse (nterm 'A (altOp altStart (seqOp seqStart (term (idx "a" 0)))))) - parse_result (just_a_parser "a") - _ (println "parse result " parse_result) + + _ (println "The a parser") + just_a_parser (parse (nterm 'A (altOp altStart (seqOp seqStart (term "a"))))) + _ (println "parse result for a " (just_a_parser "a")) + _ (println "parse result for b " (just_a_parser "b")) + _ (println "parse result for aa " (just_a_parser "aa")) + _ (println "parse result for ba " (just_a_parser "ba")) + _ (println "parse result for ab " (just_a_parser "ab")) + + _ (println "The aa parser") + just_aa_parser (parse (nterm 'A (altOp altStart (seqOp seqStart (term "aa"))))) + _ (println "parse result for a " (just_aa_parser "a")) + _ (println "parse result for b " (just_aa_parser "b")) + _ (println "parse result for aa " (just_aa_parser "aa")) + _ (println "parse result for ba " (just_aa_parser "ba")) + _ (println "parse result for ab " (just_aa_parser "ab")) + + _ (println "The a.a parser") + just_aa_parser (parse (nterm 'A (altOp altStart (seqOp (seqOp seqStart (term "a")) (term "a"))))) + _ (println "parse result for a " (just_aa_parser "a")) + _ (println "parse result for b " (just_aa_parser "b")) + _ (println "parse result for aa " (just_aa_parser "aa")) + _ (println "parse result for ba " (just_aa_parser "ba")) + _ (println "parse result for ab " (just_aa_parser "ab")) + + _ (println "The b|a.a parser") + just_aa_parser (parse (nterm 'A (altOp (altOp altStart (seqOp seqStart (term "b"))) (seqOp (seqOp seqStart (term "a")) (term "a"))))) + _ (println "parse result for a " (just_aa_parser "a")) + _ (println "parse result for b " (just_aa_parser "b")) + _ (println "parse result for aa " (just_aa_parser "aa")) + _ (println "parse result for ba " (just_aa_parser "ba")) + _ (println "parse result for ab " (just_aa_parser "ab")) + + _ (println "The a|a,A parser") + just_aa_parser (let-rec ( + As (nterm 'A (altOp (altOp altStart (seqOp seqStart (term "a"))) (seqOp (seqOp seqStart (term ",")) As))) + ) (parse As)) + _ (println "parse result for a " (just_aa_parser "a")) + _ (println "parse result for b " (just_aa_parser "b")) + _ (println "parse result for aa " (just_aa_parser "aa")) + _ (println "parse result for ba " (just_aa_parser "ba")) + _ (println "parse result for ab " (just_aa_parser "ab")) + _ (println "parse result for a,a " (just_aa_parser "a,a")) + _ (println "parse result for a,a,a " (just_aa_parser "a,a,a")) + ) nil)) diff --git a/k_prime.krak b/k_prime.krak index b1b13e9..223ad18 100644 --- a/k_prime.krak +++ b/k_prime.krak @@ -46,6 +46,15 @@ obj KPEnv (Object) { destruct() copy_construct(&other) } + fun operator<(other: ref KPEnv):bool { + if data.keys < other.data.keys || data.values < other.data.values { + return true; + } + if (outer != null()) && ((other.outer == null()) || (*outer < *other.outer)) { + return true; + } + return false; + } fun set(key: str, val: KPValue) { data.set(key, val) } @@ -117,6 +126,9 @@ obj KPBuiltinCombiner (Object) { fun operator==(other: ref KPBuiltinCombiner):bool { return name == other.name } + fun operator<(other: ref KPBuiltinCombiner):bool { + return name < other.name + } fun call(params: vec, dynamic_env: KPValue): pair<*KPEnv, KPResult> { if !dynamic_env.is_env() { return make_pair(null(), KPResult::Err(kpString(pr_str(dynamic_env, true) + " is not an env"))) @@ -178,6 +190,10 @@ obj KPCombiner (Object) { // not sure about env return env == other.env && dynamic_env_name == other.dynamic_env_name && wrap_level == other.wrap_level && parameters == other.parameters && is_variadic == other.is_variadic && body->equals(*other.body) } + fun operator<(other: ref KPCombiner):bool { + // not sure about env + return *env < *other.env || dynamic_env_name < other.dynamic_env_name || wrap_level < other.wrap_level || parameters < other.parameters || is_variadic < other.is_variadic || body->lt(*other.body) + } // no call b/c need to do in EVAL for TCO fun prep_call(params: ref vec, dynamic_env: KPValue): pair<*KPEnv, KPResult> { for (var l = 0; l < wrap_level; l++;) { @@ -268,6 +284,45 @@ obj KPValue (Object) { } return false } + fun variant(): int { + match (internal) { + KPValue_int::Array(d) { return 0; } + KPValue_int::String(d) { return 1; } + KPValue_int::Int(d) { return 2; } + KPValue_int::Symbol(d) { return 3; } + KPValue_int::Combiner(d) { return 4; } + KPValue_int::BuiltinCombiner(d) { return 5; } + KPValue_int::Env(e) { return 6; } + KPValue_int::True() { return 7; } + KPValue_int::False() { return 8; } + KPValue_int::Nil() { return 9; } + } + } + fun operator<(other: ref KPValue):bool { + return this->lt(other) + } + fun lt(other: ref KPValue): bool { + var our_variant = variant() + var their_variant = other.variant() + if our_variant < their_variant { + return true; + } else if our_variant > their_variant { + return false; + } + match (internal) { + KPValue_int::Array(d) { match (other.internal) { KPValue_int::Array(db) { return d.get() < db.get(); } } } + KPValue_int::String(d) { match (other.internal) { KPValue_int::String(db) { return d < db; } } } + KPValue_int::Int(d) { match (other.internal) { KPValue_int::Int(db) { return d < db; } } } + KPValue_int::Symbol(d) { match (other.internal) { KPValue_int::Symbol(db) { return d < db; } } } + KPValue_int::Combiner(d){ match (other.internal) { KPValue_int::Combiner(db) { return d < db; } } } + KPValue_int::BuiltinCombiner(d) { match (other.internal) { KPValue_int::BuiltinCombiner(db) { return d < db; } } } + KPValue_int::Env(e) { match (other.internal) { KPValue_int::Env(eb) { return e < eb; } } } + KPValue_int::True() { match (other.internal) { KPValue_int::True() { return false; } } } + KPValue_int::False() { match (other.internal) { KPValue_int::False() { return false; } } } + KPValue_int::Nil() { match (other.internal) { KPValue_int::Nil() { return false; } } } + } + return false + } fun deep_clone(): KPValue { match (internal) { KPValue_int::Array(v) { @@ -1100,25 +1155,33 @@ fun main(argc: int, argv: **char): int { })); env->set(str("="), make_builtin_combiner(str("="), 1, false, fun(params: vec, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { - if params.size != 2 { - return make_pair(null(), KPResult::Err(kpString(str("Need 2 params to =")))) + if params.size <= 1 { + return make_pair(null(), KPResult::Err(kpString(str("Need 2 or more params to =")))) } - return make_pair(null(), KPResult::Ok(kpBool(params[0].equals(params[1])))) + for (var i = 0; i < params.size - 1; i++;) { + if !(params[i].equals(params[i+1])) { + return make_pair(null(), KPResult::Ok(kpBool(false))) + } + } + return make_pair(null(), KPResult::Ok(kpBool(true))) })); env->set(str("!="), make_builtin_combiner(str("!="), 1, false, fun(params: vec, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { - if params.size != 2 { - return make_pair(null(), KPResult::Err(kpString(str("Need 2 params to !=")))) + if params.size <= 1 { + return make_pair(null(), KPResult::Err(kpString(str("Need 2 or more params to !=")))) } - return make_pair(null(), KPResult::Ok(kpBool(!params[0].equals(params[1])))) + for (var i = 0; i < params.size - 1; i++;) { + if (params[i].equals(params[i+1])) { + return make_pair(null(), KPResult::Ok(kpBool(false))) + } + } + return make_pair(null(), KPResult::Ok(kpBool(true))) })); env->set(str("<"), make_builtin_combiner(str("<"), 1, false, fun(params: vec, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { if params.size <= 1 { return make_pair(null(), KPResult::Err(kpString(str("Need 2 or more params to <")))) } - if !params[0].is_int() { return make_pair(null(), KPResult::Err(kpString(str("called < with first not an int ") + pr_str(params[0], true) + "\nenv was\n" + dynamic_env->to_string()))); } for (var i = 0; i < params.size - 1; i++;) { - if !params[i+1].is_int() { return make_pair(null(), KPResult::Err(kpString(str("called < with param ") + (i+1) + " not an int " + pr_str(params[i+1], true)))); } - if !(params[i].get_int() < params[i+1].get_int()) { + if !(params[i].lt(params[i+1])) { return make_pair(null(), KPResult::Ok(kpBool(false))) } } @@ -1128,10 +1191,8 @@ fun main(argc: int, argv: **char): int { if params.size <= 1 { return make_pair(null(), KPResult::Err(kpString(str("Need 2 or more params to <=")))) } - if !params[0].is_int() { return make_pair(null(), KPResult::Err(kpString(str("called <= with first not an int")))); } for (var i = 0; i < params.size - 1; i++;) { - if !params[i+1].is_int() { return make_pair(null(), KPResult::Err(kpString(str("called <= with not an int")))); } - if !(params[i].get_int() <= params[i+1].get_int()) { + if !(params[i].lt(params[i+1])) && !(params[i].equals(params[i+1])) { return make_pair(null(), KPResult::Ok(kpBool(false))) } } @@ -1141,10 +1202,8 @@ fun main(argc: int, argv: **char): int { if params.size <= 1 { return make_pair(null(), KPResult::Err(kpString(str("Need 2 or more params to >")))) } - if !params[0].is_int() { return make_pair(null(), KPResult::Err(kpString(str("called > with first not an int")))); } for (var i = 0; i < params.size - 1; i++;) { - if !params[i+1].is_int() { return make_pair(null(), KPResult::Err(kpString(str("called > with param ") + (i+1) + " not an int " + pr_str(params[i+1], true)))); } - if !(params[i].get_int() > params[i+1].get_int()) { + if params[i].lt(params[i+1]) || params[i].equals(params[i+1]) { return make_pair(null(), KPResult::Ok(kpBool(false))) } } @@ -1154,10 +1213,8 @@ fun main(argc: int, argv: **char): int { if params.size <= 1 { return make_pair(null(), KPResult::Err(kpString(str("Need 2 or more params to >=")))) } - if !params[0].is_int() { return make_pair(null(), KPResult::Err(kpString(str("called >= with first not an int")))); } for (var i = 0; i < params.size - 1; i++;) { - if !params[i+1].is_int() { return make_pair(null(), KPResult::Err(kpString(str("called >= with not an int")))); } - if !(params[i].get_int() >= params[i+1].get_int()) { + if params[i].lt(params[i+1]) { return make_pair(null(), KPResult::Ok(kpBool(false))) } } diff --git a/stdlib/str.krak b/stdlib/str.krak index 0d83aa7..5805a18 100644 --- a/stdlib/str.krak +++ b/stdlib/str.krak @@ -223,6 +223,9 @@ obj str (Object, Serializable, Hashable) { r++ } } + fun operator<(other: ref str): bool { + return *this <= other && *this != other + } fun operator*(n: int): str { var to_ret.construct(): str diff --git a/stdlib/vec.krak b/stdlib/vec.krak index 4e64fcf..a14e866 100644 --- a/stdlib/vec.krak +++ b/stdlib/vec.krak @@ -207,6 +207,16 @@ obj vec (Object, Serializable) { return false return true } + fun operator< (other: ref vec):bool { + if (size < other.size) + return true + if (size > other.size) + return false + for (var i = 0; i < size; i++;) + if (data[i] < other.data[i]) // it's !(==) because we want equality if our members are equal, and overloading etc + return true + return false + } fun set(index: int, dataIn: ref T): void { if (index < 0 || index >= size)