From 71c7fd62f8b5257b82cf32b0f747fcf313fcc617 Mon Sep 17 00:00:00 2001 From: Roland Reichwein Date: Fri, 6 Nov 2020 18:20:34 +0100 Subject: Prepare Token/Node handling --- Makefile | 6 ++++-- asm/operators.h | 2 ++ cpp.cpp | 55 +++++++++++++++++++++++++++++++++++++---------------- cpp.h | 11 +++++++---- flowgraph/data.h | 2 ++ flowgraph/node.cpp | 21 ++++++++++++++++++-- flowgraph/node.h | 5 ++++- flowgraph/storage.h | 5 +++-- grammer.h | 4 ++-- 9 files changed, 82 insertions(+), 29 deletions(-) diff --git a/Makefile b/Makefile index 84a17fa..a50edc2 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/cpp.cpp b/cpp.cpp index 2135e67..b9f405f 100644 --- a/cpp.cpp +++ b/cpp.cpp @@ -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& return true; // match } -void CPP::trDeclaration(index_t node_id) +//std::unordered_map> + +// 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 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(data)); + } else { + mValues.push_back(std::make_shared(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 diff --git a/cpp.h b/cpp.h index 95289fc..ce4a516 100644 --- a/cpp.h +++ b/cpp.h @@ -3,6 +3,9 @@ #include "grammer.h" #include "minicc.h" +#include +#include +#include #include struct CPPContext { @@ -43,8 +46,6 @@ private: std::vector m_tokens; // result of phase 7.a std::vector 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& 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> 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 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 + using namespace FlowGraph; -Data FlowGraph::MakeLocalPointer(const std::string& name) { return Data(DataType::Pointer, std::make_shared(name)); } -Data FlowGraph::MakeLocalSize(const std::string& name) { return Data(DataType::Size, std::make_shared(name)); } +// 4 byte for now +Data FlowGraph::MakeConstantInt(int i) +{ + std::vector value(size_t(4)); + *(reinterpret_cast(value.data())) = boost::endian::native_to_little(static_cast(i)); + return Data(DataType::Int, std::make_shared(value)); +} + +Data FlowGraph::MakeLocalPointer(const std::string& name) +{ + return Data(DataType::Pointer, std::make_shared(name)); +} + +Data FlowGraph::MakeLocalSize(const std::string& name) +{ + return Data(DataType::Size, std::make_shared(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 value) {} // little endian data + Constant(std::vector& value): m_value(value) {} // little endian data const std::vector& value() const { return m_value; } private: std::vector m_value; diff --git a/grammer.h b/grammer.h index e179a9e..90f9e87 100644 --- a/grammer.h +++ b/grammer.h @@ -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); -- cgit v1.2.3