Skip to content

Commit c35b87b

Browse files
authored
Merge pull request #1019 from vsbogd/add-macros
Add universal metta! macros to embed MeTTa syntax into Rust programs
2 parents 92bc30c + 6d40292 commit c35b87b

File tree

9 files changed

+682
-48
lines changed

9 files changed

+682
-48
lines changed

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ members = [
33
"hyperon-common",
44
"hyperon-atom",
55
"hyperon-space",
6+
"hyperon-macros",
67
"lib",
78
"c",
89
"repl",
@@ -18,6 +19,7 @@ hyperon = { path = "./lib", version = "0.2.6" }
1819
hyperon-common = { path = "./hyperon-common", version = "0.2.6" }
1920
hyperon-atom = { path = "./hyperon-atom", version = "0.2.6" }
2021
hyperon-space = { path = "./hyperon-space", version = "0.2.6" }
22+
hyperon-macros = { path = "./hyperon-macros", version = "0.2.6" }
2123

2224
regex = "1.11.0"
2325
log = "0.4.0"
@@ -27,6 +29,7 @@ env_logger = "0.8.4"
2729
hyperon-common = { path = "./hyperon-common", version = "0.2.6" }
2830
hyperon-atom = { path = "./hyperon-atom", version = "0.2.6" }
2931
hyperon-space = { path = "./hyperon-space", version = "0.2.6" }
32+
hyperon-macros = { path = "./hyperon-macros", version = "0.2.6" }
3033

3134
[profile.release]
3235
strip = "symbols"

hyperon-atom/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ smallvec = "1.10.0"
99
bitset = "0.1.2"
1010

1111
hyperon-common = { workspace = true }
12+
hyperon-macros = { workspace = true }
1213

1314
[lib]
1415
path = "src/lib.rs"

hyperon-atom/src/lib.rs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -91,14 +91,6 @@ macro_rules! expr {
9191
($($x:tt)*) => { $crate::Atom::expr([ $( expr!($x) , )* ]) };
9292
}
9393

94-
#[macro_export]
95-
macro_rules! constexpr {
96-
() => { $crate::Atom::Expression($crate::ExpressionAtom::new(hyperon_common::collections::CowArray::Literal(&[]))) };
97-
($x:literal) => { $crate::Atom::Symbol($crate::SymbolAtom::new(hyperon_common::unique_string::UniqueString::Const($x))) };
98-
(($($x:tt)*)) => { $crate::Atom::Expression($crate::ExpressionAtom::new(hyperon_common::collections::CowArray::Literal(const { &[ $( constexpr!($x) , )* ] }))) };
99-
($($x:tt)*) => { $crate::Atom::Expression($crate::ExpressionAtom::new(hyperon_common::collections::CowArray::Literal(const { &[ $( constexpr!($x) , )* ] }))) };
100-
}
101-
10294
/// Constructs new symbol atom. Can be used to construct `const` instances.
10395
///
10496
/// # Examples
@@ -171,7 +163,7 @@ pub struct ExpressionAtom {
171163

172164
impl ExpressionAtom {
173165
/// Constructs new expression from vector of sub-atoms. Not intended to be
174-
/// used directly, use [expr!], [constexpr!] or [Atom::expr] instead.
166+
/// used directly, use [expr!], [metta!], [metta_const!] or [Atom::expr] instead.
175167
pub const fn new(children: CowArray<Atom>) -> Self {
176168
Self{ children, evaluated: false }
177169
}
@@ -242,16 +234,24 @@ pub struct VariableAtom {
242234
}
243235

244236
impl VariableAtom {
245-
/// Constructs new variable using `name` provided. Name should not contain
246-
/// `#` characted which is reserved for internal name formatting (see
247-
/// [VariableAtom::parse_name]). Usually [Atom::var] method should be used
248-
/// to create new variable atom instance. But sometimes [VariableAtom]
249-
/// instance is required. For example for using as a key in variable bindings
250-
/// (see [matcher::Bindings]).
237+
/// Constructs new variable using `name` provided. Usually [Atom::var]
238+
/// method should be used to create new variable atom instance. But
239+
/// sometimes [VariableAtom] instance is required. For example for using
240+
/// as a key in variable bindings (see [matcher::Bindings]).
241+
/// Name should not contain `#` characted which is reserved for internal
242+
/// name formatting (see [VariableAtom::parse_name]).
251243
pub fn new<T: Into<UniqueString>>(name: T) -> Self {
252244
Self{ name: Self::check_name(name), id: 0 }
253245
}
254246

247+
/// Constructs new constant variable instance using `name` provided. Method
248+
/// is introduced to support creating constant expressions.
249+
/// Name should not contain `#` characted which is reserved for internal
250+
/// name formatting (see [VariableAtom::parse_name]).
251+
pub const fn new_const(name: UniqueString) -> Self {
252+
Self{ name, id: 0 }
253+
}
254+
255255
/// Constructs new variable using `name` and 'id' provided. This method is
256256
/// used to construct proper variable for testing purposes only.
257257
pub fn new_id<T: Into<UniqueString>>(name: T, id: usize) -> Self {

hyperon-atom/tests/macros.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
use hyperon_atom::*;
2+
use hyperon_macros::metta;
3+
4+
#[test]
5+
fn macros_metta_symbol() {
6+
assert_eq!(metta!{A}, Atom::sym("A"));
7+
}
8+
9+
#[test]
10+
fn macros_metta_variable() {
11+
assert_eq!(metta!{$a}, Atom::var("a"));
12+
assert_eq!(metta!{$a+}, Atom::var("a+"));
13+
}
14+
15+
#[test]
16+
fn macros_metta_expression() {
17+
assert_eq!(metta!{()}, Atom::expr([]));
18+
assert_eq!(metta!{(A $a)}, Atom::expr([Atom::sym("A"), Atom::var("a")]));
19+
assert_eq!(metta!{(A ($b B) $a)}, Atom::expr([
20+
Atom::sym("A"),
21+
Atom::expr([Atom::var("b"), Atom::sym("B")]),
22+
Atom::var("a")
23+
]));
24+
}

hyperon-macros/Cargo.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[package]
2+
name = "hyperon-macros"
3+
version.workspace = true
4+
edition.workspace = true
5+
6+
[dependencies]
7+
litrs = "0.5.1"
8+
9+
[lib]
10+
proc-macro = true

0 commit comments

Comments
 (0)