diff options
author | Roland Reichwein <mail@reichwein.it> | 2020-11-23 22:01:49 +0100 |
---|---|---|
committer | Roland Reichwein <mail@reichwein.it> | 2020-11-23 22:01:49 +0100 |
commit | 61db05a4127790da3219fccce87c34aa890d1d08 (patch) | |
tree | f88ca783621c9a44fdb1fe605d81a0f4e54eccce /cpp.cpp | |
parent | ff69e8cab318101843cd8b49a0cb04df9763e10f (diff) |
Add Subtract, generalized binary operations
Diffstat (limited to 'cpp.cpp')
-rw-r--r-- | cpp.cpp | 118 |
1 files changed, 50 insertions, 68 deletions
@@ -354,6 +354,8 @@ std::string CPP::ruleString(index_t node_id) return result; } +namespace { + // Promote last op of specified graph if appropriate (i.e. if not yet big enough) void promoteLastOp(FlowGraph::Graph& graph, FlowGraph::DataType targetType) { @@ -382,6 +384,52 @@ void promoteLastOps(FlowGraph::Graph& graph0, FlowGraph::Graph& graph1) promoteLastOp(graph1, targetType); } +std::unordered_map<std::string, FlowGraph::BinaryOperationType> binaryOperationsMap { + {"+", FlowGraph::BinaryOperationType::Add}, + {"-", FlowGraph::BinaryOperationType::Subtract}, + {"*", FlowGraph::BinaryOperationType::Multiply}, + {"/", FlowGraph::BinaryOperationType::Divide}, + {"%", FlowGraph::BinaryOperationType::Modulo}, +}; + +} // namespace + +FlowGraph::Graph CPP::BinaryOperation(index_t index) +{ + if (getValue(index, 0).type() != typeid(FlowGraph::Graph)) + throw std::runtime_error("ICE: 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: Bad data type for argument 3: "s + demangle(getValue(index, 2).type())); + + FlowGraph::Graph value0{std::any_cast<FlowGraph::Graph>(getValue(index, 0))}; + 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::MakeTemporary(result.scope(), lastOp0->destination().type())}; + + std::string typeString{getType(index, 1)}; + auto it{binaryOperationsMap.find(typeString)}; + FlowGraph::BinaryOperationType type{}; + if (it != binaryOperationsMap.end()) { + type = it->second; + } else { + throw std::runtime_error("ICE: Unknown operation: "s + typeString); + } + + std::shared_ptr<FlowGraph::Node> node {std::make_shared<FlowGraph::BinaryOperation>(type, + destination, + lastOp0->destination(), lastOp1->destination())}; + result.append(node); + return result; +} + std::unordered_map<std::string, std::function<std::any(index_t)>> CPP::getNodeEvalMap() { return { @@ -425,41 +473,7 @@ std::unordered_map<std::string, std::function<std::any(index_t)>> CPP::getNodeEv { "multiplicative-expression", [&](index_t index) -> std::any { if (childTypesOfNodeMatch(index, {"multiplicative-expression", "", "pm-expression"})) { - if (getValue(index, 0).type() != typeid(FlowGraph::Graph)) - throw std::runtime_error("ICE: multiplicative-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: 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))}; - 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::MakeTemporary(result.scope(), lastOp0->destination().type())}; - - FlowGraph::BinaryOperationType type{}; - if (getType(index, 1) == "*") - type = FlowGraph::BinaryOperationType::Multiply; - else if (getType(index, 1) == "/") - type = FlowGraph::BinaryOperationType::Divide; - else if (getType(index, 1) == "%") - type = FlowGraph::BinaryOperationType::Modulo; - else - throw std::runtime_error("ICE: multiplicative-expression: Unknown operand: "s + getType(index, 1)); - - std::shared_ptr<FlowGraph::Node> node {std::make_shared<FlowGraph::BinaryOperation>(type, - destination, - lastOp0->destination(), lastOp1->destination())}; - - result.append(node); - - return result; + return BinaryOperation(index); } if (childTypesOfNodeMatch(index, {"pm-expression"})) return getValue(index, 0); @@ -469,39 +483,7 @@ std::unordered_map<std::string, std::function<std::any(index_t)>> CPP::getNodeEv { "additive-expression", [&](index_t index) -> std::any { 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))}; - 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::MakeTemporary(result.scope(), lastOp0->destination().type())}; - - 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())}; - - result.append(node); - - return result; + return BinaryOperation(index); } if (childTypesOfNodeMatch(index, {"multiplicative-expression"})) return getValue(index, 0); |