work on ast_transformation, fix adt depending on type CGenerator order bug (correctly add poset dependencies)
This commit is contained in:
@@ -14,7 +14,7 @@ class Type;
|
|||||||
#define NULL ((void*)0)
|
#define NULL ((void*)0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum ASTType {undef, translation_unit, interpreter_directive, import, identifier, type_def, adt_def,
|
enum ASTType {undef, translation_unit, import, identifier, type_def, adt_def,
|
||||||
function, code_block, typed_parameter, expression, boolean_expression, statement,
|
function, code_block, typed_parameter, expression, boolean_expression, statement,
|
||||||
if_statement, match_statement, case_statement, while_loop, for_loop, return_statement, break_statement,
|
if_statement, match_statement, case_statement, while_loop, for_loop, return_statement, break_statement,
|
||||||
continue_statement, defer_statement, assignment_statement, declaration_statement, if_comp, simple_passthrough,
|
continue_statement, defer_statement, assignment_statement, declaration_statement, if_comp, simple_passthrough,
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ float_end = "(0|1|2|3|4|5|6|7|8|9)+" | "(0|1|2|3|4|5|6|7|8|9)+f" | "(0|1|2|3|4|5
|
|||||||
bool = "true" | "false" ;
|
bool = "true" | "false" ;
|
||||||
character = "'(`|1|2|3|4|5|6|7|8|9|0|-|=|(\\t)|q|w|e|r|t|y|u|i|o|p|[|]|(\\\\)|a|s|d|f|g|h|j|k|l|;|'|(\\n)|z|x|c|v|b|n|m|,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|Q|W|E|R|T|Y|U|I|O|P|{|}|\||A|S|D|F|G|H|J|K|L|:|\"|Z|X|C|V|B|N|M|<|>|\?| |(\\0))'" ;
|
character = "'(`|1|2|3|4|5|6|7|8|9|0|-|=|(\\t)|q|w|e|r|t|y|u|i|o|p|[|]|(\\\\)|a|s|d|f|g|h|j|k|l|;|'|(\\n)|z|x|c|v|b|n|m|,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|Q|W|E|R|T|Y|U|I|O|P|{|}|\||A|S|D|F|G|H|J|K|L|:|\"|Z|X|C|V|B|N|M|<|>|\?| |(\\0))'" ;
|
||||||
|
|
||||||
keywords_also_identifiers = "obj" | "def" | "fun" | "var" | "adt" ;
|
keywords_also_identifiers = "obj" | "def" | "fun" | "var" | "adt" | "import" | "simple_passthrough" ;
|
||||||
alpha_alphanumeric = "(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|_)(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)*" ;
|
alpha_alphanumeric = "(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|_)(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)*" ;
|
||||||
augmented_alpha_alphanumeric = alpha_alphanumeric augmented_alpha_alphanumeric | keywords_also_identifiers augmented_alpha_alphanumeric | alpha_alphanumeric | keywords_also_identifiers ;
|
augmented_alpha_alphanumeric = alpha_alphanumeric augmented_alpha_alphanumeric | keywords_also_identifiers augmented_alpha_alphanumeric | alpha_alphanumeric | keywords_also_identifiers ;
|
||||||
|
|
||||||
|
|||||||
@@ -30,8 +30,6 @@ std::string ASTData::ASTTypeToString(ASTType type) {
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case translation_unit:
|
case translation_unit:
|
||||||
return "translation_unit";
|
return "translation_unit";
|
||||||
case interpreter_directive:
|
|
||||||
return "interpreter_directive";
|
|
||||||
case identifier:
|
case identifier:
|
||||||
return "identifier";
|
return "identifier";
|
||||||
case import:
|
case import:
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ NodeTree<ASTData>* ASTTransformation::firstPass(std::string fileName, NodeTree<S
|
|||||||
for (NodeTree<Symbol>* i : children) {
|
for (NodeTree<Symbol>* i : children) {
|
||||||
if (i->getDataRef()->getName() == "import") {
|
if (i->getDataRef()->getName() == "import") {
|
||||||
auto importChildren = i->getChildren();
|
auto importChildren = i->getChildren();
|
||||||
std::string toImport = concatSymbolTree(importChildren[0]);
|
std::string toImport = concatSymbolTree(importChildren[1]);
|
||||||
auto importNode = addToScope("~enclosing_scope", translationUnit, new NodeTree<ASTData>("import", ASTData(import, Symbol(toImport, true))));
|
auto importNode = addToScope("~enclosing_scope", translationUnit, new NodeTree<ASTData>("import", ASTData(import, Symbol(toImport, true))));
|
||||||
translationUnit->addChild(importNode);
|
translationUnit->addChild(importNode);
|
||||||
//Do the imported file too
|
//Do the imported file too
|
||||||
@@ -130,7 +130,7 @@ NodeTree<ASTData>* ASTTransformation::firstPass(std::string fileName, NodeTree<S
|
|||||||
// Note that import affects scope in two ways:
|
// Note that import affects scope in two ways:
|
||||||
// (1) The other file's translationUnit is added to our translationUnit's scope under it's name
|
// (1) The other file's translationUnit is added to our translationUnit's scope under it's name
|
||||||
// (2) The import node's scope contains the nodes indicated by the qualifiers after the import (i.e. the import a:b; or import a:*;)
|
// (2) The import node's scope contains the nodes indicated by the qualifiers after the import (i.e. the import a:b; or import a:*;)
|
||||||
for (auto importQualifer : slice(importChildren, 1, -1)) { // Not the first child, that's the name of the file
|
for (auto importQualifer : slice(importChildren, 2, -1)) { // Not the first child, import, or the second that's the name of the file
|
||||||
auto name = concatSymbolTree(importQualifer);
|
auto name = concatSymbolTree(importQualifer);
|
||||||
if (name == "*") {
|
if (name == "*") {
|
||||||
std::vector<NodeTree<ASTData>*> tmp;
|
std::vector<NodeTree<ASTData>*> tmp;
|
||||||
@@ -823,6 +823,7 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
} else if (name == "simple_passthrough") {
|
} else if (name == "simple_passthrough") {
|
||||||
newNode = new NodeTree<ASTData>(name, ASTData(simple_passthrough));
|
newNode = new NodeTree<ASTData>(name, ASTData(simple_passthrough));
|
||||||
addToScope("~enclosing_scope", scope, newNode);
|
addToScope("~enclosing_scope", scope, newNode);
|
||||||
|
skipChildren.insert(0); //Don't do the identifier. The identifier lookup will fail. That's why we do it here.
|
||||||
} else if (name == "passthrough_params") {
|
} else if (name == "passthrough_params") {
|
||||||
newNode = new NodeTree<ASTData>(name, ASTData(passthrough_params));
|
newNode = new NodeTree<ASTData>(name, ASTData(passthrough_params));
|
||||||
addToScope("~enclosing_scope", scope, newNode);
|
addToScope("~enclosing_scope", scope, newNode);
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ std::string CGenerator::generateTypeStruct(NodeTree<ASTData>* from) {
|
|||||||
structString = "struct __struct_dummy_";
|
structString = "struct __struct_dummy_";
|
||||||
structString += prefixIfNeeded(scopePrefix(from), CifyName(data.symbol.getName())+"__") + " {\n";
|
structString += prefixIfNeeded(scopePrefix(from), CifyName(data.symbol.getName())+"__") + " {\n";
|
||||||
if (data.type == adt_def) {
|
if (data.type == adt_def) {
|
||||||
structString = "typedef " + structString + " enum " + enumName + " flag;\n union { \n";
|
structString = structString + " enum " + enumName + " flag;\n union { \n";
|
||||||
tabLevel++;
|
tabLevel++;
|
||||||
}
|
}
|
||||||
tabLevel++;
|
tabLevel++;
|
||||||
@@ -87,7 +87,7 @@ std::string CGenerator::generateTypeStruct(NodeTree<ASTData>* from) {
|
|||||||
if (data.type == adt_def) {
|
if (data.type == adt_def) {
|
||||||
//structString += "} data; /*end union*/ \n";
|
//structString += "} data; /*end union*/ \n";
|
||||||
tabLevel--;
|
tabLevel--;
|
||||||
structString += " }; /*end union*/\n} " + CifyName(data.symbol.getName()) + "; /* end struct */";
|
structString += " }; /*end union*/\n};";
|
||||||
} else {
|
} else {
|
||||||
structString += "};";
|
structString += "};";
|
||||||
}
|
}
|
||||||
@@ -204,8 +204,17 @@ std::pair<std::string, std::string> CGenerator::generateTranslationUnit(std::str
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (children[i]->getDataRef()->type == adt_def) {
|
} else if (children[i]->getDataRef()->type == adt_def) {
|
||||||
//
|
|
||||||
typedefPoset.addVertex(children[i]); // We add this definition by itself just in case there are no dependencies.
|
typedefPoset.addVertex(children[i]); // We add this definition by itself just in case there are no dependencies.
|
||||||
|
std::vector<NodeTree<ASTData>*> adtChildren = children[i]->getChildren();
|
||||||
|
for (auto j : adtChildren) {
|
||||||
|
if (j->getDataRef()->type == identifier) {
|
||||||
|
Type* decType = j->getDataRef()->valueType; // Type of the declaration
|
||||||
|
if (decType->typeDefinition == children[i])
|
||||||
|
continue;
|
||||||
|
if (decType->typeDefinition && decType->getIndirection() == 0) // If this is a custom type and not a pointer
|
||||||
|
typedefPoset.addRelationship(children[i], decType->typeDefinition); // Add a dependency
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -298,6 +307,9 @@ std::pair<std::string, std::string> CGenerator::generateTranslationUnit(std::str
|
|||||||
break;
|
break;
|
||||||
case adt_def:
|
case adt_def:
|
||||||
{
|
{
|
||||||
|
plainTypedefs += "typedef struct __struct_dummy_" +
|
||||||
|
prefixIfNeeded(scopePrefix(declaration), CifyName(declarationData.symbol.getName()) + "__") + " " +
|
||||||
|
prefixIfNeeded(scopePrefix(declaration), CifyName(declarationData.symbol.getName())) + ";\n";
|
||||||
for (auto child : decChildren) {
|
for (auto child : decChildren) {
|
||||||
if (child->getName() == "function") {
|
if (child->getName() == "function") {
|
||||||
std::string orig_fun_name = child->getDataRef()->symbol.getName();
|
std::string orig_fun_name = child->getDataRef()->symbol.getName();
|
||||||
@@ -452,9 +464,6 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
|||||||
throw "That's not gonna work";
|
throw "That's not gonna work";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case interpreter_directive:
|
|
||||||
//Do nothing
|
|
||||||
break;
|
|
||||||
case import:
|
case import:
|
||||||
return CCodeTriple("/* never reached import? */\n");
|
return CCodeTriple("/* never reached import? */\n");
|
||||||
case identifier:
|
case identifier:
|
||||||
|
|||||||
@@ -33,12 +33,11 @@ Importer::Importer(Parser* parserIn, std::vector<std::string> includePaths, std:
|
|||||||
removeSymbols.push_back(Symbol("}", true));
|
removeSymbols.push_back(Symbol("}", true));
|
||||||
removeSymbols.push_back(Symbol("(", true));
|
removeSymbols.push_back(Symbol("(", true));
|
||||||
removeSymbols.push_back(Symbol(")", true));
|
removeSymbols.push_back(Symbol(")", true));
|
||||||
removeSymbols.push_back(Symbol("import", true));
|
//removeSymbols.push_back(Symbol("import", true));
|
||||||
removeSymbols.push_back(Symbol("interpreter_directive", false));
|
|
||||||
removeSymbols.push_back(Symbol("if", true));
|
removeSymbols.push_back(Symbol("if", true));
|
||||||
removeSymbols.push_back(Symbol("while", true));
|
removeSymbols.push_back(Symbol("while", true));
|
||||||
removeSymbols.push_back(Symbol("__if_comp__", true));
|
removeSymbols.push_back(Symbol("__if_comp__", true));
|
||||||
removeSymbols.push_back(Symbol("simple_passthrough", true));
|
//removeSymbols.push_back(Symbol("simple_passthrough", true));
|
||||||
removeSymbols.push_back(Symbol("comp_simple_passthrough", true));
|
removeSymbols.push_back(Symbol("comp_simple_passthrough", true));
|
||||||
removeSymbols.push_back(Symbol("def_nonterm", false));
|
removeSymbols.push_back(Symbol("def_nonterm", false));
|
||||||
removeSymbols.push_back(Symbol("obj_nonterm", false));
|
removeSymbols.push_back(Symbol("obj_nonterm", false));
|
||||||
|
|||||||
@@ -9,7 +9,103 @@ import mem:*
|
|||||||
import io:*
|
import io:*
|
||||||
|
|
||||||
adt ast_node {
|
adt ast_node {
|
||||||
undef
|
undef: undef,
|
||||||
|
translation_unit: translation_unit,
|
||||||
|
import: import,
|
||||||
|
identifier: identifier,
|
||||||
|
type_def: type_def,
|
||||||
|
adt_def: adt_def,
|
||||||
|
function: function,
|
||||||
|
code_block: code_block,
|
||||||
|
typed_parameter: typed_parameter,
|
||||||
|
expression: expression,
|
||||||
|
boolean_expression: boolean_expression,
|
||||||
|
statement: statement,
|
||||||
|
if_statement: if_statement,
|
||||||
|
match_statement: match_statement,
|
||||||
|
case_statement: case_statement,
|
||||||
|
while_loop: while_loop,
|
||||||
|
for_loop: for_loop,
|
||||||
|
return_statement: return_statement,
|
||||||
|
break_statement: break_statement,
|
||||||
|
continue_statement: continue_statement,
|
||||||
|
defer_statement: defer_statement,
|
||||||
|
assignment_statement: assignment_statement,
|
||||||
|
declaration_statement: declaration_statement,
|
||||||
|
if_comp: if_comp,
|
||||||
|
simple_passthrough: simple_passthrough,
|
||||||
|
passthrough_params: passthrough_params,
|
||||||
|
in_passthrough_params: in_passthrough_params,
|
||||||
|
out_passthrough_params: out_passthrough_params,
|
||||||
|
opt_string: opt_string,
|
||||||
|
param_assign: param_assign,
|
||||||
|
function_call: function_call,
|
||||||
|
value: value
|
||||||
|
}
|
||||||
|
|
||||||
|
obj undef (Object) {
|
||||||
|
}
|
||||||
|
obj translation_unit (Object) {
|
||||||
|
}
|
||||||
|
obj import (Object) {
|
||||||
|
}
|
||||||
|
obj identifier (Object) {
|
||||||
|
}
|
||||||
|
obj type_def (Object) {
|
||||||
|
}
|
||||||
|
obj adt_def (Object) {
|
||||||
|
}
|
||||||
|
obj function (Object) {
|
||||||
|
}
|
||||||
|
obj code_block (Object) {
|
||||||
|
}
|
||||||
|
obj typed_parameter (Object) {
|
||||||
|
}
|
||||||
|
obj expression (Object) {
|
||||||
|
}
|
||||||
|
obj boolean_expression (Object) {
|
||||||
|
}
|
||||||
|
obj statement (Object) {
|
||||||
|
}
|
||||||
|
obj if_statement (Object) {
|
||||||
|
}
|
||||||
|
obj match_statement (Object) {
|
||||||
|
}
|
||||||
|
obj case_statement (Object) {
|
||||||
|
}
|
||||||
|
obj while_loop (Object) {
|
||||||
|
}
|
||||||
|
obj for_loop (Object) {
|
||||||
|
}
|
||||||
|
obj return_statement (Object) {
|
||||||
|
}
|
||||||
|
obj break_statement (Object) {
|
||||||
|
}
|
||||||
|
obj continue_statement (Object) {
|
||||||
|
}
|
||||||
|
obj defer_statement (Object) {
|
||||||
|
}
|
||||||
|
obj assignment_statement (Object) {
|
||||||
|
}
|
||||||
|
obj declaration_statement (Object) {
|
||||||
|
}
|
||||||
|
obj if_comp (Object) {
|
||||||
|
}
|
||||||
|
obj simple_passthrough (Object) {
|
||||||
|
}
|
||||||
|
obj passthrough_params (Object) {
|
||||||
|
}
|
||||||
|
obj in_passthrough_params (Object) {
|
||||||
|
}
|
||||||
|
obj out_passthrough_params (Object) {
|
||||||
|
}
|
||||||
|
obj opt_string (Object) {
|
||||||
|
}
|
||||||
|
obj param_assign (Object) {
|
||||||
|
}
|
||||||
|
obj function_call (Object) {
|
||||||
|
}
|
||||||
|
obj value (Object) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user