From 754ff412266c34c08fe9b0f15bade45576b7cc27 Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Sat, 28 Jan 2017 00:09:13 -0500 Subject: [PATCH] C_generator can call raw function pointers now --- kraken.krak | 6 +++++- stdlib/c_generator.krak | 32 ++++++++++++++------------------ stdlib/lexer.krak | 4 +++- stdlib/parser.krak | 13 ++++++++----- stdlib/regex.krak | 1 - 5 files changed, 30 insertions(+), 26 deletions(-) diff --git a/kraken.krak b/kraken.krak index 82c323d..0d868c6 100644 --- a/kraken.krak +++ b/kraken.krak @@ -1,5 +1,6 @@ import io:* import grammer:* +import lexer:* import parser:* import string:* import util:* @@ -17,6 +18,8 @@ import ctce_lower:* import c_line_control:* import node_counter:* import c_generator:* +import vector:* +import set:* fun main(argc: int, argv: **char):int { // delay construction until we either load it or copy construct it @@ -99,7 +102,8 @@ fun main(argc: int, argv: **char):int { println("done writing") } - var parse1.construct(&gram): parser + var lex = lexer(gram.terminals) + var parse1.construct(&gram, &lex): parser /*var parse2.construct(&gram): parser*/ /*var parse3.construct(&gram): parser*/ /*var parse4.construct(&gram): parser*/ diff --git a/stdlib/c_generator.krak b/stdlib/c_generator.krak index 8bcc853..fa02632 100644 --- a/stdlib/c_generator.krak +++ b/stdlib/c_generator.krak @@ -645,8 +645,9 @@ obj c_generator (Object) { ref_pre += "(*" ref_post += ")" } - if (!is_function(node->function_call.func) || node->function_call.func->function.closed_variables.size()) { + if (!func_type->is_raw && (!is_function(node->function_call.func) || node->function_call.func->function.closed_variables.size())) { // not function, so we must be an identifier or function call return or something + // and also is closure style, so need special call if (!dot_style_method_call) { // lambda if (pre_call == "" && (!func_return_type->is_void() || func_return_type->indirection)) { @@ -661,23 +662,18 @@ obj c_generator (Object) { call_string.post += name_temp.post func_name = name_temp.value // should not have return var because is void - if (pre_call == "") { - var func_type = get_ast_type(node->function_call.func) - call_string.pre += string("if (")+func_name+".data) ((" + type_to_c(func_type) + "_with_data) "+func_name+".func)("+func_name +".data" - if (call_string.value != "") - call_string.pre += string(",") + call_string.value - call_string.pre += ");\n" - call_string.pre += string("else ((") + type_to_c(func_type) + "_without_data) " + func_name+".func)(" + call_string.value + ");\n" - call_string.value = "" - } else { - var func_type = get_ast_type(node->function_call.func) - call_string.pre += string("if (")+func_name+".data) " + pre_call + " = ((" + type_to_c(func_type) + "_with_data) "+func_name+".func)("+func_name +".data" - if (call_string.value != "") - call_string.pre += string(",") + call_string.value - call_string.pre += ");\n" - call_string.pre += string("else ") + pre_call + " = ((" + type_to_c(func_type) + "_without_data) " + func_name+".func)(" + call_string.value + ");\n" - call_string.value = pre_call - } + var pre_call_plus = pre_call + if (pre_call_plus != "") + pre_call_plus += " = " + + var func_type = get_ast_type(node->function_call.func) + call_string.pre += string("if (")+func_name+".data) " + pre_call_plus + " ((" + type_to_c(func_type) + "_with_data) "+func_name+".func)("+func_name +".data" + if (call_string.value != "") + call_string.pre += string(",") + call_string.value + call_string.pre += ");\n" + call_string.pre += string("else ") + pre_call_plus + " ((" + type_to_c(func_type) + "_without_data) " + func_name+".func)(" + call_string.value + ");\n" + call_string.value = pre_call + call_string.value = ref_pre + call_string.value + ref_post return call_string } diff --git a/stdlib/lexer.krak b/stdlib/lexer.krak index 5662bd0..8a9284c 100644 --- a/stdlib/lexer.krak +++ b/stdlib/lexer.krak @@ -60,7 +60,9 @@ obj lexer (Object) { fun add_regex(newOne: *char) { regs.add(util::make_pair(string::string(newOne), regex::regex(newOne))) } - fun set_input(in: string::string) { + fun set_input(in: ref string::string) { + position = 0 + line_number = 1 input = in } fun next(): symbol::symbol { diff --git a/stdlib/parser.krak b/stdlib/parser.krak index 388bb61..acf468e 100644 --- a/stdlib/parser.krak +++ b/stdlib/parser.krak @@ -14,6 +14,7 @@ import io:* obj parser (Object) { var input: vector var gram: *grammer + var lex: *lexer var gss: gss var to_reduce: stack var to_shift: stack< pair<*tree, int> > @@ -21,9 +22,10 @@ obj parser (Object) { var packed_map: map<*tree, bool> var reduces_to_null_map: map, bool> - fun construct(grammerIn: *grammer): *parser { + fun construct(grammerIn: *grammer, lexIn: *lexer): *parser { input.construct() gram = grammerIn + lex = lexIn gss.construct() to_reduce.construct() to_shift.construct() @@ -32,12 +34,14 @@ obj parser (Object) { reduces_to_null_map.construct() return this } + // for maybe_construct for containers fun construct(): *parser { - return construct(null()) + return construct(null(), null()) } fun copy_construct(old: *parser) { input.copy_construct(&old->input) gram = old->gram + lex = old->lex gss.copy_construct(&old->gss) to_reduce.copy_construct(&old->to_reduce) to_shift.copy_construct(&old->to_shift) @@ -75,10 +79,9 @@ obj parser (Object) { return new>()->construct(null_symbol()) } - var lex = lexer(gram->terminals) - lex.set_input(inputStr) + lex->set_input(inputStr) var current_symbol.construct(): symbol - for (current_symbol = lex.next(); current_symbol != eof_symbol() && current_symbol != invalid_symbol(); current_symbol = lex.next();) { + for (current_symbol = lex->next(); current_symbol != eof_symbol() && current_symbol != invalid_symbol(); current_symbol = lex->next();) { if (current_symbol != eof_symbol() && current_symbol != invalid_symbol()) current_symbol.source = name input.addEnd(current_symbol) diff --git a/stdlib/regex.krak b/stdlib/regex.krak index c1deca9..7908a3c 100644 --- a/stdlib/regex.krak +++ b/stdlib/regex.krak @@ -234,7 +234,6 @@ obj regex (Object, Serializable) { return -1 return regexString.length(); } - /*var next = set::set(begin)*/ for (var i = 1; i < flagsA.size; i++;) flagsA[i] = false; flagsA[0] = true