commit 2e55268805deb6a7d9d08aaeac925c69774c597f Author: Ilja Kovalovs Date: Wed Oct 15 17:20:56 2025 +0200 Initial commit diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..b9c7c32 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.14) + +project(Interpreter) + +set(CXX_STANDARD 20) + +add_subdirectory(Parser) + +add_subdirectory(Program) diff --git a/Parser/CMakeLists.txt b/Parser/CMakeLists.txt new file mode 100644 index 0000000..a776c14 --- /dev/null +++ b/Parser/CMakeLists.txt @@ -0,0 +1,9 @@ +add_library( + Parser + Parser.h + Parser.cpp + Lexer.h + Lexer.cpp +) + +target_include_directories(Parser PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/") \ No newline at end of file diff --git a/Parser/Expression/Binary.h b/Parser/Expression/Binary.h new file mode 100644 index 0000000..1fdca14 --- /dev/null +++ b/Parser/Expression/Binary.h @@ -0,0 +1,20 @@ +#include "Expression.h" +#include "Lexer.h" +#include + +namespace Parser +{ + struct Binary : public Expression + { + std::unique_ptr left; + std::unique_ptr right; + Lexer::Token::TokenType op; + + Binary(std::unique_ptr&& left, std::unique_ptr&& right, Lexer::Token::TokenType op) : Expression() + { + this->left = std::move(left); + this->right = std::move(right); + this->op = op; + } + }; +} \ No newline at end of file diff --git a/Parser/Expression/Expression.h b/Parser/Expression/Expression.h new file mode 100644 index 0000000..6405cb9 --- /dev/null +++ b/Parser/Expression/Expression.h @@ -0,0 +1,3 @@ +namespace Parser{ +struct Expression{}; +} \ No newline at end of file diff --git a/Parser/Expression/Grouping.h b/Parser/Expression/Grouping.h new file mode 100644 index 0000000..119a840 --- /dev/null +++ b/Parser/Expression/Grouping.h @@ -0,0 +1,12 @@ +#include "Expression.h" +#include + +namespace Parser +{ + struct Grouping : public Expression{ + std::unique_ptr expr; + Grouping(std::unique_ptr&& expr) : Expression(){ + this->expr = std::move(expr); + }; + }; +} diff --git a/Parser/Lexer.cpp b/Parser/Lexer.cpp new file mode 100644 index 0000000..b553390 --- /dev/null +++ b/Parser/Lexer.cpp @@ -0,0 +1,122 @@ +#include "Lexer.h" +#include + +namespace Parser +{ + using Parser::Lexer; + std::list Lexer::tokenize(const std::string_view &text) + { + tokens.clear(); + this->text = text; + + while (current != text.length()) + { + if (text.at(current) == ' ') + { + advance(); + continue; + } + if (text.at(current) == '\n') + { + advance(); + line++; + continue; + } + + start = current; + + switch (Lexer::peek()) + { + case '+': + advance(); + token(Token::PLUS); + break; + case '-': + advance(); + token(Token::MINUS); + break; + case '*': + advance(); + token(Token::MULTIPLY); + break; + case '/': + advance(); + token(Token::DIVIDE); + break; + case '=': + advance(); + token(Token::ASSIGNMENT); + break; + case '(': + advance(); + token(Token::BRACKET_LEFT); + break; + case ')': + advance(); + token(Token::BRACKET_RIGHT); + break; + + default: + if (isDigit(peek())) + { + advance(); + number(); + } + + if (isAlpha(peek())) + { + advance(); + identifier(); + } + } + } + + return tokens; + } + void Lexer::advance() + { + current++; + } + + char Lexer::peek() + { + if (current == text.length()) + return 0; + return text.at(current); + } + + void Lexer::token(const Token::TokenType type) + { + tokens.emplace_back(Token(type, line, text.substr(start, (current - start)))); + } + + bool Lexer::isDigit(const char &c) + { + return c >= '0' && c <= '9'; + } + + void Lexer::number() + { + while (isDigit(peek())) + { + advance(); + } + + token(Token::INT); + } + + bool Lexer::isAlpha(const char &c) + { + return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')); + } + + void Lexer::identifier() + { + while (isAlpha(peek()) || isDigit(peek())) + { + advance(); + } + + token(Token::IDENTIFIER); + } +} \ No newline at end of file diff --git a/Parser/Lexer.h b/Parser/Lexer.h new file mode 100644 index 0000000..4ba7365 --- /dev/null +++ b/Parser/Lexer.h @@ -0,0 +1,66 @@ +#pragma once +#include +#include +#include +#include +#include + +namespace Parser +{ + class Lexer + { + public: + struct Token + { + enum TokenType + { + INT, + PLUS, + MINUS, + MULTIPLY, + DIVIDE, + ASSIGNMENT, + BRACKET_LEFT, + BRACKET_RIGHT, + IDENTIFIER + }; + + TokenType type; + uint line; + std::string_view occurence; + + Token(TokenType type, uint line, std::string_view&& str) + { + this->type = type; + this->line = line; + occurence = str; + } + + std::string toString(){ + return std::to_string(type) + " " + std::string(occurence); + } + }; + + Lexer() = default; + std::list tokenize(const std::string_view &text); + + private: + uint current{}; + uint start{}; + uint line{}; + + std::string_view text; + std::list tokens; + + + + private: + void identifier(); + bool isAlpha(const char& c); + bool isDigit(const char& c); + void number(); + void advance(); + char peek(); + void token(const Token::TokenType type); + }; +} \ No newline at end of file diff --git a/Parser/Parser.cpp b/Parser/Parser.cpp new file mode 100644 index 0000000..27030e7 --- /dev/null +++ b/Parser/Parser.cpp @@ -0,0 +1,9 @@ +#include "Parser.h" +#include + +namespace Parser{ + void Parser::parse(std::string_view source) { + lexer.tokenize(source); + + } +} \ No newline at end of file diff --git a/Parser/Parser.h b/Parser/Parser.h new file mode 100644 index 0000000..6c763a3 --- /dev/null +++ b/Parser/Parser.h @@ -0,0 +1,18 @@ +#pragma once +#include "Lexer.h" +#include "Expression/Expression.h" + +namespace Parser +{ + class Parser + { + Lexer lexer; + std::string_view source; + std::list exprs; +public: + Parser() = default; + void parse(std::string_view source); +private: + generateAST(); + }; +}; \ No newline at end of file diff --git a/Program/CMakeLists.txt b/Program/CMakeLists.txt new file mode 100644 index 0000000..6438568 --- /dev/null +++ b/Program/CMakeLists.txt @@ -0,0 +1,3 @@ +add_executable(Interpreter main.cpp) + +target_link_libraries(Interpreter PRIVATE Parser) diff --git a/Program/main.cpp b/Program/main.cpp new file mode 100644 index 0000000..a1b59bc --- /dev/null +++ b/Program/main.cpp @@ -0,0 +1,10 @@ +#include +#include "Parser.h" + +int main() { + Parser::Parser parser; + + std::string input = "123 + 5432 - 33 / 434 (asd)"; + + parser.parse(input); +} \ No newline at end of file