Whole lot of added code around if exprs
This commit is contained in:
parent
33d4b28786
commit
dd9a1b8a2e
@ -10,7 +10,7 @@ use nom::combinator::{cut, map, map_res, value, opt, verify};
|
||||
use nom::multi::{separated_list, separated_nonempty_list, many1, many0};
|
||||
use nom::error::{context, ParseError, VerboseError};
|
||||
use nom::branch::alt;
|
||||
use nom::sequence::{pair, delimited, preceded};
|
||||
use nom::sequence::{pair, tuple, delimited, preceded};
|
||||
|
||||
use crate::ast::*;
|
||||
use crate::builtin::Builtin;
|
||||
@ -26,6 +26,10 @@ where
|
||||
delimited(space0, parser, space0)
|
||||
}
|
||||
|
||||
fn statement_sep(text: &str) -> ParseResult<()> {
|
||||
value((), one_of("\n;"))(text)
|
||||
}
|
||||
|
||||
fn single_alphabetic_character(text: &str) -> ParseResult<char> {
|
||||
let p = verify(take(1usize), |s: &str| s.chars().nth(0).map(|c| c.is_alphabetic()).unwrap_or(false));
|
||||
map(p, |s: &str| s.chars().nth(0).unwrap())(text)
|
||||
@ -124,18 +128,15 @@ fn prefix_op(text: &str) -> ParseResult<PrefixOp> {
|
||||
map(p, |sigil| PrefixOp::from_str(&sigil.to_string()).unwrap())(text)
|
||||
}
|
||||
|
||||
fn identifier_expr(text: &str) -> ParseResult<ExpressionKind> {
|
||||
let (text, qualified_identifier) = map(
|
||||
qualified_identifier_list,
|
||||
fn qualified_name(text: &str) -> ParseResult<QualifiedName> {
|
||||
map(
|
||||
separated_nonempty_list(tag("::"), identifier),
|
||||
|components| QualifiedName { id: ItemId::new(0), components }
|
||||
)(text)?;
|
||||
//TODO handle struct literals
|
||||
let exp = Expression::new(ItemId::new(0), ExpressionKind::Value(qualified_identifier));
|
||||
Ok((text, exp.kind))
|
||||
)(text)
|
||||
}
|
||||
|
||||
fn qualified_identifier_list(text: &str) -> ParseResult<Vec<Rc<String>>> {
|
||||
separated_nonempty_list(tag("::"), identifier)(text)
|
||||
fn identifier_expr(text: &str) -> ParseResult<ExpressionKind> {
|
||||
map(qualified_name, ExpressionKind::Value)(text)
|
||||
}
|
||||
|
||||
fn primary_expr(text: &str) -> ParseResult<ExpressionKind> {
|
||||
@ -173,6 +174,94 @@ fn if_expr(text: &str) -> ParseResult<ExpressionKind> {
|
||||
}
|
||||
*/
|
||||
|
||||
fn if_expr_body(text: &str) -> ParseResult<IfExpressionBody> {
|
||||
alt((
|
||||
preceded(tag("then"), simple_conditional),
|
||||
preceded(tag("is"), simple_pattern_match),
|
||||
cond_block,
|
||||
))(text)
|
||||
}
|
||||
|
||||
fn simple_conditional(text: &str) -> ParseResult<IfExpressionBody> {
|
||||
map(
|
||||
pair(expr_or_block, else_case),
|
||||
|(then_case, else_case)| IfExpressionBody::SimpleConditional { then_case, else_case }
|
||||
)(text)
|
||||
}
|
||||
|
||||
fn else_case(text: &str) -> ParseResult<Option<Block>> {
|
||||
opt(preceded(tag("else"), expr_or_block))(text)
|
||||
}
|
||||
|
||||
fn simple_pattern_match(text: &str) -> ParseResult<IfExpressionBody> {
|
||||
let p = tuple((pattern, tag("then"), expr_or_block, else_case));
|
||||
map(p, |(pattern, _, then_case, else_case)|
|
||||
IfExpressionBody::SimplePatternMatch { pattern, then_case, else_case }
|
||||
)(text)
|
||||
}
|
||||
|
||||
fn pattern(text: &str) -> ParseResult<Pattern> {
|
||||
use nom::character::complete::char;
|
||||
|
||||
let t = delimited(char('('),
|
||||
separated_nonempty_list(char(','), pattern),
|
||||
char(')')
|
||||
);
|
||||
|
||||
alt((
|
||||
map(t, |patterns| Pattern::TuplePattern(patterns)),
|
||||
simple_pattern,
|
||||
))(text)
|
||||
}
|
||||
|
||||
fn simple_pattern(text: &str) -> ParseResult<Pattern> {
|
||||
alt((
|
||||
value(Pattern::Ignored, tag("_")),
|
||||
tuple_struct_pattern,
|
||||
record_pattern,
|
||||
map(pattern_literal, Pattern::Literal),
|
||||
map(qualified_name, Pattern::VarOrName),
|
||||
))(text)
|
||||
}
|
||||
|
||||
fn tuple_struct_pattern(text: &str) -> ParseResult<Pattern> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn record_pattern(text: &str) -> ParseResult<Pattern> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn pattern_literal(text: &str) -> ParseResult<PatternLiteral> {
|
||||
use PatternLiteral::*;
|
||||
use nom::character::complete::char;
|
||||
alt((
|
||||
value(BoolPattern(true), tag("true")),
|
||||
value(BoolPattern(false), tag("false")),
|
||||
map(delimited(char('"'), take_until("\""), char('"')), |s: &str| StringPattern(Rc::new(s.to_string()))),
|
||||
))(text)
|
||||
//TODO handle signed_number_literal
|
||||
}
|
||||
|
||||
fn cond_block(text: &str) -> ParseResult<IfExpressionBody> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn expr_or_block(text: &str) -> ParseResult<Block> {
|
||||
//TODO fix
|
||||
alt((block, map(expression, |expr| vec![Statement { id: ItemId::new(0), kind: StatementKind::Expression(expr)}])))(text)
|
||||
}
|
||||
|
||||
fn block(text: &str) -> ParseResult<Block> {
|
||||
use nom::character::complete::char;
|
||||
//TODO fix this so it can handle nested statements
|
||||
delimited(char('{'),
|
||||
separated_nonempty_list(statement_sep,
|
||||
map(expression, |e| Statement { id: ItemId::new(0), kind: StatementKind::Expression(e) })
|
||||
),
|
||||
char('}'))(text)
|
||||
}
|
||||
|
||||
fn call_expr(text: &str) -> ParseResult<ExpressionKind> {
|
||||
use nom::character::complete::char;
|
||||
let parse_call = opt(
|
||||
|
Loading…
Reference in New Issue
Block a user