diff --git a/krakenGrammer.kgm b/krakenGrammer.kgm index 4689ab8..27c818d 100644 --- a/krakenGrammer.kgm +++ b/krakenGrammer.kgm @@ -28,29 +28,30 @@ typed_parameter = type WS parameter ; opt_parameter_list = parameter_list | ; parameter_list = parameter_list WS parameter | parameter ; -parameter = expression ; +parameter = boolean_expression ; code_block = "{" WS statement_list WS "}" ; statement_list = statement_list WS statement | statement ; -statement = if_statement | return_statement | expression WS ";" | boolean_expression WS ";" | assignment_statement WS ";" | declaration_statement WS ";" | code_block ; +statement = if_statement | return_statement | boolean_expression WS ";" | boolean_expression WS ";" | assignment_statement WS ";" | declaration_statement WS ";" | code_block ; function_call = scope identifier "\(" WS opt_parameter_list WS "\)" ; scope = scope identifier "::" | ; -if_statement = "if" WS boolean_expression WS statement | "if" WS "\(" WS boolean_expression WS "\)" WS statement ; +if_statement = "if" WS boolean_expression WS statement ; + +return_statement = "return" WS boolean_expression WS ";" ; boolean_expression = boolean_expression WS "\|\|" WS and_boolean_expression | and_boolean_expression ; and_boolean_expression = and_boolean_expression "&&" bool_exp | bool_exp ; -bool_exp = "!" WS bool_exp | expression WS "==" WS expression | bool ; - -return_statement = "return" WS "\(" WS expression WS "\)" WS ";" | "return" WS expression WS ";" ; +bool_exp = "!" WS bool_exp | expression WS comparator WS expression | bool | expression ; +comparator = "==" | "<=" | ">=" | "!=" ; expression = expression WS "-" WS term | expression WS "\+" WS term | term ; term = term WS forward_slash WS factor | term WS "\*" WS factor | factor ; -factor = number | identifier | function_call | bool | string ; +factor = number | identifier | function_call | bool | string | "\(" WS boolean_expression WS "\)" ; number = integer | float | double ; -assignment_statement = identifier WS "=" WS expression ; -declaration_statement = type WS identifier WS "=" WS expression ; +assignment_statement = identifier WS "=" WS boolean_expression ; +declaration_statement = type WS identifier WS "=" WS boolean_expression ; alphanumeric = alphanumeric numeric | alphanumeric alpha | numeric | alpha ; hexadecimal = "0x(1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)+" ; @@ -61,4 +62,4 @@ 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 = "\"(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 f94a99f..a072818 100644 --- a/main.cpp +++ b/main.cpp @@ -121,6 +121,8 @@ int main(int argc, char* argv[]) { preASTTransforms.push_back(new RemovalTransformation(Symbol(";", true))); preASTTransforms.push_back(new RemovalTransformation(Symbol("{", true))); preASTTransforms.push_back(new RemovalTransformation(Symbol("}", true))); + preASTTransforms.push_back(new RemovalTransformation(Symbol("(", true))); + preASTTransforms.push_back(new RemovalTransformation(Symbol(")", true))); preASTTransforms.push_back(new RemovalTransformation(Symbol("import", true))); //Don't need the actual text of the symbol preASTTransforms.push_back(new RemovalTransformation(Symbol("interpreter_directive", false))); preASTTransforms.push_back(new RemovalTransformation(Symbol("if", true))); diff --git a/src/ASTTransformation.cpp b/src/ASTTransformation.cpp index 8c51ef9..36cca8a 100644 --- a/src/ASTTransformation.cpp +++ b/src/ASTTransformation.cpp @@ -34,6 +34,33 @@ NodeTree* ASTTransformation::transform(NodeTree* from) { newNode = transform(children[1]); //Transform to get the identifier newNode->getDataRef()->valueType = ASTData::strToType(concatSymbolTree(children[0])); //Get the type (left child) and set our new identifer to be that type return newNode; + } else if (name == "boolean_expression") { + //If this is an actual part of an expression, not just a premoted term + if (children.size() > 1) { + std::string functionCallName = concatSymbolTree(children[1]); + newNode = new NodeTree(functionCallName, ASTData(function_call, Symbol(functionCallName, true))); + skipChildren.insert(1); + } else { + return transform(children[0]); //Just a promoted term, so do child + } + } else if (name == "and_boolean_expression") { + //If this is an actual part of an expression, not just a premoted bool_exp + if (children.size() > 1) { + std::string functionCallName = concatSymbolTree(children[1]); + newNode = new NodeTree(functionCallName, ASTData(function_call, Symbol(functionCallName, true))); + skipChildren.insert(1); + } else { + return transform(children[0]); //Just a promoted bool_exp, so do child + } + } else if (name == "bool_exp") { + //If this is an actual part of an expression, not just a premoted bool_exp. + if (children.size() > 1) { + std::string functionCallName = concatSymbolTree(children[1]); + newNode = new NodeTree(functionCallName, ASTData(function_call, Symbol(functionCallName, true))); + skipChildren.insert(1); + } else { + return transform(children[0]); //Just a promoted bool_exp, so do child + } } else if (name == "expression") { //If this is an actual part of an expression, not just a premoted term if (children.size() > 1) { @@ -54,8 +81,6 @@ NodeTree* ASTTransformation::transform(NodeTree* from) { } } else if (name == "factor") { return transform(children[0]); //Just a premoted number or function call or something, so use it instead - } else if (name == "boolean_expression") { - newNode = new NodeTree(name, ASTData(boolean_expression)); } else if (name == "statement") { newNode = new NodeTree(name, ASTData(statement)); } else if (name == "if_statement") { diff --git a/src/CGenerator.cpp b/src/CGenerator.cpp index 04c9d79..abef745 100644 --- a/src/CGenerator.cpp +++ b/src/CGenerator.cpp @@ -26,7 +26,7 @@ std::string CGenerator::generate(NodeTree* from) { //Do nothing break; case import: - return "#include \"" + data.symbol.getName() + "\"\n"; + return "#include <" + data.symbol.getName() + ">\n"; break; case identifier: return data.symbol.getName(); @@ -42,7 +42,7 @@ std::string CGenerator::generate(NodeTree* from) { return output; break; case code_block: - output += tabs() + "{\n"; + output += "{\n"; tabLevel++; for (int i = 0; i < children.size(); i++) output += generate(children[i]); @@ -60,7 +60,7 @@ std::string CGenerator::generate(NodeTree* from) { return tabs() + generate(children[0]) + ";\n"; break; case if_statement: - output += "if (" + generate(children[0]) + ") \n" + generate(children[1]); + output += "if (" + generate(children[0]) + ")\n\t" + generate(children[1]); if (children.size() > 2) output += " else " + generate(children[2]); return output; @@ -76,7 +76,7 @@ std::string CGenerator::generate(NodeTree* from) { //Handle operators specially for now. Will later replace with //Inlined functions in the standard library std::string name = data.symbol.getName(); - if (name == "+" || name == "-" || name == "*" || name == "/") { + if (name == "+" || name == "-" || name == "*" || name == "/" || name == "==" || name == ">=" || name == "<=" || name == "!=") { return "((" + generate(children[0]) + ")" + name + "(" + generate(children[1]) + "))"; } output += data.symbol.getName() + "(";