Add type specification for array and range types

This commit is contained in:
Shunsuke Shibayama 2022-09-28 00:05:23 +09:00
parent f6637f0f51
commit f548f9e6ef
4 changed files with 58 additions and 3 deletions

View file

@ -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()

View file

@ -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.

View file

@ -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(())
}
}
} }
} }

View file

@ -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 {