diff --git a/Cargo.lock b/Cargo.lock index 1eb1cc622b..24fe390b48 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3749,6 +3749,7 @@ dependencies = [ "roc_parse", "roc_region", "roc_reporting", + "roc_std", "roc_target", "roc_types", ] @@ -3823,6 +3824,9 @@ dependencies = [ [[package]] name = "roc_std" version = "0.1.0" +dependencies = [ + "roc_error_macros", +] [[package]] name = "roc_target" diff --git a/repl_eval/Cargo.toml b/repl_eval/Cargo.toml index ebb3843553..37e58c2f50 100644 --- a/repl_eval/Cargo.toml +++ b/repl_eval/Cargo.toml @@ -18,5 +18,6 @@ roc_mono = {path = "../compiler/mono"} roc_parse = {path = "../compiler/parse"} roc_region = {path = "../compiler/region"} roc_reporting = {path = "../reporting"} +roc_std = {path = "../roc_std", default-features = false} roc_target = {path = "../compiler/roc_target"} roc_types = {path = "../compiler/types"} diff --git a/repl_eval/src/eval.rs b/repl_eval/src/eval.rs index e706ddde0a..ad48f1350a 100644 --- a/repl_eval/src/eval.rs +++ b/repl_eval/src/eval.rs @@ -13,6 +13,7 @@ use roc_mono::layout::{ }; use roc_parse::ast::{AssignedField, Collection, Expr, StrLiteral}; use roc_region::all::{Loc, Region}; +use roc_std::RocDec; use roc_target::TargetInfo; use roc_types::subs::{Content, FlatType, GetSubsSlice, RecordFields, Subs, UnionTags, Variable}; @@ -277,6 +278,14 @@ fn jit_to_ast_help<'a, A: ReplApp<'a>>( layout: &Layout<'a>, content: &'a Content, ) -> Result, ToAstProblem> { + macro_rules! helper { + ($ty:ty) => { + app.call_function(main_fn_name, |_, num: $ty| { + num_to_ast(env, number_literal_to_ast(env.arena, num), content) + }) + }; + } + let (newtype_containers, content) = unroll_newtypes(env, content); let content = unroll_aliases(env, content); let result = match layout { @@ -287,14 +296,6 @@ fn jit_to_ast_help<'a, A: ReplApp<'a>>( Layout::Builtin(Builtin::Int(int_width)) => { use IntWidth::*; - macro_rules! helper { - ($ty:ty) => { - app.call_function(main_fn_name, |_, num: $ty| { - num_to_ast(env, number_literal_to_ast(env.arena, num), content) - }) - }; - } - let result = match int_width { U8 | I8 => { // NOTE: `helper!` does not handle 8-bit numbers yet @@ -317,14 +318,6 @@ fn jit_to_ast_help<'a, A: ReplApp<'a>>( Layout::Builtin(Builtin::Float(float_width)) => { use FloatWidth::*; - macro_rules! helper { - ($ty:ty) => { - app.call_function(main_fn_name, |_, num: $ty| { - num_to_ast(env, number_literal_to_ast(env.arena, num), content) - }) - }; - } - let result = match float_width { F32 => helper!(f32), F64 => helper!(f64), @@ -333,6 +326,9 @@ fn jit_to_ast_help<'a, A: ReplApp<'a>>( Ok(result) } + Layout::Builtin(Builtin::Decimal) => { + Ok(helper!(RocDec)) + } Layout::Builtin(Builtin::Str) => { let size = layout.stack_size(env.target_info) as usize; Ok( @@ -1246,5 +1242,9 @@ fn num_to_ast<'a>(env: &Env<'a, '_>, num_expr: Expr<'a>, content: &Content) -> E /// This is centralized in case we want to format it differently later, /// e.g. adding underscores for large numbers fn number_literal_to_ast(arena: &Bump, num: T) -> Expr<'_> { - Expr::Num(arena.alloc(format!("{}", num))) + use std::fmt::Write; + + let mut string = bumpalo::collections::String::with_capacity_in(64, arena); + write!(string, "{}", num).unwrap(); + Expr::Num(string.into_bump_str()) } diff --git a/repl_eval/src/lib.rs b/repl_eval/src/lib.rs index 0aebe53507..f1b52d4530 100644 --- a/repl_eval/src/lib.rs +++ b/repl_eval/src/lib.rs @@ -1,4 +1,5 @@ use roc_parse::ast::Expr; +use roc_std::RocDec; pub mod eval; pub mod gen; @@ -47,5 +48,10 @@ pub trait ReplAppMemory { fn deref_f32(&self, addr: usize) -> f32; fn deref_f64(&self, addr: usize) -> f64; + fn deref_dec(&self, addr: usize) -> RocDec { + let bits = self.deref_i128(addr); + return RocDec(bits); + } + fn deref_str(&self, addr: usize) -> &str; } diff --git a/roc_std/Cargo.toml b/roc_std/Cargo.toml index 03576dbeda..265bd0fd40 100644 --- a/roc_std/Cargo.toml +++ b/roc_std/Cargo.toml @@ -8,6 +8,9 @@ readme = "README.md" repository = "https://github.com/rtfeldman/roc" version = "0.1.0" +[dependencies] +roc_error_macros = { path = "../error_macros" } + [dev-dependencies] indoc = "1.0.3" pretty_assertions = "1.0.0" @@ -17,4 +20,4 @@ libc = "0.2.106" [features] default = ["platform"] -platform = [] \ No newline at end of file +platform = [] diff --git a/roc_std/src/lib.rs b/roc_std/src/lib.rs index d40457eac4..8aafa95fcf 100644 --- a/roc_std/src/lib.rs +++ b/roc_std/src/lib.rs @@ -4,6 +4,9 @@ use core::ffi::c_void; use core::fmt; use core::mem::{ManuallyDrop, MaybeUninit}; use core::ops::Drop; +use core::str; +// use roc_error_macros::internal_error; +// uncomment when we figure out why it fails below. mod rc; mod roc_list; @@ -277,4 +280,30 @@ impl RocDec { pub fn from_str_to_i128_unsafe(val: &str) -> i128 { Self::from_str(val).unwrap().0 } + + fn to_str_helper(&self, bytes: &mut [u8; 1]) { + bytes[0] = 0; + // TODO + } + + pub fn to_str(&self) -> RocStr { + let mut bytes: [u8; 1] = [0]; + self.to_str_helper(&mut bytes); + unsafe {RocStr::from_slice(&bytes) } + } + +} + +impl fmt::Display for RocDec { + fn fmt(&self, fmtr: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut bytes: [u8; 1] = [0]; + self.to_str_helper(&mut bytes); + match str::from_utf8(&bytes) { + Ok(slice) => write!(fmtr, "{}", slice), + Err(payload) => panic!("Error in converting RocDec({}) to a string: {}", self.0, payload), + // Err(payload) => internal_error!("Error in converting RocDec({}) to a string: {}", self.0, payload), + // This raises a compile error: can't find eprintln + // Is this because we don't use std? + } + } }