From ef662106dfc34a63359e96a14182647d6b0d07fb Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Mon, 18 Dec 2023 19:40:43 +0100 Subject: [PATCH 1/3] Add number->string function --- src/usr/lisp/env.rs | 1 + src/usr/lisp/number.rs | 1 + src/usr/lisp/primitive.rs | 27 +++++++++++++++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/src/usr/lisp/env.rs b/src/usr/lisp/env.rs index b31ef6ecd..95409768b 100644 --- a/src/usr/lisp/env.rs +++ b/src/usr/lisp/env.rs @@ -50,6 +50,7 @@ pub fn default_env() -> Rc> { data.insert("binary->string".to_string(), Exp::Primitive(primitive::lisp_binary_string)); data.insert("binary->number".to_string(), Exp::Primitive(primitive::lisp_binary_number)); data.insert("number->binary".to_string(), Exp::Primitive(primitive::lisp_number_binary)); + data.insert("number->string".to_string(), Exp::Primitive(primitive::lisp_number_string)); data.insert("string->number".to_string(), Exp::Primitive(primitive::lisp_string_number)); data.insert("type".to_string(), Exp::Primitive(primitive::lisp_type)); data.insert("parse".to_string(), Exp::Primitive(primitive::lisp_parse)); diff --git a/src/usr/lisp/number.rs b/src/usr/lisp/number.rs index b2b3d6357..a980c704a 100644 --- a/src/usr/lisp/number.rs +++ b/src/usr/lisp/number.rs @@ -310,6 +310,7 @@ macro_rules! try_from_number { } try_from_number!(usize, to_usize); +try_from_number!(u32, to_u32); try_from_number!(u8, to_u8); impl fmt::Display for Number { diff --git a/src/usr/lisp/primitive.rs b/src/usr/lisp/primitive.rs index 223f974fe..ff31fb2d7 100644 --- a/src/usr/lisp/primitive.rs +++ b/src/usr/lisp/primitive.rs @@ -20,6 +20,7 @@ use core::cmp::Ordering::Equal; use core::convert::TryFrom; use core::convert::TryInto; use core::str::FromStr; +use num_bigint::BigInt; use smoltcp::wire::IpAddress; pub fn lisp_eq(args: &[Exp]) -> Result { @@ -216,6 +217,32 @@ pub fn lisp_number_binary(args: &[Exp]) -> Result { Ok(Exp::List(n.to_be_bytes().iter().map(|b| Exp::Num(Number::from(*b))).collect())) } +pub fn lisp_number_string(args: &[Exp]) -> Result { + let r = match args.len() { + 2 => { + let r = number(&args[1])?.try_into()?; // TODO: Reject Number::Float + if !(2..37).contains(&r) { + return expected!("radix in the range 2..37"); + } + r + } + _ => 10 + }; + let s = match number(&args[0])? { + Number::Int(n) if args.len() == 2 => { + BigInt::from(n).to_str_radix(r).to_uppercase() + } + Number::BigInt(n) if args.len() == 2 => { + n.to_str_radix(r).to_uppercase() + } + n => { + ensure_length_eq!(args, 1); + format!("{}", n) + } + }; + Ok(Exp::Str(s)) +} + pub fn lisp_string_number(args: &[Exp]) -> Result { ensure_length_eq!(args, 1); let s = string(&args[0])?; From 43a552a111d3395d14d3b37347fd356a10e94794 Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Mon, 18 Dec 2023 19:40:55 +0100 Subject: [PATCH 2/3] Add alias --- dsk/lib/lisp/core.lsp | 1 + 1 file changed, 1 insertion(+) diff --git a/dsk/lib/lisp/core.lsp b/dsk/lib/lisp/core.lsp index 0fafa94a1..d3e1809ba 100644 --- a/dsk/lib/lisp/core.lsp +++ b/dsk/lib/lisp/core.lsp @@ -146,6 +146,7 @@ (var str->num string->number) (var str->bin string->binary) (var num->bin number->binary) +(var num->str number->string) (var bin->str binary->string) (var bin->num binary->number) (var bool? boolean?) From 1e7d1fbf683c32b8fadaf9611ce82ea85b52b432 Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Mon, 18 Dec 2023 19:41:03 +0100 Subject: [PATCH 3/3] Add documentation --- doc/lisp.md | 3 ++- www/lisp.html | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/lisp.md b/doc/lisp.md index dac785c36..85f8a8dc4 100644 --- a/doc/lisp.md +++ b/doc/lisp.md @@ -47,7 +47,7 @@ MOROS Lisp is a Lisp-1 dialect inspired by Scheme, Clojure, and Ruby! ### Primitive Operators - `type`, `number/type` (aliased to `num/type`), `parse` - `string` (aliased to `str`) -- `string->number` (aliased to to `str->num`) +- `string->number` and `number->string` (aliased to `str->num` and `num->str`) - `string->binary` and `binary->string` (aliased to `str->bin` and `bin->str`) - `number->binary` and `binary->number` (aliased to `num->bin` and `bin->num`) - `regex/find` @@ -216,3 +216,4 @@ language and reading from the filesystem. - Add `empty?`, `reject`, `put`, `push`, and `host` functions` - Add `dict` type - Use `/` instead of `.` as namespace separator +- Add `number->string` (aliased to `num->str`) with an optional radix argument diff --git a/www/lisp.html b/www/lisp.html index 50388ff8a..a24ad633a 100644 --- a/www/lisp.html +++ b/www/lisp.html @@ -66,7 +66,7 @@

Primitive Operators

  • type, number/type (aliased to num/type), parse
  • string (aliased to str)
  • -
  • string->number (aliased to to str->num)
  • +
  • string->number and number->string (aliased to str->num and num->str)
  • string->binary and binary->string (aliased to str->bin and bin->str)
  • number->binary and binary->number (aliased to num->bin and bin->num)
  • regex/find
  • @@ -262,6 +262,7 @@

    Unreleased

  • Add empty?, reject, put, push, and host functions`
  • Add dict type
  • Use / instead of . as namespace separator
  • +
  • Add number->string (aliased to num->str) with an optional radix argument