Wooo actual scoping and better C interop
This commit is contained in:
@@ -68,6 +68,12 @@ std::string ASTData::ASTTypeToString(ASTType type) {
|
||||
return "simple_passthrough";
|
||||
case passthrough_params:
|
||||
return "passthrough_params";
|
||||
case in_passthrough_params:
|
||||
return "out_passthrough_params";
|
||||
case param_assign:
|
||||
return "param_assign";
|
||||
case opt_string:
|
||||
return "opt_string";
|
||||
case function_call:
|
||||
return "function_call";
|
||||
case value:
|
||||
|
||||
@@ -56,6 +56,8 @@ NodeTree<ASTData>* ASTTransformation::firstPass(std::string fileName, NodeTree<S
|
||||
else //It's not
|
||||
name = concatSymbolTree(i->getChildren()[0]);
|
||||
NodeTree<ASTData>* firstDec = addToScope("~enclosing_scope", translationUnit, new NodeTree<ASTData>("type_def", ASTData(type_def, Symbol(name, true, name))));
|
||||
addToScope(name, firstDec, translationUnit);
|
||||
translationUnit->addChild(firstDec);
|
||||
//If this is a template, go ahead and set it up. Pass 2 needs templates set up so it can (partially) instantiate them.
|
||||
//So we give this typedef its name without any template types and make its type template_type, and point to this from node.
|
||||
//Then, when this template is instantiated, it will run transform on from with the types filled in.
|
||||
@@ -71,9 +73,6 @@ NodeTree<ASTData>* ASTTransformation::firstPass(std::string fileName, NodeTree<S
|
||||
else if (typedefChildren.size() == 1 || typedefChildren[1]->getData().getName() != "type") //We don't make the type for alises, because the second pass will assign it the type it points to
|
||||
firstDec->getDataRef()->valueType = new Type(firstDec);
|
||||
|
||||
translationUnit->addChild(firstDec);
|
||||
translationUnit->getDataRef()->scope[name].push_back(firstDec);
|
||||
firstDec->getDataRef()->scope["~enclosing_scope"].push_back(translationUnit);
|
||||
} else if (i->getDataRef()->getName() == "if_comp") {
|
||||
std::cout << "IF COMP" << std::endl;
|
||||
NodeTree<ASTData>* newNode = addToScope("~enclosing_scope", translationUnit, new NodeTree<ASTData>(i->getDataRef()->getName(), ASTData(if_comp)));
|
||||
@@ -154,7 +153,9 @@ void ASTTransformation::secondPass(NodeTree<ASTData>* ast, NodeTree<Symbol>* par
|
||||
if (typedefChildren.size() > 1 && typedefChildren[1]->getData().getName() == "type") {
|
||||
Type* aliasedType = typeFromTypeNode(typedefChildren[1], ast, std::map<std::string, Type*>());
|
||||
typeDef->getDataRef()->valueType = aliasedType;
|
||||
typeDef->getDataRef()->scope["~enclosing_scope"][0] = aliasedType->typeDefinition; //So that object lookups find the right member. Note that this overrides translation_unit as a parent scope
|
||||
// only put in scope if it has a definition, that is it is not an aliased primitive
|
||||
if (aliasedType->typeDefinition)
|
||||
typeDef->getDataRef()->scope["~enclosing_scope"][0] = aliasedType->typeDefinition; //So that object lookups find the right member. Note that this overrides translation_unit as a parent scope
|
||||
// std::cout << name << " alias's to " << aliasedType->typeDefinition << std::endl;
|
||||
// std::cout << "that is " << aliasedType->typeDefinition->getDataRef()->toString() << std::endl;
|
||||
continue;
|
||||
@@ -629,6 +630,18 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
||||
} else if (name == "passthrough_params") {
|
||||
newNode = new NodeTree<ASTData>(name, ASTData(passthrough_params));
|
||||
addToScope("~enclosing_scope", scope, newNode);
|
||||
} else if (name == "in_passthrough_params") {
|
||||
newNode = new NodeTree<ASTData>(name, ASTData(in_passthrough_params));
|
||||
addToScope("~enclosing_scope", scope, newNode);
|
||||
} else if (name == "out_passthrough_params") {
|
||||
newNode = new NodeTree<ASTData>(name, ASTData(out_passthrough_params));
|
||||
addToScope("~enclosing_scope", scope, newNode);
|
||||
} else if (name == "opt_string") {
|
||||
newNode = new NodeTree<ASTData>(name, ASTData(opt_string));
|
||||
addToScope("~enclosing_scope", scope, newNode);
|
||||
} else if (name == "param_assign") {
|
||||
newNode = new NodeTree<ASTData>(name, ASTData(param_assign));
|
||||
addToScope("~enclosing_scope", scope, newNode);
|
||||
} else if (name == "function_call") {
|
||||
std::string functionCallName = concatSymbolTree(children[0]);
|
||||
newNode = new NodeTree<ASTData>(functionCallName, ASTData(function_call, Symbol(functionCallName, true)));
|
||||
|
||||
@@ -27,6 +27,7 @@ void CGenerator::generateCompSet(std::map<std::string, NodeTree<ASTData>*> ASTs,
|
||||
outputCFile.close();
|
||||
outputHFile.close();
|
||||
|
||||
buildString += linkerString;
|
||||
buildString += "-o " + outputName;
|
||||
std::ofstream outputBuild;
|
||||
outputBuild.open(outputName + "/" + split(outputName, '/').back() + ".sh");
|
||||
@@ -191,7 +192,7 @@ std::pair<std::string, std::string> CGenerator::generateTranslationUnit(std::str
|
||||
parameters += ValueTypeToCType(decChildren[j]->getData().valueType) + " " + generate(decChildren[j], nullptr);
|
||||
nameDecoration += "_" + ValueTypeToCTypeDecoration(decChildren[j]->getData().valueType);
|
||||
}
|
||||
functionPrototypes += scopePrefix(declaration) +
|
||||
functionPrototypes += ((declarationData.symbol.getName() == "main") ? "" : scopePrefix(declaration)) +
|
||||
CifyName(declarationData.symbol.getName() + nameDecoration) +
|
||||
"(" + parameters + "); /*func*/\n";
|
||||
// generate function
|
||||
@@ -295,7 +296,9 @@ std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
||||
parameters += ValueTypeToCType(children[j]->getData().valueType) + " " + generate(children[j], enclosingObject);
|
||||
nameDecoration += "_" + ValueTypeToCTypeDecoration(children[j]->getData().valueType);
|
||||
}
|
||||
output += scopePrefix(from) + CifyName(data.symbol.getName() + nameDecoration) + "(" + parameters + ")\n" + generate(children[children.size()-1], enclosingObject);
|
||||
|
||||
output += ((data.symbol.getName() == "main") ? "" : scopePrefix(from)) +
|
||||
CifyName(data.symbol.getName() + nameDecoration) + "(" + parameters + ")\n" + generate(children[children.size()-1], enclosingObject);
|
||||
return output;
|
||||
}
|
||||
case code_block:
|
||||
@@ -379,7 +382,28 @@ std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
||||
return generate(children[1], enclosingObject);
|
||||
return "";
|
||||
case simple_passthrough:
|
||||
return strSlice(generate(children[0], enclosingObject), 3, -4);
|
||||
{
|
||||
// Stuff is bit more interesting now! XXX
|
||||
std::string pre_passthrough, post_passthrough;
|
||||
// Handle input/output parameters
|
||||
if (children.front()->getDataRef()->type == passthrough_params) {
|
||||
auto optParamAssignLists = children.front()->getChildren();
|
||||
for (auto in_or_out : optParamAssignLists) {
|
||||
for (auto assign : in_or_out->getChildren()) {
|
||||
auto assignChildren = assign->getChildren();
|
||||
if (in_or_out->getDataRef()->type == in_passthrough_params)
|
||||
pre_passthrough += ValueTypeToCType(assignChildren[0]->getDataRef()->valueType) + " " + assignChildren[1]->getDataRef()->symbol.getName() + " = " + generate(assignChildren[0], enclosingObject) + ";\n";
|
||||
else if (in_or_out->getDataRef()->type == out_passthrough_params)
|
||||
post_passthrough += generate(assignChildren[0], enclosingObject) + " = " + assignChildren[1]->getDataRef()->symbol.getName() + ";\n";
|
||||
else
|
||||
linkerString += " " + strSlice(generate(in_or_out, enclosingObject), 1, -2) + " ";
|
||||
}
|
||||
}
|
||||
}
|
||||
// The actual passthrough string is the last child now, as we might
|
||||
// have passthrough_params be the first child
|
||||
return pre_passthrough + strSlice(generate(children.back(), enclosingObject), 3, -4) + post_passthrough;
|
||||
}
|
||||
case function_call:
|
||||
{
|
||||
//NOTE: The first (0th) child of a function call node is the declaration of the function
|
||||
|
||||
@@ -36,7 +36,8 @@ Importer::Importer(Parser* parserIn, std::vector<std::string> includePaths, std:
|
||||
removeSymbols.push_back(Symbol("template", true));
|
||||
removeSymbols.push_back(Symbol("\\|", true));
|
||||
//collapseSymbols.push_back(Symbol("scoped_identifier", false));
|
||||
collapseSymbols.push_back(Symbol("opt_param_assign_list", false));
|
||||
collapseSymbols.push_back(Symbol("opt_param_assign_list", false));
|
||||
collapseSymbols.push_back(Symbol("param_assign_list", false));
|
||||
collapseSymbols.push_back(Symbol("opt_typed_parameter_list", false));
|
||||
collapseSymbols.push_back(Symbol("opt_parameter_list", false));
|
||||
collapseSymbols.push_back(Symbol("opt_import_list", false));
|
||||
|
||||
Reference in New Issue
Block a user