ztsdb
ast.hpp
1 // (C) 2016 Leonardo Silvestri
2 //
3 // This file is part of ztsdb.
4 //
5 // ztsdb is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // ztsdb is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with ztsdb. If not, see <http://www.gnu.org/licenses/>.
17 
18 
19 #ifndef AST_HPP
20 #define AST_HPP
21 
22 #include <cstdint>
23 #include <iostream>
24 #include <cstring>
25 #include <vector>
26 #include <set>
27 #include <map>
28 #include "globals.hpp"
29 #include "timezone/interval.hpp"
30 #include "cow_ptr.hpp"
31 #include "string.hpp"
32 #include "array.hpp"
33 #include "main_parser/location.hpp"
34 #include "main_parser/position.hpp"
35 
36 
37 using namespace std;
38 
39 
40 enum Etype {
41  etempty,
42  etnull,
43  etnext,
44  etbreak,
45  etellipsis,
46  etbool,
47  etdouble,
48  etdtime,
49  etinterval,
50  etsymbol,
51  etstring,
52  etboundvar,
53  etescape,
54  etinvoke,
55  etunop,
56  etbinop,
57  etexprlist,
58  etwhile,
59  etifelse,
60  etfor,
61  etleftassign,
62  etspecialassign,
63  etrequest,
64  ettaggedexpr,
65  etfunction,
66  etfuncall,
67  etcode,
68  etarg,
69 };
70 
71 using loc_t = yy::location;
72 using pos_t = yy::position;
73 
74 extern const char* et_to_string[];
75 
76 struct E {
77  E(Etype et, const loc_t& l) : etype(et), loc(l) {
78  // std::cout << "E loc: " << l << std::endl;
79  }
80  virtual E* clone() const { return new E(*this); }
81  virtual bool operator==(const E& o) const { return etype == o.etype; }
82  Etype etype;
83  virtual ~E() { }
84  loc_t loc;
85 
86 private:
87  E(const E& e) : etype(e.etype), loc(e.loc) { }
88 };
89 
90 template<Etype t>
91 struct Et : E {
92  Et(const loc_t& l) : E(t, l) { }
93  virtual Et* clone() const { return new Et(*this); }
94 
95 private:
96  Et(const Et& e) : E(t, e.loc) { }
97 };
98 
99 using Null = Et<etnull>;
100 using Next = Et<etnext>;
101 using Break = Et<etbreak>;
102 using Ellipsis = Et<etellipsis>;
103 
104 
105 template<Etype t>
106 struct SElt : E {
107  SElt(const string& s, const loc_t& l) : E(t, l), data(s) { }
108  string data;
109  virtual SElt* clone() const { return new SElt(*this); }
110  virtual bool operator==(const SElt& s) const {
111  return data == s.data;
112  }
113 private:
114  SElt(const SElt& e) : E(t, e.loc), data(e.data) { }
115 };
116 
117 using Invoke = SElt<etinvoke>;
118 using Boundvar = SElt<etboundvar>;
119 
120 
121 struct Symbol : E {
122  Symbol(const string& s, const loc_t& l, bool ref_p=false) :
123  E(etsymbol, l), data(s), ref(ref_p) { }
124 
125  string data;
126  const bool ref; // is it a reference?
127 
128  virtual Symbol* clone() const { return new Symbol(*this); }
129  virtual bool operator==(const Symbol& s) const { return data == s.data; }
130  ~Symbol() { }
131 private:
132  Symbol(const Symbol& e) : E(etsymbol, e.loc), data(e.data), ref(e.ref) { }
133 };
134 
135 
136 struct ElNode {
137  ElNode(E* e_p) : e(e_p), next(nullptr) { }
138  E* e;
139  ElNode* next;
140  ~ElNode() {
141  if (e) delete e;
142  }
143 };
144 
145 struct El : E { // Expression list element
146  El() : E(etexprlist, yy::missing_loc()), n(0), begin(nullptr), end(nullptr) { }
147  El(E* e) : E(etexprlist, e->loc) {
148  begin = end = new ElNode(e);
149  n = 1;
150  }
151 
152  // update locations as expressions are added! LLL
153  El* add(E* e) {
154  ElNode* eln = new ElNode(e);
155  if (end) {
156  end->next = eln;
157  } else {
158  begin = eln;
159  }
160  end = eln;
161  ++n;
162  return this;
163  }
164 
165  El* addfirst(E* e) {
166  ElNode* eln = new ElNode(e);
167  eln->next = begin;
168  begin = eln;
169  if (!end) {
170  end = eln;
171  }
172  ++n;
173  return this;
174  }
175 
176  El* addafter(E* e, ElNode*& here) {
177  if (here) {
178  ElNode* eln = new ElNode(e);
179  eln->next = here->next;
180  here->next = eln;
181  if (end == here) {
182  end = eln;
183  }
184  here = eln; // so multiple insertions are sequential
185  ++n;
186  }
187  else {
188  addfirst(e);
189  here = begin;
190  }
191  return this;
192  }
193 
196  auto node = here;
197  here = here->next;
198  node->e = nullptr;
199  node->next = nullptr;
200  delete node;
201  --n;
202  return this;
203  }
204 
205  virtual El* clone() const { return new El(*this); }
206  virtual bool operator==(const El& el) const {
207  if (n != el.n) {
208  return false;
209  }
210 
211  bool equal = true;
212  ElNode* iter = begin;
213  ElNode* iters = el.begin;
214  for (unsigned i=0; i<n; ++i) {
215  if (!(*iter->e == *iters->e)) {
216  return false;
217  } else {
218  iter = iter->next;
219  iters = iters->next;
220  }
221  }
222  return equal;
223  }
224 
225  unsigned n; // number of elements
226  ElNode* begin;
227  ElNode* end;
228  ~El() {
229  ElNode* iter = begin;
230  ElNode* next = nullptr;
231  for (unsigned i=0; i<n; ++i) {
232  next = iter->next;
233  delete iter;
234  iter = next;
235  }
236  }
237 
238 private:
239  El(const El& el) : E(etexprlist, el.loc) {
240  n = el.n;
241  if (el.begin) {
242  begin = new ElNode(el.begin->e->clone());
243  ElNode* iterclone = begin;
244  ElNode* iter = el.begin;
245  while (iter->next) {
246  iterclone->next = new ElNode(iter->next->e->clone());
247  iterclone = iterclone->next;
248  iter = iter->next;
249  }
250  end = iterclone;
251  }
252  else {
253  begin = el.begin;
254  end = el.end;
255  }
256  }
257 };
258 
259 template<Etype t>
260 struct EEl : E {
261  EEl(E* e_p, El* el_p) :
262  E(t, yy::span_loc(e_p->loc, el_p->loc)), e(e_p), el(el_p) { }
263  EEl(E* e_p) : E(t, e_p->loc), e(e_p), el(nullptr) { }
264  virtual EEl* clone() const { return new EEl(*this); }
265  virtual bool operator==(const EEl<t>& eel) const {
266  return *e == *eel.e ? *el == *eel.el : false;
267  }
268 
269  E* e;
270  El* el;
271  ~EEl() { delete e; delete el; }
272 
273 private:
274  EEl(const EEl& ee) : E(t, ee.loc), e(ee.e->clone()), el(ee.el->clone()) { }
275 };
276 
277 using Funcall = EEl<etfuncall>;
278 
279 struct Binop : E {
280  Binop(unsigned op_p, E* l, E* r, loc_t loc_p, E* a=nullptr) :
281  E(etbinop, loc_p), op(op_p), left(l), right(r), attrib(a ? a : new Null(yy::missing_loc())) { }
282  virtual Binop* clone() const { return new Binop(*this); }
283  virtual bool operator==(const Binop& b) const {
284  return op == b.op ?
285  *left == *b.left ?
286  *right == *b.right ?
287  *attrib == *b.attrib : false : false : false;
288  }
289 
290  unsigned op;
291  E* left;
292  E* right;
293  E* attrib;
294  ~Binop() { delete left; delete right; delete attrib; }
295 
296 private:
297  Binop(const Binop& b) :
298  E(etbinop, b.loc),
299  op(b.op),
300  left(b.left->clone()),
301  right(b.right->clone()),
302  attrib(b.attrib->clone()) { }
303 };
304 
305 struct Unop : E {
306  Unop(unsigned op_p, E* e_p, loc_t l) : E(etunop, l), op(op_p), e(e_p) { }
307  virtual Unop* clone() const { return new Unop(*this); }
308  virtual bool operator==(const Unop& u) const {
309  return op == u.op ? (*e == *u.e) : false;
310  }
311 
312  unsigned op;
313  E* e;
314  ~Unop() { delete e; }
315 
316 private:
317  Unop(const Unop& u) : E(etunop, u.loc), op(u.op), e(u.e->clone()) { }
318 };
319 
320 
321 template<Etype t>
322 struct E1 : E {
323  E1(E* e_p, loc_t l) : E(t, l), e(e_p) { }
324  virtual E* clone() const { return new E1(*this); }
325  virtual bool operator==(const E1<t>& ee) const {
326  return *e == *ee.e;
327  }
328 
329  E* e;
330  ~E1() { if (e) delete e; }
331 
332 private:
333  E1(const E1& e) : E(t, e.loc), e(e.e->clone()) { }
334 };
335 
336 using Code = E1<etcode>;
337 using Escape = E1<etescape>;
338 
339 
340 template<Etype t>
341 struct E2 : E {
342  E2(E* e1_p, E* e2_p, loc_t l) : E(t, l), e1(e1_p), e2(e2_p) { }
343  virtual E2* clone() const { return new E2(*this); }
344  virtual bool operator==(const E2<t>& e) const {
345  return *e1 == *e.e1 ? (*e2 == *e.e2) : false;
346  }
347 
348  E* e1;
349  E* e2;
350  ~E2() { delete e1; delete e2; }
351 
352 private:
353  E2(const E2& e) : E(t, e.loc), e1(e.e1->clone()), e2(e.e2->clone()) { }
354 };
355 
356 using While = E2<etwhile>;
359 using Request = E2<etrequest>; // 'e1' is the connection and 'e2' the request itself
360 
361 template<Etype t>
362 struct E3 : E { // ifelse, while
363  E3(E* e1_p, E* e2_p, E* e3_p, loc_t l) : E(t, l), e1(e1_p), e2(e2_p), e3(e3_p) { }
364  virtual E3* clone() const { return new E3(*this); }
365  virtual bool operator==(const E3<t>& e) const {
366  return *e1 == *e.e1 ?
367  (*e2 == *e.e2 ?
368  (*e3 == *e.e3) : false) : false;
369  }
370 
371  E* e1;
372  E* e2;
373  E* e3;
374  ~E3() { delete e1; delete e2; delete e3; }
375 
376 private:
377  E3(const E3& e) : E(t, e.loc), e1(e.e1->clone()), e2(e.e2->clone()), e3(e.e3->clone()) { }
378 };
379 
380 using IfElse = E3<etifelse>;
381 
382 struct For : E {
383  For(Symbol* s, E* e1, E* e2, loc_t l);
384  For(E* forloop_p, loc_t l) :
385  E(etfor, l), forloop(forloop_p) { } // only used in decoding, and
386  // please note that forloop_p
387  // relinquishes ownership to
388  // forloop!
389  virtual For* clone() const { return new For(*this); }
390  virtual bool operator==(const For& f) const { return *forloop == *f.forloop; }
391 
392  E* forloop;
393  ~For() { delete forloop; }
394 
395 private:
396  For(const For& f) : E(etfor, f.loc), forloop(f.forloop->clone()) { }
397 };
398 
399 template<Etype t, typename T>
400 struct EData : E { // double, int, bool
402  typedef T value_type;
403 
404  EData(T d, loc_t l) :
405  E(t, l), data(arr::make_cow<arr::Array<T>>(false,
407  arr::Vector<T>{d},
408  vector<arr::Vector<arr::zstring>>())) { }
409  virtual EData* clone() const { return new EData(*this); }
410  virtual bool operator==(const EData& ed) const {
411  return *data == *ed.data;
412  }
413 
415 private:
416  EData(const EData& e) : E(t, e.loc), data(e.data) { }
417 };
418 
424 
425 template<Etype t>
426 struct GenArg : E {
427  GenArg(Symbol* s, E* e_p, loc_t l) : E(t, l), symb(s), e(e_p) { }
428  virtual GenArg* clone() const { return new GenArg(*this); }
429  virtual bool operator==(const GenArg& te) const {
430  return *symb == *te.symb ? (*e == *te.e) : false;
431  }
432 
433  Symbol* symb;
434  E* e;
435  ~GenArg() { delete symb; delete e; }
436 
437 private:
438  GenArg(const GenArg& te) :
439  E(t, te.loc), symb(te.symb->clone()), e(te.e->clone()) { }
440 };
441 
443 
444 struct Arg : GenArg<etarg> {
445  Arg(bool ref_p, E* e_p, loc_t l) : GenArg(new Symbol("", l, ref_p), e_p, l) { }
446 };
447 
448 
449 struct Function : E {
450  Function(E* b, loc_t l) : E(etfunction, l), formlist(nullptr), body(b) { }
451  Function(El* fl, E* b, loc_t l) : E(etfunction, l), formlist(fl), body(b) { }
452 
453  virtual Function* clone() const { return new Function(*this); }
454  virtual bool operator==(const Function& f) const {
455  return *formlist == *f.formlist ? *body == *f.body : false;
456  }
457 
458  El* formlist;
459  E* body;
460 
461  void processFormlist(map<string, int>& argMap, int& ellipsisPos) {
462  ellipsisPos = -1;
463  if (formlist) {
464  ElNode* eln = formlist->begin;
465  for (unsigned n=0; n<formlist->n; ++n) {
466  if (eln->e->etype == ettaggedexpr) {
467  auto te = static_cast<TaggedExpr*>(eln->e);
468  auto res = argMap.emplace(te->symb->data, static_cast<int>(n));
469  if (!res.second) {
470  throw range_error("repeated formal argument '" + te->symb->data + "'");
471  }
472  }
473  else if (eln->e->etype == etsymbol) {
474  auto symb = static_cast<Symbol*>(eln->e);
475  auto res = argMap.emplace(symb->data, static_cast<int>(n));
476  if (!res.second) {
477  throw range_error("repeated formal argument '" + symb->data + "'");
478  }
479  }
480  else {
481  if (ellipsisPos != -1) {
482  throw std::range_error("repeated formal argument '...'");
483  }
484  else {
485  ellipsisPos = static_cast<int>(n);
486  }
487  }
488  eln = eln->next;
489  }
490  }
491  }
492 
493  ~Function() { if (formlist) delete formlist; delete body; }
494 
495 private:
496  Function(const Function& f) :
497  E(etfunction, f.loc),
498  formlist(f.formlist ? f.formlist->clone() : nullptr),
499  body(f.body->clone()) { }
500 };
501 
502 
503 
504 string to_string(const E& e);
505 // comma-separated:
506 string to_string_cs(const El& el);
507 
508 void getBoundVars(E* e, set<string>& ss);
509 
510 bool isEqual(const E*, const E*);
511 
512 
513 #endif
E
Definition: ast.hpp:76
Et
Definition: ast.hpp:91
For
Definition: ast.hpp:382
El
Definition: ast.hpp:145
ElNode
Definition: ast.hpp:136
Symbol
Definition: ast.hpp:121
EData
Definition: ast.hpp:400
arr::cow_ptr
Definition: cow_ptr.hpp:42
arr::Vector
Definition: vector_base.hpp:103
GenArg
Definition: ast.hpp:426
position.hpp
yy::location
Abstract a location.
Definition: location.hpp:54
Binop
Definition: ast.hpp:279
Function
Definition: ast.hpp:449
E1
Definition: ast.hpp:322
Arg
Definition: ast.hpp:444
El::remove_nodelete
El * remove_nodelete(ElNode *&here)
Remove the node pointed to by 'here', but don't delete the expression.
Definition: ast.hpp:195
location.hpp
E3
Definition: ast.hpp:362
yy::position
Abstract a position.
Definition: position.hpp:62
E2
Definition: ast.hpp:341
SElt
Definition: ast.hpp:106
EEl
Definition: ast.hpp:260
arr::Array
Definition: array.hpp:109
Unop
Definition: ast.hpp:305