diff options
author | Roland Reichwein <mail@reichwein.it> | 2020-11-06 18:20:34 +0100 |
---|---|---|
committer | Roland Reichwein <mail@reichwein.it> | 2020-11-06 18:20:34 +0100 |
commit | 71c7fd62f8b5257b82cf32b0f747fcf313fcc617 (patch) | |
tree | 6f014b14d08080459a04a965912c62605d9015ca | |
parent | 62aafc5c9273cb0b7a91bf2e4dee1ac2d3658bb3 (diff) |
Prepare Token/Node handling
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | asm/operators.h | 2 | ||||
-rw-r--r-- | cpp.cpp | 55 | ||||
-rw-r--r-- | cpp.h | 11 | ||||
-rw-r--r-- | flowgraph/data.h | 2 | ||||
-rw-r--r-- | flowgraph/node.cpp | 21 | ||||
-rw-r--r-- | flowgraph/node.h | 5 | ||||
-rw-r--r-- | flowgraph/storage.h | 5 | ||||
-rw-r--r-- | grammer.h | 4 |
9 files changed, 82 insertions, 29 deletions
@@ -98,7 +98,9 @@ test-$(PROJECTNAME): $(TESTSRC:.cpp=.o) mcc: $(SRC:.cpp=.o) $(CXX) $(CXXFLAGS) $^ $(LIBS) -o $@ -dep: $(TESTSRC:.cpp=.d) mcc.d +dep: + -rm -f $(TESTSRC:.cpp=.d) mcc.d + $(MAKE) $(TESTSRC:.cpp=.d) mcc.d %.d: %.cpp $(CXX) $(CXXFLAGS) $(CXXTESTFLAGS) -MM -MP -MF $@ -c $< @@ -123,6 +125,6 @@ zip: clean zip -r ../$(PROJECTNAME).zip * ls -l ../$(PROJECTNAME).zip -.PHONY: clean all zip +.PHONY: clean all zip dep -include $(wildcard $(SRC:.cpp=.d)) diff --git a/asm/operators.h b/asm/operators.h index 93dc15e..741ec72 100644 --- a/asm/operators.h +++ b/asm/operators.h @@ -1,3 +1,5 @@ +// Operating on data + #pragma once #include <cstdint> @@ -1,5 +1,6 @@ #include "cpp.h" +#include "flowgraph/node.h" #include "bnf.h" #include "cppbnf.h" #include "debug.h" @@ -294,25 +295,46 @@ bool CPP::childTypesOfNodeMatch(index_t node_id, const std::vector<std::string>& return true; // match } -void CPP::trDeclaration(index_t node_id) +//std::unordered_map<std::string, std::function<>> + +// precondition: stack contains child values c1, ..., cn on top -> to be popped +// postcondition: stack contains value on top -> to be pushed +void CPP::getValueOfNode(index_t index) { - std::cout << "DEBUG" << std::endl; + size_t num_childs {m_nodes[index].child_ids.size()}; + + if (mValues.size() < num_childs) + throw std::runtime_error("Expected num_childs elements on Values stack at "s + locationOfNode(index)); + + std::shared_ptr<std::any> result {nullptr}; + + mValues.resize(mValues.size() - num_childs); + + mValues.push_back(result); } -void CPP::trTranslationUnit(index_t node_id) +// pushes result onto stack +void CPP::getValueOfToken(index_t index) { - if (childTypesOfNodeMatch(node_id, {"declaration-seq"})) { - // resolve sequence - do { - node_id = m_nodes[node_id].child_ids[0]; - if (childTypesOfNodeMatch(node_id, {"declaration"})) { - trDeclaration(m_nodes[node_id].child_ids[0]); - return; - } - } while (childTypesOfNodeMatch(node_id, {"declaration-seq", "declaration"})); - compileError(node_id, "ICE: bad declaration-seq"); - } else - compileError(node_id, "declaration-seq expected"); + if (m_tokens[index].type == "literal") { + FlowGraph::Data data{FlowGraph::MakeConstantInt(stoi(m_tokens[index].value))}; + mValues.push_back(std::make_shared<std::any>(data)); + } else { + mValues.push_back(std::make_shared<std::any>(nullptr)); + } +} + +void CPP::visitRecursive(index_t node_id) +{ + const auto& childs {m_nodes[node_id].child_ids}; + for (const auto child: childs) { + if (ChildIdIsNode(child)) { + visitRecursive(child); + } else { + getValueOfToken(TokenIdFromChildId(child)); + } + } + getValueOfNode(node_id); } // Phase 7.c: Translate @@ -321,7 +343,8 @@ void CPP::translate() if (m_nodes.size() == 0) throw std::runtime_error("ICE: Tree is empty"); - trTranslationUnit(0); + // TODO: this could be implemented iteratively, via a stack? + visitRecursive(0); } // Phase 8: Instantiate objects @@ -3,6 +3,9 @@ #include "grammer.h" #include "minicc.h" +#include <any> +#include <deque> +#include <memory> #include <vector> struct CPPContext { @@ -43,8 +46,6 @@ private: std::vector<Token> m_tokens; // result of phase 7.a std::vector<Gram::TreeNode> m_nodes; // result of phase 7.b - CPPContext m_cpp_context; - std::string valueOfNode(index_t node_index) const; std::string typeOfNode(index_t node_index) const; std::string locationOfNode(index_t node_index) const; ///< Empty if no location available @@ -52,7 +53,9 @@ private: 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 - void trTranslationUnit(index_t node_id); - void trDeclaration(index_t node_id); + std::deque<std::shared_ptr<std::any>> mValues; + void getValueOfToken(index_t index); + void getValueOfNode(index_t index); + void visitRecursive(index_t node_id); }; diff --git a/flowgraph/data.h b/flowgraph/data.h index 353567c..1ed4964 100644 --- a/flowgraph/data.h +++ b/flowgraph/data.h @@ -1,3 +1,5 @@ +// Basic Data types, abstract (not yet machine specific) + #pragma once #include <cstdint> diff --git a/flowgraph/node.cpp b/flowgraph/node.cpp index fc55ef6..f81a7e1 100644 --- a/flowgraph/node.cpp +++ b/flowgraph/node.cpp @@ -2,8 +2,25 @@ #include "data.h" +#include <boost/endian/conversion.hpp> + using namespace FlowGraph; -Data FlowGraph::MakeLocalPointer(const std::string& name) { return Data(DataType::Pointer, std::make_shared<LocalStorage>(name)); } -Data FlowGraph::MakeLocalSize(const std::string& name) { return Data(DataType::Size, std::make_shared<LocalStorage>(name)); } +// 4 byte for now +Data FlowGraph::MakeConstantInt(int i) +{ + std::vector<uint8_t> value(size_t(4)); + *(reinterpret_cast<int32_t*>(value.data())) = boost::endian::native_to_little(static_cast<int32_t>(i)); + return Data(DataType::Int, std::make_shared<Constant>(value)); +} + +Data FlowGraph::MakeLocalPointer(const std::string& name) +{ + return Data(DataType::Pointer, std::make_shared<LocalStorage>(name)); +} + +Data FlowGraph::MakeLocalSize(const std::string& name) +{ + return Data(DataType::Size, std::make_shared<LocalStorage>(name)); +} diff --git a/flowgraph/node.h b/flowgraph/node.h index 37af95a..40846e2 100644 --- a/flowgraph/node.h +++ b/flowgraph/node.h @@ -1,3 +1,5 @@ +// Nodes in flow graph: Abstract Operations + #pragma once #include "data.h" @@ -36,6 +38,7 @@ namespace FlowGraph { Data m_location; // in: Pointer }; + Data MakeConstantInt(int i); Data MakeLocalPointer(const std::string& name); Data MakeLocalSize(const std::string& name); @@ -147,4 +150,4 @@ namespace FlowGraph { Data m_source1; }; -} +} // namespace FlowGraph diff --git a/flowgraph/storage.h b/flowgraph/storage.h index c2fa7c5..efd7d52 100644 --- a/flowgraph/storage.h +++ b/flowgraph/storage.h @@ -1,3 +1,4 @@ +// Different kinds of abstract storage locations: Constants, Global and Local Storage, Temporaries, ... #pragma once #include "data.h" @@ -15,13 +16,13 @@ namespace FlowGraph { class Storage { public: - virtual ~Storage() {} // force class to be polymorphic + virtual ~Storage() {} // force class to be polymorphic, for smart pointers }; class Constant: public Storage { public: - Constant(std::vector<uint8_t> value) {} // little endian data + Constant(std::vector<uint8_t>& value): m_value(value) {} // little endian data const std::vector<uint8_t>& value() const { return m_value; } private: std::vector<uint8_t> m_value; @@ -97,8 +97,8 @@ public: }; bool ChildIdIsEmpty(int32_t child_id); -bool ChildIdIsToken(int32_t child_id); -bool ChildIdIsNode(int32_t child_id); +bool ChildIdIsToken(int32_t child_id); // negative values +bool ChildIdIsNode(int32_t child_id); // identity index_t TokenIdFromChildId(int32_t child_id); int32_t ChildIdFromTokenId(index_t token_id); |