Less memory allocations at runtime
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::ops::Op;
|
||||
use super::types::{Dictionary, SourceSpan};
|
||||
use super::words::compile_word;
|
||||
@@ -118,7 +120,7 @@ fn compile(tokens: &[Token], dict: &Dictionary) -> Result<Vec<Op>, String> {
|
||||
ops.push(Op::PushFloat(*f, Some(*span)));
|
||||
}
|
||||
}
|
||||
Token::Str(s, span) => ops.push(Op::PushStr(s.clone(), Some(*span))),
|
||||
Token::Str(s, span) => ops.push(Op::PushStr(Arc::from(s.as_str()), Some(*span))),
|
||||
Token::Word(w, span) => {
|
||||
let word = w.as_str();
|
||||
if word == "{" {
|
||||
@@ -129,7 +131,7 @@ fn compile(tokens: &[Token], dict: &Dictionary) -> Result<Vec<Op>, String> {
|
||||
start: span.start,
|
||||
end: end_span.end,
|
||||
};
|
||||
ops.push(Op::Quotation(quote_ops, Some(body_span)));
|
||||
ops.push(Op::Quotation(Arc::from(quote_ops), Some(body_span)));
|
||||
} else if word == "}" {
|
||||
return Err("unexpected }".into());
|
||||
} else if word == ":" {
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::types::SourceSpan;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum Op {
|
||||
PushInt(i64, Option<SourceSpan>),
|
||||
PushFloat(f64, Option<SourceSpan>),
|
||||
PushStr(String, Option<SourceSpan>),
|
||||
PushStr(Arc<str>, Option<SourceSpan>),
|
||||
Dup,
|
||||
Dupn,
|
||||
Drop,
|
||||
@@ -71,7 +73,7 @@ pub enum Op {
|
||||
Ftom,
|
||||
SetTempo,
|
||||
Every,
|
||||
Quotation(Vec<Op>, Option<SourceSpan>),
|
||||
Quotation(Arc<[Op]>, Option<SourceSpan>),
|
||||
When,
|
||||
Unless,
|
||||
Adsr,
|
||||
|
||||
@@ -60,9 +60,9 @@ pub(super) type CmdSnapshot<'a> = (Option<&'a Value>, &'a [(String, Value)]);
|
||||
pub enum Value {
|
||||
Int(i64, Option<SourceSpan>),
|
||||
Float(f64, Option<SourceSpan>),
|
||||
Str(String, Option<SourceSpan>),
|
||||
Quotation(Vec<Op>, Option<SourceSpan>),
|
||||
CycleList(Vec<Value>),
|
||||
Str(Arc<str>, Option<SourceSpan>),
|
||||
Quotation(Arc<[Op]>, Option<SourceSpan>),
|
||||
CycleList(Arc<[Value]>),
|
||||
}
|
||||
|
||||
impl PartialEq for Value {
|
||||
@@ -116,7 +116,7 @@ impl Value {
|
||||
match self {
|
||||
Value::Int(i, _) => i.to_string(),
|
||||
Value::Float(f, _) => f.to_string(),
|
||||
Value::Str(s, _) => s.clone(),
|
||||
Value::Str(s, _) => s.to_string(),
|
||||
Value::Quotation(..) => String::new(),
|
||||
Value::CycleList(_) => String::new(),
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use rand::rngs::StdRng;
|
||||
use rand::{Rng as RngTrait, SeedableRng};
|
||||
use std::borrow::Cow;
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::compiler::compile_script;
|
||||
use super::ops::Op;
|
||||
@@ -423,7 +424,7 @@ impl Forth {
|
||||
let val = if values.len() == 1 {
|
||||
values.into_iter().next().unwrap()
|
||||
} else {
|
||||
Value::CycleList(values)
|
||||
Value::CycleList(Arc::from(values))
|
||||
};
|
||||
cmd.set_sound(val);
|
||||
}
|
||||
@@ -435,7 +436,7 @@ impl Forth {
|
||||
let val = if values.len() == 1 {
|
||||
values.into_iter().next().unwrap()
|
||||
} else {
|
||||
Value::CycleList(values)
|
||||
Value::CycleList(Arc::from(values))
|
||||
};
|
||||
cmd.set_param(param.clone(), val);
|
||||
}
|
||||
@@ -735,7 +736,7 @@ impl Forth {
|
||||
} else {
|
||||
let key = format!("__chain_{}_{}__", ctx.bank, ctx.pattern);
|
||||
let val = format!("{bank}:{pattern}");
|
||||
self.vars.lock().unwrap().insert(key, Value::Str(val, None));
|
||||
self.vars.lock().unwrap().insert(key, Value::Str(Arc::from(val), None));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use std::collections::HashMap;
|
||||
use std::sync::LazyLock;
|
||||
use std::sync::{Arc, LazyLock};
|
||||
|
||||
use super::ops::Op;
|
||||
use super::theory;
|
||||
@@ -3031,7 +3031,7 @@ pub(super) fn compile_word(
|
||||
// @varname - fetch variable
|
||||
if let Some(var_name) = name.strip_prefix('@') {
|
||||
if !var_name.is_empty() {
|
||||
ops.push(Op::PushStr(var_name.to_string(), span));
|
||||
ops.push(Op::PushStr(Arc::from(var_name), span));
|
||||
ops.push(Op::Get);
|
||||
return true;
|
||||
}
|
||||
@@ -3040,7 +3040,7 @@ pub(super) fn compile_word(
|
||||
// !varname - store into variable
|
||||
if let Some(var_name) = name.strip_prefix('!') {
|
||||
if !var_name.is_empty() {
|
||||
ops.push(Op::PushStr(var_name.to_string(), span));
|
||||
ops.push(Op::PushStr(Arc::from(var_name), span));
|
||||
ops.push(Op::Set);
|
||||
return true;
|
||||
}
|
||||
@@ -3073,6 +3073,6 @@ pub(super) fn compile_word(
|
||||
}
|
||||
|
||||
// Unrecognized token becomes a string
|
||||
ops.push(Op::PushStr(name.to_string(), span));
|
||||
ops.push(Op::PushStr(Arc::from(name), span));
|
||||
true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user