massage new constructor to be a function and add methods to both it and the new syntax

This commit is contained in:
Nathan Braswell
2020-09-08 23:30:56 -04:00
parent ba64276630
commit 54cffb4185
2 changed files with 128 additions and 226 deletions

View File

@@ -637,9 +637,7 @@ fun rep(grammar: ref Grammer<KPResult, KPValue>, env: *KPEnv, a: str): str {
fun str_wrapper(params: ref vec<KPValue>, dynamic_env: *KPEnv, sep: *char, print_readably: bool): KPResult { fun str_wrapper(params: ref vec<KPValue>, dynamic_env: *KPEnv, sep: *char, print_readably: bool): KPResult {
var to_ret = str() var to_ret = str()
for (var i = 0; i < params.size; i++;) { for (var i = 0; i < params.size; i++;) {
var ip = EVAL(dynamic_env, params[i]) to_ret += pr_str(params[i], print_readably)
if is_err(ip) { return ip; }
to_ret += pr_str(get_value(ip), print_readably)
if i != params.size-1 { if i != params.size-1 {
to_ret += sep to_ret += sep
} }
@@ -809,42 +807,25 @@ fun main(argc: int, argv: **char): int {
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("None of cond branches were true")))) return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("None of cond branches were true"))))
})); }));
env->set(str("symbol?"), make_builtin_combiner(str("symbol?"), 0, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { env->set(str("symbol?"), make_builtin_combiner(str("symbol?"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
if params.size != 1 { if params.size != 1 {
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 1 param to symbol?")))) return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 1 param to symbol?"))))
} }
var ip = EVAL(dynamic_env, params[0]) return make_pair(null<KPEnv>(), KPResult::Ok(kpBool(params[0].is_symbol())))
if is_err(ip) {
return make_pair(null<KPEnv>(), ip)
}
return make_pair(null<KPEnv>(), KPResult::Ok(kpBool(get_value(ip).is_symbol())))
})); }));
env->set(str("get-text"), make_builtin_combiner(str("get-text"), 0, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { env->set(str("get-text"), make_builtin_combiner(str("get-text"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
if params.size != 1 { if params.size != 1 {
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 1 param to get-text")))) return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 1 param to get-text"))))
} }
var ip = EVAL(dynamic_env, params[0]) if !params[0].is_symbol() {
if is_err(ip) {
return make_pair(null<KPEnv>(), ip)
}
var iv = get_value(ip)
if !iv.is_symbol() {
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Called get-text with not a symbol")))) return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Called get-text with not a symbol"))))
} }
return make_pair(null<KPEnv>(), KPResult::Ok(kpString(iv.get_symbol_text()))) return make_pair(null<KPEnv>(), KPResult::Ok(kpString(params[0].get_symbol_text())))
})); }));
env->set(str("array"), make_builtin_combiner(str("array"), 0, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { env->set(str("array"), make_builtin_combiner(str("array"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
var evaled_params = vec<KPValue>() return make_pair(null<KPEnv>(), KPResult::Ok(kpArray(params)))
for (var i = 0; i < params.size; i++;) {
var ip = EVAL(dynamic_env, params[i])
if is_err(ip) {
return make_pair(null<KPEnv>(), ip)
}
evaled_params.add(get_value(ip))
}
return make_pair(null<KPEnv>(), KPResult::Ok(kpArray(evaled_params)))
})); }));
env->set(str("array-with-len"), make_builtin_combiner(str("array-with-len"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { env->set(str("array-with-len"), make_builtin_combiner(str("array-with-len"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
if !params[0].is_int() { if !params[0].is_int() {
@@ -857,109 +838,76 @@ fun main(argc: int, argv: **char): int {
} }
return make_pair(null<KPEnv>(), KPResult::Ok(kpArray(to_ret))) return make_pair(null<KPEnv>(), KPResult::Ok(kpArray(to_ret)))
})); }));
env->set(str("array?"), make_builtin_combiner(str("array?"), 0, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { env->set(str("array?"), make_builtin_combiner(str("array?"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
if params.size != 1 { if params.size != 1 {
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 1 param to array?")))) return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 1 param to array?"))))
} }
var ip = EVAL(dynamic_env, params[0]) return make_pair(null<KPEnv>(), KPResult::Ok(kpBool(params[0].is_array())))
if is_err(ip) {
return make_pair(null<KPEnv>(), ip)
}
return make_pair(null<KPEnv>(), KPResult::Ok(kpBool(get_value(ip).is_array())))
})); }));
env->set(str("len"), make_builtin_combiner(str("len"), 0, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { env->set(str("len"), make_builtin_combiner(str("len"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
if params.size != 1 { if params.size != 1 {
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 1 param to len")))) return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 1 param to len"))))
} }
var v = EVAL(dynamic_env, params[0]); if !params[0].is_array() {
if is_err(v) { return make_pair(null<KPEnv>(), v); } return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Called len with not an array"))))
return make_pair(null<KPEnv>(), KPResult::Ok(kpInt(get_value(v).get_array_rc().get().size))) }
return make_pair(null<KPEnv>(), KPResult::Ok(kpInt(params[0].get_array_rc().get().size)))
})); }));
env->set(str("idx"), make_builtin_combiner(str("idx"), 0, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { env->set(str("idx"), make_builtin_combiner(str("idx"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
if params.size != 2 { if params.size != 2 {
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 2 params to idx")))) return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 2 params to idx"))))
} }
var v = EVAL(dynamic_env, params[0]); if !params[0].is_array() { return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Param 1 to idx is not array")))); }
if is_err(v) { return make_pair(null<KPEnv>(), v); } if !params[1].is_int() { return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Param 2 to idx is not int")))); }
var vv = get_value(v)
if !vv.is_array() { return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Param 1 to idx is not array")))); }
var i = EVAL(dynamic_env, params[1]);
if is_err(i) { return make_pair(null<KPEnv>(), i); }
var iv = get_value(i)
if !iv.is_int() { return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Param 2 to idx is not int")))); }
var index = iv.get_int() var index = params[1].get_int()
if index < 0 { if index < 0 {
index += vv.get_array_rc().get().size index += params[0].get_array_rc().get().size
} }
return make_pair(null<KPEnv>(), KPResult::Ok(vv.get_array_rc().get()[index])) return make_pair(null<KPEnv>(), KPResult::Ok(params[0].get_array_rc().get()[index]))
})); }));
env->set(str("set-idx!"), make_builtin_combiner(str("set-idx!"), 0, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { env->set(str("set-idx!"), make_builtin_combiner(str("set-idx!"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
if params.size != 3 { if params.size != 3 {
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 3 params to set-idx!")))) return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 3 params to set-idx!"))))
} }
var v = EVAL(dynamic_env, params[0]); if !params[0].is_array() { return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Param 1 to set-idx! is not array")))); }
if is_err(v) { return make_pair(null<KPEnv>(), v); } if !params[1].is_int() { return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Param 2 to set-idx! is not int")))); }
var vv = get_value(v)
if !vv.is_array() { return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Param 1 to set-idx! is not array")))); }
var i = EVAL(dynamic_env, params[1]);
if is_err(i) { return make_pair(null<KPEnv>(), i); }
var iv = get_value(i)
if !iv.is_int() { return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Param 2 to set-idx! is not int")))); }
var r = EVAL(dynamic_env, params[2]); params[0].get_array_rc().get()[params[1].get_int()] = params[2];
if is_err(r) { return make_pair(null<KPEnv>(), r); }
var rv = get_value(r)
vv.get_array_rc().get()[iv.get_int()] = rv;
return make_pair(null<KPEnv>(), KPResult::Ok(kpNil())) return make_pair(null<KPEnv>(), KPResult::Ok(kpNil()))
})); }));
env->set(str("slice"), make_builtin_combiner(str("slice"), 0, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { env->set(str("slice"), make_builtin_combiner(str("slice"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
if params.size != 3 { if params.size != 3 {
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 3 params to slice")))) return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 3 params to slice"))))
} }
var lr = EVAL(dynamic_env, params[0]); if !params[0].is_array() { return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("first param to slice is not array")))); }
if is_err(lr) { return make_pair(null<KPEnv>(), lr); } if !params[1].is_int() { return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("second param to slice is not int")))); }
var lv = get_value(lr); var start = params[1].get_int();
if !lv.is_array() { return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("first param to slice is not array")))); } if !params[2].is_int() { return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("third param to slice is not int")))); }
var startr = EVAL(dynamic_env, params[1]); var end = params[2].get_int();
if is_err(startr) { return make_pair(null<KPEnv>(), startr); }
var startv = get_value(startr);
if !startv.is_int() { return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("second param to slice is not int")))); }
var start = startv.get_int();
var endr = EVAL(dynamic_env, params[2]);
if is_err(endr) { return make_pair(null<KPEnv>(), endr); }
var endv = get_value(endr);
if !endv.is_int() { return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("third param to slice is not int")))); }
var end = endv.get_int();
return make_pair(null<KPEnv>(), KPResult::Ok(kpArray(params[0].get_array_rc().get().slice(start, end))))
return make_pair(null<KPEnv>(), KPResult::Ok(kpArray(lv.get_array_rc().get().slice(start, end))))
})); }));
env->set(str("+"), make_builtin_combiner(str("+"), 0, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { env->set(str("+"), make_builtin_combiner(str("+"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
var to_ret = 0 var to_ret = 0
for (var i = 0; i < params.size; i++;) { for (var i = 0; i < params.size; i++;) {
var ip = EVAL(dynamic_env, params[i]) match (params[i].internal) {
if is_err(ip) { return make_pair(null<KPEnv>(), ip); }
match (get_value(ip).internal) {
KPValue_int::Int(v) { KPValue_int::Int(v) {
to_ret += v to_ret += v
continue continue
} }
} }
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("called + with not an int: ") + pr_str(get_value(ip), false)))) return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("called + with not an int: ") + pr_str(params[i], false))))
} }
return make_pair(null<KPEnv>(), KPResult::Ok(kpInt(to_ret))) return make_pair(null<KPEnv>(), KPResult::Ok(kpInt(to_ret)))
})); }));
env->set(str("-"), make_builtin_combiner(str("-"), 0, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { env->set(str("-"), make_builtin_combiner(str("-"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
var to_ret = 0 var to_ret = 0
for (var i = 0; i < params.size; i++;) { for (var i = 0; i < params.size; i++;) {
var ip = EVAL(dynamic_env, params[i]) match (params[i].internal) {
if is_err(ip) { return make_pair(null<KPEnv>(), ip); }
match (get_value(ip).internal) {
KPValue_int::Int(v) { KPValue_int::Int(v) {
if i == 0 { if i == 0 {
to_ret += v to_ret += v
@@ -969,31 +917,27 @@ fun main(argc: int, argv: **char): int {
continue continue
} }
} }
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("called - with not an int: ") + pr_str(get_value(ip), false)))) return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("called - with not an int: ") + pr_str(params[i], false))))
} }
return make_pair(null<KPEnv>(), KPResult::Ok(kpInt(to_ret))) return make_pair(null<KPEnv>(), KPResult::Ok(kpInt(to_ret)))
})); }));
env->set(str("*"), make_builtin_combiner(str("*"), 0, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { env->set(str("*"), make_builtin_combiner(str("*"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
var to_ret = 1 var to_ret = 1
for (var i = 0; i < params.size; i++;) { for (var i = 0; i < params.size; i++;) {
var ip = EVAL(dynamic_env, params[i]) match (params[i].internal) {
if is_err(ip) { return make_pair(null<KPEnv>(), ip); }
match (get_value(ip).internal) {
KPValue_int::Int(v) { KPValue_int::Int(v) {
to_ret *= v to_ret *= v
continue continue
} }
} }
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("called * with not an int: ") + pr_str(get_value(ip), false)))) return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("called * with not an int: ") + pr_str(params[i], false))))
} }
return make_pair(null<KPEnv>(), KPResult::Ok(kpInt(to_ret))) return make_pair(null<KPEnv>(), KPResult::Ok(kpInt(to_ret)))
})); }));
env->set(str("/"), make_builtin_combiner(str("/"), 0, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { env->set(str("/"), make_builtin_combiner(str("/"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
var to_ret = 1 var to_ret = 1
for (var i = 0; i < params.size; i++;) { for (var i = 0; i < params.size; i++;) {
var ip = EVAL(dynamic_env, params[i]) match (params[i].internal) {
if is_err(ip) { return make_pair(null<KPEnv>(), ip); }
match (get_value(ip).internal) {
KPValue_int::Int(v) { KPValue_int::Int(v) {
if i == 0 { if i == 0 {
to_ret *= v to_ret *= v
@@ -1003,16 +947,14 @@ fun main(argc: int, argv: **char): int {
continue continue
} }
} }
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("called / with not an int: ") + pr_str(get_value(ip), false)))) return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("called / with not an int: ") + pr_str(params[i], false))))
} }
return make_pair(null<KPEnv>(), KPResult::Ok(kpInt(to_ret))) return make_pair(null<KPEnv>(), KPResult::Ok(kpInt(to_ret)))
})); }));
env->set(str("%"), make_builtin_combiner(str("%"), 0, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { env->set(str("%"), make_builtin_combiner(str("%"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
var to_ret = 1 var to_ret = 1
for (var i = 0; i < params.size; i++;) { for (var i = 0; i < params.size; i++;) {
var ip = EVAL(dynamic_env, params[i]) match (params[i].internal) {
if is_err(ip) { return make_pair(null<KPEnv>(), ip); }
match (get_value(ip).internal) {
KPValue_int::Int(v) { KPValue_int::Int(v) {
if i == 0 { if i == 0 {
to_ret *= v to_ret *= v
@@ -1022,86 +964,54 @@ fun main(argc: int, argv: **char): int {
continue continue
} }
} }
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("called % with not an int: ") + pr_str(get_value(ip), false)))) return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("called % with not an int: ") + pr_str(params[i], false))))
} }
return make_pair(null<KPEnv>(), KPResult::Ok(kpInt(to_ret))) return make_pair(null<KPEnv>(), KPResult::Ok(kpInt(to_ret)))
})); }));
env->set(str("="), make_builtin_combiner(str("="), 0, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { env->set(str("="), make_builtin_combiner(str("="), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
if params.size != 2 { if params.size != 2 {
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 2 params to =")))) return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 2 params to ="))))
} }
var a = EVAL(dynamic_env, params[0]); return make_pair(null<KPEnv>(), KPResult::Ok(kpBool(params[0].equals(params[1]))))
if is_err(a) { return make_pair(null<KPEnv>(), a); }
var b = EVAL(dynamic_env, params[1]);
if is_err(b) { return make_pair(null<KPEnv>(), b); }
return make_pair(null<KPEnv>(), KPResult::Ok(kpBool(get_value(a).equals(get_value(b)))))
})); }));
env->set(str("!="), make_builtin_combiner(str("!="), 0, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { env->set(str("!="), make_builtin_combiner(str("!="), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
if params.size != 2 { if params.size != 2 {
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 2 params to !=")))) return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 2 params to !="))))
} }
var a = EVAL(dynamic_env, params[0]); return make_pair(null<KPEnv>(), KPResult::Ok(kpBool(!params[0].equals(params[1]))))
if is_err(a) { return make_pair(null<KPEnv>(), a); }
var b = EVAL(dynamic_env, params[1]);
if is_err(b) { return make_pair(null<KPEnv>(), b); }
return make_pair(null<KPEnv>(), KPResult::Ok(kpBool(!get_value(a).equals(get_value(b)))))
})); }));
env->set(str("<"), make_builtin_combiner(str("<"), 0, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { env->set(str("<"), make_builtin_combiner(str("<"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
if params.size != 2 { if params.size != 2 {
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 2 params to <")))) return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 2 params to <"))))
} }
var a = EVAL(dynamic_env, params[0]); if !params[0].is_int() { return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("called < with first not an int")))); }
if is_err(a) { return make_pair(null<KPEnv>(), a); } if !params[1].is_int() { return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("called < with second not an int")))); }
var av = get_value(a) return make_pair(null<KPEnv>(), KPResult::Ok(kpBool(params[0].get_int() < params[1].get_int())))
if !av.is_int() { return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("called < with first not an int")))); }
var b = EVAL(dynamic_env, params[1]);
if is_err(b) { return make_pair(null<KPEnv>(), b); }
var bv = get_value(b)
if !bv.is_int() { return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("called < with second not an int")))); }
return make_pair(null<KPEnv>(), KPResult::Ok(kpBool(av.get_int() < bv.get_int())))
})); }));
env->set(str("<="), make_builtin_combiner(str("<="), 0, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { env->set(str("<="), make_builtin_combiner(str("<="), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
if params.size != 2 { if params.size != 2 {
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 2 params to <=")))) return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 2 params to <="))))
} }
var a = EVAL(dynamic_env, params[0]); if !params[0].is_int() { return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("called <= with first not an int")))); }
if is_err(a) { return make_pair(null<KPEnv>(), a); } if !params[1].is_int() { return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("called <= with second not an int")))); }
var av = get_value(a) return make_pair(null<KPEnv>(), KPResult::Ok(kpBool(params[0].get_int() <= params[1].get_int())))
if !av.is_int() { return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("called <= with first not an int")))); }
var b = EVAL(dynamic_env, params[1]);
if is_err(b) { return make_pair(null<KPEnv>(), b); }
var bv = get_value(b)
if !bv.is_int() { return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("called <= with second not an int")))); }
return make_pair(null<KPEnv>(), KPResult::Ok(kpBool(av.get_int() <= bv.get_int())))
})); }));
env->set(str(">"), make_builtin_combiner(str(">"), 0, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { env->set(str(">"), make_builtin_combiner(str(">"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
if params.size != 2 { if params.size != 2 {
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 2 params to >")))) return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 2 params to >"))))
} }
var a = EVAL(dynamic_env, params[0]); if !params[0].is_int() { return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("called > with first not an int")))); }
if is_err(a) { return make_pair(null<KPEnv>(), a); } if !params[1].is_int() { return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("called > with second not an int")))); }
var av = get_value(a) return make_pair(null<KPEnv>(), KPResult::Ok(kpBool(params[0].get_int() > params[1].get_int())))
if !av.is_int() { return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("called > with first not an int")))); }
var b = EVAL(dynamic_env, params[1]);
if is_err(b) { return make_pair(null<KPEnv>(), b); }
var bv = get_value(b)
if !bv.is_int() { return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("called > with second not an int")))); }
return make_pair(null<KPEnv>(), KPResult::Ok(kpBool(av.get_int() > bv.get_int())))
})); }));
env->set(str(">="), make_builtin_combiner(str(">="), 0, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { env->set(str(">="), make_builtin_combiner(str(">="), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
if params.size != 2 { if params.size != 2 {
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 2 params to >=")))) return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("Need 2 params to >="))))
} }
var a = EVAL(dynamic_env, params[0]); if !params[0].is_int() { return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("called >= with first not an int")))); }
if is_err(a) { return make_pair(null<KPEnv>(), a); } if !params[1].is_int() { return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("called >= with second not an int")))); }
var av = get_value(a) return make_pair(null<KPEnv>(), KPResult::Ok(kpBool(params[0].get_int() >= params[1].get_int())))
if !av.is_int() { return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("called >= with first not an int")))); }
var b = EVAL(dynamic_env, params[1]);
if is_err(b) { return make_pair(null<KPEnv>(), b); }
var bv = get_value(b)
if !bv.is_int() { return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("called >= with second not an int")))); }
return make_pair(null<KPEnv>(), KPResult::Ok(kpBool(av.get_int() >= bv.get_int())))
})); }));
env->set(str("and"), make_builtin_combiner(str("and"), 0, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { env->set(str("and"), make_builtin_combiner(str("and"), 0, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
@@ -1127,69 +1037,57 @@ fun main(argc: int, argv: **char): int {
return make_pair(null<KPEnv>(), KPResult::Ok(kpFalse())) return make_pair(null<KPEnv>(), KPResult::Ok(kpFalse()))
})); }));
env->set(str("pr-str"), make_builtin_combiner(str("pr-str"), 0, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { env->set(str("pr-str"), make_builtin_combiner(str("pr-str"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
return make_pair(null<KPEnv>(), str_wrapper(params, dynamic_env, " ", true)) return make_pair(null<KPEnv>(), str_wrapper(params, dynamic_env, " ", true))
})); }));
env->set(str("str"), make_builtin_combiner(str("str"), 0, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { env->set(str("str"), make_builtin_combiner(str("str"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
return make_pair(null<KPEnv>(), str_wrapper(params, dynamic_env, "", false)) return make_pair(null<KPEnv>(), str_wrapper(params, dynamic_env, "", false))
})); }));
env->set(str("prn"), make_builtin_combiner(str("prn"), 0, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { env->set(str("prn"), make_builtin_combiner(str("prn"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
var to_print = str_wrapper(params, dynamic_env, " ", true) var to_print = str_wrapper(params, dynamic_env, " ", true)
if is_err(to_print) { return make_pair(null<KPEnv>(), to_print); } if is_err(to_print) { return make_pair(null<KPEnv>(), to_print); }
println(get_value(to_print).get_string()) println(get_value(to_print).get_string())
return make_pair(null<KPEnv>(), KPResult::Ok(kpNil())) return make_pair(null<KPEnv>(), KPResult::Ok(kpNil()))
})); }));
env->set(str("println"), make_builtin_combiner(str("println"), 0, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { env->set(str("println"), make_builtin_combiner(str("println"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
var to_print = str_wrapper(params, dynamic_env, " ", false) var to_print = str_wrapper(params, dynamic_env, " ", false)
if is_err(to_print) { return make_pair(null<KPEnv>(), to_print); } if is_err(to_print) { return make_pair(null<KPEnv>(), to_print); }
println(get_value(to_print).get_string()) println(get_value(to_print).get_string())
return make_pair(null<KPEnv>(), KPResult::Ok(kpNil())) return make_pair(null<KPEnv>(), KPResult::Ok(kpNil()))
})); }));
env->set(str("meta"), make_builtin_combiner(str("meta"), 0, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { env->set(str("meta"), make_builtin_combiner(str("meta"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
if params.size != 1 { if params.size != 1 {
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("meta called with not one argument")))) return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("meta called with not one argument"))))
} else { } else {
var or = EVAL(dynamic_env, params[0]) if params[0].meta != null<KPValue>() {
if is_err(or) { return make_pair(null<KPEnv>(), or); } return make_pair(null<KPEnv>(), KPResult::Ok(*params[0].meta))
var o = get_value(or)
if o.meta != null<KPValue>() {
return make_pair(null<KPEnv>(), KPResult::Ok(*o.meta))
} else { } else {
return make_pair(null<KPEnv>(), KPResult::Ok(kpNil())) return make_pair(null<KPEnv>(), KPResult::Ok(kpNil()))
} }
} }
})); }));
env->set(str("with-meta"), make_builtin_combiner(str("with-meta"), 0, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { env->set(str("with-meta"), make_builtin_combiner(str("with-meta"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
if params.size != 2 { if params.size != 2 {
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("with-meta called with not two arguments")))) return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("with-meta called with not two arguments"))))
} else { } else {
var or = EVAL(dynamic_env, params[0])
if is_err(or) { return make_pair(null<KPEnv>(), or); }
var mr = EVAL(dynamic_env, params[1])
if is_err(mr) { return make_pair(null<KPEnv>(), mr); }
var new_meta = new<KPValue>() var new_meta = new<KPValue>()
new_meta->copy_construct(&get_value(mr)) new_meta->copy_construct(&params[1])
var new_value = get_value(or).deep_clone(); var new_value = params[0].deep_clone();
new_value.meta = new_meta new_value.meta = new_meta
return make_pair(null<KPEnv>(), KPResult::Ok(new_value)) return make_pair(null<KPEnv>(), KPResult::Ok(new_value))
} }
})); }));
// self-modifying grammar // self-modifying grammar
env->set(str("add_terminal"), make_builtin_combiner(str("add_terminal"), 0, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { env->set(str("add_terminal"), make_builtin_combiner(str("add_terminal"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
if params.size != 2 { if params.size != 2 {
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("add_terminal called with wrong number (not 2) params")))) return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("add_terminal called with wrong number (not 2) params"))))
} else { } else {
var namer = EVAL(dynamic_env, params[0]); if !params[0].is_string() {
if is_err(namer) { return make_pair(null<KPEnv>(), namer); } return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("add_terminal called with not string as first param"))))
var namev = get_value(namer)
if !namev.is_string() {
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("add_terminal called with wrong number (not 2) params"))))
} }
var funcr = EVAL(dynamic_env, params[1]); return make_pair(null<KPEnv>(), KPResult::Ok(kpInt(grammar.add_terminal(params[0].get_string(), params[1], fun(f: ref KPValue, input: ref str, l: int, r: int): KPResult {
if is_err(funcr) { return make_pair(null<KPEnv>(), funcr); }
return make_pair(null<KPEnv>(), KPResult::Ok(kpInt(grammar.add_terminal(namev.get_string(), get_value(funcr), fun(f: ref KPValue, input: ref str, l: int, r: int): KPResult {
return function_call(f, vec(kpString(input.slice(l,r))), kpNil()) return function_call(f, vec(kpString(input.slice(l,r))), kpNil())
})))) }))))
} }
@@ -1264,19 +1162,13 @@ fun main(argc: int, argv: **char): int {
} }
return KPResult::Ok(kpInt(grammar.add_to_or_create_nonterminal(nonterminal_str, int_rule, data, f))) return KPResult::Ok(kpInt(grammar.add_to_or_create_nonterminal(nonterminal_str, int_rule, data, f)))
} }
env->set(str("add_grammar_rule"), make_builtin_combiner(str("add_grammar_rule"), 0, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { env->set(str("add_grammar_rule"), make_builtin_combiner(str("add_grammar_rule"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
var params_evaled = vec<KPValue>() if params.size != 3 || !params[0].is_symbol() || !params[1].is_array() {
for (var i = 0; i < params.size; i++;) {
var ip = EVAL(dynamic_env, params[i])
if is_err(ip) { return make_pair(null<KPEnv>(), ip); }
params_evaled.add(get_value(ip))
}
if params_evaled.size != 3 || !params_evaled[0].is_symbol() || !params_evaled[1].is_array() {
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("add_grammar_rule called with wrong number or type of params_evaled")))) return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("add_grammar_rule called with wrong number or type of params_evaled"))))
} else { } else {
var nonterminal_str = params_evaled[0].get_symbol_text() var nonterminal_str = params[0].get_symbol_text()
var rule = params_evaled[1].get_array_rc().get() var rule = params[1].get_array_rc().get()
return make_pair(null<KPEnv>(), add_grammer_rule_helper(nonterminal_str, rule, params_evaled[2], fun(f: ref KPValue, x: ref vec<KPResult>): KPResult { return make_pair(null<KPEnv>(), add_grammer_rule_helper(nonterminal_str, rule, params[2], fun(f: ref KPValue, x: ref vec<KPResult>): KPResult {
var params = vec<KPValue>() var params = vec<KPValue>()
for (var i = 0; i < x.size; i++;) { for (var i = 0; i < x.size; i++;) {
if is_err(x[i]) { if is_err(x[i]) {
@@ -1295,20 +1187,14 @@ fun main(argc: int, argv: **char): int {
if params.size != 2 { if params.size != 2 {
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("eval-read-string with not a single string and env")))) return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("eval-read-string with not a single string and env"))))
} else { } else {
var ip = EVAL(dynamic_env, params[0]) if !params[0].is_string() {
if is_err(ip) { return make_pair(null<KPEnv>(), ip); }
var ipv = get_value(ip)
if !ipv.is_string() {
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("first param to eval-read-string s not a string")))) return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("first param to eval-read-string s not a string"))))
} }
var input = ipv.get_string() var input = params[0].get_string()
var ep = EVAL(dynamic_env, params[1]) if !params[1].is_env() {
if is_err(ep) { return make_pair(null<KPEnv>(), ep); }
var epv = get_value(ep)
if !epv.is_env() {
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("second param to eval-read-string is not a env")))) return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("second param to eval-read-string is not a env"))))
} }
var eval_env = epv.get_env() var eval_env = params[1].get_env()
var i = 0 var i = 0
var current_ret = KPResult::Ok(kpNil()) var current_ret = KPResult::Ok(kpNil())
if i < input.length() { if i < input.length() {
@@ -1353,35 +1239,29 @@ fun main(argc: int, argv: **char): int {
return make_pair(null<KPEnv>(), current_ret) return make_pair(null<KPEnv>(), current_ret)
} }
} }
env->set(str("eval-read-string"), make_builtin_combiner(str("eval-read-string"), 0, false, ERS)); env->set(str("eval-read-string"), make_builtin_combiner(str("eval-read-string"), 1, false, ERS));
env->set(str("read-string"), make_builtin_combiner(str("read-string"), 0, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { env->set(str("read-string"), make_builtin_combiner(str("read-string"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
if params.size != 1 { if params.size != 1 {
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("read-string with not a single string")))) return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("read-string with not a single string"))))
} else { } else {
var ip = EVAL(dynamic_env, params[0]) if !params[0].is_string() {
if is_err(ip) { return make_pair(null<KPEnv>(), ip); }
var ipv = get_value(ip)
if !ipv.is_string() {
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("read-string with not a single string")))) return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("read-string with not a single string"))))
} }
return make_pair(null<KPEnv>(), READ(grammar, ipv.get_string())) return make_pair(null<KPEnv>(), READ(grammar, params[0].get_string()))
} }
})); }));
env->set(str("slurp"), make_builtin_combiner(str("slurp"), 0, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { env->set(str("slurp"), make_builtin_combiner(str("slurp"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {
if params.size != 1 { if params.size != 1 {
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("slurp with not a single string")))) return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("slurp with not a single string"))))
} else { } else {
var ip = EVAL(dynamic_env, params[0]) if !params[0].is_string() {
if is_err(ip) { return make_pair(null<KPEnv>(), ip); }
var ipv = get_value(ip)
if !ipv.is_string() {
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("read-string with not a single string")))) return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("read-string with not a single string"))))
} }
if !file_exists(ipv.get_string()) { if !file_exists(params[0].get_string()) {
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("read-string with bad path ") + ipv.get_string()))) return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("read-string with bad path ") + params[0].get_string())))
} }
return make_pair(null<KPEnv>(), KPResult::Ok(kpString(read_file(ipv.get_string())))) return make_pair(null<KPEnv>(), KPResult::Ok(kpString(read_file(params[0].get_string()))))
} }
})); }));
env->set(str("wrap"), make_builtin_combiner(str("wrap"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> { env->set(str("wrap"), make_builtin_combiner(str("wrap"), 1, false, fun(params: vec<KPValue>, dynamic_env: *KPEnv): pair<*KPEnv, KPResult> {

View File

@@ -20,14 +20,16 @@
(lambda (o _ m _ _ _ p _ _) `(method-call ~o '~m ,p))) (lambda (o _ m _ _ _ p _ _) `(method-call ~o '~m ,p)))
; object creation ; object creation
(set! make_object (vau de (name members) (fun make_constructor (members methods)
(eval (print_through `(fun ~name ~members (eval `(lambda ~members
(with-meta [,members] (with-meta [,members]
[,(map_with_idx (lambda (i x) [array `'~x (lambda (o) (idx o i))]) members)]))) de))) [,(map_with_idx (lambda (i x) [array `'~x (lambda (o) (idx o i))]) members)
,(map (lambda (x) [array `'~(idx x 0) (idx x 1)]) methods)]))))
; object syntax ; object syntax
(add_grammar_rule 'form ["obj" 'WS 'atom "\\(" ['optional_WS 'atom] * 'optional_WS "\\)" 'optional_WS "{" "}"] (lambda (_ _ name _ members _ _ _ _ _) (add_grammar_rule 'form ["obj" 'WS 'atom "\\(" ['optional_WS 'atom] * 'optional_WS "\\)" 'optional_WS "{" 'optional_WS ['atom 'optional_WS 'form 'optional_WS] * "}"] (lambda (_ _ name _ members _ _ _ _ _ methods _)
`(make_object ~name ~(map (lambda (x) (idx x 1)) members)))) `(set! ~name (make_constructor [,(map (lambda (x) `'~(idx x 1)) members)]
[,(map (lambda (x) `['~(idx x 0) ~(idx x 2)]) methods)]))))
; Ok, let's create our object by hand for this example ; Ok, let's create our object by hand for this example
(set! actual_obj (with-meta [0] [ (set! actual_obj (with-meta [0] [
@@ -38,7 +40,20 @@
])) ]))
(println "asdf") (println "asdf")
(println (make_object Wooo ( a b c ))) (let (
MyConstructor (make_constructor '( a b c ) [ ['sum (lambda (o) (+ o.a o.b o.c))]
['add_a (lambda (o c) (+ o.a c))]])
my_object (MyConstructor 1 2 3)
)
(do
(println MyConstructor)
(println my_object)
(println my_object.a)
(println my_object.b)
(println my_object.c)
(println my_object.sum)
(println my_object.add_a(12))
))
(println "fdsa") (println "fdsa")
obj MyConstructor() {} obj MyConstructor() {}
@@ -50,7 +65,10 @@ obj MyConstructor() {}
(println '(obj MyConstructor2( mem1 mem2 ) {})) (println '(obj MyConstructor2( mem1 mem2 ) {}))
obj MyConstructor2( mem1 mem2 ) {} obj MyConstructor2( mem1 mem2 ) {
add (lambda (self & nums) (lapply + (concat [self.mem1 self.mem2] nums)))
sub (lambda (self & nums) (lapply - (concat [self.mem1 self.mem2] nums)))
}
(println "made") (println "made")
(println MyConstructor2) (println MyConstructor2)
(println (MyConstructor2 1 2)) (println (MyConstructor2 1 2))
@@ -58,6 +76,10 @@ obj MyConstructor2( mem1 mem2 ) {}
(println "it will be " (MyConstructor2 1337 266).mem1()) (println "it will be " (MyConstructor2 1337 266).mem1())
(println "it will be " (MyConstructor2 1337 266).mem2()) (println "it will be " (MyConstructor2 1337 266).mem2())
(println "it will be " (MyConstructor2 1337 777).mem2) (println "it will be " (MyConstructor2 1337 777).mem2)
(println "it will be " (MyConstructor2 1337 777).add)
(println "it will be " (MyConstructor2 1337 777).add(1))
(println "it will be " (MyConstructor2 1337 777).add(1 2))
(println "it will be " (MyConstructor2 1337 777).sub(1 2))
(println "it was") (println "it was")
(do (do