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::multi::{separated_list, separated_nonempty_list, many1, many0};
|
||||||
use nom::error::{context, ParseError, VerboseError};
|
use nom::error::{context, ParseError, VerboseError};
|
||||||
use nom::branch::alt;
|
use nom::branch::alt;
|
||||||
use nom::sequence::{pair, delimited, preceded};
|
use nom::sequence::{pair, tuple, delimited, preceded};
|
||||||
|
|
||||||
use crate::ast::*;
|
use crate::ast::*;
|
||||||
use crate::builtin::Builtin;
|
use crate::builtin::Builtin;
|
||||||
@ -26,6 +26,10 @@ where
|
|||||||
delimited(space0, parser, space0)
|
delimited(space0, parser, space0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn statement_sep(text: &str) -> ParseResult<()> {
|
||||||
|
value((), one_of("\n;"))(text)
|
||||||
|
}
|
||||||
|
|
||||||
fn single_alphabetic_character(text: &str) -> ParseResult<char> {
|
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));
|
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)
|
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)
|
map(p, |sigil| PrefixOp::from_str(&sigil.to_string()).unwrap())(text)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn identifier_expr(text: &str) -> ParseResult<ExpressionKind> {
|
fn qualified_name(text: &str) -> ParseResult<QualifiedName> {
|
||||||
let (text, qualified_identifier) = map(
|
map(
|
||||||
qualified_identifier_list,
|
separated_nonempty_list(tag("::"), identifier),
|
||||||
|components| QualifiedName { id: ItemId::new(0), components }
|
|components| QualifiedName { id: ItemId::new(0), components }
|
||||||
)(text)?;
|
)(text)
|
||||||
//TODO handle struct literals
|
|
||||||
let exp = Expression::new(ItemId::new(0), ExpressionKind::Value(qualified_identifier));
|
|
||||||
Ok((text, exp.kind))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn qualified_identifier_list(text: &str) -> ParseResult<Vec<Rc<String>>> {
|
fn identifier_expr(text: &str) -> ParseResult<ExpressionKind> {
|
||||||
separated_nonempty_list(tag("::"), identifier)(text)
|
map(qualified_name, ExpressionKind::Value)(text)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn primary_expr(text: &str) -> ParseResult<ExpressionKind> {
|
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> {
|
fn call_expr(text: &str) -> ParseResult<ExpressionKind> {
|
||||||
use nom::character::complete::char;
|
use nom::character::complete::char;
|
||||||
let parse_call = opt(
|
let parse_call = opt(
|
||||||
|
Loading…
Reference in New Issue
Block a user