Add basic tables

This commit is contained in:
Sofia 2026-03-17 18:18:31 +02:00
parent d4da1f9184
commit 8e57def387
5 changed files with 42 additions and 3 deletions

View File

@ -16,6 +16,8 @@ function min(x, y)
return m
end
global sometable = {}
print(max(11, 9))
print(add(10)(15))
print(add(10)(15))

View File

@ -292,6 +292,7 @@ pub enum Expression {
FunctionDefinition(Vec<Node<String>>, Block),
FunctionCall(Box<Node<Expression>>, Node<ExpressionList>),
Literal(Literal),
TableConstructor,
}
impl Parse for Expression {
@ -424,6 +425,10 @@ impl Parse for PrimaryExpression {
} else if let Some(Token::StringLit(value)) = peeked {
stream.next(); // Consume string-literal
Expression::Literal(Literal::String(value))
} else if let Some(Token::Symbol('{')) = peeked {
stream.next();
stream.expect_symbol('}')?;
Expression::TableConstructor
} else {
Expression::ValueRef(stream.parse()?)
};

View File

@ -324,6 +324,10 @@ impl Expression {
constants
}
},
Expression::TableConstructor => {
let constants = HashSet::new();
constants
}
}
}
@ -540,6 +544,12 @@ impl Expression {
));
(instructions, vec![reg])
}
Expression::TableConstructor => {
let mut instructions = Vec::new();
let reg = scope.register_counter.next();
instructions.push(Instruction::NewTable(reg));
(instructions, vec![reg])
}
}
}
}

View File

@ -16,7 +16,7 @@ mod vm;
static TEST: &str = include_str!("../examples/test.lua");
#[derive(Debug)]
#[derive(Debug, PartialEq, Eq)]
pub struct Max;
impl RustFunction for Max {
fn execute(&self, parameters: Vec<vm::Value>) -> Result<Vec<vm::Value>, RuntimeError> {
@ -31,7 +31,7 @@ impl RustFunction for Max {
}
}
}
#[derive(Debug)]
#[derive(Debug, PartialEq, Eq)]
pub struct Print;
impl RustFunction for Print {
fn execute(&self, parameters: Vec<vm::Value>) -> Result<Vec<vm::Value>, RuntimeError> {

View File

@ -1,6 +1,6 @@
use thiserror::Error;
use std::{cell::RefCell, collections::HashMap, fmt::Debug, rc::Rc};
use std::{cell::RefCell, collections::HashMap, fmt::Debug, hash::Hash, rc::Rc};
use crate::{
ast::{BinaryOperator, LuaNumber, UnaryOperator},
@ -43,6 +43,8 @@ pub enum Instruction {
GetUpVal(u16, u16),
/// U[B] := R(A)
SetUpVal(u16, u16),
/// R(A) := {}
NewTable(u16),
/// R(A) := R(B) + R(C)
Add(u16, u16, u16),
/// R(A) := -R(B)
@ -81,6 +83,7 @@ impl Debug for Instruction {
Instruction::GetGlobal(arg0, arg1) => write!(f, "GETGLOBAL {} {}", arg0, arg1),
Instruction::GetUpVal(arg0, arg1) => write!(f, "GETUPVAL {} {}", arg0, arg1),
Instruction::SetUpVal(arg0, arg1) => write!(f, "SETUPVAL {} {}", arg0, arg1),
Instruction::NewTable(arg0) => write!(f, "NEWTABLE {}", arg0),
Instruction::Jmp(arg0) => write!(f, "JMP {}", arg0),
Instruction::Test(arg0, arg1, arg2) => write!(f, "TEST {} {} {}", arg0, arg1, arg2),
Instruction::Call(arg0, arg1, arg2) => write!(f, "CALL {} {} {}", arg0, arg1, arg2),
@ -127,6 +130,15 @@ pub enum Value {
RustFunction(Rc<RefCell<dyn RustFunction>>),
Function(Closure),
Nil,
Table(HashMap<IndexableValue, Value>),
}
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
pub enum IndexableValue {
String(String),
Number(VMNumber),
RustFunction(String),
Function(u32),
}
impl Value {
@ -247,6 +259,13 @@ impl Debug for Value {
.debug_tuple(&format!("Function({})", closure.prototype))
.finish(),
Value::Nil => write!(f, "Nil"),
Value::Table(hash_map) => {
let mut table = f.debug_struct("Table");
for (key, value) in hash_map {
table.field(&format!("{:?}", key), value);
}
table.finish()
}
}
}
}
@ -475,6 +494,9 @@ impl ClosureRunner {
.map(|v| v.borrow().clone())
.unwrap_or(Value::Nil);
}
Instruction::NewTable(reg) => {
self.set_stack(*reg, Value::Table(HashMap::new()));
}
Instruction::Jmp(b) => {
self.program_counter = (self.program_counter as i32 + *b) as usize
}