2025-05-07 09:19:33 -07:00
|
|
|
/* Mycelium Scheme
|
|
|
|
|
* Copyright (C) 2025 Ava Affine
|
|
|
|
|
*
|
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
use core::fmt::{self, Formatter};
|
|
|
|
|
use alloc::rc::Rc;
|
|
|
|
|
use alloc::vec::Vec;
|
|
|
|
|
use alloc::string::String;
|
|
|
|
|
|
Number library and integrations
This commit adds a number library which handles fractions, floats,
whole numbers, scientific notation, and special symbolic numbers
all according to the R7RS small specification.
Numeric trait is used to abstract operations across all number types
and a Number enum is used to offer a non-opaque type that stores any
kind of number.
Upon the Number enum is implemented the following traits:
- Add, Div, Sub, Mul
- Pow
- PartialEq
- PartialOrd
Which then offer the following operators to use on the Number enum
instances themselves: + - / * == != < > <= >= and of course x.pow(y).
Additionally, the number package contains parsing logic for each type
of number. FromStr is implemented as part of the Numeric trait, and
then in turn implemented on Number. Additionally Into<String> is
implemented for the Numeric trait and then on the Number enum type
as well.
Test cases have been added for basic cases, but could be expanded.
Additional modifications:
- LexError has a custom display implementation that properly outputs
formatted errors.
- Sexpr package updated to use new number package
Signed-off-by: Ava Affine <ava@sunnypup.io>
2025-05-15 12:49:08 -07:00
|
|
|
use crate::number::Number;
|
|
|
|
|
|
2025-05-07 09:19:33 -07:00
|
|
|
#[derive(Default, Clone)]
|
|
|
|
|
pub enum Datum {
|
Number library and integrations
This commit adds a number library which handles fractions, floats,
whole numbers, scientific notation, and special symbolic numbers
all according to the R7RS small specification.
Numeric trait is used to abstract operations across all number types
and a Number enum is used to offer a non-opaque type that stores any
kind of number.
Upon the Number enum is implemented the following traits:
- Add, Div, Sub, Mul
- Pow
- PartialEq
- PartialOrd
Which then offer the following operators to use on the Number enum
instances themselves: + - / * == != < > <= >= and of course x.pow(y).
Additionally, the number package contains parsing logic for each type
of number. FromStr is implemented as part of the Numeric trait, and
then in turn implemented on Number. Additionally Into<String> is
implemented for the Numeric trait and then on the Number enum type
as well.
Test cases have been added for basic cases, but could be expanded.
Additional modifications:
- LexError has a custom display implementation that properly outputs
formatted errors.
- Sexpr package updated to use new number package
Signed-off-by: Ava Affine <ava@sunnypup.io>
2025-05-15 12:49:08 -07:00
|
|
|
Number(Number),
|
2025-05-07 09:19:33 -07:00
|
|
|
Bool(bool),
|
|
|
|
|
List(Ast),
|
|
|
|
|
Symbol(String),
|
Number library and integrations
This commit adds a number library which handles fractions, floats,
whole numbers, scientific notation, and special symbolic numbers
all according to the R7RS small specification.
Numeric trait is used to abstract operations across all number types
and a Number enum is used to offer a non-opaque type that stores any
kind of number.
Upon the Number enum is implemented the following traits:
- Add, Div, Sub, Mul
- Pow
- PartialEq
- PartialOrd
Which then offer the following operators to use on the Number enum
instances themselves: + - / * == != < > <= >= and of course x.pow(y).
Additionally, the number package contains parsing logic for each type
of number. FromStr is implemented as part of the Numeric trait, and
then in turn implemented on Number. Additionally Into<String> is
implemented for the Numeric trait and then on the Number enum type
as well.
Test cases have been added for basic cases, but could be expanded.
Additional modifications:
- LexError has a custom display implementation that properly outputs
formatted errors.
- Sexpr package updated to use new number package
Signed-off-by: Ava Affine <ava@sunnypup.io>
2025-05-15 12:49:08 -07:00
|
|
|
Char(u8),
|
2025-05-07 09:19:33 -07:00
|
|
|
String(Vec<u8>),
|
|
|
|
|
Vector(Vec<Datum>),
|
|
|
|
|
ByteVector(Vec<u8>),
|
|
|
|
|
#[default]
|
|
|
|
|
None,
|
|
|
|
|
}
|
|
|
|
|
|
Number library and integrations
This commit adds a number library which handles fractions, floats,
whole numbers, scientific notation, and special symbolic numbers
all according to the R7RS small specification.
Numeric trait is used to abstract operations across all number types
and a Number enum is used to offer a non-opaque type that stores any
kind of number.
Upon the Number enum is implemented the following traits:
- Add, Div, Sub, Mul
- Pow
- PartialEq
- PartialOrd
Which then offer the following operators to use on the Number enum
instances themselves: + - / * == != < > <= >= and of course x.pow(y).
Additionally, the number package contains parsing logic for each type
of number. FromStr is implemented as part of the Numeric trait, and
then in turn implemented on Number. Additionally Into<String> is
implemented for the Numeric trait and then on the Number enum type
as well.
Test cases have been added for basic cases, but could be expanded.
Additional modifications:
- LexError has a custom display implementation that properly outputs
formatted errors.
- Sexpr package updated to use new number package
Signed-off-by: Ava Affine <ava@sunnypup.io>
2025-05-15 12:49:08 -07:00
|
|
|
fn byte_to_escaped_char(b: u8) -> String {
|
|
|
|
|
unimplemented!()
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-07 09:19:33 -07:00
|
|
|
impl fmt::Display for Datum {
|
|
|
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
|
|
|
|
match self {
|
Number library and integrations
This commit adds a number library which handles fractions, floats,
whole numbers, scientific notation, and special symbolic numbers
all according to the R7RS small specification.
Numeric trait is used to abstract operations across all number types
and a Number enum is used to offer a non-opaque type that stores any
kind of number.
Upon the Number enum is implemented the following traits:
- Add, Div, Sub, Mul
- Pow
- PartialEq
- PartialOrd
Which then offer the following operators to use on the Number enum
instances themselves: + - / * == != < > <= >= and of course x.pow(y).
Additionally, the number package contains parsing logic for each type
of number. FromStr is implemented as part of the Numeric trait, and
then in turn implemented on Number. Additionally Into<String> is
implemented for the Numeric trait and then on the Number enum type
as well.
Test cases have been added for basic cases, but could be expanded.
Additional modifications:
- LexError has a custom display implementation that properly outputs
formatted errors.
- Sexpr package updated to use new number package
Signed-off-by: Ava Affine <ava@sunnypup.io>
2025-05-15 12:49:08 -07:00
|
|
|
Datum::Number(n) => write!(f, "{}", Into::<String>::into(*n)),
|
2025-05-07 09:19:33 -07:00
|
|
|
Datum::Bool(n) => write!(f, "{n}"),
|
|
|
|
|
Datum::List(n) => write!(f, "{n}"),
|
|
|
|
|
Datum::Symbol(n) => write!(f, "{n}"),
|
Number library and integrations
This commit adds a number library which handles fractions, floats,
whole numbers, scientific notation, and special symbolic numbers
all according to the R7RS small specification.
Numeric trait is used to abstract operations across all number types
and a Number enum is used to offer a non-opaque type that stores any
kind of number.
Upon the Number enum is implemented the following traits:
- Add, Div, Sub, Mul
- Pow
- PartialEq
- PartialOrd
Which then offer the following operators to use on the Number enum
instances themselves: + - / * == != < > <= >= and of course x.pow(y).
Additionally, the number package contains parsing logic for each type
of number. FromStr is implemented as part of the Numeric trait, and
then in turn implemented on Number. Additionally Into<String> is
implemented for the Numeric trait and then on the Number enum type
as well.
Test cases have been added for basic cases, but could be expanded.
Additional modifications:
- LexError has a custom display implementation that properly outputs
formatted errors.
- Sexpr package updated to use new number package
Signed-off-by: Ava Affine <ava@sunnypup.io>
2025-05-15 12:49:08 -07:00
|
|
|
Datum::Char(n) => write!(f, "{}",
|
|
|
|
|
byte_to_escaped_char(*n)),
|
2025-05-07 09:19:33 -07:00
|
|
|
Datum::String(n) =>
|
|
|
|
|
write!(f, "\"{}\"", String::from_utf8_lossy(&*n)),
|
|
|
|
|
Datum::Vector(n) => write!(f, "#({n:?})"),
|
|
|
|
|
Datum::ByteVector(n) => write!(f, "#u8({n:?})"),
|
|
|
|
|
Datum::None => Ok(())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* WARNING
|
|
|
|
|
* This is in a sense overloaded.
|
|
|
|
|
* Instead of using this to print debugging information for the
|
|
|
|
|
* Rust code, I have instead overloaded it to print the most
|
|
|
|
|
* maximal expanded valid syntax for this Datum
|
|
|
|
|
*/
|
|
|
|
|
impl fmt::Debug for Datum {
|
|
|
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
|
|
|
|
match self {
|
Number library and integrations
This commit adds a number library which handles fractions, floats,
whole numbers, scientific notation, and special symbolic numbers
all according to the R7RS small specification.
Numeric trait is used to abstract operations across all number types
and a Number enum is used to offer a non-opaque type that stores any
kind of number.
Upon the Number enum is implemented the following traits:
- Add, Div, Sub, Mul
- Pow
- PartialEq
- PartialOrd
Which then offer the following operators to use on the Number enum
instances themselves: + - / * == != < > <= >= and of course x.pow(y).
Additionally, the number package contains parsing logic for each type
of number. FromStr is implemented as part of the Numeric trait, and
then in turn implemented on Number. Additionally Into<String> is
implemented for the Numeric trait and then on the Number enum type
as well.
Test cases have been added for basic cases, but could be expanded.
Additional modifications:
- LexError has a custom display implementation that properly outputs
formatted errors.
- Sexpr package updated to use new number package
Signed-off-by: Ava Affine <ava@sunnypup.io>
2025-05-15 12:49:08 -07:00
|
|
|
Datum::Number(n) => write!(f, "{}", Into::<String>::into(*n)),
|
2025-05-07 09:19:33 -07:00
|
|
|
Datum::Bool(n) => write!(f, "{n}"),
|
|
|
|
|
Datum::List(n) => write!(f, "{n}"),
|
Number library and integrations
This commit adds a number library which handles fractions, floats,
whole numbers, scientific notation, and special symbolic numbers
all according to the R7RS small specification.
Numeric trait is used to abstract operations across all number types
and a Number enum is used to offer a non-opaque type that stores any
kind of number.
Upon the Number enum is implemented the following traits:
- Add, Div, Sub, Mul
- Pow
- PartialEq
- PartialOrd
Which then offer the following operators to use on the Number enum
instances themselves: + - / * == != < > <= >= and of course x.pow(y).
Additionally, the number package contains parsing logic for each type
of number. FromStr is implemented as part of the Numeric trait, and
then in turn implemented on Number. Additionally Into<String> is
implemented for the Numeric trait and then on the Number enum type
as well.
Test cases have been added for basic cases, but could be expanded.
Additional modifications:
- LexError has a custom display implementation that properly outputs
formatted errors.
- Sexpr package updated to use new number package
Signed-off-by: Ava Affine <ava@sunnypup.io>
2025-05-15 12:49:08 -07:00
|
|
|
Datum::Char(n) => write!(f, "{}",
|
|
|
|
|
byte_to_escaped_char(*n)),
|
2025-05-07 09:19:33 -07:00
|
|
|
Datum::Symbol(n) => write!(f, "{n}"),
|
|
|
|
|
Datum::String(n) =>
|
|
|
|
|
write!(f, "\"{}\"", String::from_utf8_lossy(&*n)),
|
|
|
|
|
Datum::Vector(n) => write!(f, "#({n:?})"),
|
|
|
|
|
Datum::ByteVector(n) => write!(f, "#u8({n:?})"),
|
|
|
|
|
Datum::None => Ok(())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
Number library and integrations
This commit adds a number library which handles fractions, floats,
whole numbers, scientific notation, and special symbolic numbers
all according to the R7RS small specification.
Numeric trait is used to abstract operations across all number types
and a Number enum is used to offer a non-opaque type that stores any
kind of number.
Upon the Number enum is implemented the following traits:
- Add, Div, Sub, Mul
- Pow
- PartialEq
- PartialOrd
Which then offer the following operators to use on the Number enum
instances themselves: + - / * == != < > <= >= and of course x.pow(y).
Additionally, the number package contains parsing logic for each type
of number. FromStr is implemented as part of the Numeric trait, and
then in turn implemented on Number. Additionally Into<String> is
implemented for the Numeric trait and then on the Number enum type
as well.
Test cases have been added for basic cases, but could be expanded.
Additional modifications:
- LexError has a custom display implementation that properly outputs
formatted errors.
- Sexpr package updated to use new number package
Signed-off-by: Ava Affine <ava@sunnypup.io>
2025-05-15 12:49:08 -07:00
|
|
|
|
2025-05-07 09:19:33 -07:00
|
|
|
#[derive(Default, Clone)]
|
|
|
|
|
pub struct Ast(Rc<Datum>, Rc<Datum>);
|
|
|
|
|
|
|
|
|
|
impl Iterator for Ast {
|
|
|
|
|
type Item = Rc<Datum>;
|
|
|
|
|
|
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
|
|
|
if let Datum::List(n) = &*self.1 {
|
|
|
|
|
let tmp_pair = n;
|
|
|
|
|
self.0 = tmp_pair.0.clone();
|
|
|
|
|
self.1 = tmp_pair.1.clone();
|
|
|
|
|
return Some(self.0.clone());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if let Datum::None = *self.1 {
|
|
|
|
|
return None;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let tmp = self.1.clone();
|
|
|
|
|
self.0 = Rc::from(Datum::None);
|
|
|
|
|
self.1 = Rc::from(Datum::None);
|
|
|
|
|
return Some(tmp);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl fmt::Display for Ast {
|
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
|
write!(f, "({}", self.0)?;
|
|
|
|
|
let mut cur = self;
|
|
|
|
|
while let Datum::List(next) = &*cur.1 {
|
|
|
|
|
cur = &next;
|
|
|
|
|
write!(f, " {}", cur.0)?;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if let Datum::None = &*cur.1 {
|
|
|
|
|
write!(f, ")")
|
|
|
|
|
} else {
|
|
|
|
|
write!(f, " {})", cur.1)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl fmt::Debug for Ast {
|
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
|
write!(f, "({}", self.0)?;
|
|
|
|
|
let mut cur = self;
|
|
|
|
|
let mut end = 1;
|
|
|
|
|
while let Datum::List(next) = &*cur.1 {
|
|
|
|
|
cur = &next;
|
|
|
|
|
end += 1;
|
|
|
|
|
write!(f, "({} . ", cur.0)?
|
|
|
|
|
}
|
|
|
|
|
write!(f, "{}{}", cur.1, ")".repeat(end))
|
|
|
|
|
}
|
|
|
|
|
}
|