diff --git a/src/ast/mod.rs b/src/ast/mod.rs index dfc8521..9f229d7 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -125,18 +125,18 @@ pub enum TokenType { #[derive(Debug, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)] pub struct Token { pub typ: TokenType, - pub fragment: String, + pub fragment: Rc, pub pos: Position, } impl Token { /// Constructs a new Token with a type and line and column information. - pub fn new, P: Into>(f: S, typ: TokenType, p: P) -> Self { + pub fn new>, P: Into>(f: S, typ: TokenType, p: P) -> Self { Self::new_with_pos(f, typ, p.into()) } // Constructs a new Token with a type and a Position. - pub fn new_with_pos>(f: S, typ: TokenType, pos: Position) -> Self { + pub fn new_with_pos>>(f: S, typ: TokenType, pos: Position) -> Self { Token { typ, fragment: f.into(), @@ -241,8 +241,8 @@ pub enum Value { Boolean(PositionedItem), Int(PositionedItem), Float(PositionedItem), - Str(PositionedItem), - Symbol(PositionedItem), + Str(PositionedItem>), + Symbol(PositionedItem>), Tuple(PositionedItem), List(ListDef), } @@ -250,7 +250,7 @@ pub enum Value { #[derive(PartialEq, Debug, Clone)] pub enum ImportShape { Resolved(Position, TupleShape), - Unresolved(PositionedItem), + Unresolved(PositionedItem>), } #[derive(PartialEq, Debug, Clone)] @@ -281,15 +281,15 @@ pub enum Shape { Boolean(PositionedItem), Int(PositionedItem), Float(PositionedItem), - Str(PositionedItem), + Str(PositionedItem>), Tuple(PositionedItem), List(NarrowedShape), Func(FuncShapeDef), Module(ModuleShape), - Hole(PositionedItem), // A type hole We don't know what this type is yet. - Narrowed(NarrowedShape), // A narrowed type. We know *some* of the possible options. - Import(ImportShape), // A type hole We don't know what this type is yet. - TypeErr(Position, String), // A type hole We don't know what this type is yet. + Hole(PositionedItem>), // A type hole We don't know what this type is yet. + Narrowed(NarrowedShape), // A narrowed type. We know *some* of the possible options. + Import(ImportShape), // A type hole We don't know what this type is yet. + TypeErr(Position, String), // A type hole We don't know what this type is yet. } impl Shape { @@ -327,7 +327,12 @@ impl Shape { } } - fn narrow_tuple_shapes(&self, left_slist: &PositionedItem>, right_slist: &PositionedItem>, right: &Shape) -> Shape { + fn narrow_tuple_shapes( + &self, + left_slist: &PositionedItem>, + right_slist: &PositionedItem>, + right: &Shape, + ) -> Shape { let left_iter = left_slist.val.iter(); let right_iter = right_slist.val.iter(); if is_tuple_subset(left_iter, right_slist) { @@ -542,7 +547,7 @@ impl Value { ) } - fn derive_shape(&self, symbol_table: &mut BTreeMap) -> Shape { + fn derive_shape(&self, symbol_table: &mut BTreeMap, Shape>) -> Shape { let shape = match self { Value::Empty(p) => Shape::Empty(p.clone()), Value::Boolean(p) => Shape::Boolean(p.clone()), @@ -690,8 +695,8 @@ impl<'a> From<&'a Token> for PositionedItem { } } -impl<'a> From<&'a PositionedItem> for PositionedItem { - fn from(t: &PositionedItem) -> PositionedItem { +impl<'a> From<&'a PositionedItem>> for PositionedItem> { + fn from(t: &PositionedItem>) -> PositionedItem> { PositionedItem { pos: t.pos.clone(), val: t.val.clone(), @@ -705,7 +710,7 @@ impl<'a> From<&'a PositionedItem> for PositionedItem { #[derive(PartialEq, Debug, Clone)] pub struct FuncDef { pub scope: Option, - pub argdefs: Vec>, + pub argdefs: Vec>>, pub fields: Box, pub pos: Position, } @@ -713,7 +718,11 @@ pub struct FuncDef { impl FuncDef { fn derive_shape(&self) -> Shape { // 1. First set up our symbols. - let _table = self.argdefs.iter().map(|sym| (sym.val.clone(), Shape::Hole(sym.clone()))).collect::>(); + let _table = self + .argdefs + .iter() + .map(|sym| (sym.val.clone(), Shape::Hole(sym.clone()))) + .collect::, Shape>>(); // 2.Then determine the shapes of those symbols in our expression. // 3. Finally determine what the return shape can be. todo!(); @@ -983,11 +992,11 @@ impl Expression { } } - fn derive_shape(&self, symbol_table: &mut BTreeMap) -> Shape { + fn derive_shape(&self, symbol_table: &mut BTreeMap, Shape>) -> Shape { let shape = match self { Expression::Simple(v) => v.derive_shape(symbol_table), Expression::Format(def) => { - Shape::Str(PositionedItem::new("".to_owned(), def.pos.clone())) + Shape::Str(PositionedItem::new("".into(), def.pos.clone())) } Expression::Not(def) => derive_not_shape(def, symbol_table), Expression::Grouped(v, _pos) => v.as_ref().derive_shape(symbol_table), @@ -997,7 +1006,7 @@ impl Expression { )), Expression::Cast(def) => match def.cast_type { CastType::Int => Shape::Int(PositionedItem::new(0, def.pos.clone())), - CastType::Str => Shape::Str(PositionedItem::new("".to_owned(), def.pos.clone())), + CastType::Str => Shape::Str(PositionedItem::new("".into(), def.pos.clone())), CastType::Float => Shape::Float(PositionedItem::new(0.0, def.pos.clone())), CastType::Bool => Shape::Boolean(PositionedItem::new(true, def.pos.clone())), }, @@ -1040,7 +1049,7 @@ fn derive_include_shape( )) } -fn derive_not_shape(def: &NotDef, symbol_table: &mut BTreeMap) -> Shape { +fn derive_not_shape(def: &NotDef, symbol_table: &mut BTreeMap, Shape>) -> Shape { let shape = def.expr.as_ref().derive_shape(symbol_table); if let Shape::Boolean(b) = shape { Shape::Boolean(PositionedItem::new(!b.val, def.pos.clone())) @@ -1056,7 +1065,7 @@ fn derive_not_shape(def: &NotDef, symbol_table: &mut BTreeMap) -> } } -fn derive_copy_shape(def: &CopyDef, symbol_table: &mut BTreeMap) -> Shape { +fn derive_copy_shape(def: &CopyDef, symbol_table: &mut BTreeMap, Shape>) -> Shape { let base_shape = def.selector.derive_shape(symbol_table); match &base_shape { // TODO(jwall): Should we allow a stack of these? @@ -1113,7 +1122,7 @@ fn derive_copy_shape(def: &CopyDef, symbol_table: &mut BTreeMap) .fields .iter() .map(|(tok, expr)| (tok.fragment.clone(), expr.derive_shape(symbol_table))) - .collect::>(); + .collect::, Shape>>(); // 1. Do our copyable fields have the right names and shapes based on mdef.items. for (tok, shape) in mdef.items.iter() { if let Some(s) = arg_fields.get(&tok.fragment) { diff --git a/src/ast/rewrite.rs b/src/ast/rewrite.rs index 9153ba7..571ab65 100644 --- a/src/ast/rewrite.rs +++ b/src/ast/rewrite.rs @@ -31,9 +31,9 @@ impl Visitor for Rewriter { // Rewrite all paths except for stdlib paths to absolute. let main_separator = format!("{}", std::path::MAIN_SEPARATOR); if let Expression::Include(ref mut def) = expr { - let path = PathBuf::from(&def.path.fragment); + let path = PathBuf::from(def.path.fragment.as_ref()); if path.is_relative() { - def.path.fragment = self.base.join(path).to_string_lossy().to_string(); + def.path.fragment = self.base.join(path).to_string_lossy().to_string().into(); } } if let Expression::Import(ref mut def) = expr { @@ -48,7 +48,7 @@ impl Visitor for Rewriter { return; } if path.is_relative() { - def.path.fragment = self.base.join(path).to_string_lossy().to_string(); + def.path.fragment = self.base.join(path).to_string_lossy().to_string().into(); } } } diff --git a/src/ast/test.rs b/src/ast/test.rs index 26511af..2017376 100644 --- a/src/ast/test.rs +++ b/src/ast/test.rs @@ -46,11 +46,11 @@ fn derive_shape_values() { ), ( Value::Str(PositionedItem::new( - "foo".to_owned(), + "foo".into(), Position::new(0, 1, 2), )), Shape::Str(PositionedItem::new( - "foo".to_owned(), + "foo".into(), Position::new(0, 1, 2), )), ), @@ -103,7 +103,7 @@ fn derive_shape_expressions() { ), ( "\"foo {}\" % (1);", - Shape::Str(PositionedItem::new("".to_owned(), Position::new(0, 0, 0))), + Shape::Str(PositionedItem::new("".into(), Position::new(0, 0, 0))), ), ( "not true;", @@ -112,8 +112,8 @@ fn derive_shape_expressions() { ( "0:1;", Shape::List(NarrowedShape::new_with_pos( - vec![Shape::Int(PositionedItem::new(0, Position::new(0, 0, 0)))], - Position::new(0, 0, 0), + vec![Shape::Int(PositionedItem::new(0, Position::new(1, 1, 0)))], + Position::new(1, 1, 0), )), ), ( @@ -126,7 +126,7 @@ fn derive_shape_expressions() { ), ( "str(1);", - Shape::Str(PositionedItem::new("".to_owned(), Position::new(0, 0, 0))), + Shape::Str(PositionedItem::new("".into(), Position::new(0, 0, 0))), ), ( "bool(\"true\");", diff --git a/src/ast/typecheck/mod.rs b/src/ast/typecheck/mod.rs index 4f14801..d3efa5f 100644 --- a/src/ast/typecheck/mod.rs +++ b/src/ast/typecheck/mod.rs @@ -15,6 +15,7 @@ //! Implements typechecking for the parsed ucg AST. // FIXME(jwall): This probably just needs to disappear now. use std::collections::BTreeMap; +use std::rc::Rc; use crate::ast::walk::Visitor; use crate::ast::{Expression, FailDef, ImportDef, IncludeDef, Position, Shape, Statement, Value}; @@ -28,7 +29,7 @@ use Statement::Let; use Value::{Boolean, Empty, Float, Int, List, Str, Symbol, Tuple}; pub struct Checker { - symbol_table: BTreeMap, + symbol_table: BTreeMap, Shape>, err_stack: Vec, shape_stack: Vec, } @@ -46,7 +47,7 @@ impl Checker { self.shape_stack.pop() } - pub fn result(mut self) -> Result, BuildError> { + pub fn result(mut self) -> Result, Shape>, BuildError> { if let Some(err) = self.err_stack.pop() { Err(err) } else { diff --git a/src/ast/typecheck/test.rs b/src/ast/typecheck/test.rs index f867f3a..2b1fb9d 100644 --- a/src/ast/typecheck/test.rs +++ b/src/ast/typecheck/test.rs @@ -45,7 +45,7 @@ fn simple_binary_typecheck() { ); assert_type_success!( "\"\" + \"\";", - Shape::Str(PositionedItem::new(String::new(), Position::new(1, 1, 0))) + Shape::Str(PositionedItem::new("".into(), Position::new(1, 1, 0))) ); assert_type_success!( "1.0 + 1.0;", @@ -64,7 +64,7 @@ fn simple_binary_typecheck() { "{foo = 1} + {foo = 1};", Shape::Tuple(PositionedItem::new( vec![ - (Token { typ: TokenType::BAREWORD, fragment: "foo".to_owned(), pos: Position::new(1, 2, 1)}, + (Token { typ: TokenType::BAREWORD, fragment: "foo".into(), pos: Position::new(1, 2, 1)}, Shape::Int(PositionedItem::new_with_pos(1, Position::new(1, 8, 7)))), ], Position::new(1, 1, 0) diff --git a/src/build/compile_test.rs b/src/build/compile_test.rs index 0d31f6c..82851b9 100644 --- a/src/build/compile_test.rs +++ b/src/build/compile_test.rs @@ -26,7 +26,7 @@ fn assert_build(input: &str) { let out_buffer: Vec = Vec::new(); let err_buffer: Vec = Vec::new(); let mut env_vars = BTreeMap::new(); - env_vars.insert("FOO".to_owned(), "bar".to_owned()); + env_vars.insert("FOO".into(), "bar".into()); let env = RefCell::new(Environment::new_with_vars(out_buffer, err_buffer, env_vars)); let mut b = FileBuilder::new("", &i_paths, &env); b.enable_validate_mode(); diff --git a/src/build/ir.rs b/src/build/ir.rs index bbbe1e3..1f2d7bd 100644 --- a/src/build/ir.rs +++ b/src/build/ir.rs @@ -15,10 +15,10 @@ pub enum Val { Boolean(bool), Int(i64), Float(f64), - Str(String), + Str(Rc), List(Vec>), - Tuple(Vec<(String, Rc)>), - Env(Vec<(String, String)>), + Tuple(Vec<(Rc, Rc)>), + Env(Vec<(Rc, Rc)>), } impl Val { @@ -103,7 +103,7 @@ impl Val { } /// Returns the fields if this Val is a tuple. None otherwise. - pub fn get_fields(&self) -> Option<&Vec<(String, Rc)>> { + pub fn get_fields(&self) -> Option<&Vec<(Rc, Rc)>> { if let &Val::Tuple(ref fs) = self { Some(fs) } else { @@ -208,8 +208,8 @@ impl Display for Val { } } -impl From for String { - fn from(v: Val) -> String { +impl From for Rc { + fn from(v: Val) -> Self { match v { Val::Int(ref i) => format!("{}", i), Val::Float(ref f) => format!("{}", f), @@ -217,12 +217,12 @@ impl From for String { Val::Boolean(ref b) => format!("{}", b), Val::Empty => "NULL".to_string(), val => format!("{}", val), - } + }.into() } } -impl From for Val { - fn from(s: String) -> Val { +impl From> for Val { + fn from(s: Rc) -> Val { Val::Str(s) } } diff --git a/src/build/mod.rs b/src/build/mod.rs index 437b130..abeff92 100644 --- a/src/build/mod.rs +++ b/src/build/mod.rs @@ -181,7 +181,7 @@ where if found.contains(&link) { continue; } - let ops = match self.environment.borrow_mut().get_ops_for_path(link.clone()) { + let ops = match self.environment.borrow_mut().get_ops_for_path(link.as_ref()) { Ok(ops) => ops, Err(e) => return Err(Box::new(e.with_pos(path_pos))), }; @@ -343,7 +343,7 @@ where if let Some(val) = self.out.clone() { if let &Val::Tuple(ref flds) = val.as_ref() { for (k, v) in flds.iter() { - if k == name { + if k.as_ref() == name { return Some(v.clone()); } } diff --git a/src/build/opcode/convert.rs b/src/build/opcode/convert.rs index b248b48..90469ff 100644 --- a/src/build/opcode/convert.rs +++ b/src/build/opcode/convert.rs @@ -19,14 +19,14 @@ impl Error { } } -impl From<&Primitive> for String { +impl From<&Primitive> for Rc { fn from(p: &Primitive) -> Self { match p { - Primitive::Int(i) => format!("{}", i), - Primitive::Float(f) => format!("{}", f), - Primitive::Str(s) => format!("{}", s), - Primitive::Bool(b) => format!("{}", b), - Primitive::Empty => "NULL".to_owned(), + Primitive::Int(i) => format!("{}", i).into(), + Primitive::Float(f) => format!("{}", f).into(), + Primitive::Str(s) => format!("{}", s).into(), + Primitive::Bool(b) => format!("{}", b).into(), + Primitive::Empty => "NULL".into(), } } } @@ -85,7 +85,7 @@ impl TryFrom<&Primitive> for bool { cast_type: CastType::Int, }), Primitive::Bool(b) => Ok(*b), - Primitive::Str(s) => match s.as_str() { + Primitive::Str(s) => match s.as_ref() { "true" => Ok(true), "false" => Ok(false), _ => Err(Error { @@ -192,15 +192,15 @@ impl From<&Val> for Value { } } -impl From<&Composite> for String { +impl From<&Composite> for Rc { fn from(c: &Composite) -> Self { let mut buf = String::new(); match c { &List(ref elems, _) => { buf.push_str("["); for e in elems.iter() { - let val: String = e.as_ref().into(); - buf.push_str(&val); + let val: Rc = e.as_ref().into(); + buf.push_str(val.as_ref()); buf.push_str(","); } buf.push_str("]"); @@ -210,26 +210,26 @@ impl From<&Composite> for String { for &(ref k, ref v) in flds.iter() { buf.push_str(&k); buf.push_str(" = "); - let val: String = v.as_ref().into(); + let val: Rc = v.as_ref().into(); buf.push_str(&val); buf.push_str(","); } buf.push_str("}"); } } - buf + buf.into() } } -impl From<&Value> for String { +impl From<&Value> for Rc { fn from(v: &Value) -> Self { match v { &S(ref s) => s.clone(), &P(ref p) => p.into(), &C(ref c) => c.into(), - &T(_) => "".to_owned(), - &F(_) => "".to_owned(), - &M(_) => "".to_owned(), + &T(_) => "".into(), + &F(_) => "".into(), + &M(_) => "".into(), } } } diff --git a/src/build/opcode/environment.rs b/src/build/opcode/environment.rs index 5e8dc66..44ff23f 100644 --- a/src/build/opcode/environment.rs +++ b/src/build/opcode/environment.rs @@ -34,7 +34,7 @@ where Stdout: Write + Clone, Stderr: Write + Clone, { - pub val_cache: BTreeMap>, + pub val_cache: BTreeMap, Rc>, // TODO implement a shape cache here. pub op_cache: cache::Ops, pub converter_registry: ConverterRegistry, @@ -42,7 +42,7 @@ where pub assert_results: AssertCollector, pub stdout: Stdout, pub stderr: Stderr, - pub env_vars: BTreeMap, // Environment Variables + pub env_vars: BTreeMap, Rc>, // Environment Variables pub out_lock: BTreeSet, } @@ -52,7 +52,7 @@ impl Environment { Self::new_with_vars(out, err, BTreeMap::new()) } - pub fn new_with_vars(out: Stdout, err: Stderr, vars: BTreeMap) -> Self { + pub fn new_with_vars(out: Stdout, err: Stderr, vars: BTreeMap, Rc>) -> Self { let mut me = Self { val_cache: BTreeMap::new(), env_vars: vars, @@ -78,11 +78,11 @@ impl Environment { Value::C(Composite::Tuple(fields, positions)) } - pub fn get_cached_path_val(&self, path: &String) -> Option> { - self.val_cache.get(path).cloned() + pub fn get_cached_path_val(&self, path: Rc) -> Option> { + self.val_cache.get(&path).cloned() } - pub fn update_path_val(&mut self, path: &String, val: Rc) { + pub fn update_path_val(&mut self, path: Rc, val: Rc) { self.val_cache.insert(path.clone(), val); } diff --git a/src/build/opcode/error.rs b/src/build/opcode/error.rs index 556b587..2a1717f 100644 --- a/src/build/opcode/error.rs +++ b/src/build/opcode/error.rs @@ -15,19 +15,20 @@ use std::convert::From; use std::fmt; use std::fmt::Display; use std::io; +use std::rc::Rc; use crate::ast::Position; use crate::build::opcode::convert; #[derive(Debug)] pub struct Error { - message: String, + message: Rc, pos: Option, call_stack: Vec, } impl Error { - pub fn new(msg: String, pos: Position) -> Self { + pub fn new(msg: Rc, pos: Position) -> Self { Self { message: msg, pos: Some(pos), @@ -69,7 +70,7 @@ macro_rules! decorate_call { impl From for Error { fn from(e: regex::Error) -> Self { Error { - message: format!("{}", e), + message: format!("{}", e).into(), pos: None, call_stack: Vec::new(), } @@ -83,7 +84,7 @@ impl From for Error { format!("OSError: Path not found: {}", e) } _ => format!("{}", e), - }; + }.into(); Error { message: msg, pos: None, @@ -95,7 +96,7 @@ impl From for Error { impl From for Error { fn from(e: convert::Error) -> Self { Error { - message: e.message(), + message: e.message().into(), pos: None, call_stack: Vec::new(), } diff --git a/src/build/opcode/mod.rs b/src/build/opcode/mod.rs index 18349d0..fcd552c 100644 --- a/src/build/opcode/mod.rs +++ b/src/build/opcode/mod.rs @@ -39,7 +39,7 @@ pub enum Primitive { // Primitive Types Int(i64), Float(f64), - Str(String), + Str(Rc), Bool(bool), Empty, } @@ -67,7 +67,7 @@ impl Value { #[derive(Debug, PartialEq, Clone)] pub enum Composite { List(Vec>, Vec), - Tuple(Vec<(String, Rc)>, Vec<(Position, Position)>), + Tuple(Vec<(Rc, Rc)>, Vec<(Position, Position)>), } use Composite::{List, Tuple}; @@ -75,7 +75,7 @@ use Composite::{List, Tuple}; #[derive(Debug, PartialEq, Clone)] pub struct Func { ptr: OpPointer, - bindings: Vec, + bindings: Vec>, snapshot: Stack, } @@ -83,7 +83,7 @@ pub struct Func { pub struct Module { ptr: OpPointer, result_ptr: Option, - flds: Vec<(String, Rc)>, + flds: Vec<(Rc, Rc)>, flds_pos_list: Vec<(Position, Position)>, pkg_ptr: Option, } @@ -91,7 +91,7 @@ pub struct Module { #[derive(Clone)] pub enum Value { // Binding names. - S(String), + S(Rc), // Primitive Types P(Primitive), // Composite Types. @@ -147,9 +147,9 @@ pub enum Op { // Primitive casts Cast(CastType), // A bareword for use in bindings or lookups - Sym(String), + Sym(Rc), // Reference a binding on the heap - DeRef(String), + DeRef(Rc), // Complex Type ops InitTuple, Field, diff --git a/src/build/opcode/pointer.rs b/src/build/opcode/pointer.rs index 403ce3c..8315065 100644 --- a/src/build/opcode/pointer.rs +++ b/src/build/opcode/pointer.rs @@ -60,7 +60,7 @@ impl OpPointer { return Ok(()); } Err(Error::new( - format!("FAULT!!! Invalid Jump!"), + "FAULT!!! Invalid Jump!".into(), match self.pos() { Some(pos) => pos.clone(), None => Position::new(0, 0, 0), @@ -86,7 +86,7 @@ impl OpPointer { match self.ptr { Some(ptr) => Ok(ptr), None => Err(Error::new( - format!("FAULT!!! Position Check failure!"), + "FAULT!!! Position Check failure!".into(), Position::new(0, 0, 0), )), } diff --git a/src/build/opcode/runtime.rs b/src/build/opcode/runtime.rs index 4b1b320..5c55014 100644 --- a/src/build/opcode/runtime.rs +++ b/src/build/opcode/runtime.rs @@ -63,7 +63,7 @@ impl Builtins { h: Hook, stack: &mut Vec<(Rc, Position)>, env: &'a RefCell>, - import_stack: &mut Vec, + import_stack: &mut Vec>, pos: Position, ) -> Result<(), Error> where @@ -86,19 +86,19 @@ impl Builtins { } } - fn get_file_as_string(&self, path: &str) -> Result { + fn get_file_as_string(&self, path: &str) -> Result, Error> { let mut f = File::open(path)?; let mut contents = String::new(); // TODO(jwall): Proper error here f.read_to_string(&mut contents)?; - Ok(contents) + Ok(contents.into()) } fn import<'a, O, E>( &mut self, stack: &mut Vec<(Rc, Position)>, env: &'a RefCell>, - import_stack: &mut Vec, + import_stack: &mut Vec>, pos: Position, ) -> Result<(), Error> where @@ -110,39 +110,39 @@ impl Builtins { if let &Value::P(Str(ref path)) = val.as_ref() { // TODO(jwall): A bit hacky we should probably change import stacks to be pathbufs. // first we chack the cache - if let Some(val) = env.borrow().get_cached_path_val(&path) { + if let Some(val) = env.borrow().get_cached_path_val(path.clone()) { stack.push((val, path_pos)); return Ok(()); } - if import_stack.iter().find(|p| *p == path).is_some() { + if import_stack.iter().find(|p| p.as_ref() == path.as_ref()).is_some() { return Err(Error::new( - format!("Import cycle detected: {} in {:?}", path, import_stack), + format!("Import cycle detected: {} in {:?}", path, import_stack).into(), pos, )); } - let val = { env.borrow_mut().get_cached_path_val(&path) }; + let val = { env.borrow_mut().get_cached_path_val(path.clone()) }; match val { Some(v) => { stack.push((v, path_pos)); } None => { - let path_buf = PathBuf::from(path); + let path_buf = PathBuf::from(path.as_ref()); let op_pointer = - decorate_error!(path_pos => env.borrow_mut().get_ops_for_path(&path))?; + decorate_error!(path_pos => env.borrow_mut().get_ops_for_path(path.as_ref()))?; // TODO(jwall): What if we don't have a base path? let mut vm = VM::with_pointer(self.strict, op_pointer, path_buf.parent().unwrap()) .with_import_stack(import_stack.clone()); vm.run(env)?; let result = Rc::new(vm.symbols_to_tuple(true)); - env.borrow_mut().update_path_val(&path, result.clone()); + env.borrow_mut().update_path_val(path.clone(), result.clone()); stack.push((result, pos)); } } import_stack.push(path.clone()); return Ok(()); } - return Err(Error::new(format!("Invalid Path {:?}", val), pos)); + return Err(Error::new(format!("Invalid Path {:?}", val).into(), pos)); } unreachable!(); } @@ -163,7 +163,7 @@ impl Builtins { if let &Value::P(Str(ref path)) = val.as_ref() { path.clone() } else { - return Err(Error::new(format!("Invalid Path {:?}", val), path_pos)); + return Err(Error::new(format!("Invalid Path {:?}", val).into(), path_pos)); } } else { unreachable!(); @@ -173,14 +173,14 @@ impl Builtins { typ.clone() } else { return Err(Error::new( - format!("Expected conversion type but got {:?}", val), + format!("Expected conversion type but got {:?}", val).into(), typ_pos, )); } } else { unreachable!(); }; - if typ == "str" { + if typ.as_ref() == "str" { stack.push(( Rc::new(P(Str(self.get_file_as_string(&path)?))), pos.clone(), @@ -196,12 +196,12 @@ impl Builtins { } else { match importer.import(contents.as_bytes()) { Ok(v) => v.into(), - Err(e) => return Err(Error::new(format!("{}", e), pos)), + Err(e) => return Err(Error::new(format!("{}", e).into(), pos)), } } } None => { - return Err(Error::new(format!("No such conversion type {}", &typ), pos)) + return Err(Error::new(format!("No such conversion type {}", &typ).into(), pos)) } }), pos, @@ -226,10 +226,10 @@ impl Builtins { // look for the ok field. let mut ok = None; for &(ref name, ref val) in tuple_flds.iter() { - if name == "desc" { + if name.as_ref() == "desc" { desc = Some(val.as_ref()); } - if name == "ok" { + if name.as_ref() == "ok" { ok = Some(val.as_ref()); } } @@ -284,7 +284,7 @@ impl Builtins { let write_path = path.as_ref().to_path_buf(); if env.borrow().get_out_lock_for_path(&path) { return Err(Error::new( - format!("You can only have one output per file"), + "You can only have one output per file".into(), pos, )); } @@ -293,7 +293,7 @@ impl Builtins { } else { if env.borrow().get_out_lock_for_path("/dev/stdout") { return Err(Error::new( - format!("You can only have one output per file"), + "You can only have one output per file".into(), pos, )); } @@ -316,18 +316,18 @@ impl Builtins { None => Box::new(stdout), }; if let Err(e) = c.convert(Rc::new(val), &mut writer) { - return Err(Error::new(format!("{}", e), pos.clone())); + return Err(Error::new(format!("{}", e).into(), pos.clone())); } return Ok(()); } else { return Err(Error::new( - format!("No such conversion type {:?}", c_type), + format!("No such conversion type {:?}", c_type).into(), c_type_pos, )); } } return Err(Error::new( - format!("Not a conversion type {:?}", c_type_val), + format!("Not a conversion type {:?}", c_type_val).into(), val_pos, )); } @@ -356,14 +356,14 @@ impl Builtins { Ok(_) => { stack.push(( Rc::new(P(Str( - String::from_utf8_lossy(buf.as_slice()).to_string() + String::from_utf8_lossy(buf.as_slice()).into() ))), pos, )); } Err(_e) => { return Err(Error::new( - format!("No such conversion type {:?}", c_type), + format!("No such conversion type {:?}", c_type).into(), c_typ_pos, )); } @@ -373,7 +373,7 @@ impl Builtins { } } return Err(Error::new( - format!("Not a conversion type {:?}", val), + format!("Not a conversion type {:?}", val).into(), val_pos, )); } @@ -384,7 +384,7 @@ impl Builtins { &self, stack: &mut Vec<(Rc, Position)>, env: &'a RefCell>, - import_stack: &Vec, + import_stack: &Vec>, pos: Position, ) -> Result<(), Error> where @@ -407,7 +407,7 @@ impl Builtins { let f = if let &F(ref f) = fptr.as_ref() { f } else { - return Err(Error::new(format!("Not a function!!"), fptr_pos)); + return Err(Error::new(format!("Not a function!!").into(), fptr_pos)); }; match list.as_ref() { @@ -443,16 +443,14 @@ impl Builtins { // we expect them to be a list of exactly 2 items. if fval.len() != 2 { return Err(Error::new( - format!( - "Map Functions over tuples must return a list of two items" - ), + "Map Functions over tuples must return a list of two items".into(), result_pos, )); } let name = match fval[0].as_ref() { &P(Str(ref name)) => name.clone(), _ => return Err(Error::new( - format!("Map functions over tuples must return a String as the first list item"), + "Map functions over tuples must return a String as the first list item".into(), result_pos, )), }; @@ -467,7 +465,7 @@ impl Builtins { &P(Str(ref s)) => { let mut buf = String::new(); for c in s.chars() { - stack.push((Rc::new(P(Str(c.to_string()))), list_pos.clone())); + stack.push((Rc::new(P(Str(c.to_string().into()))), list_pos.clone())); // call function and push it's result on the stack. let (result, result_pos) = decorate_call!(pos => VM::fcall_impl(f, self.strict, stack, env.clone(), import_stack))?; @@ -475,16 +473,16 @@ impl Builtins { buf.push_str(s); } else { return Err(Error::new( - format!("Map functions over string should return strings"), + "Map functions over string should return strings".into(), result_pos, )); } } - stack.push((Rc::new(P(Str(buf))), pos)); + stack.push((Rc::new(P(Str(buf.into()))), pos)); } _ => { return Err(Error::new( - format!("You can only map over lists, tuples, or strings"), + "You can only map over lists, tuples, or strings".into(), pos, )) } @@ -496,7 +494,7 @@ impl Builtins { &self, stack: &mut Vec<(Rc, Position)>, env: &'a RefCell>, - import_stack: &Vec, + import_stack: &Vec>, pos: Position, ) -> Result<(), Error> where @@ -519,7 +517,7 @@ impl Builtins { let f = if let &F(ref f) = fptr.as_ref() { f } else { - return Err(Error::new(format!("Not a function!!"), fptr_pos)); + return Err(Error::new("Not a function!!".into(), fptr_pos)); }; match list.as_ref() { @@ -578,7 +576,7 @@ impl Builtins { &P(Str(ref s)) => { let mut buf = String::new(); for c in s.chars() { - stack.push((Rc::new(P(Str(c.to_string()))), list_pos.clone())); + stack.push((Rc::new(P(Str(c.to_string().into()))), list_pos.clone())); // call function and push it's result on the stack. let (condition, _) = decorate_call!(pos => VM::fcall_impl(f, self.strict, stack, env.clone(), import_stack))?; @@ -591,11 +589,11 @@ impl Builtins { _ => buf.push(c), } } - stack.push((Rc::new(P(Str(buf))), pos)); + stack.push((Rc::new(P(Str(buf.into()))), pos)); } _ => { return Err(Error::new( - format!("You can only filter over lists, tuples, or strings"), + "You can only filter over lists, tuples, or strings".into(), pos, )) } @@ -610,7 +608,7 @@ impl Builtins { s.clone() } else { return Err(Error::new( - format!("Expected string bug got {:?}", val), + format!("Expected string bug got {:?}", val).into(), val_pos, )); } @@ -624,7 +622,7 @@ impl Builtins { s.clone() } else { return Err(Error::new( - format!("Expected string bug got {:?}", val), + format!("Expected string bug got {:?}", val).into(), val_pos, )); } @@ -642,7 +640,7 @@ impl Builtins { &self, stack: &mut Vec<(Rc, Position)>, env: &'a RefCell>, - import_stack: &Vec, + import_stack: &Vec>, pos: Position, ) -> Result<(), Error> where @@ -671,7 +669,7 @@ impl Builtins { let f = if let &F(ref f) = fptr.as_ref() { f } else { - return Err(Error::new(format!("Not a function!"), fptr_pos)); + return Err(Error::new("Noe a function!".into(), fptr_pos)); }; match list.as_ref() { @@ -711,7 +709,7 @@ impl Builtins { for c in s.chars() { // push function arguments on the stack. stack.push((acc.clone(), acc_pos.clone())); - stack.push((Rc::new(P(Str(c.to_string()))), list_pos.clone())); + stack.push((Rc::new(P(Str(c.to_string().into()))), list_pos.clone())); // call function and push it's result on the stack. let (new_acc, new_acc_pos) = decorate_call!(pos => VM::fcall_impl(f, self.strict, stack, env.clone(), import_stack))?; @@ -721,7 +719,7 @@ impl Builtins { } _ => { return Err(Error::new( - format!("You can only reduce over lists, tuples, or strings"), + "You can only reduce over lists, tuples, or strings".into(), pos.clone(), )) } @@ -769,7 +767,7 @@ impl Builtins { } _ => { return Err(Error::new( - format!("Ranges can only be created with Ints"), + format!("Ranges can only be created with Ints").into(), pos, )); } @@ -809,7 +807,7 @@ impl Builtins { writable_val, &val_pos ) { - return Err(Error::new(format!("{}", e), pos)); + return Err(Error::new(format!("{}", e).into(), pos)); }; stack.push((val, val_pos)); Ok(()) diff --git a/src/build/opcode/scope.rs b/src/build/opcode/scope.rs index 54893b2..79fa99e 100644 --- a/src/build/opcode/scope.rs +++ b/src/build/opcode/scope.rs @@ -19,7 +19,7 @@ use crate::ast::Position; #[derive(Clone, PartialEq, Debug)] pub struct Stack { - curr: BTreeMap, Position)>, + curr: BTreeMap, (Rc, Position)>, } impl Stack { @@ -41,12 +41,12 @@ impl Stack { self.curr.get(name).is_some() } - pub fn add(&mut self, name: String, val: Rc, pos: Position) { + pub fn add(&mut self, name: Rc, val: Rc, pos: Position) { self.curr.insert(name, (val, pos)); } - pub fn symbol_list(&self) -> Vec<&String> { - self.curr.keys().collect() + pub fn symbol_list(&self) -> Vec> { + self.curr.keys().cloned().collect() } pub fn snapshot(&self) -> Self { diff --git a/src/build/opcode/translate.rs b/src/build/opcode/translate.rs index 016671a..98d8175 100644 --- a/src/build/opcode/translate.rs +++ b/src/build/opcode/translate.rs @@ -13,6 +13,7 @@ // limitations under the License. use std::collections::BTreeMap; use std::path::Path; +use std::rc::Rc; use crate::ast::rewrite::Rewriter; use crate::ast::walk::Walker; @@ -30,8 +31,8 @@ pub struct AST(); pub struct OpsMap { pub ops: Vec, pub pos: Vec, - pub shape_map: BTreeMap, - pub links: BTreeMap, + pub shape_map: BTreeMap, Shape>, + pub links: BTreeMap, Position>, } impl OpsMap { @@ -51,7 +52,7 @@ impl OpsMap { self } - pub fn add_link(&mut self, path: String, pos: Position) { + pub fn add_link(&mut self, path: Rc, pos: Position) { self.links.insert(path, pos); } @@ -227,7 +228,7 @@ impl AST { kind: BinaryExprType::IS, right: Box::new(Expression::Simple(Value::Str( PositionedItem::new( - "tuple".to_owned(), + "tuple".into(), def.left.pos().clone(), ), ))), @@ -321,7 +322,7 @@ impl AST { Expression::Fail(def) => { let msg_pos = def.message.pos().clone(); Self::translate_expr(*def.message, &mut ops, root); - ops.push(Op::Val(Primitive::Str("UserDefined: ".to_owned())), msg_pos); + ops.push(Op::Val(Primitive::Str("UserDefined: ".into())), msg_pos); ops.push(Op::Add, def.pos.clone()); ops.push(Op::Bang, def.pos); } @@ -373,7 +374,7 @@ impl AST { // Add our item binding shadowing any binding that already // existed. let expr_pos = expr.pos().clone(); - ops.push(Op::Sym("item".to_owned()), expr.pos().clone()); + ops.push(Op::Sym("item".into()), expr.pos().clone()); Self::translate_expr(*expr, &mut ops, root); ops.push(Op::BindOver, expr_pos.clone()); let mut elems = Vec::new(); @@ -531,7 +532,7 @@ impl AST { } else { ops.push( Op::Val(Primitive::Str( - "Unhandled select case with no default".to_owned(), + "Unhandled select case with no default".into(), )), default_pos, ); @@ -569,7 +570,7 @@ impl AST { let _ = printer.render_expr(&def.expr); } let expr_pretty = String::from_utf8(buffer).unwrap(); - ops.push(Op::Val(Primitive::Str(expr_pretty)), def.pos.clone()); + ops.push(Op::Val(Primitive::Str(expr_pretty.into())), def.pos.clone()); Self::translate_expr(*def.expr, &mut ops, root); ops.push(Op::Runtime(Hook::Trace(def.pos.clone())), def.pos); } @@ -586,7 +587,8 @@ impl AST { ) { match part { TemplatePart::Str(s) => { - ops.push(Op::Val(Primitive::Str(s.into_iter().collect())), pos); + let part: String = s.into_iter().map(|c| c.to_string()).collect(); + ops.push(Op::Val(Primitive::Str(part.into())), pos); } TemplatePart::PlaceHolder(_idx) => { if !place_holder { diff --git a/src/build/opcode/vm.rs b/src/build/opcode/vm.rs index 96e1c04..f2eeae6 100644 --- a/src/build/opcode/vm.rs +++ b/src/build/opcode/vm.rs @@ -46,7 +46,7 @@ pub struct VM { working_dir: PathBuf, stack: Vec<(Rc, Position)>, symbols: Stack, - import_stack: Vec, + import_stack: Vec>, runtime: runtime::Builtins, ops: OpPointer, pub last: Option<(Rc, Position)>, @@ -82,7 +82,7 @@ impl VM { self } - pub fn with_import_stack(mut self, imports: Vec) -> Self { + pub fn with_import_stack(mut self, imports: Vec>) -> Self { self.import_stack = imports; self } @@ -114,8 +114,8 @@ impl VM { let mut flds = Vec::new(); let mut pos_list = Vec::new(); for sym in self.symbols.symbol_list() { - if include_mod || sym != "mod" { - let (val, pos) = self.symbols.get(sym).unwrap().clone(); + if include_mod || sym.as_ref() != "mod" { + let (val, pos) = self.symbols.get(sym.as_ref()).unwrap().clone(); pos_list.push((pos.clone(), pos.clone())); flds.push((sym.clone(), val)); } @@ -198,7 +198,7 @@ impl VM { }; } if let Some(p) = self.ops.path.as_ref() { - self.import_stack.push(p.to_string_lossy().to_string()); + self.import_stack.push(p.to_string_lossy().into()); } Ok(()) } @@ -207,7 +207,7 @@ impl VM { if let Value::P(ref p) = val { self.push( Rc::new(match t { - CastType::Str => Value::P(Primitive::Str(format!("{}", p))), + CastType::Str => Value::P(Primitive::Str(format!("{}", p).into())), CastType::Int => Value::P(Primitive::Int(p.try_into()?)), CastType::Float => Value::P(Primitive::Float(p.try_into()?)), CastType::Bool => Value::P(Primitive::Bool(p.try_into()?)), @@ -236,15 +236,14 @@ impl VM { M(_) => "module", S(_) => "sym", T(_) => "thunk", - } - .to_owned(); - self.push(Rc::new(P(Str(typ_name))), pos)?; + }; + self.push(Rc::new(P(Str(typ_name.into()))), pos)?; Ok(()) } fn op_deref( &mut self, - name: String, + name: Rc, env: &RefCell>, pos: &Position, ) -> Result<(), Error> @@ -279,7 +278,7 @@ impl VM { format!( "Not a boolean condition {:?} in && expression at {}", cond, pos - ), + ).into(), cond_pos.clone(), )); } @@ -299,7 +298,7 @@ impl VM { format!( "Not a boolean condition {:?} in || expression at {}!", cond, pos - ), + ).into(), cond_pos.clone(), )); } @@ -314,7 +313,7 @@ impl VM { } } else { return Err(Error::new( - format!("Expected boolean but got {:?}!", cond), + format!("Expected boolean but got {:?}!", cond).into(), cond_pos.clone(), )); } @@ -329,7 +328,7 @@ impl VM { } } else { return Err(Error::new( - format!("Expected boolean but got {:?}!", cond), + format!("Expected boolean but got {:?}!", cond).into(), pos.clone(), )); } @@ -345,9 +344,9 @@ impl VM { let matched = match (field_name.as_ref(), search.as_ref()) { (&S(ref fname), &P(Str(ref sname))) | (&S(ref fname), &S(ref sname)) => fname == sname, (&S(ref fname), &P(Bool(b))) => { - if fname == "true" && b { + if fname.as_ref() == "true" && b { true - } else if fname == "false" && !b { + } else if fname.as_ref() == "false" && !b { true } else { false @@ -373,14 +372,14 @@ impl VM { (Some(ptr), flds.clone(), pos_list.clone()) } else { return Err(Error::new( - format!("Expected tuple but got {:?}", tpl_val), + format!("Expected tuple but got {:?}", tpl_val).into(), tpl_val_pos, )); } } _ => { return Err(Error::new( - format!("Expected tuple but got {:?}", mod_val), + format!("Expected tuple but got {:?}", mod_val).into(), mod_val_pos, )); } @@ -392,7 +391,7 @@ impl VM { let pkg_ops = vec![ Op::InitList, Op::Func(3), - Op::Val(Str(path.to_string_lossy().to_string())), + Op::Val(Str(path.to_string_lossy().into())), Op::Runtime(Hook::Import), Op::Return, ]; @@ -434,13 +433,13 @@ impl VM { bindings.push(sym.clone()); } else { return Err(Error::new( - format!("Not an argument name {:?}", e), + format!("Not an argument name {:?}", e).into(), args_pos, )); } } } else { - return Err(Error::new(format!("Fault!!! Bad Argument List"), args_pos)); + return Err(Error::new("Fault!!! Bad Argument List".into(), args_pos)); } let mut ops = self.ops.clone(); ops.jump(idx)?; @@ -462,7 +461,7 @@ impl VM { strict: bool, stack: &mut Vec<(Rc, Position)>, env: &'a RefCell>, - import_stack: &Vec, + import_stack: &Vec>, ) -> Result<(Rc, Position), Error> where O: std::io::Write + Clone, @@ -531,7 +530,7 @@ impl VM { format!( "Func called with too many args expected {} args but got {}", arity, arg_length - ), + ).into(), pos, )); } @@ -540,7 +539,7 @@ impl VM { format!( "Func called with too few args expected {} args but got {}", arity, arg_length - ), + ).into(), pos, )); } @@ -549,7 +548,7 @@ impl VM { Self::fcall_impl(f, self.runtime.strict, &mut self.stack, env.clone(), &self.import_stack))?; self.push(val, pos.clone())?; } else { - return Err(Error::new(format!("Not a function! {:?}", f,), pos)); + return Err(Error::new(format!("Not a function! {:?}", f,).into(), pos)); } Ok(()) } @@ -569,7 +568,7 @@ impl VM { format!( "Expected Boolean but got {:?} in expression at {}", operand, pos - ), + ).into(), operand_pos, )); } @@ -584,7 +583,7 @@ impl VM { format!( "Expected values of the same type but got {:?} at {} and {:?} at {} for expression", left, left_pos, right, right_pos, - ), + ).into(), pos, )); } @@ -607,7 +606,7 @@ impl VM { format!( "Expected numeric values of the same type but got {:?} at {} and {:?} at {} for expression", left, left_pos, right, right_pos, - ), + ).into(), pos.clone(), )); } @@ -630,7 +629,7 @@ impl VM { format!( "Expected numeric values of the same type but got {:?} at {} and {:?} at {} for expression", left, left_pos, right, right_pos, - ), + ).into(), pos.clone(), )); } @@ -653,7 +652,7 @@ impl VM { format!( "Expected numeric values of the same type but got {:?} at {} and {:?} at {} for expression", left, left_pos, right, right_pos, - ), + ).into(), pos, )); } @@ -676,7 +675,7 @@ impl VM { format!( "Expected numeric values of the same type but got {:?} at {} and {:?} at {} for expression", left, left_pos, right, right_pos, - ), + ).into(), pos, )); } @@ -850,7 +849,7 @@ impl VM { return Ok(()); } return Err(Error::new( - format!("Invalid selector index: {:?} target: {:?}", right, left), + format!("Invalid selector index: {:?} target: {:?}", right, left).into(), pos, )); } @@ -869,7 +868,7 @@ impl VM { } } else { return Err(Error::new( - format!("Expected String or Symbol got: {}", right.type_name()), + format!("Expected String or Symbol got: {}", right.type_name()).into(), right_pos, )); } @@ -884,13 +883,13 @@ impl VM { } &P(Str(ref s)) => { if let &P(Str(ref part)) = right.as_ref() { - self.push(Rc::new(P(Bool(s.contains(part)))), pos)?; + self.push(Rc::new(P(Bool(s.contains(part.as_ref())))), pos)?; return Ok(()); } } _ => { return Err(Error::new( - format!("Expected String, Tuple, or List got: {}", left.type_name()), + format!("Expected String, Tuple, or List got: {}", left.type_name()).into(), left_pos, )); } @@ -974,7 +973,7 @@ impl VM { self.merge_field_into_tuple( &mut flds, &mut flds_pos_list, - "this".to_owned(), + "this".into(), &pos, Rc::new(this), &val_pos, @@ -989,7 +988,7 @@ impl VM { self.merge_field_into_tuple( &mut flds, &mut flds_pos_list, - "pkg".to_owned(), + "pkg".into(), &pos, pkg_func, &val_pos, @@ -1000,7 +999,7 @@ impl VM { .clean_copy() .to_new_pointer(ptr.clone()) .with_import_stack(self.import_stack.clone()); - vm.push(Rc::new(S("mod".to_owned())), pos.clone())?; + vm.push(Rc::new(S("mod".into())), pos.clone())?; vm.push(Rc::new(C(Tuple(flds, flds_pos_list))), pos.clone())?; decorate_call!(pos => vm.run(env))?; if let Some(ptr) = result_ptr { @@ -1014,7 +1013,7 @@ impl VM { } _ => { return Err(Error::new( - format!("Expected a Tuple or Module but got {:?}", tgt), + format!("Expected a Tuple or Module but got {:?}", tgt).into(), pos, )); } @@ -1024,9 +1023,9 @@ impl VM { fn merge_field_into_tuple( &self, - src_fields: &mut Vec<(String, Rc)>, + src_fields: &mut Vec<(Rc, Rc)>, pos_fields: &mut Vec<(Position, Position)>, - name: String, + name: Rc, name_pos: &Position, value: Rc, val_pos: &Position, @@ -1043,7 +1042,7 @@ impl VM { fld.1.type_name(), name, value.type_name(), - ), + ).into(), val_pos.clone(), )); } @@ -1065,21 +1064,21 @@ impl VM { pub fn binding_push( &mut self, - name: String, + name: Rc, val: Rc, strict: bool, pos: &Position, name_pos: &Position, ) -> Result<(), Error> { - if self.reserved_words.contains(name.as_str()) { + if self.reserved_words.contains(name.as_ref()) { return Err(Error::new( - format!("{} is a reserved word.", name), + format!("{} is a reserved word.", name).into(), name_pos.clone(), )); } if self.symbols.is_bound(&name) && strict { return Err(Error::new( - format!("Binding {} already exists", name), + format!("Binding {} already exists", name).into(), pos.clone(), )); } @@ -1116,7 +1115,7 @@ impl VM { match tpl { Some((v, pos)) => Ok((v, pos)), None => { - return Err(Error::new(format!("No such binding {}", name), pos.clone())); + return Err(Error::new(format!("No such binding {}", name).into(), pos.clone())); } } } @@ -1137,7 +1136,7 @@ impl VM { (P(Float(f)), P(Float(ff))) => Float(f * ff), _ => { return Err(Error::new( - format!("Expected {} but got {:?}", left.type_name(), right), + format!("Expected {} but got {:?}", left.type_name(), right).into(), pos.clone(), )) } @@ -1150,7 +1149,7 @@ impl VM { (P(Float(f)), P(Float(ff))) => Float(f / ff), _ => { return Err(Error::new( - format!("Expected {} but got {:?}", left.type_name(), right), + format!("Expected {} but got {:?}", left.type_name(), right).into(), pos.clone(), )) } @@ -1163,7 +1162,7 @@ impl VM { (P(Float(f)), Value::P(Float(ff))) => Float(f - ff), _ => { return Err(Error::new( - format!("Expected {} but got {:?}", left.type_name(), right), + format!("Expected {} but got {:?}", left.type_name(), right).into(), pos.clone(), )) } @@ -1176,7 +1175,7 @@ impl VM { (P(Float(f)), Value::P(Float(ff))) => Float(f % ff), _ => { return Err(Error::new( - format!("Expected {} but got {:?}", left.type_name(), right), + format!("Expected {} but got {:?}", left.type_name(), right).into(), pos.clone(), )) } @@ -1191,7 +1190,7 @@ impl VM { let mut ns = String::new(); ns.push_str(&s); ns.push_str(&ss); - P(Str(ns)) + P(Str(ns.into())) } ( C(List(ref left_list, ref left_pos_list)), @@ -1216,7 +1215,7 @@ impl VM { } _ => { return Err(Error::new( - format!("Expected {} but got {:?}", left.type_name(), right), + format!("Expected {} but got {:?}", left.type_name(), right).into(), pos.clone(), )) } diff --git a/src/build/scope.rs b/src/build/scope.rs index 9f9ca26..e7a92f0 100644 --- a/src/build/scope.rs +++ b/src/build/scope.rs @@ -10,9 +10,9 @@ use crate::ast::PositionedItem; use crate::build::ir::Val; use crate::error; -pub fn find_in_fieldlist(target: &str, fs: &Vec<(String, Rc)>) -> Option> { +pub fn find_in_fieldlist(target: &str, fs: &Vec<(Rc, Rc)>) -> Option> { for (key, val) in fs.iter().cloned() { - if target == &key { + if target == key.as_ref() { return Some(val.clone()); } } @@ -20,7 +20,7 @@ pub fn find_in_fieldlist(target: &str, fs: &Vec<(String, Rc)>) -> Option, Rc>; +pub type ValueMap = HashMap>, Rc>; /// Defines a scope for execution in ucg. /// @@ -132,11 +132,11 @@ impl Scope { /// valid when the current value is a tuple. /// * everything else is looked up in the currently accumulated build output /// for this execution context. - pub fn lookup_sym(&self, sym: &PositionedItem, is_symbol: bool) -> Option> { - if &sym.val == "env" && is_symbol { + pub fn lookup_sym(&self, sym: &PositionedItem>, is_symbol: bool) -> Option> { + if sym.val.as_ref() == "env" && is_symbol { return Some(self.env.clone()); } - if &sym.val == "self" && is_symbol { + if sym.val.as_ref() == "self" && is_symbol { return self.curr_val.clone(); } if self.search_curr_val && self.curr_val.is_some() { @@ -179,7 +179,7 @@ impl Scope { fn lookup_in_tuple( pos: &Position, field: &str, - fs: &Vec<(String, Rc)>, + fs: &Vec<(Rc, Rc)>, ) -> Result, Box> { if let Some(vv) = find_in_fieldlist(&field, fs) { Ok(vv) diff --git a/src/build/test.rs b/src/build/test.rs index 16c844b..9bff6dd 100644 --- a/src/build/test.rs +++ b/src/build/test.rs @@ -153,7 +153,7 @@ fn test_expr_copy_no_such_tuple() { vec![( Expression::Copy(CopyDef { selector: Value::Symbol(PositionedItem::new( - "tpl1".to_string(), + "tpl1".into(), Position::new(1, 1, 1), )), fields: Vec::new(), diff --git a/src/convert/b64.rs b/src/convert/b64.rs index a8a2459..932e77c 100644 --- a/src/convert/b64.rs +++ b/src/convert/b64.rs @@ -15,9 +15,9 @@ pub struct Base64Importer { impl Importer for Base64Importer { fn import(&self, bytes: &[u8]) -> Result, Box> { return if self.url_safe { - Ok(Rc::new(Val::Str(STANDARD.encode(bytes)))) + Ok(Rc::new(Val::Str(STANDARD.encode(bytes).into()))) } else { - Ok(Rc::new(Val::Str(URL_SAFE.encode(bytes)))) + Ok(Rc::new(Val::Str(URL_SAFE.encode(bytes).into()))) }; } } diff --git a/src/convert/env.rs b/src/convert/env.rs index a0c0ecd..27f5ae5 100644 --- a/src/convert/env.rs +++ b/src/convert/env.rs @@ -28,7 +28,7 @@ impl EnvConverter { EnvConverter {} } - fn convert_tuple(&self, flds: &Vec<(String, Rc)>, w: &mut dyn IOWrite) -> ConvertResult { + fn convert_tuple(&self, flds: &Vec<(Rc, Rc)>, w: &mut dyn IOWrite) -> ConvertResult { for &(ref name, ref val) in flds.iter() { if val.is_tuple() { eprintln!("Skipping embedded tuple..."); diff --git a/src/convert/exec.rs b/src/convert/exec.rs index 6d0566b..939cfa4 100644 --- a/src/convert/exec.rs +++ b/src/convert/exec.rs @@ -48,12 +48,12 @@ impl ExecConverter { ) .to_boxed()); } - let mut env: Option<&Vec<(String, Rc)>> = None; + let mut env: Option<&Vec<(Rc, Rc)>> = None; let mut command: Option<&str> = None; let mut args: Option<&Vec>> = None; for &(ref name, ref val) in fields.iter() { // We require a command field in our exec tuple. - if name == "command" { + if name.as_ref() == "command" { if command.is_some() { return Err(BuildError::new( "There can only be one command field in an exec tuple", @@ -72,7 +72,7 @@ impl ExecConverter { .to_boxed()); } // We optionally allow an env field in our exec tuple. - if name == "env" { + if name.as_ref() == "env" { if let &Val::Tuple(ref l) = val.as_ref() { if env.is_some() { return Err(BuildError::new( @@ -91,7 +91,7 @@ impl ExecConverter { .to_boxed()); } // We optionally allow an args field in our exec tuple. - if name == "args" { + if name.as_ref() == "args" { if let &Val::List(ref l) = val.as_ref() { if args.is_some() { return Err(BuildError::new( diff --git a/src/convert/flags.rs b/src/convert/flags.rs index 643e8d4..75f80f7 100644 --- a/src/convert/flags.rs +++ b/src/convert/flags.rs @@ -94,7 +94,7 @@ impl FlagConverter { Ok(()) } - fn write(&self, pfx: &str, flds: &Vec<(String, Rc)>, w: &mut dyn Write) -> ConvertResult { + fn write(&self, pfx: &str, flds: &Vec<(Rc, Rc)>, w: &mut dyn Write) -> ConvertResult { for &(ref name, ref val) in flds.iter() { if let &Val::Empty = val.as_ref() { self.write_flag_name(pfx, name, w)?; diff --git a/src/convert/json.rs b/src/convert/json.rs index 7f65c6d..9233be6 100644 --- a/src/convert/json.rs +++ b/src/convert/json.rs @@ -34,19 +34,19 @@ impl JsonConverter { Ok(serde_json::Value::Array(v)) } - fn convert_tuple(&self, items: &Vec<(String, Rc)>) -> std::io::Result { + fn convert_tuple(&self, items: &Vec<(Rc, Rc)>) -> std::io::Result { let mut mp = serde_json::Map::new(); for &(ref k, ref v) in items.iter() { - mp.entry(k.clone()).or_insert(self.convert_value(v)?); + mp.entry(k.as_ref()).or_insert(self.convert_value(v)?); } Ok(serde_json::Value::Object(mp)) } - fn convert_env(&self, items: &Vec<(String, String)>) -> std::io::Result { + fn convert_env(&self, items: &Vec<(Rc, Rc)>) -> std::io::Result { let mut mp = serde_json::Map::new(); for &(ref k, ref v) in items.iter() { - mp.entry(k.clone()) - .or_insert(serde_json::Value::String(v.clone())); + mp.entry(k.as_ref()) + .or_insert(serde_json::Value::String(v.to_string())); } Ok(serde_json::Value::Object(mp)) } @@ -71,7 +71,7 @@ impl JsonConverter { }; serde_json::Value::Number(n) } - &Val::Str(ref s) => serde_json::Value::String(s.clone()), + &Val::Str(ref s) => serde_json::Value::String(s.to_string()), &Val::Env(ref fs) => self.convert_env(fs)?, &Val::List(ref l) => self.convert_list(l)?, &Val::Tuple(ref t) => self.convert_tuple(t)?, @@ -81,7 +81,7 @@ impl JsonConverter { fn convert_json_val(&self, v: &serde_json::Value) -> std::result::Result> { Ok(match v { - serde_json::Value::String(s) => Val::Str(s.clone()), + serde_json::Value::String(s) => Val::Str(s.clone().into()), serde_json::Value::Number(n) => { if let Some(i) = n.as_i64() { Val::Int(i) @@ -101,7 +101,7 @@ impl JsonConverter { serde_json::Value::Object(m) => { let mut fs = Vec::with_capacity(m.len()); for (key, value) in m { - fs.push((key.to_string(), Rc::new(self.convert_json_val(value)?))); + fs.push((key.clone().into(), Rc::new(self.convert_json_val(value)?))); } Val::Tuple(fs) } diff --git a/src/convert/toml.rs b/src/convert/toml.rs index ac6e9f1..f4c65c2 100644 --- a/src/convert/toml.rs +++ b/src/convert/toml.rs @@ -41,19 +41,19 @@ impl TomlConverter { Ok(toml::Value::Array(v)) } - fn convert_tuple(&self, items: &Vec<(String, Rc)>) -> Result { + fn convert_tuple(&self, items: &Vec<(Rc, Rc)>) -> Result { let mut mp = toml::value::Table::new(); for &(ref k, ref v) in items.iter() { - mp.entry(k.clone()).or_insert(self.convert_value(v)?); + mp.entry(k.to_string()).or_insert(self.convert_value(v)?); } Ok(toml::Value::Table(mp)) } - fn convert_env(&self, items: &Vec<(String, String)>) -> Result { + fn convert_env(&self, items: &Vec<(Rc, Rc)>) -> Result { let mut mp = toml::value::Table::new(); for &(ref k, ref v) in items.iter() { - mp.entry(k.clone()) - .or_insert(toml::Value::String(v.clone())); + mp.entry(k.to_string()) + .or_insert(toml::Value::String(v.to_string())); } Ok(toml::Value::Table(mp)) } @@ -67,7 +67,7 @@ impl TomlConverter { } &Val::Float(f) => toml::Value::Float(f), &Val::Int(i) => toml::Value::Integer(i), - &Val::Str(ref s) => toml::Value::String(s.clone()), + &Val::Str(ref s) => toml::Value::String(s.to_string()), &Val::Env(ref fs) => self.convert_env(fs)?, &Val::List(ref l) => self.convert_list(l)?, &Val::Tuple(ref t) => self.convert_tuple(t)?, @@ -77,7 +77,7 @@ impl TomlConverter { fn convert_toml_val(&self, v: &toml::Value) -> std::result::Result> { Ok(match v { - toml::Value::String(s) => Val::Str(s.clone()), + toml::Value::String(s) => Val::Str(s.clone().into()), toml::Value::Integer(i) => Val::Int(*i), toml::Value::Float(f) => Val::Float(*f), toml::Value::Boolean(b) => Val::Boolean(*b), @@ -91,11 +91,11 @@ impl TomlConverter { toml::Value::Table(m) => { let mut fs = Vec::with_capacity(m.len()); for (key, value) in m { - fs.push((key.to_string(), Rc::new(self.convert_toml_val(value)?))); + fs.push((key.clone().into(), Rc::new(self.convert_toml_val(value)?))); } Val::Tuple(fs) } - toml::Value::Datetime(d) => Val::Str(format!("{}", d)), + toml::Value::Datetime(d) => Val::Str(format!("{}", d).into()), }) } diff --git a/src/convert/xml.rs b/src/convert/xml.rs index edfc256..cc3ae9c 100644 --- a/src/convert/xml.rs +++ b/src/convert/xml.rs @@ -38,7 +38,7 @@ impl XmlConverter { } } - fn get_tuple_val(v: &Val) -> std::result::Result<&Vec<(String, Rc)>, Box> { + fn get_tuple_val(v: &Val) -> std::result::Result<&Vec<(Rc, Rc)>, Box> { if let Val::Tuple(ref fs) = v { Ok(fs) } else { @@ -58,15 +58,15 @@ impl XmlConverter { // First we determine if this is a tag or text node if let Val::Tuple(ref fs) = v { let mut name: Option<&str> = None; - let mut attrs: Option<&Vec<(String, Rc)>> = None; + let mut attrs: Option<&Vec<(Rc, Rc)>> = None; let mut children: Option<&Vec>> = None; let mut text: Option<&str> = None; let mut ns: Option<(&str, &str)> = None; for (ref field, ref val) in fs.iter() { - if field == "name" { + if field.as_ref() == "name" { name = Some(Self::get_str_val(val.as_ref())?); } - if field == "ns" { + if field.as_ref() == "ns" { if let Val::Tuple(ref fs) = val.as_ref() { let mut prefix = ""; let mut uri = ""; @@ -74,10 +74,10 @@ impl XmlConverter { if val.is_empty() { continue; } - if name == "uri" { + if name.as_ref() == "uri" { uri = Self::get_str_val(val.as_ref())?; } - if name == "prefix" { + if name.as_ref() == "prefix" { prefix = Self::get_str_val(val.as_ref())?; } } @@ -88,19 +88,19 @@ impl XmlConverter { ns = Some(("", s)); } } - if field == "attrs" { + if field.as_ref() == "attrs" { // This should be a tuple. if !val.is_empty() { attrs = Some(Self::get_tuple_val(val.as_ref())?); } } - if field == "children" { + if field.as_ref() == "children" { // This should be a list of tuples. if !val.is_empty() { children = Some(Self::get_list_val(val.as_ref())?); } } - if field == "text" { + if field.as_ref() == "text" { if !val.is_empty() { text = Some(Self::get_str_val(val.as_ref())?); } @@ -160,19 +160,19 @@ impl XmlConverter { let mut standalone: Option = None; let mut root: Option> = None; for &(ref name, ref val) in fs.iter() { - if name == "version" { + if name.as_ref() == "version" { version = Some(Self::get_str_val(val)?); } - if name == "encoding" { + if name.as_ref() == "encoding" { encoding = Some(Self::get_str_val(val)?); } - if name == "standalone" { + if name.as_ref() == "standalone" { standalone = match val.as_ref() { Val::Boolean(b) => Some(*b), _ => None, }; } - if name == "root" { + if name.as_ref() == "root" { root = Some(val.clone()); } } diff --git a/src/convert/yaml.rs b/src/convert/yaml.rs index 1a507b0..30bd47a 100644 --- a/src/convert/yaml.rs +++ b/src/convert/yaml.rs @@ -25,21 +25,21 @@ impl YamlConverter { Ok(serde_yaml::Value::Sequence(v)) } - fn convert_env(&self, items: &Vec<(String, String)>) -> std::io::Result { + fn convert_env(&self, items: &Vec<(Rc, Rc)>) -> std::io::Result { let mut mp = serde_yaml::Mapping::new(); for &(ref k, ref v) in items.iter() { mp.insert( - serde_yaml::Value::String(k.clone()), - serde_yaml::Value::String(v.clone()), + serde_yaml::Value::String(k.to_string()), + serde_yaml::Value::String(v.to_string()), ); } Ok(serde_yaml::Value::Mapping(mp)) } - fn convert_tuple(&self, items: &Vec<(String, Rc)>) -> std::io::Result { + fn convert_tuple(&self, items: &Vec<(Rc, Rc)>) -> std::io::Result { let mut mapping = serde_yaml::Mapping::new(); for &(ref k, ref v) in items.iter() { - mapping.insert(serde_yaml::Value::String(k.clone()), self.convert_value(v)?); + mapping.insert(serde_yaml::Value::String(k.to_string()), self.convert_value(v)?); } Ok(serde_yaml::Value::Mapping(mapping)) } @@ -56,7 +56,7 @@ impl YamlConverter { Ok(v) => v, _ => panic!("Int is too large or not a Number {}", i), }, - &Val::Str(ref s) => serde_yaml::Value::String(s.clone()), + &Val::Str(ref s) => serde_yaml::Value::String(s.to_string()), &Val::Env(ref fs) => self.convert_env(fs)?, &Val::List(ref l) => self.convert_list(l)?, &Val::Tuple(ref t) => self.convert_tuple(t)?, @@ -97,7 +97,7 @@ impl YamlConverter { fn convert_yaml_val(&self, v: &serde_yaml::Value) -> Result> { Ok(match v { - serde_yaml::Value::String(s) => Val::Str(s.clone()), + serde_yaml::Value::String(s) => Val::Str(s.clone().into()), serde_yaml::Value::Number(n) => { if let Some(i) = n.as_i64() { Val::Int(i) @@ -122,7 +122,7 @@ impl YamlConverter { let mut collapsed = Vec::with_capacity(fs.len()); for (k, val) in fs { if !seen_keys.contains(&k) { - collapsed.push((k.clone(), val)); + collapsed.push((k.clone().into(), val)); seen_keys.insert(k); } } diff --git a/src/main.rs b/src/main.rs index e5dd6b2..aa58b85 100644 --- a/src/main.rs +++ b/src/main.rs @@ -489,7 +489,7 @@ fn main() { let mut import_paths = Vec::new(); let mut env_vars = BTreeMap::new(); for (var, val) in std::env::vars() { - env_vars.insert(var, val); + env_vars.insert(var.into(), val.into()); } let env = RefCell::new(Environment::new_with_vars( StdoutWrapper::new(), diff --git a/src/parse/mod.rs b/src/parse/mod.rs index 087183d..5f89b5b 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -71,7 +71,7 @@ macro_rules! trace_parse { fn symbol_to_value(s: &Token) -> ConvertResult { Ok(Value::Symbol(value_node!( - s.fragment.to_string(), + s.fragment.clone(), s.pos.clone() ))) } @@ -84,7 +84,7 @@ make_fn!( fn str_to_value(s: &Token) -> ConvertResult { Ok(Value::Str(value_node!( - s.fragment.to_string(), + s.fragment.clone(), s.pos.clone() ))) } @@ -125,7 +125,7 @@ fn triple_to_number<'a>( } let suf = match v.2 { - None => "".to_string(), + None => "".into(), Some(bs) => bs.fragment, }; @@ -205,7 +205,7 @@ make_fn!( do_each!( b => match_type!(BOOLEAN), (Value::Boolean(PositionedItem{ - val: b.fragment == "true", + val: b.fragment.as_ref() == "true", pos: b.pos, })) ) @@ -367,7 +367,7 @@ fn tuple_to_func<'a>( .drain(0..) .map(|s| PositionedItem { pos: s.pos().clone(), - val: s.to_string(), + val: s.to_string().into(), }) .collect(); Ok(Expression::Func(FuncDef { @@ -567,7 +567,7 @@ make_fn!( expr => expression, _ => punct!(")"), (Expression::Cast(CastDef{ - cast_type: match typ.fragment.as_str() { + cast_type: match typ.fragment.as_ref() { "int" => CastType::Int, "float" => CastType::Float, "str" => CastType::Str, @@ -812,7 +812,7 @@ macro_rules! match_binding_name { let mut _i = $i.clone(); match match_type!(_i, BAREWORD) { Result::Complete(i, t) => { - if t.fragment == "env" { + if t.fragment.as_ref() == "env" { return Result::Abort(Error::new( format!("Cannot use binding {}. It is a reserved word.", t.fragment), Box::new($i.clone()), diff --git a/src/tokenizer/mod.rs b/src/tokenizer/mod.rs index 8d301a8..ef8736b 100644 --- a/src/tokenizer/mod.rs +++ b/src/tokenizer/mod.rs @@ -14,6 +14,7 @@ //! The tokenization stage of the ucg compiler. use std; +use std::rc::Rc; use abortable_parser::combinators::*; use abortable_parser::iter::SliceIter; @@ -104,7 +105,7 @@ make_fn!(strtok, (Token{ typ: TokenType::QUOTED, pos: Position::from(&span), - fragment: frag.to_string(), + fragment: frag.into(), }) ) ); @@ -117,7 +118,7 @@ make_fn!(barewordtok, (Token{ typ: TokenType::BAREWORD, pos: Position::from(&span), - fragment: frag.to_string(), + fragment: frag.into(), }) ) ); @@ -130,7 +131,7 @@ make_fn!(digittok, (Token{ typ: TokenType::DIGIT, pos: Position::from(&span), - fragment: digits.to_string(), + fragment: digits.into(), }) ) ); @@ -145,7 +146,7 @@ make_fn!(booleantok, (Token{ typ: TokenType::BOOLEAN, pos: Position::from(&span), - fragment: token.to_string(), + fragment: token.into(), }) ) ); @@ -161,7 +162,7 @@ macro_rules! do_text_token_tok { (Token { typ: $type, pos: Position::from(&span), - fragment: frag.to_string(), + fragment: frag.into(), }) ) }; @@ -173,7 +174,7 @@ macro_rules! do_text_token_tok { (Token { typ: $type, pos: Position::from(&span), - fragment: frag.to_string(), + fragment: frag.into(), }) ) }; @@ -414,7 +415,7 @@ make_fn!(whitespace, (Token{ typ: TokenType::WS, pos: Position::from(&span), - fragment: String::new(), + fragment: "".into(), }) ) ); @@ -426,7 +427,7 @@ make_fn!(end_of_input, (Token{ typ: TokenType::END, pos: Position::from(&span), - fragment: String::new(), + fragment: "".into(), }) ) ); @@ -557,7 +558,7 @@ pub fn tokenize<'a>( } // ensure that we always have an END token to go off of. out.push(Token { - fragment: String::new(), + fragment: "".into(), typ: TokenType::END, pos: Position::from(&i), }); @@ -688,10 +689,12 @@ macro_rules! match_token { ($i:expr, $t:expr, $f:expr, $msg:expr, $h:expr) => {{ use abortable_parser::Result; use std; + use std::rc::Rc; + let f: Rc = $f.into(); let mut i_ = $i.clone(); let tok = i_.next(); if let Some(tok) = tok { - if tok.typ == $t && &tok.fragment == $f { + if tok.typ == $t && tok.fragment.as_ref() == f.as_ref() { match $h(tok) { std::result::Result::Ok(v) => Result::Complete(i_.clone(), v), std::result::Result::Err(e) => { diff --git a/src/tokenizer/test.rs b/src/tokenizer/test.rs index 8d2d3df..2db49a9 100644 --- a/src/tokenizer/test.rs +++ b/src/tokenizer/test.rs @@ -11,7 +11,7 @@ fn test_empty_token() { let result = emptytok(OffsetStrIter::new("NULL ")); assert!(result.is_complete(), "result {:?} is not done", result); if let Result::Complete(_, tok) = result { - assert_eq!(tok.fragment, "NULL"); + assert_eq!(tok.fragment.as_ref(), "NULL"); assert_eq!(tok.typ, TokenType::EMPTY); } } @@ -21,7 +21,7 @@ fn test_assert_token() { let result = asserttok(OffsetStrIter::new("assert ")); assert!(result.is_complete(), "result {:?} is not done", result); if let Result::Complete(_, tok) = result { - assert_eq!(tok.fragment, "assert"); + assert_eq!(tok.fragment.as_ref(), "assert"); assert_eq!(tok.typ, TokenType::BAREWORD); } } @@ -31,7 +31,7 @@ fn test_out_token() { let result = outtok(OffsetStrIter::new("out ")); assert!(result.is_complete(), "result {:?} is not done", result); if let Result::Complete(_, tok) = result { - assert_eq!(tok.fragment, "out"); + assert_eq!(tok.fragment.as_ref(), "out"); assert_eq!(tok.typ, TokenType::BAREWORD); } } @@ -41,7 +41,7 @@ fn test_out_token_with_comment() { let result = outtok(OffsetStrIter::new("out//comment")); assert!(result.is_complete(), "result {:?} is not done", result); if let Result::Complete(_, tok) = result { - assert_eq!(tok.fragment, "out"); + assert_eq!(tok.fragment.as_ref(), "out"); assert_eq!(tok.typ, TokenType::BAREWORD); } } @@ -66,7 +66,7 @@ fn test_string_with_escaping() { let result = strtok(OffsetStrIter::new("\"foo \\\\ \\\"bar\"")); assert!(result.is_complete(), "result {:?} is not ok", result); if let Result::Complete(_, tok) = result { - assert_eq!(tok.fragment, "foo \\ \"bar".to_string()); + assert_eq!(tok.fragment.as_ref(), "foo \\ \"bar".to_string()); } } @@ -77,7 +77,7 @@ fn test_tokenize_bareword_with_dash() { assert!(result.is_ok(), "result {:?} is not ok", result); if let Ok(toks) = result { assert_eq!(toks.len(), 2); - assert_eq!(toks[0].fragment, "foo-bar"); + assert_eq!(toks[0].fragment.as_ref(), "foo-bar"); } } @@ -92,7 +92,7 @@ macro_rules! assert_token { ); if let Result::Complete(_, tok) = result { assert_eq!(tok.typ, $typ); - assert_eq!(tok.fragment, $input); + assert_eq!(tok.fragment.as_ref(), $input); } }; } @@ -204,7 +204,7 @@ fn test_parse_comment() { cmt, Token { typ: TokenType::COMMENT, - fragment: " comment".to_string(), + fragment: " comment".into(), pos: Position { file: None, line: 1, @@ -221,7 +221,7 @@ fn test_parse_comment() { cmt, Token { typ: TokenType::COMMENT, - fragment: " comment".to_string(), + fragment: " comment".into(), pos: Position { file: None, column: 1, @@ -238,7 +238,7 @@ fn test_parse_comment() { cmt, Token { typ: TokenType::COMMENT, - fragment: " comment".to_string(), + fragment: " comment".into(), pos: Position { file: None, column: 1, @@ -254,7 +254,7 @@ fn test_parse_comment() { #[test] fn test_match_word() { let input = vec![Token { - fragment: "foo".to_string(), + fragment: "foo".into(), typ: TokenType::BAREWORD, pos: Position { file: None, @@ -273,7 +273,7 @@ fn test_match_word() { #[test] fn test_match_word_empty_input() { let input = vec![Token { - fragment: "".to_string(), + fragment: "".into(), typ: TokenType::END, pos: Position { file: None, @@ -296,7 +296,7 @@ fn test_match_word_empty_input() { #[test] fn test_match_punct() { let input = vec![Token { - fragment: "!".to_string(), + fragment: "!".into(), typ: TokenType::PUNCT, pos: Position { file: None, @@ -315,7 +315,7 @@ fn test_match_punct() { #[test] fn test_match_type() { let input = vec![Token { - fragment: "foo".to_string(), + fragment: "foo".into(), typ: TokenType::BAREWORD, pos: Position { file: None,