init
This commit is contained in:
135
state.cpp
Normal file
135
state.cpp
Normal file
@@ -0,0 +1,135 @@
|
||||
#include "state.h"
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
namespace camellya {
|
||||
|
||||
State::State() : interpreter_(std::make_unique<Interpreter>()) {}
|
||||
|
||||
bool State::do_string(const std::string& script) {
|
||||
try {
|
||||
Lexer lexer(script);
|
||||
auto tokens = lexer.tokenize();
|
||||
|
||||
Parser parser(std::move(tokens));
|
||||
Program program = parser.parse();
|
||||
|
||||
interpreter_->execute(program);
|
||||
|
||||
last_error_.clear();
|
||||
return true;
|
||||
} catch (const std::exception& e) {
|
||||
last_error_ = e.what();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool State::do_file(const std::string& filename) {
|
||||
std::ifstream file(filename);
|
||||
if (!file.is_open()) {
|
||||
last_error_ = "Failed to open file: " + filename;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::stringstream buffer;
|
||||
buffer << file.rdbuf();
|
||||
return do_string(buffer.str());
|
||||
}
|
||||
|
||||
void State::register_function(const std::string& name, NativeFunction func) {
|
||||
auto func_value = std::make_shared<FunctionValue>(name, func);
|
||||
interpreter_->global_environment->define(name, func_value);
|
||||
}
|
||||
|
||||
ValuePtr State::get_global(const std::string& name) {
|
||||
return interpreter_->global_environment->get(name);
|
||||
}
|
||||
|
||||
void State::set_global(const std::string& name, ValuePtr value) {
|
||||
interpreter_->global_environment->define(name, value);
|
||||
}
|
||||
|
||||
void State::push_number(double value) {
|
||||
stack_.push_back(std::make_shared<NumberValue>(value));
|
||||
}
|
||||
|
||||
void State::push_string(const std::string& value) {
|
||||
stack_.push_back(std::make_shared<StringValue>(value));
|
||||
}
|
||||
|
||||
void State::push_bool(bool value) {
|
||||
stack_.push_back(std::make_shared<BoolValue>(value));
|
||||
}
|
||||
|
||||
void State::push_nil() {
|
||||
stack_.push_back(std::make_shared<NilValue>());
|
||||
}
|
||||
|
||||
void State::push_value(ValuePtr value) {
|
||||
stack_.push_back(std::move(value));
|
||||
}
|
||||
|
||||
double State::to_number(int index) {
|
||||
ValuePtr val = get_stack_value(index);
|
||||
if (val && val->type() == Type::NUMBER) {
|
||||
return std::dynamic_pointer_cast<NumberValue>(val)->value;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
std::string State::to_string(int index) {
|
||||
ValuePtr val = get_stack_value(index);
|
||||
if (val) {
|
||||
return val->to_string();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
bool State::to_bool(int index) {
|
||||
ValuePtr val = get_stack_value(index);
|
||||
return is_truthy(val);
|
||||
}
|
||||
|
||||
ValuePtr State::to_value(int index) {
|
||||
return get_stack_value(index);
|
||||
}
|
||||
|
||||
void State::set_top(int index) {
|
||||
if (index < 0) {
|
||||
index = static_cast<int>(stack_.size()) + index + 1;
|
||||
}
|
||||
|
||||
if (index < 0) {
|
||||
stack_.clear();
|
||||
} else if (static_cast<size_t>(index) < stack_.size()) {
|
||||
stack_.resize(index);
|
||||
} else {
|
||||
while (static_cast<size_t>(index) > stack_.size()) {
|
||||
stack_.push_back(std::make_shared<NilValue>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void State::pop(int n) {
|
||||
if (n > static_cast<int>(stack_.size())) {
|
||||
stack_.clear();
|
||||
} else {
|
||||
stack_.resize(stack_.size() - n);
|
||||
}
|
||||
}
|
||||
|
||||
ValuePtr State::get_stack_value(int index) {
|
||||
if (index < 0) {
|
||||
index = static_cast<int>(stack_.size()) + index;
|
||||
} else {
|
||||
index -= 1; // Convert to 0-based
|
||||
}
|
||||
|
||||
if (index < 0 || static_cast<size_t>(index) >= stack_.size()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return stack_[index];
|
||||
}
|
||||
|
||||
} // namespace camellya
|
||||
Reference in New Issue
Block a user