From ce7d228358b998dfc018c5de8e10bf7e9266325f Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Sun, 29 Mar 2020 20:42:51 -0400 Subject: [PATCH] Use the new parser (now with reduction functions) for mal --- fungll.krak | 123 ++++++++++++++++++++---- k_prime.krak | 264 ++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 301 insertions(+), 86 deletions(-) diff --git a/fungll.krak b/fungll.krak index b9867b0..bf77e64 100644 --- a/fungll.krak +++ b/fungll.krak @@ -7,46 +7,57 @@ import str:* import regex:* // nonterminals are negative, terminals are positive -obj Grammer (Object) { +obj Grammer (Object) { var nonterminals: vec>> var nonterminal_names: vec + var nonterminal_funs: vec): T>> var terminals: vec + var terminal_funs: vec var start_symbol: int fun construct(): *Grammer { nonterminals.construct() nonterminal_names.construct() + nonterminal_funs.construct() terminals.construct() + terminal_funs.construct() start_symbol = 0 return this } fun copy_construct(old: *Grammer): void { nonterminals.copy_construct(&old->nonterminals) nonterminal_names.copy_construct(&old->nonterminal_names) + nonterminal_funs.copy_construct(&old->nonterminal_funs) terminals.copy_construct(&old->terminals) + terminal_funs.copy_construct(&old->terminal_funs) start_symbol = old->start_symbol } fun destruct(): void { nonterminals.destruct() nonterminal_names.destruct() + nonterminal_funs.destruct() terminals.destruct() + terminal_funs.destruct() } fun operator=(other:ref Grammer):void { destruct() copy_construct(&other) } - fun add_new_nonterminal(name: *char, rule: ref vec): int { - return add_new_nonterminal(str(name), rule) + fun add_new_nonterminal(name: *char, rule: ref vec, f: fun(ref vec): T): int { + return add_new_nonterminal(str(name), rule, f) } - fun add_new_nonterminal(name: ref str, rule: ref vec): int { + fun add_new_nonterminal(name: ref str, rule: ref vec, f: fun(ref vec): T): int { nonterminals.add(vec(rule)) nonterminal_names.add(name) + nonterminal_funs.add(vec(f)) return -1*nonterminals.size } - fun add_to_nonterminal(nonterminal: int, rule: ref vec) { + fun add_to_nonterminal(nonterminal: int, rule: ref vec, f: fun(ref vec): T) { nonterminals[(-1*nonterminal)-1].add(rule) + nonterminal_funs[(-1*nonterminal)-1].add(f) } - fun add_terminal(c: *char): int { + fun add_terminal(c: *char, f: fun(ref str,int,int): T): int { terminals.add(regex(c)) + terminal_funs.add(f) return terminals.size } fun get_nonterminal_rules(nonterminal: int): ref vec> { @@ -69,6 +80,9 @@ obj Grammer (Object) { } var erminal = nonterminals[(-1*it.nonterminal)-1][it.rule_idx][i] rule_str += to_string(erminal) + if i < nonterminals[(-1*it.nonterminal)-1][it.rule_idx].size-1 { + rule_str += " " + } } if it.idx_into_rule == nonterminals[(-1*it.nonterminal)-1][it.rule_idx].size { rule_str += "*" @@ -82,6 +96,60 @@ obj Grammer (Object) { return terminals[erminal-1].regexString } } + fun eval_BSR(input: ref str, BSR: ref set): T { + var top = -1 + for (var i = 0; i < BSR.data.size; i++;) { + if BSR.data[i].nonterminal == start_symbol && BSR.data[i].idx_into_rule == nonterminals[(-1*BSR.data[i].nonterminal)-1][BSR.data[i].rule_idx].size && BSR.data[i].left == 0 && BSR.data[i].right == input.length() { + top = i + break + } + } + if top == -1 { + error("Could not find top") + } + return eval_BSR(input, BSR, top) + } + fun eval_BSR(input: ref str, BSR: ref set, c: int): T { + var bs = BSR.data[c] + var nonterminal = (-1*bs.nonterminal)-1 + if bs.idx_into_rule != nonterminals[nonterminal][bs.rule_idx].size { + error("Evaluating BSR from not the end!") + } + var params = vec() + for (var i = bs.idx_into_rule-1; i >= 0; i--;) { + var erminal = nonterminals[nonterminal][bs.rule_idx][i] + if is_terminal(erminal) { + var right_value = terminal_funs[erminal-1](input, bs.pivot, bs.right) + params.add(right_value) + } else { + /*var right = find_comp(erminal, bs.pivot, bs.right)*/ + var right = -1 + var sub_nonterminal_idx = (-1*erminal)-1 + for (var j = 0; j < BSR.data.size; j++;) { + if BSR.data[j].nonterminal == erminal && BSR.data[j].idx_into_rule == nonterminals[sub_nonterminal_idx][BSR.data[j].rule_idx].size && BSR.data[j].left == bs.pivot && BSR.data[j].right == bs.right { + right = j + break + } + } + var right_value = eval_BSR(input, BSR, right) + params.add(right_value) + } + // get the new left bs + if i != 0 { + /*var new_bs_idx = find_mid(bs.nonterminal, bs.rule_idx, i, bs.left, bs.pivot)*/ + var new_bs_idx = -1 + for (var j = 0; j < BSR.data.size; j++;) { + if BSR.data[j].nonterminal == bs.nonterminal && BSR.data[j].rule_idx == bs.rule_idx && BSR.data[j].idx_into_rule == i && BSR.data[j].left == bs.left && BSR.data[j].right == bs.pivot { + new_bs_idx = j + break + } + } + bs = BSR.data[new_bs_idx] + } + } + var to_ret = nonterminal_funs[nonterminal][bs.rule_idx](params.reverse()) + return to_ret + } } obj Pending (Object) { var nonterminal: int @@ -197,7 +265,7 @@ 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 return to_ret } -fun fungll(grammer: ref Grammer, input: ref str): set { +fun fungll(grammer: ref Grammer, input: ref str): set { var R = descend(grammer, grammer.start_symbol, 0) var U = set() var G = map, set>() @@ -211,10 +279,10 @@ fun fungll(grammer: ref Grammer, input: ref str): set { var Gp = it.second var Pp = it.third - var U_with_d = U.union(set(d)); - var nextR = R.union(Rp) - U_with_d + U.add(d) + var nextR = R.union(Rp) - U R = nextR - U = U_with_d + for (var i = 0; i < Gp.keys.size; i++;) { if G.contains_key(Gp.keys[i]) { G[Gp.keys[i]].add(Gp.values[i]) @@ -233,13 +301,13 @@ fun fungll(grammer: ref Grammer, input: ref str): set { } return Y } -fun descend(grammer: ref Grammer, symbol: int, l: int): set { +fun descend(grammer: ref Grammer, symbol: int, l: int): set { var to_ret = set() for (var rhs = 0; rhs < grammer.get_nonterminal_rules(symbol).size; rhs++;) to_ret.add(descriptor(symbol, rhs, 0, l, l)) return to_ret } -fun process(grammer: ref Grammer, input: ref str, descript: Descriptor, G: ref map, set>, P: ref map, set>): triple, set>, map, set>, map, set>> { +fun process(grammer: ref Grammer, input: ref str, descript: Descriptor, G: ref map, set>, P: ref map, set>): triple, set>, map, set>, map, set>> { // if at end / end is emptystr if descript.idx_into_rule == grammer.get_nonterminal_rules(descript.nonterminal)[descript.rule_idx].size { return process_e(grammer, descript, G, P) @@ -247,7 +315,7 @@ fun process(grammer: ref Grammer, input: ref str, descript: Descriptor, G: ref m return process_symbol(grammer, input, descript, G, P) } } -fun process_e(grammer: ref Grammer, descript: Descriptor, G: ref map, set>, P: ref map, set>): triple, set>, map, set>, map, set>> { +fun process_e(grammer: ref Grammer, descript: Descriptor, G: ref map, set>, P: ref map, set>): triple, set>, map, set>, map, set>> { var nonterminal: int var rule_idx: int var left: int @@ -264,7 +332,7 @@ fun process_e(grammer: ref Grammer, descript: Descriptor, G: ref map, set>(), map(make_pair(X,l), set(k))) } -fun process_symbol(grammer: ref Grammer, input: ref str, descript: Descriptor, G: ref map, set>, P: ref map, set>): triple, set>, map, set>, map, set>> { +fun process_symbol(grammer: ref Grammer, input: ref str, descript: Descriptor, G: ref map, set>, P: ref map, set>): triple, set>, map, set>, map, set>> { var s = grammer.get_nonterminal_rules(descript.nonterminal)[descript.rule_idx][descript.idx_into_rule] var k = descript.pivot var R = P.get_with_default(make_pair(s,k), set()) @@ -277,7 +345,7 @@ fun process_symbol(grammer: ref Grammer, input: ref str, descript: Descriptor, G return make_triple(skip(k,pending(descript.nonterminal, descript.rule_idx, descript.idx_into_rule+1, descript.left), R), Gp, map, set>()) } } -fun matc(grammer: ref Grammer, input: ref str, descript: Descriptor): pair, set> { +fun matc(grammer: ref Grammer, input: ref str, descript: Descriptor): pair, set> { /*println("trying to match " + grammer.to_string(grammer.get_nonterminal_rules(descript.nonterminal)[descript.rule_idx][descript.idx_into_rule]))*/ var match_length = grammer.match_terminal(grammer.get_nonterminal_rules(descript.nonterminal)[descript.rule_idx][descript.idx_into_rule], input, descript.pivot) if match_length > 0 { @@ -303,18 +371,31 @@ fun nmatch(k:int, K: ref set, R: ref set): pair, s return make_pair(Rp,Y) } /*fun main(argc: int, argv: **char): int {*/ - /*var grammer.construct(): Grammer*/ - /*var one = grammer.add_terminal("12")*/ - /*var E = grammer.add_new_nonterminal("E", vec())*/ - /*grammer.add_to_nonterminal(E, vec(one))*/ - /*grammer.add_to_nonterminal(E, vec(E,E,E))*/ + /*var grammer.construct(): Grammer*/ + /*var Number = grammer.add_new_nonterminal("Number", vec(grammer.add_terminal("[0-9]+", fun(input: ref str, l: int, r: int): int { return string_to_num(input.slice(l,r)); })), fun(i: ref vec): int { return i[0]; })*/ + + /*var mult = grammer.add_terminal("\\*", fun(input: ref str, l: int, r: int): int { return 1; })*/ + /*var Factor = grammer.add_new_nonterminal("Factor", vec(Number), fun(i: ref vec): int { return i[0]; })*/ + /*grammer.add_to_nonterminal(Factor, vec(Factor, mult, Number), fun(i: ref vec): int { return i[0]*i[2]; })*/ + + /*var add = grammer.add_terminal("\\+", fun(input: ref str, l: int, r: int): int { return 1; })*/ + /*var Term = grammer.add_new_nonterminal("Term", vec(Factor), fun(i: ref vec): int { return i[0]; })*/ + /*grammer.add_to_nonterminal(Term, vec(Term, add, Factor), fun(i: ref vec): int { return i[0]+i[2]; })*/ + + /*grammer.set_start_symbol(Term)*/ + + /*var input = str("1+23*44")*/ + /*var BSR = fungll(grammer, input)*/ + - /*var BSR = fungll(grammer, str("1212"))*/ /*println(str("length of BSR is: ") + BSR.size())*/ /*for (var i = 0; i < BSR.data.size; i++;) {*/ /*var BS = BSR.data[i]*/ /*println(str() + i + ": " + grammer.to_string(BSR.data[i]))*/ /*}*/ + /*var res = grammer.eval_BSR(input, BSR)*/ + /*println(str("result of grammer.eval_BSR(fungll(grammer, ") + input + ")) = " + res)*/ + /*return 0*/ /*}*/ diff --git a/k_prime.krak b/k_prime.krak index 7dc7971..13d1817 100644 --- a/k_prime.krak +++ b/k_prime.krak @@ -7,50 +7,6 @@ import map:* import fungll:* -fun make_grammer(): Grammer { - var grammer.construct(): Grammer - - var WS = grammer.add_new_nonterminal("WS", vec(grammer.add_terminal("( |,| | -)+"))) - var optional_WS = grammer.add_new_nonterminal("optional_WS", vec()) - grammer.add_to_nonterminal(optional_WS, vec(WS)) - - var atom = grammer.add_new_nonterminal("atom", vec(grammer.add_terminal("-?[0-9]+"))) - grammer.add_to_nonterminal(atom, vec(grammer.add_terminal("true"))) - grammer.add_to_nonterminal(atom, vec(grammer.add_terminal("false"))) - grammer.add_to_nonterminal(atom, vec(grammer.add_terminal("nil"))) - grammer.add_to_nonterminal(atom, vec(grammer.add_terminal("\"([#-[]| |[]-~]|(\\\\)|(\\n)|(\\t)|(\\\*)|(\\0)| -|[ -!]|(\\\"))*\""))) //" - grammer.add_to_nonterminal(atom, vec(grammer.add_terminal("([a-z]|[A-Z]|_|[0-9]|\\*|\\?|\\+|-|!|=|&|'|<|>)*"))) - grammer.add_to_nonterminal(atom, vec(grammer.add_terminal(":([a-z]|[A-Z]|_)([a-z]|[A-Z]|_|[0-9])*"))) - - var form = grammer.add_new_nonterminal("form", vec(atom)) - var space_forms = grammer.add_new_nonterminal("space_forms", vec(form)) - grammer.add_to_nonterminal(space_forms, vec(form, WS, space_forms)) - - grammer.add_to_nonterminal(form, vec(grammer.add_terminal("\\("), - space_forms, - grammer.add_terminal("\\)"))) - grammer.add_to_nonterminal(form, vec(grammer.add_terminal("\\["), - space_forms, - grammer.add_terminal("]"))) - - var doubled_space_forms = grammer.add_new_nonterminal("doubled_space_forms", vec(form, WS, form)) - grammer.add_to_nonterminal(doubled_space_forms, vec(form, WS, form, WS, doubled_space_forms)) - grammer.add_to_nonterminal(form, vec(grammer.add_terminal("{"), - doubled_space_forms, - grammer.add_terminal("}"))) - grammer.add_to_nonterminal(form, vec(grammer.add_terminal("@"), form)) - grammer.add_to_nonterminal(form, vec(grammer.add_terminal("'"), form)) - grammer.add_to_nonterminal(form, vec(grammer.add_terminal("`"), form)) - grammer.add_to_nonterminal(form, vec(grammer.add_terminal("~"), form)) - grammer.add_to_nonterminal(form, vec(grammer.add_terminal("~@"), form)) - - grammer.set_start_symbol(form) - - return grammer -} - fun tokenize(s: str): vec { var to_ret = vec() for (var i = 0; i < s.length(); i++;) { @@ -268,16 +224,27 @@ fun read_atom(tokens: *vec, i: *int): MalResult { return MalResult::Ok(MalValue::Symbol(token)) } } -fun read_str(s: str): MalResult { +fun read_str(grammer: ref Grammer, s: str): MalResult { var tokens = tokenize(s) - var grammer = make_grammer() + + var normal_to_ret = MalResult::Ok(MalValue::Nil()) + var new_to_ret = MalResult::Ok(MalValue::Nil()) + + var BSR = fungll(grammer, s) var success = false for (var i = 0; i < BSR.data.size; i++;) { var BS = BSR.data[i] - success = success || (BSR.data[i].right == s.length()) + success = success || (BSR.data[i].nonterminal == grammer.start_symbol && BSR.data[i].right == s.length()) } if success { + /*println("parsed: " + s)*/ + /*println(str("length of BSR is: ") + BSR.size())*/ + /*for (var i = 0; i < BSR.data.size; i++;) {*/ + /*var BS = BSR.data[i]*/ + /*println(str() + i + ": " + grammer.to_string(BSR.data[i]))*/ + /*}*/ + new_to_ret = grammer.eval_BSR(s, BSR) } else { println("trying to parse: " + s) println(str("length of BSR is: ") + BSR.size()) @@ -290,10 +257,31 @@ fun read_str(s: str): MalResult { } // comment, print nothing if tokens.size == 0 { - return MalResult::Err(MalValue::String(str(""))) + normal_to_ret = MalResult::Err(MalValue::String(str(""))) + } else { + var i = 0 + normal_to_ret = read_form(&tokens, &i) } - var i = 0 - return read_form(&tokens, &i) + + /*var readably = false*/ + var readably = true + if is_err(normal_to_ret) { + println("normal Was error") + println(pr_str(get_err(normal_to_ret), readably)) + } else { + println("normal Was value") + println(pr_str(get_value(normal_to_ret), readably)) + } + if is_err(new_to_ret) { + println("new Was error") + println(pr_str(get_err(new_to_ret), readably)) + } else { + println("new Was value") + println(pr_str(get_value(new_to_ret), readably)) + } + + /*return normal_to_ret*/ + return new_to_ret } adt MalValue { Nil, @@ -890,8 +878,8 @@ fun pr_str(v: MalValue, print_readably: bool): str { error("can't print") } -fun READ(s: str): MalResult { - return read_str(s) +fun READ(grammer: ref Grammer, s: str): MalResult { + return read_str(grammer, s) } fun eval_ast(env: *Env, ast: MalValue): MalResult { @@ -1137,8 +1125,8 @@ fun PRINT(v: MalValue): str { return pr_str(v, true) } -fun rep(env: *Env, a: str): str { - var read = READ(a) +fun rep(grammer: ref Grammer, env: *Env, a: str): str { + var read = READ(grammer, a) if is_err(read) { return PRINT(get_err(read)) } else { @@ -1162,6 +1150,152 @@ fun print_wrapper(params: vec, sep: *char, print_readably: bool): str } fun main(argc: int, argv: **char): int { + + var grammer.construct(): Grammer + + var ret_nil_term: fun(ref str, int, int): MalResult = fun(input: ref str, l: int, r: int): MalResult { return MalResult::Ok(MalValue::Nil()); } + var ret_nil_sym: fun(ref vec): MalResult = fun(x: ref vec): MalResult { return MalResult::Ok(MalValue::Nil()); } + var ret_0_sym: fun(ref vec): MalResult = fun(x: ref vec): MalResult { return x[0]; } + + var WS = grammer.add_new_nonterminal("WS", vec(grammer.add_terminal("( |,| | +|(;[ -~]* +))+", ret_nil_term)), ret_nil_sym) + var optional_WS = grammer.add_new_nonterminal("optional_WS", vec(), ret_nil_sym) + grammer.add_to_nonterminal(optional_WS, vec(WS), ret_nil_sym) + + var atom = grammer.add_new_nonterminal("atom", vec(grammer.add_terminal("-?[0-9]+", fun(input: ref str, l: int, r: int): MalResult { return MalResult::Ok(MalValue::Int(string_to_num(input.slice(l,r)))); })), ret_0_sym) + grammer.add_to_nonterminal(atom, vec(grammer.add_terminal("true", fun(input: ref str, l: int, r: int): MalResult { return MalResult::Ok(MalValue::True()); })), ret_0_sym) + grammer.add_to_nonterminal(atom, vec(grammer.add_terminal("false", fun(input: ref str, l: int, r: int): MalResult { return MalResult::Ok(MalValue::False()); })), ret_0_sym) + grammer.add_to_nonterminal(atom, vec(grammer.add_terminal("nil", fun(input: ref str, l: int, r: int): MalResult { return MalResult::Ok(MalValue::Nil()); })), ret_0_sym) + grammer.add_to_nonterminal(atom, vec(grammer.add_terminal("\"([#-[]| |[]-~]|(\\\\)|(\\n)|(\\t)|(\\\*)|(\\0)| +|[ -!]|(\\\\\"))*\"", fun(input: ref str, l: int, r: int): MalResult { + var to_ret = str() + for (var i = l+1; i < r-1; i++;) { + if input[i] == '\\' { + if input[i+1] == 'n' { + to_ret += '\n' + } else if input[i+1] == '\\' || input[i+1] == '"' { + to_ret += input[i+1] + } else { + return MalResult::Err(MalValue::String(str("bad string escape"))) + } + // skip + i++ + } else { + to_ret += input[i] + } + } + /*return MalResult::Ok(MalValue::String(input.slice(l+1,r-1)));*/ + return MalResult::Ok(MalValue::String(to_ret)); + })), fun(x: ref vec): MalResult { return x[0]; }) //" + /*grammer.add_to_nonterminal(atom, vec(grammer.add_terminal("([a-z]|[A-Z]|_|[0-9]|\\*|\\?|\\+|-|!|=|&|'|<|>)*", fun(input: ref str, l: int, r: int): MalResult { return MalResult::Ok(MalValue::Symbol(input.slice(l,r))); })), ret_0_sym)*/ + grammer.add_to_nonterminal(atom, vec(grammer.add_terminal("([a-z]|[A-Z]|_|\\*|\\?|\\+|-|!|=|&|<|>)([a-z]|[A-Z]|_|[0-9]|\\*|\\?|\\+|-|!|=|&|<|>)*", fun(input: ref str, l: int, r: int): MalResult { return MalResult::Ok(MalValue::Symbol(input.slice(l,r))); })), ret_0_sym) + grammer.add_to_nonterminal(atom, vec(grammer.add_terminal(":([a-z]|[A-Z]|_)([a-z]|[A-Z]|_|[0-9])*", fun(input: ref str, l: int, r: int): MalResult { return MalResult::Ok(MalValue::Keyword(input.slice(l,r))); })), ret_0_sym) + + var form = grammer.add_new_nonterminal("form", vec(atom), ret_0_sym) + var space_forms = grammer.add_new_nonterminal("space_forms", vec(form), fun(x: ref vec): MalResult { + if is_err(x[0]) { + return x[0] + } + return MalResult::Ok(MalValue::List(vec(get_value(x[0])))) + }) + grammer.add_to_nonterminal(space_forms, vec(form, WS, space_forms), fun(x: ref vec): MalResult { + if is_err(x[0]) { + return x[0] + } + if is_err(x[1]) { + return x[1] + } + return MalResult::Ok(MalValue::List(vec(get_value(x[0])) + get_list(get_value(x[2])))) + }) + + grammer.add_to_nonterminal(form, vec(grammer.add_terminal("\\(", ret_nil_term), + optional_WS, + space_forms, + optional_WS, + grammer.add_terminal("\\)", ret_nil_term)), fun(x: ref vec): MalResult { return x[2]; }) + grammer.add_to_nonterminal(form, vec(grammer.add_terminal("\\[", ret_nil_term), + optional_WS, + space_forms, + optional_WS, + grammer.add_terminal("]", ret_nil_term)), fun(x: ref vec): MalResult { + if is_err(x[2]) { + return x[2] + } + return MalResult::Ok(MalValue::Vector(get_list(get_value(x[2])))) + }) + + var doubled_space_forms = grammer.add_new_nonterminal("doubled_space_forms", vec(form, WS, form), fun(x: ref vec): MalResult { + if is_err(x[0]) { + return x[0] + } + if is_err(x[2]) { + return x[2] + } + return MalResult::Ok(MalValue::List(vec(get_value(x[0]), get_value(x[2])))) + }) + grammer.add_to_nonterminal(doubled_space_forms, vec(form, WS, form, WS, doubled_space_forms), fun(x: ref vec): MalResult { + if is_err(x[0]) { + return x[0] + } + if is_err(x[2]) { + return x[2] + } + if is_err(x[4]) { + return x[4] + } + return MalResult::Ok(MalValue::List(vec(get_value(x[0]), get_value(x[2])) + get_list(get_value(x[4])))) + }) + grammer.add_to_nonterminal(form, vec(grammer.add_terminal("{", ret_nil_term), + optional_WS, + doubled_space_forms, + optional_WS, + grammer.add_terminal("}", ret_nil_term)), fun(x: ref vec): MalResult { + if is_err(x[2]) { + return x[2] + } + + var to_ret = map() + var values = get_list(get_value(x[2])) + for (var i = 0; i < values.size; i+=2;) { + to_ret.set(values[i], values[i+1]) + } + return MalResult::Ok(MalValue::Map(to_ret)) + }) + grammer.add_to_nonterminal(form, vec(grammer.add_terminal("@", ret_nil_term), form), fun(x: ref vec): MalResult { + if is_err(x[1]) { + return x[1] + } + return MalResult::Ok(MalValue::List(vec(MalValue::Symbol(str("deref")), get_value(x[1])))) + }) + grammer.add_to_nonterminal(form, vec(grammer.add_terminal("'", ret_nil_term), form), fun(x: ref vec): MalResult { + if is_err(x[1]) { + return x[1] + } + return MalResult::Ok(MalValue::List(vec(MalValue::Symbol(str("deref")), get_value(x[1])))) + }) + grammer.add_to_nonterminal(form, vec(grammer.add_terminal("`", ret_nil_term), form), fun(x: ref vec): MalResult { + if is_err(x[1]) { + return x[1] + } + return MalResult::Ok(MalValue::List(vec(MalValue::Symbol(str("deref")), get_value(x[1])))) + }) + grammer.add_to_nonterminal(form, vec(grammer.add_terminal("~", ret_nil_term), form), fun(x: ref vec): MalResult { + if is_err(x[1]) { + return x[1] + } + return MalResult::Ok(MalValue::List(vec(MalValue::Symbol(str("deref")), get_value(x[1])))) + }) + grammer.add_to_nonterminal(form, vec(grammer.add_terminal("~@", ret_nil_term),form), fun(x: ref vec): MalResult { + if is_err(x[1]) { + return x[1] + } + return MalResult::Ok(MalValue::List(vec(MalValue::Symbol(str("deref")), get_value(x[1])))) + }) + + grammer.set_start_symbol(form) + + var env = new()->construct() env->set(str("+"), make_builtin_function(fun(params: vec): MalResult { var to_ret = 0 @@ -1307,7 +1441,7 @@ fun main(argc: int, argv: **char): int { if params.size != 1 || !is_string(params[0]) { return MalResult::Err(MalValue::String(str("read-string with not a single string"))) } else { - return read_str(get_string(params[0])) + return read_str(grammer, get_string(params[0])) } })); env->set(str("slurp"), make_builtin_function(fun(params: vec): MalResult { @@ -1615,28 +1749,28 @@ fun main(argc: int, argv: **char): int { env->set(str("conj"), make_builtin_function(fun(params: vec): MalResult { return MalResult::Err(MalValue::String(str("not implemented"))) })); - rep(env, str("(def! not (fn* (a) (if a false true)))")) - rep(env, str("(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \" \\nnil)\")))))")) - rep(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(env, str("(def! nil? (fn* (a) (= nil a)))")) - rep(env, str("(def! true? (fn* (a) (= true a)))")) - rep(env, str("(def! false? (fn* (a) (= false a)))")) - rep(env, str("(def! *host-language* \"kraken\")")) + 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("(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! true? (fn* (a) (= true a)))")) + rep(grammer, env, str("(def! false? (fn* (a) (= false a)))")) + rep(grammer, env, str("(def! *host-language* \"kraken\")")) var params = vec() if argc > 1 { for (var i = 2; i < argc; i++;) { params.add(MalValue::String(str(argv[i]))) } env->set(str("*ARGV*"), MalValue::List(params)) - rep(env, str("(load-file \"") + argv[1] + "\")") + rep(grammer, env, str("(load-file \"") + argv[1] + "\")") } else { env->set(str("*ARGV*"), MalValue::List(params)) - rep(env, str("(println (str \"Mal [\" *host-language* \"]\"))")) + rep(grammer, env, str("(println (str \"Mal [\" *host-language* \"]\"))")) while (true) { var line = get_line(str("user> "), 1024) if (line == "***EOF***") break - println(rep(env, line)) + println(rep(grammer, env, line)) } } }