From 111d232c944041ffa9936d096edc9b5724bd9525 Mon Sep 17 00:00:00 2001 From: Jason Williams <936006+jasonwilliams@users.noreply.github.com> Date: Sun, 28 Jul 2019 21:14:04 +0100 Subject: [PATCH] clippy changes, including benchmark updates for more accuracy, fixes #84 --- Cargo.lock | 2 +- benches/string.rs | 25 +- .../declerative_environment_record.rs | 4 +- .../environment/environment_record_trait.rs | 2 +- .../function_environment_record.rs | 4 +- .../environment/global_environment_record.rs | 5 +- src/lib/environment/lexical_environment.rs | 2 +- .../environment/object_environment_record.rs | 4 +- src/lib/exec.rs | 84 +++-- src/lib/js/array.rs | 14 +- src/lib/js/console.rs | 4 +- src/lib/js/error.rs | 9 +- src/lib/js/function.rs | 7 +- src/lib/js/json.rs | 12 +- src/lib/js/object.rs | 2 +- src/lib/js/string.rs | 5 +- src/lib/js/value.rs | 2 +- src/lib/lib.rs | 9 +- src/lib/syntax/ast/expr.rs | 132 +++---- src/lib/syntax/lexer.rs | 19 +- src/lib/syntax/parser.rs | 324 +++++++++--------- 21 files changed, 344 insertions(+), 327 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2c0b732c2b..a7beaeb54e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,7 +2,7 @@ # It is not intended for manual editing. [[package]] name = "Boa" -version = "0.2.2" +version = "0.3.0" dependencies = [ "chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/benches/string.rs b/benches/string.rs index add59c87a1..166f279c26 100644 --- a/benches/string.rs +++ b/benches/string.rs @@ -13,20 +13,27 @@ fn hello_world_lexer(c: &mut Criterion) { c.bench_function("Hello World (Lexer)", move |b| { b.iter(|| { let mut lexer = Lexer::new(black_box(SRC)); - let _ = lexer.lex(); + // return the value into the blackbox so its not optimized away + // https://gist.github.com/jasonwilliams/5325da61a794d8211dcab846d466c4fd + lexer.lex() }) }); } fn hello_world_parser(c: &mut Criterion) { - c.bench_function("Hello World (Parser)", move |b| { - b.iter(|| { - let mut lexer = Lexer::new(SRC); - lexer.lex().unwrap(); - let tokens = lexer.tokens; - Parser::new(black_box(tokens)).parse_all().unwrap(); - }) - }); + // Don't include lexing as part of the parser benchmark + let mut lexer = Lexer::new(SRC); + lexer.lex().expect("failed to lex"); + let tokens = lexer.tokens; + c.bench_function_over_inputs( + "Hello World (Parser)", + move |b, tok| { + b.iter(|| { + Parser::new(black_box(tok.to_vec())).parse_all().unwrap(); + }) + }, + vec![tokens], + ); } fn hello_world(c: &mut Criterion) { diff --git a/src/lib/environment/declerative_environment_record.rs b/src/lib/environment/declerative_environment_record.rs index 0f9ce8add3..4f66337e71 100644 --- a/src/lib/environment/declerative_environment_record.rs +++ b/src/lib/environment/declerative_environment_record.rs @@ -59,7 +59,7 @@ impl EnvironmentRecordTrait for DeclerativeEnvironmentRecord { ); } - fn create_immutable_binding(&mut self, name: String, strict: bool) { + fn create_immutable_binding(&mut self, name: String, strict: bool) -> bool { if self.env_rec.contains_key(&name) { // TODO: change this when error handling comes into play panic!("Identifier {} has already been declared", name); @@ -74,6 +74,8 @@ impl EnvironmentRecordTrait for DeclerativeEnvironmentRecord { strict, }, ); + + true } fn initialize_binding(&mut self, name: &str, value: Value) { diff --git a/src/lib/environment/environment_record_trait.rs b/src/lib/environment/environment_record_trait.rs index 70295f453f..9f1ead6058 100644 --- a/src/lib/environment/environment_record_trait.rs +++ b/src/lib/environment/environment_record_trait.rs @@ -31,7 +31,7 @@ pub trait EnvironmentRecordTrait: Debug + Trace + Finalize { /// The String value N is the text of the bound name. /// If strict is true then attempts to set it after it has been initialized will always throw an exception, /// regardless of the strict mode setting of operations that reference that binding. - fn create_immutable_binding(&mut self, name: String, strict: bool); + fn create_immutable_binding(&mut self, name: String, strict: bool) -> bool; /// Set the value of an already existing but uninitialized binding in an Environment Record. /// The String value N is the text of the bound name. diff --git a/src/lib/environment/function_environment_record.rs b/src/lib/environment/function_environment_record.rs index d721f97dc0..4f9d7f0442 100644 --- a/src/lib/environment/function_environment_record.rs +++ b/src/lib/environment/function_environment_record.rs @@ -116,7 +116,7 @@ impl EnvironmentRecordTrait for FunctionEnvironmentRecord { ); } - fn create_immutable_binding(&mut self, name: String, strict: bool) { + fn create_immutable_binding(&mut self, name: String, strict: bool) -> bool { if self.env_rec.contains_key(&name) { // TODO: change this when error handling comes into play panic!("Identifier {} has already been declared", name); @@ -131,6 +131,8 @@ impl EnvironmentRecordTrait for FunctionEnvironmentRecord { strict, }, ); + + true } fn initialize_binding(&mut self, name: &str, value: Value) { diff --git a/src/lib/environment/global_environment_record.rs b/src/lib/environment/global_environment_record.rs index 82153671e3..1a1225900c 100644 --- a/src/lib/environment/global_environment_record.rs +++ b/src/lib/environment/global_environment_record.rs @@ -108,11 +108,12 @@ impl EnvironmentRecordTrait for GlobalEnvironmentRecord { .create_mutable_binding(name.clone(), deletion) } - fn create_immutable_binding(&mut self, name: String, strict: bool) { + fn create_immutable_binding(&mut self, name: String, strict: bool) -> bool { if self.declerative_record.has_binding(&name) { // TODO: change to exception panic!("Binding already exists!"); } + self.declerative_record .create_immutable_binding(name.clone(), strict) } @@ -178,7 +179,7 @@ impl EnvironmentRecordTrait for GlobalEnvironmentRecord { } fn set_outer_environment(&mut self, _env: Environment) { - unimplemented!() + unimplemented!(); } fn get_environment_type(&self) -> EnvironmentType { diff --git a/src/lib/environment/lexical_environment.rs b/src/lib/environment/lexical_environment.rs index 9c6fe1d1aa..45a74df1f1 100644 --- a/src/lib/environment/lexical_environment.rs +++ b/src/lib/environment/lexical_environment.rs @@ -101,7 +101,7 @@ impl LexicalEnvironment { .create_mutable_binding(name, deletion) } - pub fn create_immutable_binding(&mut self, name: String, deletion: bool) { + pub fn create_immutable_binding(&mut self, name: String, deletion: bool) -> bool { self.get_current_environment() .borrow_mut() .create_immutable_binding(name, deletion) diff --git a/src/lib/environment/object_environment_record.rs b/src/lib/environment/object_environment_record.rs index 59ee3a4100..2cf6589168 100644 --- a/src/lib/environment/object_environment_record.rs +++ b/src/lib/environment/object_environment_record.rs @@ -50,8 +50,8 @@ impl EnvironmentRecordTrait for ObjectEnvironmentRecord { bindings.set_prop(name, prop); } - fn create_immutable_binding(&mut self, _name: String, _strict: bool) { - unimplemented!() + fn create_immutable_binding(&mut self, _name: String, _strict: bool) -> bool { + true } fn initialize_binding(&mut self, name: &str, value: Value) { diff --git a/src/lib/exec.rs b/src/lib/exec.rs index ce2bd06cfa..60578e8fb7 100644 --- a/src/lib/exec.rs +++ b/src/lib/exec.rs @@ -50,17 +50,17 @@ impl Executor for Interpreter { #[allow(clippy::match_same_arms)] fn run(&mut self, expr: &Expr) -> ResultValue { match expr.def { - ExprDef::ConstExpr(Const::Null) => Ok(to_value(None::<()>)), - ExprDef::ConstExpr(Const::Undefined) => Ok(Gc::new(ValueData::Undefined)), - ExprDef::ConstExpr(Const::Num(num)) => Ok(to_value(num)), - ExprDef::ConstExpr(Const::Int(num)) => Ok(to_value(num)), + ExprDef::Const(Const::Null) => Ok(to_value(None::<()>)), + ExprDef::Const(Const::Undefined) => Ok(Gc::new(ValueData::Undefined)), + ExprDef::Const(Const::Num(num)) => Ok(to_value(num)), + ExprDef::Const(Const::Int(num)) => Ok(to_value(num)), // we can't move String from Const into value, because const is a garbage collected value // Which means Drop() get's called on Const, but str will be gone at that point. // Do Const values need to be garbage collected? We no longer need them once we've generated Values - ExprDef::ConstExpr(Const::String(ref str)) => Ok(to_value(str.to_owned())), - ExprDef::ConstExpr(Const::Bool(val)) => Ok(to_value(val)), - ExprDef::ConstExpr(Const::RegExp(_, _, _)) => Ok(to_value(None::<()>)), - ExprDef::BlockExpr(ref es) => { + ExprDef::Const(Const::String(ref str)) => Ok(to_value(str.to_owned())), + ExprDef::Const(Const::Bool(val)) => Ok(to_value(val)), + ExprDef::Const(Const::RegExp(_, _, _)) => Ok(to_value(None::<()>)), + ExprDef::Block(ref es) => { let mut obj = to_value(None::<()>); for e in es.iter() { let val = self.run(e)?; @@ -70,26 +70,26 @@ impl Executor for Interpreter { } Ok(obj) } - ExprDef::LocalExpr(ref name) => { + ExprDef::Local(ref name) => { let val = self.environment.get_binding_value(name); Ok(val) } - ExprDef::GetConstFieldExpr(ref obj, ref field) => { + ExprDef::GetConstField(ref obj, ref field) => { let val_obj = self.run(obj)?; Ok(val_obj.borrow().get_field(field)) } - ExprDef::GetFieldExpr(ref obj, ref field) => { + ExprDef::GetField(ref obj, ref field) => { let val_obj = self.run(obj)?; let val_field = self.run(field)?; Ok(val_obj.borrow().get_field(&val_field.borrow().to_string())) } - ExprDef::CallExpr(ref callee, ref args) => { + ExprDef::Call(ref callee, ref args) => { let (this, func) = match callee.def { - ExprDef::GetConstFieldExpr(ref obj, ref field) => { + ExprDef::GetConstField(ref obj, ref field) => { let obj = self.run(obj)?; (obj.clone(), obj.borrow().get_field(field)) } - ExprDef::GetFieldExpr(ref obj, ref field) => { + ExprDef::GetField(ref obj, ref field) => { let obj = self.run(obj)?; let field = self.run(field)?; ( @@ -135,28 +135,26 @@ impl Executor for Interpreter { _ => Err(Gc::new(ValueData::Undefined)), } } - ExprDef::WhileLoopExpr(ref cond, ref expr) => { + ExprDef::WhileLoop(ref cond, ref expr) => { let mut result = Gc::new(ValueData::Undefined); while self.run(cond)?.borrow().is_true() { result = self.run(expr)?; } Ok(result) } - ExprDef::IfExpr(ref cond, ref expr, None) => { - Ok(if self.run(cond)?.borrow().is_true() { - self.run(expr)? - } else { - Gc::new(ValueData::Undefined) - }) - } - ExprDef::IfExpr(ref cond, ref expr, Some(ref else_e)) => { + ExprDef::If(ref cond, ref expr, None) => Ok(if self.run(cond)?.borrow().is_true() { + self.run(expr)? + } else { + Gc::new(ValueData::Undefined) + }), + ExprDef::If(ref cond, ref expr, Some(ref else_e)) => { Ok(if self.run(cond)?.borrow().is_true() { self.run(expr)? } else { self.run(else_e)? }) } - ExprDef::SwitchExpr(ref val_e, ref vals, ref default) => { + ExprDef::Switch(ref val_e, ref vals, ref default) => { let val = self.run(val_e)?.clone(); let mut result = Gc::new(ValueData::Null); let mut matched = false; @@ -180,7 +178,7 @@ impl Executor for Interpreter { } Ok(result) } - ExprDef::ObjectDeclExpr(ref map) => { + ExprDef::ObjectDecl(ref map) => { let global_val = &self.environment.get_global_object().unwrap(); let obj = ValueData::new_obj(Some(global_val)); for (key, val) in map.iter() { @@ -188,7 +186,7 @@ impl Executor for Interpreter { } Ok(obj) } - ExprDef::ArrayDeclExpr(ref arr) => { + ExprDef::ArrayDecl(ref arr) => { let global_val = &self.environment.get_global_object().unwrap(); let arr_map = ValueData::new_obj(Some(global_val)); // Note that this object is an Array @@ -209,7 +207,7 @@ impl Executor for Interpreter { arr_map.borrow().set_field_slice("length", to_value(index)); Ok(arr_map) } - ExprDef::FunctionDeclExpr(ref name, ref args, ref expr) => { + ExprDef::FunctionDecl(ref name, ref args, ref expr) => { let function = Function::RegularFunc(RegularFunction::new(*expr.clone(), args.clone())); let val = Gc::new(ValueData::Function(Box::new(GcCell::new(function)))); @@ -221,14 +219,14 @@ impl Executor for Interpreter { } Ok(val) } - ExprDef::ArrowFunctionDeclExpr(ref args, ref expr) => { + ExprDef::ArrowFunctionDecl(ref args, ref expr) => { let function = Function::RegularFunc(RegularFunction::new(*expr.clone(), args.clone())); Ok(Gc::new(ValueData::Function(Box::new(GcCell::new( function, ))))) } - ExprDef::BinOpExpr(BinOp::Num(ref op), ref a, ref b) => { + ExprDef::BinOp(BinOp::Num(ref op), ref a, ref b) => { let v_r_a = self.run(a)?; let v_r_b = self.run(b)?; let v_a = (*v_r_a).clone(); @@ -241,7 +239,7 @@ impl Executor for Interpreter { NumOp::Mod => v_a % v_b, })) } - ExprDef::UnaryOpExpr(ref op, ref a) => { + ExprDef::UnaryOp(ref op, ref a) => { let v_r_a = self.run(a)?; let v_a = (*v_r_a).clone(); Ok(match *op { @@ -251,7 +249,7 @@ impl Executor for Interpreter { _ => unreachable!(), }) } - ExprDef::BinOpExpr(BinOp::Bit(ref op), ref a, ref b) => { + ExprDef::BinOp(BinOp::Bit(ref op), ref a, ref b) => { let v_r_a = self.run(a)?; let v_r_b = self.run(b)?; let v_a = (*v_r_a).clone(); @@ -264,7 +262,7 @@ impl Executor for Interpreter { BitOp::Shr => v_a >> v_b, })) } - ExprDef::BinOpExpr(BinOp::Comp(ref op), ref a, ref b) => { + ExprDef::BinOp(BinOp::Comp(ref op), ref a, ref b) => { let v_r_a = self.run(a)?; let v_r_b = self.run(b)?; let v_a = v_r_a.borrow(); @@ -284,7 +282,7 @@ impl Executor for Interpreter { CompOp::LessThanOrEqual => v_a.to_num() <= v_b.to_num(), })) } - ExprDef::BinOpExpr(BinOp::Log(ref op), ref a, ref b) => { + ExprDef::BinOp(BinOp::Log(ref op), ref a, ref b) => { let v_a = from_value::(self.run(a)?).unwrap(); let v_b = from_value::(self.run(b)?).unwrap(); Ok(match *op { @@ -292,7 +290,7 @@ impl Executor for Interpreter { LogOp::Or => to_value(v_a || v_b), }) } - ExprDef::ConstructExpr(ref callee, ref args) => { + ExprDef::Construct(ref callee, ref args) => { let func = self.run(callee)?; let mut v_args = Vec::with_capacity(args.len()); for arg in args.iter() { @@ -331,19 +329,19 @@ impl Executor for Interpreter { _ => Ok(Gc::new(ValueData::Undefined)), } } - ExprDef::ReturnExpr(ref ret) => match *ret { + ExprDef::Return(ref ret) => match *ret { Some(ref v) => self.run(v), None => Ok(Gc::new(ValueData::Undefined)), }, - ExprDef::ThrowExpr(ref ex) => Err(self.run(ex)?), - ExprDef::AssignExpr(ref ref_e, ref val_e) => { + ExprDef::Throw(ref ex) => Err(self.run(ex)?), + ExprDef::Assign(ref ref_e, ref val_e) => { let val = self.run(val_e)?; match ref_e.def { - ExprDef::LocalExpr(ref name) => { + ExprDef::Local(ref name) => { self.environment.create_mutable_binding(name.clone(), false); self.environment.initialize_binding(name, val.clone()); } - ExprDef::GetConstFieldExpr(ref obj, ref field) => { + ExprDef::GetConstField(ref obj, ref field) => { let val_obj = self.run(obj)?; val_obj.borrow().set_field(field.clone(), val.clone()); } @@ -351,7 +349,7 @@ impl Executor for Interpreter { } Ok(val) } - ExprDef::VarDeclExpr(ref vars) => { + ExprDef::VarDecl(ref vars) => { for var in vars.iter() { let (name, value) = var.clone(); let val = match value { @@ -363,7 +361,7 @@ impl Executor for Interpreter { } Ok(Gc::new(ValueData::Undefined)) } - ExprDef::LetDeclExpr(ref vars) => { + ExprDef::LetDecl(ref vars) => { for var in vars.iter() { let (name, value) = var.clone(); let val = match value { @@ -375,7 +373,7 @@ impl Executor for Interpreter { } Ok(Gc::new(ValueData::Undefined)) } - ExprDef::ConstDeclExpr(ref vars) => { + ExprDef::ConstDecl(ref vars) => { for (name, value) in vars.iter() { self.environment .create_immutable_binding(name.clone(), false); @@ -384,7 +382,7 @@ impl Executor for Interpreter { } Ok(Gc::new(ValueData::Undefined)) } - ExprDef::TypeOfExpr(ref val_e) => { + ExprDef::TypeOf(ref val_e) => { let val = self.run(val_e)?; Ok(to_value(match *val { ValueData::Undefined => "undefined", diff --git a/src/lib/js/array.rs b/src/lib/js/array.rs index b9503ecb2a..1916b610a1 100644 --- a/src/lib/js/array.rs +++ b/src/lib/js/array.rs @@ -14,7 +14,8 @@ fn create_array_object(array_obj: &Value, array_contents: &[Value]) -> ResultVal let array_obj_ptr = array_obj.clone(); // Wipe existing contents of the array object - let orig_length: i32 = from_value(array_obj.get_field_slice("length")).unwrap(); + let orig_length: i32 = + from_value(array_obj.get_field_slice("length")).expect("failed to convert length to i32"); for n in 0..orig_length { array_obj_ptr.remove_prop(&n.to_string()); } @@ -29,7 +30,8 @@ fn create_array_object(array_obj: &Value, array_contents: &[Value]) -> ResultVal /// Utility function which takes an existing array object and puts additional /// values on the end, correctly rewriting the length fn add_to_array_object(array_ptr: &Value, add_values: &[Value]) -> ResultValue { - let orig_length: i32 = from_value(array_ptr.get_field_slice("length")).unwrap(); + let orig_length: i32 = + from_value(array_ptr.get_field_slice("length")).expect("failed to conveert lenth to i32"); for (n, value) in add_values.iter().enumerate() { let new_index = orig_length + (n as i32); @@ -296,16 +298,16 @@ mod tests { "#; forward(&mut engine, init); // Empty ++ Empty - let ee = forward(&mut engine, "empty.concat(empty)"); + let _ee = forward(&mut engine, "empty.concat(empty)"); //assert_eq!(ee, String::from("")); // Empty ++ NonEmpty - let en = forward(&mut engine, "empty.concat(one)"); + let _en = forward(&mut engine, "empty.concat(one)"); //assert_eq!(en, String::from("a")); // NonEmpty ++ Empty - let ne = forward(&mut engine, "one.concat(empty)"); + let _ne = forward(&mut engine, "one.concat(empty)"); //assert_eq!(ne, String::from("a.b.c")); // NonEmpty ++ NonEmpty - let nn = forward(&mut engine, "one.concat(one)"); + let _nn = forward(&mut engine, "one.concat(one)"); //assert_eq!(nn, String::from("a.b.c")); } diff --git a/src/lib/js/console.rs b/src/lib/js/console.rs index 8504327fa6..a4bbbe546f 100644 --- a/src/lib/js/console.rs +++ b/src/lib/js/console.rs @@ -23,10 +23,10 @@ fn log_string_from(x: Value) -> String { v.borrow() .internal_slots .get("PrimitiveValue") - .unwrap() + .expect("Cannot get primitive value from String") .clone(), ) - .unwrap(); + .expect("Cannot clone primitive value from String"); write!(s, "{}", str_val).unwrap(); } ObjectKind::Array => { diff --git a/src/lib/js/error.rs b/src/lib/js/error.rs index e7b84b3553..46b20c1ea9 100644 --- a/src/lib/js/error.rs +++ b/src/lib/js/error.rs @@ -11,7 +11,14 @@ use gc::Gc; /// Create a new error pub fn make_error(this: &Value, args: &[Value], _: &Interpreter) -> ResultValue { if !args.is_empty() { - this.set_field_slice("message", to_value(args.get(0).unwrap().to_string())); + this.set_field_slice( + "message", + to_value( + args.get(0) + .expect("failed getting error message") + .to_string(), + ), + ); } // This value is used by console.log and other routines to match Object type // to its Javascript Identifier (global constructor method name) diff --git a/src/lib/js/function.rs b/src/lib/js/function.rs index 876dd17d50..d638b85ddc 100644 --- a/src/lib/js/function.rs +++ b/src/lib/js/function.rs @@ -40,6 +40,7 @@ pub struct RegularFunction { impl RegularFunction { /// Make a new regular function + #[allow(clippy::cast_possible_wrap)] pub fn new(expr: Expr, args: Vec) -> Self { let mut object = ObjectData::default(); object.properties.insert( @@ -69,7 +70,11 @@ impl NativeFunction { impl Debug for NativeFunction { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "({:?})", self.object) + write!(f, "{{")?; + for (key, val) in self.object.properties.iter() { + write!(f, "{}: {}", key, val.value.clone())?; + } + write!(f, "}}") } } diff --git a/src/lib/js/json.rs b/src/lib/js/json.rs index 1e16d0a36c..3e002d73cc 100644 --- a/src/lib/js/json.rs +++ b/src/lib/js/json.rs @@ -8,16 +8,22 @@ use serde_json::{self, to_string_pretty, Value as JSONValue}; /// Parse a JSON string into a Javascript object /// pub fn parse(_: &Value, args: &[Value], _: &Interpreter) -> ResultValue { - match serde_json::from_str::(&args.get(0).unwrap().clone().to_string()) { + match serde_json::from_str::( + &args + .get(0) + .expect("cannot get argument for JSON.parse") + .clone() + .to_string(), + ) { Ok(json) => Ok(to_value(json)), Err(err) => Err(to_value(err.to_string())), } } /// Process a Javascript object into a JSON string pub fn stringify(_: &Value, args: &[Value], _: &Interpreter) -> ResultValue { - let obj = args.get(0).unwrap(); + let obj = args.get(0).expect("cannot get argument for JSON.stringify"); let json = obj.to_json(); - Ok(to_value(to_string_pretty(&json).unwrap())) + Ok(to_value(to_string_pretty(&json).expect(""))) } /// Create a new `JSON` object diff --git a/src/lib/js/object.rs b/src/lib/js/object.rs index 614ea5d0ee..bdf8c148cb 100644 --- a/src/lib/js/object.rs +++ b/src/lib/js/object.rs @@ -32,7 +32,7 @@ pub struct ObjectData { impl ObjectData { /// Return a new ObjectData struct, with `kind` set to Ordinary - pub fn default() -> ObjectData { + pub fn default() -> Self { Self { kind: ObjectKind::Ordinary, internal_slots: Box::new(HashMap::new()), diff --git a/src/lib/js/string.rs b/src/lib/js/string.rs index 072fc99846..684553f324 100644 --- a/src/lib/js/string.rs +++ b/src/lib/js/string.rs @@ -7,7 +7,6 @@ use crate::{ }, }; use gc::Gc; -use gc_derive::{Finalize, Trace}; use std::{ cmp::{max, min}, f64::NAN, @@ -544,8 +543,8 @@ mod tests { const nice = new String('Have a nice day.'); "#; forward(&mut engine, init); - let a = forward(&mut engine, "hello.concat(world, nice)"); - let b = forward(&mut engine, "hello + world + nice"); + let _a = forward(&mut engine, "hello.concat(world, nice)"); + let _b = forward(&mut engine, "hello + world + nice"); // Todo: fix this //assert_eq!(a, String::from("Hello, world! Have a nice day.")); //assert_eq!(b, String::from("Hello, world! Have a nice day.")); diff --git a/src/lib/js/value.rs b/src/lib/js/value.rs index edffc91ca5..a54d3505c3 100644 --- a/src/lib/js/value.rs +++ b/src/lib/js/value.rs @@ -46,7 +46,7 @@ impl ValueData { if global.is_some() { let obj_proto = global - .unwrap() + .expect("Expected global object in making-new-object") .get_field_slice("Object") .get_field_slice(PROTOTYPE); obj.properties diff --git a/src/lib/lib.rs b/src/lib/lib.rs index 128f8975dd..664fdb6b3f 100644 --- a/src/lib/lib.rs +++ b/src/lib/lib.rs @@ -23,7 +23,10 @@ clippy::missing_docs_in_private_items, clippy::missing_inline_in_public_items, clippy::implicit_return, - clippy::wildcard_enum_match_arm + clippy::wildcard_enum_match_arm, + clippy::cognitive_complexity, + clippy::module_name_repetitions, + clippy::print_stdout )] pub mod environment; @@ -47,9 +50,9 @@ extern "C" { fn parser_expr(src: &str) -> Expr { let mut lexer = Lexer::new(src); - lexer.lex().unwrap(); + lexer.lex().expect("lexing failed"); let tokens = lexer.tokens; - Parser::new(tokens).parse_all().unwrap() + Parser::new(tokens).parse_all().expect("parsing failed") } /// Execute the code using an existing Interpreter diff --git a/src/lib/syntax/ast/expr.rs b/src/lib/syntax/ast/expr.rs index a0bdddcf4f..eac8c040ae 100644 --- a/src/lib/syntax/ast/expr.rs +++ b/src/lib/syntax/ast/expr.rs @@ -31,81 +31,81 @@ impl Display for Expr { /// A Javascript Expression pub enum ExprDef { /// Run a operation between 2 expressions - BinOpExpr(BinOp, Box, Box), + BinOp(BinOp, Box, Box), /// Run an operation on a value - UnaryOpExpr(UnaryOp, Box), + UnaryOp(UnaryOp, Box), /// Make a constant value - ConstExpr(Const), + Const(Const), /// Const declaration - ConstDeclExpr(Vec<(String, Expr)>), + ConstDecl(Vec<(String, Expr)>), /// Construct an object from the function and arg{ - ConstructExpr(Box, Vec), + Construct(Box, Vec), /// Run several expressions from top-to-bottom - BlockExpr(Vec), + Block(Vec), /// Load a reference to a value - LocalExpr(String), + Local(String), /// Gets the constant field of a value - GetConstFieldExpr(Box, String), + GetConstField(Box, String), /// Gets the field of a value - GetFieldExpr(Box, Box), + GetField(Box, Box), /// Call a function with some values - CallExpr(Box, Vec), + Call(Box, Vec), /// Repeatedly run an expression while the conditional expression resolves to true - WhileLoopExpr(Box, Box), + WhileLoop(Box, Box), /// Check if a conditional expression is true and run an expression if it is and another expression if it isn't - IfExpr(Box, Box, Option>), + If(Box, Box, Option>), /// Run blocks whose cases match the expression - SwitchExpr(Box, Vec<(Expr, Vec)>, Option>), + Switch(Box, Vec<(Expr, Vec)>, Option>), /// Create an object out of the binary tree given - ObjectDeclExpr(Box>), + ObjectDecl(Box>), /// Create an array with items inside - ArrayDeclExpr(Vec), + ArrayDecl(Vec), /// Create a function with the given name, arguments, and expression - FunctionDeclExpr(Option, Vec, Box), + FunctionDecl(Option, Vec, Box), /// Create an arrow function with the given arguments and expression - ArrowFunctionDeclExpr(Vec, Box), + ArrowFunctionDecl(Vec, Box), /// Return the expression from a function - ReturnExpr(Option>), + Return(Option>), /// Throw a value - ThrowExpr(Box), + Throw(Box), /// Assign an expression to a value - AssignExpr(Box, Box), + Assign(Box, Box), /// { /// A variable declaratio /// } - VarDeclExpr(Vec<(String, Option)>), + VarDecl(Vec<(String, Option)>), /// Let declaraton - LetDeclExpr(Vec<(String, Option)>), + LetDecl(Vec<(String, Option)>), /// Return a string representing the type of the given expression - TypeOfExpr(Box), + TypeOf(Box), } impl Operator for ExprDef { fn get_assoc(&self) -> bool { match *self { - ExprDef::ConstructExpr(_, _) - | ExprDef::UnaryOpExpr(_, _) - | ExprDef::TypeOfExpr(_) - | ExprDef::IfExpr(_, _, _) - | ExprDef::AssignExpr(_, _) => false, + ExprDef::Construct(_, _) + | ExprDef::UnaryOp(_, _) + | ExprDef::TypeOf(_) + | ExprDef::If(_, _, _) + | ExprDef::Assign(_, _) => false, _ => true, } } fn get_precedence(&self) -> u64 { match self { - ExprDef::GetFieldExpr(_, _) | ExprDef::GetConstFieldExpr(_, _) => 1, - ExprDef::CallExpr(_, _) | ExprDef::ConstructExpr(_, _) => 2, - ExprDef::UnaryOpExpr(UnaryOp::IncrementPost, _) - | ExprDef::UnaryOpExpr(UnaryOp::IncrementPre, _) - | ExprDef::UnaryOpExpr(UnaryOp::DecrementPost, _) - | ExprDef::UnaryOpExpr(UnaryOp::DecrementPre, _) => 3, - ExprDef::UnaryOpExpr(UnaryOp::Not, _) - | ExprDef::UnaryOpExpr(UnaryOp::Minus, _) - | ExprDef::TypeOfExpr(_) => 4, - ExprDef::BinOpExpr(op, _, _) => op.get_precedence(), - ExprDef::IfExpr(_, _, _) => 15, + ExprDef::GetField(_, _) | ExprDef::GetConstField(_, _) => 1, + ExprDef::Call(_, _) | ExprDef::Construct(_, _) => 2, + ExprDef::UnaryOp(UnaryOp::IncrementPost, _) + | ExprDef::UnaryOp(UnaryOp::IncrementPre, _) + | ExprDef::UnaryOp(UnaryOp::DecrementPost, _) + | ExprDef::UnaryOp(UnaryOp::DecrementPre, _) => 3, + ExprDef::UnaryOp(UnaryOp::Not, _) + | ExprDef::UnaryOp(UnaryOp::Minus, _) + | ExprDef::TypeOf(_) => 4, + ExprDef::BinOp(op, _, _) => op.get_precedence(), + ExprDef::If(_, _, _) => 15, // 16 should be yield - ExprDef::AssignExpr(_, _) => 17, + ExprDef::Assign(_, _) => 17, _ => 19, } } @@ -114,23 +114,23 @@ impl Operator for ExprDef { impl Display for ExprDef { fn fmt(&self, f: &mut Formatter) -> Result { match *self { - ExprDef::ConstExpr(ref c) => write!(f, "{}", c), - ExprDef::BlockExpr(ref block) => { + ExprDef::Const(ref c) => write!(f, "{}", c), + ExprDef::Block(ref block) => { write!(f, "{{")?; for expr in block.iter() { write!(f, "{};", expr)?; } write!(f, "}}") } - ExprDef::LocalExpr(ref s) => write!(f, "{}", s), - ExprDef::GetConstFieldExpr(ref ex, ref field) => write!(f, "{}.{}", ex, field), - ExprDef::GetFieldExpr(ref ex, ref field) => write!(f, "{}[{}]", ex, field), - ExprDef::CallExpr(ref ex, ref args) => { + ExprDef::Local(ref s) => write!(f, "{}", s), + ExprDef::GetConstField(ref ex, ref field) => write!(f, "{}.{}", ex, field), + ExprDef::GetField(ref ex, ref field) => write!(f, "{}[{}]", ex, field), + ExprDef::Call(ref ex, ref args) => { write!(f, "{}(", ex)?; let arg_strs: Vec = args.iter().map(ToString::to_string).collect(); write!(f, "{})", arg_strs.join(",")) } - ExprDef::ConstructExpr(ref func, ref args) => { + ExprDef::Construct(ref func, ref args) => { f.write_fmt(format_args!("new {}", func))?; f.write_str("(")?; let mut first = true; @@ -143,12 +143,12 @@ impl Display for ExprDef { } f.write_str(")") } - ExprDef::WhileLoopExpr(ref cond, ref expr) => write!(f, "while({}) {}", cond, expr), - ExprDef::IfExpr(ref cond, ref expr, None) => write!(f, "if({}) {}", cond, expr), - ExprDef::IfExpr(ref cond, ref expr, Some(ref else_e)) => { + ExprDef::WhileLoop(ref cond, ref expr) => write!(f, "while({}) {}", cond, expr), + ExprDef::If(ref cond, ref expr, None) => write!(f, "if({}) {}", cond, expr), + ExprDef::If(ref cond, ref expr, Some(ref else_e)) => { write!(f, "if({}) {} else {}", cond, expr, else_e) } - ExprDef::SwitchExpr(ref val, ref vals, None) => { + ExprDef::Switch(ref val, ref vals, None) => { f.write_fmt(format_args!("switch({})", val))?; f.write_str(" {")?; for e in vals.iter() { @@ -157,7 +157,7 @@ impl Display for ExprDef { } f.write_str("}") } - ExprDef::SwitchExpr(ref val, ref vals, Some(ref def)) => { + ExprDef::Switch(ref val, ref vals, Some(ref def)) => { f.write_fmt(format_args!("switch({})", val))?; f.write_str(" {")?; for e in vals.iter() { @@ -168,33 +168,33 @@ impl Display for ExprDef { Display::fmt(def, f)?; f.write_str("}") } - ExprDef::ObjectDeclExpr(ref map) => { + ExprDef::ObjectDecl(ref map) => { f.write_str("{")?; for (key, value) in map.iter() { f.write_fmt(format_args!("{}: {},", key, value))?; } f.write_str("}") } - ExprDef::ArrayDeclExpr(ref arr) => { + ExprDef::ArrayDecl(ref arr) => { f.write_str("[")?; join_expr(f, arr)?; f.write_str("]") } - ExprDef::FunctionDeclExpr(ref name, ref args, ref expr) => match name { + ExprDef::FunctionDecl(ref name, ref args, ref expr) => match name { Some(val) => write!(f, "function {}({}){}", val, args.join(", "), expr), None => write!(f, "function ({}){}", args.join(", "), expr), }, - ExprDef::ArrowFunctionDeclExpr(ref args, ref expr) => { + ExprDef::ArrowFunctionDecl(ref args, ref expr) => { write!(f, "({}) => {}", args.join(", "), expr) } - ExprDef::BinOpExpr(ref op, ref a, ref b) => write!(f, "{} {} {}", a, op, b), - ExprDef::UnaryOpExpr(ref op, ref a) => write!(f, "{}{}", op, a), - ExprDef::ReturnExpr(Some(ref ex)) => write!(f, "return {}", ex), - ExprDef::ReturnExpr(None) => write!(f, "return"), - ExprDef::ThrowExpr(ref ex) => write!(f, "throw {}", ex), - ExprDef::AssignExpr(ref ref_e, ref val) => write!(f, "{} = {}", ref_e, val), - ExprDef::VarDeclExpr(ref vars) | ExprDef::LetDeclExpr(ref vars) => { - if let ExprDef::VarDeclExpr(_) = *self { + ExprDef::BinOp(ref op, ref a, ref b) => write!(f, "{} {} {}", a, op, b), + ExprDef::UnaryOp(ref op, ref a) => write!(f, "{}{}", op, a), + ExprDef::Return(Some(ref ex)) => write!(f, "return {}", ex), + ExprDef::Return(None) => write!(f, "return"), + ExprDef::Throw(ref ex) => write!(f, "throw {}", ex), + ExprDef::Assign(ref ref_e, ref val) => write!(f, "{} = {}", ref_e, val), + ExprDef::VarDecl(ref vars) | ExprDef::LetDecl(ref vars) => { + if let ExprDef::VarDecl(_) = *self { f.write_str("var ")?; } else { f.write_str("let ")?; @@ -207,14 +207,14 @@ impl Display for ExprDef { } Ok(()) } - ExprDef::ConstDeclExpr(ref vars) => { + ExprDef::ConstDecl(ref vars) => { f.write_str("const ")?; for (key, val) in vars.iter() { f.write_fmt(format_args!("{} = {}", key, val))? } Ok(()) } - ExprDef::TypeOfExpr(ref e) => write!(f, "typeof {}", e), + ExprDef::TypeOf(ref e) => write!(f, "typeof {}", e), } } } diff --git a/src/lib/syntax/lexer.rs b/src/lib/syntax/lexer.rs index 2bafcac5e1..56663b4322 100644 --- a/src/lib/syntax/lexer.rs +++ b/src/lib/syntax/lexer.rs @@ -544,7 +544,7 @@ mod tests { fn check_string() { let s = "'aaa' \"bbb\""; let mut lexer = Lexer::new(s); - lexer.lex().unwrap(); + lexer.lex().expect("failed to lex"); assert_eq!( lexer.tokens[0].data, TokenData::StringLiteral("aaa".to_string()) @@ -563,7 +563,7 @@ mod tests { + - * % -- << >> >>> & | ^ ! ~ && || ? : \ = += -= *= &= **= ++ ** <<= >>= >>>= &= |= ^= =>"; let mut lexer = Lexer::new(s); - lexer.lex().unwrap(); + lexer.lex().expect("failed to lex"); assert_eq!( lexer.tokens[0].data, TokenData::Punctuator(Punctuator::OpenBlock) @@ -761,7 +761,7 @@ mod tests { new return super switch this throw try typeof var void while with yield"; let mut lexer = Lexer::new(s); - lexer.lex().unwrap(); + lexer.lex().expect("failed to lex"); assert_eq!(lexer.tokens[0].data, TokenData::Keyword(Keyword::Await)); assert_eq!(lexer.tokens[1].data, TokenData::Keyword(Keyword::Break)); assert_eq!(lexer.tokens[2].data, TokenData::Keyword(Keyword::Case)); @@ -805,7 +805,7 @@ mod tests { fn check_variable_definition_tokens() { let s = &String::from("let a = 'hello';"); let mut lexer = Lexer::new(s); - lexer.lex().unwrap(); + lexer.lex().expect("failed to lex"); assert_eq!(lexer.tokens[0].data, TokenData::Keyword(Keyword::Let)); assert_eq!(lexer.tokens[1].data, TokenData::Identifier("a".to_string())); assert_eq!( @@ -823,7 +823,7 @@ mod tests { let s = &String::from("console.log(\"hello world\");"); // -------------------123456789 let mut lexer = Lexer::new(s); - lexer.lex().unwrap(); + lexer.lex().expect("failed to lex"); // The first column is 1 (not zero indexed) assert_eq!(lexer.tokens[0].pos.column_number, 1); assert_eq!(lexer.tokens[0].pos.line_number, 1); @@ -853,7 +853,7 @@ mod tests { // Here we want an example of decrementing an integer let s = &String::from("let a = b--;"); let mut lexer = Lexer::new(s); - lexer.lex().unwrap(); + lexer.lex().expect("failed to lex"); assert_eq!(lexer.tokens[4].data, TokenData::Punctuator(Punctuator::Dec)); // Decrementing means adding 2 characters '--', the lexer should consume it as a single token // and move the curser forward by 2, meaning the next token should be a semicolon @@ -866,7 +866,7 @@ mod tests { #[test] fn numbers() { let mut lexer = Lexer::new("1 2 0x34 056 7.89 42. 5e3 5e+3 5e-3 0b10 0O123 0999"); - lexer.lex().unwrap(); + lexer.lex().expect("failed to lex"); assert_eq!(lexer.tokens[0].data, TokenData::NumericLiteral(1.0)); assert_eq!(lexer.tokens[1].data, TokenData::NumericLiteral(2.0)); assert_eq!(lexer.tokens[2].data, TokenData::NumericLiteral(52.0)); @@ -884,14 +884,13 @@ mod tests { #[test] fn test_single_number_without_semicolon() { let mut lexer = Lexer::new("1"); - lexer.lex().unwrap(); - dbg!(lexer.tokens); + lexer.lex().expect("failed to lex"); } #[test] fn test_number_followed_by_dot() { let mut lexer = Lexer::new("1.."); - lexer.lex().unwrap(); + lexer.lex().expect("failed to lex"); assert_eq!(lexer.tokens[0].data, TokenData::NumericLiteral(1.0)); assert_eq!(lexer.tokens[1].data, TokenData::Punctuator(Punctuator::Dot)); } diff --git a/src/lib/syntax/parser.rs b/src/lib/syntax/parser.rs index f7616332d4..c5542dadc4 100644 --- a/src/lib/syntax/parser.rs +++ b/src/lib/syntax/parser.rs @@ -54,14 +54,14 @@ impl Parser { exprs.push(result); } - // In the case of `BlockExpr` the Positions seem unnecessary + // In the case of `Block` the Positions seem unnecessary // TODO: refactor this or the `mk!` perhaps? - Ok(Expr::new(ExprDef::BlockExpr(exprs))) + Ok(Expr::new(ExprDef::Block(exprs))) } fn get_token(&self, pos: usize) -> Result { if pos < self.tokens.len() { - Ok(self.tokens[pos].clone()) + Ok(self.tokens.get(pos).expect("failed getting token").clone()) } else { Err(ParseError::AbruptEnd) } @@ -71,7 +71,7 @@ impl Parser { match keyword { Keyword::Throw => { let thrown = self.parse()?; - Ok(mk!(self, ExprDef::ThrowExpr(Box::new(thrown)))) + Ok(mk!(self, ExprDef::Throw(Box::new(thrown)))) } // vars, lets and consts are similar in parsing structure, we can group them together Keyword::Var | Keyword::Let => { @@ -124,8 +124,8 @@ impl Parser { } match keyword { - Keyword::Let => Ok(Expr::new(ExprDef::LetDeclExpr(vars))), - _ => Ok(Expr::new(ExprDef::VarDeclExpr(vars))), + Keyword::Let => Ok(Expr::new(ExprDef::LetDecl(vars))), + _ => Ok(Expr::new(ExprDef::VarDecl(vars))), } } Keyword::Const => { @@ -174,23 +174,22 @@ impl Parser { } } - Ok(Expr::new(ExprDef::ConstDeclExpr(vars))) + Ok(Expr::new(ExprDef::ConstDecl(vars))) } Keyword::Return => Ok(mk!( self, - ExprDef::ReturnExpr(Some(Box::new(self.parse()?.clone()))) + ExprDef::Return(Some(Box::new(self.parse()?.clone()))) )), Keyword::New => { let call = self.parse()?; match call.def { - ExprDef::CallExpr(ref func, ref args) => Ok(mk!( - self, - ExprDef::ConstructExpr(func.clone(), args.clone()) - )), + ExprDef::Call(ref func, ref args) => { + Ok(mk!(self, ExprDef::Construct(func.clone(), args.clone()))) + } _ => Err(ParseError::ExpectedExpr("constructor", call)), } } - Keyword::TypeOf => Ok(mk!(self, ExprDef::TypeOfExpr(Box::new(self.parse()?)))), + Keyword::TypeOf => Ok(mk!(self, ExprDef::TypeOf(Box::new(self.parse()?)))), Keyword::If => { self.expect_punc(Punctuator::OpenParen, "if block")?; let cond = self.parse()?; @@ -199,7 +198,7 @@ impl Parser { let next = self.get_token(self.pos); Ok(mk!( self, - ExprDef::IfExpr( + ExprDef::If( Box::new(cond), Box::new(expr), if next.is_ok() && next.unwrap().data == TokenData::Keyword(Keyword::Else) { @@ -218,7 +217,7 @@ impl Parser { let expr = self.parse()?; Ok(mk!( self, - ExprDef::WhileLoopExpr(Box::new(cond), Box::new(expr)) + ExprDef::WhileLoop(Box::new(cond), Box::new(expr)) )) } Keyword::Switch => { @@ -257,7 +256,7 @@ impl Parser { _ => block.push(self.parse()?), } } - default = Some(mk!(self, ExprDef::BlockExpr(block))); + default = Some(mk!(self, ExprDef::Block(block))); } TokenData::Punctuator(Punctuator::CloseBlock) => break, _ => { @@ -276,7 +275,7 @@ impl Parser { self.expect_punc(Punctuator::CloseBlock, "switch block")?; Ok(mk!( self, - ExprDef::SwitchExpr( + ExprDef::Switch( Box::new(value.unwrap()), cases, match default { @@ -328,7 +327,7 @@ impl Parser { let block = self.parse()?; Ok(mk!( self, - ExprDef::FunctionDeclExpr(name, args, Box::new(block)) + ExprDef::FunctionDecl(name, args, Box::new(block)) )) } _ => Err(ParseError::UnexpectedKeyword(keyword)), @@ -349,16 +348,16 @@ impl Parser { self.parse()? } TokenData::Punctuator(Punctuator::Semicolon) | TokenData::Comment(_) => { - mk!(self, ExprDef::ConstExpr(Const::Undefined)) + mk!(self, ExprDef::Const(Const::Undefined)) } - TokenData::NumericLiteral(num) => mk!(self, ExprDef::ConstExpr(Const::Num(num))), - TokenData::NullLiteral => mk!(self, ExprDef::ConstExpr(Const::Null)), - TokenData::StringLiteral(text) => mk!(self, ExprDef::ConstExpr(Const::String(text))), - TokenData::BooleanLiteral(val) => mk!(self, ExprDef::ConstExpr(Const::Bool(val))), + TokenData::NumericLiteral(num) => mk!(self, ExprDef::Const(Const::Num(num))), + TokenData::NullLiteral => mk!(self, ExprDef::Const(Const::Null)), + TokenData::StringLiteral(text) => mk!(self, ExprDef::Const(Const::String(text))), + TokenData::BooleanLiteral(val) => mk!(self, ExprDef::Const(Const::Bool(val))), TokenData::Identifier(ref s) if s == "undefined" => { - mk!(self, ExprDef::ConstExpr(Const::Undefined)) + mk!(self, ExprDef::Const(Const::Undefined)) } - TokenData::Identifier(s) => mk!(self, ExprDef::LocalExpr(s)), + TokenData::Identifier(s) => mk!(self, ExprDef::Local(s)), TokenData::Keyword(keyword) => self.parse_struct(keyword)?, TokenData::Punctuator(Punctuator::OpenParen) => { match self.get_token(self.pos)?.data { @@ -370,7 +369,7 @@ impl Parser { let expr = self.parse()?; mk!( self, - ExprDef::ArrowFunctionDeclExpr(Vec::new(), Box::new(expr)), + ExprDef::ArrowFunctionDecl(Vec::new(), Box::new(expr)), token ) } @@ -384,7 +383,7 @@ impl Parser { // at this point it's probably gonna be an arrow function let mut args = vec![ match next.def { - ExprDef::LocalExpr(ref name) => (*name).clone(), + ExprDef::Local(ref name) => (*name).clone(), _ => "".to_string(), }, match self.get_token(self.pos)?.data { @@ -436,7 +435,7 @@ impl Parser { let expr = self.parse()?; mk!( self, - ExprDef::ArrowFunctionDeclExpr(args, Box::new(expr)), + ExprDef::ArrowFunctionDecl(args, Box::new(expr)), token ) } @@ -464,7 +463,7 @@ impl Parser { TokenData::Punctuator(Punctuator::Comma) => { if !saw_expr_last { // An elision indicates that a space is saved in the array - array.push(mk!(self, ExprDef::ConstExpr(Const::Undefined))) + array.push(mk!(self, ExprDef::Const(Const::Undefined))) } saw_expr_last = false; self.pos += 1; @@ -487,18 +486,14 @@ impl Parser { } } } - mk!(self, ExprDef::ArrayDeclExpr(array), token) + mk!(self, ExprDef::ArrayDecl(array), token) } TokenData::Punctuator(Punctuator::OpenBlock) if self.get_token(self.pos)?.data == TokenData::Punctuator(Punctuator::CloseBlock) => { self.pos += 1; - mk!( - self, - ExprDef::ObjectDeclExpr(Box::new(BTreeMap::new())), - token - ) + mk!(self, ExprDef::ObjectDecl(Box::new(BTreeMap::new())), token) } TokenData::Punctuator(Punctuator::OpenBlock) if self.get_token(self.pos + 1)?.data @@ -532,7 +527,7 @@ impl Parser { map.insert(name, value); self.pos += 1; } - mk!(self, ExprDef::ObjectDeclExpr(map), token) + mk!(self, ExprDef::ObjectDecl(map), token) } TokenData::Punctuator(Punctuator::OpenBlock) => { let mut exprs = Vec::new(); @@ -546,27 +541,27 @@ impl Parser { } } self.pos += 1; - mk!(self, ExprDef::BlockExpr(exprs), token) + mk!(self, ExprDef::Block(exprs), token) } TokenData::Punctuator(Punctuator::Sub) => mk!( self, - ExprDef::UnaryOpExpr(UnaryOp::Minus, Box::new(self.parse()?)) + ExprDef::UnaryOp(UnaryOp::Minus, Box::new(self.parse()?)) ), TokenData::Punctuator(Punctuator::Add) => mk!( self, - ExprDef::UnaryOpExpr(UnaryOp::Plus, Box::new(self.parse()?)) + ExprDef::UnaryOp(UnaryOp::Plus, Box::new(self.parse()?)) ), TokenData::Punctuator(Punctuator::Not) => mk!( self, - ExprDef::UnaryOpExpr(UnaryOp::Not, Box::new(self.parse()?)) + ExprDef::UnaryOp(UnaryOp::Not, Box::new(self.parse()?)) ), TokenData::Punctuator(Punctuator::Inc) => mk!( self, - ExprDef::UnaryOpExpr(UnaryOp::IncrementPre, Box::new(self.parse()?)) + ExprDef::UnaryOp(UnaryOp::IncrementPre, Box::new(self.parse()?)) ), TokenData::Punctuator(Punctuator::Dec) => mk!( self, - ExprDef::UnaryOpExpr(UnaryOp::DecrementPre, Box::new(self.parse()?)) + ExprDef::UnaryOp(UnaryOp::DecrementPre, Box::new(self.parse()?)) ), _ => return Err(ParseError::Expected(Vec::new(), token.clone(), "script")), }; @@ -587,10 +582,7 @@ impl Parser { let tk = self.get_token(self.pos)?; match tk.data { TokenData::Identifier(ref s) => { - result = mk!( - self, - ExprDef::GetConstFieldExpr(Box::new(expr), s.to_string()) - ) + result = mk!(self, ExprDef::GetConstField(Box::new(expr), s.to_string())) } _ => { return Err(ParseError::Expected( @@ -634,7 +626,7 @@ impl Parser { expect_comma_or_end = true; } } - result = mk!(self, ExprDef::CallExpr(Box::new(expr), args)); + result = mk!(self, ExprDef::Call(Box::new(expr), args)); } TokenData::Punctuator(Punctuator::Question) => { self.pos += 1; @@ -643,7 +635,7 @@ impl Parser { let else_e = self.parse()?; result = mk!( self, - ExprDef::IfExpr(Box::new(expr), Box::new(if_e), Some(Box::new(else_e))) + ExprDef::If(Box::new(expr), Box::new(if_e), Some(Box::new(else_e))) ); } TokenData::Punctuator(Punctuator::OpenBracket) => { @@ -653,7 +645,7 @@ impl Parser { TokenData::Punctuator(Punctuator::CloseBracket), "array index", )?; - result = mk!(self, ExprDef::GetFieldExpr(Box::new(expr), Box::new(index))); + result = mk!(self, ExprDef::GetField(Box::new(expr), Box::new(index))); } TokenData::Punctuator(Punctuator::Semicolon) | TokenData::Comment(_) => { self.pos += 1; @@ -661,17 +653,17 @@ impl Parser { TokenData::Punctuator(Punctuator::Assign) => { self.pos += 1; let next = self.parse()?; - result = mk!(self, ExprDef::AssignExpr(Box::new(expr), Box::new(next))); + result = mk!(self, ExprDef::Assign(Box::new(expr), Box::new(next))); } TokenData::Punctuator(Punctuator::Arrow) => { self.pos += 1; let mut args = Vec::with_capacity(1); match result.def { - ExprDef::LocalExpr(ref name) => args.push((*name).clone()), + ExprDef::Local(ref name) => args.push((*name).clone()), _ => return Err(ParseError::ExpectedExpr("identifier", result)), } let next = self.parse()?; - result = mk!(self, ExprDef::ArrowFunctionDeclExpr(args, Box::new(next))); + result = mk!(self, ExprDef::ArrowFunctionDecl(args, Box::new(next))); } TokenData::Punctuator(Punctuator::Add) => { result = self.binop(BinOp::Num(NumOp::Add), expr)? @@ -736,13 +728,13 @@ impl Parser { TokenData::Punctuator(Punctuator::Inc) => { result = mk!( self, - ExprDef::UnaryOpExpr(UnaryOp::IncrementPost, Box::new(self.parse()?)) + ExprDef::UnaryOp(UnaryOp::IncrementPost, Box::new(self.parse()?)) ) } TokenData::Punctuator(Punctuator::Dec) => { result = mk!( self, - ExprDef::UnaryOpExpr(UnaryOp::DecrementPost, Box::new(self.parse()?)) + ExprDef::UnaryOp(UnaryOp::DecrementPost, Box::new(self.parse()?)) ) } _ => carry_on = false, @@ -759,28 +751,28 @@ impl Parser { self.pos += 1; let next = self.parse()?; Ok(match next.def { - ExprDef::BinOpExpr(ref op2, ref a, ref b) => { + ExprDef::BinOp(ref op2, ref a, ref b) => { let other_precedence = op2.get_precedence(); if precedence < other_precedence || (precedence == other_precedence && !assoc) { mk!( self, - ExprDef::BinOpExpr( + ExprDef::BinOp( op2.clone(), b.clone(), Box::new(mk!( self, - ExprDef::BinOpExpr(op.clone(), Box::new(orig), a.clone()) + ExprDef::BinOp(op.clone(), Box::new(orig), a.clone()) )) ) ) } else { mk!( self, - ExprDef::BinOpExpr(op, Box::new(orig), Box::new(next.clone())) + ExprDef::BinOp(op, Box::new(orig), Box::new(next.clone())) ) } } - _ => mk!(self, ExprDef::BinOpExpr(op, Box::new(orig), Box::new(next))), + _ => mk!(self, ExprDef::BinOp(op, Box::new(orig), Box::new(next))), }) } @@ -812,17 +804,17 @@ mod tests { fn check_parser(js: &str, expr: &[Expr]) { let mut lexer = Lexer::new(js); - lexer.lex().unwrap(); + lexer.lex().expect("failed to lex"); assert_eq!( Parser::new(lexer.tokens).parse_all().unwrap(), - Expr::new(ExprDef::BlockExpr(expr.into())) + Expr::new(ExprDef::Block(expr.into())) ); } fn check_invalid(js: &str) { let mut lexer = Lexer::new(js); - lexer.lex().unwrap(); + lexer.lex().expect("failed to lex"); assert!(Parser::new(lexer.tokens).parse_all().is_err()); } @@ -834,13 +826,13 @@ mod tests { // Check empty string check_parser( "\"\"", - &[Expr::new(ExprDef::ConstExpr(Const::String(String::new())))], + &[Expr::new(ExprDef::Const(Const::String(String::new())))], ); // Check non-empty string check_parser( "\"hello\"", - &[Expr::new(ExprDef::ConstExpr(Const::String(String::from( + &[Expr::new(ExprDef::Const(Const::String(String::from( "hello", ))))], ); @@ -851,76 +843,76 @@ mod tests { use crate::syntax::ast::constant::Const; // Check empty array - check_parser("[]", &[Expr::new(ExprDef::ArrayDeclExpr(vec![]))]); + check_parser("[]", &[Expr::new(ExprDef::ArrayDecl(vec![]))]); // Check array with empty slot check_parser( "[,]", - &[Expr::new(ExprDef::ArrayDeclExpr(vec![Expr::new( - ExprDef::ConstExpr(Const::Undefined), + &[Expr::new(ExprDef::ArrayDecl(vec![Expr::new( + ExprDef::Const(Const::Undefined), )]))], ); // Check numeric array check_parser( "[1, 2, 3]", - &[Expr::new(ExprDef::ArrayDeclExpr(vec![ - Expr::new(ExprDef::ConstExpr(Const::Num(1.0))), - Expr::new(ExprDef::ConstExpr(Const::Num(2.0))), - Expr::new(ExprDef::ConstExpr(Const::Num(3.0))), + &[Expr::new(ExprDef::ArrayDecl(vec![ + Expr::new(ExprDef::Const(Const::Num(1.0))), + Expr::new(ExprDef::Const(Const::Num(2.0))), + Expr::new(ExprDef::Const(Const::Num(3.0))), ]))], ); // Check numeric array with trailing comma check_parser( "[1, 2, 3,]", - &[Expr::new(ExprDef::ArrayDeclExpr(vec![ - Expr::new(ExprDef::ConstExpr(Const::Num(1.0))), - Expr::new(ExprDef::ConstExpr(Const::Num(2.0))), - Expr::new(ExprDef::ConstExpr(Const::Num(3.0))), + &[Expr::new(ExprDef::ArrayDecl(vec![ + Expr::new(ExprDef::Const(Const::Num(1.0))), + Expr::new(ExprDef::Const(Const::Num(2.0))), + Expr::new(ExprDef::Const(Const::Num(3.0))), ]))], ); // Check numeric array with an elision check_parser( "[1, 2, , 3]", - &[Expr::new(ExprDef::ArrayDeclExpr(vec![ - Expr::new(ExprDef::ConstExpr(Const::Num(1.0))), - Expr::new(ExprDef::ConstExpr(Const::Num(2.0))), - Expr::new(ExprDef::ConstExpr(Const::Undefined)), - Expr::new(ExprDef::ConstExpr(Const::Num(3.0))), + &[Expr::new(ExprDef::ArrayDecl(vec![ + Expr::new(ExprDef::Const(Const::Num(1.0))), + Expr::new(ExprDef::Const(Const::Num(2.0))), + Expr::new(ExprDef::Const(Const::Undefined)), + Expr::new(ExprDef::Const(Const::Num(3.0))), ]))], ); // Check numeric array with repeated elision check_parser( "[1, 2, ,, 3]", - &[Expr::new(ExprDef::ArrayDeclExpr(vec![ - Expr::new(ExprDef::ConstExpr(Const::Num(1.0))), - Expr::new(ExprDef::ConstExpr(Const::Num(2.0))), - Expr::new(ExprDef::ConstExpr(Const::Undefined)), - Expr::new(ExprDef::ConstExpr(Const::Undefined)), - Expr::new(ExprDef::ConstExpr(Const::Num(3.0))), + &[Expr::new(ExprDef::ArrayDecl(vec![ + Expr::new(ExprDef::Const(Const::Num(1.0))), + Expr::new(ExprDef::Const(Const::Num(2.0))), + Expr::new(ExprDef::Const(Const::Undefined)), + Expr::new(ExprDef::Const(Const::Undefined)), + Expr::new(ExprDef::Const(Const::Num(3.0))), ]))], ); // Check combined array check_parser( "[1, \"a\", 2]", - &[Expr::new(ExprDef::ArrayDeclExpr(vec![ - Expr::new(ExprDef::ConstExpr(Const::Num(1.0))), - Expr::new(ExprDef::ConstExpr(Const::String(String::from("a")))), - Expr::new(ExprDef::ConstExpr(Const::Num(2.0))), + &[Expr::new(ExprDef::ArrayDecl(vec![ + Expr::new(ExprDef::Const(Const::Num(1.0))), + Expr::new(ExprDef::Const(Const::String(String::from("a")))), + Expr::new(ExprDef::Const(Const::Num(2.0))), ]))], ); // Check combined array with empty string check_parser( "[1, \"\", 2]", - &[Expr::new(ExprDef::ArrayDeclExpr(vec![ - Expr::new(ExprDef::ConstExpr(Const::Num(1.0))), - Expr::new(ExprDef::ConstExpr(Const::String(String::new()))), - Expr::new(ExprDef::ConstExpr(Const::Num(2.0))), + &[Expr::new(ExprDef::ArrayDecl(vec![ + Expr::new(ExprDef::Const(Const::Num(1.0))), + Expr::new(ExprDef::Const(Const::String(String::new()))), + Expr::new(ExprDef::Const(Const::Num(2.0))), ]))], ); } @@ -932,42 +924,39 @@ mod tests { // Check `var` declaration check_parser( "var a = 5;", - &[Expr::new(ExprDef::VarDeclExpr(vec![( + &[Expr::new(ExprDef::VarDecl(vec![( String::from("a"), - Some(Expr::new(ExprDef::ConstExpr(Const::Num(5.0)))), + Some(Expr::new(ExprDef::Const(Const::Num(5.0)))), )]))], ); // Check `var` declaration with no spaces check_parser( "var a=5;", - &[Expr::new(ExprDef::VarDeclExpr(vec![( + &[Expr::new(ExprDef::VarDecl(vec![( String::from("a"), - Some(Expr::new(ExprDef::ConstExpr(Const::Num(5.0)))), + Some(Expr::new(ExprDef::Const(Const::Num(5.0)))), )]))], ); // Check empty `var` declaration check_parser( "var a;", - &[Expr::new(ExprDef::VarDeclExpr(vec![( - String::from("a"), - None, - )]))], + &[Expr::new(ExprDef::VarDecl(vec![(String::from("a"), None)]))], ); // Check multiple `var` declaration check_parser( "var a = 5, b, c = 6;", - &[Expr::new(ExprDef::VarDeclExpr(vec![ + &[Expr::new(ExprDef::VarDecl(vec![ ( String::from("a"), - Some(Expr::new(ExprDef::ConstExpr(Const::Num(5.0)))), + Some(Expr::new(ExprDef::Const(Const::Num(5.0)))), ), (String::from("b"), None), ( String::from("c"), - Some(Expr::new(ExprDef::ConstExpr(Const::Num(6.0)))), + Some(Expr::new(ExprDef::Const(Const::Num(6.0)))), ), ]))], ); @@ -975,42 +964,39 @@ mod tests { // Check `let` declaration check_parser( "let a = 5;", - &[Expr::new(ExprDef::LetDeclExpr(vec![( + &[Expr::new(ExprDef::LetDecl(vec![( String::from("a"), - Some(Expr::new(ExprDef::ConstExpr(Const::Num(5.0)))), + Some(Expr::new(ExprDef::Const(Const::Num(5.0)))), )]))], ); // Check `let` declaration with no spaces check_parser( "let a=5;", - &[Expr::new(ExprDef::LetDeclExpr(vec![( + &[Expr::new(ExprDef::LetDecl(vec![( String::from("a"), - Some(Expr::new(ExprDef::ConstExpr(Const::Num(5.0)))), + Some(Expr::new(ExprDef::Const(Const::Num(5.0)))), )]))], ); // Check empty `let` declaration check_parser( "let a;", - &[Expr::new(ExprDef::LetDeclExpr(vec![( - String::from("a"), - None, - )]))], + &[Expr::new(ExprDef::LetDecl(vec![(String::from("a"), None)]))], ); // Check multiple `let` declaration check_parser( "let a = 5, b, c = 6;", - &[Expr::new(ExprDef::LetDeclExpr(vec![ + &[Expr::new(ExprDef::LetDecl(vec![ ( String::from("a"), - Some(Expr::new(ExprDef::ConstExpr(Const::Num(5.0)))), + Some(Expr::new(ExprDef::Const(Const::Num(5.0)))), ), (String::from("b"), None), ( String::from("c"), - Some(Expr::new(ExprDef::ConstExpr(Const::Num(6.0)))), + Some(Expr::new(ExprDef::Const(Const::Num(6.0)))), ), ]))], ); @@ -1018,18 +1004,18 @@ mod tests { // Check `const` declaration check_parser( "const a = 5;", - &[Expr::new(ExprDef::ConstDeclExpr(vec![( + &[Expr::new(ExprDef::ConstDecl(vec![( String::from("a"), - Expr::new(ExprDef::ConstExpr(Const::Num(5.0))), + Expr::new(ExprDef::Const(Const::Num(5.0))), )]))], ); // Check `const` declaration with no spaces check_parser( "const a=5;", - &[Expr::new(ExprDef::ConstDeclExpr(vec![( + &[Expr::new(ExprDef::ConstDecl(vec![( String::from("a"), - Expr::new(ExprDef::ConstExpr(Const::Num(5.0))), + Expr::new(ExprDef::Const(Const::Num(5.0))), )]))], ); @@ -1039,14 +1025,14 @@ mod tests { // Check multiple `const` declaration check_parser( "const a = 5, c = 6;", - &[Expr::new(ExprDef::ConstDeclExpr(vec![ + &[Expr::new(ExprDef::ConstDecl(vec![ ( String::from("a"), - Expr::new(ExprDef::ConstExpr(Const::Num(5.0))), + Expr::new(ExprDef::Const(Const::Num(5.0))), ), ( String::from("c"), - Expr::new(ExprDef::ConstExpr(Const::Num(6.0))), + Expr::new(ExprDef::Const(Const::Num(6.0))), ), ]))], ); @@ -1057,7 +1043,7 @@ mod tests { use crate::syntax::ast::{constant::Const, op::BinOp}; fn create_bin_op(op: BinOp, exp1: Expr, exp2: Expr) -> Expr { - Expr::new(ExprDef::BinOpExpr(op, Box::new(exp1), Box::new(exp2))) + Expr::new(ExprDef::BinOp(op, Box::new(exp1), Box::new(exp2))) } // Check numeric operations @@ -1065,80 +1051,80 @@ mod tests { "a + b", &[create_bin_op( BinOp::Num(NumOp::Add), - Expr::new(ExprDef::LocalExpr(String::from("a"))), - Expr::new(ExprDef::LocalExpr(String::from("b"))), + Expr::new(ExprDef::Local(String::from("a"))), + Expr::new(ExprDef::Local(String::from("b"))), )], ); check_parser( "a+1", &[create_bin_op( BinOp::Num(NumOp::Add), - Expr::new(ExprDef::LocalExpr(String::from("a"))), - Expr::new(ExprDef::ConstExpr(Const::Num(1.0))), + Expr::new(ExprDef::Local(String::from("a"))), + Expr::new(ExprDef::Const(Const::Num(1.0))), )], ); check_parser( "a - b", &[create_bin_op( BinOp::Num(NumOp::Sub), - Expr::new(ExprDef::LocalExpr(String::from("a"))), - Expr::new(ExprDef::LocalExpr(String::from("b"))), + Expr::new(ExprDef::Local(String::from("a"))), + Expr::new(ExprDef::Local(String::from("b"))), )], ); check_parser( "a-1", &[create_bin_op( BinOp::Num(NumOp::Sub), - Expr::new(ExprDef::LocalExpr(String::from("a"))), - Expr::new(ExprDef::ConstExpr(Const::Num(1.0))), + Expr::new(ExprDef::Local(String::from("a"))), + Expr::new(ExprDef::Const(Const::Num(1.0))), )], ); check_parser( "a / b", &[create_bin_op( BinOp::Num(NumOp::Div), - Expr::new(ExprDef::LocalExpr(String::from("a"))), - Expr::new(ExprDef::LocalExpr(String::from("b"))), + Expr::new(ExprDef::Local(String::from("a"))), + Expr::new(ExprDef::Local(String::from("b"))), )], ); check_parser( "a/2", &[create_bin_op( BinOp::Num(NumOp::Div), - Expr::new(ExprDef::LocalExpr(String::from("a"))), - Expr::new(ExprDef::ConstExpr(Const::Num(2.0))), + Expr::new(ExprDef::Local(String::from("a"))), + Expr::new(ExprDef::Const(Const::Num(2.0))), )], ); check_parser( "a * b", &[create_bin_op( BinOp::Num(NumOp::Mul), - Expr::new(ExprDef::LocalExpr(String::from("a"))), - Expr::new(ExprDef::LocalExpr(String::from("b"))), + Expr::new(ExprDef::Local(String::from("a"))), + Expr::new(ExprDef::Local(String::from("b"))), )], ); check_parser( "a*2", &[create_bin_op( BinOp::Num(NumOp::Mul), - Expr::new(ExprDef::LocalExpr(String::from("a"))), - Expr::new(ExprDef::ConstExpr(Const::Num(2.0))), + Expr::new(ExprDef::Local(String::from("a"))), + Expr::new(ExprDef::Const(Const::Num(2.0))), )], ); check_parser( "a % b", &[create_bin_op( BinOp::Num(NumOp::Mod), - Expr::new(ExprDef::LocalExpr(String::from("a"))), - Expr::new(ExprDef::LocalExpr(String::from("b"))), + Expr::new(ExprDef::Local(String::from("a"))), + Expr::new(ExprDef::Local(String::from("b"))), )], ); check_parser( "a%2", &[create_bin_op( BinOp::Num(NumOp::Mod), - Expr::new(ExprDef::LocalExpr(String::from("a"))), - Expr::new(ExprDef::ConstExpr(Const::Num(2.0))), + Expr::new(ExprDef::Local(String::from("a"))), + Expr::new(ExprDef::Const(Const::Num(2.0))), )], ); @@ -1147,18 +1133,18 @@ mod tests { "a + d*(b-3)+1", &[create_bin_op( BinOp::Num(NumOp::Add), - Expr::new(ExprDef::LocalExpr(String::from("a"))), + Expr::new(ExprDef::Local(String::from("a"))), create_bin_op( BinOp::Num(NumOp::Add), // FIXME: shouldn't the last addition be on the right? - Expr::new(ExprDef::ConstExpr(Const::Num(1.0))), + Expr::new(ExprDef::Const(Const::Num(1.0))), create_bin_op( BinOp::Num(NumOp::Mul), - Expr::new(ExprDef::LocalExpr(String::from("d"))), + Expr::new(ExprDef::Local(String::from("d"))), create_bin_op( BinOp::Num(NumOp::Sub), - Expr::new(ExprDef::LocalExpr(String::from("b"))), - Expr::new(ExprDef::ConstExpr(Const::Num(3.0))), + Expr::new(ExprDef::Local(String::from("b"))), + Expr::new(ExprDef::Const(Const::Num(3.0))), ), ), ), @@ -1170,16 +1156,16 @@ mod tests { "a & b", &[create_bin_op( BinOp::Bit(BitOp::And), - Expr::new(ExprDef::LocalExpr(String::from("a"))), - Expr::new(ExprDef::LocalExpr(String::from("b"))), + Expr::new(ExprDef::Local(String::from("a"))), + Expr::new(ExprDef::Local(String::from("b"))), )], ); check_parser( "a&b", &[create_bin_op( BinOp::Bit(BitOp::And), - Expr::new(ExprDef::LocalExpr(String::from("a"))), - Expr::new(ExprDef::LocalExpr(String::from("b"))), + Expr::new(ExprDef::Local(String::from("a"))), + Expr::new(ExprDef::Local(String::from("b"))), )], ); @@ -1187,16 +1173,16 @@ mod tests { "a | b", &[create_bin_op( BinOp::Bit(BitOp::Or), - Expr::new(ExprDef::LocalExpr(String::from("a"))), - Expr::new(ExprDef::LocalExpr(String::from("b"))), + Expr::new(ExprDef::Local(String::from("a"))), + Expr::new(ExprDef::Local(String::from("b"))), )], ); check_parser( "a|b", &[create_bin_op( BinOp::Bit(BitOp::Or), - Expr::new(ExprDef::LocalExpr(String::from("a"))), - Expr::new(ExprDef::LocalExpr(String::from("b"))), + Expr::new(ExprDef::Local(String::from("a"))), + Expr::new(ExprDef::Local(String::from("b"))), )], ); @@ -1204,16 +1190,16 @@ mod tests { "a ^ b", &[create_bin_op( BinOp::Bit(BitOp::Xor), - Expr::new(ExprDef::LocalExpr(String::from("a"))), - Expr::new(ExprDef::LocalExpr(String::from("b"))), + Expr::new(ExprDef::Local(String::from("a"))), + Expr::new(ExprDef::Local(String::from("b"))), )], ); check_parser( "a^b", &[create_bin_op( BinOp::Bit(BitOp::Xor), - Expr::new(ExprDef::LocalExpr(String::from("a"))), - Expr::new(ExprDef::LocalExpr(String::from("b"))), + Expr::new(ExprDef::Local(String::from("a"))), + Expr::new(ExprDef::Local(String::from("b"))), )], ); @@ -1221,16 +1207,16 @@ mod tests { "a << b", &[create_bin_op( BinOp::Bit(BitOp::Shl), - Expr::new(ExprDef::LocalExpr(String::from("a"))), - Expr::new(ExprDef::LocalExpr(String::from("b"))), + Expr::new(ExprDef::Local(String::from("a"))), + Expr::new(ExprDef::Local(String::from("b"))), )], ); check_parser( "a<> b", &[create_bin_op( BinOp::Bit(BitOp::Shr), - Expr::new(ExprDef::LocalExpr(String::from("a"))), - Expr::new(ExprDef::LocalExpr(String::from("b"))), + Expr::new(ExprDef::Local(String::from("a"))), + Expr::new(ExprDef::Local(String::from("b"))), )], ); check_parser( "a>>b", &[create_bin_op( BinOp::Bit(BitOp::Shr), - Expr::new(ExprDef::LocalExpr(String::from("a"))), - Expr::new(ExprDef::LocalExpr(String::from("b"))), + Expr::new(ExprDef::Local(String::from("a"))), + Expr::new(ExprDef::Local(String::from("b"))), )], ); }