Some basic tree-shaking
This commit is contained in:
+24
-9
@@ -106,6 +106,21 @@ impl<'a> Node<'a> {
|
|||||||
_ => unreachable!()
|
_ => unreachable!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn shake(node: Node<'a>) -> Node<'a> {
|
||||||
|
match node {
|
||||||
|
Node::Expr(first, rest) => {
|
||||||
|
let shaken_car = Node::shake(*first);
|
||||||
|
if rest.is_empty() {
|
||||||
|
shaken_car
|
||||||
|
} else {
|
||||||
|
let shaken_cdr = rest.into_iter().map(|(op, n)| (op, Node::shake(n))).collect();
|
||||||
|
Node::Expr(Box::from(shaken_car), shaken_cdr)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => node
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TryFrom<Pair<'a, Rule>> for Node<'a> {
|
impl<'a> TryFrom<Pair<'a, Rule>> for Node<'a> {
|
||||||
@@ -221,7 +236,7 @@ fn parse_vasm_line(line: &str) -> Result<VASMLine, ParseError<'_>> {
|
|||||||
vasm_line = vasm_line.with_instruction(Instruction::try_from(pairs.next().unwrap())?);
|
vasm_line = vasm_line.with_instruction(Instruction::try_from(pairs.next().unwrap())?);
|
||||||
|
|
||||||
if let Some(argument_group) = pairs.next() {
|
if let Some(argument_group) = pairs.next() {
|
||||||
vasm_line = vasm_line.with_argument(Node::try_from(argument_group)?)
|
vasm_line = vasm_line.with_argument(Node::shake(Node::try_from(argument_group)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,19 +255,19 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn op_number(opcode: Opcode, argument: i32) -> VASMLine<'a> {
|
fn op_number(opcode: Opcode, argument: i32) -> VASMLine<'a> {
|
||||||
Self::blank().with_opcode(opcode).with_argument(Node::simple_expr(Node::simple_expr(Node::Number(argument))))
|
Self::blank().with_opcode(opcode).with_argument(Node::Number(argument))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_label(opcode: Opcode, argument: &'a str) -> VASMLine<'a> {
|
fn op_label(opcode: Opcode, argument: &'a str) -> VASMLine<'a> {
|
||||||
Self::blank().with_opcode(opcode).with_argument(Node::simple_expr(Node::simple_expr(Node::Label(argument))))
|
Self::blank().with_opcode(opcode).with_argument(Node::Label(argument))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_rel_label(opcode: Opcode, argument: &'a str) -> VASMLine<'a> {
|
fn op_rel_label(opcode: Opcode, argument: &'a str) -> VASMLine<'a> {
|
||||||
Self::blank().with_opcode(opcode).with_argument(Node::simple_expr(Node::simple_expr(Node::RelativeLabel(argument))))
|
Self::blank().with_opcode(opcode).with_argument(Node::RelativeLabel(argument))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_off(opcode: Opcode, argument: Node<'a>) -> VASMLine<'a> {
|
fn op_off(opcode: Opcode, argument: Node<'a>) -> VASMLine<'a> {
|
||||||
Self::blank().with_opcode(opcode).with_argument(Node::simple_expr(Node::simple_expr(argument)))
|
Self::blank().with_opcode(opcode).with_argument(argument)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dir_str(directive: Directive, string: &str) -> VASMLine<'a> {
|
pub fn dir_str(directive: Directive, string: &str) -> VASMLine<'a> {
|
||||||
@@ -290,7 +305,7 @@ mod test {
|
|||||||
VASMLine::op(Add)
|
VASMLine::op(Add)
|
||||||
.with_argument(
|
.with_argument(
|
||||||
Node::Expr(
|
Node::Expr(
|
||||||
Box::from(Node::simple_expr(Node::Number(2))),
|
Box::from(Node::Number(2)),
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
Operator::Add,
|
Operator::Add,
|
||||||
@@ -300,12 +315,12 @@ mod test {
|
|||||||
(
|
(
|
||||||
Operator::Mul,
|
Operator::Mul,
|
||||||
Node::Expr(
|
Node::Expr(
|
||||||
Box::from(Node::simple_expr(Node::Number(4))),
|
Box::from(Node::Number(4)),
|
||||||
vec![(Operator::Sub, Node::simple_expr(Node::Number(5)))],
|
vec![(Operator::Sub, Node::Number(5))],
|
||||||
))],)),
|
))],)),
|
||||||
(
|
(
|
||||||
Operator::Add,
|
Operator::Add,
|
||||||
Node::simple_expr(Node::Number(6))
|
Node::Number(6)
|
||||||
)],))));
|
)],))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user