Importing libraries

This commit is contained in:
2025-10-29 11:45:58 +00:00
parent db963463b0
commit 7e071a1b01
5 changed files with 101 additions and 5 deletions

View File

@@ -1,15 +1,21 @@
#include "runner.h"
#include <iostream>
#include <ostream>
#include <fstream>
#include <utility>
#include "../parser/parser.h"
#include "../lexer/lexer.h"
Object::Object(ASTValue value) : value(value) {}
Object::Object(ASTFunction function) : value(function) {}
Object::Object() = default;
std::map<std::string, Object> Executor::getVariables() {
return variables;
}
std::map<std::string, Object> globalVariables;
std::optional<ASTNode> Executor::consume() {
if (iterator < code.nodes.size()) {
@@ -121,7 +127,52 @@ Executor::Executor(ASTCodeBlock in, bool isInitCall, std::map<std::string, Objec
}
if (fnName == "import") {
// work on importing modules later
for (Object &object : callArgs) {
ASTValue arg;
if (object.isCustomObject == false && std::holds_alternative<ASTValue>(object.value)) {
arg = std::get<ASTValue>(object.value);
if (arg.type == ValueType::String) {
std::optional<std::string> importName = arg.getString();
if (importName.has_value()) {
const char* libpathEnv = std::getenv("FUNK_PATH");
if (libpathEnv == nullptr) {
std::cout << "Error: FUNK_PATH environment variable is not set" << std::endl;
exit(1);
}
std::string libpath = libpathEnv;
// Import the Funk file for this library
std::ifstream file(libpath + "/" + importName.value() + ".funk");
// Execute the file and capture it's content
if (file.is_open()) {
std::string fc;
std::string buf;
while (std::getline(file, buf)) {
fc += buf + "\n";
}
Executor importedCode(ASTCodeBlock(Lexer(fc).content));
for (auto const &[key, val] : importedCode.getVariables()) {
std::string newVarName = importName.value() + "::" + key;
if (isInitCall) {
globalVariables[newVarName] = val;
variables[newVarName] = val;
} else {
variables[newVarName] = val;
}
}
}
} else {
std::cout << "Type mismatch - expecting a string but found something else" << std::endl;
exit(1);
}
} else {
std::cout << "Type mismatch - expecting string for import" << std::endl;
exit(1);
}
} else {
std::cout << "Type mismatch - expecting string for import" << std::endl;
exit(1);
}
}
continue;
}
if (isInitCall) {
@@ -268,14 +319,14 @@ Executor::Executor(ASTCodeBlock in, bool isInitCall, std::map<std::string, Objec
if (variables.find(fnName) != variables.end()) {
if (variables[fnName].isCustomObject) {
if (std::holds_alternative<ASTFunction>(variables[fnName].children["handler"])) {
Executor(std::get<ASTFunction>(variables[fnName].children["handler"]).body, false, {}, callArgs);
Executor(std::get<ASTFunction>(variables[fnName].children["handler"]).body, false, globalVariables, callArgs);
} else {
std::cout << "Object " << fnName << " does not have a handler function" << std::endl;
exit(1);
}
}
if (std::holds_alternative<ASTFunction>(variables[fnName].value)) {
Executor(std::get<ASTFunction>(variables[fnName].value).body, false, {}, callArgs);
Executor(std::get<ASTFunction>(variables[fnName].value).body, false, globalVariables, callArgs);
}
} else {
@@ -289,6 +340,7 @@ Executor::Executor(ASTCodeBlock in, bool isInitCall, std::map<std::string, Objec
}
}
if (isInitCall) {
Executor(std::get<ASTFunction>(variables[std::string("main")].value).body, false, variables);
globalVariables = variables;
Executor(std::get<ASTFunction>(variables[std::string("main")].value).body, false, globalVariables);
}
}

View File

@@ -37,5 +37,6 @@ class Executor {
std::optional<ASTNode> peek(int ahead = 1);
public:
explicit Executor(ASTCodeBlock in, bool isInitCall = false, std::map<std::string, Object> scopeVals = {}, std::vector<Object> args = {});
std::map<std::string, Object> getVariables();
};