mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-29 04:24:43 +00:00
Add type specification for array and range types
This commit is contained in:
parent
f6637f0f51
commit
f548f9e6ef
4 changed files with 58 additions and 3 deletions
|
@ -617,7 +617,11 @@ impl Context {
|
||||||
self.instantiate_typespec(lhs, opt_decl_t, tv_ctx, mode)?,
|
self.instantiate_typespec(lhs, opt_decl_t, tv_ctx, mode)?,
|
||||||
self.instantiate_typespec(rhs, 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
|
// FIXME: unwrap
|
||||||
TypeSpec::Tuple(tys) => Ok(tuple(
|
TypeSpec::Tuple(tys) => Ok(tuple(
|
||||||
tys.iter()
|
tys.iter()
|
||||||
|
|
|
@ -1586,6 +1586,15 @@ impl fmt::Display for ArrayTypeSpec {
|
||||||
|
|
||||||
impl_locational!(ArrayTypeSpec, ty, len);
|
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.
|
/// * Array: `[Int; 3]`, `[Int, Ratio, Complex]`, etc.
|
||||||
/// * Dict: `[Str: Str]`, etc.
|
/// * Dict: `[Str: Str]`, etc.
|
||||||
/// * And (Intersection type): Add and Sub and Mul (== Num), etc.
|
/// * And (Intersection type): Add and Sub and Mul (== Num), etc.
|
||||||
|
|
|
@ -2485,6 +2485,25 @@ impl Parser {
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
Ok(TypeSpec::Array(array))
|
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 => {
|
other => {
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
let err = ParseError::simple_syntax_error(line!() as usize, other.loc());
|
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<ArrayTypeSpec> {
|
fn convert_array_to_array_type_spec(&mut self, array: Array) -> ParseResult<ArrayTypeSpec> {
|
||||||
debug_call_info!(self);
|
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(())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -265,6 +265,10 @@ impl TokenKind {
|
||||||
FuncArrow | ProcArrow | Equal /* | PreDollar | PreAt */
|
FuncArrow | ProcArrow | Equal /* | PreDollar | PreAt */
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const fn is_range_op(&self) -> bool {
|
||||||
|
matches!(self, Closed | LeftOpen | RightOpen | Open)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for TokenKind {
|
impl fmt::Display for TokenKind {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue