diff options
author | Loek Le Blansch <loek@pipeframe.xyz> | 2024-06-07 15:22:00 +0200 |
---|---|---|
committer | Loek Le Blansch <loek@pipeframe.xyz> | 2024-06-07 15:22:00 +0200 |
commit | 9e1b22e12bb0915081c94e6266b9725251500dcd (patch) | |
tree | 014f96a345201df949bcb4ff032728e792c18be9 | |
parent | bde4c3fe7885b66c0bb59b8407c74b350fc6b44d (diff) |
WIP begin writing factory
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | Circuit.cpp | 19 | ||||
-rw-r--r-- | Circuit.h | 19 | ||||
-rw-r--r-- | GateAnd.cpp | 39 | ||||
-rw-r--r-- | GateAnd.h | 15 | ||||
-rw-r--r-- | Node.cpp | 36 | ||||
-rw-r--r-- | Node.h | 30 | ||||
-rw-r--r-- | NodeFactory.cpp | 24 | ||||
-rw-r--r-- | NodeFactory.h | 21 | ||||
-rw-r--r-- | Parser.cpp | 24 | ||||
-rw-r--r-- | Parser.h | 23 | ||||
-rw-r--r-- | docs/class-diag.puml | 2 | ||||
-rw-r--r-- | main.cpp | 11 | ||||
-rw-r--r-- | makefile | 4 |
14 files changed, 189 insertions, 80 deletions
@@ -1,3 +1,5 @@ main *.o .vscode +.cache +compile_commands.json diff --git a/Circuit.cpp b/Circuit.cpp new file mode 100644 index 0000000..f6229f1 --- /dev/null +++ b/Circuit.cpp @@ -0,0 +1,19 @@ +#include "Circuit.h" +#include "NodeFactory.h" + +void Circuit::create(string label, vector<string> nodes) { + if (nodes.size() == 1 && NodeFactory::has_type(nodes[0])) + return new_node(label, nodes[0]); + + for (string node : nodes) + new_net(label, node); +} + +void Circuit::new_node(string label, string type) { + printf("[%s] (%s)\n", label.c_str(), type.c_str()); +} + +void Circuit::new_net(string label, string connection) { + printf("[%s] -> %s\n", label.c_str(), connection.c_str()); +} + diff --git a/Circuit.h b/Circuit.h new file mode 100644 index 0000000..249301d --- /dev/null +++ b/Circuit.h @@ -0,0 +1,19 @@ +#pragma once + +#include <string> +#include <vector> + +using std::string; +using std::vector; + +class Circuit { +public: + Circuit() = default; + virtual ~Circuit() = default; + +public: + void create(string label, vector<string> nodes); + void new_node(string label, string type); + void new_net(string label, string node); +}; + diff --git a/GateAnd.cpp b/GateAnd.cpp new file mode 100644 index 0000000..e48b21c --- /dev/null +++ b/GateAnd.cpp @@ -0,0 +1,39 @@ +#include <iostream> + +#include "GateAnd.h" + +using std::cout; +using std::endl; + +GateAnd GateAnd::instance(GateAnd::type); + +GateAnd::GateAnd(const char * type) : Node(type) { + cout << __PRETTY_FUNCTION__ << endl; +} + +// Concrete Nodes: +void GateAnd::compare() { + SignalLevel new_out = HIGH; +// TODO fix segfault somewhere below +// for (int i = 0; i < this->inputs.size(); i++){ +// switch (this->inputs[i]->getLevel()){ +// case LOW: +// new_out = LOW; +// break; +// case HIGH: +// continue; +// break; +// case UNDEFINED: +// default: +// new_out = UNDEFINED; +// exit; +// break; +// } +// } + +// if (this->output->getLevel() == new_out){ +// /* do nothing */ +// } else { +// this->output->setLevel(new_out); +// } +} diff --git a/GateAnd.h b/GateAnd.h new file mode 100644 index 0000000..40e3927 --- /dev/null +++ b/GateAnd.h @@ -0,0 +1,15 @@ +#pragma once + +#include "Node.h" + +class GateAnd : public Node { +public: + GateAnd(const char * type); + virtual ~GateAnd() = default; + virtual void compare(); + +private: + constexpr static const char * type = "and"; + static GateAnd instance; +}; + @@ -2,11 +2,14 @@ #include <iostream> -Node::Node(){} -Node::~Node(){} -void Node::addInput(Net* net){ +Node::Node(const char * type) { + +} + +void Node::addInput(Net* net) { net->attach(this); } + void Node::setOutput(Net* net){ this->output = net; } @@ -16,30 +19,3 @@ void Node::update(){ this->compare(); } -/*/ Concrete Nodes: /*/ - -void GateAnd::compare(){ - SignalLevel new_out = HIGH; -// TODO fix segfault somewhere below -// for (int i = 0; i < this->inputs.size(); i++){ -// switch (this->inputs[i]->getLevel()){ -// case LOW: -// new_out = LOW; -// break; -// case HIGH: -// continue; -// break; -// case UNDEFINED: -// default: -// new_out = UNDEFINED; -// exit; -// break; -// } -// } - -// if (this->output->getLevel() == new_out){ -// /* do nothing */ -// } else { -// this->output->setLevel(new_out); -// } -} @@ -6,26 +6,22 @@ #include "Observer.h" #include "Net.h" -class Node: Observer { -protected: - std::string label; - std::string type; - - std::vector<Net*> inputs; - Net* output; +using std::string; +using std::vector; +class Node : Observer { public: - Node(/* args */); - virtual ~Node(); + Node(const char * type); + virtual ~Node() = default; void update(); - virtual void addInput(Net*); - virtual void setOutput(Net*); + virtual void addInput(Net *); + virtual void setOutput(Net *); virtual void compare() = 0; -}; -class GateAnd: public Node { -public: - GateAnd(){}; - ~GateAnd(){}; - void compare(); +protected: + string label; + + vector<Net *> inputs; + Net * output; }; + diff --git a/NodeFactory.cpp b/NodeFactory.cpp new file mode 100644 index 0000000..da4cc72 --- /dev/null +++ b/NodeFactory.cpp @@ -0,0 +1,24 @@ +#include <locale> +#include <ranges> +#include <algorithm> + +#include "NodeFactory.h" + +bool NodeFactory::has_type(const char * type) { + return has_type(string(type)); +} + +bool NodeFactory::has_type(string type) { + std::ranges::transform(type, type.begin(), [] (unsigned char c) { return std::tolower(c); }); + + // TODO: query the map instead + if (type == "and") return true; + if (type == "not") return true; + if (type == "or") return true; + if (type == "input_high") return true; + if (type == "input_low") return true; + if (type == "probe") return true; + + return false; +} + diff --git a/NodeFactory.h b/NodeFactory.h new file mode 100644 index 0000000..b5757d4 --- /dev/null +++ b/NodeFactory.h @@ -0,0 +1,21 @@ +#pragma once + +#include <string> + +#include "Node.h" + +using std::string; + +class NodeFactory { +public: + NodeFactory() = default; + virtual ~NodeFactory() = default; + +public: + static bool has_type(const char * type); + static bool has_type(string type); + +private: + friend Node; +}; + @@ -52,7 +52,11 @@ size_t Parser::filter(char * input) { return len - offset; } -void Parser::parse(istream & input) const { +void Parser::set_circuit(Circuit & circuit) { + this->circuit = &circuit; +} + +void Parser::parse(istream & input) { unsigned linenum = 0; string line_str; while (getline(input, line_str)) { @@ -74,31 +78,23 @@ void Parser::parse(istream & input) const { content = NULL; } - handle_line(label, nodes); + if (circuit == nullptr) throw ParserException("circuit is not initialized!"); + circuit->create(label, nodes); } } -void Parser::handle_line(string label, vector<string> nodes) const { - if (nodes.size() == 1) { - printf("node or net "); - } else { - printf("net "); - } - - printf("[%s]\n", label.c_str()); -} -istream & operator >> (istream & s, const Parser & parser) { +istream & operator >> (istream & s, Parser & parser) { parser.parse(s); return s; } -istream & operator << (const Parser & parser, istream & s) { +istream & operator << (Parser & parser, istream & s) { parser.parse(s); return s; } -void Parser::parse(string input) const { +void Parser::parse(string input) { std::istringstream s(input); parse(s); } @@ -3,17 +3,17 @@ #include <iostream> #include <istream> #include <exception> -#include <vector> + +#include "Circuit.h" using std::istream; using std::string; -using std::vector; class ParserException : public std::exception { public: ParserException(const char * fmt, ...); - ~ParserException(); - const char * what(); + virtual ~ParserException(); + virtual const char * what(); private: char * error = NULL; @@ -21,8 +21,11 @@ private: class Parser { public: - void parse(string input) const; - void parse(istream & input) const; + Parser() = default; + virtual ~Parser() = default; + + void parse(string input); + void parse(istream & input); /** * \brief preprocess (filter) line of input @@ -31,10 +34,12 @@ public: */ static size_t filter(char * input); - void handle_line(string label, vector<string> nodes) const; + void set_circuit(Circuit & circuit); private: - friend istream & operator << (const Parser & parser, istream & s); - friend istream & operator >> (istream & s, const Parser & parser); + friend istream & operator << (Parser & parser, istream & s); + friend istream & operator >> (istream & s, Parser & parser); + + Circuit * circuit; }; diff --git a/docs/class-diag.puml b/docs/class-diag.puml index ea245cd..5efda1b 100644 --- a/docs/class-diag.puml +++ b/docs/class-diag.puml @@ -5,7 +5,7 @@ abstract class Node { /' (also ConcreteObserver) '/ + addInput(Net*) - inputs: Net*[] - output: Net* - - type: static constexpr const string + - type: static const char * string - minInputs: constexpr unsigned int - maxInputs: constexpr int } @@ -1,27 +1,24 @@ -#include <cstdio> #include <iostream> -#include <exception> #include <fstream> #include "Parser.h" -// #include "Circuit.h" +#include "Circuit.h" using std::cout; using std::endl; -using std::exception; using std::ifstream; -using std::istream; int main(int argc, char** argv) { Parser main_parser; - // Circuit circuit; + Circuit circuit; - // main_parser.setCircuit(circuit); + main_parser.set_circuit(circuit); ifstream file("circuits/full-adder.txt"); try { file >> main_parser; + // main_parser << file; } catch (ParserException & e) { cout << "Parser error: " << e.what() << endl; return EXIT_FAILURE; @@ -1,7 +1,7 @@ CC = g++ LD = g++ RM = rm -f -CFLAGS = -g -std=c++17 +CFLAGS = -g -std=c++20 LFLAGS = TARGET = main SRCS := $(wildcard *.cpp) @@ -18,5 +18,5 @@ $(TARGET): $(OBJS) clean: $(RM) $(TARGET) $(OBJS) -compile_commands: clean +compile_commands.json: compiledb make -Bn |