mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-29 04:24:43 +00:00
Change ref
and ref!
to unary operators
This commit is contained in:
parent
62e89a1edf
commit
f0d686cd7b
5 changed files with 87 additions and 55 deletions
|
@ -1987,6 +1987,12 @@ impl NestedDisplay for VarRecordAttr {
|
|||
impl_display_from_nested!(VarRecordAttr);
|
||||
impl_locational!(VarRecordAttr, lhs, rhs);
|
||||
|
||||
impl VarRecordAttr {
|
||||
pub const fn new(lhs: Identifier, rhs: Identifier) -> Self {
|
||||
Self { lhs, rhs }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct VarRecordAttrs {
|
||||
pub(crate) elems: Vec<VarRecordAttr>,
|
||||
|
@ -2038,7 +2044,7 @@ impl VarRecordPattern {
|
|||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct VarDataPackPattern {
|
||||
pub class: Identifier, // TODO: allow Attribute
|
||||
pub class: Accessor, // TODO: allow polymorphic
|
||||
pub args: VarRecordPattern,
|
||||
}
|
||||
|
||||
|
@ -2051,7 +2057,7 @@ impl fmt::Display for VarDataPackPattern {
|
|||
impl_locational!(VarDataPackPattern, class, args);
|
||||
|
||||
impl VarDataPackPattern {
|
||||
pub const fn new(class: Identifier, args: VarRecordPattern) -> Self {
|
||||
pub const fn new(class: Accessor, args: VarRecordPattern) -> Self {
|
||||
Self { class, args }
|
||||
}
|
||||
}
|
||||
|
@ -2275,6 +2281,7 @@ pub enum ParamPattern {
|
|||
Array(ParamArrayPattern),
|
||||
Tuple(ParamTuplePattern),
|
||||
Record(ParamRecordPattern),
|
||||
// DataPack(ParamDataPackPattern),
|
||||
Ref(VarName),
|
||||
RefMut(VarName),
|
||||
// e.g. `a` of `[...a, b] = [1, 2, 3]` (a == [1, 2], b == 3)
|
||||
|
|
|
@ -367,20 +367,14 @@ impl Desugarer {
|
|||
todo!("{dict}")
|
||||
}
|
||||
Expr::BinOp(binop) => {
|
||||
let mut args = vec![];
|
||||
for arg in binop.args.into_iter() {
|
||||
args.push(self.rec_desugar_shortened_record(*arg));
|
||||
}
|
||||
let lhs = args.remove(0);
|
||||
let rhs = args.remove(0);
|
||||
let mut args = binop.args.into_iter();
|
||||
let lhs = self.rec_desugar_shortened_record(*args.next().unwrap());
|
||||
let rhs = self.rec_desugar_shortened_record(*args.next().unwrap());
|
||||
Expr::BinOp(BinOp::new(binop.op, lhs, rhs))
|
||||
}
|
||||
Expr::UnaryOp(unaryop) => {
|
||||
let mut args = vec![];
|
||||
for arg in unaryop.args.into_iter() {
|
||||
args.push(self.rec_desugar_shortened_record(*arg));
|
||||
}
|
||||
let expr = args.remove(0);
|
||||
let mut args = unaryop.args.into_iter();
|
||||
let expr = self.rec_desugar_shortened_record(*args.next().unwrap());
|
||||
Expr::UnaryOp(UnaryOp::new(unaryop.op, expr))
|
||||
}
|
||||
Expr::Call(call) => {
|
||||
|
|
|
@ -525,6 +525,8 @@ impl Lexer /*<'a>*/ {
|
|||
"isnot" => IsNotOp,
|
||||
"dot" => DotOp,
|
||||
"cross" => CrossOp,
|
||||
"ref" => RefOp,
|
||||
"ref!" => RefMutOp,
|
||||
// これらはリテラルというより定数だが便宜的にリテラルということにしておく
|
||||
"True" | "False" => BoolLit,
|
||||
"None" => NoneLit,
|
||||
|
|
|
@ -1692,22 +1692,51 @@ impl Parser {
|
|||
todo!()
|
||||
}
|
||||
|
||||
fn convert_record_to_record_pat(&mut self, _record: Record) -> ParseResult<VarRecordPattern> {
|
||||
fn convert_record_to_record_pat(&mut self, record: Record) -> ParseResult<VarRecordPattern> {
|
||||
debug_call_info!(self);
|
||||
match _record {
|
||||
Record::Normal(_rec) => {
|
||||
todo!()
|
||||
match record {
|
||||
Record::Normal(rec) => {
|
||||
let mut pats = vec![];
|
||||
for mut attr in rec.attrs.into_iter() {
|
||||
let lhs =
|
||||
option_enum_unwrap!(attr.sig, Signature::Var).unwrap_or_else(|| todo!());
|
||||
let lhs =
|
||||
option_enum_unwrap!(lhs.pat, VarPattern::Ident).unwrap_or_else(|| todo!());
|
||||
assert_eq!(attr.body.block.len(), 1);
|
||||
let rhs = option_enum_unwrap!(attr.body.block.remove(0), Expr::Accessor)
|
||||
.unwrap_or_else(|| todo!());
|
||||
let rhs = self
|
||||
.convert_accessor_to_ident(rhs)
|
||||
.map_err(|_| self.stack_dec())?;
|
||||
pats.push(VarRecordAttr::new(lhs, rhs));
|
||||
}
|
||||
let attrs = VarRecordAttrs::new(pats);
|
||||
self.level -= 1;
|
||||
Ok(VarRecordPattern::new(rec.l_brace, attrs, rec.r_brace))
|
||||
}
|
||||
Record::Shortened(rec) => {
|
||||
let mut pats = vec![];
|
||||
for ident in rec.idents.into_iter() {
|
||||
pats.push(VarRecordAttr::new(ident.clone(), ident));
|
||||
}
|
||||
let attrs = VarRecordAttrs::new(pats);
|
||||
self.level -= 1;
|
||||
Ok(VarRecordPattern::new(rec.l_brace, attrs, rec.r_brace))
|
||||
}
|
||||
_ => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_data_pack_to_data_pack_pat(
|
||||
&mut self,
|
||||
_pack: DataPack,
|
||||
pack: DataPack,
|
||||
) -> ParseResult<VarDataPackPattern> {
|
||||
debug_call_info!(self);
|
||||
todo!()
|
||||
let class = option_enum_unwrap!(*pack.class, Expr::Accessor).unwrap_or_else(|| todo!());
|
||||
let args = self
|
||||
.convert_record_to_record_pat(pack.args)
|
||||
.map_err(|_| self.stack_dec())?;
|
||||
self.level -= 1;
|
||||
Ok(VarDataPackPattern::new(class, args))
|
||||
}
|
||||
|
||||
fn convert_tuple_to_tuple_pat(&mut self, tuple: Tuple) -> ParseResult<VarTuplePattern> {
|
||||
|
@ -1868,30 +1897,26 @@ impl Parser {
|
|||
self.level -= 1;
|
||||
Ok(param)
|
||||
}
|
||||
Expr::Call(mut call) => match *call.obj {
|
||||
Expr::Accessor(Accessor::Local(local)) => match &local.inspect()[..] {
|
||||
"ref" => {
|
||||
assert_eq!(call.args.len(), 1);
|
||||
let var = call.args.remove_pos(0).expr;
|
||||
let var = option_enum_unwrap!(var, Expr::Accessor:(Accessor::Local:(_)))
|
||||
.unwrap_or_else(|| todo!());
|
||||
let pat = ParamPattern::Ref(VarName::new(var.symbol));
|
||||
let param = ParamSignature::new(pat, None, None);
|
||||
self.level -= 1;
|
||||
Ok(param)
|
||||
}
|
||||
"ref!" => {
|
||||
assert_eq!(call.args.len(), 1);
|
||||
let var = call.args.remove_pos(0).expr;
|
||||
let var = option_enum_unwrap!(var, Expr::Accessor:(Accessor::Local:(_)))
|
||||
.unwrap_or_else(|| todo!());
|
||||
let pat = ParamPattern::RefMut(VarName::new(var.symbol));
|
||||
let param = ParamSignature::new(pat, None, None);
|
||||
self.level -= 1;
|
||||
Ok(param)
|
||||
}
|
||||
other => todo!("{other}"),
|
||||
},
|
||||
Expr::UnaryOp(unary) => match unary.op.kind {
|
||||
TokenKind::RefOp => {
|
||||
let var = unary.args.into_iter().next().unwrap();
|
||||
let var = option_enum_unwrap!(*var, Expr::Accessor:(Accessor::Local:(_)))
|
||||
.unwrap_or_else(|| todo!());
|
||||
let pat = ParamPattern::Ref(VarName::new(var.symbol));
|
||||
let param = ParamSignature::new(pat, None, None);
|
||||
self.level -= 1;
|
||||
Ok(param)
|
||||
}
|
||||
TokenKind::RefMutOp => {
|
||||
let var = unary.args.into_iter().next().unwrap();
|
||||
let var = option_enum_unwrap!(*var, Expr::Accessor:(Accessor::Local:(_)))
|
||||
.unwrap_or_else(|| todo!());
|
||||
let pat = ParamPattern::RefMut(VarName::new(var.symbol));
|
||||
let param = ParamSignature::new(pat, None, None);
|
||||
self.level -= 1;
|
||||
Ok(param)
|
||||
}
|
||||
// Spread
|
||||
other => todo!("{other}"),
|
||||
},
|
||||
other => todo!("{other}"), // Error
|
||||
|
|
|
@ -103,6 +103,10 @@ pub enum TokenKind {
|
|||
DotOp,
|
||||
/// `cross` (vector product)
|
||||
CrossOp,
|
||||
/// `ref` (special unary)
|
||||
RefOp,
|
||||
/// `ref!` (special unary)
|
||||
RefMutOp,
|
||||
/// =
|
||||
Equal,
|
||||
/// :=
|
||||
|
@ -210,7 +214,7 @@ impl TokenKind {
|
|||
Symbol => TokenCategory::Symbol,
|
||||
NatLit | IntLit | RatioLit | StrLit | BoolLit | NoneLit | EllipsisLit | NoImplLit
|
||||
| InfLit => TokenCategory::Literal,
|
||||
PrePlus | PreMinus | PreBitNot | Mutate => TokenCategory::UnaryOp,
|
||||
PrePlus | PreMinus | PreBitNot | Mutate | RefOp | RefMutOp => TokenCategory::UnaryOp,
|
||||
Try => TokenCategory::PostfixOp,
|
||||
Comma | Colon | DblColon | SupertypeOf | SubtypeOf | Dot | Pipe | Walrus => {
|
||||
TokenCategory::SpecialBinOp
|
||||
|
@ -234,16 +238,16 @@ impl TokenKind {
|
|||
|
||||
pub const fn precedence(&self) -> Option<usize> {
|
||||
let prec = match self {
|
||||
Dot | DblColon => 200, // .
|
||||
Pow => 190, // **
|
||||
PrePlus | PreMinus | PreBitNot => 180, // (unary) + - * ~
|
||||
Star | Slash | FloorDiv | Mod | CrossOp | DotOp => 170, // * / // % cross dot
|
||||
Plus | Minus => 160, // + -
|
||||
Shl | Shr => 150, // << >>
|
||||
BitAnd => 140, // &&
|
||||
BitXor => 130, // ^^
|
||||
BitOr => 120, // ||
|
||||
Closed | LeftOpen | RightOpen | Open => 100, // range operators
|
||||
Dot | DblColon => 200, // .
|
||||
Pow => 190, // **
|
||||
PrePlus | PreMinus | PreBitNot | RefOp | RefMutOp => 180, // (unary) + - * ~ ref ref!
|
||||
Star | Slash | FloorDiv | Mod | CrossOp | DotOp => 170, // * / // % cross dot
|
||||
Plus | Minus => 160, // + -
|
||||
Shl | Shr => 150, // << >>
|
||||
BitAnd => 140, // &&
|
||||
BitXor => 130, // ^^
|
||||
BitOr => 120, // ||
|
||||
Closed | LeftOpen | RightOpen | Open => 100, // range operators
|
||||
Less | Gre | LessEq | GreEq | DblEq | NotEq | InOp | NotInOp | IsOp | IsNotOp => 90, // < > <= >= == != in notin is isnot
|
||||
AndOp => 80, // and
|
||||
OrOp => 70, // or
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue