Match statements work with ADTs! (still no object stuff or anything though)
This commit is contained in:
@@ -16,9 +16,9 @@ class Type;
|
|||||||
|
|
||||||
enum ASTType {undef, translation_unit, interpreter_directive, import, identifier, type_def, adt_def,
|
enum ASTType {undef, translation_unit, interpreter_directive, 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, while_loop, for_loop, return_statement, break_statement, continue_statement, defer_statement,
|
if_statement, match_statement, case_statement, while_loop, for_loop, return_statement, break_statement,
|
||||||
assignment_statement, declaration_statement, if_comp, simple_passthrough, passthrough_params,
|
continue_statement, defer_statement, assignment_statement, declaration_statement, if_comp, simple_passthrough,
|
||||||
in_passthrough_params, out_passthrough_params, opt_string, param_assign, function_call, value};
|
passthrough_params, in_passthrough_params, out_passthrough_params, opt_string, param_assign, function_call, value};
|
||||||
|
|
||||||
class ASTData {
|
class ASTData {
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -95,6 +95,10 @@ adt_option = identifier | identifier WS dec_type ;
|
|||||||
|
|
||||||
if_statement = "if" WS "\(" WS boolean_expression WS "\)" WS statement | "if" WS "\(" WS boolean_expression WS "\)" WS statement WS "else" WS statement ;
|
if_statement = "if" WS "\(" WS boolean_expression WS "\)" WS statement | "if" WS "\(" WS boolean_expression WS "\)" WS statement WS "else" WS statement ;
|
||||||
|
|
||||||
|
match_statement = "match" WS "\(" WS boolean_expression WS "\)" WS "{" WS case_statement_list WS "}" ;
|
||||||
|
case_statement_list = case_statement WS case_statement_list | case_statement ;
|
||||||
|
case_statement = scoped_identifier WS "\(" WS identifier WS "\)" WS statement | scoped_identifier WS "\(" WS "\)" WS statement ;
|
||||||
|
|
||||||
while_loop = "while" WS boolean_expression WS statement ;
|
while_loop = "while" WS boolean_expression WS statement ;
|
||||||
|
|
||||||
for_loop = "for" WS "\(" WS statement WS boolean_expression line_end WS statement WS "\)" WS statement ;
|
for_loop = "for" WS "\(" WS statement WS boolean_expression line_end WS statement WS "\)" WS statement ;
|
||||||
@@ -104,7 +108,7 @@ return_statement = "return" | "return" WS boolean_expression ;
|
|||||||
code_block = "{" WS statement_list WS "}" | "{" WS "}" ;
|
code_block = "{" WS statement_list WS "}" | "{" WS "}" ;
|
||||||
|
|
||||||
statement_list = statement_list WS statement | statement ;
|
statement_list = statement_list WS statement | statement ;
|
||||||
statement = if_statement | while_loop | for_loop | return_statement line_end | boolean_expression line_end | assignment_statement line_end | declaration_statement line_end | code_block | if_comp | simple_passthrough | break_statement | continue_statement | defer_statement ;
|
statement = if_statement | match_statement | while_loop | for_loop | return_statement line_end | boolean_expression line_end | assignment_statement line_end | declaration_statement line_end | code_block | if_comp | simple_passthrough | break_statement | continue_statement | defer_statement ;
|
||||||
break_statement = "break" ;
|
break_statement = "break" ;
|
||||||
continue_statement = "continue" ;
|
continue_statement = "continue" ;
|
||||||
defer_statement = "defer" WS statement ;
|
defer_statement = "defer" WS statement ;
|
||||||
|
|||||||
@@ -662,6 +662,30 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
newNode = new NodeTree<ASTData>(name, ASTData(statement));
|
newNode = new NodeTree<ASTData>(name, ASTData(statement));
|
||||||
} else if (name == "if_statement") {
|
} else if (name == "if_statement") {
|
||||||
newNode = new NodeTree<ASTData>(name, ASTData(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") {
|
} else if (name == "while_loop") {
|
||||||
newNode = new NodeTree<ASTData>(name, ASTData(while_loop));
|
newNode = new NodeTree<ASTData>(name, ASTData(while_loop));
|
||||||
} else if (name == "for_loop") {
|
} else if (name == "for_loop") {
|
||||||
|
|||||||
@@ -526,6 +526,35 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
|||||||
if (children.size() > 2)
|
if (children.size() > 2)
|
||||||
output += " else { " + generate(children[2], enclosingObject, justFuncName, enclosingFunction).oneString() + " }";
|
output += " else { " + generate(children[2], enclosingObject, justFuncName, enclosingFunction).oneString() + " }";
|
||||||
return output;
|
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:
|
case while_loop:
|
||||||
{
|
{
|
||||||
// we push on a new vector to hold while stuff that might need a destructor call
|
// we push on a new vector to hold while stuff that might need a destructor call
|
||||||
|
|||||||
@@ -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("adt_nonterm", false));
|
||||||
removeSymbols.push_back(Symbol("template", true));
|
removeSymbols.push_back(Symbol("template", true));
|
||||||
removeSymbols.push_back(Symbol("\\|", 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("opt_param_assign_list", false));
|
||||||
collapseSymbols.push_back(Symbol("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_typed_parameter_list", false));
|
||||||
|
|||||||
@@ -53,6 +53,21 @@ fun main():int {
|
|||||||
println("equality false works!")
|
println("equality false works!")
|
||||||
else
|
else
|
||||||
println("equality false fails!")
|
println("equality false fails!")
|
||||||
|
|
||||||
|
match (maybe_int::an_int(11)) {
|
||||||
|
maybe_int::an_int(the_int) {
|
||||||
|
print("matched an int:")
|
||||||
|
print(the_int)
|
||||||
|
println(" correctly!")
|
||||||
|
}
|
||||||
|
maybe_int::no_int() {
|
||||||
|
println("matched no int incorrectly!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match (maybe_int::no_int()) {
|
||||||
|
maybe_int::an_int(the_int) println("matched an int incorrectly!")
|
||||||
|
maybe_int::no_int() println("matched no int correctly!")
|
||||||
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user