Skip to content

Commit

Permalink
fix struct ini grammar and add tests for it
Browse files Browse the repository at this point in the history
  • Loading branch information
SkymanOne committed Feb 2, 2024
1 parent 6c2605c commit 1efd032
Show file tree
Hide file tree
Showing 5 changed files with 251 additions and 61 deletions.
1 change: 1 addition & 0 deletions crates/parser/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,7 @@ pub enum Expression {
FunctionCall(FunctionCall),
MemberAccess(MemberAccess),
Pipe(BinaryExpression),
StructInit(UnaryExpression<StructInit>),

List(UnaryExpression<Vec<Expression>>),
}
Expand Down
36 changes: 24 additions & 12 deletions crates/parser/src/folidity.lalrpop
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,10 @@ MutParam: ast::Param = {
}

MutParams: Vec<ast::Param> = {
"(" ")" => Vec::new(),
"()" => Vec::new(),
"(" <ListComma<Param>> ")" => <>,
"(" <ListComma<MutParam>> ")" => <>,

"()" => Vec::new(),
"(" ")" => Vec::new(),
"(" <error:!> ")" => {
errors.push(error);
Vec::new()
Expand All @@ -152,20 +152,21 @@ Param: ast::Param = {
}
}


Params: Vec<ast::Param> = {
"{" "}" => Vec::new(),
"{" <ListComma<Param>> "}" => <>,

"{" "}" => Vec::new(),
"{" <error:!> "}" => {
errors.push(error);
Vec::new()
}
}

Variants: Vec<ast::Identifier> = {
"{" "}" => Vec::new(),
"{" <ListComma<Identifier>> "}" => <>,

"{" "}" => Vec::new(),
"{" <error:!> "}" => {
errors.push(error);
Vec::new()
Expand All @@ -174,9 +175,9 @@ Variants: Vec<ast::Identifier> = {


ListExpr: Vec<ast::Expression> = {
"[" "]" => Vec::new(),
"[" <ListComma<Expression>> "]" => <>,

"[" "]" => Vec::new(),
"[" <error:!> "]" => {
errors.push(error);
Vec::new()
Expand Down Expand Up @@ -216,11 +217,11 @@ Variable: ast::Variable = {
ast::Variable::new(start, end, vec![i], mt.is_some(), ty, val)
},

<start:@L> "let" <mt:"mut"?> "{" <is:Identifier+> "}" <ty:(":" <Type>)?> <val:("=" <Expression>)?> <end:@R> => {
<start:@L> "let" <mt:"mut"?> <is:Variants> <ty:(":" <Type>)?> <val:("=" <Expression>)?> <end:@R> => {
ast::Variable::new(start, end, is, mt.is_some(), ty, val)
},

<start:@L> "let" <mt:"mut"?> "{" <is:Identifier+> "}" <ty:(":" <Type>)?> <error:!> <end:@R> => {
<start:@L> "let" <mt:"mut"?> <is:Variants> <ty:(":" <Type>)?> <error:!> <end:@R> => {
errors.push(error);
ast::Variable::new(start, end, is, mt.is_some(), ty, None)
},
Expand All @@ -238,7 +239,7 @@ IfElse: ast::IfElse = {
ast::IfElse::new(start, end, cond, Box::new(body), None)
},

#[precedence(level = "1")] #[assoc(side="left")]
#[precedence(level = "1")]
<start:@L> "if" <cond:Expression> <body:StatementBlock> <mid:@R> "else" <else_part:Statement> <end:@R> => {
match else_part {
ast::Statement::Block(_) | ast::Statement::IfElse(_) => {},
Expand Down Expand Up @@ -279,10 +280,13 @@ FunCall: ast::FunctionCall = {
}

StructInit: ast::StructInit = {
<start:@L> <i:Identifier> "{" <args:ListComma<Expression>> <auto_obj:(".." <Identifier>)?> "}" <end:@R> => {
<start:@L> <i:Identifier> ":" "{" ".." <auto_obj:Identifier> "}" <end:@R> => {
ast::StructInit::new(start, end, i, vec![], Some(auto_obj))
},
<start:@L> <i:Identifier> ":" "{" <args:ListComma<Expression>> <auto_obj:("|" ".." <Identifier>)?> "}" <end:@R> => {
ast::StructInit::new(start, end, i, args, auto_obj)
},
<start:@L> <i:Identifier> ("{" "}")? <end:@R> => {
<start:@L> <i:Identifier> ":" "{" "}" <end:@R> => {
ast::StructInit::new(start, end, i, vec![], None)
},
}
Expand Down Expand Up @@ -424,9 +428,17 @@ Expression: ast::Expression = {
}

Term: ast::Expression = {
#[precedence(level="1")]
<i:Identifier> => {
ast::Expression::Variable(i)
},

<start:@L> <val:StructInit> <end:@R> => {
ast::Expression::StructInit(
ast::UnaryExpression::new(start, end, val)
)
},

<FunCall> => ast::Expression::FunctionCall(<>),

<start:@L> <val:ListExpr> <end:@R> => {
Expand Down Expand Up @@ -519,9 +531,9 @@ extern {
"(" => Token::LParen,
")" => Token::RParen,
"{" => Token::LCurly,
"}" => Token::RCurly,
"[" => Token::LSquare,
"]" => Token::RSquare,
"}" => Token::RCurly,
"<" => Token::LAngle,
">" => Token::RAngle,
"=" => Token::Assign,
Expand Down
2 changes: 1 addition & 1 deletion crates/parser/src/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ pub enum Token<'input> {
Hex(&'input str),
#[regex("a\"[a-zA-Z]+\"", |lex| lex.slice())]
Address(&'input str),
#[regex("[_a-zA-Z][_0-9a-zA-Z]+", |lex| lex.slice())]
#[regex("[_a-zA-Z][_0-9a-zA-Z]*", |lex| lex.slice())]
Identifier(&'input str),
#[token("true")]
True,
Expand Down
8 changes: 4 additions & 4 deletions crates/parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ fn parser_error_to_report(error: &ParseError<usize, Token<'_>, LexicalError>) ->
ParseError::UnrecognizedEof { location, expected } => {
let tokens = expected
.iter()
.fold(String::new(), |init, c| format!("{} `{}`", init, c))
.fold(String::new(), |init, c| format!("{} {}", init, c))
.trim()
.to_string();
let expected = if expected.is_empty() {
Expand All @@ -76,7 +76,7 @@ fn parser_error_to_report(error: &ParseError<usize, Token<'_>, LexicalError>) ->
ParseError::UnrecognizedToken { token, expected } => {
let tokens = expected
.iter()
.fold(String::new(), |init, c| format!("{} `{}`", init, c))
.fold(String::new(), |init, c| format!("{} {}", init, c))
.trim()
.to_string();
let expected = if expected.is_empty() {
Expand All @@ -85,13 +85,13 @@ fn parser_error_to_report(error: &ParseError<usize, Token<'_>, LexicalError>) ->
format!(" Expected: {}", tokens)
};
let message = format!(
"Unrecognised token, `{}`, at this location.{}",
"Unrecognised token, {}, at this location.{}",
token.1, expected
);
Report::parser_error(token.0, token.2, message)
}
ParseError::ExtraToken { token } => {
let message = format!("Unrecognised token, `{}`, at this location", token.1);
let message = format!("Unrecognised token, {}, at this location", token.1);
Report::parser_error(token.0, token.2, message)
}
ParseError::User { error } => Report::from(error.clone()),
Expand Down
Loading

0 comments on commit 1efd032

Please sign in to comment.