Add number->string function to lisp (#561)

* Add number->string function

* Add alias

* Add documentation
This commit is contained in:
Vincent Ollivier 2023-12-19 22:51:13 +01:00 committed by GitHub
parent 9f525990a5
commit 82bc08ed96
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 34 additions and 2 deletions

View File

@ -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

View File

@ -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?)

View File

@ -50,6 +50,7 @@ pub fn default_env() -> Rc<RefCell<Env>> {
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));

View File

@ -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 {

View File

@ -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<Exp, Err> {
@ -216,6 +217,32 @@ pub fn lisp_number_binary(args: &[Exp]) -> Result<Exp, Err> {
Ok(Exp::List(n.to_be_bytes().iter().map(|b| Exp::Num(Number::from(*b))).collect()))
}
pub fn lisp_number_string(args: &[Exp]) -> Result<Exp, Err> {
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<Exp, Err> {
ensure_length_eq!(args, 1);
let s = string(&args[0])?;

View File

@ -66,7 +66,7 @@ of the Shell.</p>
<ul>
<li><code>type</code>, <code>number/type</code> (aliased to <code>num/type</code>), <code>parse</code></li>
<li><code>string</code> (aliased to <code>str</code>)</li>
<li><code>string-&gt;number</code> (aliased to to <code>str-&gt;num</code>)</li>
<li><code>string-&gt;number</code> and <code>number-&gt;string</code> (aliased to <code>str-&gt;num</code> and <code>num-&gt;str</code>)</li>
<li><code>string-&gt;binary</code> and <code>binary-&gt;string</code> (aliased to <code>str-&gt;bin</code> and <code>bin-&gt;str</code>)</li>
<li><code>number-&gt;binary</code> and <code>binary-&gt;number</code> (aliased to <code>num-&gt;bin</code> and <code>bin-&gt;num</code>)</li>
<li><code>regex/find</code></li>
@ -262,6 +262,7 @@ language and reading from the filesystem.</p>
<li>Add <code>empty?</code>, <code>reject</code>, <code>put</code>, <code>push</code>, and <code>host</code> functions`</li>
<li>Add <code>dict</code> type</li>
<li>Use <code>/</code> instead of <code>.</code> as namespace separator</li>
<li>Add <code>number-&gt;string</code> (aliased to <code>num-&gt;str</code>) with an optional radix argument</li>
</ul>
<footer><p><a href="/">MOROS</a></footer>
</body>