shitshow

A shitty programming language
git clone git://git.bain.cz/shitshow.git
Log | Files | Refs

commit 7f625eba293c4ec33fbd63a8dae9d585fd3bde2d
parent 3ed7b5866ce740ea5f3a1eb538071fb555442f3e
Author: bain3 <31798786+bain3@users.noreply.github.com>
Date:   Fri, 30 Apr 2021 23:50:48 +0200

Switch to unique pointers

Diffstat:
Mlexer/handlers.cpp | 2+-
Mmain.cpp | 44++++++++++++++++++++++++++++++--------------
Mparser/parser.cpp | 38++++++++++++++++++++++----------------
Mparser/parser.h | 35++++++++++++++++++++---------------
4 files changed, 73 insertions(+), 46 deletions(-)

diff --git a/lexer/handlers.cpp b/lexer/handlers.cpp @@ -12,7 +12,7 @@ int lexer::handlers::single_char(const lexer::GrammarRule &rule, lexer::Token &t int lexer::handlers::multi_char(const GrammarRule &rule, Token &token, const std::string &input) { if (input.length() >= rule.definition.length()) { - std::string sub = input.substr(rule.definition.length()); + std::string sub = input.substr(0, rule.definition.length()); if (sub == rule.definition) { token.type = rule.type; token.value = sub; diff --git a/main.cpp b/main.cpp @@ -8,28 +8,43 @@ std::string tab(const int &deep) { return o; } -void print_expression(parser::elements::Expression* expression, int deep) { +void print_expression(const std::unique_ptr<parser::elements::Expression> &expression, int deep) { using namespace parser; - std::cout << tab(deep); - for (parser::elements::ParserElement* e : expression->children) { - std::cout << e->type << " "; + for (const std::unique_ptr<elements::ParserElement> &e : expression->children) { + switch (e->type) { + case parser::CONST_DEFINE: { + auto* constant = (elements::ConstDefine*)e.get(); + std::cout << tab(deep) << "constant " << constant->value << std::endl; + break; + } + default: + std::cout << tab(deep) << "element of type " << e->type << std::endl; + } } - std::cout << std::endl; } -void print_statement(parser::elements::Statement* statement, int deep) { +void print_statement(const std::unique_ptr<parser::elements::Statement> &statement, int deep) { using namespace parser; - for (parser::elements::ParserElement* e : statement->children) { + for (std::unique_ptr<elements::ParserElement> &e : statement->children) { switch (e->type) { case parser::DECLARATION: { - auto* declaration = (elements::Declaration*)e; - std::cout << tab(deep) << "declaring " << declaration->name << " as " << declaration->data_type << std::endl; + auto* declaration = (elements::Declaration*)e.get(); + std::cout << tab(deep) << "declaring " << declaration->name << " as "; + switch (declaration->data_type) { + case INT: + std::cout << "int"; + break; + case STRING: + std::cout << "string"; + break; + } + std::cout << std::endl; break; } case parser::ASSIGNMENT: { - auto* assignment = (elements::Assignment*)e; + auto* assignment = (elements::Assignment*)e.get(); std::cout << tab(deep) << "assigning " << assignment->name << " to " << std::endl; - print_expression(&assignment->value, deep+4); + print_expression(assignment->value, deep+4); break; } default: @@ -38,7 +53,7 @@ void print_statement(parser::elements::Statement* statement, int deep) { } } void print_block(const parser::elements::Block &block, const int &deep) { - for (parser::elements::Statement* e : block.children) { + for (const std::unique_ptr<parser::elements::Statement> &e : block.children) { std::cout << tab(deep) << "statement begin" << std::endl; print_statement(e, deep+4); std::cout << tab(deep) << "statement end" << std::endl; @@ -53,11 +68,12 @@ int main() { {.type=lexer::TokenType::RIGHT_PARENT, .definition=")", .handler=lexer::HandlerType::SINGLE_CHAR}, {.type=lexer::TokenType::LEFT_BRACKET, .definition="{", .handler=lexer::HandlerType::SINGLE_CHAR}, {.type=lexer::TokenType::RIGHT_BRACKET, .definition="}", .handler=lexer::HandlerType::SINGLE_CHAR}, + {.type=lexer::TokenType::TYPE_INT, .definition="int", .handler=lexer::HandlerType::MULTI_CHAR}, {.type=lexer::TokenType::NAME, .definition=R"([A-Za-z_](?:[\w]+)?)", .handler=lexer::HandlerType::REGEX}, - {.type=lexer::TokenType::NUMBER_LITERAL, .definition=R"([0-9](?:.[0-9])?)", .handler=lexer::HandlerType::REGEX}, + {.type=lexer::TokenType::NUMBER_LITERAL, .definition=R"([0-9]+)", .handler=lexer::HandlerType::REGEX}, {.type=lexer::TokenType::STRING_LITERAL, .handler=lexer::HandlerType::STRING} }); - std::vector<lexer::Token> out = lxr.tokenize("int i = 0; print i;"); + std::vector<lexer::Token> out = lxr.tokenize("int i = 120;"); for (const lexer::Token& token : out) { std::cout << token.type << ": " << token.value << std::endl; } diff --git a/parser/parser.cpp b/parser/parser.cpp @@ -36,8 +36,7 @@ parser::elements::Block parser::parse_block(const std::vector<lexer::Token> &tok lexer::Token token = token_stream[consumed]; switch (token.type) { case lexer::SEMICOLON: { - elements::Statement st = parse_statement(statement_tokens); - block.children.push_back(&st); + block.children.push_back(std::unique_ptr<elements::Statement>(parse_statement(statement_tokens))); statement_tokens.clear(); break; } @@ -47,8 +46,7 @@ parser::elements::Block parser::parse_block(const std::vector<lexer::Token> &tok break; case lexer::RIGHT_BRACKET: if (!brackets) { - elements::Statement st = parse_statement(statement_tokens); - block.children.push_back(&st); + block.children.push_back(std::unique_ptr<elements::Statement>(parse_statement(statement_tokens))); statement_tokens.clear(); } break; @@ -60,9 +58,9 @@ parser::elements::Block parser::parse_block(const std::vector<lexer::Token> &tok return block; } -parser::elements::Statement parser::parse_statement(const std::vector<lexer::Token> &token_stream) { +parser::elements::Statement* parser::parse_statement(const std::vector<lexer::Token> &token_stream) { int consumed = 0; - elements::Statement statement; + auto* statement = new elements::Statement; if (token_stream.empty()) { return statement; } @@ -79,12 +77,11 @@ parser::elements::Statement parser::parse_statement(const std::vector<lexer::Tok if (token_stream.size() < consumed+3) { error("Nothing to assign.", reconstruct_code(token_stream)); } - elements::Expression exp = parse_expression(token_stream, consumed+2); - elements::Assignment assignment { + auto* assignment = new elements::Assignment { .name = token.value, - .value = exp, + .value = std::unique_ptr<elements::Expression>(parse_expression(token_stream, consumed+2)), }; - statement.children.push_back(&assignment); + statement->children.push_back(std::unique_ptr<elements::ParserElement>((elements::ParserElement*)assignment)); break; } default: @@ -98,13 +95,15 @@ parser::elements::Statement parser::parse_statement(const std::vector<lexer::Tok } else if (token_stream[consumed+1].type != lexer::TokenType::NAME) { error("Can only declare names.", reconstruct_code(token_stream)); } - elements::Declaration declaration { + auto* declaration = new elements::Declaration { .name = token_stream[consumed+1].value, .data_type = INT }; - statement.children.push_back(&declaration); - if (token_stream.size() > consumed+2 && token_stream[consumed+2].type == lexer::ASSIGNMENT) + statement->children.push_back(std::unique_ptr<elements::ParserElement>((elements::ParserElement*)declaration)); + if (token_stream.size() > consumed+2 && token_stream[consumed+2].type == lexer::ASSIGNMENT) { + consumed++; continue; // continue to run the main loop to get the assignment + } } case lexer::PRINT: case lexer::LEFT_BRACKET: @@ -117,8 +116,15 @@ parser::elements::Statement parser::parse_statement(const std::vector<lexer::Tok return statement; } -parser::elements::Expression parser::parse_expression(const std::vector<lexer::Token> &token_stream, int start_at) { - - return parser::elements::Expression(); +parser::elements::Expression* parser::parse_expression(const std::vector<lexer::Token> &token_stream, int start_at) { + auto* expression = new parser::elements::Expression; + if (token_stream[start_at].type == lexer::NUMBER_LITERAL) { + auto* number = new parser::elements::ConstDefine { + .data_type = INT, + .value = token_stream[start_at].value + }; + expression->children.push_back(std::unique_ptr<elements::ParserElement>((elements::ParserElement*)(number))); + } + return expression; } diff --git a/parser/parser.h b/parser/parser.h @@ -3,10 +3,12 @@ #define SHITSHOW_PARSER_H #include <string> #include <vector> +#include <memory> #include "../lexer/lexer.h" namespace parser { enum ParserElementType { + NONE, BLOCK, EXPRESSION, STATEMENT, @@ -22,51 +24,54 @@ namespace parser { STRING }; namespace elements { - struct ParserElement { ParserElementType type; }; - struct Expression : ParserElement { + struct ParserElement { + ParserElementType type = NONE; + }; + struct Expression { ParserElementType type = EXPRESSION; // TODO: memory leaks? - std::vector<ParserElement*> children; + std::vector<std::unique_ptr<ParserElement>> children; }; - struct Statement : Expression { + struct Statement { ParserElementType type = STATEMENT; + std::vector<std::unique_ptr<ParserElement>> children; }; - struct Block : ParserElement { + struct Block { ParserElementType type = BLOCK; // TODO: memory leaks? - std::vector<Statement*> children; + std::vector<std::unique_ptr<Statement>> children; }; - struct Declaration : ParserElement { + struct Declaration { ParserElementType type = DECLARATION; std::string name; DataType data_type; }; - struct Assignment : ParserElement { + struct Assignment { ParserElementType type = ASSIGNMENT; std::string name; - Expression value; + std::unique_ptr<Expression> value; }; - struct ConstDefine : ParserElement { + struct ConstDefine { ParserElementType type = CONST_DEFINE; DataType data_type; std::string value; }; - struct Call : ParserElement { + struct Call { ParserElementType type = CALL; std::string name; }; - struct Name : ParserElement { + struct Name { ParserElementType type = NAME; std::string name; }; - struct Print : ParserElement { + struct Print { ParserElementType type = PRINT; ParserElement value; }; } elements::Block parse_block(const std::vector<lexer::Token> &token_stream, int start_at); - elements::Statement parse_statement(const std::vector<lexer::Token> &token_stream); - elements::Expression parse_expression(const std::vector<lexer::Token> &token_stream, int start_at); + elements::Statement* parse_statement(const std::vector<lexer::Token> &token_stream); + elements::Expression * parse_expression(const std::vector<lexer::Token> &token_stream, int start_at); } #endif //SHITSHOW_PARSER_H