Implement match guard (Enum type)

This commit is contained in:
Shunsuke Shibayama 2022-11-09 23:27:11 +09:00
parent 30604fc299
commit 0ad31f4391
3 changed files with 95 additions and 14 deletions

View file

@ -59,6 +59,7 @@ pub enum CommonOpcode {
// POP_JUMP_IF_FALSE = 114, // POP_JUMP_IF_FALSE = 114,
// POP_JUMP_IF_TRUE = 115, // POP_JUMP_IF_TRUE = 115,
LOAD_GLOBAL = 116, LOAD_GLOBAL = 116,
CONTAINS_OP = 118,
LOAD_FAST = 124, LOAD_FAST = 124,
STORE_FAST = 125, STORE_FAST = 125,
DELETE_FAST = 126, DELETE_FAST = 126,
@ -123,6 +124,7 @@ impl TryFrom<u8> for CommonOpcode {
// 114 => POP_JUMP_IF_FALSE, // 114 => POP_JUMP_IF_FALSE,
// 115 => POP_JUMP_IF_TRUE, // 115 => POP_JUMP_IF_TRUE,
116 => LOAD_GLOBAL, 116 => LOAD_GLOBAL,
118 => CONTAINS_OP,
124 => LOAD_FAST, 124 => LOAD_FAST,
125 => STORE_FAST, 125 => STORE_FAST,
126 => DELETE_FAST, 126 => DELETE_FAST,

View file

@ -1677,19 +1677,20 @@ impl PyCodeGenerator {
#[allow(clippy::single_match)] #[allow(clippy::single_match)]
match t_spec { match t_spec {
TypeSpec::Enum(enm) => { TypeSpec::Enum(enm) => {
let (mut elems, ..) = enm.deconstruct(); let elems = enm
if elems.len() != 1 { .deconstruct()
todo!() .0
} .into_iter()
let ConstExpr::Lit(lit) = elems.remove(0).expr else { .map(|elem| {
todo!() let ConstExpr::Lit(lit) = elem.expr else { todo!() };
};
let value = {
let t = type_from_token_kind(lit.token.kind); let t = type_from_token_kind(lit.token.kind);
ValueObj::from_str(t, lit.token.content).unwrap() ValueObj::from_str(t, lit.token.content).unwrap()
}; })
self.emit_load_const(value); .collect::<Vec<_>>();
self.emit_compare_op(CompareOp::EQ); self.emit_load_const(elems);
self.write_instr(CONTAINS_OP);
self.write_arg(0);
self.stack_dec();
pop_jump_points.push(self.lasti()); pop_jump_points.push(self.lasti());
// in 3.11, POP_JUMP_IF_FALSE is replaced with POP_JUMP_FORWARD_IF_FALSE // in 3.11, POP_JUMP_IF_FALSE is replaced with POP_JUMP_FORWARD_IF_FALSE
// but the numbers are the same, only the way the jumping points are calculated is different. // but the numbers are the same, only the way the jumping points are calculated is different.
@ -1697,8 +1698,14 @@ impl PyCodeGenerator {
self.write_arg(0); self.write_arg(0);
self.stack_dec(); self.stack_dec();
} }
/*TypeSpec::Interval { op, lhs, rhs } => {
let binop = BinOp::new(op, lhs.downcast(), rhs.downcast(), VarInfo::default());
self.emit_binop(binop);
}*/
// TODO: // TODO:
_ => {} other => {
log!(err "{other}")
}
} }
} }

View file

@ -1159,6 +1159,10 @@ impl ConstLocal {
pub const fn inspect(&self) -> &Str { pub const fn inspect(&self) -> &Str {
&self.symbol.content &self.symbol.content
} }
pub fn downcast(self) -> Identifier {
Identifier::new(None, VarName::new(self.symbol))
}
} }
/// type variables /// type variables
@ -1190,6 +1194,10 @@ impl ConstAttribute {
name, name,
} }
} }
pub fn downcast(self) -> Attribute {
Attribute::new(self.obj.downcast(), self.name.downcast())
}
} }
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
@ -1277,6 +1285,16 @@ impl ConstAccessor {
pub fn subscr(obj: ConstExpr, index: ConstExpr) -> Self { pub fn subscr(obj: ConstExpr, index: ConstExpr) -> Self {
Self::Subscr(ConstSubscript::new(obj, index)) Self::Subscr(ConstSubscript::new(obj, index))
} }
pub fn downcast(self) -> Accessor {
match self {
Self::Local(local) => Accessor::Ident(local.downcast()),
Self::Attr(attr) => Accessor::Attr(attr.downcast()),
// Self::TupleAttr(attr) => Accessor::TupleAttr(attr.downcast()),
// Self::Subscr(subscr) => Accessor::Subscr(subscr.downcast()),
_ => todo!(),
}
}
} }
/// DictはキーつきArray(型としては別物) /// DictはキーつきArray(型としては別物)
@ -1310,6 +1328,14 @@ impl ConstArray {
guard: guard.map(Box::new), guard: guard.map(Box::new),
} }
} }
pub fn downcast(self) -> Array {
Array::Normal(NormalArray::new(
self.l_sqbr,
self.r_sqbr,
self.elems.downcast(),
))
}
} }
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
@ -1336,6 +1362,10 @@ impl ConstDict {
attrs, attrs,
} }
} }
/*pub fn downcast(self) -> Dict {
Dict::Normal(NormalDict::new(self.l_brace, self.r_brace, self.attrs.downcast()))
}*/
} }
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
@ -1362,6 +1392,10 @@ impl ConstBinOp {
rhs: Box::new(rhs), rhs: Box::new(rhs),
} }
} }
pub fn downcast(self) -> BinOp {
BinOp::new(self.op, self.lhs.downcast(), self.rhs.downcast())
}
} }
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
@ -1386,6 +1420,10 @@ impl ConstUnaryOp {
expr: Box::new(expr), expr: Box::new(expr),
} }
} }
pub fn downcast(self) -> UnaryOp {
UnaryOp::new(self.op, self.expr.downcast())
}
} }
/// Application /// Application
@ -1417,6 +1455,10 @@ impl ConstApp {
pub const fn new(acc: ConstAccessor, args: ConstArgs) -> Self { pub const fn new(acc: ConstAccessor, args: ConstArgs) -> Self {
Self { acc, args } Self { acc, args }
} }
pub fn downcast(self) -> Call {
Expr::Accessor(self.acc.downcast()).call(self.args.downcast())
}
} }
/// valid expression for an argument of polymorphic types /// valid expression for an argument of polymorphic types
@ -1442,6 +1484,20 @@ impl ConstExpr {
pub fn need_to_be_closed(&self) -> bool { pub fn need_to_be_closed(&self) -> bool {
matches!(self, Self::BinOp(_) | Self::UnaryOp(_)) matches!(self, Self::BinOp(_) | Self::UnaryOp(_))
} }
pub fn downcast(self) -> Expr {
match self {
Self::Lit(lit) => Expr::Lit(lit),
Self::Accessor(acc) => Expr::Accessor(acc.downcast()),
Self::App(app) => Expr::Call(app.downcast()),
Self::Array(arr) => Expr::Array(arr.downcast()),
// Self::Set(set) => Expr::Set(set.downcast()),
// Self::Dict(dict) => Expr::Dict(dict.downcast()),
Self::BinOp(binop) => Expr::BinOp(binop.downcast()),
Self::UnaryOp(unop) => Expr::UnaryOp(unop.downcast()),
_ => todo!(),
}
}
} }
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
@ -1565,6 +1621,22 @@ impl ConstArgs {
pub fn push_kw(&mut self, arg: ConstKwArg) { pub fn push_kw(&mut self, arg: ConstKwArg) {
self.kw_args.push(arg); self.kw_args.push(arg);
} }
pub fn downcast(self) -> Args {
let (pos_args, kw_args, paren) = self.deconstruct();
Args::new(
pos_args
.into_iter()
.map(|arg| PosArg::new(arg.expr.downcast()))
.collect(),
kw_args
.into_iter()
// TODO t_spec
.map(|arg| KwArg::new(arg.keyword, None, arg.expr.downcast()))
.collect(),
paren,
)
}
} }
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]