feat: add as operator

This commit is contained in:
Shunsuke Shibayama 2023-04-19 15:20:46 +09:00
parent 1c6a6b2ec8
commit daf01f3cf2
14 changed files with 119 additions and 12 deletions

View file

@ -1452,6 +1452,11 @@ impl PyCodeGenerator {
self.emit_push_null();
self.emit_load_name_instr(Identifier::private("#in_operator"));
}
// (x as T) == x
TokenKind::AsOp => {
self.emit_expr(*bin.lhs);
return;
}
_ => {}
}
let lhs_t = bin

View file

@ -79,6 +79,7 @@ fn op_to_name(op: OpKind) -> &'static str {
OpKind::Le => "__le__",
OpKind::Gt => "__gt__",
OpKind::Ge => "__ge__",
OpKind::As => "__as__",
OpKind::And => "__and__",
OpKind::Or => "__or__",
OpKind::Not => "__not__",

View file

@ -604,6 +604,10 @@ impl Context {
let op_t = bin_op(I, T, Bool).quantify();
self.register_builtin_erg_impl(OP_IN, op_t.clone(), Const, Visibility::BUILTIN_PRIVATE);
self.register_builtin_erg_impl(OP_NOT_IN, op_t, Const, Visibility::BUILTIN_PRIVATE);
let Sub = mono_q(TY_SUB, instanceof(Type));
let Sup = mono_q(TY_SUP, supertypeof(Sub.clone()));
let op_t = bin_op(Sub, tp_enum(Type, set! { ty_tp(Sup.clone()) }), Sup).quantify();
self.register_builtin_erg_impl(OP_AS, op_t, Const, Visibility::BUILTIN_PRIVATE);
/* unary */
// TODO: +/- Bool would like to be warned
let M = mono_q(TY_M, subtypeof(mono(MUTIZABLE)));

View file

@ -336,6 +336,7 @@ const OP_DIV: &str = "__div__";
const OP_FLOOR_DIV: &str = "__floordiv__";
const OP_ABS: &str = "__abs__";
const OP_PARTIAL_CMP: &str = "__partial_cmp__";
const OP_AS: &str = "__as__";
const OP_AND: &str = "__and__";
const OP_OR: &str = "__or__";
const OP_POW: &str = "__pow__";
@ -395,6 +396,8 @@ const TY_L: &str = "L";
const TY_N: &str = "N";
const TY_M: &str = "M";
const TY_O: &str = "O";
const TY_SUB: &str = "Sub";
const TY_SUP: &str = "Sup";
const KW_OLD: &str = "old";
const KW_B: &str = "b";

View file

@ -94,6 +94,7 @@ pub fn binop_to_dname(op: &str) -> &str {
"&&" | "&" | "and" => "__and__",
"||" | "|" | "or" => "__or__",
"^^" | "^" => "__xor__",
"as" => "__as__",
"in" => "__in__",
"notin" => "__notin__", // NOTE: this doesn't exist in Python
"contains" => "__contains__",
@ -138,6 +139,7 @@ pub fn readable_name(name: &str) -> &str {
"__lorng__" => "`<..`",
"__rorng__" => "`..<`",
"__orng__" => "`<..<`",
"__as__" => "`as`",
"__and__" => "`and`", // TODO: `&&` if not boolean
"__or__" => "`or`", // TODO: `||` if not boolean
"__in__" => "`in`",

View file

@ -482,6 +482,11 @@ pub fn subtypeof(sup: Type) -> Constraint {
Constraint::new_sandwiched(Type::Never, sup)
}
#[inline]
pub fn supertypeof(sub: Type) -> Constraint {
Constraint::new_sandwiched(sub, Type::Obj)
}
#[inline]
pub fn mono_q_tp<S: Into<Str>>(name: S, constr: Constraint) -> TyParam {
TyParam::mono_q(name, constr)

View file

@ -39,6 +39,7 @@ pub enum OpKind {
Le,
Eq,
Ne,
As,
And,
Or,
Not,
@ -69,6 +70,7 @@ impl fmt::Display for OpKind {
Self::Le => write!(f, "<="),
Self::Eq => write!(f, "=="),
Self::Ne => write!(f, "!="),
Self::As => write!(f, "as"),
Self::And => write!(f, "and"),
Self::Or => write!(f, "or"),
Self::Not => write!(f, "not"),