Split out name_allocator

This commit is contained in:
Andrew Morris
2022-05-13 12:12:46 +10:00
parent 2079053642
commit d3aa4ed4fa
3 changed files with 60 additions and 58 deletions

View File

@@ -1,6 +1,5 @@
use std::process::exit;
use std::{path::Path, sync::Arc};
use std::collections::HashSet;
use std::fs::File;
use std::io::prelude::*;
@@ -12,6 +11,7 @@ use swc_common::{
use swc_ecma_parser::{TsConfig, Syntax};
use super::scope::{Scope, MappedName, init_scope, ScopeTrait};
use super::name_allocator::NameAllocator;
pub fn command(args: &Vec<String>) {
if args.len() != 3 {
@@ -315,63 +315,6 @@ impl Compiler {
}
}
#[derive(Default)]
struct NameAllocator {
used_names: HashSet<String>,
released_names: Vec<String>,
}
impl NameAllocator {
fn allocate(&mut self, based_on_name: &String) -> String {
match self.released_names.pop() {
Some(name) => {
// FIXME: When reallocating a register we need to ensure we don't read
// the leftover value
self.used_names.insert(name.clone());
return name;
},
None => {},
};
if !self.used_names.contains(based_on_name) {
self.used_names.insert(based_on_name.clone());
return based_on_name.clone();
}
return self.allocate_numbered(&(based_on_name.clone() + "_"));
}
fn allocate_numbered(&mut self, prefix: &String) -> String {
match self.released_names.pop() {
Some(name) => {
// FIXME: When reallocating a register we need to ensure we don't read
// the leftover value
self.used_names.insert(name.clone());
return name;
},
None => {},
};
let mut i = 0_u64;
loop {
let candidate = prefix.clone() + &i.to_string();
if !self.used_names.contains(&candidate) {
self.used_names.insert(candidate.clone());
return candidate;
}
i += 1;
}
}
fn release(&mut self, name: &String) {
self.used_names.remove(name);
self.released_names.push(name.clone());
}
}
struct FunctionCompiler {
definition: Vec<String>,
reg_allocator: NameAllocator,

View File

@@ -3,6 +3,7 @@ mod run;
mod virtual_machine;
mod compile;
mod scope;
mod name_allocator;
use std::env;
use std::process::exit;

View File

@@ -0,0 +1,58 @@
use std::collections::HashSet;
#[derive(Default)]
pub struct NameAllocator {
used_names: HashSet<String>,
released_names: Vec<String>,
}
impl NameAllocator {
pub fn allocate(&mut self, based_on_name: &String) -> String {
match self.released_names.pop() {
Some(name) => {
// FIXME: When reallocating a register we need to ensure we don't read
// the leftover value
self.used_names.insert(name.clone());
return name;
},
None => {},
};
if !self.used_names.contains(based_on_name) {
self.used_names.insert(based_on_name.clone());
return based_on_name.clone();
}
return self.allocate_numbered(&(based_on_name.clone() + "_"));
}
pub fn allocate_numbered(&mut self, prefix: &String) -> String {
match self.released_names.pop() {
Some(name) => {
// FIXME: When reallocating a register we need to ensure we don't read
// the leftover value
self.used_names.insert(name.clone());
return name;
},
None => {},
};
let mut i = 0_u64;
loop {
let candidate = prefix.clone() + &i.to_string();
if !self.used_names.contains(&candidate) {
self.used_names.insert(candidate.clone());
return candidate;
}
i += 1;
}
}
pub fn release(&mut self, name: &String) {
self.used_names.remove(name);
self.released_names.push(name.clone());
}
}