diff --git a/lib/edlang_ast/src/lib.rs b/lib/edlang_ast/src/lib.rs index d70c7643f..c2f77e27f 100644 --- a/lib/edlang_ast/src/lib.rs +++ b/lib/edlang_ast/src/lib.rs @@ -1,3 +1,5 @@ +use std::collections::{BTreeMap, HashMap}; + pub use edlang_span::Span; #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -167,6 +169,7 @@ pub struct Struct { pub enum Expression { Value(ValueExpr), FnCall(FnCallExpr), + StructInit(StructInitExpr), Unary(UnaryOp, Box), Binary(Box, BinaryOp, Box), Deref(Box), @@ -183,6 +186,19 @@ pub enum ValueExpr { Path(PathExpr), } +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct StructInitField { + pub value: Expression, + pub span: Span, +} + +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct StructInitExpr { + pub name: Ident, + pub fields: BTreeMap, + pub span: Span, +} + #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct FnCallExpr { pub name: Ident, diff --git a/lib/edlang_lowering/src/lib.rs b/lib/edlang_lowering/src/lib.rs index 0457585ee..c3efa6768 100644 --- a/lib/edlang_lowering/src/lib.rs +++ b/lib/edlang_lowering/src/lib.rs @@ -491,6 +491,7 @@ fn find_expr_type(builder: &mut BodyBuilder, info: &ast::Expression) -> Option todo!(), ast::Expression::AsRef(_, _) => todo!(), + ast::Expression::StructInit(_) => todo!(), }) } @@ -556,6 +557,7 @@ fn lower_expr( (value, ty) } + ast::Expression::StructInit(_) => todo!(), } } diff --git a/lib/edlang_parser/src/grammar.lalrpop b/lib/edlang_parser/src/grammar.lalrpop index ad6658a62..b733021dc 100644 --- a/lib/edlang_parser/src/grammar.lalrpop +++ b/lib/edlang_parser/src/grammar.lalrpop @@ -212,6 +212,13 @@ pub(crate) LetStmt: ast::LetStmt = { value, span: ast::Span::new(lo, hi), }, + "let" ":" "=" => ast::LetStmt { + is_mut: is_mut.is_some(), + name, + r#type: target_type, + value: ast::Expression::StructInit(value), + span: ast::Span::new(lo, hi), + }, } pub(crate) AssignStmt: ast::AssignStmt = { @@ -221,6 +228,12 @@ pub(crate) AssignStmt: ast::AssignStmt = { deref_times: deref.len(), span: ast::Span::new(lo, hi), }, + "=" => ast::AssignStmt { + name, + value: ast::Expression::StructInit(value), + deref_times: deref.len(), + span: ast::Span::new(lo, hi), + }, } pub(crate) ReturnStmt: ast::ReturnStmt = { @@ -272,6 +285,7 @@ pub(crate) Term: ast::Expression = { #[precedence(level="0")] => ast::Expression::Value(<>), => ast::Expression::FnCall(<>), + "(" ")" => ast::Expression::StructInit(<>), #[precedence(level="2")] #[assoc(side="left")] "(" ")", } @@ -355,6 +369,25 @@ pub(crate) ValueExpr: ast::ValueExpr = { => ast::ValueExpr::Path(<>), } +pub(crate) StructInitField: (ast::Ident, ast::StructInitField) = { + ":" => (name, ast::StructInitField { + value, + span: ast::Span::new(lo, hi), + }), + ":" => (name, ast::StructInitField { + value: ast::Expression::StructInit(value), + span: ast::Span::new(lo, hi), + }) +} + +pub(crate) StructInitExpr: ast::StructInitExpr = { + "{" > "}" => ast::StructInitExpr { + name, + fields: fields.into_iter().collect(), + span: ast::Span::new(lo, hi), + } +} + pub(crate) RefType: ast::RefType = { "&" => ast::RefType::Not, "&" "mut" => ast::RefType::Mut,