add table expressions

This commit is contained in:
numzero 2025-04-19 15:10:41 +03:00
parent 5138ada816
commit ead7ac054d
2 changed files with 51 additions and 0 deletions

View File

@ -30,6 +30,7 @@ pub enum Expression {
Variable(Location),
Call(Call),
Function(Function),
Table(Table),
}
#[derive(Debug, Clone)]
@ -38,6 +39,17 @@ pub struct Call {
pub args: Vec<Expression>,
}
#[derive(Debug, Clone, Default)]
pub struct Table {
pub fields: Vec<Field>,
}
#[derive(Debug, Clone)]
pub struct Field {
pub name: Expression,
pub init: Expression,
}
#[derive(Debug, Clone, Default)]
pub struct Function {
pub name: Option<Ident>,

View File

@ -48,6 +48,7 @@ enum Expression {
Variable(Location),
Call(Call),
Function(Function),
Table(Table),
}
#[derive(Debug, Clone)]
@ -56,6 +57,17 @@ struct Call {
args: Vec<Expression>,
}
#[derive(Debug, Clone)]
struct Table {
fields: Vec<TableField>,
}
#[derive(Debug, Clone)]
struct TableField {
key: Expression,
value: Expression,
}
mod scope {
use std::collections::HashMap;
@ -174,6 +186,7 @@ fn build_expression(scope: &BuildContext<'_>, code: &ast::Expression) -> Express
ast::Expression::Variable(loc) => Expression::Variable(lookup(scope, loc)),
ast::Expression::Call(call) => Expression::Call(build_call(scope, call)),
ast::Expression::Function(f) => Expression::Function(build_function(scope, f)),
ast::Expression::Table(table) => Expression::Table(build_table(scope, table)),
}
}
@ -193,6 +206,19 @@ fn build_call(scope: &BuildContext<'_>, code: &ast::Call) -> Call {
}
}
fn build_table(scope: &BuildContext<'_>, code: &ast::Table) -> Table {
Table {
fields: code
.fields
.iter()
.map(|field| TableField {
key: build_expression(scope, &field.name),
value: build_expression(scope, &field.init),
})
.collect(),
}
}
fn build_function(parent: &BuildContext<'_>, code: &ast::Function) -> Function {
let scope = BuildContext {
parent: Some(parent),
@ -336,6 +362,18 @@ impl Eval for Function {
}
}
impl Eval for Table {
fn eval(&self, ctx: &RunContext) -> types::Value {
let table = types::Table::default();
for field in &self.fields {
let key = field.key.eval(ctx).expect("attempt to set a nil index");
let value = field.value.eval(ctx);
table.set(key, value);
}
Some(table.into())
}
}
impl Eval for Expression {
fn eval(&self, ctx: &RunContext) -> types::Value {
match self {
@ -343,6 +381,7 @@ impl Eval for Expression {
Expression::Variable(inner) => inner.eval(ctx),
Expression::Call(inner) => inner.eval(ctx),
Expression::Function(inner) => inner.eval(ctx),
Expression::Table(inner) => inner.eval(ctx),
}
}
}