diff --git a/reid/src/ast/mod.rs b/reid/src/ast/mod.rs index ad95cf6..7d5c6f5 100644 --- a/reid/src/ast/mod.rs +++ b/reid/src/ast/mod.rs @@ -44,12 +44,13 @@ pub enum ExpressionKind { VariableName(String), Literal(Literal), Array(Vec), - Index(Box, u64), + ArrayIndex(Box, u64), + StructIndex(Box, String), Binop(BinaryOperator, Box, Box), FunctionCall(Box), BlockExpr(Box), IfExpr(Box), - StructInit(StructInit), + StructExpression(StructExpression), } #[derive(Debug, Clone, Copy)] @@ -132,7 +133,7 @@ pub enum ReturnType { } #[derive(Debug, Clone)] -pub struct StructInit { +pub struct StructExpression { name: String, fields: Vec<(String, Expression)>, } @@ -150,7 +151,8 @@ pub struct VariableReference(pub VariableReferenceKind, pub TokenRange); #[derive(Debug, Clone)] pub enum VariableReferenceKind { Name(String, TokenRange), - Index(Box, u64), + ArrayIndex(Box, u64), + StructIndex(Box, String), } #[derive(Debug, Clone)] diff --git a/reid/src/ast/parse.rs b/reid/src/ast/parse.rs index ddfd58a..d1713b3 100644 --- a/reid/src/ast/parse.rs +++ b/reid/src/ast/parse.rs @@ -80,7 +80,7 @@ impl Parse for PrimaryExpression { (stream.peek(), stream.peek2()) { Expression( - Kind::StructInit(stream.parse()?), + Kind::StructExpression(stream.parse()?), stream.get_range().unwrap(), ) } else if let Some(token) = stream.next() { @@ -88,7 +88,7 @@ impl Parse for PrimaryExpression { Token::Identifier(v) => { if let Some(Token::BraceOpen) = stream.peek() { Expression( - Kind::StructInit(stream.parse()?), + Kind::StructExpression(stream.parse()?), stream.get_range().unwrap(), ) } else { @@ -134,11 +134,21 @@ impl Parse for PrimaryExpression { Err(stream.expected_err("expression")?)? }; - while let Ok(ValueIndex(idx)) = stream.parse() { - expr = Expression( - ExpressionKind::Index(Box::new(expr), idx), - stream.get_range().unwrap(), - ); + while let Ok(index) = stream.parse::() { + match index { + ValueIndex::Array(ArrayValueIndex(idx)) => { + expr = Expression( + ExpressionKind::ArrayIndex(Box::new(expr), idx), + stream.get_range().unwrap(), + ); + } + ValueIndex::Struct(StructValueIndex(name)) => { + expr = Expression( + ExpressionKind::StructIndex(Box::new(expr), name), + stream.get_range().unwrap(), + ); + } + } } Ok(PrimaryExpression(expr)) @@ -415,9 +425,9 @@ impl Parse for VariableReference { stream.get_range().unwrap(), ); - while let Ok(ValueIndex(idx)) = stream.parse() { + while let Ok(ArrayValueIndex(idx)) = stream.parse() { var_ref = VariableReference( - VariableReferenceKind::Index(Box::new(var_ref), idx), + VariableReferenceKind::ArrayIndex(Box::new(var_ref), idx), stream.get_range().unwrap(), ); } @@ -429,7 +439,7 @@ impl Parse for VariableReference { } } -impl Parse for StructInit { +impl Parse for StructExpression { fn parse(mut stream: TokenStream) -> Result { let Some(Token::Identifier(name)) = stream.next() else { return Err(stream.expected_err("struct identifier")?); @@ -439,9 +449,8 @@ impl Parse for StructInit { let fields = named_list.0.into_iter().map(|f| (f.0, f.1)).collect(); stream.expect(Token::BraceClose)?; - stream.expect(Token::Semi)?; - Ok(StructInit { name, fields }) + Ok(StructExpression { name, fields }) } } @@ -480,21 +489,51 @@ impl Parse for NamedField { } } -#[derive(Debug, Clone, Copy)] -pub struct ValueIndex(u64); +#[derive(Debug, Clone)] +pub enum ValueIndex { + Array(ArrayValueIndex), + Struct(StructValueIndex), +} impl Parse for ValueIndex { + fn parse(mut stream: TokenStream) -> Result { + match stream.peek() { + Some(Token::BracketOpen) => Ok(ValueIndex::Array(stream.parse()?)), + Some(Token::Dot) => Ok(ValueIndex::Struct(stream.parse()?)), + _ => Err(stream.expected_err("value or struct index")?), + } + } +} + +#[derive(Debug, Clone, Copy)] +pub struct ArrayValueIndex(u64); + +impl Parse for ArrayValueIndex { fn parse(mut stream: TokenStream) -> Result { stream.expect(Token::BracketOpen)?; if let Some(Token::DecimalValue(idx)) = stream.next() { stream.expect(Token::BracketClose)?; - Ok(ValueIndex(idx)) + Ok(ArrayValueIndex(idx)) } else { return Err(stream.expected_err("array index (number)")?); } } } +#[derive(Debug, Clone)] +pub struct StructValueIndex(String); + +impl Parse for StructValueIndex { + fn parse(mut stream: TokenStream) -> Result { + stream.expect(Token::Dot)?; + if let Some(Token::Identifier(name)) = stream.next() { + Ok(StructValueIndex(name)) + } else { + return Err(stream.expected_err("struct index (number)")?); + } + } +} + impl Parse for BlockLevelStatement { fn parse(mut stream: TokenStream) -> Result { use BlockLevelStatement as Stmt; diff --git a/reid/src/ast/process.rs b/reid/src/ast/process.rs index 9c7d7c4..39f8bd5 100644 --- a/reid/src/ast/process.rs +++ b/reid/src/ast/process.rs @@ -152,9 +152,12 @@ impl ast::VariableReferenceKind { (*range).into(), )) } - ast::VariableReferenceKind::Index(var_ref, idx) => { + ast::VariableReferenceKind::ArrayIndex(var_ref, idx) => { mir::IndexedVariableReferenceKind::Index(Box::new(var_ref.process()), *idx) } + ast::VariableReferenceKind::StructIndex(variable_reference, _) => { + todo!("struct indexing into mir") + } } } } @@ -194,12 +197,15 @@ impl ast::Expression { ast::ExpressionKind::Array(expressions) => { mir::ExprKind::Array(expressions.iter().map(|e| e.process()).collect()) } - ast::ExpressionKind::Index(expression, idx) => mir::ExprKind::Index( + ast::ExpressionKind::ArrayIndex(expression, idx) => mir::ExprKind::Index( Box::new(expression.process()), mir::TypeKind::Vague(mir::VagueType::Unknown), *idx, ), - ast::ExpressionKind::StructInit(struct_init) => todo!("implement struct init process"), + ast::ExpressionKind::StructExpression(struct_init) => { + todo!("implement struct init process") + } + ast::ExpressionKind::StructIndex(expression, _) => todo!("struct index expression"), }; mir::Expression(kind, self.1.into())