use NotNan as number representation
This commit is contained in:
parent
d8c999d5ab
commit
e41d6b802b
4
pkg/rudus.d.ts
vendored
4
pkg/rudus.d.ts
vendored
|
@ -14,8 +14,8 @@ export interface InitOutput {
|
||||||
readonly __wbindgen_malloc: (a: number, b: number) => number;
|
readonly __wbindgen_malloc: (a: number, b: number) => number;
|
||||||
readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
||||||
readonly __wbindgen_export_6: WebAssembly.Table;
|
readonly __wbindgen_export_6: WebAssembly.Table;
|
||||||
readonly closure354_externref_shim: (a: number, b: number, c: any) => void;
|
readonly closure357_externref_shim: (a: number, b: number, c: any) => void;
|
||||||
readonly closure377_externref_shim: (a: number, b: number, c: any, d: any) => void;
|
readonly closure380_externref_shim: (a: number, b: number, c: any, d: any) => void;
|
||||||
readonly __wbindgen_start: () => void;
|
readonly __wbindgen_start: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -240,13 +240,13 @@ function _assertNum(n) {
|
||||||
function __wbg_adapter_20(arg0, arg1, arg2) {
|
function __wbg_adapter_20(arg0, arg1, arg2) {
|
||||||
_assertNum(arg0);
|
_assertNum(arg0);
|
||||||
_assertNum(arg1);
|
_assertNum(arg1);
|
||||||
wasm.closure354_externref_shim(arg0, arg1, arg2);
|
wasm.closure357_externref_shim(arg0, arg1, arg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
function __wbg_adapter_46(arg0, arg1, arg2, arg3) {
|
function __wbg_adapter_46(arg0, arg1, arg2, arg3) {
|
||||||
_assertNum(arg0);
|
_assertNum(arg0);
|
||||||
_assertNum(arg1);
|
_assertNum(arg1);
|
||||||
wasm.closure377_externref_shim(arg0, arg1, arg2, arg3);
|
wasm.closure380_externref_shim(arg0, arg1, arg2, arg3);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function __wbg_load(module, imports) {
|
async function __wbg_load(module, imports) {
|
||||||
|
@ -403,8 +403,8 @@ function __wbg_get_imports() {
|
||||||
_assertBoolean(ret);
|
_assertBoolean(ret);
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
imports.wbg.__wbindgen_closure_wrapper8124 = function() { return logError(function (arg0, arg1, arg2) {
|
imports.wbg.__wbindgen_closure_wrapper8156 = function() { return logError(function (arg0, arg1, arg2) {
|
||||||
const ret = makeMutClosure(arg0, arg1, 355, __wbg_adapter_20);
|
const ret = makeMutClosure(arg0, arg1, 358, __wbg_adapter_20);
|
||||||
return ret;
|
return ret;
|
||||||
}, arguments) };
|
}, arguments) };
|
||||||
imports.wbg.__wbindgen_debug_string = function(arg0, arg1) {
|
imports.wbg.__wbindgen_debug_string = function(arg0, arg1) {
|
||||||
|
|
Binary file not shown.
4
pkg/rudus_bg.wasm.d.ts
vendored
4
pkg/rudus_bg.wasm.d.ts
vendored
|
@ -9,6 +9,6 @@ export const __wbindgen_free: (a: number, b: number, c: number) => void;
|
||||||
export const __wbindgen_malloc: (a: number, b: number) => number;
|
export const __wbindgen_malloc: (a: number, b: number) => number;
|
||||||
export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
||||||
export const __wbindgen_export_6: WebAssembly.Table;
|
export const __wbindgen_export_6: WebAssembly.Table;
|
||||||
export const closure354_externref_shim: (a: number, b: number, c: any) => void;
|
export const closure357_externref_shim: (a: number, b: number, c: any) => void;
|
||||||
export const closure377_externref_shim: (a: number, b: number, c: any, d: any) => void;
|
export const closure380_externref_shim: (a: number, b: number, c: any, d: any) => void;
|
||||||
export const __wbindgen_start: () => void;
|
export const __wbindgen_start: () => void;
|
||||||
|
|
101
src/base.rs
101
src/base.rs
|
@ -152,17 +152,11 @@ pub fn append(x: &Value, y: &Value) -> Value {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dec(x: &Value) -> Value {
|
pub fn dec(x: &Value) -> Value {
|
||||||
match x {
|
Value::from_f64(x.as_f64() - 1.0)
|
||||||
Value::Number(n) => Value::Number(n - 1.0),
|
|
||||||
_ => unreachable!("internal Ludus error"),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn inc(x: &Value) -> Value {
|
pub fn inc(x: &Value) -> Value {
|
||||||
match x {
|
Value::from_f64(x.as_f64() + 1.0)
|
||||||
Value::Number(n) => Value::Number(n + 1.0),
|
|
||||||
_ => unreachable!("internal Ludus error"),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn div(x: &Value, y: &Value) -> Value {
|
pub fn div(x: &Value, y: &Value) -> Value {
|
||||||
|
@ -180,10 +174,9 @@ pub fn mult(x: &Value, y: &Value) -> Value {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pow(x: &Value, y: &Value) -> Value {
|
pub fn pow(x: &Value, y: &Value) -> Value {
|
||||||
match (x, y) {
|
let x = x.as_f64();
|
||||||
(Value::Number(x), Value::Number(y)) => Value::Number(x.powf(*y)),
|
let y = y.as_f64();
|
||||||
_ => unreachable!("internal ludus error: pow expects numbers"),
|
Value::from_f64(x.powf(y))
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dissoc(dict: &Value, key: &Value) -> Value {
|
pub fn dissoc(dict: &Value, key: &Value) -> Value {
|
||||||
|
@ -226,14 +219,14 @@ pub fn first(ordered: &Value) -> Value {
|
||||||
pub fn at(ordered: &Value, i: &Value) -> Value {
|
pub fn at(ordered: &Value, i: &Value) -> Value {
|
||||||
match (ordered, i) {
|
match (ordered, i) {
|
||||||
(Value::List(list), Value::Number(n)) => {
|
(Value::List(list), Value::Number(n)) => {
|
||||||
let i = *n as usize;
|
let i = f64::from(*n) as usize;
|
||||||
match list.get(i) {
|
match list.get(i) {
|
||||||
Some(n) => n.clone(),
|
Some(n) => n.clone(),
|
||||||
None => Value::Nil,
|
None => Value::Nil,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Value::Tuple(tuple), Value::Number(n)) => {
|
(Value::Tuple(tuple), Value::Number(n)) => {
|
||||||
let i = *n as usize;
|
let i = f64::from(*n) as usize;
|
||||||
match tuple.get(i) {
|
match tuple.get(i) {
|
||||||
Some(n) => n.clone(),
|
Some(n) => n.clone(),
|
||||||
None => Value::Nil,
|
None => Value::Nil,
|
||||||
|
@ -308,11 +301,11 @@ pub fn rest(ordered: &Value) -> Value {
|
||||||
|
|
||||||
pub fn count(coll: &Value) -> Value {
|
pub fn count(coll: &Value) -> Value {
|
||||||
match coll {
|
match coll {
|
||||||
Value::Dict(d) => Value::Number(d.len() as f64),
|
Value::Dict(d) => Value::from_usize(d.len()),
|
||||||
Value::List(l) => Value::Number(l.len() as f64),
|
Value::List(l) => Value::from_usize(l.len()),
|
||||||
Value::Tuple(t) => Value::Number(t.len() as f64),
|
Value::Tuple(t) => Value::from_usize(t.len()),
|
||||||
Value::String(s) => Value::Number(s.len() as f64),
|
Value::String(s) => Value::from_usize(s.len()),
|
||||||
Value::Interned(s) => Value::Number(s.len() as f64),
|
Value::Interned(s) => Value::from_usize(s.len()),
|
||||||
_ => unreachable!("internal Ludus error"),
|
_ => unreachable!("internal Ludus error"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -320,11 +313,11 @@ pub fn count(coll: &Value) -> Value {
|
||||||
pub fn range(start: &Value, end: &Value) -> Value {
|
pub fn range(start: &Value, end: &Value) -> Value {
|
||||||
match (start, end) {
|
match (start, end) {
|
||||||
(Value::Number(start), Value::Number(end)) => {
|
(Value::Number(start), Value::Number(end)) => {
|
||||||
let start = *start as isize;
|
let start = f64::from(*start) as isize;
|
||||||
let end = *end as isize;
|
let end = f64::from(*end) as isize;
|
||||||
let mut range = Vector::new();
|
let mut range = Vector::new();
|
||||||
for n in start..end {
|
for n in start..end {
|
||||||
range.push_back(Value::Number(n as f64))
|
range.push_back(Value::from_usize(n as usize))
|
||||||
}
|
}
|
||||||
Value::List(Box::new(range))
|
Value::List(Box::new(range))
|
||||||
}
|
}
|
||||||
|
@ -336,14 +329,14 @@ pub fn slice(ordered: &Value, start: &Value, end: &Value) -> Value {
|
||||||
match (ordered, start, end) {
|
match (ordered, start, end) {
|
||||||
(Value::List(list), Value::Number(start), Value::Number(end)) => {
|
(Value::List(list), Value::Number(start), Value::Number(end)) => {
|
||||||
let mut newlist = list.clone();
|
let mut newlist = list.clone();
|
||||||
let start = std::cmp::max(*start as usize, 0);
|
let start = std::cmp::max(f64::from(*start) as usize, 0);
|
||||||
let end = std::cmp::min(*end as usize, list.len());
|
let end = std::cmp::min(f64::from(*end) as usize, list.len());
|
||||||
Value::List(Box::new(newlist.slice(start..end)))
|
Value::List(Box::new(newlist.slice(start..end)))
|
||||||
}
|
}
|
||||||
// TODO: figure out something better to do than return an empty string on a bad slice
|
// TODO: figure out something better to do than return an empty string on a bad slice
|
||||||
(Value::String(string), Value::Number(start), Value::Number(end)) => {
|
(Value::String(string), Value::Number(start), Value::Number(end)) => {
|
||||||
let start = std::cmp::max(*start as usize, 0);
|
let start = std::cmp::max(f64::from(*start) as usize, 0);
|
||||||
let end = std::cmp::min(*end as usize, string.len());
|
let end = std::cmp::min(f64::from(*end) as usize, string.len());
|
||||||
Value::String(Rc::new(
|
Value::String(Rc::new(
|
||||||
string
|
string
|
||||||
.clone()
|
.clone()
|
||||||
|
@ -354,8 +347,8 @@ pub fn slice(ordered: &Value, start: &Value, end: &Value) -> Value {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
(Value::Interned(string), Value::Number(start), Value::Number(end)) => {
|
(Value::Interned(string), Value::Number(start), Value::Number(end)) => {
|
||||||
let start = std::cmp::max(*start as usize, 0);
|
let start = std::cmp::max(f64::from(*start) as usize, 0);
|
||||||
let end = std::cmp::min(*end as usize, string.len());
|
let end = std::cmp::min(f64::from(*end) as usize, string.len());
|
||||||
Value::String(Rc::new(string.get(start..end).unwrap_or("").to_string()))
|
Value::String(Rc::new(string.get(start..end).unwrap_or("").to_string()))
|
||||||
}
|
}
|
||||||
_ => unreachable!("internal Ludus error"),
|
_ => unreachable!("internal Ludus error"),
|
||||||
|
@ -382,14 +375,14 @@ pub fn list(x: &Value) -> Value {
|
||||||
pub fn number(x: &Value) -> Value {
|
pub fn number(x: &Value) -> Value {
|
||||||
match x {
|
match x {
|
||||||
Value::Interned(string) => match string.parse::<f64>() {
|
Value::Interned(string) => match string.parse::<f64>() {
|
||||||
Ok(n) => Value::Tuple(Rc::new(vec![Value::Keyword("ok"), Value::Number(n)])),
|
Ok(n) => Value::Tuple(Rc::new(vec![Value::Keyword("ok"), Value::from_f64(n)])),
|
||||||
Err(_) => Value::Tuple(Rc::new(vec![
|
Err(_) => Value::Tuple(Rc::new(vec![
|
||||||
Value::Keyword("err"),
|
Value::Keyword("err"),
|
||||||
Value::String(Rc::new(format!("could not parse `{string}` as a number"))),
|
Value::String(Rc::new(format!("could not parse `{string}` as a number"))),
|
||||||
])),
|
])),
|
||||||
},
|
},
|
||||||
Value::String(string) => match string.parse::<f64>() {
|
Value::String(string) => match string.parse::<f64>() {
|
||||||
Ok(n) => Value::Tuple(Rc::new(vec![Value::Keyword("ok"), Value::Number(n)])),
|
Ok(n) => Value::Tuple(Rc::new(vec![Value::Keyword("ok"), Value::from_f64(n)])),
|
||||||
Err(_) => Value::Tuple(Rc::new(vec![
|
Err(_) => Value::Tuple(Rc::new(vec![
|
||||||
Value::Keyword("err"),
|
Value::Keyword("err"),
|
||||||
Value::String(Rc::new(format!("could not parse `{string}` as a number"))),
|
Value::String(Rc::new(format!("could not parse `{string}` as a number"))),
|
||||||
|
@ -486,63 +479,41 @@ pub fn trimr(string: &Value) -> Value {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn atan_2(x: &Value, y: &Value) -> Value {
|
pub fn atan_2(x: &Value, y: &Value) -> Value {
|
||||||
match (x, y) {
|
let x = x.as_f64();
|
||||||
(Value::Number(x), Value::Number(y)) => Value::Number(x.atan2(*y)),
|
let y = y.as_f64();
|
||||||
_ => unreachable!("internal Ludus error"),
|
Value::from_f64(x.atan2(y))
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ceil(x: &Value) -> Value {
|
pub fn ceil(x: &Value) -> Value {
|
||||||
match x {
|
Value::from_f64(x.as_f64().ceil())
|
||||||
Value::Number(x) => Value::Number(x.ceil()),
|
|
||||||
_ => unreachable!("internal Ludus error"),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cos(x: &Value) -> Value {
|
pub fn cos(x: &Value) -> Value {
|
||||||
match x {
|
Value::from_f64(x.as_f64().cos())
|
||||||
Value::Number(x) => Value::Number(x.cos()),
|
|
||||||
_ => unreachable!("internal Ludus error"),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn floor(x: &Value) -> Value {
|
pub fn floor(x: &Value) -> Value {
|
||||||
match x {
|
Value::from_f64(x.as_f64().floor())
|
||||||
Value::Number(x) => Value::Number(x.floor()),
|
|
||||||
_ => unreachable!("internal Ludus error"),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn base_random() -> Value {
|
pub fn base_random() -> Value {
|
||||||
Value::Number(random())
|
Value::from_f64(random())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn round(x: &Value) -> Value {
|
pub fn round(x: &Value) -> Value {
|
||||||
match x {
|
Value::from_f64(x.as_f64().round())
|
||||||
Value::Number(x) => Value::Number(x.round()),
|
|
||||||
_ => unreachable!("internal Ludus error"),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sin(x: &Value) -> Value {
|
pub fn sin(x: &Value) -> Value {
|
||||||
match x {
|
Value::from_f64(x.as_f64().sin())
|
||||||
Value::Number(x) => Value::Number(x.sin()),
|
|
||||||
_ => unreachable!("internal Ludus error"),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sqrt(x: &Value) -> Value {
|
pub fn sqrt(x: &Value) -> Value {
|
||||||
match x {
|
Value::from_f64(x.as_f64().sqrt())
|
||||||
Value::Number(x) => Value::Number(x.sqrt()),
|
|
||||||
_ => unreachable!("internal Ludus error"),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tan(x: &Value) -> Value {
|
pub fn tan(x: &Value) -> Value {
|
||||||
match x {
|
Value::from_f64(x.as_f64().tan())
|
||||||
Value::Number(x) => Value::Number(x.tan()),
|
|
||||||
_ => unreachable!("internal Ludus error"),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gt(x: &Value, y: &Value) -> Value {
|
pub fn gt(x: &Value, y: &Value) -> Value {
|
||||||
|
@ -675,7 +646,7 @@ pub fn make_base() -> Value {
|
||||||
"number",
|
"number",
|
||||||
Value::BaseFn(Box::new(BaseFn::Unary("number", number))),
|
Value::BaseFn(Box::new(BaseFn::Unary("number", number))),
|
||||||
),
|
),
|
||||||
("pi", Value::Number(std::f64::consts::PI)),
|
("pi", Value::from_f64(std::f64::consts::PI)),
|
||||||
("pow", Value::BaseFn(Box::new(BaseFn::Binary("pow", pow)))),
|
("pow", Value::BaseFn(Box::new(BaseFn::Binary("pow", pow)))),
|
||||||
(
|
(
|
||||||
"print!",
|
"print!",
|
||||||
|
@ -706,7 +677,7 @@ pub fn make_base() -> Value {
|
||||||
Value::BaseFn(Box::new(BaseFn::Binary("split", split))),
|
Value::BaseFn(Box::new(BaseFn::Binary("split", split))),
|
||||||
),
|
),
|
||||||
("sqrt", Value::BaseFn(Box::new(BaseFn::Unary("sqrt", sqrt)))),
|
("sqrt", Value::BaseFn(Box::new(BaseFn::Unary("sqrt", sqrt)))),
|
||||||
("sqrt_2", Value::Number(std::f64::consts::SQRT_2)),
|
("sqrt_2", Value::from_f64(std::f64::consts::SQRT_2)),
|
||||||
(
|
(
|
||||||
"store!",
|
"store!",
|
||||||
Value::BaseFn(Box::new(BaseFn::Binary("store!", store))),
|
Value::BaseFn(Box::new(BaseFn::Binary("store!", store))),
|
||||||
|
|
|
@ -4,6 +4,7 @@ use crate::op::Op;
|
||||||
use crate::spans::Spanned;
|
use crate::spans::Spanned;
|
||||||
use crate::value::*;
|
use crate::value::*;
|
||||||
use chumsky::prelude::SimpleSpan;
|
use chumsky::prelude::SimpleSpan;
|
||||||
|
use ordered_float::NotNan;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
@ -419,7 +420,7 @@ impl Compiler {
|
||||||
self.emit_op(Op::Nil);
|
self.emit_op(Op::Nil);
|
||||||
self.stack_depth += 1;
|
self.stack_depth += 1;
|
||||||
}
|
}
|
||||||
Number(n) => self.emit_constant(Value::Number(*n)),
|
Number(n) => self.emit_constant(Value::Number(NotNan::new(*n).unwrap())),
|
||||||
Boolean(b) => {
|
Boolean(b) => {
|
||||||
self.emit_op(if *b { Op::True } else { Op::False });
|
self.emit_op(if *b { Op::True } else { Op::False });
|
||||||
self.stack_depth += 1;
|
self.stack_depth += 1;
|
||||||
|
@ -536,7 +537,7 @@ impl Compiler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NumberPattern(n) => {
|
NumberPattern(n) => {
|
||||||
self.match_constant(Value::Number(*n));
|
self.match_constant(Value::Number(NotNan::new(*n).unwrap()));
|
||||||
}
|
}
|
||||||
KeywordPattern(s) => {
|
KeywordPattern(s) => {
|
||||||
let existing_kw = self.chunk.keywords.iter().position(|kw| kw == s);
|
let existing_kw = self.chunk.keywords.iter().position(|kw| kw == s);
|
||||||
|
|
|
@ -54,7 +54,7 @@ impl MsgIn {
|
||||||
MsgIn::Input(str) => Value::string(str),
|
MsgIn::Input(str) => Value::string(str),
|
||||||
MsgIn::Fetch(url, status_f64, string) => {
|
MsgIn::Fetch(url, status_f64, string) => {
|
||||||
let url = Value::string(url);
|
let url = Value::string(url);
|
||||||
let status = Value::Number(status_f64);
|
let status = Value::from_f64(status_f64);
|
||||||
let text = Value::string(string);
|
let text = Value::string(string);
|
||||||
let result_tuple = if status_f64 == 200.0 {
|
let result_tuple = if status_f64 == 200.0 {
|
||||||
Value::tuple(vec![OK, text])
|
Value::tuple(vec![OK, text])
|
||||||
|
|
21
src/value.rs
21
src/value.rs
|
@ -1,6 +1,7 @@
|
||||||
use crate::base::BaseFn;
|
use crate::base::BaseFn;
|
||||||
use crate::chunk::Chunk;
|
use crate::chunk::Chunk;
|
||||||
use imbl::{HashMap, Vector};
|
use imbl::{HashMap, Vector};
|
||||||
|
use ordered_float::NotNan;
|
||||||
use serde::ser::{Serialize, SerializeMap, SerializeSeq, Serializer};
|
use serde::ser::{Serialize, SerializeMap, SerializeSeq, Serializer};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
@ -171,7 +172,8 @@ pub enum Value {
|
||||||
Keyword(&'static str),
|
Keyword(&'static str),
|
||||||
Interned(&'static str),
|
Interned(&'static str),
|
||||||
String(Rc<String>),
|
String(Rc<String>),
|
||||||
Number(f64),
|
// Number(f64),
|
||||||
|
Number(NotNan<f64>),
|
||||||
Tuple(Rc<Vec<Value>>),
|
Tuple(Rc<Vec<Value>>),
|
||||||
List(Box<Vector<Value>>),
|
List(Box<Vector<Value>>),
|
||||||
Dict(Box<HashMap<Key, Value>>),
|
Dict(Box<HashMap<Key, Value>>),
|
||||||
|
@ -270,7 +272,7 @@ impl Serialize for Value {
|
||||||
Nil => srlzr.serialize_none(),
|
Nil => srlzr.serialize_none(),
|
||||||
True => srlzr.serialize_bool(true),
|
True => srlzr.serialize_bool(true),
|
||||||
False => srlzr.serialize_bool(false),
|
False => srlzr.serialize_bool(false),
|
||||||
Number(n) => srlzr.serialize_f64(*n),
|
Number(n) => srlzr.serialize_f64(f64::from(*n)),
|
||||||
Interned(s) => srlzr.serialize_str(s),
|
Interned(s) => srlzr.serialize_str(s),
|
||||||
Keyword(k) => srlzr.serialize_str(k),
|
Keyword(k) => srlzr.serialize_str(k),
|
||||||
String(s) => srlzr.serialize_str(s.as_str()),
|
String(s) => srlzr.serialize_str(s.as_str()),
|
||||||
|
@ -540,6 +542,21 @@ impl Value {
|
||||||
Value::Tuple(Rc::new(vec))
|
Value::Tuple(Rc::new(vec))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn from_f64(f: f64) -> Value {
|
||||||
|
Value::Number(NotNan::new(f).unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_usize(n: usize) -> Value {
|
||||||
|
Value::Number(NotNan::new(n as f64).unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_f64(&self) -> f64 {
|
||||||
|
match self {
|
||||||
|
Value::Number(n) => f64::from(*n),
|
||||||
|
_ => unreachable!("expected value to be a number"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// pub fn get_shared_box(&self, name: &'static str) -> Value {
|
// pub fn get_shared_box(&self, name: &'static str) -> Value {
|
||||||
// match self {
|
// match self {
|
||||||
// Value::Dict(dict) => dict
|
// Value::Dict(dict) => dict
|
||||||
|
|
18
src/vm.rs
18
src/vm.rs
|
@ -7,6 +7,7 @@ use crate::value::{Key, LFn, Value};
|
||||||
use crate::world::Zoo;
|
use crate::world::Zoo;
|
||||||
use imbl::{HashMap, Vector};
|
use imbl::{HashMap, Vector};
|
||||||
use num_traits::FromPrimitive;
|
use num_traits::FromPrimitive;
|
||||||
|
use ordered_float::NotNan;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -376,7 +377,10 @@ impl Creature {
|
||||||
let Value::Number(ms) = args[1] else {
|
let Value::Number(ms) = args[1] else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
};
|
};
|
||||||
self.zoo.as_ref().borrow_mut().sleep(self.pid, ms);
|
self.zoo
|
||||||
|
.as_ref()
|
||||||
|
.borrow_mut()
|
||||||
|
.sleep(self.pid, f64::from(ms));
|
||||||
self.r#yield = true;
|
self.r#yield = true;
|
||||||
self.push(Value::Keyword("ok"));
|
self.push(Value::Keyword("ok"));
|
||||||
}
|
}
|
||||||
|
@ -462,7 +466,7 @@ impl Creature {
|
||||||
let jump_len = self.read2();
|
let jump_len = self.read2();
|
||||||
let cond = self.pop();
|
let cond = self.pop();
|
||||||
match cond {
|
match cond {
|
||||||
Value::Number(x) if x <= 0.0 => self.ip += jump_len,
|
Value::Number(x) if f64::from(x) <= 0.0 => self.ip += jump_len,
|
||||||
Value::Number(..) => (),
|
Value::Number(..) => (),
|
||||||
_ => {
|
_ => {
|
||||||
return self
|
return self
|
||||||
|
@ -828,7 +832,9 @@ impl Creature {
|
||||||
ToInt => {
|
ToInt => {
|
||||||
let val = self.pop();
|
let val = self.pop();
|
||||||
if let Value::Number(x) = val {
|
if let Value::Number(x) = val {
|
||||||
self.push(Value::Number(x as usize as f64));
|
self.push(Value::Number(
|
||||||
|
NotNan::new(f64::from(x) as usize as f64).unwrap(),
|
||||||
|
));
|
||||||
} else {
|
} else {
|
||||||
return self.panic_with(format!("repeat requires a number, but got {val}"));
|
return self.panic_with(format!("repeat requires a number, but got {val}"));
|
||||||
}
|
}
|
||||||
|
@ -836,7 +842,7 @@ impl Creature {
|
||||||
Decrement => {
|
Decrement => {
|
||||||
let val = self.pop();
|
let val = self.pop();
|
||||||
if let Value::Number(x) = val {
|
if let Value::Number(x) = val {
|
||||||
self.push(Value::Number(x - 1.0));
|
self.push(Value::from_f64(f64::from(x) - 1.0));
|
||||||
} else {
|
} else {
|
||||||
return self
|
return self
|
||||||
.panic_with(format!("you may only decrement a number, but got {val}"));
|
.panic_with(format!("you may only decrement a number, but got {val}"));
|
||||||
|
@ -959,10 +965,10 @@ impl Creature {
|
||||||
let ordered = self.pop();
|
let ordered = self.pop();
|
||||||
let value = match (ordered, idx.clone()) {
|
let value = match (ordered, idx.clone()) {
|
||||||
(Value::List(l), Value::Number(i)) => {
|
(Value::List(l), Value::Number(i)) => {
|
||||||
l.get(i as usize).unwrap_or(&Value::Nil).clone()
|
l.get(f64::from(i) as usize).unwrap_or(&Value::Nil).clone()
|
||||||
}
|
}
|
||||||
(Value::Tuple(t), Value::Number(i)) => {
|
(Value::Tuple(t), Value::Number(i)) => {
|
||||||
t.get(i as usize).unwrap_or(&Value::Nil).clone()
|
t.get(f64::from(i) as usize).unwrap_or(&Value::Nil).clone()
|
||||||
}
|
}
|
||||||
(_, Value::Number(_)) => Value::Nil,
|
(_, Value::Number(_)) => Value::Nil,
|
||||||
_ => {
|
_ => {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user