From ead7ac054d699595f4a90911c27e7f59d5ed5c44 Mon Sep 17 00:00:00 2001 From: numzero Date: Sat, 19 Apr 2025 15:10:41 +0300 Subject: [PATCH] add table expressions --- src/ast.rs | 12 ++++++++++++ src/twopass.rs | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/ast.rs b/src/ast.rs index d811fde..fefbb48 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -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, } +#[derive(Debug, Clone, Default)] +pub struct Table { + pub fields: Vec, +} + +#[derive(Debug, Clone)] +pub struct Field { + pub name: Expression, + pub init: Expression, +} + #[derive(Debug, Clone, Default)] pub struct Function { pub name: Option, diff --git a/src/twopass.rs b/src/twopass.rs index 5acd9c2..2b4cb6a 100644 --- a/src/twopass.rs +++ b/src/twopass.rs @@ -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, } +#[derive(Debug, Clone)] +struct Table { + fields: Vec, +} + +#[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), } } }