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_display_from_nested!(VarRecordAttr);
|
||||||
impl_locational!(VarRecordAttr, lhs, rhs);
|
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)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct VarRecordAttrs {
|
pub struct VarRecordAttrs {
|
||||||
pub(crate) elems: Vec<VarRecordAttr>,
|
pub(crate) elems: Vec<VarRecordAttr>,
|
||||||
|
@ -2038,7 +2044,7 @@ impl VarRecordPattern {
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct VarDataPackPattern {
|
pub struct VarDataPackPattern {
|
||||||
pub class: Identifier, // TODO: allow Attribute
|
pub class: Accessor, // TODO: allow polymorphic
|
||||||
pub args: VarRecordPattern,
|
pub args: VarRecordPattern,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2051,7 +2057,7 @@ impl fmt::Display for VarDataPackPattern {
|
||||||
impl_locational!(VarDataPackPattern, class, args);
|
impl_locational!(VarDataPackPattern, class, args);
|
||||||
|
|
||||||
impl VarDataPackPattern {
|
impl VarDataPackPattern {
|
||||||
pub const fn new(class: Identifier, args: VarRecordPattern) -> Self {
|
pub const fn new(class: Accessor, args: VarRecordPattern) -> Self {
|
||||||
Self { class, args }
|
Self { class, args }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2275,6 +2281,7 @@ pub enum ParamPattern {
|
||||||
Array(ParamArrayPattern),
|
Array(ParamArrayPattern),
|
||||||
Tuple(ParamTuplePattern),
|
Tuple(ParamTuplePattern),
|
||||||
Record(ParamRecordPattern),
|
Record(ParamRecordPattern),
|
||||||
|
// DataPack(ParamDataPackPattern),
|
||||||
Ref(VarName),
|
Ref(VarName),
|
||||||
RefMut(VarName),
|
RefMut(VarName),
|
||||||
// e.g. `a` of `[...a, b] = [1, 2, 3]` (a == [1, 2], b == 3)
|
// e.g. `a` of `[...a, b] = [1, 2, 3]` (a == [1, 2], b == 3)
|
||||||
|
|
|
@ -367,20 +367,14 @@ impl Desugarer {
|
||||||
todo!("{dict}")
|
todo!("{dict}")
|
||||||
}
|
}
|
||||||
Expr::BinOp(binop) => {
|
Expr::BinOp(binop) => {
|
||||||
let mut args = vec![];
|
let mut args = binop.args.into_iter();
|
||||||
for arg in binop.args.into_iter() {
|
let lhs = self.rec_desugar_shortened_record(*args.next().unwrap());
|
||||||
args.push(self.rec_desugar_shortened_record(*arg));
|
let rhs = self.rec_desugar_shortened_record(*args.next().unwrap());
|
||||||
}
|
|
||||||
let lhs = args.remove(0);
|
|
||||||
let rhs = args.remove(0);
|
|
||||||
Expr::BinOp(BinOp::new(binop.op, lhs, rhs))
|
Expr::BinOp(BinOp::new(binop.op, lhs, rhs))
|
||||||
}
|
}
|
||||||
Expr::UnaryOp(unaryop) => {
|
Expr::UnaryOp(unaryop) => {
|
||||||
let mut args = vec![];
|
let mut args = unaryop.args.into_iter();
|
||||||
for arg in unaryop.args.into_iter() {
|
let expr = self.rec_desugar_shortened_record(*args.next().unwrap());
|
||||||
args.push(self.rec_desugar_shortened_record(*arg));
|
|
||||||
}
|
|
||||||
let expr = args.remove(0);
|
|
||||||
Expr::UnaryOp(UnaryOp::new(unaryop.op, expr))
|
Expr::UnaryOp(UnaryOp::new(unaryop.op, expr))
|
||||||
}
|
}
|
||||||
Expr::Call(call) => {
|
Expr::Call(call) => {
|
||||||
|
|
|
@ -525,6 +525,8 @@ impl Lexer /*<'a>*/ {
|
||||||
"isnot" => IsNotOp,
|
"isnot" => IsNotOp,
|
||||||
"dot" => DotOp,
|
"dot" => DotOp,
|
||||||
"cross" => CrossOp,
|
"cross" => CrossOp,
|
||||||
|
"ref" => RefOp,
|
||||||
|
"ref!" => RefMutOp,
|
||||||
// これらはリテラルというより定数だが便宜的にリテラルということにしておく
|
// これらはリテラルというより定数だが便宜的にリテラルということにしておく
|
||||||
"True" | "False" => BoolLit,
|
"True" | "False" => BoolLit,
|
||||||
"None" => NoneLit,
|
"None" => NoneLit,
|
||||||
|
|
|
@ -1692,22 +1692,51 @@ impl Parser {
|
||||||
todo!()
|
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);
|
debug_call_info!(self);
|
||||||
match _record {
|
match record {
|
||||||
Record::Normal(_rec) => {
|
Record::Normal(rec) => {
|
||||||
todo!()
|
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(
|
fn convert_data_pack_to_data_pack_pat(
|
||||||
&mut self,
|
&mut self,
|
||||||
_pack: DataPack,
|
pack: DataPack,
|
||||||
) -> ParseResult<VarDataPackPattern> {
|
) -> ParseResult<VarDataPackPattern> {
|
||||||
debug_call_info!(self);
|
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> {
|
fn convert_tuple_to_tuple_pat(&mut self, tuple: Tuple) -> ParseResult<VarTuplePattern> {
|
||||||
|
@ -1868,30 +1897,26 @@ impl Parser {
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
Ok(param)
|
Ok(param)
|
||||||
}
|
}
|
||||||
Expr::Call(mut call) => match *call.obj {
|
Expr::UnaryOp(unary) => match unary.op.kind {
|
||||||
Expr::Accessor(Accessor::Local(local)) => match &local.inspect()[..] {
|
TokenKind::RefOp => {
|
||||||
"ref" => {
|
let var = unary.args.into_iter().next().unwrap();
|
||||||
assert_eq!(call.args.len(), 1);
|
let var = option_enum_unwrap!(*var, Expr::Accessor:(Accessor::Local:(_)))
|
||||||
let var = call.args.remove_pos(0).expr;
|
|
||||||
let var = option_enum_unwrap!(var, Expr::Accessor:(Accessor::Local:(_)))
|
|
||||||
.unwrap_or_else(|| todo!());
|
.unwrap_or_else(|| todo!());
|
||||||
let pat = ParamPattern::Ref(VarName::new(var.symbol));
|
let pat = ParamPattern::Ref(VarName::new(var.symbol));
|
||||||
let param = ParamSignature::new(pat, None, None);
|
let param = ParamSignature::new(pat, None, None);
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
Ok(param)
|
Ok(param)
|
||||||
}
|
}
|
||||||
"ref!" => {
|
TokenKind::RefMutOp => {
|
||||||
assert_eq!(call.args.len(), 1);
|
let var = unary.args.into_iter().next().unwrap();
|
||||||
let var = call.args.remove_pos(0).expr;
|
let var = option_enum_unwrap!(*var, Expr::Accessor:(Accessor::Local:(_)))
|
||||||
let var = option_enum_unwrap!(var, Expr::Accessor:(Accessor::Local:(_)))
|
|
||||||
.unwrap_or_else(|| todo!());
|
.unwrap_or_else(|| todo!());
|
||||||
let pat = ParamPattern::RefMut(VarName::new(var.symbol));
|
let pat = ParamPattern::RefMut(VarName::new(var.symbol));
|
||||||
let param = ParamSignature::new(pat, None, None);
|
let param = ParamSignature::new(pat, None, None);
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
Ok(param)
|
Ok(param)
|
||||||
}
|
}
|
||||||
other => todo!("{other}"),
|
// Spread
|
||||||
},
|
|
||||||
other => todo!("{other}"),
|
other => todo!("{other}"),
|
||||||
},
|
},
|
||||||
other => todo!("{other}"), // Error
|
other => todo!("{other}"), // Error
|
||||||
|
|
|
@ -103,6 +103,10 @@ pub enum TokenKind {
|
||||||
DotOp,
|
DotOp,
|
||||||
/// `cross` (vector product)
|
/// `cross` (vector product)
|
||||||
CrossOp,
|
CrossOp,
|
||||||
|
/// `ref` (special unary)
|
||||||
|
RefOp,
|
||||||
|
/// `ref!` (special unary)
|
||||||
|
RefMutOp,
|
||||||
/// =
|
/// =
|
||||||
Equal,
|
Equal,
|
||||||
/// :=
|
/// :=
|
||||||
|
@ -210,7 +214,7 @@ impl TokenKind {
|
||||||
Symbol => TokenCategory::Symbol,
|
Symbol => TokenCategory::Symbol,
|
||||||
NatLit | IntLit | RatioLit | StrLit | BoolLit | NoneLit | EllipsisLit | NoImplLit
|
NatLit | IntLit | RatioLit | StrLit | BoolLit | NoneLit | EllipsisLit | NoImplLit
|
||||||
| InfLit => TokenCategory::Literal,
|
| InfLit => TokenCategory::Literal,
|
||||||
PrePlus | PreMinus | PreBitNot | Mutate => TokenCategory::UnaryOp,
|
PrePlus | PreMinus | PreBitNot | Mutate | RefOp | RefMutOp => TokenCategory::UnaryOp,
|
||||||
Try => TokenCategory::PostfixOp,
|
Try => TokenCategory::PostfixOp,
|
||||||
Comma | Colon | DblColon | SupertypeOf | SubtypeOf | Dot | Pipe | Walrus => {
|
Comma | Colon | DblColon | SupertypeOf | SubtypeOf | Dot | Pipe | Walrus => {
|
||||||
TokenCategory::SpecialBinOp
|
TokenCategory::SpecialBinOp
|
||||||
|
@ -236,7 +240,7 @@ impl TokenKind {
|
||||||
let prec = match self {
|
let prec = match self {
|
||||||
Dot | DblColon => 200, // .
|
Dot | DblColon => 200, // .
|
||||||
Pow => 190, // **
|
Pow => 190, // **
|
||||||
PrePlus | PreMinus | PreBitNot => 180, // (unary) + - * ~
|
PrePlus | PreMinus | PreBitNot | RefOp | RefMutOp => 180, // (unary) + - * ~ ref ref!
|
||||||
Star | Slash | FloorDiv | Mod | CrossOp | DotOp => 170, // * / // % cross dot
|
Star | Slash | FloorDiv | Mod | CrossOp | DotOp => 170, // * / // % cross dot
|
||||||
Plus | Minus => 160, // + -
|
Plus | Minus => 160, // + -
|
||||||
Shl | Shr => 150, // << >>
|
Shl | Shr => 150, // << >>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue