2020-03-03 14:53:54 +01:00
|
|
|
|
2020-05-25 17:46:23 +02:00
|
|
|
import "../option";
|
|
|
|
import "../numbers";
|
|
|
|
import "../vec";
|
|
|
|
import "../string";
|
|
|
|
import "../io";
|
2020-05-25 11:05:06 +02:00
|
|
|
|
2020-05-24 21:34:10 +02:00
|
|
|
mod Bolt::Lang {
|
2020-03-03 14:53:54 +01:00
|
|
|
|
|
|
|
pub struct Pos {
|
2020-05-25 11:05:06 +02:00
|
|
|
offset: usize,
|
|
|
|
line: usize,
|
|
|
|
column: usize,
|
2020-03-03 14:53:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
pub struct Span {
|
2020-05-25 17:46:23 +02:00
|
|
|
file: IO::File,
|
|
|
|
start: Pos,
|
|
|
|
end: Pos,
|
2020-03-03 14:53:54 +01:00
|
|
|
}
|
|
|
|
|
2020-05-25 22:46:22 +02:00
|
|
|
define_nodes! {
|
2020-03-03 14:53:54 +01:00
|
|
|
|
2020-05-25 22:46:22 +02:00
|
|
|
Identifier : Symbol {
|
|
|
|
text: String,
|
|
|
|
},
|
2020-05-24 17:47:04 +02:00
|
|
|
|
2020-05-25 22:46:22 +02:00
|
|
|
Statement,
|
2020-05-24 17:47:04 +02:00
|
|
|
|
2020-05-25 22:46:22 +02:00
|
|
|
ReturnStatement : Statement {
|
|
|
|
expression: Option<Expression>,
|
|
|
|
},
|
|
|
|
|
|
|
|
ConditionalCase {
|
|
|
|
test: Option<Expression>,
|
|
|
|
result: Vec<FunctionBodyElement>,
|
|
|
|
},
|
2020-05-24 17:47:04 +02:00
|
|
|
|
2020-05-25 22:46:22 +02:00
|
|
|
ConditionalStatement : Statement {
|
|
|
|
cases: Vec<ConditionalCase>,
|
|
|
|
},
|
2020-05-24 17:47:04 +02:00
|
|
|
|
2020-05-25 22:46:22 +02:00
|
|
|
Expression,
|
|
|
|
|
|
|
|
ReferenceExpression : Expression {
|
|
|
|
modulePath: Option<ModulePath>,
|
|
|
|
name: Symbol,
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2020-05-24 17:47:04 +02:00
|
|
|
|
|
|
|
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(stx: Syntax) {
|
|
|
|
match stx {
|
|
|
|
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(stx, cases);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
register_transformer!(elminate_match_rule);
|
|
|
|
|
2020-03-03 14:53:54 +01:00
|
|
|
}
|
|
|
|
|