diff --git a/k_prime.krak b/k_prime.krak index 9654c3a..e44a0e4 100644 --- a/k_prime.krak +++ b/k_prime.krak @@ -1237,63 +1237,83 @@ fun main(argc: int, argv: **char): int { }))) } })); + var add_grammer_rule_helper: fun(str, vec, MalValue, fun(ref MalValue, ref vec): MalResult): MalResult = fun(nonterminal_str: str, rule: vec, data: MalValue, f: fun(ref MalValue, ref vec): MalResult): MalResult { + var int_rule = vec() + for (var i = 0; i < rule.size; i++;) { + if rule[i].is_int() { + int_rule.add(rule[i].get_int()) + } else if rule[i].is_symbol() { + var sub_nonterminal_idx = grammar.nonterminal_names.find(rule[i].get_symbol_text()) + if sub_nonterminal_idx == -1 { + return MalResult::Err(malString(str("Couldn't find nonterminal: ") + rule[i].get_symbol_text())) + } + var sub_nonterminal = -1*(sub_nonterminal_idx+1) + int_rule.add(sub_nonterminal) + } else if rule[i].is_string() { + int_rule.add(grammar.add_terminal(rule[i].get_string(), malNil(), fun(f: ref MalValue, input: ref str, l: int, r: int): MalResult { + return MalResult::Ok(malString(input.slice(l,r))) + })) + } else if rule[i].is_vector() { + // A sequence! + var sub_rule_names = nonterminal_str + "_seq_" + new_tmp() + var inner_rule = add_grammer_rule_helper(sub_rule_names, rule[i].get_vector_rc().get(), malNil(), fun(_: ref MalValue, seq: ref vec): MalResult { + var to_ret = vec() + for (var i = 0; i < seq.size; i++;) { + if is_err(seq[i]) { + return seq[i] + } + to_ret.add(get_value(seq[i])) + } + return MalResult::Ok(malVector(to_ret)) + }) + if is_err(inner_rule) { + return inner_rule + } + int_rule.add(get_value(inner_rule).get_int()) + } else { + match (rule[i].internal) { + MalValue_int::BuiltinFunction(f) { + if f.name == "+" || f.name == "*" { + if int_rule.size == 0 { + return MalResult::Err(malString(str("add_grammar_rule has + or * in first position, with nothing to repeat"))) + } + var current = int_rule.last() + var sub_rule_names = nonterminal_str + "_" + new_tmp() + var new = grammar.add_to_or_create_nonterminal(sub_rule_names + "_one_or_more", vec(current), malNil(), fun(f: ref MalValue, x: ref vec): MalResult { + if is_err(x[0]) { return x[0]; } + return MalResult::Ok(malVector(vec(get_value(x[0])))) + }) + grammar.add_to_nonterminal(new, vec(current, new), malNil(), fun(f: ref MalValue, x: ref vec): MalResult { + if is_err(x[0]) { return x[0]; } + if is_err(x[1]) { return x[1]; } + return MalResult::Ok(malVector(vec(get_value(x[0])) + get_value(x[1]).get_vector_rc().get())) + }) + if f.name == "*" { + new = grammar.add_to_or_create_nonterminal(sub_rule_names + "_zero_or_more", vec(new), malNil(), fun(f: ref MalValue, x: ref vec): MalResult { + if is_err(x[0]) { return x[0]; } + return MalResult::Ok(get_value(x[0])) + }) + grammar.add_to_nonterminal(new, vec(), malNil(), fun(f: ref MalValue, x: ref vec): MalResult { + return MalResult::Ok(malVector(vec())) + }) + } + int_rule.last() = new + continue + } + } + } + return MalResult::Err(malString(str("add_grammar_rule called with not symbol, int, or string in rule"))) + } + } + return MalResult::Ok(malInt(grammar.add_to_or_create_nonterminal(nonterminal_str, int_rule, data, f))) + } env->set(str("add_grammar_rule"), make_builtin_function(str("add_grammar_rule"), fun(params: vec): MalResult { if params.size != 3 || !params[0].is_symbol() || !params[1].is_vector() { return MalResult::Err(malString(str("add_grammar_rule called with wrong number or type of params"))) } else { var nonterminal_str = params[0].get_symbol_text() var rule = params[1].get_vector_rc().get() - var int_rule = vec() - for (var i = 0; i < rule.size; i++;) { - if rule[i].is_int() { - int_rule.add(rule[i].get_int()) - } else if rule[i].is_symbol() { - var sub_nonterminal_idx = grammar.nonterminal_names.find(rule[i].get_symbol_text()) - if sub_nonterminal_idx == -1 { - return MalResult::Err(malString(str("Couldn't find nonterminal: ") + rule[i].get_symbol_text())) - } - var sub_nonterminal = -1*(sub_nonterminal_idx+1) - int_rule.add(sub_nonterminal) - } else if rule[i].is_string() { - int_rule.add(grammar.add_terminal(rule[i].get_string(), malNil(), fun(f: ref MalValue, input: ref str, l: int, r: int): MalResult { - return MalResult::Ok(malString(input.slice(l,r))) - })) - } else { - match (rule[i].internal) { - MalValue_int::BuiltinFunction(f) { - if f.name == "+" || f.name == "*" { - if int_rule.size == 0 { - return MalResult::Err(malString(str("add_grammar_rule has + or * in first position, with nothing to repeat"))) - } - var current = int_rule.last() - var sub_rule_names = nonterminal_str + "_" + new_tmp() - var new = grammar.add_to_or_create_nonterminal(sub_rule_names + "_one_or_more", vec(current), malNil(), fun(f: ref MalValue, x: ref vec): MalResult { - if is_err(x[0]) { return x[0]; } - return MalResult::Ok(malVector(vec(get_value(x[0])))) - }) - grammar.add_to_nonterminal(new, vec(current, new), malNil(), fun(f: ref MalValue, x: ref vec): MalResult { - if is_err(x[0]) { return x[0]; } - if is_err(x[1]) { return x[1]; } - return MalResult::Ok(malVector(vec(get_value(x[0])) + get_value(x[1]).get_vector_rc().get())) - }) - if f.name == "*" { - new = grammar.add_to_or_create_nonterminal(sub_rule_names + "_zero_or_more", vec(new), malNil(), fun(f: ref MalValue, x: ref vec): MalResult { - if is_err(x[0]) { return x[0]; } - return MalResult::Ok(get_value(x[0])) - }) - grammar.add_to_nonterminal(new, vec(), malNil(), fun(f: ref MalValue, x: ref vec): MalResult { - return MalResult::Ok(malVector(vec())) - }) - } - int_rule.last() = new - continue - } - } - } - return MalResult::Err(malString(str("add_grammar_rule called with not symbol, int, or string in rule"))) - } - } - grammar.add_to_or_create_nonterminal(nonterminal_str, int_rule, params[2], fun(f: ref MalValue, x: ref vec): MalResult { + return add_grammer_rule_helper(nonterminal_str, rule, params[2], fun(f: ref MalValue, x: ref vec): MalResult { var params = vec() for (var i = 0; i < x.size; i++;) { if is_err(x[i]) { @@ -1303,7 +1323,6 @@ fun main(argc: int, argv: **char): int { } return function_call(f, params) }) - return MalResult::Ok(malNil()) } })); var ERS = fun(params: vec): MalResult { diff --git a/method.kp b/method.kp index 9b63c32..901f080 100644 --- a/method.kp +++ b/method.kp @@ -1,6 +1,4 @@ -(def! our_obj (with-meta [0] (fn* () (set-nth! our_obj 0 (+ 1 (nth our_obj 0)))))) - (def! get-value-helper (fn* (dict key idx) (if (>= idx (count dict)) nil (if (= key (nth dict idx)) (nth dict (+ idx 1)) (get-value-helper dict key (+ idx 2)))))) (def! get-value (fn* (dict key) (get-value-helper dict key 0))) (def! method-call (fn* (object method & arguments) (let* (method_fn (get-value (meta object) method)) @@ -9,53 +7,50 @@ (apply method_fn object arguments))))) ; method call syntax (add_grammar_rule 'form [ 'form "\\." 'atom 'optional_WS "\\(" 'optional_WS 'space_forms 'optional_WS "\\)" ] (fn* (o _ m _ _ _ p _ _) `(method-call ~o '~m ,p))) -(def! actual_obj (with-meta [0] [ - 'inc (fn* (o) (set-nth! o 0 (+ (nth o 0) 1))) - 'dec (fn* (o) (set-nth! o 0 (- (nth o 0) 1))) - 'set (fn* (o n) (set-nth! o 0 n)) - 'get (fn* (o) (nth o 0)) - ])) -(def! to_be_saved (with-meta [1] [2])) -(def! main (fn* () (let* ( a 7 - b [1] - c (with-meta b "yolo") ) - (do - (try* - ((fn* () (do - (println b) - (set-nth! b 0 2) - (println b) - (println c) - (println (meta c)) - (println "world") - (println to_be_saved) - (println (meta to_be_saved)) - (println "Here in main testing our_obj") - (println our_obj) - ((meta our_obj)) - (println our_obj) - ((meta our_obj)) - (println our_obj) - (println "actual_obj" actual_obj) - (method-call actual_obj 'inc) - (println "actual_obj" actual_obj) - (println "with get: " (method-call actual_obj 'get)) - (println "actual_obj" actual_obj) - (method-call actual_obj 'dec) - (method-call actual_obj 'dec) - (println "actual_obj" actual_obj) - (println "setting old style 654") - (method-call actual_obj 'set 654) - (println "actual_obj" actual_obj) - (println "Ok, doing with new method call syntax") - actual_obj.inc() - (println "actual_obj" actual_obj) - (println "setting new style 1337") - actual_obj.set(1337) - (println "actual_obj" actual_obj) - (println "with get " actual_obj.get()) - a))) - ))))) +; object syntax +(def! flatten (fn* (l) (let* + (flatten-helper (fn* (l a f) (if (> (count l) 0) + (f (rest l) (concat a (first l)) f) + a))) + (flatten-helper l [] flatten-helper)))) +(add_grammar_rule 'form [ "obj" 'optional_WS 'atom 'optional_WS "{" 'optional_WS 'form 'optional_WS [ 'atom 'optional_WS 'form 'optional_WS ] + "}" ] (fn* (_ _ name _ _ _ constructor _ methods _) + (let* (processed_methods (flatten (map (fn* (m) [`'~(nth m 0) (nth m 2)]) methods))) + `(def! ~name (fn* (& args) (with-meta (apply ~constructor args) [ ,processed_methods ] )))))) +obj my_constructor { + (fn* () [17]) + inc (fn* (o) (set-nth! o 0 (+ (nth o 0) 1))) + dec (fn* (o) (set-nth! o 0 (- (nth o 0) 1))) + set (fn* (o n) (set-nth! o 0 n)) + get (fn* (o) (nth o 0)) +} + +(println "pre construct") +(def! actual_obj (my_constructor)) +(println "constructed" actual_obj) + +(println "here" actual_obj) +(println "here" (meta actual_obj)) + +(def! main (fn* () (do + (println "actual_obj" actual_obj) + (method-call actual_obj 'inc) + (println "actual_obj" actual_obj) + (println "with get: " (method-call actual_obj 'get)) + (println "actual_obj" actual_obj) + (method-call actual_obj 'dec) + (method-call actual_obj 'dec) + (println "actual_obj" actual_obj) + (println "setting old style 654") + (method-call actual_obj 'set 654) + (println "actual_obj" actual_obj) + (println "Ok, doing with new method call syntax") + actual_obj.inc() + (println "actual_obj" actual_obj) + (println "setting new style 1337") + actual_obj.set(1337) + (println "actual_obj" actual_obj) + (println "with get " actual_obj.get()) + 0))) (do (println "interp-main") (main)