diff --git a/compiler/erg_compiler/context/instantiate.rs b/compiler/erg_compiler/context/instantiate.rs index c75e56d0..5132226e 100644 --- a/compiler/erg_compiler/context/instantiate.rs +++ b/compiler/erg_compiler/context/instantiate.rs @@ -617,7 +617,11 @@ impl Context { self.instantiate_typespec(lhs, opt_decl_t, tv_ctx, mode)?, self.instantiate_typespec(rhs, opt_decl_t, tv_ctx, mode)?, )), - TypeSpec::Array { .. } => todo!(), + TypeSpec::Array(arr) => { + let elem_t = self.instantiate_typespec(&arr.ty, opt_decl_t, tv_ctx, mode)?; + let len = self.instantiate_const_expr(&arr.len); + Ok(array(elem_t, len)) + } // FIXME: unwrap TypeSpec::Tuple(tys) => Ok(tuple( tys.iter() diff --git a/compiler/erg_parser/ast.rs b/compiler/erg_parser/ast.rs index 4c215b1a..5f63aa50 100644 --- a/compiler/erg_parser/ast.rs +++ b/compiler/erg_parser/ast.rs @@ -1586,6 +1586,15 @@ impl fmt::Display for ArrayTypeSpec { impl_locational!(ArrayTypeSpec, ty, len); +impl ArrayTypeSpec { + pub fn new(ty: TypeSpec, len: ConstExpr) -> Self { + Self { + ty: Box::new(ty), + len, + } + } +} + /// * Array: `[Int; 3]`, `[Int, Ratio, Complex]`, etc. /// * Dict: `[Str: Str]`, etc. /// * And (Intersection type): Add and Sub and Mul (== Num), etc. diff --git a/compiler/erg_parser/parse.rs b/compiler/erg_parser/parse.rs index 821b9704..09f25917 100644 --- a/compiler/erg_parser/parse.rs +++ b/compiler/erg_parser/parse.rs @@ -2485,6 +2485,25 @@ impl Parser { self.level -= 1; Ok(TypeSpec::Array(array)) } + Expr::BinOp(bin) => { + if bin.op.kind.is_range_op() { + let op = bin.op; + let mut args = bin.args.into_iter(); + let lhs = self + .validate_const_expr(*args.next().unwrap()) + .map_err(|_| self.stack_dec())?; + let rhs = self + .validate_const_expr(*args.next().unwrap()) + .map_err(|_| self.stack_dec())?; + self.level -= 1; + Ok(TypeSpec::Interval { op, lhs, rhs }) + } else { + self.level -= 1; + let err = ParseError::simple_syntax_error(line!() as usize, bin.loc()); + self.errs.push(err); + Err(()) + } + } other => { self.level -= 1; let err = ParseError::simple_syntax_error(line!() as usize, other.loc()); @@ -2586,8 +2605,27 @@ impl Parser { )) } - fn convert_array_to_array_type_spec(&mut self, _array: Array) -> ParseResult { + fn convert_array_to_array_type_spec(&mut self, array: Array) -> ParseResult { debug_call_info!(self); - todo!() + match array { + Array::Normal(arr) => { + // TODO: add hint + self.errs + .push(ParseError::simple_syntax_error(line!() as usize, arr.loc())); + Err(()) + } + Array::WithLength(arr) => { + let t_spec = self.convert_rhs_to_type_spec(arr.elem.expr)?; + let len = self.validate_const_expr(*arr.len)?; + self.level -= 1; + Ok(ArrayTypeSpec::new(t_spec, len)) + } + Array::Comprehension(arr) => { + // TODO: add hint + self.errs + .push(ParseError::simple_syntax_error(line!() as usize, arr.loc())); + Err(()) + } + } } } diff --git a/compiler/erg_parser/token.rs b/compiler/erg_parser/token.rs index b59efee1..451657aa 100644 --- a/compiler/erg_parser/token.rs +++ b/compiler/erg_parser/token.rs @@ -265,6 +265,10 @@ impl TokenKind { FuncArrow | ProcArrow | Equal /* | PreDollar | PreAt */ ) } + + pub const fn is_range_op(&self) -> bool { + matches!(self, Closed | LeftOpen | RightOpen | Open) + } } impl fmt::Display for TokenKind {