Match statements work with ADTs! (still no object stuff or anything though)

This commit is contained in:
Nathan Braswell
2015-11-14 19:05:28 -05:00
parent ed4ed75449
commit e7a49bf2e5
6 changed files with 78 additions and 5 deletions

View File

@@ -662,6 +662,30 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
newNode = new NodeTree<ASTData>(name, ASTData(statement));
} else if (name == "if_statement") {
newNode = new NodeTree<ASTData>(name, ASTData(if_statement));
} else if (name == "match_statement") {
newNode = new NodeTree<ASTData>(name, ASTData(match_statement));
} else if (name == "case_statement") {
newNode = new NodeTree<ASTData>(name, ASTData(case_statement));
std::string adtOptionStr = concatSymbolTree(getNodes("scoped_identifier", children)[0]);
auto optionDefPoss = scopeLookup(scope, adtOptionStr);
auto optionDef = optionDefPoss[0];
//auto adtDef = optionDef->getDataRef()->scope["~enclosing_scope"][0];
addToScope("~enclosing_scope", scope, newNode);
newNode->addChild(optionDef);
// we have a destructure
auto newIdentifierSymbolNodes = getNodes("identifier", children);
if (newIdentifierSymbolNodes.size()) {
std::string newIdentifierStr = concatSymbolTree(newIdentifierSymbolNodes[0]);
NodeTree<ASTData>* newIdentifier = new NodeTree<ASTData>("identifier", ASTData(identifier, Symbol(newIdentifierStr, true), optionDef->getDataRef()->valueType));
addToScope(newIdentifierStr, newIdentifier, newNode);
addToScope("~enclosing_scope", newNode, newIdentifier);
newNode->addChild(newIdentifier);
}
newNode->addChild(transform(getNode("statement",children), newNode, types, limitToFunction, templateTypeReplacements));
return newNode;
} else if (name == "while_loop") {
newNode = new NodeTree<ASTData>(name, ASTData(while_loop));
} else if (name == "for_loop") {

View File

@@ -526,6 +526,35 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
if (children.size() > 2)
output += " else { " + generate(children[2], enclosingObject, justFuncName, enclosingFunction).oneString() + " }";
return output;
case match_statement:
{
output += "/* match_statement */\n";
CCodeTriple thingToMatch = generate(children[0], enclosingObject, false, enclosingFunction);
output.preValue += thingToMatch.preValue;
output.postValue += thingToMatch.postValue;
for (auto case_stmt : slice(children, 1, -1)) {
auto case_children = case_stmt->getChildren();
std::string option = generate(case_children[0], enclosingObject, false, enclosingFunction).oneString();
output += "/* case " + option + " if " + thingToMatch.value + " */\n";
output += tabs() + "if (" + thingToMatch.value + ".flag == " + option + ") {\n";
tabLevel++;
if (case_children.size() > 2) {
output += tabs() + ValueTypeToCType(case_children[1]->getData().valueType, generate(case_children[1], enclosingObject, false, enclosingFunction).oneString())
+ " = " + thingToMatch.value + "." + option + ";\n";
output += generate(case_children[2], enclosingObject, false, enclosingFunction).oneString();
} else {
output += generate(case_children[1], enclosingObject, false, enclosingFunction).oneString();
}
tabLevel--;
output += "}\n";
}
return output;
}
break;
case case_statement:
output += "/* case_statement */";
throw "case statement isn't actually used, but is generated in match";
break;
case while_loop:
{
// we push on a new vector to hold while stuff that might need a destructor call

View File

@@ -45,7 +45,8 @@ Importer::Importer(Parser* parserIn, std::vector<std::string> includePaths, std:
removeSymbols.push_back(Symbol("adt_nonterm", false));
removeSymbols.push_back(Symbol("template", true));
removeSymbols.push_back(Symbol("\\|", true));
//collapseSymbols.push_back(Symbol("scoped_identifier", false));
//removeSymbols.push_back(Symbol("match", true));
collapseSymbols.push_back(Symbol("case_statement_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));