Update Parser

This commit is contained in:
Shunsuke Shibayama 2022-09-14 11:17:19 +09:00
parent aa2aa79de9
commit 424f82cf9e
4 changed files with 151 additions and 60 deletions

View file

@ -2138,10 +2138,55 @@ impl ParamTuplePattern {
}
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct ParamRecordAttr {
pub lhs: Identifier,
pub rhs: ParamSignature,
}
impl NestedDisplay for ParamRecordAttr {
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result {
write!(f, "{} = {}", self.lhs, self.rhs)
}
}
impl_display_from_nested!(ParamRecordAttr);
impl_locational!(ParamRecordAttr, lhs, rhs);
impl ParamRecordAttr {
pub const fn new(lhs: Identifier, rhs: ParamSignature) -> Self {
Self { lhs, rhs }
}
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct ParamRecordAttrs {
pub(crate) elems: Vec<ParamRecordAttr>,
}
impl NestedDisplay for ParamRecordAttrs {
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result {
write!(f, "{}", fmt_vec_split_with(&self.elems, "; "))
}
}
impl_display_from_nested!(ParamRecordAttrs);
impl_stream!(ParamRecordAttrs, ParamRecordAttr, elems);
impl ParamRecordAttrs {
pub const fn new(elems: Vec<ParamRecordAttr>) -> Self {
Self { elems }
}
pub const fn empty() -> Self {
Self::new(vec![])
}
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct ParamRecordPattern {
l_brace: Token,
pub(crate) elems: Params,
pub(crate) elems: ParamRecordAttrs,
r_brace: Token,
}
@ -2155,7 +2200,7 @@ impl_display_from_nested!(ParamRecordPattern);
impl_locational!(ParamRecordPattern, l_brace, r_brace);
impl ParamRecordPattern {
pub const fn new(l_brace: Token, elems: Params, r_brace: Token) -> Self {
pub const fn new(l_brace: Token, elems: ParamRecordAttrs, r_brace: Token) -> Self {
Self {
l_brace,
elems,

View file

@ -309,18 +309,21 @@ impl Parser {
self.level -= 1;
return Ok(block);
}
assert!(self.cur_is(Newline));
self.skip();
assert!(self.cur_is(Indent));
self.skip();
loop {
match self.peek() {
Some(t) if t.is(Newline) && self.nth_is(1, Dedent) => {
let nl = self.lpop();
self.skip();
self.restore(nl);
break;
}
Some(t) if t.category_is(TC::Separator) => {
self.skip();
}
Some(t) if t.is(Indent) => {
self.skip();
}
Some(t) if t.is(Dedent) => {
self.skip();
break;
}
Some(t) if t.is(EOF) => {
break;
}
@ -391,7 +394,7 @@ impl Parser {
fn try_reduce_acc(&mut self) -> ParseResult<Accessor> {
debug_call_info!(self);
let mut acc = match self.peek() {
Some(t) if t.is(Symbol) => Accessor::local(self.lpop()),
Some(t) if t.is(Symbol) || t.is(UBar) => Accessor::local(self.lpop()),
Some(t) if t.is(Dot) => {
let dot = self.lpop();
let maybe_symbol = self.lpop();
@ -609,7 +612,8 @@ impl Parser {
|| t.category_is(TC::UnaryOp)
|| t.is(LParen)
|| t.is(LSqBr)
|| t.is(LBrace) =>
|| t.is(LBrace)
|| t.is(UBar) =>
{
Some(self.try_reduce_args())
}
@ -670,18 +674,6 @@ impl Parser {
}
debug_power_assert!(self.cur_is(Indent));
self.skip();
if !args.kw_is_empty() {
args.push_kw(self.try_reduce_kw_arg().map_err(|_| self.stack_dec())?);
} else {
match self.try_reduce_arg().map_err(|_| self.stack_dec())? {
PosOrKwArg::Pos(arg) => {
args.push_pos(arg);
}
PosOrKwArg::Kw(arg) => {
args.push_kw(arg);
}
}
}
}
Some(t) if t.is(Comma) => {
self.skip();
@ -704,14 +696,24 @@ impl Parser {
}
}
}
Some(t) if t.is(Newline) && colon_style => {
while self.cur_is(Newline) {
self.skip();
}
if self.cur_is(Dedent) {
self.skip();
Some(t) if t.is(RParen) => {
rp = Some(self.lpop());
let (pos_args, kw_args, _) = args.deconstruct();
args = Args::new(pos_args, kw_args, Some((lp.unwrap(), rp.unwrap())));
break;
}
Some(t) if t.is(Newline) => {
if !colon_style {
break;
}
let last = self.lpop();
if self.cur_is(Dedent) {
self.skip();
self.restore(last);
break;
}
}
Some(_) if colon_style => {
if !args.kw_is_empty() {
args.push_kw(self.try_reduce_kw_arg().map_err(|_| self.stack_dec())?);
} else {
@ -725,12 +727,6 @@ impl Parser {
}
}
}
Some(t) if t.is(RParen) => {
rp = Some(self.lpop());
let (pos_args, kw_args, _) = args.deconstruct();
args = Args::new(pos_args, kw_args, Some((lp.unwrap(), rp.unwrap())));
break;
}
_ => {
break;
}
@ -853,13 +849,15 @@ impl Parser {
let mut defs = vec![first];
loop {
match self.peek() {
Some(t) if t.is(Newline) && self.nth_is(1, Dedent) => {
let nl = self.lpop();
self.skip();
self.restore(nl);
break;
}
Some(t) if t.category_is(TC::Separator) => {
self.skip();
}
Some(t) if t.is(Dedent) => {
self.skip();
break;
}
Some(_) => {
let def = self.try_reduce_chunk(false).map_err(|_| self.stack_dec())?;
match def {
@ -906,6 +904,7 @@ impl Parser {
}
}
/// chunk = normal expr + def
fn try_reduce_chunk(&mut self, winding: bool) -> ParseResult<Expr> {
debug_call_info!(self);
let mut stack = Vec::<ExprOrOp>::new();
@ -1140,6 +1139,7 @@ impl Parser {
}
}
/// chunk = expr + def
/// winding: true => parse paren-less tuple
fn try_reduce_expr(&mut self, winding: bool) -> ParseResult<Expr> {
debug_call_info!(self);
@ -1326,7 +1326,7 @@ impl Parser {
}
}
}
Some(t) if t.is(Symbol) || t.is(Dot) => {
Some(t) if t.is(Symbol) || t.is(Dot) || t.is(UBar) => {
let call_or_acc = self
.try_reduce_call_or_acc()
.map_err(|_| self.stack_dec())?;
@ -1721,7 +1721,11 @@ impl Parser {
debug_call_info!(self);
match accessor {
Accessor::Ident(ident) => {
let pat = VarPattern::Ident(ident);
let pat = if &ident.inspect()[..] == "_" {
VarPattern::Discard(ident.name.into_token())
} else {
VarPattern::Ident(ident)
};
self.level -= 1;
Ok(VarSignature::new(pat, None))
}
@ -2055,10 +2059,41 @@ impl Parser {
fn convert_record_to_param_record_pat(
&mut self,
_record: Record,
record: Record,
) -> ParseResult<ParamRecordPattern> {
debug_call_info!(self);
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_param_sig(rhs)
.map_err(|_| self.stack_dec())?;
pats.push(ParamRecordAttr::new(lhs, rhs));
}
let attrs = ParamRecordAttrs::new(pats);
self.level -= 1;
Ok(ParamRecordPattern::new(rec.l_brace, attrs, rec.r_brace))
}
Record::Shortened(rec) => {
let mut pats = vec![];
for ident in rec.idents.into_iter() {
let rhs =
ParamSignature::new(ParamPattern::VarName(ident.name.clone()), None, None);
pats.push(ParamRecordAttr::new(ident.clone(), rhs));
}
let attrs = ParamRecordAttrs::new(pats);
self.level -= 1;
Ok(ParamRecordPattern::new(rec.l_brace, attrs, rec.r_brace))
}
}
}
fn convert_tuple_to_param_tuple_pat(&mut self, tuple: Tuple) -> ParseResult<ParamTuplePattern> {
@ -2147,7 +2182,11 @@ impl Parser {
debug_call_info!(self);
match accessor {
Accessor::Ident(ident) => {
let pat = ParamPattern::VarName(ident.name);
let pat = if &ident.name.inspect()[..] == "_" {
ParamPattern::Discard(ident.name.into_token())
} else {
ParamPattern::VarName(ident.name)
};
self.level -= 1;
Ok(ParamSignature::new(pat, None, None))
}
@ -2186,10 +2225,18 @@ impl Parser {
fn convert_type_asc_to_lambda_sig(
&mut self,
_tasc: TypeAscription,
tasc: TypeAscription,
) -> ParseResult<LambdaSignature> {
debug_call_info!(self);
todo!()
let sig = self
.convert_rhs_to_param(*tasc.expr, true)
.map_err(|_| self.stack_dec())?;
self.level -= 1;
Ok(LambdaSignature::new(
Params::new(vec![sig], None, vec![], None),
None,
TypeBoundSpecs::empty(),
))
}
fn convert_rhs_to_type_spec(&mut self, rhs: Expr) -> ParseResult<TypeSpec> {

View file

@ -15,10 +15,10 @@ sum = match a:
[x, y, z] -> x + y + z
(x, y, z) -> x + y + z
{x; y; z} -> x + y + z
i: Int -> i
(i: Int) -> i
_ -> panic "unknown object"
for! 0.., i =>
for! 0..1000, i =>
print! "i = {i}"
if i >= 100:
do return break()

View file

@ -1,26 +1,25 @@
LitExpr = Class {.i = Int}, Impl := Show
LitExpr.
new i = Self::__new__ {.i;}
show &self = "{self.i}"
show self = "{self.i}"
AddExpr = Class {.lhs = Expr, .rhs = Expr}, Impl := Show
AddExpr.
new lhs, rhs = Self::__new__ {.lhs; .rhs}
show &self = "{self.lhs} + {self.rhs}"
show self = "{self.lhs} + {self.rhs}"
SubExpr = Class {.lhs = Expr, .rhs = Expr}, Impl := Show
SubExpr.
new lhs, rhs = Self::__new__ {.lhs; .rhs}
show &self = "{self.lhs} - {self.rhs}"
show self = "{self.lhs} - {self.rhs}"
PosExpr = Class {.expr = Expr}, Impl := Show
PosExpr.
new expr = Self::__new__ {.expr;}
show &self = "+{self.expr}"
show self = "+{self.expr}"
NegExpr = Class {.expr = Expr}, Impl := Show
NegExpr.
new expr = Self::__new__ {.expr;}
show &self = "-{self.expr}"
show self = "-{self.expr}"
Expr = Enum:
LitExpr
Expr = Enum LitExpr:
AddExpr
SubExpr
NegExpr
@ -29,11 +28,11 @@ Expr.
add = Self.cons(AddExpr)
eval self =
match self:
l: Expr.LitExpr -> l.i
a: Expr.AddExpr -> a.lhs + a.rhs
s: Expr.SubExpr -> s.lhs - s.rhs
p: Expr.PosExpr -> p.expr
n: Expr.NegExpr -> -n.expr
(l: Expr.LitExpr) -> l.i
(a: Expr.AddExpr) -> a.lhs + a.rhs
(s: Expr.SubExpr) -> s.lhs - s.rhs
(p: Expr.PosExpr) -> p.expr
(n: Expr.NegExpr) -> -n.expr
expr = Expr.add Expr.lit(1), Expr.lit(2)
print! expr # 1 + 2