Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add number->string function to lisp #561

Merged
merged 3 commits into from
Dec 19, 2023
Merged
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
3 changes: 2 additions & 1 deletion doc/lisp.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down Expand Up @@ -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
1 change: 1 addition & 0 deletions dsk/lib/lisp/core.lsp
Original file line number Diff line number Diff line change
Expand Up @@ -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?)
Expand Down
1 change: 1 addition & 0 deletions src/usr/lisp/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
1 change: 1 addition & 0 deletions src/usr/lisp/number.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
27 changes: 27 additions & 0 deletions src/usr/lisp/primitive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down Expand Up @@ -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])?;
Expand Down
3 changes: 2 additions & 1 deletion www/lisp.html
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ <h3>Primitive Operators</h3>
<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>
Expand Down Expand Up @@ -262,6 +262,7 @@ <h3>Unreleased</h3>
<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>
Expand Down
Loading