Add SETTABLE
This commit is contained in:
parent
8e57def387
commit
83bccbbf4d
@ -30,6 +30,10 @@ impl RustFunction for Max {
|
|||||||
_ => Ok(vec![vm::Value::Nil]),
|
_ => Ok(vec![vm::Value::Nil]),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn as_indexable(&self) -> String {
|
||||||
|
"std::max".to_owned()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct Print;
|
pub struct Print;
|
||||||
@ -38,6 +42,10 @@ impl RustFunction for Print {
|
|||||||
println!("{:?}", parameters);
|
println!("{:?}", parameters);
|
||||||
Ok(Vec::new())
|
Ok(Vec::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn as_indexable(&self) -> String {
|
||||||
|
"std::print".to_owned()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compile(
|
fn compile(
|
||||||
|
|||||||
63
src/vm.rs
63
src/vm.rs
@ -1,6 +1,12 @@
|
|||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use std::{cell::RefCell, collections::HashMap, fmt::Debug, hash::Hash, rc::Rc};
|
use std::{
|
||||||
|
cell::{RefCell, RefMut},
|
||||||
|
collections::HashMap,
|
||||||
|
fmt::Debug,
|
||||||
|
hash::Hash,
|
||||||
|
rc::Rc,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{BinaryOperator, LuaNumber, UnaryOperator},
|
ast::{BinaryOperator, LuaNumber, UnaryOperator},
|
||||||
@ -43,6 +49,8 @@ pub enum Instruction {
|
|||||||
GetUpVal(u16, u16),
|
GetUpVal(u16, u16),
|
||||||
/// U[B] := R(A)
|
/// U[B] := R(A)
|
||||||
SetUpVal(u16, u16),
|
SetUpVal(u16, u16),
|
||||||
|
/// R(A)[R(B)] := R(C)
|
||||||
|
SetTable(u16, u16, u16),
|
||||||
/// R(A) := {}
|
/// R(A) := {}
|
||||||
NewTable(u16),
|
NewTable(u16),
|
||||||
/// R(A) := R(B) + R(C)
|
/// R(A) := R(B) + R(C)
|
||||||
@ -83,6 +91,9 @@ impl Debug for Instruction {
|
|||||||
Instruction::GetGlobal(arg0, arg1) => write!(f, "GETGLOBAL {} {}", arg0, arg1),
|
Instruction::GetGlobal(arg0, arg1) => write!(f, "GETGLOBAL {} {}", arg0, arg1),
|
||||||
Instruction::GetUpVal(arg0, arg1) => write!(f, "GETUPVAL {} {}", arg0, arg1),
|
Instruction::GetUpVal(arg0, arg1) => write!(f, "GETUPVAL {} {}", arg0, arg1),
|
||||||
Instruction::SetUpVal(arg0, arg1) => write!(f, "SETUPVAL {} {}", arg0, arg1),
|
Instruction::SetUpVal(arg0, arg1) => write!(f, "SETUPVAL {} {}", arg0, arg1),
|
||||||
|
Instruction::SetTable(arg0, arg1, arg2) => {
|
||||||
|
write!(f, "SETTABLE {} {} {}", arg0, arg1, arg2)
|
||||||
|
}
|
||||||
Instruction::NewTable(arg0) => write!(f, "NEWTABLE {}", arg0),
|
Instruction::NewTable(arg0) => write!(f, "NEWTABLE {}", arg0),
|
||||||
Instruction::Jmp(arg0) => write!(f, "JMP {}", arg0),
|
Instruction::Jmp(arg0) => write!(f, "JMP {}", arg0),
|
||||||
Instruction::Test(arg0, arg1, arg2) => write!(f, "TEST {} {} {}", arg0, arg1, arg2),
|
Instruction::Test(arg0, arg1, arg2) => write!(f, "TEST {} {} {}", arg0, arg1, arg2),
|
||||||
@ -114,6 +125,8 @@ pub enum RuntimeError {
|
|||||||
TriedCallingNonFunction(Value),
|
TriedCallingNonFunction(Value),
|
||||||
#[error("Global not found: {0:?}")]
|
#[error("Global not found: {0:?}")]
|
||||||
GlobalNotFound(Option<Constant>),
|
GlobalNotFound(Option<Constant>),
|
||||||
|
#[error("Unable to index tables with {0:?}")]
|
||||||
|
InvalidTableIndex(Value),
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
Custom(String),
|
Custom(String),
|
||||||
}
|
}
|
||||||
@ -133,6 +146,21 @@ pub enum Value {
|
|||||||
Table(HashMap<IndexableValue, Value>),
|
Table(HashMap<IndexableValue, Value>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Value {
|
||||||
|
pub fn as_indexable(self) -> Result<IndexableValue, RuntimeError> {
|
||||||
|
match self {
|
||||||
|
Value::String(value) => Ok(IndexableValue::String(value)),
|
||||||
|
Value::Number(value) => Ok(IndexableValue::Number(value)),
|
||||||
|
Value::RustFunction(value) => {
|
||||||
|
Ok(IndexableValue::RustFunction(value.borrow().as_indexable()))
|
||||||
|
}
|
||||||
|
Value::Function(closure) => Ok(IndexableValue::Function(closure.prototype)),
|
||||||
|
Value::Nil => Err(RuntimeError::InvalidTableIndex(self)),
|
||||||
|
Value::Table(_) => Err(RuntimeError::InvalidTableIndex(self)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
|
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
|
||||||
pub enum IndexableValue {
|
pub enum IndexableValue {
|
||||||
String(String),
|
String(String),
|
||||||
@ -272,6 +300,7 @@ impl Debug for Value {
|
|||||||
|
|
||||||
pub trait RustFunction: Debug {
|
pub trait RustFunction: Debug {
|
||||||
fn execute(&self, parameters: Vec<Value>) -> Result<Vec<Value>, RuntimeError>;
|
fn execute(&self, parameters: Vec<Value>) -> Result<Vec<Value>, RuntimeError>;
|
||||||
|
fn as_indexable(&self) -> String;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -494,6 +523,38 @@ impl ClosureRunner {
|
|||||||
.map(|v| v.borrow().clone())
|
.map(|v| v.borrow().clone())
|
||||||
.unwrap_or(Value::Nil);
|
.unwrap_or(Value::Nil);
|
||||||
}
|
}
|
||||||
|
Instruction::SetTable(tablereg, indexreg, valuereg) => {
|
||||||
|
let table = self.stack.get(tablereg);
|
||||||
|
match table {
|
||||||
|
Some(value) => {
|
||||||
|
let mut table = value.borrow_mut();
|
||||||
|
if let Value::Table(table) = &mut *table {
|
||||||
|
let index_value = self
|
||||||
|
.stack
|
||||||
|
.get(indexreg)
|
||||||
|
.map(|v| v.borrow().clone())
|
||||||
|
.unwrap_or(Value::Nil)
|
||||||
|
.as_indexable()?;
|
||||||
|
let value = self
|
||||||
|
.stack
|
||||||
|
.get(valuereg)
|
||||||
|
.map(|v| v.borrow().clone())
|
||||||
|
.unwrap_or(Value::Nil);
|
||||||
|
match value {
|
||||||
|
Value::Nil => {
|
||||||
|
table.remove(&index_value);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
table.insert(index_value, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => todo!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
Instruction::NewTable(reg) => {
|
Instruction::NewTable(reg) => {
|
||||||
self.set_stack(*reg, Value::Table(HashMap::new()));
|
self.set_stack(*reg, Value::Table(HashMap::new()));
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user