Remove interpreter
This commit is contained in:
218
src/state.cpp
218
src/state.cpp
@@ -4,171 +4,143 @@
|
||||
|
||||
namespace camellya {
|
||||
|
||||
State::State(ExecutionMode mode)
|
||||
: execution_mode_(mode),
|
||||
interpreter_(std::make_unique<Interpreter>()),
|
||||
vm_(std::make_unique<VM>()),
|
||||
compiler_(std::make_unique<Compiler>()) {}
|
||||
State::State()
|
||||
: vm_(std::make_unique<VM>()), compiler_(std::make_unique<Compiler>()) {}
|
||||
|
||||
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();
|
||||
|
||||
bool success = execute_program(program);
|
||||
if (success) {
|
||||
last_error_.clear();
|
||||
}
|
||||
return success;
|
||||
} catch (const std::exception& e) {
|
||||
last_error_ = e.what();
|
||||
return false;
|
||||
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();
|
||||
|
||||
bool success = execute_program(program);
|
||||
if (success) {
|
||||
last_error_.clear();
|
||||
}
|
||||
return success;
|
||||
} 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());
|
||||
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);
|
||||
|
||||
if (execution_mode_ == ExecutionMode::INTERPRETER) {
|
||||
interpreter_->global_environment->define(name, func_value);
|
||||
} else {
|
||||
vm_->register_native_function(name, func);
|
||||
}
|
||||
void State::register_function(const std::string &name, NativeFunction func) {
|
||||
auto func_value = std::make_shared<FunctionValue>(name, func);
|
||||
vm_->register_native_function(name, func);
|
||||
}
|
||||
|
||||
ValuePtr State::get_global(const std::string& name) {
|
||||
if (execution_mode_ == ExecutionMode::INTERPRETER) {
|
||||
return interpreter_->global_environment->get(name);
|
||||
} else {
|
||||
return vm_->get_global(name);
|
||||
}
|
||||
ValuePtr State::get_global(const std::string &name) {
|
||||
return vm_->get_global(name);
|
||||
}
|
||||
|
||||
void State::set_global(const std::string& name, ValuePtr value) {
|
||||
if (execution_mode_ == ExecutionMode::INTERPRETER) {
|
||||
interpreter_->global_environment->define(name, value);
|
||||
} else {
|
||||
vm_->set_global(name, value);
|
||||
}
|
||||
void State::set_global(const std::string &name, ValuePtr value) {
|
||||
vm_->set_global(name, value);
|
||||
}
|
||||
|
||||
void State::push_number(double value) {
|
||||
stack_.push_back(std::make_shared<NumberValue>(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_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));
|
||||
stack_.push_back(std::make_shared<BoolValue>(value));
|
||||
}
|
||||
|
||||
void State::push_nil() {
|
||||
stack_.push_back(std::make_shared<NilValue>());
|
||||
}
|
||||
void State::push_nil() { stack_.push_back(std::make_shared<NilValue>()); }
|
||||
|
||||
void State::push_value(ValuePtr value) {
|
||||
stack_.push_back(std::move(value));
|
||||
}
|
||||
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;
|
||||
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 "";
|
||||
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 val = get_stack_value(index);
|
||||
return is_truthy(val);
|
||||
}
|
||||
|
||||
ValuePtr State::to_value(int index) {
|
||||
return get_stack_value(index);
|
||||
}
|
||||
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>());
|
||||
}
|
||||
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);
|
||||
}
|
||||
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];
|
||||
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];
|
||||
}
|
||||
|
||||
bool State::execute_program(const Program& program) {
|
||||
if (execution_mode_ == ExecutionMode::INTERPRETER) {
|
||||
// Use tree-walking interpreter
|
||||
interpreter_->execute(program);
|
||||
return true;
|
||||
} else {
|
||||
// Use VM
|
||||
auto chunk = compiler_->compile(program);
|
||||
if (!chunk) {
|
||||
last_error_ = compiler_->get_error();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool success = vm_->execute(chunk);
|
||||
if (!success) {
|
||||
last_error_ = vm_->get_error();
|
||||
}
|
||||
return success;
|
||||
}
|
||||
bool State::execute_program(const Program &program) {
|
||||
// Use VM
|
||||
auto chunk = compiler_->compile(program);
|
||||
if (!chunk) {
|
||||
last_error_ = compiler_->get_error();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool success = vm_->execute(chunk);
|
||||
if (!success) {
|
||||
last_error_ = vm_->get_error();
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
} // namespace camellya
|
||||
|
||||
111
src/state.h
111
src/state.h
@@ -1,79 +1,66 @@
|
||||
#ifndef CAMELLYA_STATE_H
|
||||
#define CAMELLYA_STATE_H
|
||||
|
||||
#include "compiler.h"
|
||||
#include "lexer.h"
|
||||
#include "parser.h"
|
||||
#include "interpreter.h"
|
||||
#include "vm.h"
|
||||
#include "compiler.h"
|
||||
#include "value.h"
|
||||
#include <string>
|
||||
#include "vm.h"
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace camellya {
|
||||
|
||||
// Execution mode
|
||||
enum class ExecutionMode {
|
||||
INTERPRETER, // Tree-walking interpreter
|
||||
VM // Bytecode VM
|
||||
};
|
||||
|
||||
// Main state class - similar to lua_State
|
||||
class State {
|
||||
public:
|
||||
State(ExecutionMode mode = ExecutionMode::VM);
|
||||
~State() = default;
|
||||
|
||||
// Set execution mode
|
||||
void set_execution_mode(ExecutionMode mode) { execution_mode_ = mode; }
|
||||
ExecutionMode get_execution_mode() const { return execution_mode_; }
|
||||
|
||||
// Execute script from string
|
||||
bool do_string(const std::string& script);
|
||||
|
||||
// Execute script from file
|
||||
bool do_file(const std::string& filename);
|
||||
|
||||
// Register native function
|
||||
void register_function(const std::string& name, NativeFunction func);
|
||||
|
||||
// Get global variable
|
||||
ValuePtr get_global(const std::string& name);
|
||||
|
||||
// Set global variable
|
||||
void set_global(const std::string& name, ValuePtr value);
|
||||
|
||||
// Stack operations (Lua-like API)
|
||||
void push_number(double value);
|
||||
void push_string(const std::string& value);
|
||||
void push_bool(bool value);
|
||||
void push_nil();
|
||||
void push_value(ValuePtr value);
|
||||
|
||||
double to_number(int index);
|
||||
std::string to_string(int index);
|
||||
bool to_bool(int index);
|
||||
ValuePtr to_value(int index);
|
||||
|
||||
int get_top() const { return static_cast<int>(stack_.size()); }
|
||||
void set_top(int index);
|
||||
void pop(int n = 1);
|
||||
|
||||
// Error handling
|
||||
const std::string& get_error() const { return last_error_; }
|
||||
|
||||
State();
|
||||
~State() = default;
|
||||
|
||||
// Execute script from string
|
||||
bool do_string(const std::string &script);
|
||||
|
||||
// Execute script from file
|
||||
bool do_file(const std::string &filename);
|
||||
|
||||
// Register native function
|
||||
void register_function(const std::string &name, NativeFunction func);
|
||||
|
||||
// Get global variable
|
||||
ValuePtr get_global(const std::string &name);
|
||||
|
||||
// Set global variable
|
||||
void set_global(const std::string &name, ValuePtr value);
|
||||
|
||||
// Stack operations (Lua-like API)
|
||||
void push_number(double value);
|
||||
void push_string(const std::string &value);
|
||||
void push_bool(bool value);
|
||||
void push_nil();
|
||||
void push_value(ValuePtr value);
|
||||
|
||||
double to_number(int index);
|
||||
std::string to_string(int index);
|
||||
bool to_bool(int index);
|
||||
ValuePtr to_value(int index);
|
||||
|
||||
int get_top() const { return static_cast<int>(stack_.size()); }
|
||||
void set_top(int index);
|
||||
void pop(int n = 1);
|
||||
|
||||
// Error handling
|
||||
const std::string &get_error() const { return last_error_; }
|
||||
|
||||
private:
|
||||
ExecutionMode execution_mode_;
|
||||
std::unique_ptr<Interpreter> interpreter_;
|
||||
std::unique_ptr<VM> vm_;
|
||||
std::unique_ptr<Compiler> compiler_;
|
||||
std::vector<ValuePtr> stack_;
|
||||
std::string last_error_;
|
||||
|
||||
ValuePtr get_stack_value(int index);
|
||||
|
||||
// Helper for execution
|
||||
bool execute_program(const Program& program);
|
||||
std::unique_ptr<VM> vm_;
|
||||
std::unique_ptr<Compiler> compiler_;
|
||||
std::vector<ValuePtr> stack_;
|
||||
std::string last_error_;
|
||||
|
||||
ValuePtr get_stack_value(int index);
|
||||
|
||||
// Helper for execution
|
||||
bool execute_program(const Program &program);
|
||||
};
|
||||
|
||||
} // namespace camellya
|
||||
|
||||
Reference in New Issue
Block a user