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); | 
