knave_expand/reader/
form.rs1use std::fmt;
2use std::rc::Rc;
3
4use crate::scope::{ChainPrefix, Scope, ScopeSet};
5use crate::source::Span;
6
7#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
8pub struct Form {
9 kind: Rc<FormKind>,
10 span: Span,
11}
12
13#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
14pub enum FormKind {
15 Symbol(Symbol),
16 String(Rc<str>),
17 Number(Number),
18 List(Vec<Form>),
19}
20
21impl Form {
22 pub const NESTING_LIMIT: usize = 1024;
23
24 pub fn new(kind: FormKind, span: Span) -> Self {
25 Self {
26 kind: Rc::new(kind),
27 span,
28 }
29 }
30
31 pub fn kind(&self) -> &FormKind {
32 &self.kind
33 }
34
35 pub fn span(&self) -> Span {
36 self.span
37 }
38
39 pub fn is_same_form(&self, other: &Form) -> bool {
40 Rc::ptr_eq(&self.kind, &other.kind)
41 }
42
43 pub fn identity(&self) -> *const FormKind {
44 Rc::as_ptr(&self.kind)
45 }
46
47 pub fn form_count(&self) -> usize {
48 let items = self.as_list().unwrap_or_default();
49 1 + items.iter().map(Form::form_count).sum::<usize>()
50 }
51
52 pub fn as_symbol(&self) -> Option<&Symbol> {
53 match self.kind() {
54 FormKind::Symbol(symbol) => Some(symbol),
55 _ => None,
56 }
57 }
58
59 pub fn as_list(&self) -> Option<&[Form]> {
60 match self.kind() {
61 FormKind::List(items) => Some(items),
62 _ => None,
63 }
64 }
65
66 pub fn add_scope(&mut self, scope: Scope) {
67 self.update_scopes(&|scopes| scopes.add(scope));
68 }
69
70 pub fn add_prefix(&mut self, prefix: &ChainPrefix) {
71 self.update_scopes(&|scopes| scopes.add_prefix(prefix));
72 }
73
74 pub fn flip_scope(&mut self, scope: Scope) {
75 self.update_scopes(&|scopes| scopes.flip(scope));
76 }
77
78 pub fn flip_scope_within(&mut self, scope: Scope, allowance: &mut usize) -> bool {
79 self.update_scopes_within(&|scopes| scopes.flip(scope), allowance)
80 }
81
82 pub fn remove_scope(&mut self, scope: Scope) {
83 self.update_scopes(&|scopes| scopes.remove(scope));
84 }
85
86 pub fn retain_scopes(&mut self, keep: &dyn Fn(Scope) -> bool) {
87 self.update_scopes(&|scopes| scopes.retain(keep));
88 }
89
90 pub fn relocate_outside(&mut self, region: Span) {
91 if !region.contains(self.span) {
92 self.span = region;
93 }
94 if self.as_list().is_some()
95 && let FormKind::List(items) = Rc::make_mut(&mut self.kind)
96 {
97 items
98 .iter_mut()
99 .for_each(|item| item.relocate_outside(region));
100 }
101 }
102
103 fn update_scopes(&mut self, update: &dyn Fn(&mut ScopeSet)) {
104 match self.scoped_kind_mut() {
105 Some(FormKind::Symbol(symbol)) => update(symbol.scopes_mut()),
106 Some(FormKind::List(items)) => {
107 items.iter_mut().for_each(|item| item.update_scopes(update))
108 }
109 _ => {}
110 }
111 }
112
113 fn update_scopes_within(
114 &mut self,
115 update: &dyn Fn(&mut ScopeSet),
116 allowance: &mut usize,
117 ) -> bool {
118 let Some(remaining) = allowance.checked_sub(1) else {
119 return false;
120 };
121 *allowance = remaining;
122 match self.scoped_kind_mut() {
123 Some(FormKind::Symbol(symbol)) => {
124 update(symbol.scopes_mut());
125 true
126 }
127 Some(FormKind::List(items)) => items
128 .iter_mut()
129 .all(|item| item.update_scopes_within(update, allowance)),
130 _ => true,
131 }
132 }
133
134 #[inline(always)]
135 fn scoped_kind_mut(&mut self) -> Option<&mut FormKind> {
136 match self.kind() {
137 FormKind::Symbol(_) | FormKind::List(_) => Some(Rc::make_mut(&mut self.kind)),
138 FormKind::String(_) | FormKind::Number(_) => None,
139 }
140 }
141}
142
143impl fmt::Display for Form {
144 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
145 match self.kind() {
146 FormKind::Symbol(symbol) => write!(formatter, "{}", symbol.name()),
147 FormKind::String(text) => write!(formatter, "{text:?}"),
148 FormKind::Number(number) => write!(formatter, "{}", number.text()),
149 FormKind::List(items) => Self::fmt_list(items, formatter),
150 }
151 }
152}
153
154impl Form {
155 fn fmt_list(items: &[Form], formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
156 let rendered: Vec<String> = items.iter().map(Form::to_string).collect();
157 write!(formatter, "({})", rendered.join(" "))
158 }
159}
160
161#[derive(Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
162pub struct Symbol {
163 name: Rc<str>,
164 scopes: ScopeSet,
165}
166
167impl Symbol {
168 pub fn new(name: impl Into<Rc<str>>) -> Self {
169 Self::with_scopes(name, ScopeSet::default())
170 }
171
172 pub fn with_scopes(name: impl Into<Rc<str>>, scopes: ScopeSet) -> Self {
173 Self {
174 name: name.into(),
175 scopes,
176 }
177 }
178
179 pub fn name(&self) -> &str {
180 &self.name
181 }
182
183 pub fn shared_name(&self) -> Rc<str> {
184 Rc::clone(&self.name)
185 }
186
187 pub fn scopes(&self) -> &ScopeSet {
188 &self.scopes
189 }
190
191 pub fn scopes_mut(&mut self) -> &mut ScopeSet {
192 &mut self.scopes
193 }
194}
195
196#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
197pub enum NumberValue {
198 Integer(i128),
199 Float(f64),
200}
201
202#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
203pub struct Number {
204 text: Rc<str>,
205 value: NumberValue,
206}
207
208impl Number {
209 pub fn new(text: impl Into<Rc<str>>, value: NumberValue) -> Self {
210 Self {
211 text: text.into(),
212 value,
213 }
214 }
215
216 pub fn text(&self) -> &str {
217 &self.text
218 }
219
220 pub fn value(&self) -> &NumberValue {
221 &self.value
222 }
223}