From 9ff3943819064c4982d10cc3571cd05235ecad3c Mon Sep 17 00:00:00 2001 From: lisk77 Date: Tue, 1 Jul 2025 23:52:19 +0200 Subject: [PATCH] feat: added simple import support --- README.md | 2 +- include/ast.hpp | 12 +++++++++++- include/token.hpp | 3 ++- src/lexer.cpp | 19 +++++++++++++++++++ src/parser.cpp | 27 +++++++++++++++++++++++++++ src/token.cpp | 1 + 6 files changed, 61 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 61b72d6..6392d5b 100644 --- a/README.md +++ b/README.md @@ -42,5 +42,5 @@ For a file to be able to be run, it needs to define a `main` function. ## Future ideas - [ ] types -- [ ] imports +- [x] imports (at least simple) - [ ] small standard library diff --git a/include/ast.hpp b/include/ast.hpp index fbde70d..8def7ec 100644 --- a/include/ast.hpp +++ b/include/ast.hpp @@ -6,7 +6,8 @@ // ast stuff lul struct Expr { - virtual ~Expr() = default; + virtual ~Expr() = default; + virtual std::unique_ptr clone() const = 0; }; // represents a simple symbol like "x" or even "thisIsACoolFunctionTrustme100" @@ -16,6 +17,9 @@ struct Variable : Expr { std::string name; Variable(std::string n) : name(std::move(n)) {} + std::unique_ptr clone() const override { + return std::make_unique(name); + } }; // represents a function itself like \ x . x @@ -24,6 +28,9 @@ struct Abstraction : Expr { std::unique_ptr body; Abstraction(std::string p, std::unique_ptr b) : param(std::move(p)), body(std::move(b)) {} + std::unique_ptr clone() const override { + return std::make_unique(param, body->clone()); + } }; // wouldnt be turing complete if we couldnt apply to these functions innit @@ -34,6 +41,9 @@ struct Application : Expr { std::unique_ptr left, right; Application(std::unique_ptr l, std::unique_ptr r) : left(std::move(l)), right(std::move(r)) {} + std::unique_ptr clone() const override { + return std::make_unique(left->clone(), right->clone()); + } }; #endif // AST_HPP diff --git a/include/token.hpp b/include/token.hpp index 2e496b9..e68cac7 100644 --- a/include/token.hpp +++ b/include/token.hpp @@ -14,7 +14,8 @@ typedef enum { LPAREN, RPAREN, VARIABLE, - EQUALS + EQUALS, + IMPORT } TokenType; typedef struct { diff --git a/src/lexer.cpp b/src/lexer.cpp index f21ba84..ba4c867 100644 --- a/src/lexer.cpp +++ b/src/lexer.cpp @@ -55,6 +55,25 @@ std::vector Lexer::tokenize() { position++; } std::string lex = src.substr(start, position - start); + if (lex == "import") { + tokens.push_back({ IMPORT, lex, start, position }); + position++; + size_t startPath = position; + + while (position < len && !IS_SPACE(src[position]) && src[position] != ';') + { + position++; + } + if (position >= len) { + std::cerr << "lexer: import statement was not closed with semicolon" << std::endl; + this->error_flag = true; + continue; + } + + std::string path = src.substr(startPath, position - startPath); + tokens.push_back({ VARIABLE, path, startPath, position }); + continue; + } tokens.push_back({ VARIABLE, lex, start, position }); } else if (IS_SPACE(curr)) { diff --git a/src/parser.cpp b/src/parser.cpp index eee0556..93062f2 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1,4 +1,5 @@ #include "parser.hpp" +#include "lexer.hpp" #include "ast.hpp" #include @@ -6,6 +7,7 @@ #include #include #include +#include Parser::Parser(std::vector toks) : tokens(std::move(toks)) @@ -88,6 +90,31 @@ std::unique_ptr Parser::parseSimple() { return e; } + if (peek().type == TokenType::IMPORT) { + position++; + const auto &path = get(); + + std::ifstream file(path.lexeme, std::ios::binary); + if (!file) { + throw std::runtime_error("import: unable to open file: " + path.lexeme); + } + std::string content(std::istreambuf_iterator(file), {}); + + Lexer lexImp(content); + auto tokensImp = lexImp.tokenize(); + + Parser parserImp(std::move(tokensImp)); + parserImp.parseProgram(); + + std::cout << "importing " << path.lexeme << std::endl; + + for (const auto &entry : parserImp.definitions()) { + defs.emplace(entry.first, entry.second->clone()); + } + + return nullptr; + } + throw std::runtime_error("parser: expected \\, variable, or '(' at position " + std::to_string(peek().start)); } diff --git a/src/token.cpp b/src/token.cpp index f1b8ddb..6d384bf 100644 --- a/src/token.cpp +++ b/src/token.cpp @@ -14,6 +14,7 @@ std::string display_tokentype(TokenType type) { case RPAREN : return "RPAREN"; case EQUALS : return "EQUALS"; case VARIABLE : return "VARIABLE"; + case IMPORT : return "IMPORT"; default : return ""; } }