Add indexed access expressions
This commit is contained in:
parent
2afe480be1
commit
4ecf6ed3eb
@ -19,6 +19,7 @@ end
|
||||
global sometable = {}
|
||||
sometable["hello"] = {}
|
||||
sometable["hello"].there = "my dude"
|
||||
print(sometable.hello.there)
|
||||
|
||||
print(max(11.12345, 9))
|
||||
print(add(10)(15))
|
||||
|
||||
35
src/ast.rs
35
src/ast.rs
@ -272,7 +272,7 @@ impl Parse for Statement {
|
||||
|
||||
Ok(Self::Assignment(
|
||||
None,
|
||||
vec![(access.0.0, access.0.1)],
|
||||
vec![(access.0, access.1.0)],
|
||||
ExpressionList(vec![expression]),
|
||||
))
|
||||
} else if let Ok(expr) = stream.parse() {
|
||||
@ -290,12 +290,10 @@ pub enum AccessModifier {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct IndexedAccess(Node<String>, Vec<Node<Expression>>);
|
||||
pub struct IndexedAccess(Vec<Node<Expression>>);
|
||||
|
||||
impl Parse for IndexedAccess {
|
||||
fn parse(mut stream: TokenStream) -> Result<Self, TokenStreamError> {
|
||||
let name = stream.parse()?;
|
||||
|
||||
let mut expressions = Vec::new();
|
||||
while let Some(Token::Symbol('[') | Token::Symbol('.')) = stream.peek() {
|
||||
match stream.next().unwrap() {
|
||||
@ -315,18 +313,19 @@ impl Parse for IndexedAccess {
|
||||
}
|
||||
}
|
||||
|
||||
Ok(IndexedAccess(name, expressions))
|
||||
Ok(IndexedAccess(expressions))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct IndexedAssignment(IndexedAccess);
|
||||
pub struct IndexedAssignment(Node<String>, IndexedAccess);
|
||||
|
||||
impl Parse for IndexedAssignment {
|
||||
fn parse(mut stream: TokenStream) -> Result<Self, TokenStreamError> {
|
||||
let name = stream.parse()?;
|
||||
let access = stream.parse()?;
|
||||
stream.expect_symbol('=')?;
|
||||
Ok(IndexedAssignment(access))
|
||||
Ok(IndexedAssignment(name, access))
|
||||
}
|
||||
}
|
||||
|
||||
@ -339,6 +338,7 @@ pub enum Expression {
|
||||
FunctionCall(Box<Node<Expression>>, Node<ExpressionList>),
|
||||
Literal(Literal),
|
||||
TableConstructor,
|
||||
IndexedAccess(Box<Node<Expression>>, Box<Node<Expression>>),
|
||||
}
|
||||
|
||||
impl Parse for Expression {
|
||||
@ -501,9 +501,11 @@ impl Parse for PrimaryExpression {
|
||||
Expression::ValueRef(stream.parse()?)
|
||||
};
|
||||
|
||||
while let Some(Token::Symbol('(') | Token::Symbol('[')) = stream.peek() {
|
||||
match stream.next().unwrap() {
|
||||
while let Some(Token::Symbol('(') | Token::Symbol('[') | Token::Symbol('.')) = stream.peek()
|
||||
{
|
||||
match stream.peek().unwrap() {
|
||||
Token::Symbol('(') => {
|
||||
stream.next();
|
||||
let expression_list = stream.parse::<Node<ExpressionList>>()?;
|
||||
stream.expect(Token::Symbol(')'))?;
|
||||
expression = Expression::FunctionCall(
|
||||
@ -514,7 +516,20 @@ impl Parse for PrimaryExpression {
|
||||
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!(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -405,6 +405,12 @@ impl Expression {
|
||||
let constants = HashSet::new();
|
||||
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, 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])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user