Small fixes to the grammer, ASTTransformation and CGenerator. Should now be ready to begin implementation of multiple files, conditional inclusion, and code passthrough.
This commit is contained in:
@@ -7,6 +7,8 @@
|
|||||||
#include "NodeTree.h"
|
#include "NodeTree.h"
|
||||||
#include "ASTData.h"
|
#include "ASTData.h"
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
|
||||||
class CGenerator {
|
class CGenerator {
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -11,5 +11,6 @@
|
|||||||
|
|
||||||
std::string intToString(int theInt);
|
std::string intToString(int theInt);
|
||||||
std::string replaceExEscape(std::string first, std::string search, std::string replace);
|
std::string replaceExEscape(std::string first, std::string search, std::string replace);
|
||||||
|
std::string strSlice(std::string str, int begin, int end);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -34,15 +34,14 @@ if_statement = "if" WS "\(" WS boolean_expression WS "\)" WS statement ;
|
|||||||
|
|
||||||
while_loop = "while" WS boolean_expression WS statement ;
|
while_loop = "while" WS boolean_expression WS statement ;
|
||||||
|
|
||||||
for_update = "\(" WS statement_list WS "\)" ;
|
for_loop = "for" WS "\(" WS statement WS boolean_expression WS ";" WS statement WS "\)" WS statement ;
|
||||||
for_loop = "for" WS for_update WS statement ;
|
|
||||||
|
|
||||||
return_statement = "return" WS boolean_expression WS ";" ;
|
return_statement = "return" WS boolean_expression ;
|
||||||
|
|
||||||
code_block = "{" WS statement_list WS "}" ;
|
code_block = "{" WS statement_list WS "}" ;
|
||||||
|
|
||||||
statement_list = statement_list WS statement | statement ;
|
statement_list = statement_list WS statement | statement ;
|
||||||
statement = if_statement | while_loop | for_loop | return_statement | 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 ;
|
||||||
function_call = scope identifier "\(" WS opt_parameter_list WS "\)" ;
|
function_call = scope identifier "\(" WS opt_parameter_list WS "\)" ;
|
||||||
scope = scope identifier "::" | ;
|
scope = scope identifier "::" | ;
|
||||||
|
|
||||||
@@ -58,7 +57,7 @@ factor = "\+\+" WS unarad | unarad WS "\+\+" | "--" WS unarad | unarad WS "--" |
|
|||||||
unarad = number | identifier | function_call | bool | string | "\(" WS boolean_expression WS "\)" ;
|
unarad = number | identifier | function_call | bool | string | "\(" WS boolean_expression WS "\)" ;
|
||||||
number = integer | float | double ;
|
number = integer | float | double ;
|
||||||
|
|
||||||
assignment_statement = identifier WS "=" WS boolean_expression | identifier WS "+=" WS boolean_expression | identifier WS "-=" WS boolean_expression | identifier WS "\*=" WS boolean_expression | identifier WS "/=" WS boolean_expression ;
|
assignment_statement = identifier WS "=" WS boolean_expression | identifier WS "\+=" WS boolean_expression | identifier WS "-=" WS boolean_expression | identifier WS "\*=" WS boolean_expression | identifier WS "/=" WS boolean_expression ;
|
||||||
declaration_statement = type WS identifier WS "=" WS boolean_expression ;
|
declaration_statement = type WS identifier WS "=" WS boolean_expression ;
|
||||||
|
|
||||||
alphanumeric = alphanumeric numeric | alphanumeric alpha | numeric | alpha ;
|
alphanumeric = alphanumeric numeric | alphanumeric alpha | numeric | alpha ;
|
||||||
@@ -70,4 +69,4 @@ double = sign numeric "." numeric | sign numeric "." numeric "d" ;
|
|||||||
bool = "true" | "false" | "True" | "False" ;
|
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|_)+" ;
|
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)+" ;
|
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)+\"" ;
|
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)+\"" ;
|
||||||
2
main.cpp
2
main.cpp
@@ -16,12 +16,14 @@
|
|||||||
#include "ASTData.h"
|
#include "ASTData.h"
|
||||||
#include "CGenerator.h"
|
#include "CGenerator.h"
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
if (argc == 2 && std::string(argv[1]) == "--test") {
|
if (argc == 2 && std::string(argv[1]) == "--test") {
|
||||||
StringReader::test();
|
StringReader::test();
|
||||||
RegEx::test();
|
RegEx::test();
|
||||||
Lexer::test();
|
Lexer::test();
|
||||||
|
//std::cout << strSlice("123", 0, -1) << std::endl;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,17 +62,16 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from) {
|
|||||||
return transform(children[0]); //Just a promoted bool_exp, so do child
|
return transform(children[0]); //Just a promoted bool_exp, so do child
|
||||||
}
|
}
|
||||||
//Here's the order of ops stuff
|
//Here's the order of ops stuff
|
||||||
} else if (name == "expression" || name == "shiftand" || name == "term" || name == "unarad") {
|
} else if (name == "expression" || name == "shiftand" || name == "term" || name == "factor" || name == "unarad") {
|
||||||
//If this is an actual part of an expression, not just a premoted child
|
//If this is an actual part of an expression, not just a premoted child
|
||||||
if (children.size() > 1) {
|
if (children.size() > 1) {
|
||||||
std::string functionCallName = concatSymbolTree(children[1]);
|
std::string functionCallName = concatSymbolTree(children[1]);
|
||||||
|
std::cout << functionCallName << std::endl;
|
||||||
newNode = new NodeTree<ASTData>(functionCallName, ASTData(function_call, Symbol(functionCallName, true)));
|
newNode = new NodeTree<ASTData>(functionCallName, ASTData(function_call, Symbol(functionCallName, true)));
|
||||||
skipChildren.insert(1);
|
skipChildren.insert(1);
|
||||||
} else {
|
} else {
|
||||||
return transform(children[0]); //Just a promoted child, so do it instead
|
return transform(children[0]); //Just a promoted child, so do it instead
|
||||||
}
|
}
|
||||||
} else if (name == "factor") {
|
|
||||||
return transform(children[0]); //Just a premoted number or function call or something, so use it instead
|
|
||||||
} else if (name == "statement") {
|
} else if (name == "statement") {
|
||||||
newNode = new NodeTree<ASTData>(name, ASTData(statement));
|
newNode = new NodeTree<ASTData>(name, ASTData(statement));
|
||||||
} else if (name == "if_statement") {
|
} else if (name == "if_statement") {
|
||||||
@@ -92,7 +91,7 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from) {
|
|||||||
} else {
|
} else {
|
||||||
//For assignments like += or *=, expand the syntatic sugar.
|
//For assignments like += or *=, expand the syntatic sugar.
|
||||||
NodeTree<ASTData>* lhs = transform(children[0]);
|
NodeTree<ASTData>* lhs = transform(children[0]);
|
||||||
NodeTree<ASTData>* childCall = new NodeTree<ASTData>(assignFuncName, ASTData(function_call, Symbol(assignFuncName, true)));
|
NodeTree<ASTData>* childCall = new NodeTree<ASTData>(assignFuncName.substr(0,1), ASTData(function_call, Symbol(assignFuncName.substr(0,1), true)));
|
||||||
childCall->addChild(lhs);
|
childCall->addChild(lhs);
|
||||||
childCall->addChild(transform(children[2]));
|
childCall->addChild(transform(children[2]));
|
||||||
newNode->addChild(lhs);
|
newNode->addChild(lhs);
|
||||||
|
|||||||
@@ -58,10 +58,11 @@ std::string CGenerator::generate(NodeTree<ASTData>* from) {
|
|||||||
output += " else " + generate(children[2]);
|
output += " else " + generate(children[2]);
|
||||||
return output;
|
return output;
|
||||||
case while_loop:
|
case while_loop:
|
||||||
output += "if (" + generate(children[0]) + ")\n\t" + generate(children[1]);
|
output += "while (" + generate(children[0]) + ")\n\t" + generate(children[1]);
|
||||||
return output;
|
return output;
|
||||||
case for_loop:
|
case for_loop:
|
||||||
output += "if (" + generate(children[0]) + ")\n\t" + generate(children[1]);
|
//The strSlice's are there to get ride of an unwanted return and an unwanted semicolon
|
||||||
|
output += "for (" + strSlice(generate(children[0]),0,-2) + generate(children[1]) + ";" + strSlice(generate(children[2]),0,-3) + ")\n\t" + generate(children[3]);
|
||||||
return output;
|
return output;
|
||||||
case return_statement:
|
case return_statement:
|
||||||
return "return " + generate(children[0]);
|
return "return " + generate(children[0]);
|
||||||
@@ -74,7 +75,9 @@ std::string CGenerator::generate(NodeTree<ASTData>* from) {
|
|||||||
//Handle operators specially for now. Will later replace with
|
//Handle operators specially for now. Will later replace with
|
||||||
//Inlined functions in the standard library
|
//Inlined functions in the standard library
|
||||||
std::string name = data.symbol.getName();
|
std::string name = data.symbol.getName();
|
||||||
if (name == "+" || name == "-" || name == "*" || name == "/" || name == "==" || name == ">=" || name == "<=" || name == "!=" || name == "%") {
|
if (name == "++" || name == "--")
|
||||||
|
return generate(children[0]) + name;
|
||||||
|
if (name == "+" || name == "-" || name == "*" || name == "/" || name == "==" || name == ">=" || name == "<=" || name == "!=" || name == "<" || name == ">" || name == "%" || name == "+=" || name == "-=" || name == "*=" || name == "/=") {
|
||||||
return "((" + generate(children[0]) + ")" + name + "(" + generate(children[1]) + "))";
|
return "((" + generate(children[0]) + ")" + name + "(" + generate(children[1]) + "))";
|
||||||
}
|
}
|
||||||
output += data.symbol.getName() + "(";
|
output += data.symbol.getName() + "(";
|
||||||
|
|||||||
@@ -31,3 +31,12 @@ std::string replaceExEscape(std::string first, std::string search, std::string r
|
|||||||
}
|
}
|
||||||
return first;
|
return first;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//String slicing is crazy useful. substr isn't bad, but slicing with negative indicies is wonderful
|
||||||
|
std::string strSlice(std::string str, int begin, int end) {
|
||||||
|
if (begin < 0)
|
||||||
|
begin += str.length()+1;
|
||||||
|
if (end < 0)
|
||||||
|
end += str.length()+1;
|
||||||
|
return str.substr(begin, end-begin);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user