From 61db05a4127790da3219fccce87c34aa890d1d08 Mon Sep 17 00:00:00 2001 From: Roland Reichwein Date: Mon, 23 Nov 2020 22:01:49 +0100 Subject: Add Subtract, generalized binary operations --- cpp.cpp | 118 +++++++++++++++++++++++++++------------------------------------- 1 file changed, 50 insertions(+), 68 deletions(-) (limited to 'cpp.cpp') diff --git a/cpp.cpp b/cpp.cpp index 5dbf5e6..cefd5fd 100644 --- a/cpp.cpp +++ b/cpp.cpp @@ -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 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(getValue(index, 0))}; + FlowGraph::Graph value1{std::any_cast(getValue(index, 2))}; + + promoteLastOps(value0, value1); + + std::shared_ptr lastOp0{value0.lastOp()}; + std::shared_ptr 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 node {std::make_shared(type, + destination, + lastOp0->destination(), lastOp1->destination())}; + result.append(node); + return result; +} + std::unordered_map> CPP::getNodeEvalMap() { return { @@ -425,41 +473,7 @@ std::unordered_map> 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(getValue(index, 0))}; - FlowGraph::Graph value1{std::any_cast(getValue(index, 2))}; - - promoteLastOps(value0, value1); - - std::shared_ptr lastOp0{value0.lastOp()}; - std::shared_ptr 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 node {std::make_shared(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> 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(getValue(index, 0))}; - FlowGraph::Graph value1{std::any_cast(getValue(index, 2))}; - - promoteLastOps(value0, value1); - - std::shared_ptr lastOp0{value0.lastOp()}; - std::shared_ptr 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 node {std::make_shared(type, - destination, - lastOp0->destination(), lastOp1->destination())}; - - result.append(node); - - return result; + return BinaryOperation(index); } if (childTypesOfNodeMatch(index, {"multiplicative-expression"})) return getValue(index, 0); -- cgit v1.2.3