Иправил баг с выполнением include
This commit is contained in:
@@ -33,24 +33,24 @@ struct Context {
|
||||
std::string getVar(const std::string& name) {
|
||||
if (variables.count(name)) return variables[name];
|
||||
if (parent) return parent->getVar(name);
|
||||
std::cerr << "Runtime Error: Variable '" << name << "' not found." << std::endl; exit(1);
|
||||
throw std::runtime_error("Runtime Error: Variable '" + name + "' not found!");
|
||||
}
|
||||
|
||||
std::vector<std::string>& getArray(const std::string& name) {
|
||||
if (arrays.count(name)) return arrays[name];
|
||||
if (parent) return parent->getArray(name);
|
||||
std::cerr << "Runtime Error: Array '" << name << "' not found." << std::endl; exit(1);
|
||||
throw std::runtime_error("Runtime Error: Array '" + name + "' not found!");
|
||||
}
|
||||
|
||||
void setVar(const std::string& name, const std::string& val) {
|
||||
if (variables.count(name)) { variables[name] = val; return; }
|
||||
if (parent) { parent->setVar(name, val); return; }
|
||||
std::cerr << "Runtime Error: Variable '" << name << "' not defined." << std::endl; exit(1);
|
||||
throw std::runtime_error("Error: Variable '" + name + "' not defined!");
|
||||
}
|
||||
|
||||
void defineVar(const std::string& name, const std::string& val) {
|
||||
if (variables.count(name)) {
|
||||
std::cerr << "Runtime Error: Variable '" << name << "' already defined." << std::endl; exit(1);
|
||||
throw std::runtime_error("Error: Variable '" + name + "' already defined!");
|
||||
}
|
||||
variables[name] = val;
|
||||
}
|
||||
@@ -125,13 +125,13 @@ struct FuncCallNode : Node {
|
||||
std::string eval(Context& ctx) override {
|
||||
auto funcNodeBase = ctx.getFunc(name);
|
||||
if (!funcNodeBase) {
|
||||
std::cerr << "Runtime Error: Function '" << name << "' not found." << std::endl; exit(1);
|
||||
throw std::runtime_error("Runtime Error: Function '" + name + "' not found!");
|
||||
}
|
||||
|
||||
FuncDefNode* funcDef = static_cast<FuncDefNode*>(funcNodeBase.get());
|
||||
|
||||
if (args.size() != funcDef->params.size()) {
|
||||
std::cerr << "Args count mismatch for '" << name << "'" << std::endl; exit(1);
|
||||
throw std::runtime_error("Args count mismatch for '" + name + "'");
|
||||
}
|
||||
|
||||
std::vector<std::string> argValues;
|
||||
|
||||
+1
-2
@@ -87,8 +87,7 @@ std::vector<Token> Lexer::tokenize() {
|
||||
case '<': tokens.push_back({TokenType::LT, "<", line}); break;
|
||||
case '>': tokens.push_back({TokenType::GT, ">", line}); break;
|
||||
default:
|
||||
std::cerr << "Lexer Error: Unknown char '" << current << "' at line " << line << std::endl;
|
||||
exit(1);
|
||||
throw std::runtime_error(std::string("Runtime Error: Unknown character '") + current + "' at line " + std::to_string(line));
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
|
||||
+33
-12
@@ -14,9 +14,8 @@ Parser::Parser(std::vector<Token> t) : tokens(t) {}
|
||||
|
||||
Token Parser::consume(TokenType type) {
|
||||
if (tokens[pos].type == type) return tokens[pos++];
|
||||
std::cerr << "Syntax Error: Expected token " << (int)type
|
||||
<< " got '" << tokens[pos].value << "' line " << tokens[pos].line << std::endl;
|
||||
exit(1);
|
||||
throw std::runtime_error("Syntax Error: Expected token " + std::to_string((int)type) +
|
||||
" got '" + tokens[pos].value + "' line " + std::to_string(tokens[pos].line));
|
||||
}
|
||||
|
||||
std::unique_ptr<Node> Parser::primary() {
|
||||
@@ -82,9 +81,8 @@ std::unique_ptr<Node> Parser::primary() {
|
||||
return n;
|
||||
}
|
||||
|
||||
std::cerr << "Parser Error: Unexpected token '" << tokens[pos].value
|
||||
<< "' at line " << tokens[pos].line << std::endl;
|
||||
exit(1);
|
||||
throw std::runtime_error("Parser Error: Unexpected token '" + tokens[pos].value +
|
||||
"' at line " + std::to_string(tokens[pos].line));
|
||||
}
|
||||
|
||||
std::unique_ptr<Node> Parser::multiplication() {
|
||||
@@ -129,12 +127,35 @@ void processInclude(std::string filename, Context& ctx, std::string currentFile)
|
||||
std::string dir = getDirectory(currentFile);
|
||||
std::string fullPath = dir + filename;
|
||||
std::ifstream file(fullPath);
|
||||
if (!file.is_open()) { file.open(filename); if(!file.is_open()) exit(1); }
|
||||
std::stringstream buffer; buffer << file.rdbuf();
|
||||
|
||||
// Если не нашли по полному пути, ищем рядом с исполняемым файлом
|
||||
if (!file.is_open()) {
|
||||
file.open(filename);
|
||||
if(!file.is_open()) {
|
||||
throw std::runtime_error("Include Error: File '" + filename + "' not found.");
|
||||
}
|
||||
}
|
||||
|
||||
std::stringstream buffer;
|
||||
buffer << file.rdbuf();
|
||||
|
||||
Lexer lexer(buffer.str());
|
||||
Parser parser(lexer.tokenize());
|
||||
parser.globalContext = ctx; parser.currentFile = fullPath; parser.importMode = true;
|
||||
parser.run(); ctx = parser.globalContext;
|
||||
std::vector<Token> tokens = lexer.tokenize();
|
||||
|
||||
Parser parser(tokens);
|
||||
|
||||
// 1. Копируем текущую память внутрь include, чтобы он видел глобальные переменные
|
||||
parser.globalContext = ctx;
|
||||
parser.currentFile = fullPath;
|
||||
|
||||
// ВАЖНО: Мы убрали parser.importMode = true;
|
||||
// Теперь код внутри lib.fox (например, print) БУДЕТ выполняться.
|
||||
parser.importMode = false;
|
||||
|
||||
parser.run();
|
||||
|
||||
// 2. Возвращаем память обратно (функции из lib.fox появятся в main)
|
||||
ctx = parser.globalContext;
|
||||
}
|
||||
|
||||
std::unique_ptr<Node> Parser::statement() {
|
||||
@@ -276,7 +297,7 @@ std::unique_ptr<Node> Parser::statement() {
|
||||
}
|
||||
}
|
||||
|
||||
std::cerr << "Unknown statement " << tokens[pos].value << std::endl; exit(1);
|
||||
throw std::runtime_error("Unknown statement " + tokens[pos].value);
|
||||
}
|
||||
|
||||
void Parser::run() {
|
||||
|
||||
Reference in New Issue
Block a user