import "../option"; import "../numbers"; import "../vec"; import "../string"; import "../io"; mod Bolt::Lang { pub struct Pos { offset: usize, line: usize, column: usize, } pub struct Span { file: IO::File, start: Pos, end: Pos, } define_nodes! { Identifier : Symbol { text: String, }, Statement, ReturnStatement : Statement { expression: Option, }, ConditionalCase { test: Option, result: Vec, }, ConditionalStatement : Statement { cases: Vec, }, Expression, ReferenceExpression : Expression { modulePath: Option, name: Symbol, } } pub type Transformer = fn (node: Node) -> Node; fn build_predicate_from_pattern(pattern: Pattern) -> Expression { match pattern { BindPattern { name } => quote(true).taint(pattern), VariantPatten { elements } => quote(or($(elements),*)), RecordPattern { members } => quote(and($elements),*)), } } fn eliminate_match_rule(node: Node) { match node { quote { match $value: Expression { $patterns @ ( $pattern: Pattern => $expression: Expression ),* (,)? } } => { let cases = patterns.map(|pattern| { ConditionalCase::from_node( pattern, build_predicate_from_pattern(pattern), value ) }); return ConditionalStatement::from_node(node, cases); } } } register_transformer!(elminate_match_rule); }