1use std::fmt;
2use std::convert::From;
3use syntactic_heap::SyntacticHeap;
4use syntactic_heap::Ref;
5pub use crate::nodes::*;
6
7pub type AbstractSyntaxTree = SyntacticHeap<Node>;
12
13#[derive(Clone,Debug,PartialEq)]
18pub enum Node {
19 Utf8(String),
21 TypeDecl(TypeDecl),
23 FunctionDecl(FunctionDecl),
24 MethodDecl(MethodDecl),
25 AssertStmt(AssertStmt),
27 BlockStmt(BlockStmt),
28 SkipStmt(SkipStmt),
29 BoolExpr(BoolExpr),
31 EqualsExpr(EqualsExpr),
32 NotEqualsExpr(NotEqualsExpr),
33 LessThanExpr(LessThanExpr),
34 IntExpr(IntExpr),
35 VarExpr(VarExpr),
36 ArrayType(ArrayType),
38 BoolType(BoolType),
39 IntType(IntType),
40 NullType(NullType),
41 RecordType(RecordType),
42 ReferenceType(ReferenceType),
43 VoidType(VoidType)
44}
45
46#[derive(Clone,Copy,Debug,PartialEq)]
51pub struct Decl { pub index: usize }
52
53#[derive(Clone,Debug,PartialEq)]
55pub struct Parameter {
56 pub declared : Type,
57 pub name : Name
58}
59
60impl Decl {
61 pub fn new(ast: &mut AbstractSyntaxTree, t : Node) -> Self {
62 assert!(Decl::is(&t));
64 let index = ast.push(t).raw_index();
66 Decl{index}
68 }
69
70 pub fn is(t: &Node) -> bool {
72 match t {
73 Node::FunctionDecl(_) => true,
74 Node::MethodDecl(_) => true,
75 Node::TypeDecl(_) => true,
76 _ => false
77 }
78 }
79}
80
81impl Into<usize> for Decl {
82 fn into(self) -> usize { self.index }
83}
84
85impl From<FunctionDecl> for Node {
86 fn from(d: FunctionDecl) -> Self { Node::FunctionDecl(d) }
87}
88
89impl From<MethodDecl> for Node {
90 fn from(d: MethodDecl) -> Self { Node::MethodDecl(d) }
91}
92
93impl From<TypeDecl> for Node {
94 fn from(d: TypeDecl) -> Self { Node::TypeDecl(d) }
95}
96
97#[derive(Clone,Copy,Debug,PartialEq)]
102pub struct Stmt(pub usize);
103
104impl Stmt {
105 pub fn new(ast: &mut AbstractSyntaxTree, t : Node) -> Self {
106 assert!(Stmt::is(&t));
108 let index = ast.push(t).raw_index();
110 Stmt(index)
112 }
113
114 pub fn is(t: &Node) -> bool {
116 match t {
117 Node::AssertStmt(_) => true,
118 Node::BlockStmt(_) => true,
119 Node::SkipStmt(_) => true,
120 _ => false
121 }
122 }
123}
124
125impl Into<usize> for Stmt {
126 fn into(self) -> usize { self.0 }
127}
128
129impl From<AssertStmt> for Node {
130 fn from(s: AssertStmt) -> Self { Node::AssertStmt(s) }
131}
132
133impl From<BlockStmt> for Node {
134 fn from(s: BlockStmt) -> Self { Node::BlockStmt(s) }
135}
136
137impl From<SkipStmt> for Node {
138 fn from(s: SkipStmt) -> Self { Node::SkipStmt(s) }
139}
140
141#[derive(Clone,Copy,Debug,PartialEq)]
146pub struct Expr(pub usize);
147
148impl Expr {
149 pub fn new(ast: &mut AbstractSyntaxTree, t : Node) -> Self {
150 assert!(Expr::is(&t));
152 let index = ast.push(t).raw_index();
154 Expr(index)
156 }
157
158 pub fn is(t: &Node) -> bool {
160 match t {
161 Node::BoolExpr(_) => true,
162 Node::EqualsExpr(_) => true,
163 Node::LessThanExpr(_) => true,
164 Node::NotEqualsExpr(_) => true,
165 Node::IntExpr(_) => true,
166 Node::VarExpr(_) => true,
167 _ => false
168 }
169 }
170}
171
172impl Into<usize> for Expr {
173 fn into(self) -> usize { self.0 }
174}
175
176impl From<BoolExpr> for Node {
177 fn from(s: BoolExpr) -> Self { Node::BoolExpr(s) }
178}
179
180impl From<EqualsExpr> for Node {
181 fn from(s: EqualsExpr) -> Self { Node::EqualsExpr(s) }
182}
183
184impl From<NotEqualsExpr> for Node {
185 fn from(s: NotEqualsExpr) -> Self { Node::NotEqualsExpr(s) }
186}
187
188impl From<LessThanExpr> for Node {
189 fn from(s: LessThanExpr) -> Self { Node::LessThanExpr(s) }
190}
191
192impl From<IntExpr> for Node {
193 fn from(s: IntExpr) -> Self { Node::IntExpr(s) }
194}
195
196impl From<VarExpr> for Node {
197 fn from(s: VarExpr) -> Self { Node::VarExpr(s) }
198}
199
200#[derive(Clone,Copy,Debug,PartialEq)]
205pub struct Type(pub usize);
206
207impl Type {
208 pub fn new(ast: &mut AbstractSyntaxTree, t : Node) -> Self {
209 assert!(Type::is(ast,&t));
211 let index = ast.push(t).raw_index();
213 Type(index)
215 }
216
217 pub fn is(ast: &AbstractSyntaxTree, t: &Node) -> bool {
219 match t {
220 Node::BoolType(_) => true,
221 Node::IntType(_) => true,
222 Node::NullType(_) => true,
223 Node::VoidType(_) => true,
224 Node::ArrayType(_) => true,
225 Node::ReferenceType(_) => true,
226 Node::RecordType(_) => true,
227 _ => false
228 }
229 }
230}
231
232impl Into<usize> for Type {
233 fn into(self) -> usize { self.0 }
234}
235
236impl From<ArrayType> for Node {
237 fn from(s: ArrayType) -> Self { Node::ArrayType(s) }
238}
239
240impl From<BoolType> for Node {
241 fn from(s: BoolType) -> Self { Node::BoolType(s) }
242}
243
244impl From<IntType> for Node {
245 fn from(s: IntType) -> Self { Node::IntType(s) }
246}
247
248impl From<NullType> for Node {
249 fn from(s: NullType) -> Self { Node::NullType(s) }
250}
251
252impl From<RecordType> for Node {
253 fn from(s: RecordType) -> Self { Node::RecordType(s) }
254}
255
256impl From<ReferenceType> for Node {
257 fn from(s: ReferenceType) -> Self { Node::ReferenceType(s) }
258}
259
260impl From<VoidType> for Node {
261 fn from(s: VoidType) -> Self { Node::VoidType(s) }
262}
263
264#[derive(Clone,Copy,Debug,Hash,PartialEq,Eq)]
269pub struct Name(pub usize);
270
271impl Name {
272 pub fn new(ast: &mut AbstractSyntaxTree, s : &str) -> Self {
273 let node = Node::Utf8(s.to_string());
274 let index = ast.push(node).raw_index();
276 Name(index)
278 }
279}
280
281impl From<Ref<'_,Node>> for Decl {
286 fn from(r: Ref<'_,Node>) -> Decl {
287 Decl{index:r.raw_index()}
288 }
289}
290
291impl From<Ref<'_,Node>> for Stmt {
292 fn from(r: Ref<'_,Node>) -> Stmt {
293 Stmt(r.raw_index())
294 }
295}
296
297impl From<Ref<'_,Node>> for Type {
298 fn from(r: Ref<'_,Node>) -> Type {
299 Type(r.raw_index())
300 }
301}
302
303impl From<Ref<'_,Node>> for Name {
304 fn from(r: Ref<'_,Node>) -> Name {
305 Name(r.raw_index())
306 }
307}
308
309impl fmt::Display for Node {
314 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
315 match self {
316 Node::TypeDecl(d) => {
317 write!(f,"TypeDecl({:?})",d)
318 }
319 Node::ArrayType(t) => {
320 write!(f,"ArrayType({:?})",t.0)
321 }
322 _ => write!(f,"{:?}",self)
324 }
325 }
326}
327
328fn to_string<T:fmt::Display>(items : &[T]) -> String {
329 let mut s = String::new();
330 let mut f = true;
331 s.push('[');
332 for item in items {
333 if !f { s.push(','); }
334 f = false;
335 s.push_str(&item.to_string());
336 }
337 s.push(']');
338 return s;
339}