Compare commits

..

2 Commits

Author SHA1 Message Date
Greg Shuflin
0a471ed71c For expression stuff 2021-11-22 01:59:05 -08:00
Greg Shuflin
9c0f60b6ce Fix more parser bugs 2021-11-22 01:52:08 -08:00
4 changed files with 25 additions and 19 deletions

View File

@ -267,8 +267,9 @@ pub enum PatternLiteral {
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub struct Enumerator { pub struct Enumerator {
pub id: Rc<String>, //TODO rename this field pub identifier: Rc<String>,
pub generator: Expression, pub generator: Expression,
pub assignment: bool, //true if `=`, false if `<-`
} }
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]

View File

@ -791,12 +791,13 @@ fn for_expr(input: Span) -> ParseResult<ExpressionKind> {
fn enumerator(input: Span) -> ParseResult<Enumerator> { fn enumerator(input: Span) -> ParseResult<Enumerator> {
alt(( alt((
map(separated_pair(identifier, kw("<-"), expression_no_struct), |(ident, generator)| { map(separated_pair(identifier, kw("<-"), expression_no_struct), |(ident, generator)| {
Enumerator { id: rc_string(ident.fragment()), generator } Enumerator { identifier: rc_string(ident.fragment()), generator, assignment: false }
}), }),
//TODO distinguish these two cases in AST //TODO distinguish these two cases in AST
map(separated_pair(identifier, kw("="), expression_no_struct), |(ident, generator)| Enumerator { map(separated_pair(identifier, kw("="), expression_no_struct), |(ident, generator)| Enumerator {
id: rc_string(ident.fragment()), identifier: rc_string(ident.fragment()),
generator, generator,
assignment: true,
}), }),
))(input) ))(input)
} }

View File

@ -298,11 +298,11 @@ peg::parser! {
//TODO add guards, etc. //TODO add guards, etc.
rule enumerator(parser: &mut Parser) -> Enumerator = rule enumerator(parser: &mut Parser) -> Enumerator =
ident:identifier() _ "<-" _ generator:expression_no_struct(parser) { ident:identifier() _ "<-" _ generator:expression_no_struct(parser) {
Enumerator { id: Rc::new(ident.to_string()), generator } Enumerator { identifier: Rc::new(ident.to_string()), generator, assignment: false }
} / } /
//TODO need to distinguish these two cases in AST //TODO need to distinguish these two cases in AST
ident:identifier() _ "=" _ generator:expression_no_struct(parser) { ident:identifier() _ "=" _ generator:expression_no_struct(parser) {
Enumerator { id: Rc::new(ident.to_string()), generator } Enumerator { identifier: Rc::new(ident.to_string()), generator, assignment: true }
} }
rule for_body(parser: &mut Parser) -> Box<ForBody> = rule for_body(parser: &mut Parser) -> Box<ForBody> =
@ -470,7 +470,7 @@ peg::parser! {
bin_literal() / hex_literal() / unmarked_literal() bin_literal() / hex_literal() / unmarked_literal()
rule unmarked_literal() -> ExpressionKind = rule unmarked_literal() -> ExpressionKind =
digits:digits() { ExpressionKind::NatLiteral(digits.parse().unwrap()) } digits:digits() { let n = digits.chars().filter(|ch| *ch != '_').collect::<String>().parse().unwrap(); ExpressionKind::NatLiteral(n) }
rule bin_literal() -> ExpressionKind = rule bin_literal() -> ExpressionKind =
"0b" digits:bin_digits() {? parse_binary(digits).map(ExpressionKind::NatLiteral) } "0b" digits:bin_digits() {? parse_binary(digits).map(ExpressionKind::NatLiteral) }
@ -482,12 +482,12 @@ peg::parser! {
ds:$( digits() "." digits()? / "." digits() ) { ExpressionKind::FloatLiteral(ds.parse().unwrap()) } ds:$( digits() "." digits()? / "." digits() ) { ExpressionKind::FloatLiteral(ds.parse().unwrap()) }
rule digits() -> &'input str = $((digit_group() "_"*)+) rule digits() -> &'input str = $((digit_group() "_"*)+)
rule bin_digits() -> &'input str = $((bin_digit_group() "_"*)+) rule bin_digits() -> &'input str = $((bin_digit_group() "_"*)+)
rule hex_digits() -> &'input str = $((hex_digit_group() "_"*)+) rule hex_digits() -> &'input str = $((hex_digit_group() "_"*)+)
rule digit_group() -> &'input str = $(['0'..='9']+) rule digit_group() -> &'input str = $(['0'..='9']+)
rule bin_digit_group() -> &'input str = $(['0' | '1']+) rule bin_digit_group() -> &'input str = $(['0' | '1']+)
rule hex_digit_group() -> &'input str = $(['0'..='9' | 'a'..='f' | 'A'..='F']+) rule hex_digit_group() -> &'input str = $(['0'..='9' | 'a'..='f' | 'A'..='F']+)
} }
} }

View File

@ -405,7 +405,11 @@ fn for_expression() {
assert_expr!( assert_expr!(
"for { a <- garodzny::maybeValue } return 1", "for { a <- garodzny::maybeValue } return 1",
expr(ForExpression { expr(ForExpression {
enumerators: vec![Enumerator { id: rc("a"), generator: expr(Value(qn!(garodzny, maybeValue))) }], enumerators: vec![Enumerator {
identifier: rc("a"),
assignment: false,
generator: expr(Value(qn!(garodzny, maybeValue)))
}],
body: bx(ForBody::MonadicReturn(expr(NatLiteral(1)))) body: bx(ForBody::MonadicReturn(expr(NatLiteral(1))))
}) })
); );
@ -413,7 +417,11 @@ fn for_expression() {
assert_expr!( assert_expr!(
"for n <- someRange { f(n) ; }", "for n <- someRange { f(n) ; }",
expr(ForExpression { expr(ForExpression {
enumerators: vec![Enumerator { id: rc("n"), generator: expr(Value(qn!(someRange))) }], enumerators: vec![Enumerator {
identifier: rc("n"),
assignment: false,
generator: expr(Value(qn!(someRange)))
}],
body: bx(ForBody::StatementBlock( body: bx(ForBody::StatementBlock(
vec![stmt(StatementKind::Expression(expr(Call { vec![stmt(StatementKind::Expression(expr(Call {
f: bx(expr(Value(qn!(f)))), f: bx(expr(Value(qn!(f)))),
@ -1383,7 +1391,6 @@ fn blocks() {
assert_block!("{}", vec![].into()); assert_block!("{}", vec![].into());
//TODO this case is broken in the peg version
let source = r#"{ let source = r#"{
//hella //hella
@ -1391,11 +1398,8 @@ fn blocks() {
11; /*chutney*/0xf 11; /*chutney*/0xf
}"#; }"#;
let mut parser = Parser::new(); assert_block!(
let block = parser.block_comb(source); source,
assert_eq!(
block.unwrap(),
vec![ vec![
Statement { Statement {
id: Default::default(), id: Default::default(),