1use std::mem;
2
3use cljrs_types::span::Span;
4
5#[derive(Debug, Clone)]
10pub struct Form {
11 pub kind: FormKind,
12 pub span: Span,
13}
14
15impl Form {
16 pub fn new(kind: FormKind, span: Span) -> Self {
17 Self { kind, span }
18 }
19
20 pub fn heap_size(&self) -> usize {
22 mem::size_of::<FormKind>() + self.kind.heap_size()
23 }
24}
25
26impl FormKind {
27 pub fn heap_size(&self) -> usize {
29 match self {
30 FormKind::Nil
32 | FormKind::Bool(_)
33 | FormKind::Int(_)
34 | FormKind::Float(_)
35 | FormKind::Char(_)
36 | FormKind::Symbolic(_) => 0,
37
38 FormKind::BigInt(s)
40 | FormKind::BigDecimal(s)
41 | FormKind::Ratio(s)
42 | FormKind::Str(s)
43 | FormKind::Regex(s)
44 | FormKind::Symbol(s)
45 | FormKind::Keyword(s)
46 | FormKind::AutoKeyword(s) => s.capacity(),
47
48 FormKind::List(v)
50 | FormKind::Vector(v)
51 | FormKind::Map(v)
52 | FormKind::Set(v)
53 | FormKind::AnonFn(v) => vec_heap_size(v),
54
55 FormKind::Quote(f)
57 | FormKind::SyntaxQuote(f)
58 | FormKind::Unquote(f)
59 | FormKind::UnquoteSplice(f)
60 | FormKind::Deref(f)
61 | FormKind::Var(f) => mem::size_of::<Form>() + f.heap_size(),
62
63 FormKind::Meta(a, b) => mem::size_of::<Form>() * 2 + a.heap_size() + b.heap_size(),
65
66 FormKind::TaggedLiteral(s, f) => s.capacity() + mem::size_of::<Form>() + f.heap_size(),
68
69 FormKind::ReaderCond { clauses, .. } => vec_heap_size(clauses),
70 }
71 }
72}
73
74impl PartialEq for Form {
75 fn eq(&self, other: &Self) -> bool {
76 self.kind == other.kind
77 }
78}
79
80#[derive(Debug, Clone, PartialEq)]
82pub enum FormKind {
83 Nil,
85 Bool(bool),
86 Int(i64),
87 BigInt(String),
88 Float(f64), BigDecimal(String),
90 Ratio(String),
91 Char(char),
92 Str(String),
93 Regex(String),
94 Symbolic(f64),
96
97 Symbol(String),
99 Keyword(String),
100 AutoKeyword(String),
101
102 List(Vec<Form>),
104 Vector(Vec<Form>),
105 Map(Vec<Form>),
107 Set(Vec<Form>),
108
109 Quote(Box<Form>),
111 SyntaxQuote(Box<Form>),
112 Unquote(Box<Form>),
113 UnquoteSplice(Box<Form>),
114 Deref(Box<Form>),
115 Var(Box<Form>),
117 Meta(Box<Form>, Box<Form>),
120
121 AnonFn(Vec<Form>),
124 TaggedLiteral(String, Box<Form>),
126
127 ReaderCond {
131 splicing: bool,
132 clauses: Vec<Form>,
133 },
134}
135
136fn vec_heap_size(forms: &[Form]) -> usize {
137 mem::size_of_val(forms) + forms.iter().map(|f| f.heap_size()).sum::<usize>()
138}