diff --git a/compiler/erg_common/traits.rs b/compiler/erg_common/traits.rs index f502a251..aaa0248d 100644 --- a/compiler/erg_common/traits.rs +++ b/compiler/erg_common/traits.rs @@ -525,14 +525,74 @@ pub trait HasType { #[macro_export] macro_rules! impl_t { - ($T: ty, $t: ident) => { - impl erg_common::traits::HasType for $T { + ($T: ty) => { + impl $crate::traits::HasType for $T { #[inline] - fn ref_t(&self) -> &common::ty::Type { - &common::ty::Type::$t + fn ref_t(&self) -> &Type { + &self.t + } + #[inline] + fn ref_mut_t(&mut self) -> &mut Type { + &mut self.t + } + #[inline] + fn signature_t(&self) -> Option<&Type> { + None + } + #[inline] + fn signature_mut_t(&mut self) -> Option<&mut Type> { + None } } }; + ($T: ty, $sig_t: ident) => { + impl $crate::traits::HasType for $T { + #[inline] + fn ref_t(&self) -> &Type { + &self.t + } + #[inline] + fn ref_mut_t(&mut self) -> &mut Type { + &mut self.t + } + #[inline] + fn signature_t(&self) -> Option<&Type> { + Some(&self.$sig_t) + } + #[inline] + fn signature_mut_t(&mut self) -> Option<&mut Type> { + &mut self.$sig_t + } + } + }; +} + +#[macro_export] +macro_rules! impl_t_for_enum { + ($Enum: ident; $($Variant: ident $(,)?)*) => { + impl $crate::traits::HasType for $Enum { + fn ref_t(&self) -> &Type { + match self { + $($Enum::$Variant(v) => v.ref_t(),)* + } + } + fn ref_mut_t(&mut self) -> &mut Type { + match self { + $($Enum::$Variant(v) => v.ref_mut_t(),)* + } + } + fn signature_t(&self) -> Option<&Type> { + match self { + $($Enum::$Variant(v) => v.signature_t(),)* + } + } + fn signature_mut_t(&mut self) -> Option<&mut Type> { + match self { + $($Enum::$Variant(v) => v.signature_mut_t(),)* + } + } + } + } } /// Pythonではis演算子に相当 diff --git a/compiler/erg_compiler/codegen.rs b/compiler/erg_compiler/codegen.rs index 851308cf..ea1d2afa 100644 --- a/compiler/erg_compiler/codegen.rs +++ b/compiler/erg_compiler/codegen.rs @@ -25,7 +25,7 @@ use erg_parser::token::{Token, TokenCategory, TokenKind}; use crate::compile::{AccessKind, Name, StoreLoadKind}; use crate::error::{CompileError, CompileErrors, CompileResult}; use crate::hir::{ - Accessor, Args, Block, DefBody, Expr, Signature, SubrSignature, VarSignature, HIR, + Accessor, Args, Array, Block, DefBody, Expr, Signature, SubrSignature, VarSignature, HIR, }; use AccessKind::*; @@ -1051,19 +1051,22 @@ impl CodeGenerator { } } // TODO: list comprehension - Expr::Array(mut arr) => { - let len = arr.elems.len(); - while let Some(arg) = arr.elems.try_remove_pos(0) { - self.codegen_expr(arg.expr); + Expr::Array(arr) => match arr { + Array::Normal(mut arr) => { + let len = arr.elems.len(); + while let Some(arg) = arr.elems.try_remove_pos(0) { + self.codegen_expr(arg.expr); + } + self.write_instr(BUILD_LIST); + self.write_arg(len as u8); + if len == 0 { + self.stack_inc(); + } else { + self.stack_dec_n(len - 1); + } } - self.write_instr(BUILD_LIST); - self.write_arg(len as u8); - if len == 0 { - self.stack_inc(); - } else { - self.stack_dec_n(len - 1); - } - } + other => todo!("{other}"), + }, other => { self.errs.push(CompileError::feature_error( self.cfg.input.clone(), diff --git a/compiler/erg_compiler/context.rs b/compiler/erg_compiler/context.rs index 285e5fb2..353266c4 100644 --- a/compiler/erg_compiler/context.rs +++ b/compiler/erg_compiler/context.rs @@ -1077,8 +1077,7 @@ impl Context { vi.t.lift(); let (generalized, bounds) = self.generalize_t(vi.t.clone()); let generalized = if !bounds.is_empty() { - if self.rec_supertype_of(&Type::mono("GenericCallable"), &generalized) - { + if self.rec_supertype_of(&Type::mono("GenericCallable"), &generalized) { Type::quantified(generalized, bounds) } else { panic!() @@ -1492,8 +1491,7 @@ impl Context { self.unify(l, r, None, Some(callee.loc()))?; } // if callee is a Module object or some named one - (None, Some(r)) - if self.rec_subtype_of(r, &Type::mono("Named")) => {} + (None, Some(r)) if self.rec_subtype_of(r, &Type::mono("Named")) => {} (None, None) => {} (l, r) => todo!("{l:?}, {r:?}"), } @@ -1759,13 +1757,16 @@ impl Context { } Ok(()) } - hir::Expr::Array(array) => { - array.t = self.deref_tyvar(mem::take(&mut array.t))?; - for elem in array.elems.pos_args.iter_mut() { - self.deref_expr_t(&mut elem.expr)?; + hir::Expr::Array(array) => match array { + hir::Array::Normal(arr) => { + arr.t = self.deref_tyvar(mem::take(&mut arr.t))?; + for elem in arr.elems.pos_args.iter_mut() { + self.deref_expr_t(&mut elem.expr)?; + } + Ok(()) } - Ok(()) - } + _ => todo!(), + }, hir::Expr::Dict(_dict) => { todo!() } @@ -2359,9 +2360,7 @@ impl Context { // sup = union(sup, r) if min does not exist // * sub_unify(?T(:> Never, <: {1}), {0}): (?T(:> Never, <: {0, 1})) Constraint::Sandwiched { sub, sup } => { - if !self.rec_subtype_of(sub, r) - || !self.rec_supertype_of(sup, r) - { + if !self.rec_subtype_of(sub, r) || !self.rec_supertype_of(sup, r) { return Err(TyCheckError::subtyping_error( line!() as usize, sub, @@ -2405,7 +2404,9 @@ impl Context { .super_classes .iter() .chain(ctx.super_traits.iter()) - .filter(|t| self.structural_supertype_of(maybe_sup, t, Some(&bounds), Some(&variance))); + .filter(|t| { + self.structural_supertype_of(maybe_sup, t, Some(&bounds), Some(&variance)) + }); // instanceが複数ある場合、経験的に最も小さい型を選ぶのが良い // これでうまくいかない場合は型指定してもらう(REVIEW: もっと良い方法があるか?) if let Some(t) = self.smallest_ref_t(instances) { @@ -3093,7 +3094,12 @@ impl Context { if let Some(bs) = bounds { if let Some(bound) = bs.iter().find(|b| b.mentions_as_instance(name)) { let other_t = self.type_of(other, bounds); - return self.structural_supertype_of(bound.t(), &other_t, bounds, lhs_variance); + return self.structural_supertype_of( + bound.t(), + &other_t, + bounds, + lhs_variance, + ); } else { todo!() } // subtyping @@ -3157,8 +3163,7 @@ impl Context { } fn supertype_of(&self, lhs: &Type, rhs: &Type) -> bool { - self.structural_supertype_of(lhs, rhs, None, None) - || self.nominal_supertype_of(lhs, rhs) + self.structural_supertype_of(lhs, rhs, None, None) || self.nominal_supertype_of(lhs, rhs) } /// make judgments that include supertypes in the namespace & take into account glue patches @@ -3296,7 +3301,9 @@ impl Context { // No type constraints are imposed here, as subsequent type decisions are made according to the possibilities (FreeVar(v), rhs) => { match &*v.borrow() { - FreeKind::Linked(t) => self.structural_supertype_of(t, rhs, bounds, lhs_variance), + FreeKind::Linked(t) => { + self.structural_supertype_of(t, rhs, bounds, lhs_variance) + } FreeKind::Unbound { constraint, .. } | FreeKind::NamedUnbound { constraint, .. } => match constraint { // `(?T <: Int) :> Nat` can be true, `(?T <: Nat) :> Int` is false @@ -3322,7 +3329,9 @@ impl Context { } (lhs, FreeVar(fv)) => { match &*fv.borrow() { - FreeKind::Linked(t) => self.structural_supertype_of(lhs, t, bounds, lhs_variance), + FreeKind::Linked(t) => { + self.structural_supertype_of(lhs, t, bounds, lhs_variance) + } FreeKind::Unbound { constraint, .. } | FreeKind::NamedUnbound { constraint, .. } => match constraint { // ?T cannot be `Never` @@ -3719,9 +3728,7 @@ impl Context { fn is_sub_constraint_of(&self, l: &Constraint, r: &Constraint) -> bool { match (l, r) { // |I: Nat| <: |I: Int| - (Constraint::TypeOf(lhs), Constraint::TypeOf(rhs)) => { - self.rec_subtype_of(lhs, rhs) - } + (Constraint::TypeOf(lhs), Constraint::TypeOf(rhs)) => self.rec_subtype_of(lhs, rhs), // |T <: Int| <: |T: Type| (Constraint::Sandwiched { sub: Never, .. }, Constraint::TypeOf(Type)) => true, // |Int <: T| <: |Nat <: T| diff --git a/compiler/erg_compiler/hir.rs b/compiler/erg_compiler/hir.rs index 98d5588c..3f6f50c5 100644 --- a/compiler/erg_compiler/hir.rs +++ b/compiler/erg_compiler/hir.rs @@ -8,7 +8,7 @@ use erg_common::value::ValueObj; use erg_common::Str; use erg_common::{ impl_display_for_enum, impl_display_from_nested, impl_locational, impl_locational_for_enum, - impl_nested_display_for_enum, impl_stream_for_wrapper, + impl_nested_display_for_enum, impl_stream_for_wrapper, impl_t, impl_t_for_enum, }; use erg_parser::ast::{fmt_lines, DefId, Params, VarName, VarPattern}; @@ -23,23 +23,7 @@ pub struct Literal { t: Type, } -impl HasType for Literal { - #[inline] - fn ref_t(&self) -> &Type { - &self.t - } - fn ref_mut_t(&mut self) -> &mut Type { - &mut self.t - } - #[inline] - fn signature_t(&self) -> Option<&Type> { - None - } - #[inline] - fn signature_mut_t(&mut self) -> Option<&mut Type> { - None - } -} +impl_t!(Literal); impl NestedDisplay for Literal { fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result { @@ -279,24 +263,7 @@ impl fmt::Display for Local { } } -impl HasType for Local { - #[inline] - fn ref_t(&self) -> &Type { - &self.t - } - #[inline] - fn ref_mut_t(&mut self) -> &mut Type { - &mut self.t - } - #[inline] - fn signature_t(&self) -> Option<&Type> { - None - } - #[inline] - fn signature_mut_t(&mut self) -> Option<&mut Type> { - None - } -} +impl_t!(Local); impl Locational for Local { #[inline] @@ -335,25 +302,7 @@ impl fmt::Display for Attribute { } impl_locational!(Attribute, obj, name); - -impl HasType for Attribute { - #[inline] - fn ref_t(&self) -> &Type { - &self.t - } - #[inline] - fn ref_mut_t(&mut self) -> &mut Type { - &mut self.t - } - #[inline] - fn signature_t(&self) -> Option<&Type> { - None - } - #[inline] - fn signature_mut_t(&mut self) -> Option<&mut Type> { - None - } -} +impl_t!(Attribute); impl Attribute { pub fn new(obj: Expr, name: Token, t: Type) -> Self { @@ -379,25 +328,7 @@ impl fmt::Display for Subscript { } impl_locational!(Subscript, obj, index); - -impl HasType for Subscript { - #[inline] - fn ref_t(&self) -> &Type { - &self.t - } - #[inline] - fn ref_mut_t(&mut self) -> &mut Type { - &mut self.t - } - #[inline] - fn signature_t(&self) -> Option<&Type> { - None - } - #[inline] - fn signature_mut_t(&mut self) -> Option<&mut Type> { - None - } -} +impl_t!(Subscript); impl Subscript { pub fn new(obj: Expr, index: Expr, t: Type) -> Self { @@ -430,33 +361,7 @@ impl NestedDisplay for Accessor { impl_display_from_nested!(Accessor); impl_locational_for_enum!(Accessor; Local, SelfDot, Attr, Subscr); - -impl HasType for Accessor { - #[inline] - fn ref_t(&self) -> &Type { - match self { - Self::Local(n) | Self::SelfDot(n) => n.ref_t(), - Self::Attr(a) => a.ref_t(), - Self::Subscr(s) => s.ref_t(), - } - } - #[inline] - fn ref_mut_t(&mut self) -> &mut Type { - match self { - Self::Local(n) | Self::SelfDot(n) => n.ref_mut_t(), - Self::Attr(a) => a.ref_mut_t(), - Self::Subscr(s) => s.ref_mut_t(), - } - } - #[inline] - fn signature_t(&self) -> Option<&Type> { - None - } - #[inline] - fn signature_mut_t(&mut self) -> Option<&mut Type> { - None - } -} +impl_t_for_enum!(Accessor; Local, SelfDot, Attr, Subscr); impl Accessor { pub const fn local(symbol: Token, t: Type) -> Self { @@ -496,54 +401,83 @@ impl Accessor { } #[derive(Debug, Clone)] -pub struct Array { +pub struct ArrayWithLength { pub l_sqbr: Token, pub r_sqbr: Token, pub t: Type, - pub elems: Args, - pub guard: Option>, + pub elem: Box, + pub len: Box, } -impl HasType for Array { - #[inline] - fn ref_t(&self) -> &Type { - &self.t - } - #[inline] - fn ref_mut_t(&mut self) -> &mut Type { - &mut self.t - } - #[inline] - fn signature_t(&self) -> Option<&Type> { - None - } - #[inline] - fn signature_mut_t(&mut self) -> Option<&mut Type> { - None - } -} - -impl NestedDisplay for Array { +impl NestedDisplay for ArrayWithLength { fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result { - if let Some(guard) = &self.guard { - write!(f, "[{} | {}]", self.elems, guard) - } else { - write!(f, "[{}]", self.elems) + write!(f, "[{}; {}]", self.elem, self.len) + } +} + +impl_display_from_nested!(ArrayWithLength); +impl_locational!(ArrayWithLength, l_sqbr, r_sqbr); +impl_t!(ArrayWithLength); + +impl ArrayWithLength { + pub fn new(l_sqbr: Token, r_sqbr: Token, elem: Expr, len: Expr) -> Self { + let tp_len = match &len { + Expr::Lit(l) => match l.data { + ValueObj::Nat(n) => TyParam::value(n), + _ => todo!(), + }, + _ => todo!(), + }; + let t = Type::array(elem.t(), tp_len); + Self { + l_sqbr, + r_sqbr, + t, + elem: Box::new(elem), + len: Box::new(len), } } } -impl_display_from_nested!(Array); -impl_locational!(Array, l_sqbr, r_sqbr); +#[derive(Debug, Clone)] +pub struct ArrayComprehension { + pub l_sqbr: Token, + pub r_sqbr: Token, + pub t: Type, + pub elem: Box, + pub guard: Box, +} -impl Array { - pub fn new( - l_sqbr: Token, - r_sqbr: Token, - level: usize, - elems: Args, - guard: Option, - ) -> Self { +impl NestedDisplay for ArrayComprehension { + fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result { + write!(f, "[{} | {}]", self.elem, self.guard) + } +} + +impl_display_from_nested!(ArrayComprehension); +impl_locational!(ArrayComprehension, l_sqbr, r_sqbr); +impl_t!(ArrayComprehension); + +#[derive(Debug, Clone)] +pub struct NormalArray { + pub l_sqbr: Token, + pub r_sqbr: Token, + pub t: Type, + pub elems: Args, +} + +impl NestedDisplay for NormalArray { + fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result { + write!(f, "[{}]", self.elems) + } +} + +impl_display_from_nested!(NormalArray); +impl_locational!(NormalArray, l_sqbr, r_sqbr); +impl_t!(NormalArray); + +impl NormalArray { + pub fn new(l_sqbr: Token, r_sqbr: Token, level: usize, elems: Args) -> Self { let elem_t = elems .pos_args .first() @@ -555,7 +489,6 @@ impl Array { r_sqbr, t, elems, - guard: guard.map(Box::new), } } @@ -565,46 +498,42 @@ impl Array { } #[derive(Debug, Clone)] -pub struct Dict { +pub enum Array { + Normal(NormalArray), + Comprehension(ArrayComprehension), + WithLength(ArrayWithLength), +} + +impl_nested_display_for_enum!(Array; Normal, Comprehension, WithLength); +impl_display_for_enum!(Array; Normal, Comprehension, WithLength); +impl_locational_for_enum!(Array; Normal, Comprehension, WithLength); +impl_t_for_enum!(Array; Normal, Comprehension, WithLength); + +#[derive(Debug, Clone)] +pub struct NormalDict { pub l_brace: Token, pub r_brace: Token, + pub t: Type, pub attrs: Args, // TODO: keyをTokenではなくExprにする } -impl HasType for Dict { - fn ref_t(&self) -> &Type { - todo!() - } - fn ref_mut_t(&mut self) -> &mut Type { - todo!() - } - fn t(&self) -> Type { - todo!() - } - #[inline] - fn signature_t(&self) -> Option<&Type> { - None - } - #[inline] - fn signature_mut_t(&mut self) -> Option<&mut Type> { - None - } -} +impl_t!(NormalDict); -impl NestedDisplay for Dict { +impl NestedDisplay for NormalDict { fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result { write!(f, "{{{}}}", self.attrs) } } -impl_display_from_nested!(Dict); -impl_locational!(Dict, l_brace, r_brace); +impl_display_from_nested!(NormalDict); +impl_locational!(NormalDict, l_brace, r_brace); -impl Dict { - pub const fn new(l_brace: Token, r_brace: Token, attrs: Args) -> Self { +impl NormalDict { + pub const fn new(l_brace: Token, r_brace: Token, t: Type, attrs: Args) -> Self { Self { l_brace, r_brace, + t, attrs, } } @@ -895,25 +824,6 @@ pub struct Lambda { pub t: Type, } -impl HasType for Lambda { - #[inline] - fn ref_t(&self) -> &Type { - &self.t - } - #[inline] - fn ref_mut_t(&mut self) -> &mut Type { - &mut self.t - } - #[inline] - fn signature_t(&self) -> Option<&Type> { - None - } - #[inline] - fn signature_mut_t(&mut self) -> Option<&mut Type> { - None - } -} - impl NestedDisplay for Lambda { fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result { writeln!(f, "{} {}", self.params, self.op.content)?; @@ -923,6 +833,7 @@ impl NestedDisplay for Lambda { impl_display_from_nested!(Lambda); impl_locational!(Lambda, params, body); +impl_t!(Lambda); impl Lambda { pub const fn new(id: usize, params: Params, op: Token, body: Block, t: Type) -> Self { @@ -992,6 +903,25 @@ impl Locational for Decl { } } +impl HasType for Decl { + #[inline] + fn ref_t(&self) -> &Type { + Type::NONE + } + #[inline] + fn ref_mut_t(&mut self) -> &mut Type { + todo!() + } + #[inline] + fn signature_t(&self) -> Option<&Type> { + None + } + #[inline] + fn signature_mut_t(&mut self) -> Option<&mut Type> { + None + } +} + impl Decl { pub const fn spec_t(&self) -> &Type { &self.t @@ -1046,6 +976,25 @@ impl NestedDisplay for Def { impl_display_from_nested!(Def); impl_locational!(Def, sig, body); +impl HasType for Def { + #[inline] + fn ref_t(&self) -> &Type { + Type::NONE + } + #[inline] + fn ref_mut_t(&mut self) -> &mut Type { + todo!() + } + #[inline] + fn signature_t(&self) -> Option<&Type> { + None + } + #[inline] + fn signature_mut_t(&mut self) -> Option<&mut Type> { + None + } +} + impl Def { pub const fn new(sig: Signature, body: DefBody) -> Self { Self { sig, body } @@ -1059,7 +1008,7 @@ pub enum Expr { Array(Array), // Dict(Dict), // Set(Set), - Dict(Dict), + Dict(NormalDict), BinOp(BinOp), UnaryOp(UnaryOp), Call(Call), @@ -1071,51 +1020,7 @@ pub enum Expr { impl_nested_display_for_enum!(Expr; Lit, Accessor, Array, Dict, BinOp, UnaryOp, Call, Lambda, Decl, Def); impl_display_from_nested!(Expr); impl_locational_for_enum!(Expr; Lit, Accessor, Array, Dict, BinOp, UnaryOp, Call, Lambda, Decl, Def); - -impl HasType for Expr { - fn ref_t(&self) -> &Type { - match self { - Expr::Lit(lit) => lit.ref_t(), - Expr::Accessor(accessor) => accessor.ref_t(), - Expr::Array(array) => array.ref_t(), - Expr::Dict(dict) => dict.ref_t(), - Expr::BinOp(bin) => bin.ref_t(), - Expr::UnaryOp(unary) => unary.ref_t(), - Expr::Call(call) => call.ref_t(), - Expr::Lambda(lambda) => lambda.ref_t(), - _ => &Type::NoneType, - } - } - fn ref_mut_t(&mut self) -> &mut Type { - match self { - Expr::Lit(lit) => lit.ref_mut_t(), - Expr::Accessor(accessor) => accessor.ref_mut_t(), - Expr::Array(array) => array.ref_mut_t(), - Expr::Dict(dict) => dict.ref_mut_t(), - Expr::BinOp(bin) => bin.ref_mut_t(), - Expr::UnaryOp(unary) => unary.ref_mut_t(), - Expr::Call(call) => call.ref_mut_t(), - Expr::Lambda(lambda) => lambda.ref_mut_t(), - _ => todo!(), - } - } - fn signature_t(&self) -> Option<&Type> { - match self { - Expr::BinOp(bin) => bin.signature_t(), - Expr::UnaryOp(unary) => unary.signature_t(), - Expr::Call(call) => call.signature_t(), - _ => None, - } - } - fn signature_mut_t(&mut self) -> Option<&mut Type> { - match self { - Expr::BinOp(bin) => bin.signature_mut_t(), - Expr::UnaryOp(unary) => unary.signature_mut_t(), - Expr::Call(call) => call.signature_mut_t(), - _ => None, - } - } -} +impl_t_for_enum!(Expr; Lit, Accessor, Array, Dict, BinOp, UnaryOp, Call, Lambda, Decl, Def); impl Expr { pub fn receiver_t(&self) -> Option<&Type> { diff --git a/compiler/erg_compiler/lower.rs b/compiler/erg_compiler/lower.rs index 60b2d311..7a0cae83 100644 --- a/compiler/erg_compiler/lower.rs +++ b/compiler/erg_compiler/lower.rs @@ -97,12 +97,26 @@ impl ASTLowerer { fn lower_array(&mut self, array: ast::Array, check: bool) -> LowerResult { log!("[DEBUG] entered {}({array})", fn_name!()); - let mut hir_array = hir::Array::new( + match array { + ast::Array::Normal(arr) => Ok(hir::Array::Normal(self.lower_normal_array(arr, check)?)), + ast::Array::WithLength(arr) => Ok(hir::Array::WithLength( + self.lower_array_with_length(arr, check)?, + )), + other => todo!("{other}"), + } + } + + fn lower_normal_array( + &mut self, + array: ast::NormalArray, + check: bool, + ) -> LowerResult { + log!("[DEBUG] entered {}({array})", fn_name!()); + let mut hir_array = hir::NormalArray::new( array.l_sqbr, array.r_sqbr, self.ctx.level, hir::Args::empty(), - None, ); let inner_t = hir_array.t.ref_t().inner_ts().first().unwrap().clone(); let (elems, _) = array.elems.into_iters(); @@ -115,6 +129,18 @@ impl ASTLowerer { Ok(hir_array) } + fn lower_array_with_length( + &mut self, + array: ast::ArrayWithLength, + check: bool, + ) -> LowerResult { + log!("[DEBUG] entered {}({array})", fn_name!()); + let elem = self.lower_expr(array.elem.expr, check)?; + let len = self.lower_expr(*array.len, check)?; + let hir_array = hir::ArrayWithLength::new(array.l_sqbr, array.r_sqbr, elem, len); + Ok(hir_array) + } + /// call全体で推論できる場合があり、そのときはcheck: falseにする fn lower_acc(&mut self, acc: ast::Accessor, check: bool) -> LowerResult { log!("[DEBUG] entered {}({acc})", fn_name!()); diff --git a/compiler/erg_compiler/ownercheck.rs b/compiler/erg_compiler/ownercheck.rs index b0c51a55..a580197d 100644 --- a/compiler/erg_compiler/ownercheck.rs +++ b/compiler/erg_compiler/ownercheck.rs @@ -8,7 +8,7 @@ use erg_common::ty::{ArgsOwnership, Ownership}; use erg_common::Str; use crate::error::{OwnershipError, OwnershipErrors, OwnershipResult}; -use crate::hir::{Accessor, Block, Def, Expr, Signature, HIR}; +use crate::hir::{Accessor, Array, Block, Def, Expr, Signature, HIR}; use crate::varinfo::Visibility; use Visibility::*; @@ -178,11 +178,14 @@ impl OwnershipChecker { Expr::UnaryOp(unary) => { self.check_expr(&unary.expr, ownership); } - Expr::Array(arr) => { - for a in arr.elems.pos_args.iter() { - self.check_expr(&a.expr, ownership); + Expr::Array(array) => match array { + Array::Normal(arr) => { + for a in arr.elems.pos_args.iter() { + self.check_expr(&a.expr, ownership); + } } - } + _ => todo!(), + }, Expr::Dict(dict) => { for a in dict.attrs.kw_args.iter() { // self.check_expr(&a.key); diff --git a/compiler/erg_parser/ast.rs b/compiler/erg_parser/ast.rs index 1c60f206..26790932 100644 --- a/compiler/erg_parser/ast.rs +++ b/compiler/erg_parser/ast.rs @@ -379,82 +379,182 @@ impl Accessor { } } -/// DictはキーつきArray(型としては別物) -#[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct Array { +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct NormalArray { pub l_sqbr: Token, pub r_sqbr: Token, pub elems: Args, - pub len: Option>, // if some, elems.len() should be 1 - pub guard: Option>, } -impl NestedDisplay for Array { +impl NestedDisplay for NormalArray { fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result { - write!( - f, - "[{}{}{}]", - self.elems, - fmt_option!(pre "; ", self.len), - fmt_option!(pre "| ", self.guard) - ) + write!(f, "[{}]", self.elems) } } -impl_display_from_nested!(Array); -impl_locational!(Array, l_sqbr, r_sqbr); +impl_display_from_nested!(NormalArray); +impl_locational!(NormalArray, l_sqbr, r_sqbr); -impl Array { - pub fn new( - l_sqbr: Token, - r_sqbr: Token, - elems: Args, - len: Option, - guard: Option, - ) -> Self { +impl NormalArray { + pub fn new(l_sqbr: Token, r_sqbr: Token, elems: Args) -> Self { Self { l_sqbr, r_sqbr, elems, - len: len.map(Box::new), - guard: guard.map(Box::new), } } } -/// DictはキーつきArrayとして実現される +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct ArrayWithLength { + pub l_sqbr: Token, + pub r_sqbr: Token, + pub elem: Box, + pub len: Box, +} + +impl NestedDisplay for ArrayWithLength { + fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result { + write!(f, "[{}; {}]", self.elem, self.len) + } +} + +impl_display_from_nested!(ArrayWithLength); +impl_locational!(ArrayWithLength, l_sqbr, r_sqbr); + +impl ArrayWithLength { + pub fn new(l_sqbr: Token, r_sqbr: Token, elem: PosArg, len: Expr) -> Self { + Self { + l_sqbr, + r_sqbr, + elem: Box::new(elem), + len: Box::new(len), + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct ArrayComprehension { + pub l_sqbr: Token, + pub r_sqbr: Token, + pub elem: Box, + pub generators: Vec<(Local, Expr)>, + pub guards: Vec, +} + +impl NestedDisplay for ArrayComprehension { + fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result { + let mut generators = String::new(); + for (name, gen) in self.generators.iter() { + generators.push_str(&format!("{} <- {}, ", name, gen)); + } + write!( + f, + "[{}| {}{}]", + self.elem, + generators, + fmt_vec(&self.guards) + ) + } +} + +impl_display_from_nested!(ArrayComprehension); +impl_locational!(ArrayComprehension, l_sqbr, r_sqbr); + +impl ArrayComprehension { + pub fn new( + l_sqbr: Token, + r_sqbr: Token, + elem: Expr, + generators: Vec<(Local, Expr)>, + guards: Vec, + ) -> Self { + Self { + l_sqbr, + r_sqbr, + elem: Box::new(elem), + generators, + guards, + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum Array { + Normal(NormalArray), + WithLength(ArrayWithLength), + Comprehension(ArrayComprehension), +} + +impl_nested_display_for_enum!(Array; Normal, WithLength, Comprehension); +impl_display_for_enum!(Array; Normal, WithLength, Comprehension); +impl_locational_for_enum!(Array; Normal, WithLength, Comprehension); + #[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct Dict { +pub struct NormalDict { l_brace: Token, r_brace: Token, - pub attrs: Args, - guard: Option>, + pub attrs: Args, // TODO: Impl K: V Pair } -impl NestedDisplay for Dict { +impl NestedDisplay for NormalDict { fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result { - if let Some(guard) = &self.guard { - write!(f, "{{{} | {guard}}}", self.attrs) - } else { - write!(f, "{{{}}}", self.attrs) - } + write!(f, "{{{}}}", self.attrs) } } -impl_display_from_nested!(Dict); -impl_locational!(Dict, l_brace, r_brace); +impl_display_from_nested!(NormalDict); +impl_locational!(NormalDict, l_brace, r_brace); -impl Dict { - pub fn new(l_brace: Token, r_brace: Token, attrs: Args, guard: Option) -> Self { +impl NormalDict { + pub fn new(l_brace: Token, r_brace: Token, attrs: Args) -> Self { Self { l_brace, r_brace, attrs, - guard: guard.map(Box::new), } } } +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct DictComprehension { + l_brace: Token, + r_brace: Token, + pub attrs: Args, + guards: Vec, +} + +// TODO: +impl NestedDisplay for DictComprehension { + fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result { + write!(f, "{{{} | {}}}", self.attrs, fmt_vec(&self.guards)) + } +} + +impl_display_from_nested!(DictComprehension); +impl_locational!(DictComprehension, l_brace, r_brace); + +impl DictComprehension { + pub fn new(l_brace: Token, r_brace: Token, attrs: Args, guards: Vec) -> Self { + Self { + l_brace, + r_brace, + attrs, + guards, + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum Dict { + Normal(NormalDict), + Comprehension(DictComprehension), +} + +impl_nested_display_for_enum!(Dict; Normal, Comprehension); +impl_display_for_enum!(Dict; Normal, Comprehension); +impl_locational_for_enum!(Dict; Normal, Comprehension); + #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct BinOp { pub op: Token, @@ -2120,9 +2220,8 @@ pub enum Expr { Lit(Literal), Accessor(Accessor), Array(Array), - // Dict(Dict), - // Set(Set), Dict(Dict), + // Set(Set), BinOp(BinOp), UnaryOp(UnaryOp), Call(Call), diff --git a/compiler/erg_parser/error.rs b/compiler/erg_parser/error.rs index 40897135..6332f8e0 100644 --- a/compiler/erg_parser/error.rs +++ b/compiler/erg_parser/error.rs @@ -88,7 +88,7 @@ pub type LexResult = Result; pub type ParseError = LexError; pub type ParseErrors = LexErrors; -pub type ParseResult = Result; +pub type ParseResult = Result; #[derive(Debug)] pub struct DesugaringError { diff --git a/compiler/erg_parser/parse.rs b/compiler/erg_parser/parse.rs index 16181bb7..1ddc3dbd 100644 --- a/compiler/erg_parser/parse.rs +++ b/compiler/erg_parser/parse.rs @@ -58,6 +58,16 @@ pub enum Side { Rhs, } +pub enum ArrayInner { + Normal(Args), + WithLength(PosArg, Expr), + Comprehension { + elem: PosArg, + generators: Vec<(Local, Expr)>, + guards: Vec, + }, +} + /// To enhance error descriptions, the parsing process will continue as long as it's not fatal. #[derive(Debug)] pub struct Parser { @@ -268,9 +278,8 @@ impl Parser { self.tokens.insert(0, token); } - fn stack_dec(&mut self, e: ParseError) -> ParseError { + fn stack_dec(&mut self) -> () { self.level -= 1; - e } } @@ -343,8 +352,7 @@ impl Parser { log!("token stream: {}", self.tokens); let module = match self.try_reduce_module() { Ok(module) => module, - Err(e) => { - self.errs.push(e); + Err(_) => { return Err(mem::take(&mut self.errs)); } }; @@ -368,8 +376,8 @@ impl Parser { } } + /// Reduce to the largest unit of syntax, the module (this is called only once) /// 構文の最大単位であるモジュールに還元する(これが呼ばれるのは一度きり) - /// プログラムのトップレベルに来てよいのは単独の式のみなので、例えばBinOpが先頭に来るのは構文エラー #[inline] fn try_reduce_module(&mut self) -> ParseResult { debug_call_info!(self); @@ -389,9 +397,7 @@ impl Parser { Ok(expr) => { chunks.push(expr); } - Err(e) => { - self.errs.push(e); - } + Err(_) => {} }, _ => switch_unreachable!(), } @@ -405,7 +411,7 @@ impl Parser { let mut block = Block::with_capacity(2); // single line block if !self.cur_is(Newline) { - let chunk = self.try_reduce_expr().map_err(|e| self.stack_dec(e))?; + let chunk = self.try_reduce_expr().map_err(|_| self.stack_dec())?; block.push(chunk); self.level -= 1; return Ok(block); @@ -435,9 +441,7 @@ impl Parser { break; } } - Err(e) => { - self.errs.push(e); - } + Err(_) => {} } } _ => switch_unreachable!(), @@ -461,7 +465,8 @@ impl Parser { None, ); self.level -= 1; - Err(err) + self.errs.push(err); + Err(()) } else { self.level -= 1; Ok(block) @@ -473,7 +478,7 @@ impl Parser { debug_call_info!(self); if self.cur_is(TokenKind::AtSign) { self.lpop(); - let expr = self.try_reduce_expr().map_err(|e| self.stack_dec(e))?; + let expr = self.try_reduce_expr().map_err(|_| self.stack_dec())?; self.level -= 1; Ok(Some(Decorator::new(expr))) } else { @@ -486,7 +491,7 @@ impl Parser { fn opt_reduce_decorators(&mut self) -> ParseResult> { debug_call_info!(self); let mut decs = set![]; - while let Some(deco) = self.opt_reduce_decorator().map_err(|e| self.stack_dec(e))? { + while let Some(deco) = self.opt_reduce_decorator().map_err(|_| self.stack_dec())? { decs.insert(deco); } self.level -= 1; @@ -497,14 +502,12 @@ impl Parser { fn try_reduce_decl(&mut self) -> ParseResult { debug_call_info!(self); if self.peek().unwrap().category_is(TC::LEnclosure) { - let var = self.try_reduce_var_sig().map_err(|e| self.stack_dec(e))?; + let var = self.try_reduce_var_sig().map_err(|_| self.stack_dec())?; self.level -= 1; return Ok(Signature::Var(var)); } - let decorators = self - .opt_reduce_decorators() - .map_err(|e| self.stack_dec(e))?; - let name = self.try_reduce_name().map_err(|e| self.stack_dec(e))?; + let decorators = self.opt_reduce_decorators().map_err(|_| self.stack_dec())?; + let name = self.try_reduce_name().map_err(|_| self.stack_dec())?; // TODO: parse bounds |...| let bounds = TypeBoundSpecs::empty(); if self.cur_is(VBar) { @@ -513,11 +516,11 @@ impl Parser { if let Some(params) = self .opt_reduce_params() .transpose() - .map_err(|e| self.stack_dec(e))? + .map_err(|_| self.stack_dec())? { let t_spec = if self.cur_is(Colon) { self.skip(); - Some(self.try_reduce_type_spec().map_err(|e| self.stack_dec(e))?) + Some(self.try_reduce_type_spec().map_err(|_| self.stack_dec())?) } else { None }; @@ -540,18 +543,19 @@ impl Parser { ); self.next_expr(); self.level -= 1; - return Err(err); + self.errs.push(err); + return Err(()); } let t_spec = if name.is_const() { if self.cur_is(SubtypeOf) { self.skip(); - Some(self.try_reduce_type_spec().map_err(|e| self.stack_dec(e))?) + Some(self.try_reduce_type_spec().map_err(|_| self.stack_dec())?) } else { None } } else if self.cur_is(Colon) { self.skip(); - Some(self.try_reduce_type_spec().map_err(|e| self.stack_dec(e))?) + Some(self.try_reduce_type_spec().map_err(|_| self.stack_dec())?) } else { None }; @@ -568,10 +572,10 @@ impl Parser { debug_call_info!(self); let pat = self .try_reduce_var_pattern() - .map_err(|e| self.stack_dec(e))?; + .map_err(|_| self.stack_dec())?; let t_spec = if self.cur_is(Colon) { self.skip(); - Some(self.try_reduce_type_spec().map_err(|e| self.stack_dec(e))?) + Some(self.try_reduce_type_spec().map_err(|_| self.stack_dec())?) } else { None }; @@ -587,12 +591,10 @@ impl Parser { debug_call_info!(self); let lhs = self .try_reduce_non_default_param_sig() - .map_err(|e| self.stack_dec(e))?; + .map_err(|_| self.stack_dec())?; if self.cur_is(OrEqual) { self.skip(); - let val = self - .try_reduce_const_expr() - .map_err(|e| self.stack_dec(e))?; + let val = self.try_reduce_const_expr().map_err(|_| self.stack_dec())?; self.level -= 1; Ok(ParamSignature::new(lhs.pat, lhs.t_spec, Some(val))) } else { @@ -606,10 +608,10 @@ impl Parser { debug_call_info!(self); let pat = self .try_reduce_param_pattern() - .map_err(|e| self.stack_dec(e))?; + .map_err(|_| self.stack_dec())?; let t_spec = if self.cur_is(Colon) { self.skip(); - Some(self.try_reduce_type_spec().map_err(|e| self.stack_dec(e))?) + Some(self.try_reduce_type_spec().map_err(|_| self.stack_dec())?) } else { None }; @@ -620,18 +622,18 @@ impl Parser { #[inline] fn try_reduce_lambda_sig(&mut self) -> ParseResult { debug_call_info!(self); - let params = self.try_reduce_params().map_err(|e| self.stack_dec(e))?; + let params = self.try_reduce_params().map_err(|_| self.stack_dec())?; let return_t = match self.peek() { Some(t) if t.is(SupertypeOf) => { self.skip(); - Some(self.try_reduce_type_spec().map_err(|e| self.stack_dec(e))?) + Some(self.try_reduce_type_spec().map_err(|_| self.stack_dec())?) } _ => None, }; let bounds = match self.peek() { Some(t) if t.is(VBar) => { self.skip(); - self.try_reduce_bounds().map_err(|e| self.stack_dec(e))? + self.try_reduce_bounds().map_err(|_| self.stack_dec())? } _ => TypeBoundSpecs::empty(), }; @@ -646,7 +648,9 @@ impl Parser { // TODO: SelfDot _ => { self.level -= 1; - return Err(self.skip_and_throw_syntax_err(caused_by!())); + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); } }; loop { @@ -660,12 +664,14 @@ impl Parser { } Some(t) if t.is(LSqBr) => { self.skip(); - let index = self.try_reduce_expr().map_err(|e| self.stack_dec(e))?; + let index = self.try_reduce_expr().map_err(|_| self.stack_dec())?; if self.cur_is(RSqBr) { self.skip(); } else { self.level -= 1; - return Err(self.skip_and_throw_syntax_err(caused_by!())); + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); } acc = Accessor::subscr(Expr::Accessor(acc), index); if self.cur_is(RSqBr) { @@ -673,7 +679,9 @@ impl Parser { } else { self.level -= 1; // TODO: error report: RSqBr not found - return Err(self.skip_and_throw_syntax_err(caused_by!())); + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); } } _ => { @@ -694,19 +702,21 @@ impl Parser { return Ok(Vars::empty()); } Some(_) => { - let elem = self.try_reduce_var_sig().map_err(|e| self.stack_dec(e))?; + let elem = self.try_reduce_var_sig().map_err(|_| self.stack_dec())?; elems.push(elem); } _ => { self.level -= 1; - return Err(self.skip_and_throw_syntax_err(caused_by!())); + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); } } loop { match self.peek() { Some(t) if t.is(Comma) => { self.skip(); - let elem = self.try_reduce_var_sig().map_err(|e| self.stack_dec(e))?; + let elem = self.try_reduce_var_sig().map_err(|_| self.stack_dec())?; elems.push(elem); } Some(t) if t.category_is(TC::BinOp) => { @@ -724,7 +734,8 @@ impl Parser { ); self.next_expr(); self.level -= 1; - return Err(err); + self.errs.push(err); + return Err(()); } _ => { break; @@ -781,11 +792,13 @@ impl Parser { // TODO: RParen not found else { self.level -= 1; - return Err(self.skip_and_throw_syntax_err(caused_by!())); + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); } } Some(_) => { - let param = self.try_reduce_param_sig().map_err(|e| self.stack_dec(e))?; + let param = self.try_reduce_param_sig().map_err(|_| self.stack_dec())?; if param.has_default() { default_appeared = true; default_params.push(param); @@ -795,14 +808,16 @@ impl Parser { } _ => { self.level -= 1; - return Err(self.skip_and_throw_syntax_err(caused_by!())); + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); } } loop { match self.peek() { Some(t) if t.is(Comma) => { self.skip(); - let param = self.try_reduce_param_sig().map_err(|e| self.stack_dec(e))?; + let param = self.try_reduce_param_sig().map_err(|_| self.stack_dec())?; match (param.has_default(), default_appeared) { (true, true) => { default_params.push(param); @@ -813,13 +828,15 @@ impl Parser { } (false, true) => { self.level -= 1; - return Err(ParseError::syntax_error( + let err = ParseError::syntax_error( 0, param.loc(), // TODO: switch_lang! "non-default argument follows default argument", None, - )); + ); + self.errs.push(err); + return Err(()); } (false, false) => { non_default_params.push(param); @@ -840,7 +857,8 @@ impl Parser { ); self.next_expr(); self.level -= 1; - return Err(err); + self.errs.push(err); + return Err(()); } Some(t) if t.is(TokenKind::RParen) => { let rp = self.lpop(); @@ -854,7 +872,9 @@ impl Parser { } else { self.level -= 1; // LParen not found - return Err(self.skip_and_throw_syntax_err(caused_by!())); + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); } } _ if lp.is_none() => { @@ -864,7 +884,9 @@ impl Parser { _ => { self.level -= 1; // TODO: RParen not found - return Err(self.skip_and_throw_syntax_err(caused_by!())); + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); } } } @@ -874,7 +896,7 @@ impl Parser { debug_call_info!(self); match self.peek() { Some(t) if t.is(Symbol) => { - let varname = self.try_reduce_name().map_err(|e| self.stack_dec(e))?; + let varname = self.try_reduce_name().map_err(|_| self.stack_dec())?; self.level -= 1; Ok(VarPattern::VarName(varname)) } @@ -886,7 +908,7 @@ impl Parser { let l_sqbr = self.lpop(); let elems = self .try_reduce_elems_pattern() - .map_err(|e| self.stack_dec(e))?; + .map_err(|_| self.stack_dec())?; if self.cur_is(RSqBr) { let r_sqbr = self.lpop(); self.level -= 1; @@ -896,14 +918,16 @@ impl Parser { } else { self.level -= 1; // TODO: error report: RSqBr not found - Err(self.skip_and_throw_syntax_err(caused_by!())) + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + Err(()) } } Some(t) if t.is(LParen) => { self.skip(); let pat = self .try_reduce_var_pattern() - .map_err(|e| self.stack_dec(e))?; + .map_err(|_| self.stack_dec())?; if self.cur_is(RParen) { self.skip(); self.level -= 1; @@ -911,12 +935,16 @@ impl Parser { } else { self.level -= 1; // TODO: error report: RParen not found - Err(self.skip_and_throw_syntax_err(caused_by!())) + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + Err(()) } } _ => { self.level -= 1; - Err(self.skip_and_throw_syntax_err(caused_by!())) + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); } } } @@ -925,7 +953,7 @@ impl Parser { debug_call_info!(self); match self.peek() { Some(t) if t.is(Symbol) => { - let varname = self.try_reduce_name().map_err(|e| self.stack_dec(e))?; + let varname = self.try_reduce_name().map_err(|_| self.stack_dec())?; self.level -= 1; Ok(ParamPattern::VarName(varname)) } @@ -934,7 +962,7 @@ impl Parser { Ok(ParamPattern::Discard(self.lpop())) } Some(t) if t.category_is(TC::Literal) => { - let lit = self.try_reduce_lit().map_err(|e| self.stack_dec(e))?; + let lit = self.try_reduce_lit().map_err(|_| self.stack_dec())?; self.level -= 1; // TODO: range pattern Ok(ParamPattern::Lit(lit)) @@ -943,12 +971,12 @@ impl Parser { self.skip(); self.level -= 1; Ok(ParamPattern::VarArgsName( - self.try_reduce_name().map_err(|e| self.stack_dec(e))?, + self.try_reduce_name().map_err(|_| self.stack_dec())?, )) } Some(t) if t.is(LSqBr) => { let l_sqbr = self.lpop(); - let elems = self.try_reduce_params().map_err(|e| self.stack_dec(e))?; + let elems = self.try_reduce_params().map_err(|_| self.stack_dec())?; if self.cur_is(RSqBr) { let r_sqbr = self.lpop(); self.level -= 1; @@ -958,14 +986,16 @@ impl Parser { } else { self.level -= 1; // TODO: error report: RSqBr not found - Err(self.skip_and_throw_syntax_err(caused_by!())) + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); } } Some(t) if t.is(LParen) => { self.skip(); let pat = self .try_reduce_param_pattern() - .map_err(|e| self.stack_dec(e))?; + .map_err(|_| self.stack_dec())?; if self.cur_is(RParen) { self.skip(); self.level -= 1; @@ -973,12 +1003,16 @@ impl Parser { } else { self.level -= 1; // TODO: error report: RParen not found - Err(self.skip_and_throw_syntax_err(caused_by!())) + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); } } _ => { self.level -= 1; - Err(self.skip_and_throw_syntax_err(caused_by!())) + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); } } } @@ -990,12 +1024,12 @@ impl Parser { Some(t) if t.is(Symbol) => { let simple = self .try_reduce_simple_type_spec() - .map_err(|e| self.stack_dec(e))?; + .map_err(|_| self.stack_dec())?; // not finished TypeSpec::PreDeclTy(PreDeclTypeSpec::Simple(simple)) } Some(t) if t.category_is(TC::Literal) => { - let lit = self.try_reduce_lit().map_err(|e| self.stack_dec(e))?; + let lit = self.try_reduce_lit().map_err(|_| self.stack_dec())?; let lhs = ConstExpr::Lit(lit); let maybe_op = self.lpop(); let op = if maybe_op.is(Closed) @@ -1006,24 +1040,26 @@ impl Parser { maybe_op } else { self.level -= 1; - return Err(self.skip_and_throw_syntax_err(caused_by!())); + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); }; // TODO: maybe Name - let rhs = ConstExpr::Lit(self.try_reduce_lit().map_err(|e| self.stack_dec(e))?); + let rhs = ConstExpr::Lit(self.try_reduce_lit().map_err(|_| self.stack_dec())?); TypeSpec::interval(op, lhs, rhs) } Some(t) if t.is(LParen) => { - let func_type_spec = self.try_reduce_func_type().map_err(|e| self.stack_dec(e))?; + let func_type_spec = self.try_reduce_func_type().map_err(|_| self.stack_dec())?; func_type_spec } Some(t) if t.is(LSqBr) => { self.skip(); - let mut tys = vec![self.try_reduce_type_spec().map_err(|e| self.stack_dec(e))?]; + let mut tys = vec![self.try_reduce_type_spec().map_err(|_| self.stack_dec())?]; loop { match self.peek() { Some(t) if t.is(Comma) => { self.skip(); - let t = self.try_reduce_type_spec().map_err(|e| self.stack_dec(e))?; + let t = self.try_reduce_type_spec().map_err(|_| self.stack_dec())?; tys.push(t); } Some(t) if t.is(RSqBr) => { @@ -1032,7 +1068,9 @@ impl Parser { } _ => { self.level -= 1; - return Err(self.skip_and_throw_syntax_err(caused_by!())); + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); } } } @@ -1040,23 +1078,25 @@ impl Parser { } _ => { self.level -= 1; - return Err(self.skip_and_throw_syntax_err(caused_by!())); + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); } }; loop { match self.peek() { Some(t) if t.is(AndOp) => { - let rhs = self.try_reduce_type_spec().map_err(|e| self.stack_dec(e))?; + let rhs = self.try_reduce_type_spec().map_err(|_| self.stack_dec())?; typ = TypeSpec::and(typ, rhs); } Some(t) if t.is(OrOp) => { - let rhs = self.try_reduce_type_spec().map_err(|e| self.stack_dec(e))?; + let rhs = self.try_reduce_type_spec().map_err(|_| self.stack_dec())?; typ = TypeSpec::or(typ, rhs); } Some(t) if t.category_is(TC::LambdaOp) => { let is_func = t.is(FuncArrow); self.skip(); - let rhs = self.try_reduce_type_spec().map_err(|e| self.stack_dec(e))?; + let rhs = self.try_reduce_type_spec().map_err(|_| self.stack_dec())?; typ = if is_func { TypeSpec::func(None, vec![ParamTySpec::anonymous(typ)], vec![], rhs) } else { @@ -1075,13 +1115,13 @@ impl Parser { fn try_reduce_func_type_param(&mut self) -> ParseResult { debug_call_info!(self); if self.cur_is(Symbol) && self.nth_is(1, Colon) { - let name = self.try_reduce_name().map_err(|e| self.stack_dec(e))?; + let name = self.try_reduce_name().map_err(|_| self.stack_dec())?; self.skip(); - let typ = self.try_reduce_type_spec().map_err(|e| self.stack_dec(e))?; + let typ = self.try_reduce_type_spec().map_err(|_| self.stack_dec())?; self.level -= 1; Ok(ParamTySpec::new(Some(name.into_token()), typ)) } else { - let ty_spec = self.try_reduce_type_spec().map_err(|e| self.stack_dec(e))?; + let ty_spec = self.try_reduce_type_spec().map_err(|_| self.stack_dec())?; self.level -= 1; Ok(ParamTySpec::anonymous(ty_spec)) } @@ -1093,14 +1133,14 @@ impl Parser { let lparen = Some(self.lpop()); let mut non_defaults = vec![self .try_reduce_func_type_param() - .map_err(|e| self.stack_dec(e))?]; + .map_err(|_| self.stack_dec())?]; loop { match self.peek() { Some(t) if t.is(Comma) => { self.skip(); non_defaults.push( self.try_reduce_func_type_param() - .map_err(|e| self.stack_dec(e))?, + .map_err(|_| self.stack_dec())?, ); } Some(t) if t.is(RParen) => { @@ -1109,7 +1149,9 @@ impl Parser { } _ => { self.level -= 1; - return Err(self.skip_and_throw_syntax_err(caused_by!())); + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); } } } @@ -1117,7 +1159,7 @@ impl Parser { Some(t) if t.category_is(TC::LambdaOp) => { let is_func = t.is(FuncArrow); self.skip(); - let rhs = self.try_reduce_type_spec().map_err(|e| self.stack_dec(e))?; + let rhs = self.try_reduce_type_spec().map_err(|_| self.stack_dec())?; self.level -= 1; if is_func { Ok(TypeSpec::func(lparen, non_defaults, vec![], rhs)) @@ -1127,7 +1169,9 @@ impl Parser { } _ => { self.level -= 1; - Err(self.skip_and_throw_syntax_err(caused_by!())) + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); } } } @@ -1137,7 +1181,7 @@ impl Parser { debug_call_info!(self); match self.peek() { Some(t) if t.is(Symbol) => { - let name = self.try_reduce_name().map_err(|e| self.stack_dec(e))?; + let name = self.try_reduce_name().map_err(|_| self.stack_dec())?; if let Some(res) = self.opt_reduce_args() { let args = self.validate_const_args(res?)?; self.level -= 1; @@ -1149,7 +1193,9 @@ impl Parser { } _ => { self.level -= 1; - Err(self.skip_and_throw_syntax_err(caused_by!())) + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); } } } @@ -1166,7 +1212,8 @@ impl Parser { Ok(ConstExpr::Accessor(ConstAccessor::Local(local))) } // TODO: App, Array, Record, BinOp, UnaryOp, - other => Err(ParseError::syntax_error( + other => { + self.errs.push(ParseError::syntax_error( 0, other.loc(), switch_lang!( @@ -1176,7 +1223,9 @@ impl Parser { "english" => "this expression is not computable at the compile-time, so cannot used as a type-argument", ), None, - )), + )); + Err(()) + } } } @@ -1215,36 +1264,39 @@ impl Parser { /// For parsing elements of arrays and tuples /// The second return value is a specified length, the third return value is a guard - fn try_reduce_elems(&mut self) -> ParseResult<(Args, Option, Option)> { + fn try_reduce_elems(&mut self) -> ParseResult { debug_call_info!(self); if self.cur_category_is(TC::REnclosure) { let args = Args::new(vec![], vec![], None); self.level -= 1; - return Ok((args, None, None)); + return Ok(ArrayInner::Normal(args)); } - let mut elems = Args::new(vec![], vec![], None); + let first = self.try_reduce_elem().map_err(|_| self.stack_dec())?; + let mut elems = Args::new(vec![first], vec![], None); match self.peek() { Some(semi) if semi.is(Semi) => { - let loc = semi.loc(); + self.lpop(); + let len = self.try_reduce_expr().map_err(|_| self.stack_dec())?; self.level -= 1; - return Err(ParseError::feature_error( - line!() as usize, - loc, - "length specification", - )); + return Ok(ArrayInner::WithLength(elems.remove_pos(0), len)); } Some(vbar) if vbar.is(VBar) => { - let loc = vbar.loc(); + let err = ParseError::feature_error(line!() as usize, vbar.loc(), "comprehension"); + self.lpop(); + self.errs.push(err); self.level -= 1; - return Err(ParseError::feature_error(line!() as usize, loc, "guard")); + return Err(()); } + Some(t) if t.category_is(TC::REnclosure) || t.is(Comma) => {} Some(_) => { - let elem = self.try_reduce_elem().map_err(|e| self.stack_dec(e))?; + let elem = self.try_reduce_elem().map_err(|_| self.stack_dec())?; elems.push_pos(elem); } None => { self.level -= 1; - return Err(self.skip_and_throw_syntax_err(caused_by!())); + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); } } loop { @@ -1253,9 +1305,11 @@ impl Parser { self.skip(); if self.cur_is(Comma) { self.level -= 1; - return Err(self.skip_and_throw_syntax_err(caused_by!())); + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); } - elems.push_pos(self.try_reduce_elem().map_err(|e| self.stack_dec(e))?); + elems.push_pos(self.try_reduce_elem().map_err(|_| self.stack_dec())?); } Some(t) if t.category_is(TC::REnclosure) => { break; @@ -1263,19 +1317,21 @@ impl Parser { _ => { self.skip(); self.level -= 1; - return Err(self.skip_and_throw_syntax_err(caused_by!())); + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); } } } self.level -= 1; - Ok((elems, None, None)) + Ok(ArrayInner::Normal(elems)) } fn try_reduce_elem(&mut self) -> ParseResult { debug_call_info!(self); match self.peek() { Some(_) => { - let expr = self.try_reduce_expr().map_err(|e| self.stack_dec(e))?; + let expr = self.try_reduce_expr().map_err(|_| self.stack_dec())?; self.level -= 1; Ok(PosArg::new(expr)) } @@ -1327,7 +1383,7 @@ impl Parser { self.level -= 1; return Ok(Args::new(vec![], vec![], None)); } - let mut args = match self.try_reduce_arg().map_err(|e| self.stack_dec(e))? { + let mut args = match self.try_reduce_arg().map_err(|_| self.stack_dec())? { PosOrKwArg::Pos(arg) => Args::new(vec![arg], vec![], None), PosOrKwArg::Kw(arg) => Args::new(vec![], vec![arg], None), }; @@ -1337,7 +1393,9 @@ impl Parser { Some(t) if t.is(Colon) && colon_style => { self.skip(); self.level -= 1; - return Err(self.skip_and_throw_syntax_err(caused_by!())); + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); } Some(t) if t.is(Colon) => { self.skip(); @@ -1348,9 +1406,9 @@ impl Parser { debug_power_assert!(self.cur_is(Indent)); self.skip(); if !args.kw_is_empty() { - args.push_kw(self.try_reduce_kw_arg().map_err(|e| self.stack_dec(e))?); + args.push_kw(self.try_reduce_kw_arg().map_err(|_| self.stack_dec())?); } else { - match self.try_reduce_arg().map_err(|e| self.stack_dec(e))? { + match self.try_reduce_arg().map_err(|_| self.stack_dec())? { PosOrKwArg::Pos(arg) => { args.push_pos(arg); } @@ -1364,12 +1422,14 @@ impl Parser { self.skip(); if colon_style || self.cur_is(Comma) { self.level -= 1; - return Err(self.skip_and_throw_syntax_err(caused_by!())); + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); } if !args.kw_is_empty() { - args.push_kw(self.try_reduce_kw_arg().map_err(|e| self.stack_dec(e))?); + args.push_kw(self.try_reduce_kw_arg().map_err(|_| self.stack_dec())?); } else { - match self.try_reduce_arg().map_err(|e| self.stack_dec(e))? { + match self.try_reduce_arg().map_err(|_| self.stack_dec())? { PosOrKwArg::Pos(arg) => { args.push_pos(arg); } @@ -1388,9 +1448,9 @@ impl Parser { break; } if !args.kw_is_empty() { - args.push_kw(self.try_reduce_kw_arg().map_err(|e| self.stack_dec(e))?); + args.push_kw(self.try_reduce_kw_arg().map_err(|_| self.stack_dec())?); } else { - match self.try_reduce_arg().map_err(|e| self.stack_dec(e))? { + match self.try_reduce_arg().map_err(|_| self.stack_dec())? { PosOrKwArg::Pos(arg) => { args.push_pos(arg); } @@ -1420,7 +1480,7 @@ impl Parser { match self.peek() { Some(t) if t.is(Symbol) => { if self.nth_is(1, Colon) { - let acc = self.try_reduce_acc().map_err(|e| self.stack_dec(e))?; + let acc = self.try_reduce_acc().map_err(|_| self.stack_dec())?; debug_power_assert!(self.cur_is(Colon)); if self.nth_is(1, Newline) { self.level -= 1; @@ -1433,20 +1493,22 @@ impl Parser { } else { self.next_expr(); self.level -= 1; - return Err(ParseError::simple_syntax_error(0, acc.loc())); + let err = ParseError::simple_syntax_error(0, acc.loc()); + self.errs.push(err); + return Err(()); }; - let expr = self.try_reduce_expr().map_err(|e| self.stack_dec(e))?; + let expr = self.try_reduce_expr().map_err(|_| self.stack_dec())?; self.level -= 1; Ok(PosOrKwArg::Kw(KwArg::new(kw, expr))) } } else { - let expr = self.try_reduce_expr().map_err(|e| self.stack_dec(e))?; + let expr = self.try_reduce_expr().map_err(|_| self.stack_dec())?; self.level -= 1; Ok(PosOrKwArg::Pos(PosArg::new(expr))) } } Some(_) => { - let expr = self.try_reduce_expr().map_err(|e| self.stack_dec(e))?; + let expr = self.try_reduce_expr().map_err(|_| self.stack_dec())?; self.level -= 1; Ok(PosOrKwArg::Pos(PosArg::new(expr))) } @@ -1459,7 +1521,7 @@ impl Parser { match self.peek() { Some(t) if t.is(Symbol) => { if self.nth_is(1, Colon) { - let acc = self.try_reduce_acc().map_err(|e| self.stack_dec(e))?; + let acc = self.try_reduce_acc().map_err(|_| self.stack_dec())?; debug_power_assert!(self.cur_is(Colon)); self.skip(); let keyword = if let Accessor::Local(n) = acc { @@ -1467,21 +1529,25 @@ impl Parser { } else { self.next_expr(); self.level -= 1; - return Err(ParseError::simple_syntax_error(0, acc.loc())); + self.errs + .push(ParseError::simple_syntax_error(0, acc.loc())); + return Err(()); }; - let expr = self.try_reduce_expr().map_err(|e| self.stack_dec(e))?; + let expr = self.try_reduce_expr().map_err(|_| self.stack_dec())?; self.level -= 1; Ok(KwArg::new(keyword, expr)) } else { let loc = t.loc(); self.level -= 1; - Err(ParseError::simple_syntax_error(0, loc)) + self.errs.push(ParseError::simple_syntax_error(0, loc)); + Err(()) } } Some(other) => { let loc = other.loc(); self.level -= 1; - Err(ParseError::simple_syntax_error(0, loc)) + self.errs.push(ParseError::simple_syntax_error(0, loc)); + Err(()) } None => switch_unreachable!(), } @@ -1489,7 +1555,7 @@ impl Parser { fn try_reduce_const_expr(&mut self) -> ParseResult { debug_call_info!(self); - let expr = self.try_reduce_expr().map_err(|e| self.stack_dec(e))?; + let expr = self.try_reduce_expr().map_err(|_| self.stack_dec())?; self.level -= 1; self.validate_const_expr(expr) } @@ -1499,53 +1565,57 @@ impl Parser { let mut stack = Vec::::new(); match self.cur_side() { Side::LhsAssign => { - let sig = self.try_reduce_decl().map_err(|e| self.stack_dec(e))?; + let sig = self.try_reduce_decl().map_err(|_| self.stack_dec())?; match self.peek() { Some(t) if t.is(Equal) => { let op = self.lpop(); self.counter.inc(); - let block = self.try_reduce_block().map_err(|e| self.stack_dec(e))?; + let block = self.try_reduce_block().map_err(|_| self.stack_dec())?; let body = DefBody::new(op, block, self.counter); self.level -= 1; Ok(Expr::Def(Def::new(sig, body))) } _other => { self.level -= 1; - Err(self.skip_and_throw_syntax_err(caused_by!())) + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); } } } Side::LhsLambda => { - let params = self.try_reduce_params().map_err(|e| self.stack_dec(e))?; + let params = self.try_reduce_params().map_err(|_| self.stack_dec())?; match self.peek() { Some(t) if t.category_is(TC::LambdaOp) => { let sig = LambdaSignature::new(params, None, TypeBoundSpecs::empty()); let op = self.lpop(); - let body = self.try_reduce_block().map_err(|e| self.stack_dec(e))?; + let body = self.try_reduce_block().map_err(|_| self.stack_dec())?; self.counter.inc(); self.level -= 1; Ok(Expr::Lambda(Lambda::new(sig, op, body, self.counter))) } Some(t) if t.is(Colon) => { self.lpop(); - let spec_t = self.try_reduce_type_spec().map_err(|e| self.stack_dec(e))?; + let spec_t = self.try_reduce_type_spec().map_err(|_| self.stack_dec())?; let sig = LambdaSignature::new(params, Some(spec_t), TypeBoundSpecs::empty()); let op = self.lpop(); - let body = self.try_reduce_block().map_err(|e| self.stack_dec(e))?; + let body = self.try_reduce_block().map_err(|_| self.stack_dec())?; self.counter.inc(); self.level -= 1; Ok(Expr::Lambda(Lambda::new(sig, op, body, self.counter))) } _other => { self.level -= 1; - Err(self.skip_and_throw_syntax_err(caused_by!())) + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); } } } Side::Rhs => { stack.push(ExprOrOp::Expr( - self.try_reduce_bin_lhs().map_err(|e| self.stack_dec(e))?, + self.try_reduce_bin_lhs().map_err(|_| self.stack_dec())?, )); loop { match self.peek() { @@ -1574,7 +1644,7 @@ impl Parser { } stack.push(ExprOrOp::Op(self.lpop())); stack.push(ExprOrOp::Expr( - self.try_reduce_bin_lhs().map_err(|e| self.stack_dec(e))?, + self.try_reduce_bin_lhs().map_err(|_| self.stack_dec())?, )); } Some(t) if t.category_is(TC::DefOp) => { @@ -1588,7 +1658,9 @@ impl Parser { expr } else { self.level -= 1; - return Err(self.skip_and_throw_syntax_err(caused_by!())); + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); }; let acc = Accessor::attr(obj, Local::new(symbol)); if let Ok(args) = self.try_reduce_args() { @@ -1601,7 +1673,9 @@ impl Parser { other => { self.restore(other); self.level -= 1; - return Err(self.skip_and_throw_syntax_err(caused_by!())); + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); } } } @@ -1640,7 +1714,9 @@ impl Parser { } Some(ExprOrOp::Op(op)) => { self.level -= 1; - Err(ParseError::compiler_bug(0, op.loc(), fn_name!(), line!())) + self.errs + .push(ParseError::compiler_bug(0, op.loc(), fn_name!(), line!())); + Err(()) } _ => switch_unreachable!(), } @@ -1655,41 +1731,43 @@ impl Parser { match self.peek() { Some(t) if t.category_is(TC::Literal) => { // TODO: 10.times ...などメソッド呼び出しもある - let lit = self.try_reduce_lit().map_err(|e| self.stack_dec(e))?; + let lit = self.try_reduce_lit().map_err(|_| self.stack_dec())?; self.level -= 1; Ok(Expr::Lit(lit)) } Some(t) if t.is(Symbol) || t.is(Dot) => { let acc = self .try_reduce_call_or_acc() - .map_err(|e| self.stack_dec(e))?; + .map_err(|_| self.stack_dec())?; self.level -= 1; Ok(acc) } Some(t) if t.category_is(TC::UnaryOp) => { - let unaryop = self.try_reduce_unary().map_err(|e| self.stack_dec(e))?; + let unaryop = self.try_reduce_unary().map_err(|_| self.stack_dec())?; self.level -= 1; Ok(Expr::UnaryOp(unaryop)) } Some(t) if t.category_is(TC::Caret) => { - let lambda = self.try_reduce_lambda().map_err(|e| self.stack_dec(e))?; + let lambda = self.try_reduce_lambda().map_err(|_| self.stack_dec())?; self.level -= 1; Ok(Expr::Lambda(lambda)) } Some(t) if t.is(LParen) => { self.skip(); - let expr = self.try_reduce_expr().map_err(|e| self.stack_dec(e))?; + let expr = self.try_reduce_expr().map_err(|_| self.stack_dec())?; if self.cur_is(RParen) { self.skip(); self.level -= 1; Ok(expr) } else { self.level -= 1; - Err(self.skip_and_throw_syntax_err(caused_by!())) + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); } } Some(t) if t.is(LSqBr) => { - let array = self.try_reduce_array().map_err(|e| self.stack_dec(e))?; + let array = self.try_reduce_array().map_err(|_| self.stack_dec())?; self.level -= 1; Ok(Expr::Array(array)) } @@ -1699,11 +1777,15 @@ impl Parser { Some(t) if t.is(UBar) => { let token = self.lpop(); self.level -= 1; - Err(ParseError::feature_error(0, token.loc(), "discard pattern")) + self.errs + .push(ParseError::feature_error(0, token.loc(), "discard pattern")); + Err(()) } _other => { self.level -= 1; - Err(self.skip_and_throw_syntax_err(caused_by!())) + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); } } } @@ -1711,9 +1793,9 @@ impl Parser { #[inline] fn try_reduce_call_or_acc(&mut self) -> ParseResult { debug_call_info!(self); - let acc = self.try_reduce_acc().map_err(|e| self.stack_dec(e))?; + let acc = self.try_reduce_acc().map_err(|_| self.stack_dec())?; if let Some(res) = self.opt_reduce_args() { - let args = res.map_err(|e| self.stack_dec(e))?; + let args = res.map_err(|_| self.stack_dec())?; let call = Call::new(Expr::Accessor(acc), args); self.level -= 1; Ok(Expr::Call(call)) @@ -1726,19 +1808,19 @@ impl Parser { #[inline] fn try_reduce_lambda(&mut self) -> ParseResult { debug_call_info!(self); - let sig = self - .try_reduce_lambda_sig() - .map_err(|e| self.stack_dec(e))?; + let sig = self.try_reduce_lambda_sig().map_err(|_| self.stack_dec())?; let op = self.lpop(); if op.category() != TC::LambdaOp { self.level -= 1; - return Err(self.skip_and_throw_syntax_err(caused_by!())); + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + return Err(()); } // REVIEW: この箇所必要か while self.cur_is(Newline) { self.skip(); } - let body = self.try_reduce_block().map_err(|e| self.stack_dec(e))?; + let body = self.try_reduce_block().map_err(|_| self.stack_dec())?; self.counter.inc(); self.level -= 1; Ok(Lambda::new(sig, op, body, self.counter)) @@ -1748,7 +1830,7 @@ impl Parser { fn try_reduce_unary(&mut self) -> ParseResult { debug_call_info!(self); let op = self.lpop(); - let expr = self.try_reduce_expr().map_err(|e| self.stack_dec(e))?; + let expr = self.try_reduce_expr().map_err(|_| self.stack_dec())?; self.level -= 1; Ok(UnaryOp::new(op, expr)) } @@ -1757,13 +1839,21 @@ impl Parser { fn try_reduce_array(&mut self) -> ParseResult { debug_call_info!(self); let l_sqbr = self.lpop(); - let (elems, len, guard) = self.try_reduce_elems().map_err(|e| self.stack_dec(e))?; + let inner = self.try_reduce_elems().map_err(|_| self.stack_dec())?; let r_sqbr = self.lpop(); if !r_sqbr.is(RSqBr) { self.level -= 1; - return Err(ParseError::simple_syntax_error(0, r_sqbr.loc())); + self.errs + .push(ParseError::simple_syntax_error(0, r_sqbr.loc())); + return Err(()); } - let arr = Array::new(l_sqbr, r_sqbr, elems, len, guard); + let arr = match inner { + ArrayInner::Normal(elems) => Array::Normal(NormalArray::new(l_sqbr, r_sqbr, elems)), + ArrayInner::WithLength(elem, len) => { + Array::WithLength(ArrayWithLength::new(l_sqbr, r_sqbr, elem, len)) + } + ArrayInner::Comprehension { .. } => todo!(), + }; self.level -= 1; Ok(arr) } @@ -1774,7 +1864,11 @@ impl Parser { self.level -= 1; match self.peek() { Some(t) if t.is(Symbol) => Ok(VarName::new(self.lpop())), - _ => Err(self.skip_and_throw_syntax_err(caused_by!())), + _ => { + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + Err(()) + } } } @@ -1784,7 +1878,11 @@ impl Parser { self.level -= 1; match self.peek() { Some(t) if t.category_is(TC::Literal) => Ok(Literal::from(self.lpop())), - _ => Err(self.skip_and_throw_syntax_err(caused_by!())), + _ => { + let err = self.skip_and_throw_syntax_err(caused_by!()); + self.errs.push(err); + Err(()) + } } } }