Skip to content

Commit

Permalink
Merge pull request #181 from Glyphack/fix-slice
Browse files Browse the repository at this point in the history
  • Loading branch information
Glyphack authored Oct 7, 2023
2 parents 57d7432 + 5a02075 commit 4270ed7
Show file tree
Hide file tree
Showing 22 changed files with 12,797 additions and 10,827 deletions.
6 changes: 4 additions & 2 deletions parser/src/lexer/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -859,9 +859,11 @@ impl Lexer {
}
}
if de_indents != 1 {
self.next_token_is_dedent += 1;
// minus 1 because the dedent with actual Indent value is already added
// This is super hacky and I don't like it
self.next_token_is_dedent += de_indents - 1;
}
TokenValue::Indent(de_indents)
TokenValue::Indent(de_indents.into())
}
Kind::Indent => TokenValue::Indent(1),
_ => TokenValue::None,
Expand Down
93 changes: 50 additions & 43 deletions parser/src/parser/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -472,8 +472,6 @@ impl Parser {
vec![]
};

self.bump(Kind::Dedent);

Ok(Statement::WhileStatement(While {
node: self.finish_node(node),
test,
Expand Down Expand Up @@ -510,8 +508,6 @@ impl Parser {
vec![]
};

self.bump(Kind::Dedent);

if is_async {
Ok(Statement::AsyncForStatement(AsyncFor {
node: self.finish_node(node),
Expand Down Expand Up @@ -539,8 +535,6 @@ impl Parser {
self.expect(Kind::Colon)?;
let body = self.parse_suite()?;

self.bump(Kind::Dedent);

if is_async {
Ok(Statement::AsyncWithStatement(AsyncWith {
node: self.finish_node(node),
Expand Down Expand Up @@ -1915,14 +1909,21 @@ impl Parser {
values: vec![],
})));
}
if self.at(Kind::Pow) {
// key must be None
let (key, value) = self.parse_double_starred_kv_pair()?;
return self.parse_dict(node, key, value)
}
let first_key_or_element = self.parse_star_named_expression()?;
if matches!(
self.cur_kind(),
Kind::Comma | Kind::RightBracket | Kind::Async | Kind::For | Kind::Walrus
) {
self.parse_set(node, first_key_or_element)
} else {
self.parse_dict(node, first_key_or_element)
self.expect(Kind::Colon)?;
let first_value = self.parse_expression_2()?;
self.parse_dict(node, Some(first_key_or_element), first_value)
}
}

Expand Down Expand Up @@ -1957,17 +1958,30 @@ impl Parser {
fn parse_dict(
&mut self,
node: Node,
first_key: Expression,
first_key: Option<Expression>,
first_value: Expression,
) -> Result<Expression, ParsingError> {
self.expect(Kind::Colon)?;
let first_val = self.parse_expression_2()?;
if self.at(Kind::For) || self.at(Kind::Async) && matches!(self.peek_kind(), Ok(Kind::For)) {
let key = if first_key.is_none() {
let err = ParsingError::InvalidSyntax {
path: Box::from(self.path.as_str()),
msg: Box::from("cannot use ** in dict comprehension"),
line: self.get_line_number_of_character_position(self.cur_token.end),
input: self.curr_line_string.clone(),
advice: "".into(),
span: (node.start, node.end),
};
return Err(err);
} else {
first_key.unwrap()
};
// make sure the first key is some
let generators = self.parse_comp_for()?;
self.expect(Kind::RightBracket)?;
Ok(Expression::DictComp(Box::new(DictComp {
node: self.finish_node(node),
key: Box::new(first_key),
value: Box::new(first_val),
key: Box::new(key),
value: Box::new(first_value),
generators,
})))
} else {
Expand All @@ -1977,13 +1991,17 @@ impl Parser {
self.expect(Kind::Comma)?;
self.consume_whitespace_and_newline();
}
let mut keys = vec![first_key];
let mut values = vec![first_val];
let mut keys = match first_key {
Some(k) => vec![k],
None => vec![],
};
let mut values = vec![first_value];
while !self.eat(Kind::RightBracket) {
let key = self.parse_expression_2()?;
self.expect(Kind::Colon)?;
let value = self.parse_expression_2()?;
keys.push(key);
let (key, value) = self.parse_double_starred_kv_pair()?;
match key {
Some(k) => keys.push(k),
None => {}
}
values.push(value);
if !self.at(Kind::RightBracket) {
self.expect(Kind::Comma)?;
Expand All @@ -1998,6 +2016,18 @@ impl Parser {
}
}

fn parse_double_starred_kv_pair(&mut self) -> Result<(Option<Expression>,Expression), ParsingError> {
if self.eat(Kind::Pow) {
let value = self.parse_expression_2()?;
Ok((None, value))
} else {
let key = self.parse_expression_2()?;
self.expect(Kind::Colon)?;
let value = self.parse_expression_2()?;
Ok((Some(key), value))
}
}

fn consume_whitespace_and_newline(&mut self) -> bool {
let mut consumed = false;
while matches!(self.cur_kind(), Kind::WhiteSpace | Kind::NewLine) {
Expand Down Expand Up @@ -2611,6 +2641,7 @@ impl Parser {
fn parse_slice_list(&mut self) -> Result<Expression, ParsingError> {
let node = self.start_node();
let mut elements = vec![];
// TODO: This EOF check should not be here.
while !self.at(Kind::Eof) && !self.at(Kind::RightBrace) {
if self.at(Kind::Colon) {
elements.push(self.parse_proper_slice(None)?);
Expand Down Expand Up @@ -2651,7 +2682,7 @@ impl Parser {
Some(Box::new(self.parse_expression_2()?))
};
let upper = if self.eat(Kind::Colon) {
if self.at(Kind::RightBrace) {
if self.at(Kind::RightBrace) || self.at(Kind::Colon) {
None
} else {
Some(Box::new(self.parse_expression_2()?))
Expand Down Expand Up @@ -3309,30 +3340,6 @@ mod tests {
}
}

#[test]
fn test_subscript() {
for test_case in &[
"a[b]",
"a[b:c]",
"a[b:c:d]",
"a[b, c, d]",
"a[b, c: d, e]",
"a[::]",
"a[b, c:d:e, f]",
"a[::d,]",
] {
let mut parser = Parser::new(test_case.to_string(), String::from(""));
let program = parser.parse();

insta::with_settings!({
description => test_case.to_string(), // the template source code
omit_expression => true // do not include the default expression
}, {
assert_debug_snapshot!(program);
});
}
}

#[test]
fn test_attribute_ref() {
for test_case in &["a.b", "a.b.c", "a.b_c", "a.b.c.d"] {
Expand Down
Loading

0 comments on commit 4270ed7

Please sign in to comment.