diff --git a/include/Parser.h b/include/Parser.h index 2a4eba5..a0d9543 100644 --- a/include/Parser.h +++ b/include/Parser.h @@ -28,7 +28,7 @@ class Parser { virtual void loadGrammer(std::string grammerInputString); virtual void createStateSet(); virtual std::string stateSetToString(); - virtual NodeTree* parseInput(std::string inputString, std::string filename) = 0; // filename for error reporting + virtual NodeTree* parseInput(std::string inputString, std::string filename, bool highlight_errors) = 0; // filename for error reporting virtual std::string grammerToString(); virtual std::string grammerToDOT(); diff --git a/include/RNGLRParser.h b/include/RNGLRParser.h index 1dad38e..5c8c756 100644 --- a/include/RNGLRParser.h +++ b/include/RNGLRParser.h @@ -17,7 +17,7 @@ class RNGLRParser: public Parser { public: RNGLRParser(); ~RNGLRParser(); - NodeTree* parseInput(std::string inputString, std::string filename); // filename for error reporting + NodeTree* parseInput(std::string inputString, std::string filename, bool highlight_errors); // filename for error reporting void printReconstructedFrontier(int frontier); private: diff --git a/src/Importer.cpp b/src/Importer.cpp index 13ccda4..ecfd3b5 100644 --- a/src/Importer.cpp +++ b/src/Importer.cpp @@ -197,7 +197,7 @@ NodeTree* Importer::parseAndTrim(std::string fileName) { programInFile.close(); //std::cout << programInputFileString << std::endl; - NodeTree* parseTree = parser->parseInput(programInputFileString, inputFileName); + NodeTree* parseTree = parser->parseInput(programInputFileString, inputFileName, !only_parse); if (parseTree) { //std::cout << parseTree->DOTGraphString() << std::endl; @@ -208,6 +208,8 @@ NodeTree* Importer::parseAndTrim(std::string fileName) { throw "unexceptablblllll"; return NULL; } + if (only_parse) + return parseTree; //outFile.close(); //Remove Transformations diff --git a/src/RNGLRParser.cpp b/src/RNGLRParser.cpp index 51a7f3d..006856a 100644 --- a/src/RNGLRParser.cpp +++ b/src/RNGLRParser.cpp @@ -33,7 +33,7 @@ void RNGLRParser::printReconstructedFrontier(int frontier) { } } -NodeTree* RNGLRParser::parseInput(std::string inputString, std::string filename) { +NodeTree* RNGLRParser::parseInput(std::string inputString, std::string filename, bool highlight_errors) { input.clear(); gss.clear(); while(!toReduce.empty()) toReduce.pop(); @@ -114,29 +114,36 @@ NodeTree* RNGLRParser::parseInput(std::string inputString, std::string f for (int i = 0; i < input.size(); i++) { // std::cout << "Checking if frontier " << i << " is empty" << std::endl; - if (gss.frontierIsEmpty(i)) { - //std::cout << "Frontier " << i << " is empty." << std::endl; - //std::cerr << "Parsing failed on " << input[i].toString() << std::endl; - //std::cerr << "Problem is on line: " << findLine(i) << std::endl; -// std::cerr << filename << ":" << findLine(i) << std::endl; + if (gss.frontierIsEmpty(i)) { + //std::cout << "Frontier " << i << " is empty." << std::endl; + //std::cerr << "Parsing failed on " << input[i].toString() << std::endl; + //std::cerr << "Problem is on line: " << findLine(i) << std::endl; + // std::cerr << filename << ":" << findLine(i) << std::endl; errord = true; - std::cout << BOLDMAGENTA << "parse error" << std::endl; - - std::cout << BOLDWHITE << "Error at: " << BOLDBLUE << filename << ":" << findLine(i) << std::endl; - - std::ifstream infile(filename); - std::string line; - int linecount = 0; - while(std::getline(infile,line)) - { - if(linecount == findLine(i) - 1) - std::cout << BOLDRED << line << std::endl; - linecount++; + if (highlight_errors) + std::cout << BOLDBLUE; + std::cout << filename << ":" << findLine(i) << std::endl; + if (highlight_errors) + std::cout << BOLDMAGENTA; + std::cout << ": parse error" << std::endl; + + std::ifstream infile(filename); + std::string line; + int linecount = 0; + while(std::getline(infile,line)) + { + if(linecount == findLine(i) - 1) { + if (highlight_errors) + std::cout << BOLDRED; + std::cout << line << std::endl; } + linecount++; + } + if (highlight_errors) std::cout << RESET << std::endl; break; - } + } //Clear the vector of SPPF nodes created every step SPPFStepNodes.clear(); diff --git a/stdlib/ast_transformation.krak b/stdlib/ast_transformation.krak index ff519e3..5f13c4c 100644 --- a/stdlib/ast_transformation.krak +++ b/stdlib/ast_transformation.krak @@ -204,8 +204,13 @@ obj ast_transformation (Object) { while (!fourth_pass_worklist.empty()) { var partially_inst_type_def = fourth_pass_worklist.pop() partially_inst_type_def->type_def.methods.for_each(fun(method: *ast_node) { - // this is the wrong map - method->function.body_statement = transform_statement(get_node("statement", ast_to_syntax[method]), method, map()) + var template = partially_inst_type_def->type_def.scope[string("~enclosing_scope")][0] + var template_types = template->template.template_types + var real_types = template->template.instantiated_map.reverse_get(partially_inst_type_def) + var replacements = map() + for (var i = 0; i < template_types.size; i++;) + replacements.set(template_types[i], real_types[i].clone()) + method->function.body_statement = transform_statement(get_node("statement", ast_to_syntax[method]), method, replacements) }) } } diff --git a/stdlib/c_generator.krak b/stdlib/c_generator.krak index 878f3ca..7dae2b4 100644 --- a/stdlib/c_generator.krak +++ b/stdlib/c_generator.krak @@ -118,7 +118,6 @@ obj c_generator (Object) { var defer_stack = stack>>(make_pair(false, stack<*ast_node>())) var decorated_name = generate_function(child).one_string() - // also add in name decoration backing.parameters.for_each(fun(parameter: *ast_node) { if (parameter_types != "") { parameter_types += ", "; parameters += ", ";} parameter_types += type_to_c(parameter->identifier.type) @@ -183,8 +182,10 @@ obj c_generator (Object) { }) }) type_poset.get_sorted().for_each(fun(vert: *ast_node) { - plain_typedefs += string("typedef struct ") + vert->type_def.name + "_dummy " + vert->type_def.name + ";\n" - structs += string("struct ") + vert->type_def.name + "_dummy {\n" + /*var base_name = vert->type_def.name*/ + var base_name = get_name(vert) + plain_typedefs += string("typedef struct ") + base_name + "_dummy " + base_name + ";\n" + structs += string("struct ") + base_name + "_dummy {\n" vert->type_def.variables.for_each(fun(variable_declaration: *ast_node) structs += generate_declaration_statement(variable_declaration, null(), null>>>(), true).one_string() + ";\n";) structs += "};\n" // generate the methods @@ -317,9 +318,7 @@ obj c_generator (Object) { } // this generates the function as a value, not the actual function fun generate_function(node: *ast_node): code_triple { - var str = code_triple(node->function.name) - node->function.parameters.for_each(fun(param: *ast_node) str += string("_") + type_decoration(param->identifier.type);) - return str + return code_triple(get_name(node)) } fun generate_function_call(node: *ast_node, enclosing_object: *ast_node): code_triple { var func_name = string() @@ -461,7 +460,7 @@ obj c_generator (Object) { base_type::floating() return string("float") + indirection base_type::double_precision() return string("double") + indirection base_type::object() { - return type->type_def->type_def.name + indirection + return get_name(type->type_def) + indirection } base_type::function() { var temp = indirection + string("function: (") @@ -471,6 +470,28 @@ obj c_generator (Object) { } return string("impossible type") + indirection } + fun get_name(node: *ast_node): string { + match (*node) { + ast_node::type_def(backing) { + var upper = backing.scope[string("~enclosing_scope")][0] + var result = backing.name + if (is_template(upper)) + upper->template.instantiated_map.reverse_get(node).for_each(fun(t: ref type) result += string("_") + type_decoration(&t);) + return result + } + ast_node::function(backing) { + // be careful, operators like . come through this + var upper = backing.scope.get_with_default(string("~enclosing_scope"), vector(null()))[0] + var str = string() + if (upper && is_type_def(upper)) + str += get_name(upper) + str += node->function.name + node->function.parameters.for_each(fun(param: *ast_node) str += string("_") + type_decoration(param->identifier.type);) + return str + } + } + return string("impossible name") + } } diff --git a/stdlib/map.krak b/stdlib/map.krak index 1d6e1b4..798b76d 100644 --- a/stdlib/map.krak +++ b/stdlib/map.krak @@ -74,6 +74,20 @@ obj map (Object, Serializable) { } return values.get(key_loc) } + fun get_with_default(key: T, default_val: ref U): ref U { + if (contains_key(key)) + return get(key) + return default_val + } + fun reverse_get(value: U): ref T { + /*return values.get(keys.find(key))*/ + var value_loc = values.find(value) + if (value_loc == -1) { + io::println("trying to access nonexistant value-key!") + while (true) {} + } + return keys.get(value_loc) + } fun remove(key: T) { var idx = keys.find(key) if (idx < 0) { diff --git a/stdlib/type.krak b/stdlib/type.krak index 5931c48..a424b2f 100644 --- a/stdlib/type.krak +++ b/stdlib/type.krak @@ -150,6 +150,7 @@ obj type (Object) { } return 0 } + fun clone(): *type return clone_with_indirection(indirection); fun clone_with_increased_indirection(): *type return clone_with_indirection(indirection+1); fun clone_with_increased_indirection(more: int): *type return clone_with_indirection(indirection+more); fun clone_with_decreased_indirection(): *type return clone_with_indirection(indirection-1); diff --git a/tests/test_obj_create_scope.expected_results b/tests/test_obj_create_scope.expected_results new file mode 100644 index 0000000..7f8f011 --- /dev/null +++ b/tests/test_obj_create_scope.expected_results @@ -0,0 +1 @@ +7 diff --git a/tests/test_obj_create_scope.krak b/tests/test_obj_create_scope.krak new file mode 100644 index 0000000..b20b3b8 --- /dev/null +++ b/tests/test_obj_create_scope.krak @@ -0,0 +1,23 @@ +import simple_print:* + +obj ConTest { + var a: int + fun construct(a: int): *ConTest { + ConTest::a = a + return this + } +} + +fun main(): int { + var b.construct(7): ConTest + println(b.a) + return 0 +} + + + + + + + + diff --git a/tests/to_parse.krak b/tests/to_parse.krak index b0bccd5..5d649df 100644 --- a/tests/to_parse.krak +++ b/tests/to_parse.krak @@ -56,11 +56,21 @@ fun some_other_function(in: bool): float { */ obj SimpleContainer { var data: T + fun print_data() { + var indirection: T + indirection = data + println(indirection) + } + fun construct(dataIn: T) data = dataIn } fun main(): int { var it: SimpleContainer<*char> it.data = "Wooo object template" println(it.data) + it.data = "Wooo object template methods" + it.print_data() + var it2.construct(3): SimpleContainer + it2.print_data() /*println(other_id("Wooo function template inference"))*/ /*var a = id(7)*/ /*println(a)*/