summaryrefslogtreecommitdiffhomepage
path: root/cpp.cpp
diff options
context:
space:
mode:
authorRoland Reichwein <mail@reichwein.it>2020-11-22 22:14:23 +0100
committerRoland Reichwein <mail@reichwein.it>2020-11-22 22:14:23 +0100
commitff69e8cab318101843cd8b49a0cb04df9763e10f (patch)
tree58778d0ba28264880df8bdf6bfe45766939c3af9 /cpp.cpp
parentad3fd947005400c90f41baa4416a27d94b1bc157 (diff)
Generalize Add / Mul, Integer promotion, tests
Diffstat (limited to 'cpp.cpp')
-rw-r--r--cpp.cpp60
1 files changed, 50 insertions, 10 deletions
diff --git a/cpp.cpp b/cpp.cpp
index 61fdc0e..5dbf5e6 100644
--- a/cpp.cpp
+++ b/cpp.cpp
@@ -354,6 +354,34 @@ std::string CPP::ruleString(index_t node_id)
return result;
}
+// Promote last op of specified graph if appropriate (i.e. if not yet big enough)
+void promoteLastOp(FlowGraph::Graph& graph, FlowGraph::DataType targetType)
+{
+ FlowGraph::DataType sourceType {graph.lastOp()->destination().type()};
+
+ if (targetType != sourceType) {
+ FlowGraph::Data temporary {FlowGraph::MakeTemporary(graph.scope(), targetType)};
+ std::shared_ptr<FlowGraph::Node> node {std::make_shared<FlowGraph::UnaryOperation>(FlowGraph::UnaryOperationType::Resize,
+ temporary,
+ graph.lastOp()->destination())};
+ graph.append(node);
+ }
+}
+
+// Promote last ops of specified graphs until width is equal
+void promoteLastOps(FlowGraph::Graph& graph0, FlowGraph::Graph& graph1)
+{
+ // Find target type
+ FlowGraph::DataType targetType = FlowGraph::DataType::Int;
+ if (graph0.lastOp()->destination().type() == FlowGraph::DataType::LongLong ||
+ graph1.lastOp()->destination().type() == FlowGraph::DataType::LongLong)
+ targetType = FlowGraph::DataType::LongLong; // TODO: Support unsigned variants
+
+ // promote both graph results to target types
+ promoteLastOp(graph0, targetType);
+ promoteLastOp(graph1, targetType);
+}
+
std::unordered_map<std::string, std::function<std::any(index_t)>> CPP::getNodeEvalMap()
{
return {
@@ -403,15 +431,17 @@ std::unordered_map<std::string, std::function<std::any(index_t)>> CPP::getNodeEv
throw std::runtime_error("ICE: multiplicative-expression: Bad data type for argument 3: "s + demangle(getValue(index, 2).type()));
FlowGraph::Graph value0{std::any_cast<FlowGraph::Graph>(getValue(index, 0))};
- std::shared_ptr<FlowGraph::Node> lastOp0{value0.lastOp()};
-
FlowGraph::Graph value1{std::any_cast<FlowGraph::Graph>(getValue(index, 2))};
+
+ promoteLastOps(value0, value1);
+
+ std::shared_ptr<FlowGraph::Node> lastOp0{value0.lastOp()};
std::shared_ptr<FlowGraph::Node> lastOp1{value1.lastOp()};
FlowGraph::Graph result{value0};
result.append(value1);
- FlowGraph::Data destination{FlowGraph::MakeTemporaryInt(result.scope())};
+ FlowGraph::Data destination{FlowGraph::MakeTemporary(result.scope(), lastOp0->destination().type())};
FlowGraph::BinaryOperationType type{};
if (getType(index, 1) == "*")
@@ -433,29 +463,39 @@ std::unordered_map<std::string, std::function<std::any(index_t)>> CPP::getNodeEv
}
if (childTypesOfNodeMatch(index, {"pm-expression"}))
return getValue(index, 0);
- throw std::runtime_error("ICE: Unsupported childs: "s + ruleString(index)); // TODO
+ throw std::runtime_error("ICE: Unsupported childs: "s + ruleString(index));
}
},
{ "additive-expression", [&](index_t index) -> std::any
{
- if (childTypesOfNodeMatch(index, {"additive-expression", "+", "multiplicative-expression"})) {
+ if (childTypesOfNodeMatch(index, {"additive-expression", "", "multiplicative-expression"})) {
if (getValue(index, 0).type() != typeid(FlowGraph::Graph))
throw std::runtime_error("ICE: additive-expression: Bad data type for argument 1: "s + demangle(getValue(index, 0).type()));
if (getValue(index, 2).type() != typeid(FlowGraph::Graph))
throw std::runtime_error("ICE: additive-expression: Bad data type for argument 3: "s + demangle(getValue(index, 2).type()));
FlowGraph::Graph value0{std::any_cast<FlowGraph::Graph>(getValue(index, 0))};
- std::shared_ptr<FlowGraph::Node> lastOp0{value0.lastOp()};
-
FlowGraph::Graph value1{std::any_cast<FlowGraph::Graph>(getValue(index, 2))};
+
+ promoteLastOps(value0, value1);
+
+ std::shared_ptr<FlowGraph::Node> lastOp0{value0.lastOp()};
std::shared_ptr<FlowGraph::Node> lastOp1{value1.lastOp()};
FlowGraph::Graph result{value0};
result.append(value1);
- FlowGraph::Data destination{FlowGraph::MakeTemporaryInt(result.scope())};
+ FlowGraph::Data destination{FlowGraph::MakeTemporary(result.scope(), lastOp0->destination().type())};
- std::shared_ptr<FlowGraph::Node> node {std::make_shared<FlowGraph::BinaryOperation>(FlowGraph::BinaryOperationType::Add,
+ FlowGraph::BinaryOperationType type{};
+ if (getType(index, 1) == "+")
+ type = FlowGraph::BinaryOperationType::Add;
+ else if (getType(index, 1) == "-")
+ type = FlowGraph::BinaryOperationType::Subtract;
+ else
+ throw std::runtime_error("ICE: additive-expression: Unknown operand: "s + getType(index, 1));
+
+ std::shared_ptr<FlowGraph::Node> node {std::make_shared<FlowGraph::BinaryOperation>(type,
destination,
lastOp0->destination(), lastOp1->destination())};
@@ -465,7 +505,7 @@ std::unordered_map<std::string, std::function<std::any(index_t)>> CPP::getNodeEv
}
if (childTypesOfNodeMatch(index, {"multiplicative-expression"}))
return getValue(index, 0);
- throw std::runtime_error("ICE: Unsupported childs: "s + ruleString(index)); // TODO
+ throw std::runtime_error("ICE: Unsupported childs: "s + ruleString(index));
}
},
{ "shift-expression", [&](index_t index) -> std::any