diff options
| -rw-r--r-- | TODO | 2 | ||||
| -rw-r--r-- | asm/intel64/encode.cpp | 2 | ||||
| -rw-r--r-- | cpp.cpp | 60 | ||||
| -rw-r--r-- | flowgraph/node.cpp | 7 | ||||
| -rw-r--r-- | flowgraph/node.h | 3 | ||||
| -rw-r--r-- | systemtest/mcc-execute.tests/exitcodes.exp | 3 | ||||
| -rw-r--r-- | systemtest/mcc-execute.tests/test-parentheses-left.cpp | 1 | ||||
| -rw-r--r-- | systemtest/mcc-execute.tests/test-parentheses-right.cpp | 1 | ||||
| -rw-r--r-- | systemtest/mcc-execute.tests/test-parentheses.cpp | 1 | 
9 files changed, 69 insertions, 11 deletions
| @@ -1,3 +1,3 @@ -Fix stack +encode.cpp: Sub  grammer.cpp: match() : return point of match error ("Compile error") diff --git a/asm/intel64/encode.cpp b/asm/intel64/encode.cpp index 1cc1a6d..6118743 100644 --- a/asm/intel64/encode.cpp +++ b/asm/intel64/encode.cpp @@ -175,6 +175,8 @@ void Asm::toMachineCode(const FlowGraph::Graph& graph, Segment& segment)       segment.push_back(makeLoadValue(operands[1], graph));       segment.append(parseAsm("neg eax"));       segment.push_back(makeStoreValue(operands[0], graph)); +    } else if (op.type() == FlowGraph::UnaryOperationType::Resize) { +     throw std::runtime_error("ICE: Asm: Unsupported unary operation type: Resize"s);      } else       throw std::runtime_error("ICE: Asm: Unsupported unary operation type: "s + std::to_string(static_cast<int>(op.type()))); @@ -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 diff --git a/flowgraph/node.cpp b/flowgraph/node.cpp index cb7677a..27310a9 100644 --- a/flowgraph/node.cpp +++ b/flowgraph/node.cpp @@ -16,6 +16,13 @@ FlowGraph::Data& Node::destination()   return mOperands[0];  } +Data FlowGraph::MakeTemporary(std::shared_ptr<FlowGraph::LocalScope> scope, DataType type) +{ + Data data{type, std::make_shared<TemporaryStorage>()}; + scope->push_back(std::make_shared<Data>(data)); + return data; +} +  // 4 byte for now  Data FlowGraph::MakeConstantInt(int i)  { diff --git a/flowgraph/node.h b/flowgraph/node.h index 34e937b..f653096 100644 --- a/flowgraph/node.h +++ b/flowgraph/node.h @@ -47,6 +47,8 @@ namespace FlowGraph {    {}   }; + Data MakeTemporary(std::shared_ptr<LocalScope> scope, DataType type); +    Data MakeConstantInt(int i);   Data MakeLocalInt(std::shared_ptr<FlowGraph::LocalScope> scope, const std::string& name);   Data MakeLocalPointer(std::shared_ptr<FlowGraph::LocalScope> scope, const std::string& name); @@ -120,6 +122,7 @@ namespace FlowGraph {    LogicalNot,    BitwiseNot,    Minus, +  Resize, // Promote / narrow a value   };   class UnaryOperation: public Node diff --git a/systemtest/mcc-execute.tests/exitcodes.exp b/systemtest/mcc-execute.tests/exitcodes.exp index 0480be8..dc4d377 100644 --- a/systemtest/mcc-execute.tests/exitcodes.exp +++ b/systemtest/mcc-execute.tests/exitcodes.exp @@ -5,4 +5,7 @@ runtest_exit_code "Addition" "systemtest/mcc-execute.tests/test-addition" 3  runtest_exit_code "Multiplication" "systemtest/mcc-execute.tests/test-multiplication" 6  runtest_exit_code "Division" "systemtest/mcc-execute.tests/test-division" 2  runtest_exit_code "Modulo" "systemtest/mcc-execute.tests/test-modulo" 1 +runtest_exit_code "Parentheses Tree" "systemtest/mcc-execute.tests/test-parentheses" 36 +runtest_exit_code "Parentheses Left" "systemtest/mcc-execute.tests/test-parentheses-left" 36 +runtest_exit_code "Parentheses Right" "systemtest/mcc-execute.tests/test-parentheses-right" 36 diff --git a/systemtest/mcc-execute.tests/test-parentheses-left.cpp b/systemtest/mcc-execute.tests/test-parentheses-left.cpp new file mode 100644 index 0000000..2ebc713 --- /dev/null +++ b/systemtest/mcc-execute.tests/test-parentheses-left.cpp @@ -0,0 +1 @@ +int main() { return (((((((1 + 2) + 3) + 4) + 5) + 6) + 7) + 8); } diff --git a/systemtest/mcc-execute.tests/test-parentheses-right.cpp b/systemtest/mcc-execute.tests/test-parentheses-right.cpp new file mode 100644 index 0000000..662af95 --- /dev/null +++ b/systemtest/mcc-execute.tests/test-parentheses-right.cpp @@ -0,0 +1 @@ +int main() { return (1 + (2 + (3 + (4 + (5 + (6 + (7 + 8))))))); } diff --git a/systemtest/mcc-execute.tests/test-parentheses.cpp b/systemtest/mcc-execute.tests/test-parentheses.cpp new file mode 100644 index 0000000..fca52e9 --- /dev/null +++ b/systemtest/mcc-execute.tests/test-parentheses.cpp @@ -0,0 +1 @@ +int main() { return ((1 + 2) + (3 + 4)) + ((5 + 6) + (7 + 8)); } | 
