From ff69e8cab318101843cd8b49a0cb04df9763e10f Mon Sep 17 00:00:00 2001 From: Roland Reichwein Date: Sun, 22 Nov 2020 22:14:23 +0100 Subject: Generalize Add / Mul, Integer promotion, tests --- cpp.cpp | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 50 insertions(+), 10 deletions(-) (limited to 'cpp.cpp') 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 node {std::make_shared(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> CPP::getNodeEvalMap() { return { @@ -403,15 +431,17 @@ std::unordered_map> 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(getValue(index, 0))}; - std::shared_ptr lastOp0{value0.lastOp()}; - 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::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> 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(getValue(index, 0))}; - std::shared_ptr lastOp0{value0.lastOp()}; - 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::MakeTemporaryInt(result.scope())}; + FlowGraph::Data destination{FlowGraph::MakeTemporary(result.scope(), lastOp0->destination().type())}; - std::shared_ptr node {std::make_shared(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 node {std::make_shared(type, destination, lastOp0->destination(), lastOp1->destination())}; @@ -465,7 +505,7 @@ std::unordered_map> 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 -- cgit v1.2.3