From 935cc6f9687cb36bec1916c50e834f440bc87025 Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Sun, 22 Dec 2013 01:34:59 -0600 Subject: [PATCH] Added generator-dependent compilation and simple passthrough that allows us to have non-cheated emitted, printing c-code for the first time! (no typechecking or anything yet, but we'll get there). It's also still rough. --- include/ASTData.h | 4 ++-- include/CGenerator.h | 1 + krakenGrammer.kgm | 25 ++++++++++++++++--------- main.cpp | 8 ++++---- src/ASTData.cpp | 16 +++++++++------- src/ASTTransformation.cpp | 6 +++++- src/CGenerator.cpp | 24 ++++++++++++++++-------- src/RNGLRParser.cpp | 2 +- src/util.cpp | 2 +- 9 files changed, 55 insertions(+), 33 deletions(-) diff --git a/include/ASTData.h b/include/ASTData.h index b025ea1..593c84b 100644 --- a/include/ASTData.h +++ b/include/ASTData.h @@ -13,8 +13,8 @@ enum ASTType {undef, translation_unit, interpreter_directive, import, identifier function, code_block, typed_parameter, expression, boolean_expression, statement, if_statement, while_loop, for_loop, return_statement, assignment_statement, declaration_statement, - function_call, value}; -enum ValueType {none, boolean, integer, floating, double_percision, char_string }; + if_comp, simple_passthrough, function_call, value}; +enum ValueType {none, void_type, boolean, integer, floating, double_percision, char_string }; class ASTData { diff --git a/include/CGenerator.h b/include/CGenerator.h index f18fadd..b819f77 100644 --- a/include/CGenerator.h +++ b/include/CGenerator.h @@ -16,6 +16,7 @@ class CGenerator { ~CGenerator(); std::string generate(NodeTree* from); static std::string ValueTypeToCType(ValueType type); + std::string generatorString; private: std::string tabs(); int tabLevel; diff --git a/krakenGrammer.kgm b/krakenGrammer.kgm index 63618c5..bb027b5 100644 --- a/krakenGrammer.kgm +++ b/krakenGrammer.kgm @@ -1,9 +1,9 @@ Goal = translation_unit ; -translation_unit = interpreter_directive WS opt_import_list WS function_list WS ; +translation_unit = interpreter_directive WS unorderd_list_part WS ; +unorderd_list_part = import_list WS unorderd_list_part | function WS unorderd_list_part | if_comp WS unorderd_list_part | simple_passthrough WS unorderd_list_part | import_list | function | if_comp | simple_passthrough ; -type = "\*" WS type | "void" | "int" | "float" | "double" | "char" | identifier ; +type = type WS "\*" | "void" | "int" | "float" | "double" | "char" | identifier ; -opt_import_list = import_list | ; import_list = import_list WS import | import ; import = "import" WS identifier WS ";" ; @@ -14,12 +14,16 @@ forward_slash = "/" ; back_slash = "\\" ; WS = "( | | -)+" | ; +)+" | WS comment WS | ; + +if_comp = "__if_comp__" WS identifier WS if_comp_pred ; +if_comp_pred = code_block | simple_passthrough ; +simple_passthrough = "comp_simple_passthrough" WS triple_quoted_string ; +triple_quoted_string = "\"\"\"(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|.|,|!|\?|_|-|:|;|%|=|\+| | | +|\\|/|\||\(|\)|\"|#|<|\*|>|0|1|2|3|4|5|6|7|8|9)+\"\"\"" ; identifier = alpha | alpha alphanumeric ; -function_list = function_list WS function | function ; - function = type WS identifier WS "\(" WS opt_typed_parameter_list WS "\)" WS code_block ; opt_typed_parameter_list = typed_parameter_list | ; @@ -36,12 +40,12 @@ while_loop = "while" WS boolean_expression WS statement ; for_loop = "for" WS "\(" WS statement WS boolean_expression WS ";" WS statement WS "\)" WS statement ; -return_statement = "return" WS boolean_expression ; +return_statement = "return" | "return" WS boolean_expression ; code_block = "{" WS statement_list WS "}" ; statement_list = statement_list WS statement | statement ; -statement = if_statement | while_loop | for_loop | return_statement WS ";" | boolean_expression WS ";" | assignment_statement WS ";" | declaration_statement WS ";" | code_block ; +statement = if_statement | while_loop | for_loop | return_statement WS ";" | boolean_expression WS ";" | assignment_statement WS ";" | declaration_statement WS ";" | code_block | if_comp | simple_passthrough ; function_call = scope identifier "\(" WS opt_parameter_list WS "\)" ; scope = scope identifier "::" | ; @@ -69,4 +73,7 @@ double = sign numeric "." numeric | sign numeric "." numeric "d" ; bool = "true" | "false" | "True" | "False" ; alpha = "(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|_)+" ; numeric = "(0|1|2|3|4|5|6|7|8|9)+" ; -string = "\"(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|.|,|!|\?|_|-|:|%| | |\\|/|\||\(|\)|0|1|2|3|4|5|6|7|8|9)+\"" ; \ No newline at end of file +string = triple_quoted_string | "\"(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|.|,|!|\?|_|-|:|%| | |\\|/|\||\(|\)|0|1|2|3|4|5|6|7|8|9)+\"" ; + +comment = "//(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|.|,|!|\?|_|-|:|;|%|=|\+| | |\\|/|\||\(|\)|\*|0|1|2|3|4|5|6|7|8|9)+ +" | "/\*(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|.|,|!|\?|_|-|:|%|=|\+| | |\\|/|\||\(|\)|0|1|2|3|4|5|6|7|8|9)+\*/" ; \ No newline at end of file diff --git a/main.cpp b/main.cpp index 955a7c6..2b1ca82 100644 --- a/main.cpp +++ b/main.cpp @@ -134,10 +134,11 @@ int main(int argc, char* argv[]) { preASTTransforms.push_back(new CollapseTransformation(Symbol("opt_parameter_list", false))); preASTTransforms.push_back(new CollapseTransformation(Symbol("opt_import_list", false))); preASTTransforms.push_back(new CollapseTransformation(Symbol("import_list", false))); - preASTTransforms.push_back(new CollapseTransformation(Symbol("function_list", false))); preASTTransforms.push_back(new CollapseTransformation(Symbol("statement_list", false))); preASTTransforms.push_back(new CollapseTransformation(Symbol("parameter_list", false))); preASTTransforms.push_back(new CollapseTransformation(Symbol("typed_parameter_list", false))); + preASTTransforms.push_back(new CollapseTransformation(Symbol("unorderd_list_part", false))); + preASTTransforms.push_back(new CollapseTransformation(Symbol("if_comp_pred", false))); for (int i = 0; i < preASTTransforms.size(); i++) { parseTree = preASTTransforms[i]->transform(parseTree); @@ -145,7 +146,6 @@ int main(int argc, char* argv[]) { preASTTransforms.erase(preASTTransforms.begin(), preASTTransforms.end()); NodeTree* AST = ASTTransformation().transform(parseTree); - //NodeTree* AST = (new ASTTransformation())->transform(parseTree); if (parseTree) { outFileTransformed << parseTree->DOTGraphString() << std::endl; @@ -162,13 +162,13 @@ int main(int argc, char* argv[]) { outFileAST.close(); //Do type checking, scope creation, etc. here. - //None at this time, instead going strait to C in this first (more naive) version + //None at this time, instead going straight to C in this first (more naive) version //Code generation //For right now, just C std::string c_code = CGenerator().generate(AST); outFileC << c_code << std::endl; - outFileC.close(); + outFileC.close(); return(0); } diff --git a/src/ASTData.cpp b/src/ASTData.cpp index 81c0bda..5e5ee66 100644 --- a/src/ASTData.cpp +++ b/src/ASTData.cpp @@ -24,7 +24,9 @@ std::string ASTData::toString() { } ValueType ASTData::strToType(std::string type) { - if (type == "bool") + if (type == "void") + return void_type; + else if (type == "bool") return boolean; else if (type == "int") return integer; @@ -41,22 +43,18 @@ std::string ASTData::ValueTypeToString(ValueType type) { switch (type) { case none: return "none"; - break; + case void_type: + return "void"; case boolean: return "bool"; - break; case integer: return "int"; - break; case floating: return "float"; - break; case double_percision: return "double"; - break; case char_string: return "string"; - break; default: return "unknown_ValueType"; } @@ -96,6 +94,10 @@ std::string ASTData::ASTTypeToString(ASTType type) { return "assignment_statement"; case declaration_statement: return "declaration_statement"; + case if_comp: + return "if_comp"; + case simple_passthrough: + return "simple_passthrough"; case function_call: return "function_call"; case value: diff --git a/src/ASTTransformation.cpp b/src/ASTTransformation.cpp index 9ccd943..52d17c0 100644 --- a/src/ASTTransformation.cpp +++ b/src/ASTTransformation.cpp @@ -105,6 +105,10 @@ NodeTree* ASTTransformation::transform(NodeTree* from) { newNode->addChild(newIdentifier); skipChildren.insert(0); //These, the type and the identifier, have been taken care of. skipChildren.insert(1); + } else if (name == "if_comp") { + newNode = new NodeTree(name, ASTData(if_comp)); + } else if (name == "simple_passthrough") { + newNode = new NodeTree(name, ASTData(simple_passthrough)); } else if (name == "function_call") { //children[0] is scope std::string functionCallName = concatSymbolTree(children[1]); @@ -122,7 +126,7 @@ NodeTree* ASTTransformation::transform(NodeTree* from) { newNode = new NodeTree(name, ASTData(value, Symbol(concatSymbolTree(from), true), floating)); } else if (name == "double") { newNode = new NodeTree(name, ASTData(value, Symbol(concatSymbolTree(from), true), double_percision)); - } else if (name == "string") { + } else if (name == "string" || name == "triple_quoted_string") { newNode = new NodeTree(name, ASTData(value, Symbol(concatSymbolTree(children[0]), true), char_string)); } else { return new NodeTree(); diff --git a/src/CGenerator.cpp b/src/CGenerator.cpp index 53575cf..2f68091 100644 --- a/src/CGenerator.cpp +++ b/src/CGenerator.cpp @@ -1,6 +1,6 @@ #include "CGenerator.h" -CGenerator::CGenerator() { +CGenerator::CGenerator() : generatorString("__C__") { tabLevel = 0; } CGenerator::~CGenerator() { @@ -26,7 +26,8 @@ std::string CGenerator::generate(NodeTree* from) { //Do nothing break; case import: - return "#include <" + data.symbol.getName() + ">\n"; + return "/* would import \"" + data.symbol.getName() + "\" but....*/\n"; + //return "#include <" + data.symbol.getName() + ">\n"; case identifier: return data.symbol.getName(); case function: @@ -34,7 +35,7 @@ std::string CGenerator::generate(NodeTree* from) { for (int i = 0; i < children.size()-1; i++) { if (i > 0) output += ", "; - output += ASTData::ValueTypeToString(children[i]->getData().valueType) + " " + generate(children[i]); + output += ValueTypeToCType(children[i]->getData().valueType) + " " + generate(children[i]); } output+= ")\n" + generate(children[children.size()-1]); return output; @@ -65,11 +66,20 @@ std::string CGenerator::generate(NodeTree* from) { output += "for (" + strSlice(generate(children[0]),0,-2) + generate(children[1]) + ";" + strSlice(generate(children[2]),0,-3) + ")\n\t" + generate(children[3]); return output; case return_statement: - return "return " + generate(children[0]); + if (children.size()) + return "return " + generate(children[0]); + else + return "return"; case assignment_statement: return generate(children[0]) + " = " + generate(children[1]); case declaration_statement: return ASTData::ValueTypeToString(children[0]->getData().valueType) + " " + generate(children[0]) + " = " + generate(children[1]); + case if_comp: + if (generate(children[0]) == generatorString) + return generate(children[1]); + return ""; + case simple_passthrough: + return strSlice(generate(children[0]), 3, -4); case function_call: { //Handle operators specially for now. Will later replace with @@ -104,22 +114,20 @@ std::string CGenerator::ValueTypeToCType(ValueType type) { switch (type) { case none: return "none"; - break; + case void_type: + return "void"; case boolean: return "bool"; - break; case integer: return "int"; break; case floating: return "float"; - break; case double_percision: return "double"; break; case char_string: return "char*"; - break; default: return "unknown_ValueType"; } diff --git a/src/RNGLRParser.cpp b/src/RNGLRParser.cpp index ec64df5..392bc30 100644 --- a/src/RNGLRParser.cpp +++ b/src/RNGLRParser.cpp @@ -79,7 +79,7 @@ NodeTree* RNGLRParser::parseInput(std::string inputString) { std::cout << "Frontier " << i << " is empty." << std::endl; std::cout << "Failed on " << input[i].toString() << std::endl; std::cout << "Nearby is:" << std::endl; - int range = 5; + const int range = 10; for (int j = (i-range >= 0 ? i-range : 0); j < (i+range < input.size() ? i+range : input.size()); j++) if (j == i) std::cout << "||*||*||" << input[j].toString() << "||*||*|| "; diff --git a/src/util.cpp b/src/util.cpp index ce48395..03d5cd3 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -8,7 +8,7 @@ std::string intToString(int theInt) { std::string replaceExEscape(std::string first, std::string search, std::string replace) { size_t pos = 0; - while (pos < first.size()-search.size()) { + while (pos <= first.size()-search.size()) { pos = first.find(search, pos); if (pos == std::string::npos) break;