summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--cpp.cpp122
-rw-r--r--cpp.h6
-rw-r--r--flowgraph/node.cpp4
-rw-r--r--flowgraph/node.h7
-rw-r--r--flowgraph/storage.h1
5 files changed, 136 insertions, 4 deletions
diff --git a/cpp.cpp b/cpp.cpp
index 4ab3b94..b884af4 100644
--- a/cpp.cpp
+++ b/cpp.cpp
@@ -299,11 +299,128 @@ bool CPP::childTypesOfNodeMatch(index_t node_id, const std::vector<std::string>&
return true; // match
}
+bool CPP::childTypesOfChildMatch(index_t index, index_t child_index, const std::vector<std::string>& pattern) const
+{
+ if (index >= m_nodes.size())
+ return false;
+
+ if (child_index >= m_nodes[index].child_ids.size())
+ return false;
+
+ if (!ChildIdIsNode(m_nodes[index].child_ids[child_index]))
+ return false;
+
+ return childTypesOfNodeMatch(m_nodes[index].child_ids[child_index], pattern);
+}
+
+std::shared_ptr<std::any> CPP::getValue(index_t node_id, index_t child_index)
+{
+ size_t num_values_on_top {m_nodes[node_id].child_ids.size()};
+
+ if (num_values_on_top > mValues.size())
+ throw std::runtime_error("ICE: Expected at least "s + std::to_string(num_values_on_top) + " but only have "s + std::to_string(mValues.size()) + " in total"s);
+
+ if (child_index >= num_values_on_top)
+ throw std::runtime_error("ICE: Requested value at index "s + std::to_string(child_index) + " but only have "s + std::to_string(num_values_on_top) + " values on top"s);
+
+ return *(mValues.end() - num_values_on_top + child_index);
+}
+
+std::string CPP::getType(index_t node_id, index_t child_index)
+{
+ if (node_id >= m_nodes.size())
+ throw std::runtime_error("ICE: Requested node at index "s + std::to_string(node_id) + " but only have "s + std::to_string(m_nodes.size()) + " nodes"s);
+
+ if (child_index >= m_nodes[node_id].child_ids.size())
+ throw std::runtime_error("ICE: "s + m_nodes[node_id].type + ": Requested child at index "s + std::to_string(child_index) + " but only have "s + std::to_string(m_nodes[node_id].child_ids.size()) + " childs"s);
+
+ int32_t child_id {m_nodes[node_id].child_ids[child_index]};
+ return typeOfChild(child_id);
+}
+
+std::string CPP::ruleString(index_t node_id)
+{
+ if (node_id >= m_nodes.size())
+ throw std::runtime_error("ICE: Requested node at index "s + std::to_string(node_id) + " but only have "s + std::to_string(m_nodes.size()) + " nodes"s);
+
+ std::string result{m_nodes[node_id].type + ":"};
+
+ for (const auto child_id: m_nodes[node_id].child_ids) {
+ result += " " + typeOfChild(child_id);
+ }
+
+ return result;
+}
std::unordered_map<std::string, std::function<std::shared_ptr<std::any>(index_t)>> CPP::getNodeEvalMap()
{
return {
- { "primary-expression ", [&](index_t index) -> std::shared_ptr<std::any> { return nullptr; }},
+ { "primary-expression", [&](index_t index) -> std::shared_ptr<std::any>
+ {
+ if (childTypesOfNodeMatch(index, {"literal"}))
+ return getValue(index, 0);
+ throw std::runtime_error("ICE: Unsupported childs: "s + ruleString(index)); // TODO
+ }
+ },
+ { "postfix-expression", [&](index_t index) -> std::shared_ptr<std::any>
+ {
+ if (childTypesOfNodeMatch(index, {"primary-expression", ""}) && !getValue(index, 1))
+ return getValue(index, 0);
+ throw std::runtime_error("ICE: Unsupported childs: "s + ruleString(index)); // TODO
+ }
+ },
+ { "unary-expression", [&](index_t index) -> std::shared_ptr<std::any>
+ {
+ if (childTypesOfNodeMatch(index, {"postfix-expression"}))
+ return getValue(index, 0);
+ throw std::runtime_error("ICE: Unsupported childs: "s + ruleString(index)); // TODO
+ }
+ },
+ { "cast-expression", [&](index_t index) -> std::shared_ptr<std::any>
+ {
+ if (childTypesOfNodeMatch(index, {"unary-expression"}))
+ return getValue(index, 0);
+ throw std::runtime_error("ICE: Unsupported childs: "s + ruleString(index)); // TODO
+ }
+ },
+ { "pm-expression", [&](index_t index) -> std::shared_ptr<std::any>
+ {
+ if (childTypesOfNodeMatch(index, {"cast-expression", ""}) && !getValue(index, 1))
+ return getValue(index, 0);
+ throw std::runtime_error("ICE: Unsupported childs: "s + ruleString(index)); // TODO
+ }
+ },
+ { "multiplicative-expression", [&](index_t index) -> std::shared_ptr<std::any>
+ {
+ if (childTypesOfNodeMatch(index, {"pm-expression", ""}) && !getValue(index, 1))
+ return getValue(index, 0);
+ throw std::runtime_error("ICE: Unsupported childs: "s + ruleString(index)); // TODO
+ }
+ },
+ { "additive-expression", [&](index_t index) -> std::shared_ptr<std::any>
+ {
+ if (childTypesOfNodeMatch(index, {"multiplicative-expression", "additive-expression-EXT"}) && childTypesOfChildMatch(index, 1, {"+", "", ""})) {
+ FlowGraph::LocalScope scope;
+ FlowGraph::Data destination{FlowGraph::MakeTemporaryInt(scope)};
+ auto value0 {getValue(index, 0)};
+ auto value1 {getValue(index, 1)};
+
+ //return std::make_shared<FlowGraph::BinaryOperation>(FlowGraph::BinaryOperationType::Add, destination, value0, value1);
+ return getValue(index, 0); // TODO
+ }
+ throw std::runtime_error("ICE: Unsupported childs: "s + ruleString(index)); // TODO
+ }
+ },
+ { "additive-expression-EXT", [&](index_t index) -> std::shared_ptr<std::any>
+ {
+ if (childTypesOfNodeMatch(index, {"+", "multiplicative-expression", ""}) && !getValue(index, 2)) {
+ return getValue(index, 1);
+ } else if (childTypesOfNodeMatch(index, {})) {
+ return nullptr;
+ }
+ throw std::runtime_error("ICE: Unsupported childs: "s + ruleString(index)); // TODO
+ }
+ },
};
}
@@ -320,6 +437,8 @@ void CPP::getValueOfNode(index_t index)
std::shared_ptr<std::any> result {nullptr};
if (function_it != node_eval_map.end()) {
result = function_it->second(index);
+ } else {
+ //TODO: throw std::runtime_error("ICE: Node type not implemented: "s + m_nodes[index].type);
}
mValues.resize(mValues.size() - num_childs);
@@ -332,6 +451,7 @@ void CPP::getValueOfToken(index_t index)
{
// TODO: also support the other tokens ...
if (m_tokens[index].type == "literal") {
+ // TODO: also support other types, different from Int
FlowGraph::Data data{FlowGraph::MakeConstantInt(stoi(m_tokens[index].value))};
mValues.push_back(std::make_shared<std::any>(data));
} else {
diff --git a/cpp.h b/cpp.h
index 2594a4c..abd7e16 100644
--- a/cpp.h
+++ b/cpp.h
@@ -51,9 +51,13 @@ private:
std::string locationOfNode(index_t node_index) const; ///< Empty if no location available
void compileError(index_t node_id, const std::string& msg) const;
std::string typeOfChild(int32_t child_id) const;
- bool childTypesOfNodeMatch(index_t, const std::vector<std::string>& pattern) const; ///< returns true iff specified type list matches; "" -> don't care
+ bool childTypesOfNodeMatch(index_t index, const std::vector<std::string>& pattern) const; ///< returns true iff specified type list matches; "" -> don't care
+ bool childTypesOfChildMatch(index_t index, index_t child_index, const std::vector<std::string>& pattern) const; ///< returns true iff specified type list matches in specified child; "" -> don't care
std::deque<std::shared_ptr<std::any>> mValues; // values stack during phase 7.c
+ std::shared_ptr<std::any> getValue(index_t node_id, index_t child_id);
+ std::string getType(index_t node_id, index_t child_index);
+ std::string ruleString(index_t node_id);
std::unordered_map<std::string, std::function<std::shared_ptr<std::any>(index_t)>> getNodeEvalMap();
std::unordered_map<std::string, std::function<std::shared_ptr<std::any>(index_t)>> node_eval_map;
diff --git a/flowgraph/node.cpp b/flowgraph/node.cpp
index f81a7e1..81217ce 100644
--- a/flowgraph/node.cpp
+++ b/flowgraph/node.cpp
@@ -24,3 +24,7 @@ Data FlowGraph::MakeLocalSize(const std::string& name)
return Data(DataType::Size, std::make_shared<LocalStorage>(name));
}
+Data FlowGraph::MakeTemporaryInt(FlowGraph::LocalScope& scope)
+{
+ return Data(DataType::Int, std::make_shared<TemporaryStorage>(scope));
+}
diff --git a/flowgraph/node.h b/flowgraph/node.h
index aa9d333..c1b7380 100644
--- a/flowgraph/node.h
+++ b/flowgraph/node.h
@@ -41,6 +41,7 @@ namespace FlowGraph {
Data MakeConstantInt(int i);
Data MakeLocalPointer(const std::string& name);
Data MakeLocalSize(const std::string& name);
+ Data MakeTemporaryInt(LocalScope& scope);
class MemCopy: public Node
{
@@ -117,8 +118,9 @@ namespace FlowGraph {
class UnaryOperation: public Node
{
public:
- UnaryOperation(Data& destination, Data& source): m_destination(destination), m_source(source) {}
+ UnaryOperation(UnaryOperationType type, Data& destination, Data& source): m_type(type), m_destination(destination), m_source(source) {}
private:
+ UnaryOperationType m_type;
Data m_destination;
Data m_source;
};
@@ -143,8 +145,9 @@ namespace FlowGraph {
class BinaryOperation: public Node
{
public:
- BinaryOperation(Data& destination, Data& source0, Data& source1): m_destination(destination), m_source0(source0), m_source1(source1) {}
+ BinaryOperation(BinaryOperationType type, Data& destination, Data& source0, Data& source1): m_type(type), m_destination(destination), m_source0(source0), m_source1(source1) {}
private:
+ BinaryOperationType m_type;
Data m_destination;
Data m_source0;
Data m_source1;
diff --git a/flowgraph/storage.h b/flowgraph/storage.h
index efd7d52..28aae1e 100644
--- a/flowgraph/storage.h
+++ b/flowgraph/storage.h
@@ -50,6 +50,7 @@ namespace FlowGraph {
class LocalScope
{
public:
+ LocalScope() = default;
size_t getNewIndex() { return m_index++; }
private:
size_t m_index{ 0 };