Use the new parser (now with reduction functions) for mal

This commit is contained in:
Nathan Braswell
2020-03-29 20:42:51 -04:00
parent a9bb011bd9
commit ce7d228358
2 changed files with 301 additions and 86 deletions

View File

@@ -7,46 +7,57 @@ import str:*
import regex:*
// nonterminals are negative, terminals are positive
obj Grammer (Object) {
obj Grammer<T> (Object) {
var nonterminals: vec<vec<vec<int>>>
var nonterminal_names: vec<str>
var nonterminal_funs: vec<vec<fun(ref vec<T>): T>>
var terminals: vec<regex>
var terminal_funs: vec<fun(ref str,int,int): T>
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>): int {
return add_new_nonterminal(str(name), rule)
fun add_new_nonterminal(name: *char, rule: ref vec<int>, f: fun(ref vec<T>): T): int {
return add_new_nonterminal(str(name), rule, f)
}
fun add_new_nonterminal(name: ref str, rule: ref vec<int>): int {
fun add_new_nonterminal(name: ref str, rule: ref vec<int>, f: fun(ref vec<T>): 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<int>) {
fun add_to_nonterminal(nonterminal: int, rule: ref vec<int>, f: fun(ref vec<T>): 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<vec<int>> {
@@ -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<BS>): 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<BS>, 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<T>()
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<BS> {
fun fungll<T>(grammer: ref Grammer<T>, input: ref str): set<BS> {
var R = descend(grammer, grammer.start_symbol, 0)
var U = set<Descriptor>()
var G = map<pair<int, int>, set<Pending>>()
@@ -211,10 +279,10 @@ fun fungll(grammer: ref Grammer, input: ref str): set<BS> {
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<BS> {
}
return Y
}
fun descend(grammer: ref Grammer, symbol: int, l: int): set<Descriptor> {
fun descend<T>(grammer: ref Grammer<T>, symbol: int, l: int): set<Descriptor> {
var to_ret = set<Descriptor>()
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<pair<int, int>, set<Pending>>, P: ref map<pair<int,int>, set<int>>): triple<pair<set<Descriptor>, set<BS>>, map<pair<int, int>, set<Pending>>, map<pair<int,int>, set<int>>> {
fun process<T>(grammer: ref Grammer<T>, input: ref str, descript: Descriptor, G: ref map<pair<int, int>, set<Pending>>, P: ref map<pair<int,int>, set<int>>): triple<pair<set<Descriptor>, set<BS>>, map<pair<int, int>, set<Pending>>, map<pair<int,int>, set<int>>> {
// 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<pair<int, int>, set<Pending>>, P: ref map<pair<int,int>, set<int>>): triple<pair<set<Descriptor>, set<BS>>, map<pair<int, int>, set<Pending>>, map<pair<int,int>, set<int>>> {
fun process_e<T>(grammer: ref Grammer<T>, descript: Descriptor, G: ref map<pair<int, int>, set<Pending>>, P: ref map<pair<int,int>, set<int>>): triple<pair<set<Descriptor>, set<BS>>, map<pair<int, int>, set<Pending>>, map<pair<int,int>, set<int>>> {
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<pair<int, i
}
return make_triple(make_pair(R,Y), map<pair<int, int>, set<Pending>>(), map(make_pair(X,l), set(k)))
}
fun process_symbol(grammer: ref Grammer, input: ref str, descript: Descriptor, G: ref map<pair<int, int>, set<Pending>>, P: ref map<pair<int,int>, set<int>>): triple<pair<set<Descriptor>, set<BS>>, map<pair<int, int>, set<Pending>>, map<pair<int,int>, set<int>>> {
fun process_symbol<T>(grammer: ref Grammer<T>, input: ref str, descript: Descriptor, G: ref map<pair<int, int>, set<Pending>>, P: ref map<pair<int,int>, set<int>>): triple<pair<set<Descriptor>, set<BS>>, map<pair<int, int>, set<Pending>>, map<pair<int,int>, set<int>>> {
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<int>())
@@ -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<pair<int,int>, set<int>>())
}
}
fun matc(grammer: ref Grammer, input: ref str, descript: Descriptor): pair<set<Descriptor>, set<BS>> {
fun matc<T>(grammer: ref Grammer<T>, input: ref str, descript: Descriptor): pair<set<Descriptor>, set<BS>> {
/*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<Pending>, R: ref set<int>): pair<set<Descriptor>, 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<int>())*/
/*grammer.add_to_nonterminal(E, vec(one))*/
/*grammer.add_to_nonterminal(E, vec(E,E,E))*/
/*var grammer.construct(): Grammer<int>*/
/*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<int>(input.slice(l,r)); })), fun(i: ref vec<int>): 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>): int { return i[0]; })*/
/*grammer.add_to_nonterminal(Factor, vec(Factor, mult, Number), fun(i: ref vec<int>): 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>): int { return i[0]; })*/
/*grammer.add_to_nonterminal(Term, vec(Term, add, Factor), fun(i: ref vec<int>): 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*/
/*}*/

View File

@@ -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<int>())
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<str> {
var to_ret = vec<str>()
for (var i = 0; i < s.length(); i++;) {
@@ -268,16 +224,27 @@ fun read_atom(tokens: *vec<str>, i: *int): MalResult {
return MalResult::Ok(MalValue::Symbol(token))
}
}
fun read_str(s: str): MalResult {
fun read_str(grammer: ref Grammer<MalResult>, 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<MalResult>, 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<MalResult>, 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<MalValue>, sep: *char, print_readably: bool): str
}
fun main(argc: int, argv: **char): int {
var grammer.construct(): Grammer<MalResult>
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>): MalResult = fun(x: ref vec<MalResult>): MalResult { return MalResult::Ok(MalValue::Nil()); }
var ret_0_sym: fun(ref vec<MalResult>): MalResult = fun(x: ref vec<MalResult>): 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<int>(), 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<int>(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>): 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>): 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>): 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>): 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>): 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>): 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>): 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>): MalResult {
if is_err(x[2]) {
return x[2]
}
var to_ret = map<MalValue,MalValue>()
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>): 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>): 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>): 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>): 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>): 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<Env>()->construct()
env->set(str("+"), make_builtin_function(fun(params: vec<MalValue>): 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<MalValue>): MalResult {
@@ -1615,28 +1749,28 @@ fun main(argc: int, argv: **char): int {
env->set(str("conj"), make_builtin_function(fun(params: vec<MalValue>): 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<MalValue>()
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))
}
}
}