mirror of
https://github.com/erg-lang/erg.git
synced 2025-10-02 21:44:34 +00:00
Impl Dict
parsing
This commit is contained in:
parent
7d659da6a5
commit
ec196d0695
3 changed files with 174 additions and 49 deletions
|
@ -590,16 +590,40 @@ impl Tuple {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub struct KeyValue {
|
||||||
|
pub key: Box<Expr>,
|
||||||
|
pub value: Box<Expr>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NestedDisplay for KeyValue {
|
||||||
|
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result {
|
||||||
|
write!(f, "{}: {}", self.key, self.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_display_from_nested!(KeyValue);
|
||||||
|
impl_locational!(KeyValue, key, value);
|
||||||
|
|
||||||
|
impl KeyValue {
|
||||||
|
pub fn new(key: Expr, value: Expr) -> Self {
|
||||||
|
Self {
|
||||||
|
key: Box::new(key),
|
||||||
|
value: Box::new(value),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct NormalDict {
|
pub struct NormalDict {
|
||||||
l_brace: Token,
|
pub(crate) l_brace: Token,
|
||||||
r_brace: Token,
|
pub(crate) r_brace: Token,
|
||||||
pub attrs: Args, // TODO: Impl K: V Pair
|
pub kvs: Vec<KeyValue>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NestedDisplay for NormalDict {
|
impl NestedDisplay for NormalDict {
|
||||||
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result {
|
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result {
|
||||||
write!(f, "{{{}}}", self.attrs)
|
write!(f, "{{{}}}", fmt_vec(&self.kvs))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -607,11 +631,11 @@ impl_display_from_nested!(NormalDict);
|
||||||
impl_locational!(NormalDict, l_brace, r_brace);
|
impl_locational!(NormalDict, l_brace, r_brace);
|
||||||
|
|
||||||
impl NormalDict {
|
impl NormalDict {
|
||||||
pub fn new(l_brace: Token, r_brace: Token, attrs: Args) -> Self {
|
pub fn new(l_brace: Token, r_brace: Token, kvs: Vec<KeyValue>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
l_brace,
|
l_brace,
|
||||||
r_brace,
|
r_brace,
|
||||||
attrs,
|
kvs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,11 +12,11 @@ use erg_common::{enum_unwrap, get_hash, log, set};
|
||||||
|
|
||||||
use crate::ast::{
|
use crate::ast::{
|
||||||
Accessor, Args, Array, ArrayComprehension, ArrayWithLength, BinOp, Block, Call, DataPack, Def,
|
Accessor, Args, Array, ArrayComprehension, ArrayWithLength, BinOp, Block, Call, DataPack, Def,
|
||||||
DefBody, DefId, Expr, Identifier, KwArg, Lambda, LambdaSignature, Literal, Methods, Module,
|
DefBody, DefId, Dict, Expr, Identifier, KeyValue, KwArg, Lambda, LambdaSignature, Literal,
|
||||||
NormalArray, NormalRecord, NormalSet, NormalTuple, ParamPattern, ParamSignature, Params,
|
Methods, Module, NormalArray, NormalDict, NormalRecord, NormalSet, NormalTuple, ParamPattern,
|
||||||
PosArg, Record, RecordAttrs, Set as astSet, SetWithLength, ShortenedRecord, Signature,
|
ParamSignature, Params, PosArg, Record, RecordAttrs, Set as astSet, SetWithLength,
|
||||||
SubrSignature, Tuple, TypeAscription, TypeBoundSpecs, TypeSpec, UnaryOp, VarName, VarPattern,
|
ShortenedRecord, Signature, SubrSignature, Tuple, TypeAscription, TypeBoundSpecs, TypeSpec,
|
||||||
VarRecordAttr, VarSignature,
|
UnaryOp, VarName, VarPattern, VarRecordAttr, VarSignature,
|
||||||
};
|
};
|
||||||
use crate::token::{Token, TokenKind};
|
use crate::token::{Token, TokenKind};
|
||||||
|
|
||||||
|
@ -439,9 +439,22 @@ impl Desugarer {
|
||||||
Expr::Set(astSet::WithLength(set))
|
Expr::Set(astSet::WithLength(set))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Expr::Dict(dict) => {
|
Expr::Dict(dict) => match dict {
|
||||||
todo!("{dict}")
|
Dict::Normal(dic) => {
|
||||||
}
|
let new_kvs = dic
|
||||||
|
.kvs
|
||||||
|
.into_iter()
|
||||||
|
.map(|elem| {
|
||||||
|
let key = self.rec_desugar_shortened_record(*elem.key);
|
||||||
|
let value = self.rec_desugar_shortened_record(*elem.value);
|
||||||
|
KeyValue::new(key, value)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
let tup = NormalDict::new(dic.l_brace, dic.r_brace, new_kvs);
|
||||||
|
Expr::Dict(Dict::Normal(tup))
|
||||||
|
}
|
||||||
|
_ => todo!("dict comprehension"),
|
||||||
|
},
|
||||||
Expr::BinOp(binop) => {
|
Expr::BinOp(binop) => {
|
||||||
let mut args = binop.args.into_iter();
|
let mut args = binop.args.into_iter();
|
||||||
let lhs = self.rec_desugar_shortened_record(*args.next().unwrap());
|
let lhs = self.rec_desugar_shortened_record(*args.next().unwrap());
|
||||||
|
|
|
@ -264,7 +264,7 @@ impl Parser {
|
||||||
switch_unreachable!()
|
switch_unreachable!()
|
||||||
}
|
}
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
if let Ok(expr) = self.try_reduce_chunk(true) {
|
if let Ok(expr) = self.try_reduce_chunk(true, false) {
|
||||||
chunks.push(expr);
|
chunks.push(expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -280,7 +280,9 @@ impl Parser {
|
||||||
let mut block = Block::with_capacity(2);
|
let mut block = Block::with_capacity(2);
|
||||||
// single line block
|
// single line block
|
||||||
if !self.cur_is(Newline) {
|
if !self.cur_is(Newline) {
|
||||||
let chunk = self.try_reduce_chunk(true).map_err(|_| self.stack_dec())?;
|
let chunk = self
|
||||||
|
.try_reduce_chunk(true, false)
|
||||||
|
.map_err(|_| self.stack_dec())?;
|
||||||
block.push(chunk);
|
block.push(chunk);
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
return Ok(block);
|
return Ok(block);
|
||||||
|
@ -304,7 +306,7 @@ impl Parser {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
if let Ok(expr) = self.try_reduce_chunk(true) {
|
if let Ok(expr) = self.try_reduce_chunk(true, false) {
|
||||||
block.push(expr);
|
block.push(expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -343,7 +345,7 @@ impl Parser {
|
||||||
if self.cur_is(TokenKind::AtSign) {
|
if self.cur_is(TokenKind::AtSign) {
|
||||||
self.lpop();
|
self.lpop();
|
||||||
let expr = self
|
let expr = self
|
||||||
.try_reduce_expr(false, false)
|
.try_reduce_expr(false, false, false)
|
||||||
.map_err(|_| self.stack_dec())?;
|
.map_err(|_| self.stack_dec())?;
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
Ok(Some(Decorator::new(expr)))
|
Ok(Some(Decorator::new(expr)))
|
||||||
|
@ -472,7 +474,7 @@ impl Parser {
|
||||||
Some(t) if t.is(LSqBr) => {
|
Some(t) if t.is(LSqBr) => {
|
||||||
self.skip();
|
self.skip();
|
||||||
let index = self
|
let index = self
|
||||||
.try_reduce_expr(false, false)
|
.try_reduce_expr(false, false, false)
|
||||||
.map_err(|_| self.stack_dec())?;
|
.map_err(|_| self.stack_dec())?;
|
||||||
if self.cur_is(RSqBr) {
|
if self.cur_is(RSqBr) {
|
||||||
self.skip();
|
self.skip();
|
||||||
|
@ -568,7 +570,7 @@ impl Parser {
|
||||||
Some(semi) if semi.is(Semi) => {
|
Some(semi) if semi.is(Semi) => {
|
||||||
self.lpop();
|
self.lpop();
|
||||||
let len = self
|
let len = self
|
||||||
.try_reduce_expr(false, false)
|
.try_reduce_expr(false, false, false)
|
||||||
.map_err(|_| self.stack_dec())?;
|
.map_err(|_| self.stack_dec())?;
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
return Ok(ArrayInner::WithLength(elems.remove_pos(0), len));
|
return Ok(ArrayInner::WithLength(elems.remove_pos(0), len));
|
||||||
|
@ -625,7 +627,7 @@ impl Parser {
|
||||||
match self.peek() {
|
match self.peek() {
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
let expr = self
|
let expr = self
|
||||||
.try_reduce_expr(false, false)
|
.try_reduce_expr(false, false, false)
|
||||||
.map_err(|_| self.stack_dec())?;
|
.map_err(|_| self.stack_dec())?;
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
Ok(PosArg::new(expr))
|
Ok(PosArg::new(expr))
|
||||||
|
@ -814,13 +816,13 @@ impl Parser {
|
||||||
return Err(());
|
return Err(());
|
||||||
};
|
};
|
||||||
let expr = self
|
let expr = self
|
||||||
.try_reduce_expr(false, in_type_args)
|
.try_reduce_expr(false, in_type_args, false)
|
||||||
.map_err(|_| self.stack_dec())?;
|
.map_err(|_| self.stack_dec())?;
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
Ok(PosOrKwArg::Kw(KwArg::new(kw, None, expr)))
|
Ok(PosOrKwArg::Kw(KwArg::new(kw, None, expr)))
|
||||||
} else {
|
} else {
|
||||||
let expr = self
|
let expr = self
|
||||||
.try_reduce_expr(false, in_type_args)
|
.try_reduce_expr(false, in_type_args, false)
|
||||||
.map_err(|_| self.stack_dec())?;
|
.map_err(|_| self.stack_dec())?;
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
Ok(PosOrKwArg::Pos(PosArg::new(expr)))
|
Ok(PosOrKwArg::Pos(PosArg::new(expr)))
|
||||||
|
@ -828,7 +830,7 @@ impl Parser {
|
||||||
}
|
}
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
let expr = self
|
let expr = self
|
||||||
.try_reduce_expr(false, in_type_args)
|
.try_reduce_expr(false, in_type_args, false)
|
||||||
.map_err(|_| self.stack_dec())?;
|
.map_err(|_| self.stack_dec())?;
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
Ok(PosOrKwArg::Pos(PosArg::new(expr)))
|
Ok(PosOrKwArg::Pos(PosArg::new(expr)))
|
||||||
|
@ -867,7 +869,7 @@ impl Parser {
|
||||||
None
|
None
|
||||||
};*/
|
};*/
|
||||||
let expr = self
|
let expr = self
|
||||||
.try_reduce_expr(false, in_type_args)
|
.try_reduce_expr(false, in_type_args, false)
|
||||||
.map_err(|_| self.stack_dec())?;
|
.map_err(|_| self.stack_dec())?;
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
Ok(KwArg::new(keyword, None, expr))
|
Ok(KwArg::new(keyword, None, expr))
|
||||||
|
@ -901,7 +903,9 @@ impl Parser {
|
||||||
while self.cur_is(Newline) {
|
while self.cur_is(Newline) {
|
||||||
self.skip();
|
self.skip();
|
||||||
}
|
}
|
||||||
let first = self.try_reduce_chunk(false).map_err(|_| self.stack_dec())?;
|
let first = self
|
||||||
|
.try_reduce_chunk(false, false)
|
||||||
|
.map_err(|_| self.stack_dec())?;
|
||||||
let first = if let Some(fst) = option_enum_unwrap!(first, Expr::Def) {
|
let first = if let Some(fst) = option_enum_unwrap!(first, Expr::Def) {
|
||||||
fst
|
fst
|
||||||
} else {
|
} else {
|
||||||
|
@ -924,7 +928,9 @@ impl Parser {
|
||||||
self.skip();
|
self.skip();
|
||||||
}
|
}
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
let def = self.try_reduce_chunk(false).map_err(|_| self.stack_dec())?;
|
let def = self
|
||||||
|
.try_reduce_chunk(false, false)
|
||||||
|
.map_err(|_| self.stack_dec())?;
|
||||||
match def {
|
match def {
|
||||||
Expr::Def(def) => {
|
Expr::Def(def) => {
|
||||||
defs.push(def);
|
defs.push(def);
|
||||||
|
@ -968,7 +974,7 @@ impl Parser {
|
||||||
Ok(Lambda::new(sig, op, body, self.counter))
|
Ok(Lambda::new(sig, op, body, self.counter))
|
||||||
} else {
|
} else {
|
||||||
let expr = self
|
let expr = self
|
||||||
.try_reduce_expr(true, false)
|
.try_reduce_expr(true, false, false)
|
||||||
.map_err(|_| self.stack_dec())?;
|
.map_err(|_| self.stack_dec())?;
|
||||||
let block = Block::new(vec![expr]);
|
let block = Block::new(vec![expr]);
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
|
@ -977,11 +983,11 @@ impl Parser {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// chunk = normal expr + def
|
/// chunk = normal expr + def
|
||||||
fn try_reduce_chunk(&mut self, winding: bool) -> ParseResult<Expr> {
|
fn try_reduce_chunk(&mut self, winding: bool, in_brace: bool) -> ParseResult<Expr> {
|
||||||
debug_call_info!(self);
|
debug_call_info!(self);
|
||||||
let mut stack = Vec::<ExprOrOp>::new();
|
let mut stack = Vec::<ExprOrOp>::new();
|
||||||
stack.push(ExprOrOp::Expr(
|
stack.push(ExprOrOp::Expr(
|
||||||
self.try_reduce_bin_lhs(false)
|
self.try_reduce_bin_lhs(false, in_brace)
|
||||||
.map_err(|_| self.stack_dec())?,
|
.map_err(|_| self.stack_dec())?,
|
||||||
));
|
));
|
||||||
loop {
|
loop {
|
||||||
|
@ -1016,14 +1022,19 @@ impl Parser {
|
||||||
self.counter,
|
self.counter,
|
||||||
))));
|
))));
|
||||||
}
|
}
|
||||||
|
// type ascription
|
||||||
Some(op)
|
Some(op)
|
||||||
if (op.is(Colon) && !self.nth_is(1, Newline))
|
if (op.is(Colon) && !self.nth_is(1, Newline))
|
||||||
|| (op.is(SubtypeOf) || op.is(SupertypeOf)) =>
|
|| (op.is(SubtypeOf) || op.is(SupertypeOf)) =>
|
||||||
{
|
{
|
||||||
|
// "a": 1 (key-value pair)
|
||||||
|
if in_brace {
|
||||||
|
break;
|
||||||
|
}
|
||||||
let op = self.lpop();
|
let op = self.lpop();
|
||||||
let lhs = enum_unwrap!(stack.pop(), Some:(ExprOrOp::Expr:(_)));
|
let lhs = enum_unwrap!(stack.pop(), Some:(ExprOrOp::Expr:(_)));
|
||||||
let t_spec = self
|
let t_spec = self
|
||||||
.try_reduce_expr(false, false)
|
.try_reduce_expr(false, false, false)
|
||||||
.map_err(|_| self.stack_dec())?;
|
.map_err(|_| self.stack_dec())?;
|
||||||
let t_spec = self
|
let t_spec = self
|
||||||
.convert_rhs_to_type_spec(t_spec)
|
.convert_rhs_to_type_spec(t_spec)
|
||||||
|
@ -1053,7 +1064,7 @@ impl Parser {
|
||||||
}
|
}
|
||||||
stack.push(ExprOrOp::Op(self.lpop()));
|
stack.push(ExprOrOp::Op(self.lpop()));
|
||||||
stack.push(ExprOrOp::Expr(
|
stack.push(ExprOrOp::Expr(
|
||||||
self.try_reduce_bin_lhs(false)
|
self.try_reduce_bin_lhs(false, in_brace)
|
||||||
.map_err(|_| self.stack_dec())?,
|
.map_err(|_| self.stack_dec())?,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -1225,11 +1236,17 @@ impl Parser {
|
||||||
|
|
||||||
/// chunk = expr + def
|
/// chunk = expr + def
|
||||||
/// winding: true => parse paren-less tuple
|
/// winding: true => parse paren-less tuple
|
||||||
fn try_reduce_expr(&mut self, winding: bool, in_type_args: bool) -> ParseResult<Expr> {
|
/// in_brace: true => (1: 1) will not be a syntax error (key-value pair)
|
||||||
|
fn try_reduce_expr(
|
||||||
|
&mut self,
|
||||||
|
winding: bool,
|
||||||
|
in_type_args: bool,
|
||||||
|
in_brace: bool,
|
||||||
|
) -> ParseResult<Expr> {
|
||||||
debug_call_info!(self);
|
debug_call_info!(self);
|
||||||
let mut stack = Vec::<ExprOrOp>::new();
|
let mut stack = Vec::<ExprOrOp>::new();
|
||||||
stack.push(ExprOrOp::Expr(
|
stack.push(ExprOrOp::Expr(
|
||||||
self.try_reduce_bin_lhs(in_type_args)
|
self.try_reduce_bin_lhs(in_type_args, in_brace)
|
||||||
.map_err(|_| self.stack_dec())?,
|
.map_err(|_| self.stack_dec())?,
|
||||||
));
|
));
|
||||||
loop {
|
loop {
|
||||||
|
@ -1249,14 +1266,19 @@ impl Parser {
|
||||||
self.counter,
|
self.counter,
|
||||||
))));
|
))));
|
||||||
}
|
}
|
||||||
|
// type ascription
|
||||||
Some(op)
|
Some(op)
|
||||||
if (op.is(Colon) && !self.nth_is(1, Newline))
|
if (op.is(Colon) && !self.nth_is(1, Newline))
|
||||||
|| (op.is(SubtypeOf) || op.is(SupertypeOf)) =>
|
|| (op.is(SubtypeOf) || op.is(SupertypeOf)) =>
|
||||||
{
|
{
|
||||||
|
// "a": 1 (key-value pair)
|
||||||
|
if in_brace {
|
||||||
|
break;
|
||||||
|
}
|
||||||
let op = self.lpop();
|
let op = self.lpop();
|
||||||
let lhs = enum_unwrap!(stack.pop(), Some:(ExprOrOp::Expr:(_)));
|
let lhs = enum_unwrap!(stack.pop(), Some:(ExprOrOp::Expr:(_)));
|
||||||
let t_spec = self
|
let t_spec = self
|
||||||
.try_reduce_expr(false, in_type_args)
|
.try_reduce_expr(false, in_type_args, in_brace)
|
||||||
.map_err(|_| self.stack_dec())?;
|
.map_err(|_| self.stack_dec())?;
|
||||||
let t_spec = self
|
let t_spec = self
|
||||||
.convert_rhs_to_type_spec(t_spec)
|
.convert_rhs_to_type_spec(t_spec)
|
||||||
|
@ -1286,7 +1308,7 @@ impl Parser {
|
||||||
}
|
}
|
||||||
stack.push(ExprOrOp::Op(self.lpop()));
|
stack.push(ExprOrOp::Op(self.lpop()));
|
||||||
stack.push(ExprOrOp::Expr(
|
stack.push(ExprOrOp::Expr(
|
||||||
self.try_reduce_bin_lhs(in_type_args)
|
self.try_reduce_bin_lhs(in_type_args, in_brace)
|
||||||
.map_err(|_| self.stack_dec())?,
|
.map_err(|_| self.stack_dec())?,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -1383,7 +1405,7 @@ impl Parser {
|
||||||
|
|
||||||
/// "LHS" is the smallest unit that can be the left-hand side of an BinOp.
|
/// "LHS" is the smallest unit that can be the left-hand side of an BinOp.
|
||||||
/// e.g. Call, Name, UnaryOp, Lambda
|
/// e.g. Call, Name, UnaryOp, Lambda
|
||||||
fn try_reduce_bin_lhs(&mut self, in_type_args: bool) -> ParseResult<Expr> {
|
fn try_reduce_bin_lhs(&mut self, in_type_args: bool, in_brace: bool) -> ParseResult<Expr> {
|
||||||
debug_call_info!(self);
|
debug_call_info!(self);
|
||||||
match self.peek() {
|
match self.peek() {
|
||||||
Some(t) if t.category_is(TC::Literal) => {
|
Some(t) if t.category_is(TC::Literal) => {
|
||||||
|
@ -1394,7 +1416,7 @@ impl Parser {
|
||||||
}
|
}
|
||||||
Some(t) if t.is(AtSign) => {
|
Some(t) if t.is(AtSign) => {
|
||||||
let decos = self.opt_reduce_decorators()?;
|
let decos = self.opt_reduce_decorators()?;
|
||||||
let expr = self.try_reduce_chunk(false)?;
|
let expr = self.try_reduce_chunk(false, in_brace)?;
|
||||||
let mut def = if let Some(def) = option_enum_unwrap!(expr, Expr::Def) {
|
let mut def = if let Some(def) = option_enum_unwrap!(expr, Expr::Def) {
|
||||||
def
|
def
|
||||||
} else {
|
} else {
|
||||||
|
@ -1447,7 +1469,7 @@ impl Parser {
|
||||||
return Ok(Expr::Tuple(unit));
|
return Ok(Expr::Tuple(unit));
|
||||||
}
|
}
|
||||||
let mut expr = self
|
let mut expr = self
|
||||||
.try_reduce_expr(true, false)
|
.try_reduce_expr(true, false, false)
|
||||||
.map_err(|_| self.stack_dec())?;
|
.map_err(|_| self.stack_dec())?;
|
||||||
let rparen = self.lpop();
|
let rparen = self.lpop();
|
||||||
if let Expr::Tuple(Tuple::Normal(tup)) = &mut expr {
|
if let Expr::Tuple(Tuple::Normal(tup)) = &mut expr {
|
||||||
|
@ -1533,7 +1555,7 @@ impl Parser {
|
||||||
debug_call_info!(self);
|
debug_call_info!(self);
|
||||||
let op = self.lpop();
|
let op = self.lpop();
|
||||||
let expr = self
|
let expr = self
|
||||||
.try_reduce_expr(false, false)
|
.try_reduce_expr(false, false, false)
|
||||||
.map_err(|_| self.stack_dec())?;
|
.map_err(|_| self.stack_dec())?;
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
Ok(UnaryOp::new(op, expr))
|
Ok(UnaryOp::new(op, expr))
|
||||||
|
@ -1620,6 +1642,9 @@ impl Parser {
|
||||||
return Ok(BraceContainer::Record(Record::Normal(rec)));
|
return Ok(BraceContainer::Record(Record::Normal(rec)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.level -= 1;
|
||||||
|
let err = self.skip_and_throw_syntax_err(caused_by!());
|
||||||
|
self.errs.push(err);
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
if first.is(Colon) {
|
if first.is(Colon) {
|
||||||
|
@ -1627,16 +1652,20 @@ impl Parser {
|
||||||
if let Some(t) = self.peek() {
|
if let Some(t) = self.peek() {
|
||||||
if t.is(RBrace) {
|
if t.is(RBrace) {
|
||||||
let r_brace = self.lpop();
|
let r_brace = self.lpop();
|
||||||
let arg = Args::empty();
|
let dict = NormalDict::new(l_brace, r_brace, vec![]);
|
||||||
let dict = NormalDict::new(l_brace, r_brace, arg);
|
|
||||||
return Ok(BraceContainer::Dict(Dict::Normal(dict)));
|
return Ok(BraceContainer::Dict(Dict::Normal(dict)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.level -= 1;
|
||||||
|
let err = self.skip_and_throw_syntax_err(caused_by!());
|
||||||
|
self.errs.push(err);
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let first = self.try_reduce_chunk(false).map_err(|_| self.stack_dec())?;
|
let first = self
|
||||||
|
.try_reduce_chunk(false, true)
|
||||||
|
.map_err(|_| self.stack_dec())?;
|
||||||
match first {
|
match first {
|
||||||
Expr::Def(def) => {
|
Expr::Def(def) => {
|
||||||
let record = self
|
let record = self
|
||||||
|
@ -1645,8 +1674,6 @@ impl Parser {
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
Ok(BraceContainer::Record(Record::Normal(record)))
|
Ok(BraceContainer::Record(Record::Normal(record)))
|
||||||
}
|
}
|
||||||
// Dict
|
|
||||||
Expr::TypeAsc(_) => todo!(),
|
|
||||||
// TODO: {X; Y} will conflict with Set
|
// TODO: {X; Y} will conflict with Set
|
||||||
Expr::Accessor(acc)
|
Expr::Accessor(acc)
|
||||||
if self.cur_is(Semi)
|
if self.cur_is(Semi)
|
||||||
|
@ -1659,6 +1686,14 @@ impl Parser {
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
Ok(BraceContainer::Record(Record::Shortened(record)))
|
Ok(BraceContainer::Record(Record::Shortened(record)))
|
||||||
}
|
}
|
||||||
|
// Dict
|
||||||
|
other if self.cur_is(Colon) => {
|
||||||
|
let dict = self
|
||||||
|
.try_reduce_normal_dict(l_brace, other)
|
||||||
|
.map_err(|_| self.stack_dec())?;
|
||||||
|
self.level -= 1;
|
||||||
|
Ok(BraceContainer::Dict(Dict::Normal(dict)))
|
||||||
|
}
|
||||||
other => {
|
other => {
|
||||||
let set = self
|
let set = self
|
||||||
.try_reduce_set(l_brace, other)
|
.try_reduce_set(l_brace, other)
|
||||||
|
@ -1704,7 +1739,9 @@ impl Parser {
|
||||||
return Ok(NormalRecord::new(l_brace, r_brace, attrs));
|
return Ok(NormalRecord::new(l_brace, r_brace, attrs));
|
||||||
}
|
}
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
let def = self.try_reduce_chunk(false).map_err(|_| self.stack_dec())?;
|
let def = self
|
||||||
|
.try_reduce_chunk(false, false)
|
||||||
|
.map_err(|_| self.stack_dec())?;
|
||||||
let def = if let Some(def) = option_enum_unwrap!(def, Expr::Def) {
|
let def = if let Some(def) = option_enum_unwrap!(def, Expr::Def) {
|
||||||
def
|
def
|
||||||
} else {
|
} else {
|
||||||
|
@ -1791,8 +1828,59 @@ impl Parser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn _try_reduce_dict() -> ParseResult<Dict> {
|
fn try_reduce_normal_dict(
|
||||||
todo!()
|
&mut self,
|
||||||
|
l_brace: Token,
|
||||||
|
first_key: Expr,
|
||||||
|
) -> ParseResult<NormalDict> {
|
||||||
|
debug_call_info!(self);
|
||||||
|
assert!(self.cur_is(Colon));
|
||||||
|
self.skip();
|
||||||
|
let value = self
|
||||||
|
.try_reduce_chunk(false, false)
|
||||||
|
.map_err(|_| self.stack_dec())?;
|
||||||
|
let mut kvs = vec![KeyValue::new(first_key, value)];
|
||||||
|
loop {
|
||||||
|
match self.peek() {
|
||||||
|
Some(t) if t.is(Comma) => {
|
||||||
|
self.skip();
|
||||||
|
if self.cur_is(Comma) {
|
||||||
|
self.level -= 1;
|
||||||
|
let err = self.skip_and_throw_syntax_err(caused_by!());
|
||||||
|
self.errs.push(err);
|
||||||
|
return Err(());
|
||||||
|
} else if self.cur_is(RBrace) {
|
||||||
|
let dict = NormalDict::new(l_brace, self.lpop(), kvs);
|
||||||
|
self.level -= 1;
|
||||||
|
return Ok(dict);
|
||||||
|
}
|
||||||
|
let key = self
|
||||||
|
.try_reduce_expr(false, false, true)
|
||||||
|
.map_err(|_| self.stack_dec())?;
|
||||||
|
if self.cur_is(Colon) {
|
||||||
|
self.skip();
|
||||||
|
let value = self
|
||||||
|
.try_reduce_chunk(false, false)
|
||||||
|
.map_err(|_| self.stack_dec())?;
|
||||||
|
kvs.push(KeyValue::new(key, value));
|
||||||
|
} else {
|
||||||
|
self.level -= 1;
|
||||||
|
let err = self.skip_and_throw_syntax_err(caused_by!());
|
||||||
|
self.errs.push(err);
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(t) if t.is(RBrace) => {
|
||||||
|
let dict = NormalDict::new(l_brace, self.lpop(), kvs);
|
||||||
|
self.level -= 1;
|
||||||
|
return Ok(dict);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_reduce_set(&mut self, l_brace: Token, first_elem: Expr) -> ParseResult<Set> {
|
fn try_reduce_set(&mut self, l_brace: Token, first_elem: Expr) -> ParseResult<Set> {
|
||||||
|
@ -1800,7 +1888,7 @@ impl Parser {
|
||||||
if self.cur_is(Semi) {
|
if self.cur_is(Semi) {
|
||||||
self.skip();
|
self.skip();
|
||||||
let len = self
|
let len = self
|
||||||
.try_reduce_expr(false, false)
|
.try_reduce_expr(false, false, false)
|
||||||
.map_err(|_| self.stack_dec())?;
|
.map_err(|_| self.stack_dec())?;
|
||||||
let r_brace = self.lpop();
|
let r_brace = self.lpop();
|
||||||
return Ok(Set::WithLength(SetWithLength::new(
|
return Ok(Set::WithLength(SetWithLength::new(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue