Fix hardcoded reader macros, add eval-read-string, fix niceness of whitespace between forms in repl and files. Next should be to redo the parser api to be way nicer from within kraken'
This commit is contained in:
25
fungll.krak
25
fungll.krak
@@ -51,8 +51,13 @@ obj Grammer<T,K> (Object) {
|
|||||||
nonterminal_funs.add(vec(make_pair(d,f)))
|
nonterminal_funs.add(vec(make_pair(d,f)))
|
||||||
return -1*nonterminals.size
|
return -1*nonterminals.size
|
||||||
}
|
}
|
||||||
fun add_to_nonterminal(nonterminal: ref str, rule: ref vec<int>, d: K, f: fun(ref K,ref vec<T>): T) {
|
fun add_to_or_create_nonterminal(name: ref str, rule: ref vec<int>, d: K, f: fun(ref K,ref vec<T>): T) {
|
||||||
add_to_nonterminal(-1*(nonterminal_names.find(nonterminal)+1), rule, d, f)
|
var idx = nonterminal_names.find(name)
|
||||||
|
if idx >= 0 {
|
||||||
|
add_to_nonterminal(-1*(idx+1), rule, d, f)
|
||||||
|
} else {
|
||||||
|
add_new_nonterminal(name, rule, d, f)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fun add_to_nonterminal(nonterminal: int, rule: ref vec<int>, d: K, f: fun(ref K,ref vec<T>): T) {
|
fun add_to_nonterminal(nonterminal: int, rule: ref vec<int>, d: K, f: fun(ref K,ref vec<T>): T) {
|
||||||
nonterminals[(-1*nonterminal)-1].add(rule)
|
nonterminals[(-1*nonterminal)-1].add(rule)
|
||||||
@@ -111,6 +116,12 @@ obj Grammer<T,K> (Object) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if top == -1 {
|
if top == -1 {
|
||||||
|
println("Could not find top for input:")
|
||||||
|
println(input)
|
||||||
|
println(str("of length ") + input.length())
|
||||||
|
for (var i = 0; i < BSR.data.size; i++;) {
|
||||||
|
println(str() + i + ": " + to_string(BSR.data[i]))
|
||||||
|
}
|
||||||
error("Could not find top")
|
error("Could not find top")
|
||||||
}
|
}
|
||||||
return eval_BSR(input, BSR, top)
|
return eval_BSR(input, BSR, top)
|
||||||
@@ -271,8 +282,14 @@ fun bs(nonterminal: int, rule_idx: int, idx_into_rule: int, left: int, pivot: in
|
|||||||
var to_ret.construct(nonterminal, rule_idx, idx_into_rule, left, pivot, right): BS
|
var to_ret.construct(nonterminal, rule_idx, idx_into_rule, left, pivot, right): BS
|
||||||
return to_ret
|
return to_ret
|
||||||
}
|
}
|
||||||
fun fungll<T,K>(grammer: ref Grammer<T,K>, input: ref str): set<BS> {
|
/*fun fungll<T,K>(grammer: ref Grammer<T,K>, start_symbol: *char, input: ref str): set<BS> {*/
|
||||||
var R = descend(grammer, grammer.start_symbol, 0)
|
/*return fungll(grammer, str(start_symbol), input)*/
|
||||||
|
/*}*/
|
||||||
|
/*fun fungll<T,K>(grammer: ref Grammer<T,K>, start_symbol: str, input: ref str): set<BS> {*/
|
||||||
|
/*return fungll(grammer, -1*(grammer.nonterminal_funs.find(start_symbol)+1), input)*/
|
||||||
|
/*}*/
|
||||||
|
fun fungll<T,K>(grammer: ref Grammer<T,K>, start_symbol: int, input: ref str): set<BS> {
|
||||||
|
var R = descend(grammer, start_symbol, 0)
|
||||||
var U = set<Descriptor>()
|
var U = set<Descriptor>()
|
||||||
var G = map<pair<int, int>, set<Pending>>()
|
var G = map<pair<int, int>, set<Pending>>()
|
||||||
var P = map<pair<int,int>, set<int>>()
|
var P = map<pair<int,int>, set<int>>()
|
||||||
|
|||||||
95
k_prime.krak
95
k_prime.krak
@@ -39,24 +39,25 @@ fun get_map(m: MalValue): map<MalValue, MalValue> {
|
|||||||
}
|
}
|
||||||
error("can't get_map not a map")
|
error("can't get_map not a map")
|
||||||
}
|
}
|
||||||
fun read_str(grammer: ref Grammer<MalResult,MalValue>, s: str): MalResult {
|
fun read_str(grammer: ref Grammer<MalResult,MalValue>, s: str): pair<int, MalResult> {
|
||||||
var BSR = fungll(grammer, s)
|
var BSR = fungll(grammer, grammer.start_symbol, s)
|
||||||
var success = false
|
var longest = -1
|
||||||
for (var i = 0; i < BSR.data.size; i++;) {
|
for (var i = 0; i < BSR.data.size; i++;) {
|
||||||
var BS = BSR.data[i]
|
if BSR.data[i].nonterminal == grammer.start_symbol && BSR.data[i].left == 0 {
|
||||||
success = success || (BSR.data[i].nonterminal == grammer.start_symbol && BSR.data[i].right == s.length())
|
longest = BSR.data[i].right
|
||||||
}
|
}
|
||||||
if success {
|
}
|
||||||
return grammer.eval_BSR(s, BSR)
|
if longest >= 0 {
|
||||||
|
return make_pair(longest, grammer.eval_BSR(s.slice(0, longest), BSR))
|
||||||
} else {
|
} else {
|
||||||
println("trying to parse: " + s)
|
println("trying to parse: " + s)
|
||||||
println(str("length of BSR is: ") + BSR.size())
|
println(str("length of BSR is: ") + BSR.size())
|
||||||
for (var i = 0; i < BSR.data.size; i++;) {
|
for (var i = 0; i < BSR.data.size; i++;) {
|
||||||
var BS = BSR.data[i]
|
|
||||||
println(str() + i + ": " + grammer.to_string(BSR.data[i]))
|
println(str() + i + ": " + grammer.to_string(BSR.data[i]))
|
||||||
}
|
}
|
||||||
println("Parse failed")
|
println("Parse failed")
|
||||||
error("faileD")
|
/*error("faileD")*/
|
||||||
|
return make_pair(-1, MalResult::Err(MalValue::String(str("failed to parse"))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
adt MalValue {
|
adt MalValue {
|
||||||
@@ -655,7 +656,16 @@ fun pr_str(v: MalValue, print_readably: bool): str {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun READ(grammer: ref Grammer<MalResult, MalValue>, s: str): MalResult {
|
fun READ(grammer: ref Grammer<MalResult, MalValue>, s: str): MalResult {
|
||||||
return read_str(grammer, s)
|
var to_ret = read_str(grammer, s)
|
||||||
|
if to_ret.first != s.length() {
|
||||||
|
if is_err(to_ret.second) {
|
||||||
|
return to_ret.second
|
||||||
|
} else {
|
||||||
|
println("parsed to var: " + pr_str(get_value(to_ret.second), true))
|
||||||
|
}
|
||||||
|
error("parsed some, but not all")
|
||||||
|
}
|
||||||
|
return to_ret.second
|
||||||
}
|
}
|
||||||
|
|
||||||
fun eval_ast(env: *Env, ast: MalValue): MalResult {
|
fun eval_ast(env: *Env, ast: MalValue): MalResult {
|
||||||
@@ -1055,25 +1065,25 @@ fun main(argc: int, argv: **char): int {
|
|||||||
if is_err(x[1]) {
|
if is_err(x[1]) {
|
||||||
return x[1]
|
return x[1]
|
||||||
}
|
}
|
||||||
return MalResult::Ok(MalValue::List(vec(MalValue::Symbol(str("deref")), get_value(x[1]))))
|
return MalResult::Ok(MalValue::List(vec(MalValue::Symbol(str("quote")), get_value(x[1]))))
|
||||||
})
|
})
|
||||||
grammer.add_to_nonterminal(form, vec(grammer.add_terminal("`", MalValue::Nil(), ret_nil_term), form), MalValue::Nil(), fun(_: ref MalValue, x: ref vec<MalResult>): MalResult {
|
grammer.add_to_nonterminal(form, vec(grammer.add_terminal("`", MalValue::Nil(), ret_nil_term), form), MalValue::Nil(), fun(_: ref MalValue, x: ref vec<MalResult>): MalResult {
|
||||||
if is_err(x[1]) {
|
if is_err(x[1]) {
|
||||||
return x[1]
|
return x[1]
|
||||||
}
|
}
|
||||||
return MalResult::Ok(MalValue::List(vec(MalValue::Symbol(str("deref")), get_value(x[1]))))
|
return MalResult::Ok(MalValue::List(vec(MalValue::Symbol(str("quasiquote")), get_value(x[1]))))
|
||||||
})
|
})
|
||||||
grammer.add_to_nonterminal(form, vec(grammer.add_terminal("~", MalValue::Nil(), ret_nil_term), form), MalValue::Nil(), fun(_: ref MalValue, x: ref vec<MalResult>): MalResult {
|
grammer.add_to_nonterminal(form, vec(grammer.add_terminal("~", MalValue::Nil(), ret_nil_term), form), MalValue::Nil(), fun(_: ref MalValue, x: ref vec<MalResult>): MalResult {
|
||||||
if is_err(x[1]) {
|
if is_err(x[1]) {
|
||||||
return x[1]
|
return x[1]
|
||||||
}
|
}
|
||||||
return MalResult::Ok(MalValue::List(vec(MalValue::Symbol(str("deref")), get_value(x[1]))))
|
return MalResult::Ok(MalValue::List(vec(MalValue::Symbol(str("unquote")), get_value(x[1]))))
|
||||||
})
|
})
|
||||||
grammer.add_to_nonterminal(form, vec(grammer.add_terminal("~@", MalValue::Nil(), ret_nil_term),form), MalValue::Nil(), fun(_: ref MalValue, x: ref vec<MalResult>): MalResult {
|
grammer.add_to_nonterminal(form, vec(grammer.add_terminal("~@", MalValue::Nil(), ret_nil_term),form), MalValue::Nil(), fun(_: ref MalValue, x: ref vec<MalResult>): MalResult {
|
||||||
if is_err(x[1]) {
|
if is_err(x[1]) {
|
||||||
return x[1]
|
return x[1]
|
||||||
}
|
}
|
||||||
return MalResult::Ok(MalValue::List(vec(MalValue::Symbol(str("deref")), get_value(x[1]))))
|
return MalResult::Ok(MalValue::List(vec(MalValue::Symbol(str("splice-unquote")), get_value(x[1]))))
|
||||||
})
|
})
|
||||||
|
|
||||||
grammer.set_start_symbol(form)
|
grammer.set_start_symbol(form)
|
||||||
@@ -1224,7 +1234,7 @@ fun main(argc: int, argv: **char): int {
|
|||||||
if params.size != 1 || !is_string(params[0]) {
|
if params.size != 1 || !is_string(params[0]) {
|
||||||
return MalResult::Err(MalValue::String(str("read-string with not a single string")))
|
return MalResult::Err(MalValue::String(str("read-string with not a single string")))
|
||||||
} else {
|
} else {
|
||||||
return read_str(grammer, get_string(params[0]))
|
return READ(grammer, get_string(params[0]))
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
env->set(str("slurp"), make_builtin_function(fun(params: vec<MalValue>): MalResult {
|
env->set(str("slurp"), make_builtin_function(fun(params: vec<MalValue>): MalResult {
|
||||||
@@ -1567,28 +1577,73 @@ fun main(argc: int, argv: **char): int {
|
|||||||
return MalResult::Ok(MalValue::Int(grammer.add_new_nonterminal(get_string(params[0]), int_rule, params[2], call_for_sym)))
|
return MalResult::Ok(MalValue::Int(grammer.add_new_nonterminal(get_string(params[0]), int_rule, params[2], call_for_sym)))
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
env->set(str("add_to_nonterminal"), make_builtin_function(fun(params: vec<MalValue>): MalResult {
|
env->set(str("add_to_or_create_nonterminal"), make_builtin_function(fun(params: vec<MalValue>): MalResult {
|
||||||
if params.size != 3 || (!is_int(params[0]) && !is_string(params[0])) || !is_list_or_vec(params[1]) {
|
if params.size != 3 || (!is_int(params[0]) && !is_string(params[0])) || !is_list_or_vec(params[1]) {
|
||||||
return MalResult::Err(MalValue::String(str("add_to_nonterminal called with wrong number or type of params")))
|
return MalResult::Err(MalValue::String(str("add_to_or_create_nonterminal called with wrong number or type of params")))
|
||||||
} else {
|
} else {
|
||||||
var rule = get_list(params[1])
|
var rule = get_list(params[1])
|
||||||
var int_rule = vec<int>()
|
var int_rule = vec<int>()
|
||||||
for (var i = 0; i < rule.size; i++;) {
|
for (var i = 0; i < rule.size; i++;) {
|
||||||
if !is_int(rule[i]) {
|
if !is_int(rule[i]) {
|
||||||
return MalResult::Err(MalValue::String(str("add_to_nonterminal called with bad rule")))
|
return MalResult::Err(MalValue::String(str("add_to_or_create_nonterminal called with bad rule")))
|
||||||
}
|
}
|
||||||
int_rule.add(get_int(rule[i]))
|
int_rule.add(get_int(rule[i]))
|
||||||
}
|
}
|
||||||
if is_int(params[0]) {
|
if is_int(params[0]) {
|
||||||
grammer.add_to_nonterminal(get_int(params[0]), int_rule, params[2], call_for_sym)
|
grammer.add_to_nonterminal(get_int(params[0]), int_rule, params[2], call_for_sym)
|
||||||
} else {
|
} else {
|
||||||
grammer.add_to_nonterminal(get_string(params[0]), int_rule, params[2], call_for_sym)
|
grammer.add_to_or_create_nonterminal(get_string(params[0]), int_rule, params[2], call_for_sym)
|
||||||
}
|
}
|
||||||
return MalResult::Ok(MalValue::Nil())
|
return MalResult::Ok(MalValue::Nil())
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
env->set(str("get_nonterminal"), make_builtin_function(fun(params: vec<MalValue>): MalResult {
|
||||||
|
if params.size != 1 || !is_string(params[0]) {
|
||||||
|
return MalResult::Err(MalValue::String(str("get_nonterminal called with wrong number or type of params")))
|
||||||
|
} else {
|
||||||
|
var nonterminal = grammer.nonterminal_names.find(get_string(params[0]))
|
||||||
|
if nonterminal >= 0 {
|
||||||
|
return MalResult::Ok(MalValue::Int(-1*(nonterminal+1)))
|
||||||
|
}
|
||||||
|
return MalResult::Err(MalValue::String(str("Couldn't find nonterminal: ") + get_string(params[0])))
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
env->set(str("eval-read-string"), make_builtin_function(fun(params: vec<MalValue>): MalResult {
|
||||||
|
if params.size != 1 || !is_string(params[0]) {
|
||||||
|
return MalResult::Err(MalValue::String(str("eval-read-string called with wrong number or type of params")))
|
||||||
|
} else {
|
||||||
|
var input = get_string(params[0])
|
||||||
|
var i = 0
|
||||||
|
var current_ret = MalResult::Ok(MalValue::Nil())
|
||||||
|
/*println(str("eval-read-string length is ") + input.length())*/
|
||||||
|
while i < input.length() {
|
||||||
|
var r = read_str(grammer, input.slice(i, -1))
|
||||||
|
i += r.first
|
||||||
|
/*println(str("new i is ") + i)*/
|
||||||
|
if is_err(r.second) {
|
||||||
|
return r.second
|
||||||
|
}
|
||||||
|
current_ret = EVAL(env, get_value(r.second))
|
||||||
|
/*println("cutting through WS")*/
|
||||||
|
var BSR = fungll(grammer, optional_WS, input.slice(i, -1))
|
||||||
|
var longest = -1
|
||||||
|
for (var j = 0; j < BSR.data.size; j++;) {
|
||||||
|
if BSR.data[j].nonterminal == optional_WS && BSR.data[j].left == 0 {
|
||||||
|
longest = BSR.data[j].right
|
||||||
|
}
|
||||||
|
/*println(str() + j + ": " + grammer.to_string(BSR.data[j]))*/
|
||||||
|
}
|
||||||
|
if longest > 0 {
|
||||||
|
i += longest
|
||||||
|
}
|
||||||
|
/*println(str("new i post WS is ") + i)*/
|
||||||
|
}
|
||||||
|
return current_ret
|
||||||
|
}
|
||||||
|
}));
|
||||||
rep(grammer, env, str("(def! not (fn* (a) (if a false true)))"))
|
rep(grammer, env, str("(def! not (fn* (a) (if a false true)))"))
|
||||||
rep(grammer, env, str("(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \" \\nnil)\")))))"))
|
/*rep(grammer, env, str("(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \" \\nnil)\")))))"))*/
|
||||||
|
rep(grammer, env, str("(def! load-file (fn* (f) (eval-read-string (slurp f))))"))
|
||||||
rep(grammer, env, str("(defmacro! cond (fn* (& xs) (if (> (count xs) 0) (list 'if (first xs) (if (> (count xs) 1) (nth xs 1) (throw \"odd number of forms to cond\")) (cons 'cond (rest (rest xs)))))))"))
|
rep(grammer, env, str("(defmacro! cond (fn* (& xs) (if (> (count xs) 0) (list 'if (first xs) (if (> (count xs) 1) (nth xs 1) (throw \"odd number of forms to cond\")) (cons 'cond (rest (rest xs)))))))"))
|
||||||
rep(grammer, env, str("(def! nil? (fn* (a) (= nil a)))"))
|
rep(grammer, env, str("(def! nil? (fn* (a) (= nil a)))"))
|
||||||
rep(grammer, env, str("(def! true? (fn* (a) (= true a)))"))
|
rep(grammer, env, str("(def! true? (fn* (a) (= true a)))"))
|
||||||
|
|||||||
Reference in New Issue
Block a user