Add indexed access expressions
This commit is contained in:
parent
2afe480be1
commit
4ecf6ed3eb
@ -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))
|
||||||
|
|||||||
35
src/ast.rs
35
src/ast.rs
@ -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!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user