Finish support for assignment operators
This commit is contained in:
parent
23d2209d8b
commit
298194c42d
41
src/eval.rs
41
src/eval.rs
@ -106,6 +106,14 @@ impl Expression {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_assignment(op: &str) -> bool {
|
||||||
|
match op {
|
||||||
|
"=" | "+=" | "-=" |
|
||||||
|
"*=" | "/=" => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> Evaluator<'a> {
|
impl<'a> Evaluator<'a> {
|
||||||
fn reduction_loop(&mut self, mut node: Statement) -> Statement {
|
fn reduction_loop(&mut self, mut node: Statement) -> Statement {
|
||||||
loop {
|
loop {
|
||||||
@ -118,6 +126,7 @@ impl<'a> Evaluator<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn step(&mut self, node: Statement) -> Statement {
|
fn step(&mut self, node: Statement) -> Statement {
|
||||||
|
println!("Step: {:?}", node);
|
||||||
let (new_node, side_effect) = self.reduce_astnode(node);
|
let (new_node, side_effect) = self.reduce_astnode(node);
|
||||||
if let Some(s) = side_effect {
|
if let Some(s) = side_effect {
|
||||||
self.perform_side_effect(s);
|
self.perform_side_effect(s);
|
||||||
@ -176,15 +185,32 @@ impl<'a> Evaluator<'a> {
|
|||||||
return (BinExp(op, left, right), side_effect);
|
return (BinExp(op, left, right), side_effect);
|
||||||
}
|
}
|
||||||
|
|
||||||
// special case for variable assignment
|
|
||||||
if *op == "=" {
|
if *op == "=" {
|
||||||
match *left {
|
return match *left {
|
||||||
Variable(var) => {
|
Variable(var) => {
|
||||||
let binding = SideEffect::AddBinding(var, *right);
|
let binding = SideEffect::AddBinding(var, *right);
|
||||||
return (Null, Some(binding));
|
(Null, Some(binding))
|
||||||
}
|
},
|
||||||
_ => return (Null, None),
|
_ => (Null, None)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if is_assignment(&*op) {
|
||||||
|
let new_op = Rc::new(String::from(match &op[..] {
|
||||||
|
"+=" => "+",
|
||||||
|
"-=" => "-",
|
||||||
|
"*=" => "*",
|
||||||
|
"/=" => "/",
|
||||||
|
_ => unreachable!(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
let reduction =
|
||||||
|
BinExp(Rc::new(String::from("=")),
|
||||||
|
Box::new(*left.clone()),
|
||||||
|
Box::new(BinExp(new_op, left, right))
|
||||||
|
);
|
||||||
|
|
||||||
|
return (reduction, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
if left.is_reducible() {
|
if left.is_reducible() {
|
||||||
@ -254,6 +280,7 @@ impl<'a> Evaluator<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn reduce_binop(&mut self, op: Rc<String>, left: Expression, right: Expression) -> Expression {
|
fn reduce_binop(&mut self, op: Rc<String>, left: Expression, right: Expression) -> Expression {
|
||||||
|
println!("Got op {:?}, l: {:?}, r: {:?}", op, left, right);
|
||||||
let truthy = Number(1.0);
|
let truthy = Number(1.0);
|
||||||
let falsy = Null;
|
let falsy = Null;
|
||||||
match (&op[..], left, right) {
|
match (&op[..], left, right) {
|
||||||
@ -273,10 +300,6 @@ impl<'a> Evaluator<'a> {
|
|||||||
("==", Null, Null) => truthy,
|
("==", Null, Null) => truthy,
|
||||||
("==", StringLiteral(s1), StringLiteral(s2)) => if s1 == s2 { truthy } else { falsy },
|
("==", StringLiteral(s1), StringLiteral(s2)) => if s1 == s2 { truthy } else { falsy },
|
||||||
("==", _, _) => falsy,
|
("==", _, _) => falsy,
|
||||||
("+=", l, r) => BinExp("=", l, BinExp("+", l, r)),
|
|
||||||
("-=", l, r) => BinExp("=", l, BinExp("-", l, r)),
|
|
||||||
("*=", l, r) => BinExp("=", l, BinExp("*", l, r)),
|
|
||||||
("/=", l, r) => BinExp("=", l, BinExp("/", l, r)),
|
|
||||||
_ => falsy,
|
_ => falsy,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,7 @@ impl Parser {
|
|||||||
"*" => 20,
|
"*" => 20,
|
||||||
"/" => 20,
|
"/" => 20,
|
||||||
"%" => 20,
|
"%" => 20,
|
||||||
"==" => 40
|
"==" => 40,
|
||||||
"=" | "+=" | "-=" | "*=" | "/=" => 1,
|
"=" | "+=" | "-=" | "*=" | "/=" => 1,
|
||||||
">" | ">=" | "<" | "<=" => 30,
|
">" | ">=" | "<" | "<=" => 30,
|
||||||
_ => 255,
|
_ => 255,
|
||||||
|
Loading…
Reference in New Issue
Block a user