Skip to content
Open

Path #308

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions src/vm/builtins/builtin_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ macro_rules! impl_type {

let mut __arg_idx = 0usize;

impl_type!(@macro dict [$] $vm);
impl_type!(@macro array [$] $vm);

$(

$(
Expand Down Expand Up @@ -395,6 +398,51 @@ macro_rules! impl_type {
(@extra Key ($name:ident, $vm:ident, $args:ident, $arg_index:ident) ) => {
let $name = $args[$arg_index];
};

(@macro dict [$dollar:tt] $vm:ident) => {
macro_rules! dict {
{ $dollar($key:ident: $value:expr $dollar(,)?)* } => {
use ahash::AHashMap;
use lasso::Spur;
use crate::vm::interpreter::{ValueKey, Visibility};
let mut dict: AHashMap<Spur, (ValueKey, Visibility)> = AHashMap::new();
$dollar(
dict.insert(
$vm.intern(stringify!($key)),
(
$vm.memory.insert(StoredValue {
value: $value,
area: CodeArea {
src: crate::sources::SpwnSource::Core(Default::default()),
span: crate::sources::CodeSpan { start: 0, end: 0 }
}
}),
Visibility::Public,
)
);
)*
Value::Dict(dict)
}
}
};
(@macro array [$dollar:tt] $vm:ident) => {
macro_rules! array {
[ $dollar($value:expr $dollar(,)?)* ] => {
let mut array: Vec<$crate::vm::interpreter::ValueKey> = Vec::new();
$dollar(
array.push(
$vm.memory.insert(StoredValue {
value: $value,
area: CodeArea {
src: crate::sources::SpwnSource::Core(Default::default()),
span: crate::sources::CodeSpan { start: 0, end: 0 }
}
}),
);
)*
}
}
};
}

pub use impl_type;
44 changes: 44 additions & 0 deletions src/vm/builtins/core/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,5 +100,49 @@ impl_type! {
slf.get_mut_ref(vm).insert(0, cloned);
Value::Empty
}

fn pick(Array(array) as self, quantity: Empty | Int if (>0) = {()}, Bool(duplicates) as allow_duplicates = {false}) {
use rand::prelude::*;

let mut rng = rand::thread_rng();

match quantity {
QuantityValue::Empty(_) => {
array.choose(&mut rng).map_or(Value::Maybe(None), |v| {
let value_key = vm.deep_clone_key_insert(*v);
vm.memory[value_key].value.clone()
})
},
QuantityValue::Int(q) => {
if array.is_empty() { return Ok(Value::Array(vec![])) }

if duplicates {
let mut output = vec![];
for i in 0..q.0 {
output.push(vm.deep_clone_key_insert(*array.choose(&mut rng).unwrap()))
}
Value::Array(output)
} else {
let mut cloned_array: Vec<_> = array.iter().map(|v| vm.deep_clone_key_insert(*v)).collect();
let mut output = vec![];
for i in 0..q.0.min(cloned_array.len() as i64) {
output.push(cloned_array.remove(rng.gen_range(0..cloned_array.len())))
}
Value::Array(output)
}
},
}
}

fn shuffle(Array(array) as self) {
use rand::prelude::*;

let mut rng = rand::thread_rng();

let mut cloned_array = array.iter().map(|v| vm.deep_clone_key_insert(*v)).collect::<Vec<_>>();
cloned_array.shuffle(&mut rng);

Value::Array(cloned_array)
}
}
}
31 changes: 31 additions & 0 deletions src/vm/builtins/core/builtins.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::hash::Hasher;
use std::time::SystemTime;

use crate::gd::gd_object::{GdObject, Trigger};
use crate::gd::ids::Id;
Expand Down Expand Up @@ -91,5 +92,35 @@ impl_type! {
vm.hash_value(value, &mut hasher);
Value::Int(unsafe { std::mem::transmute::<u64, i64>(hasher.finish()) })
}

fn time(Builtins as self) -> Int {
match std::time::SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) {
Ok(time) => Value::Float(time.as_secs_f64()),
Err(e) => {
// return Err(Runti) // not sure if there needs to be added a new error for this, idk
Value::Float(0.0)
}
}
}

fn random(Builtins as self, input: Array | Range | Empty = {()}) -> Float {
use rand::prelude::*;

let mut rng = rand::thread_rng();

match input {
InputValue::Array(array) =>
array.choose(&mut rng).map_or(Value::Maybe(None), |v| {
let value_key = vm.deep_clone_key_insert(*v);
vm.memory[value_key].value.clone()
}),
InputValue::Range(RangeDeref(start, end, step)) =>
Value::Int((start..end).step_by(step).choose(&mut rng).unwrap_or(0)),
InputValue::Empty(_) =>
Value::Float(rng.gen::<f64>()), // 0.0..1.0
_ =>
unreachable!(),
}
}
}
}
51 changes: 49 additions & 2 deletions src/vm/builtins/core/dict.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::sources::CodeArea;
use crate::vm::builtins::builtin_utils::impl_type;
use crate::vm::interpreter::Visibility;
use crate::vm::value::Value;
use crate::vm::value::{Value, StoredValue};

impl_type! {
impl Dict {
Expand All @@ -18,5 +18,52 @@ impl_type! {

// // Value::Dict(dict.clone())
// }

// what about visibility?
fn size(Dict(dict) as self) -> Int {
Value::Int(dict.len() as i64)
}

// TODO: visibility
fn keys(Dict(dict) as self) -> Array {
Value::Array(dict.keys().map(|v|
vm.memory.insert(StoredValue {
value: Value::String(vm.resolve(v).chars().collect()),
area: CodeArea { // TODO: hire a spwn dev to fix this, since I am not a spwn dev.
src: crate::sources::SpwnSource::Core(Default::default()),
span: crate::sources::CodeSpan { start: 0, end: 0 }
},
})
).collect())
}
fn values(Dict(dict) as self) -> Array {
Value::Array(dict.values().map(|v| {
vm.deep_clone_key_insert(v.0)
}).collect())
}
fn items(Dict(dict) as self) -> Array {
let mut items = vec![];

for (key, value) in &dict {
items.push(StoredValue {
value: Value::Array(vec![
vm.memory.insert(StoredValue {
value: Value::String(vm.resolve(key).chars().collect()),
area: CodeArea {
src: crate::sources::SpwnSource::Core(Default::default()),
span: crate::sources::CodeSpan { start: 0, end: 0 }
},
}),
vm.deep_clone_key_insert(value.0),
]),
area: CodeArea {
src: crate::sources::SpwnSource::Core(Default::default()),
span: crate::sources::CodeSpan { start: 0, end: 0 }
},
});
}

Value::Array(items.iter().map(|v| vm.memory.insert(v.clone())).collect())
}
}
}
5 changes: 4 additions & 1 deletion src/vm/builtins/core/float.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,14 @@ impl_type! {
fn floor(Float(n) as self) -> Float {
Value::Float(n.floor())
}
fn trunc(Float(n) as self) -> Float {
Value::Float(n.trunc())
}

fn sqrt(Float(n) as self) -> Float {
Value::Float(n.sqrt())
}
fn log(Float(n) as self, Float(base) as base = {2.7182818284590452353602874713527}) -> Float {
fn log(Float(n) as self, Float(base) as base = {2.71828182845904523536028747135266250}) -> Float {
Value::Float(n.log(base))
}

Expand Down
13 changes: 12 additions & 1 deletion src/vm/builtins/core/int.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ impl_type! {
fn sqrt(Int(n) as self) -> Float {
Value::Float((n as f64).sqrt())
}
fn log(Int(n) as self, Float(base) as base = {2.7182818284590452353602874713527}) -> Float {
fn log(Int(n) as self, Float(base) as base = {2.71828182845904523536028747135266250}) -> Float {
Value::Float((n as f64).log(base))
}
fn clamp(Int(n) as self, Int(min) as min, Int(max) as max) -> Float {
Expand All @@ -27,5 +27,16 @@ impl_type! {
fn wrap(Int(n) as self, Int(min) as min, Int(max) as max) -> Float {
Value::Int(((n - min) % (max - min)) + min)
}
fn ordinal(Int(n) as self) -> String {
let n = n.abs();
let last_digit = n % 10;
let is_ten = n / 10 % 10 == 1;
Value::String((n.to_string() + match (last_digit, is_ten) {
(1, false) => "st",
(2, false) => "nd",
(3, false) => "rd",
(_, _) => "th",
}).chars().collect())
}
}
}
1 change: 1 addition & 0 deletions src/vm/builtins/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ pub mod error;
pub mod float;
pub mod int;
pub mod string;
pub mod path;
Loading