Remove identiifer cache and extend some tests
This commit is contained in:
parent
95e22aa97f
commit
60df8b4d64
@ -14,22 +14,12 @@
|
|||||||
//! assert_eq!(foo.strong_count(), 4); // One for each of the above and one for the cache.
|
//! assert_eq!(foo.strong_count(), 4); // One for each of the above and one for the cache.
|
||||||
//! ```
|
//! ```
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
|
||||||
fmt::{self, Display, Formatter},
|
fmt::{self, Display, Formatter},
|
||||||
hash::Hash,
|
sync::Arc,
|
||||||
sync::{Arc, OnceLock, RwLock},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use serde::{de::Visitor, Deserialize, Serialize};
|
use serde::{de::Visitor, Deserialize, Serialize};
|
||||||
|
|
||||||
/// In-use identifiers.
|
|
||||||
static IDENTIFIER_CACHE: OnceLock<RwLock<HashMap<String, Identifier>>> = OnceLock::new();
|
|
||||||
|
|
||||||
/// Returns the identifier cache.
|
|
||||||
fn identifier_cache<'a>() -> &'a RwLock<HashMap<String, Identifier>> {
|
|
||||||
IDENTIFIER_CACHE.get_or_init(|| RwLock::new(HashMap::new()))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Key used to identify a value or type.
|
/// Key used to identify a value or type.
|
||||||
///
|
///
|
||||||
/// See the [module-level documentation](index.html) for more information.
|
/// See the [module-level documentation](index.html) for more information.
|
||||||
@ -40,17 +30,8 @@ impl Identifier {
|
|||||||
/// Creates a new identifier or returns a clone of an existing one from a cache.
|
/// Creates a new identifier or returns a clone of an existing one from a cache.
|
||||||
pub fn new<T: ToString>(text: T) -> Self {
|
pub fn new<T: ToString>(text: T) -> Self {
|
||||||
let string = text.to_string();
|
let string = text.to_string();
|
||||||
let mut cache = identifier_cache().write().unwrap();
|
|
||||||
|
|
||||||
if let Some(old) = cache.get(&string) {
|
Identifier(Arc::new(string.clone()))
|
||||||
old.clone()
|
|
||||||
} else {
|
|
||||||
let new = Identifier(Arc::new(string.clone()));
|
|
||||||
|
|
||||||
cache.insert(string, new.clone());
|
|
||||||
|
|
||||||
new
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_str(&self) -> &str {
|
pub fn as_str(&self) -> &str {
|
||||||
|
@ -389,10 +389,10 @@ impl Instruction {
|
|||||||
} else {
|
} else {
|
||||||
"???".to_string()
|
"???".to_string()
|
||||||
};
|
};
|
||||||
let mutable_display = if self.c_as_boolean() { "mut " } else { "" };
|
let mutable_display = if self.c_as_boolean() { "mut" } else { "" };
|
||||||
|
|
||||||
Some(format!(
|
Some(format!(
|
||||||
"L{local_index} = R{destination} {mutable_display}{identifier_display}"
|
"L{local_index} = R{destination} {mutable_display} {identifier_display}"
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
Operation::GetLocal => {
|
Operation::GetLocal => {
|
||||||
|
@ -727,22 +727,22 @@ impl<'src> Parser<'src> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn parse_if(&mut self, allow_assignment: bool, allow_return: bool) -> Result<(), ParseError> {
|
fn parse_if(&mut self, allow_assignment: bool, allow_return: bool) -> Result<(), ParseError> {
|
||||||
self.advance()?;
|
let length = self.chunk.len();
|
||||||
|
|
||||||
|
self.advance()?;
|
||||||
self.parse_expression()?;
|
self.parse_expression()?;
|
||||||
|
|
||||||
let is_explicit_true = matches!(self.previous_token, Token::Boolean("true"))
|
let is_explicit_true =
|
||||||
&& matches!(self.current_token, Token::LeftCurlyBrace);
|
matches!(self.previous_token, Token::Boolean("true")) && length == self.chunk.len() - 1;
|
||||||
|
|
||||||
|
if is_explicit_true {
|
||||||
let (mut load_boolean, load_boolean_position) =
|
let (mut load_boolean, load_boolean_position) =
|
||||||
self.chunk.pop_instruction(self.current_position)?;
|
self.chunk.pop_instruction(self.current_position)?;
|
||||||
|
|
||||||
debug_assert_eq!(load_boolean.operation(), Operation::LoadBoolean);
|
debug_assert_eq!(load_boolean.operation(), Operation::LoadBoolean);
|
||||||
|
|
||||||
load_boolean.set_c_to_boolean(is_explicit_true);
|
load_boolean.set_c_to_boolean(true);
|
||||||
self.emit_instruction(load_boolean, load_boolean_position);
|
self.emit_instruction(load_boolean, load_boolean_position);
|
||||||
|
|
||||||
if is_explicit_true {
|
|
||||||
self.increment_register()?;
|
self.increment_register()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -763,12 +763,6 @@ impl<'src> Parser<'src> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let jump_start = self.chunk.len();
|
let jump_start = self.chunk.len();
|
||||||
let load_boolean_index =
|
|
||||||
if let Operation::LoadBoolean = self.chunk.get_last_operation().unwrap() {
|
|
||||||
Some(self.chunk.len().saturating_sub(1))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Token::LeftCurlyBrace = self.current_token {
|
if let Token::LeftCurlyBrace = self.current_token {
|
||||||
self.parse_block(allow_assignment, allow_return)?;
|
self.parse_block(allow_assignment, allow_return)?;
|
||||||
@ -793,8 +787,6 @@ impl<'src> Parser<'src> {
|
|||||||
jump_position,
|
jump_position,
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(index) = load_boolean_index {}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
//! Description of a kind of value.
|
//! Value types.
|
||||||
//!
|
//!
|
||||||
//! Most types are concrete and specific, the exceptions are the Generic and Any types.
|
//! Most types are concrete and specific, the exceptions are the Generic and Any types.
|
||||||
//!
|
//!
|
||||||
|
@ -21,11 +21,13 @@ fn r#if() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn less_than() {
|
fn less_than() {
|
||||||
assert_eq!(run("1 < 2"), Ok(Some(Value::boolean(true))));
|
assert_eq!(run("1 < 2"), Ok(Some(Value::boolean(true))));
|
||||||
|
assert_eq!(run("2 < 1"), Ok(Some(Value::boolean(false))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn greater_than() {
|
fn greater_than() {
|
||||||
assert_eq!(run("1 > 2"), Ok(Some(Value::boolean(false))));
|
assert_eq!(run("1 > 2"), Ok(Some(Value::boolean(false))));
|
||||||
|
assert_eq!(run("2 > 1"), Ok(Some(Value::boolean(true))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -43,11 +45,13 @@ fn greater_than_or_equal() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn equal() {
|
fn equal() {
|
||||||
assert_eq!(run("1 == 1"), Ok(Some(Value::boolean(true))));
|
assert_eq!(run("1 == 1"), Ok(Some(Value::boolean(true))));
|
||||||
|
assert_eq!(run("1 == 2"), Ok(Some(Value::boolean(false))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn not_equal() {
|
fn not_equal() {
|
||||||
assert_eq!(run("1 != 1"), Ok(Some(Value::boolean(false))));
|
assert_eq!(run("1 != 1"), Ok(Some(Value::boolean(false))));
|
||||||
|
assert_eq!(run("2 != 1"), Ok(Some(Value::boolean(true))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
Loading…
Reference in New Issue
Block a user