Skip to content

Commit

Permalink
reducing costs
Browse files Browse the repository at this point in the history
  • Loading branch information
notJoon committed Jun 15, 2023
1 parent dcae43c commit 63abf6a
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 143 deletions.
79 changes: 29 additions & 50 deletions src/borrow_checker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,10 @@ impl<'a> BorrowChecker<'a> {
// but, we allows to have multiple immutable borrows of the same variable.
// so, modified it to check only `Borrowed` state.
BorrowState::Borrowed => {
return Err(BorrowError::BorrowedMutable(ident.to_string()));
return Err(BorrowError::BorrowedMutable(ident.into()));
}
BorrowState::Uninitialized => {
return Err(BorrowError::DeclaredWithoutInitialValue(
ident.to_string(),
));
return Err(BorrowError::DeclaredWithoutInitialValue(ident.into()));
}
_ => {}
}
Expand All @@ -123,16 +121,16 @@ impl<'a> BorrowChecker<'a> {
return Ok(());
}

Err(BorrowError::VariableNotDefined(ident.to_string()))
Err(BorrowError::VariableNotDefined(ident.into()))
}
(true, _) => Err(BorrowError::VariableNotInitialized(name.to_string())),
(true, _) => Err(BorrowError::VariableNotInitialized(name.into())),
(false, Some(expr)) => {
self.check_expression(expr)?;
self.insert_borrow(name, BorrowState::Initialized);

Ok(())
}
(false, None) => Err(BorrowError::DeclaredWithoutInitialValue(name.to_string())),
(false, None) => Err(BorrowError::DeclaredWithoutInitialValue(name.into())),
}
}

Expand All @@ -144,17 +142,17 @@ impl<'a> BorrowChecker<'a> {
if let Some(Expression::Ident(ref ident)) = value {
if let Some(state) = self.get_borrow(ident) {
if state == &BorrowState::Borrowed {
return Err(BorrowError::InvalidBorrowMutablyBorrowed(ident.to_string()));
return Err(BorrowError::InvalidBorrowMutablyBorrowed(ident.into()));
}

self.insert_borrow(name, BorrowState::ImmutBorrowed);
return Ok(());
}

return Err(BorrowError::VariableNotDefined(ident.to_string()));
return Err(BorrowError::VariableNotDefined(ident.into()));
}

Err(BorrowError::InvalidBorrow(name.to_string()))
Err(BorrowError::InvalidBorrow(name.into()))
}

fn check_value_expr(&mut self, value: &'a Option<Expression>) -> BorrowResult {
Expand Down Expand Up @@ -202,14 +200,14 @@ impl<'a> BorrowChecker<'a> {
fn declare(&mut self, var: &'a str) -> BorrowResult {
if let Some(scope) = self.borrows.last_mut() {
if scope.contains_key(var) {
return Err(BorrowError::VariableDeclaredDuplicate(var.to_string()));
return Err(BorrowError::VariableDeclaredDuplicate(var.into()));
}

scope.insert(var, BorrowState::Uninitialized);
return Ok(());
}

Err(BorrowError::NoScopeAvailable(var.to_string()))
Err(BorrowError::NoScopeAvailable(var.into()))
}
/// `check_function_call` checks a function call.
///
Expand All @@ -221,7 +219,7 @@ impl<'a> BorrowChecker<'a> {

if let Expression::Ident(ident) = arg {
if let Some(BorrowState::Borrowed) = self.get_borrow(ident) {
return Err(BorrowError::BorrowedMutable(ident.to_string()));
return Err(BorrowError::BorrowedMutable(ident.into()));
}
}
}
Expand All @@ -241,7 +239,7 @@ impl<'a> BorrowChecker<'a> {
let borrow = self.get_borrow(var);

if let Some(BorrowState::Borrowed) = borrow {
return Err(BorrowError::BorrowedMutable(var.to_string()));
return Err(BorrowError::BorrowedMutable(var.into()));
}
}

Expand All @@ -254,7 +252,7 @@ impl<'a> BorrowChecker<'a> {
// if the expression is an identifier, check if the variable is already borrowed
Expression::Ident(ident) => {
if self.get_borrow(ident).is_none() {
return Err(BorrowError::VariableNotInitialized(ident.to_string()));
return Err(BorrowError::VariableNotInitialized(ident.into()));
}
}

Expand Down Expand Up @@ -282,7 +280,7 @@ impl<'a> BorrowChecker<'a> {
return Ok(());
}

Err(BorrowError::CannotBorrowMutable(name.to_string()))
Err(BorrowError::CannotBorrowMutable(name.into()))
}
/// `borrow_imm` method should handle the logic of mutably borrowing a variable.
///
Expand All @@ -295,21 +293,8 @@ impl<'a> BorrowChecker<'a> {
return Ok(());
}

Err(BorrowError::CannotBorrowImmutable(name.to_string()))
Err(BorrowError::CannotBorrowImmutable(name.into()))
}
/// `free` method should handle the logic of releasing a borrow
/// when a variable goes out of scope.
///
/// It should remove the variable from the `BorrowChecker`.
fn free(&mut self, var: &'a str) -> Option<BorrowState> {
if !self.is_borrow_contains_key(var) {
return None;
}

self.remove_borrow(var)
}

/// helper functions

fn get_borrow(&mut self, var: &'a str) -> Option<&BorrowState> {
for scope in self.borrows.iter().rev() {
Expand Down Expand Up @@ -367,10 +352,7 @@ mod borrow_tests {
let result = setup(input);
let result = checker.check(&result);

assert_eq!(
result,
Err(BorrowError::VariableNotDefined("b".to_string()))
);
assert_eq!(result, Err(BorrowError::VariableNotDefined("b".into())));
}

#[test]
Expand All @@ -379,12 +361,15 @@ mod borrow_tests {

// let b = &a;
let stmts = vec![Statement::VariableDecl {
name: "b".to_string(),
value: Some(Expression::Reference("a".to_string())),
name: "b".into(),
value: Some(Expression::Reference("a".into())),
is_borrowed: true,
}];

assert!(checker.check(&stmts).is_err());
assert_eq!(
checker.check(&stmts),
Err(BorrowError::VariableNotDefined("a".into()))
);
}

#[test]
Expand Down Expand Up @@ -413,7 +398,7 @@ mod borrow_tests {

assert_eq!(
result,
Err(BorrowError::DeclaredWithoutInitialValue("a".to_string()))
Err(BorrowError::DeclaredWithoutInitialValue("a".into()))
);
}

Expand Down Expand Up @@ -464,10 +449,7 @@ mod borrow_tests {
let result = setup(input);
let result = checker.check(&result);

assert_eq!(
result,
Err(BorrowError::VariableNotDefined("b".to_string()))
);
assert_eq!(result, Err(BorrowError::VariableNotDefined("b".into())));
}

#[test]
Expand Down Expand Up @@ -527,10 +509,7 @@ mod borrow_tests {
let result = setup(input);
let result = checker.check(&result);

assert_eq!(
result,
Err(BorrowError::VariableNotDefined("z".to_string()))
);
assert_eq!(result, Err(BorrowError::VariableNotDefined("z".into())));
}

#[test]
Expand Down Expand Up @@ -627,19 +606,19 @@ mod borrow_tests {
let mut checker = BorrowChecker::new();
let stmts = vec![
Statement::VariableDecl {
name: "x".to_string(),
name: "x".into(),
value: None,
is_borrowed: false,
},
Statement::Scope(vec![Statement::VariableDecl {
name: "y".to_string(),
value: Some(Expression::Reference("x".to_string())),
name: "y".into(),
value: Some(Expression::Reference("x".into())),
is_borrowed: true,
}]),
];
assert_eq!(
checker.check(&stmts),
Err(BorrowError::DeclaredWithoutInitialValue("x".to_string())),
Err(BorrowError::DeclaredWithoutInitialValue("x".into())),
);
}

Expand Down
14 changes: 7 additions & 7 deletions src/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,13 @@ impl<'a> Evaluator<'a> {
None => 0, // default value is `0`
};

self.insert_global(name.clone(), value);
self.insert_global(name.to_owned(), value);

Ok(None)
}
Statement::FunctionDef { name, args, body } => {
self.functions
.insert(name.clone(), (args.clone().unwrap(), body));
.insert(name.to_owned(), (args.to_owned().unwrap(), body));

Ok(None)
}
Expand Down Expand Up @@ -195,12 +195,12 @@ mod eval_test {
// let y = 10;
let stmts = vec![
Statement::VariableDecl {
name: "x".to_string(),
name: "x".into(),
value: Some(Expression::Number(5)),
is_borrowed: false,
},
Statement::VariableDecl {
name: "y".to_string(),
name: "y".into(),
value: Some(Expression::Number(10)),
is_borrowed: false,
},
Expand All @@ -219,14 +219,14 @@ mod eval_test {

let stmts = vec![
Statement::VariableDecl {
name: "x".to_string(),
name: "x".into(),
value: Some(Expression::Number(5)),
is_borrowed: false,
},
Statement::VariableDecl {
name: "y".to_string(),
name: "y".into(),
value: Some(Expression::BinaryOp {
lhs: Box::new(Expression::Ident("x".to_string())),
lhs: Box::new(Expression::Ident("x".into())),
op: BinaryOp::Plus,
rhs: Box::new(Expression::Number(10)),
}),
Expand Down
30 changes: 13 additions & 17 deletions src/ownership.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ impl OwnershipGraph {
///
/// A node is added when a new variable is declared.
pub fn add_owner(&mut self, owner: &str, variable: &str) {
let entry = self.graph.entry(owner.to_string()).or_insert_with(Vec::new);
let entry = self.graph.entry(owner.into()).or_insert_with(Vec::new);

if !entry.contains(&variable.to_string()) {
entry.push(variable.to_string());
if !entry.contains(&variable.into()) {
entry.push(variable.into());
}
}

Expand All @@ -41,8 +41,8 @@ impl OwnershipGraph {
/// An edge is added when a variable borrows from another variable.
pub fn add_borrower(&mut self, owner: &str, borrower: &str) {
if let Some(borrowers) = self.graph.get_mut(owner) {
if !borrowers.contains(&borrower.to_string()) {
borrowers.push(borrower.to_string());
if !borrowers.contains(&borrower.into()) {
borrowers.push(borrower.into());
}
}
}
Expand Down Expand Up @@ -79,7 +79,7 @@ impl Default for OwnershipGraph {
fn build_ownership_graph(stmts: &[Statement]) -> Result<OwnershipGraph, OwnerGraphError> {
const GLOBAL: &str = "global_var";
let mut graph = OwnershipGraph::default();
let mut current_owner = GLOBAL.to_string();
let mut current_owner = GLOBAL.into();

for stmt in stmts {
match stmt {
Expand All @@ -90,17 +90,16 @@ fn build_ownership_graph(stmts: &[Statement]) -> Result<OwnershipGraph, OwnerGra
} => {
if *is_borrowed {
if let Some(Expression::Reference(ref_var)) = value {
current_owner = ref_var.clone();
current_owner = ref_var.to_owned();
graph.add_borrower(&current_owner, name);
// current_owner = name.clone();
}
} else {
current_owner = GLOBAL.to_string();
current_owner = GLOBAL.into();
}
graph.add_owner(&current_owner, name);
}
Statement::Scope(scope) => {
let prev_owner = current_owner.clone();
let prev_owner = current_owner.to_owned();
let mut declared_in_scope = vec![];

for inner_stmt in scope {
Expand All @@ -110,24 +109,23 @@ fn build_ownership_graph(stmts: &[Statement]) -> Result<OwnershipGraph, OwnerGra
is_borrowed,
} = inner_stmt
{
declared_in_scope.push(name.clone());
declared_in_scope.push(name.to_owned());

if *is_borrowed {
if let Some(Expression::Reference(ref_var)) = value {
current_owner = ref_var.clone();
current_owner = ref_var.to_owned();
graph.add_borrower(&current_owner, name);
// current_owner = name.clone();
}
}

graph.add_owner(&prev_owner, name);
current_owner = name.clone();
current_owner = name.into();
}
}

for var in declared_in_scope {
graph.remove_owner(&prev_owner, &var);
current_owner = prev_owner.clone();
current_owner = prev_owner.to_owned();
}
}

Expand Down Expand Up @@ -323,8 +321,6 @@ mod ownership_graph_tests {

let graph = build_ownership_graph(&stmts).unwrap();

println!("{:?}", graph);

assert_eq!(
graph,
OwnershipGraph {
Expand Down
Loading

0 comments on commit 63abf6a

Please sign in to comment.