mirror of https://github.com/mtshiba/pylyzer
feat: support `dict/tuple` types
This commit is contained in:
parent
964a3d1284
commit
c47397c159
|
|
@ -96,6 +96,8 @@ pylyzer converts Python ASTs to Erg ASTs and passes them to Erg's type checker.
|
|||
* [x] `Union`
|
||||
* [x] `Optional`
|
||||
* [x] `list`
|
||||
* [x] `dict`
|
||||
* [x] `tuple`
|
||||
* [x] `Literal`
|
||||
* [ ] `TypedDict`
|
||||
* [ ] others
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ use erg_compiler::erg_parser::ast::{
|
|||
NormalTuple, ParamPattern, Params, PosArg, PreDeclTypeSpec, ReDef, Record, RecordAttrs, Set,
|
||||
Signature, SimpleTypeSpec, SubrSignature, Tuple, TypeAscription, TypeBoundSpecs, TypeSpec,
|
||||
TypeSpecWithOp, UnaryOp, VarName, VarPattern, VarRecordAttr, VarRecordAttrs, VarRecordPattern,
|
||||
VarSignature, VisModifierSpec, ConstPosArg,
|
||||
VarSignature, VisModifierSpec, ConstPosArg, ConstDict, ConstKeyValue, TupleTypeSpec,
|
||||
};
|
||||
use erg_compiler::erg_parser::desugar::Desugarer;
|
||||
use erg_compiler::erg_parser::token::{Token, TokenKind, AS, DOT, EQUAL};
|
||||
|
|
@ -565,6 +565,41 @@ impl ASTConverter {
|
|||
let len = ConstPosArg::new(len);
|
||||
TypeSpec::poly(Identifier::private("Array!".into()), ConstArgs::new(vec![elem_t, len], None, vec![], None))
|
||||
}
|
||||
"dict" => {
|
||||
let ExpressionType::Tuple { mut elements } = args.node else {
|
||||
return Self::gen_dummy_type_spec(args.location);
|
||||
};
|
||||
let (l_brace, r_brace) = Self::gen_enclosure_tokens(TokenKind::LBrace, elements.iter(), args.location);
|
||||
let key_t = self.convert_expr(elements.remove(0));
|
||||
let key_t = match Parser::validate_const_expr(key_t) {
|
||||
Ok(key_t) => key_t,
|
||||
Err(err) => {
|
||||
let err = CompileError::new(err.into(), self.cfg.input.clone(), self.cur_namespace());
|
||||
self.errs.push(err);
|
||||
ConstExpr::Accessor(ConstAccessor::Local(Identifier::private("Obj".into())))
|
||||
}
|
||||
};
|
||||
let val_t = self.convert_expr(elements.remove(0));
|
||||
let val_t = match Parser::validate_const_expr(val_t) {
|
||||
Ok(val_t) => val_t,
|
||||
Err(err) => {
|
||||
let err = CompileError::new(err.into(), self.cfg.input.clone(), self.cur_namespace());
|
||||
self.errs.push(err);
|
||||
ConstExpr::Accessor(ConstAccessor::Local(Identifier::private("Obj".into())))
|
||||
}
|
||||
};
|
||||
let dict = ConstPosArg::new(ConstExpr::Dict(ConstDict::new(l_brace, r_brace, vec![ConstKeyValue::new(key_t, val_t)])));
|
||||
TypeSpec::poly(Identifier::private("Dict!".into()), ConstArgs::new(vec![dict], None, vec![], None))
|
||||
}
|
||||
"tuple" => {
|
||||
let ExpressionType::Tuple { elements } = args.node else {
|
||||
return Self::gen_dummy_type_spec(args.location);
|
||||
};
|
||||
let parens = Self::gen_enclosure_tokens(TokenKind::LParen, elements.iter(), args.location);
|
||||
let tys = elements.into_iter().map(|elem| self.convert_type_spec(elem)).collect();
|
||||
let tuple = TupleTypeSpec::new(Some(parens), tys);
|
||||
TypeSpec::Tuple(tuple)
|
||||
}
|
||||
_ => Self::gen_dummy_type_spec(args.location),
|
||||
}
|
||||
}
|
||||
|
|
@ -653,6 +688,7 @@ impl ASTConverter {
|
|||
match expr.node {
|
||||
ExpressionType::Number { value } => {
|
||||
let (kind, cont) = match value {
|
||||
Number::Integer { value } if value >= 0.into() => (TokenKind::NatLit, value.to_string()),
|
||||
Number::Integer { value } => (TokenKind::IntLit, value.to_string()),
|
||||
Number::Float { value } => (TokenKind::RatioLit, value.to_string()),
|
||||
Number::Complex { .. } => {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,13 @@ union_arr.append(None) # ERR
|
|||
|
||||
dic = {"a": 1}
|
||||
dic["b"] = 2
|
||||
|
||||
_ = dic["a"]
|
||||
_ = dic["b"]
|
||||
_ = dic["c"] # ERR
|
||||
|
||||
dic2: dict[str, int] = {"a": 1}
|
||||
_ = dic2["c"] # OK
|
||||
|
||||
t: tuple[int, str] = (1, "a")
|
||||
_ = t[0] == 1 # OK
|
||||
_ = t[1] == 1 # ERR
|
||||
|
|
|
|||
|
|
@ -95,6 +95,6 @@ fn exec_casting() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn exec_collection() {
|
||||
expect("tests/collections.py", 0, 3);
|
||||
fn exec_collections() {
|
||||
expect("tests/collections.py", 0, 4);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue