Add indexed access expressions

This commit is contained in:
Sofia 2026-03-17 22:45:43 +02:00
parent 2afe480be1
commit 4ecf6ed3eb
3 changed files with 48 additions and 10 deletions

View File

@ -19,6 +19,7 @@ end
global sometable = {} global sometable = {}
sometable["hello"] = {} sometable["hello"] = {}
sometable["hello"].there = "my dude" sometable["hello"].there = "my dude"
print(sometable.hello.there)
print(max(11.12345, 9)) print(max(11.12345, 9))
print(add(10)(15)) print(add(10)(15))

View File

@ -272,7 +272,7 @@ impl Parse for Statement {
Ok(Self::Assignment( Ok(Self::Assignment(
None, None,
vec![(access.0.0, access.0.1)], vec![(access.0, access.1.0)],
ExpressionList(vec![expression]), ExpressionList(vec![expression]),
)) ))
} else if let Ok(expr) = stream.parse() { } else if let Ok(expr) = stream.parse() {
@ -290,12 +290,10 @@ pub enum AccessModifier {
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct IndexedAccess(Node<String>, Vec<Node<Expression>>); pub struct IndexedAccess(Vec<Node<Expression>>);
impl Parse for IndexedAccess { impl Parse for IndexedAccess {
fn parse(mut stream: TokenStream) -> Result<Self, TokenStreamError> { fn parse(mut stream: TokenStream) -> Result<Self, TokenStreamError> {
let name = stream.parse()?;
let mut expressions = Vec::new(); let mut expressions = Vec::new();
while let Some(Token::Symbol('[') | Token::Symbol('.')) = stream.peek() { while let Some(Token::Symbol('[') | Token::Symbol('.')) = stream.peek() {
match stream.next().unwrap() { match stream.next().unwrap() {
@ -315,18 +313,19 @@ impl Parse for IndexedAccess {
} }
} }
Ok(IndexedAccess(name, expressions)) Ok(IndexedAccess(expressions))
} }
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct IndexedAssignment(IndexedAccess); pub struct IndexedAssignment(Node<String>, IndexedAccess);
impl Parse for IndexedAssignment { impl Parse for IndexedAssignment {
fn parse(mut stream: TokenStream) -> Result<Self, TokenStreamError> { fn parse(mut stream: TokenStream) -> Result<Self, TokenStreamError> {
let name = stream.parse()?;
let access = stream.parse()?; let access = stream.parse()?;
stream.expect_symbol('=')?; stream.expect_symbol('=')?;
Ok(IndexedAssignment(access)) Ok(IndexedAssignment(name, access))
} }
} }
@ -339,6 +338,7 @@ pub enum Expression {
FunctionCall(Box<Node<Expression>>, Node<ExpressionList>), FunctionCall(Box<Node<Expression>>, Node<ExpressionList>),
Literal(Literal), Literal(Literal),
TableConstructor, TableConstructor,
IndexedAccess(Box<Node<Expression>>, Box<Node<Expression>>),
} }
impl Parse for Expression { impl Parse for Expression {
@ -501,9 +501,11 @@ impl Parse for PrimaryExpression {
Expression::ValueRef(stream.parse()?) Expression::ValueRef(stream.parse()?)
}; };
while let Some(Token::Symbol('(') | Token::Symbol('[')) = stream.peek() { while let Some(Token::Symbol('(') | Token::Symbol('[') | Token::Symbol('.')) = stream.peek()
match stream.next().unwrap() { {
match stream.peek().unwrap() {
Token::Symbol('(') => { Token::Symbol('(') => {
stream.next();
let expression_list = stream.parse::<Node<ExpressionList>>()?; let expression_list = stream.parse::<Node<ExpressionList>>()?;
stream.expect(Token::Symbol(')'))?; stream.expect(Token::Symbol(')'))?;
expression = Expression::FunctionCall( expression = Expression::FunctionCall(
@ -514,7 +516,20 @@ impl Parse for PrimaryExpression {
expression_list, expression_list,
); );
} }
Token::Symbol('[') => todo!(), Token::Symbol('[') | Token::Symbol('.') => {
let meta = Metadata::produce(&mut stream, pre.clone());
let IndexedAccess(accesses) = stream.parse()?;
dbg!(&accesses, stream.peek());
for access in accesses {
expression = Expression::IndexedAccess(
Box::new(Node {
kind: expression,
meta: meta.clone(),
}),
Box::new(access),
)
}
}
_ => panic!(), _ => panic!(),
} }
} }

View File

@ -405,6 +405,12 @@ impl Expression {
let constants = HashSet::new(); let constants = HashSet::new();
constants constants
} }
Expression::IndexedAccess(expr, index) => {
let mut constants = HashSet::new();
constants.extend(expr.kind.find_constants(scope));
constants.extend(index.kind.find_constants(scope));
constants
}
} }
} }
@ -630,6 +636,22 @@ impl Expression {
instructions.push(Instruction::NewTable(reg)); instructions.push(Instruction::NewTable(reg));
(instructions, vec![reg]) (instructions, vec![reg])
} }
Expression::IndexedAccess(expr, index) => {
let mut instructions = Vec::new();
let (instr, expr_regs) = expr.kind.compile(state, scope, Some(1));
instructions.extend(instr);
let (instr, index_regs) = index.kind.compile(state, scope, Some(1));
instructions.extend(instr);
let local = scope.register_counter.next();
instructions.push(Instruction::GetTable(
local,
*expr_regs.first().unwrap(),
*index_regs.first().unwrap(),
));
(instructions, vec![local])
}
} }
} }
} }