diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/rebel-lang/src/scope.rs | 22 | ||||
-rw-r--r-- | crates/rebel-parse/src/ast/mod.rs | 19 | ||||
-rw-r--r-- | crates/rebel-parse/src/ast/pat.rs | 6 | ||||
-rw-r--r-- | crates/rebel-parse/src/grammar/recipe.rs | 12 |
4 files changed, 30 insertions, 29 deletions
diff --git a/crates/rebel-lang/src/scope.rs b/crates/rebel-lang/src/scope.rs index 4df0909..e935a07 100644 --- a/crates/rebel-lang/src/scope.rs +++ b/crates/rebel-lang/src/scope.rs @@ -1,6 +1,6 @@ use std::{collections::HashMap, ops::Deref}; -use rebel_parse::ast::{self, expr}; +use rebel_parse::ast::{self, pat}; use crate::{ func::Func, @@ -28,16 +28,10 @@ impl Context { let typ = Type::ast_expr_type(self, expr)?; // TODO: Handle explicit type - let ast::TypedExpr { - expr: dest_expr, - typ: _, - } = dest.deref(); + let ast::TypedPat { pat, typ: _ } = dest.deref(); // TODO: Handle other assignable expressions - let dest_path = match dest_expr { - expr::Expr::Path(path) => path, - _ => return Err(TypeError), - }; + let pat::Pat::Path(dest_path) = pat; let [dest_ident] = dest_path.components[..] else { return Err(TypeError); }; @@ -66,16 +60,10 @@ impl Context { let typ = value.typ().or(Err(EvalError))?; // TODO: Handle explicit type - let ast::TypedExpr { - expr: dest_expr, - typ: _, - } = dest.deref(); + let ast::TypedPat { pat, typ: _ } = dest.deref(); // TODO: Handle other assignable expressions - let dest_path = match dest_expr { - expr::Expr::Path(path) => path, - _ => return Err(EvalError), - }; + let pat::Pat::Path(dest_path) = pat; let [dest_ident] = dest_path.components[..] else { return Err(EvalError); }; diff --git a/crates/rebel-parse/src/ast/mod.rs b/crates/rebel-parse/src/ast/mod.rs index 14233dc..b439873 100644 --- a/crates/rebel-parse/src/ast/mod.rs +++ b/crates/rebel-parse/src/ast/mod.rs @@ -1,7 +1,9 @@ pub mod expr; +pub mod pat; pub mod typ; use expr::*; +use pat::Pat; use typ::Type; pub type Recipe<'a> = Vec<RecipeStmt<'a>>; @@ -52,7 +54,7 @@ impl<'a> Body<'a> { #[derive(Debug, Clone, PartialEq, Eq)] pub enum BodyStmt<'a> { Assign { - dest: Box<TypedExpr<'a>>, + dest: Box<TypedPat<'a>>, expr: Box<Expr<'a>>, }, Expr { @@ -63,14 +65,16 @@ pub enum BodyStmt<'a> { impl<'a> BodyStmt<'a> { pub(crate) fn assign( - dest: TypedExpr<'a>, + dest: TypedPat<'a>, op: Option<OpBinary>, swapped: bool, expr: Expr<'a>, ) -> Self { let expr = match op { Some(op) => { - let dest_expr = dest.expr.clone(); + let dest_expr = match &dest.pat { + Pat::Path(path) => Expr::Path(path.clone()), + }; if swapped { Expr::binary(expr, op, dest_expr) } else { @@ -87,9 +91,8 @@ impl<'a> BodyStmt<'a> { pub fn validate(&self) -> Result<(), ValidationError> { match self { - BodyStmt::Assign { dest, expr } => { - // TODO: Extend destination validation - dest.expr.validate()?; + BodyStmt::Assign { dest: _, expr } => { + // TODO: Destination validation expr.validate() } BodyStmt::Expr { expr } => expr.validate(), @@ -99,8 +102,8 @@ impl<'a> BodyStmt<'a> { } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct TypedExpr<'a> { - pub expr: Expr<'a>, +pub struct TypedPat<'a> { + pub pat: Pat<'a>, pub typ: Option<Type<'a>>, } diff --git a/crates/rebel-parse/src/ast/pat.rs b/crates/rebel-parse/src/ast/pat.rs new file mode 100644 index 0000000..a376956 --- /dev/null +++ b/crates/rebel-parse/src/ast/pat.rs @@ -0,0 +1,6 @@ +use super::*; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum Pat<'a> { + Path(Path<'a>), +} diff --git a/crates/rebel-parse/src/grammar/recipe.rs b/crates/rebel-parse/src/grammar/recipe.rs index d00c672..68d43dc 100644 --- a/crates/rebel-parse/src/grammar/recipe.rs +++ b/crates/rebel-parse/src/grammar/recipe.rs @@ -2,6 +2,7 @@ use crate::{ ast::{ self, expr::{self, Expr}, + pat::Pat, typ::{self, Type}, }, token::*, @@ -33,10 +34,10 @@ peg::parser! { = body:body_stmt() ++ p(';') { ast::Body(body) } pub rule body_stmt() -> ast::BodyStmt<'a> - = dest:typed_expr() op:assign_op() expr:expr() { + = dest:typed_pat() op:assign_op() expr:expr() { ast::BodyStmt::assign(dest, op, false, expr) } - / dest:typed_expr() p2('=', '+') expr:expr() { + / dest:typed_pat() p2('=', '+') expr:expr() { ast::BodyStmt::assign(dest, Some(Add), true, expr) } / expr:expr() { @@ -52,8 +53,8 @@ peg::parser! { / p2('/', '=') { Some(Div) } / p2('%', '=') { Some(Rem) } - rule typed_expr() -> ast::TypedExpr<'a> - = expr:expr() typ:tagged(<p(':')>, <typ()>)? { ast::TypedExpr { expr, typ } } + rule typed_pat() -> ast::TypedPat<'a> + = pat:pat() typ:tagged(<p(':')>, <typ()>)? { ast::TypedPat { pat, typ } } rule typ() -> Type<'a> = lit:typ_literal() { Type::Literal(lit) } @@ -75,6 +76,9 @@ peg::parser! { typ::Literal::Struct(entries) } + rule pat() -> Pat<'a> + = path:path() { Pat::Path(path) } + rule struct_field_typ() -> typ::StructField<'a> = field:field() p(':') typ:typ() { typ::StructField { name: field.name, typ } |