gandora-core 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,192 @@
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 4
4
+
5
+ [[package]]
6
+ name = "autocfg"
7
+ version = "1.5.1"
8
+ source = "registry+https://github.com/rust-lang/crates.io-index"
9
+ checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
10
+
11
+ [[package]]
12
+ name = "cfg-if"
13
+ version = "1.0.4"
14
+ source = "registry+https://github.com/rust-lang/crates.io-index"
15
+ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
16
+
17
+ [[package]]
18
+ name = "gan"
19
+ version = "0.2.0"
20
+ dependencies = [
21
+ "gandora-core",
22
+ ]
23
+
24
+ [[package]]
25
+ name = "gandora-core"
26
+ version = "0.2.0"
27
+
28
+ [[package]]
29
+ name = "gandora-core-py"
30
+ version = "0.2.0"
31
+ dependencies = [
32
+ "gandora-core",
33
+ "pyo3",
34
+ ]
35
+
36
+ [[package]]
37
+ name = "heck"
38
+ version = "0.5.0"
39
+ source = "registry+https://github.com/rust-lang/crates.io-index"
40
+ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
41
+
42
+ [[package]]
43
+ name = "indoc"
44
+ version = "2.0.7"
45
+ source = "registry+https://github.com/rust-lang/crates.io-index"
46
+ checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706"
47
+ dependencies = [
48
+ "rustversion",
49
+ ]
50
+
51
+ [[package]]
52
+ name = "libc"
53
+ version = "0.2.189"
54
+ source = "registry+https://github.com/rust-lang/crates.io-index"
55
+ checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"
56
+
57
+ [[package]]
58
+ name = "memoffset"
59
+ version = "0.9.1"
60
+ source = "registry+https://github.com/rust-lang/crates.io-index"
61
+ checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
62
+ dependencies = [
63
+ "autocfg",
64
+ ]
65
+
66
+ [[package]]
67
+ name = "once_cell"
68
+ version = "1.21.4"
69
+ source = "registry+https://github.com/rust-lang/crates.io-index"
70
+ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
71
+
72
+ [[package]]
73
+ name = "portable-atomic"
74
+ version = "1.14.0"
75
+ source = "registry+https://github.com/rust-lang/crates.io-index"
76
+ checksum = "3d20d5497ef88037a52ff98267d066e7f11fcc5e99bbfbd58a42336193aacec3"
77
+
78
+ [[package]]
79
+ name = "proc-macro2"
80
+ version = "1.0.107"
81
+ source = "registry+https://github.com/rust-lang/crates.io-index"
82
+ checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
83
+ dependencies = [
84
+ "unicode-ident",
85
+ ]
86
+
87
+ [[package]]
88
+ name = "pyo3"
89
+ version = "0.22.6"
90
+ source = "registry+https://github.com/rust-lang/crates.io-index"
91
+ checksum = "f402062616ab18202ae8319da13fa4279883a2b8a9d9f83f20dbade813ce1884"
92
+ dependencies = [
93
+ "cfg-if",
94
+ "indoc",
95
+ "libc",
96
+ "memoffset",
97
+ "once_cell",
98
+ "portable-atomic",
99
+ "pyo3-build-config",
100
+ "pyo3-ffi",
101
+ "pyo3-macros",
102
+ "unindent",
103
+ ]
104
+
105
+ [[package]]
106
+ name = "pyo3-build-config"
107
+ version = "0.22.6"
108
+ source = "registry+https://github.com/rust-lang/crates.io-index"
109
+ checksum = "b14b5775b5ff446dd1056212d778012cbe8a0fbffd368029fd9e25b514479c38"
110
+ dependencies = [
111
+ "once_cell",
112
+ "target-lexicon",
113
+ ]
114
+
115
+ [[package]]
116
+ name = "pyo3-ffi"
117
+ version = "0.22.6"
118
+ source = "registry+https://github.com/rust-lang/crates.io-index"
119
+ checksum = "9ab5bcf04a2cdcbb50c7d6105de943f543f9ed92af55818fd17b660390fc8636"
120
+ dependencies = [
121
+ "libc",
122
+ "pyo3-build-config",
123
+ ]
124
+
125
+ [[package]]
126
+ name = "pyo3-macros"
127
+ version = "0.22.6"
128
+ source = "registry+https://github.com/rust-lang/crates.io-index"
129
+ checksum = "0fd24d897903a9e6d80b968368a34e1525aeb719d568dba8b3d4bfa5dc67d453"
130
+ dependencies = [
131
+ "proc-macro2",
132
+ "pyo3-macros-backend",
133
+ "quote",
134
+ "syn",
135
+ ]
136
+
137
+ [[package]]
138
+ name = "pyo3-macros-backend"
139
+ version = "0.22.6"
140
+ source = "registry+https://github.com/rust-lang/crates.io-index"
141
+ checksum = "36c011a03ba1e50152b4b394b479826cad97e7a21eb52df179cd91ac411cbfbe"
142
+ dependencies = [
143
+ "heck",
144
+ "proc-macro2",
145
+ "pyo3-build-config",
146
+ "quote",
147
+ "syn",
148
+ ]
149
+
150
+ [[package]]
151
+ name = "quote"
152
+ version = "1.0.47"
153
+ source = "registry+https://github.com/rust-lang/crates.io-index"
154
+ checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
155
+ dependencies = [
156
+ "proc-macro2",
157
+ ]
158
+
159
+ [[package]]
160
+ name = "rustversion"
161
+ version = "1.0.23"
162
+ source = "registry+https://github.com/rust-lang/crates.io-index"
163
+ checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f"
164
+
165
+ [[package]]
166
+ name = "syn"
167
+ version = "2.0.119"
168
+ source = "registry+https://github.com/rust-lang/crates.io-index"
169
+ checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
170
+ dependencies = [
171
+ "proc-macro2",
172
+ "quote",
173
+ "unicode-ident",
174
+ ]
175
+
176
+ [[package]]
177
+ name = "target-lexicon"
178
+ version = "0.12.16"
179
+ source = "registry+https://github.com/rust-lang/crates.io-index"
180
+ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
181
+
182
+ [[package]]
183
+ name = "unicode-ident"
184
+ version = "1.0.24"
185
+ source = "registry+https://github.com/rust-lang/crates.io-index"
186
+ checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
187
+
188
+ [[package]]
189
+ name = "unindent"
190
+ version = "0.2.4"
191
+ source = "registry+https://github.com/rust-lang/crates.io-index"
192
+ checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
@@ -0,0 +1,8 @@
1
+ [workspace]
2
+ resolver = "2"
3
+ members = ["crates/core", "crates/core-py"]
4
+
5
+ [workspace.package]
6
+ version = "0.2.0"
7
+ edition = "2021"
8
+ license = "MIT"
@@ -0,0 +1,15 @@
1
+ Metadata-Version: 2.4
2
+ Name: gandora-core
3
+ Version: 0.2.0
4
+ Summary: The Gandora compiler as a Python extension module (GEP-0012)
5
+ License-Expression: MIT
6
+ Requires-Python: >=3.9
7
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
8
+ Project-URL: Repository, https://github.com/mjason/gandora
9
+
10
+ # gandora-core
11
+
12
+ The [Gandora](https://github.com/mjason/gandora) compiler as a Python
13
+ extension module (GEP-0012): parse, expand, diagnose, and compile
14
+ Gandora source in-process. Quoted terms use the Elixir encoding.
15
+
@@ -0,0 +1,5 @@
1
+ # gandora-core
2
+
3
+ The [Gandora](https://github.com/mjason/gandora) compiler as a Python
4
+ extension module (GEP-0012): parse, expand, diagnose, and compile
5
+ Gandora source in-process. Quoted terms use the Elixir encoding.
@@ -0,0 +1,11 @@
1
+ [package]
2
+ name = "gandora-core"
3
+ version.workspace = true
4
+ edition.workspace = true
5
+ license.workspace = true
6
+ description = "The Gandora compiler as a library"
7
+
8
+ [lib]
9
+ name = "gandora_core"
10
+
11
+ [dependencies]
@@ -0,0 +1,133 @@
1
+ //! The Gandora AST.
2
+ //!
3
+ //! The shape follows Elixir's quoted form (GEP-0002-R002): every composite
4
+ //! construct is a call `{name, meta, args}`; literals represent themselves.
5
+ //! Special forms (`defmodule`, `def`, `if`, `case`, `quote`, ...) are calls
6
+ //! whose callee is a plain name, with `do`/`else` blocks carried as trailing
7
+ //! keyword arguments whose values are `__block__` calls.
8
+
9
+ use crate::diag::Span;
10
+
11
+ #[derive(Debug, Clone, PartialEq)]
12
+ pub enum Term {
13
+ Int(i64),
14
+ Float(f64),
15
+ Bool(bool),
16
+ Nil,
17
+ /// A string literal as interpolation parts.
18
+ Str(Vec<StrPart>),
19
+ Atom(String),
20
+ /// A lowercase identifier reference. `ctx` is the hygiene context:
21
+ /// `None` for user-written code, `Some(id)` for macro-template names.
22
+ Var(String, Option<u64>),
23
+ /// A module path such as `App.Hello`, stored as segments.
24
+ Alias(Vec<String>),
25
+ List(Vec<Term>),
26
+ Tuple(Vec<Term>),
27
+ /// `%{k => v, ...}`; `a: 1` sugar arrives as an Atom key.
28
+ Map(Vec<(Term, Term)>),
29
+ /// A keyword pair `name: value` (inside lists / trailing arguments).
30
+ Pair(String, Box<Term>),
31
+ Call(Box<Call>),
32
+ }
33
+
34
+ #[derive(Debug, Clone, PartialEq)]
35
+ pub struct Call {
36
+ pub callee: Callee,
37
+ pub args: Vec<Term>,
38
+ pub span: Span,
39
+ }
40
+
41
+ #[derive(Debug, Clone, PartialEq)]
42
+ pub enum Callee {
43
+ /// `foo(...)`, operators (`+`), and special forms (`if`, `def`, ...).
44
+ Name(String),
45
+ /// `base.name(...)` — remote atom calls, module calls, method calls.
46
+ /// `base.name` without parens parses as `Dot` with `is_call = false`.
47
+ Dot {
48
+ base: Box<Term>,
49
+ name: String,
50
+ is_call: bool,
51
+ },
52
+ /// `f.(x)` — calling an anonymous function value.
53
+ Apply(Box<Term>),
54
+ }
55
+
56
+ #[derive(Debug, Clone, PartialEq)]
57
+ pub enum StrPart {
58
+ Text(String),
59
+ Interp(Box<Term>),
60
+ }
61
+
62
+ impl Term {
63
+ pub fn call(name: &str, args: Vec<Term>, span: Span) -> Term {
64
+ Term::Call(Box::new(Call {
65
+ callee: Callee::Name(name.to_string()),
66
+ args,
67
+ span,
68
+ }))
69
+ }
70
+
71
+ pub fn block(stmts: Vec<Term>, span: Span) -> Term {
72
+ Term::call("__block__", stmts, span)
73
+ }
74
+
75
+ pub fn span(&self) -> Span {
76
+ match self {
77
+ Term::Call(c) => c.span,
78
+ _ => Span::default(),
79
+ }
80
+ }
81
+
82
+ /// The statements of a `__block__`, or the term itself as a single one.
83
+ pub fn as_block(&self) -> Vec<Term> {
84
+ match self {
85
+ Term::Call(c) if matches!(&c.callee, Callee::Name(n) if n == "__block__") => {
86
+ c.args.clone()
87
+ }
88
+ other => vec![other.clone()],
89
+ }
90
+ }
91
+
92
+ pub fn is_call_named(&self, name: &str) -> bool {
93
+ matches!(self, Term::Call(c)
94
+ if matches!(&c.callee, Callee::Name(n) if n == name))
95
+ }
96
+
97
+ /// Plain string literal contents when the term is an uninterpolated string.
98
+ pub fn as_plain_str(&self) -> Option<String> {
99
+ match self {
100
+ Term::Str(parts) => {
101
+ let mut out = String::new();
102
+ for p in parts {
103
+ match p {
104
+ StrPart::Text(t) => out.push_str(t),
105
+ StrPart::Interp(_) => return None,
106
+ }
107
+ }
108
+ Some(out)
109
+ }
110
+ _ => None,
111
+ }
112
+ }
113
+
114
+ /// Look up `key:` in a trailing keyword segment of `args`.
115
+ pub fn keyword_arg<'a>(args: &'a [Term], key: &str) -> Option<&'a Term> {
116
+ for arg in args.iter().rev() {
117
+ match arg {
118
+ Term::Pair(k, v) if k == key => return Some(v),
119
+ Term::List(items) => {
120
+ for item in items {
121
+ if let Term::Pair(k, v) = item {
122
+ if k == key {
123
+ return Some(v);
124
+ }
125
+ }
126
+ }
127
+ }
128
+ _ => {}
129
+ }
130
+ }
131
+ None
132
+ }
133
+ }