parse record
This commit is contained in:
parent
fb37bae29f
commit
8836f95149
2 changed files with 78 additions and 1 deletions
|
|
@ -78,6 +78,7 @@ fn parse_simple_expr(tokens: &mut Tokens) -> ParseResult<ast::Expr> {
|
||||||
parse_string,
|
parse_string,
|
||||||
parse_bool,
|
parse_bool,
|
||||||
parse_fn,
|
parse_fn,
|
||||||
|
parse_record,
|
||||||
|t| t.between(&Token::OpenParen, &Token::CloseParen, parse_expr),
|
|t| t.between(&Token::OpenParen, &Token::CloseParen, parse_expr),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
@ -110,6 +111,40 @@ fn parse_args(tokens: &mut Tokens) -> ParseResult<Vec<ast::Arg>> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_record(tokens: &mut Tokens) -> ParseResult<ast::Expr> {
|
||||||
|
if let Some(vect) = tokens.between(&Token::OpenCurly, &Token::CloseCurly, |tokens| {
|
||||||
|
tokens.many_sep_by(&Token::Comma, parse_record_field_expr)
|
||||||
|
})? {
|
||||||
|
Ok(Some(ast::Expr::Value(ast::Value::Record(ast::Record(
|
||||||
|
vect.into_iter().collect(),
|
||||||
|
)))))
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_record_field_expr(tokens: &mut Tokens) -> ParseResult<(ast::Label, ast::Expr)> {
|
||||||
|
if let Some(label) = parse_identifier_label(tokens)? {
|
||||||
|
if let Some(_) = tokens.next_if(&Token::Colon) {
|
||||||
|
if let Some(expr) = parse_expr(tokens)? {
|
||||||
|
Ok(Some((label, expr)))
|
||||||
|
} else {
|
||||||
|
Err(Error::UnexpectedTokenForParser(
|
||||||
|
"parse_record_field_expr_expr".into(),
|
||||||
|
tokens.next(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Err(Error::UnexpectedToken {
|
||||||
|
expected: Token::Colon,
|
||||||
|
got: tokens.next(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_string(tokens: &mut Tokens) -> ParseResult<ast::Expr> {
|
fn parse_string(tokens: &mut Tokens) -> ParseResult<ast::Expr> {
|
||||||
if let Some(LocatedToken {
|
if let Some(LocatedToken {
|
||||||
token: Token::String(string),
|
token: Token::String(string),
|
||||||
|
|
@ -143,12 +178,20 @@ fn parse_identifier_arg(tokens: &mut Tokens) -> ParseResult<ast::Arg> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_identifier_name(tokens: &mut Tokens) -> ParseResult<ast::Name> {
|
fn parse_identifier_name(tokens: &mut Tokens) -> ParseResult<ast::Name> {
|
||||||
|
Ok(parse_identifier_string(tokens)?.map(|string| ast::Name(string)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_identifier_label(tokens: &mut Tokens) -> ParseResult<ast::Label> {
|
||||||
|
Ok(parse_identifier_string(tokens)?.map(|string| ast::Label(string)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_identifier_string(tokens: &mut Tokens) -> ParseResult<String> {
|
||||||
if let Some(LocatedToken {
|
if let Some(LocatedToken {
|
||||||
token: Token::Identifier(string),
|
token: Token::Identifier(string),
|
||||||
..
|
..
|
||||||
}) = tokens.next_if(&Token::Identifier("".into()))
|
}) = tokens.next_if(&Token::Identifier("".into()))
|
||||||
{
|
{
|
||||||
Ok(Some(ast::Name(string)))
|
Ok(Some(string))
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
@ -195,6 +238,12 @@ mod tests {
|
||||||
insta::assert_debug_snapshot!(result);
|
insta::assert_debug_snapshot!(result);
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
|
fn record() {
|
||||||
|
let program = "{ hello: 17, hi: \"cool\"}".to_string();
|
||||||
|
let result = parse(&mut scan(program), parse_expr);
|
||||||
|
insta::assert_debug_snapshot!(result);
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
fn fn_def() {
|
fn fn_def() {
|
||||||
let program = "fn(a1, boco, c_c) { 108 }".to_string();
|
let program = "fn(a1, boco, c_c) { 108 }".to_string();
|
||||||
let result = parse(&mut scan(program), parse_expr);
|
let result = parse(&mut scan(program), parse_expr);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
---
|
||||||
|
source: src/parser/parser.rs
|
||||||
|
expression: result
|
||||||
|
---
|
||||||
|
Ok(
|
||||||
|
Value(
|
||||||
|
Record(
|
||||||
|
Record(
|
||||||
|
{
|
||||||
|
Label(
|
||||||
|
"hello",
|
||||||
|
): Value(
|
||||||
|
Int(
|
||||||
|
17,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Label(
|
||||||
|
"hi",
|
||||||
|
): Value(
|
||||||
|
String(
|
||||||
|
"cool",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
Loading…
Add table
Reference in a new issue