diff options
Diffstat (limited to 'cpp.cpp')
-rw-r--r-- | cpp.cpp | 60 |
1 files changed, 50 insertions, 10 deletions
@@ -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 |