as2js: /home/snapwebsites/snapcpp/contrib/as2js/lib/node_display.cpp Source File

as2js  0.1.14
AlexScript to JavaScript
node_display.cpp
Go to the documentation of this file.
1 /* lib/node_display.cpp
2 
3 Copyright (c) 2005-2019 Made to Order Software Corp. All Rights Reserved
4 
6 
7 Permission is hereby granted, free of charge, to any
8 person obtaining a copy of this software and
9 associated documentation files (the "Software"), to
10 deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify,
12 merge, publish, distribute, sublicense, and/or sell
13 copies of the Software, and to permit persons to whom
14 the Software is furnished to do so, subject to the
15 following conditions:
16 
17 The above copyright notice and this permission notice
18 shall be included in all copies or substantial
19 portions of the Software.
20 
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
22 ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
23 LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
24 FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
25 EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
27 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
28 ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 SOFTWARE.
31 
32 */
33 
34 #include "as2js/node.h"
35 #include "as2js/os_raii.h"
36 
37 #include <iomanip>
38 
39 
67 namespace as2js
68 {
69 
70 
71 /**********************************************************************/
72 /**********************************************************************/
73 /*** NODE DISPLAY ***************************************************/
74 /**********************************************************************/
75 /**********************************************************************/
76 
77 
91 void Node::display_data(std::ostream& out) const
92 {
93  // safely save the output stream flags
94  raii_stream_flags stream_flags(out);
95 
96  struct sub_function
97  {
98  static void display_str(std::ostream & out, String str)
99  {
100  out << ": '";
101  for(as_char_t const *s(str.c_str()); *s != '\0'; ++s)
102  {
103  if(*s < 0x20)
104  {
105  // show controls as ^<letter>
106  out << '^' << static_cast<char>(*s + '@');
107  }
108  else if(*s < 0x7f)
109  {
110  if(*s == '\'')
111  {
112  out << "\\'";
113  }
114  else
115  {
116  out << static_cast<char>(*s);
117  }
118  }
119  else if(*s < 0x100)
120  {
121  out << "\\x" << std::hex << *s << std::dec;
122  }
123  else if(*s < 0x10000)
124  {
125  out << "\\u" << std::hex << std::setfill('0') << std::setw(4) << *s << std::dec;
126  }
127  else
128  {
129  out << "\\U" << std::hex << std::setfill('0') << std::setw(8) << *s << std::dec;
130  }
131  }
132  out << "'";
133  }
134  };
135 
136  // WARNING: somehow g++ views the node_t type as a Node type and thus
137  // it recursively calls this function until the stack is full
138  out << std::setw(4) << std::setfill('0') << static_cast<int>(static_cast<node_t>(f_type))
139  << std::setfill('\0') << ": " << get_type_name();
140  if(static_cast<int>(static_cast<node_t>(f_type)) > ' ' && static_cast<int>(static_cast<node_t>(f_type)) < 0x7F)
141  {
142  out << " = '" << static_cast<char>(static_cast<node_t>(f_type)) << "'";
143  }
144 
145  switch(f_type)
146  {
147  case node_t::NODE_BREAK:
149  case node_t::NODE_GOTO:
151  case node_t::NODE_LABEL:
154  sub_function::display_str(out, f_str);
155  break;
156 
157  case node_t::NODE_CATCH:
158  out << ":";
159  if(f_flags[static_cast<size_t>(flag_t::NODE_CATCH_FLAG_TYPED)])
160  {
161  out << " TYPED";
162  }
163  break;
164 
166  out << ":";
168  {
169  out << " NEW-VARIABLES";
170  }
171  break;
172 
173  case node_t::NODE_ENUM:
174  sub_function::display_str(out, f_str);
175  if(f_flags[static_cast<size_t>(flag_t::NODE_ENUM_FLAG_CLASS)])
176  {
177  out << " CLASS";
178  }
179  if(f_flags[static_cast<size_t>(flag_t::NODE_ENUM_FLAG_INUSE)])
180  {
181  out << " INUSE";
182  }
183  break;
184 
185  case node_t::NODE_FOR:
186  out << ":";
187  if(f_flags[static_cast<size_t>(flag_t::NODE_FOR_FLAG_CONST)])
188  {
189  out << " CONST";
190  }
191  if(f_flags[static_cast<size_t>(flag_t::NODE_FOR_FLAG_FOREACH)])
192  {
193  out << " FOREACH";
194  }
195  if(f_flags[static_cast<size_t>(flag_t::NODE_FOR_FLAG_IN)])
196  {
197  out << " IN";
198  }
199  break;
200 
201  case node_t::NODE_CLASS:
203  case node_t::NODE_STRING:
205  sub_function::display_str(out, f_str);
206  if(f_flags[static_cast<size_t>(flag_t::NODE_IDENTIFIER_FLAG_WITH)])
207  {
208  out << " WITH";
209  }
210  if(f_flags[static_cast<size_t>(flag_t::NODE_IDENTIFIER_FLAG_TYPED)])
211  {
212  out << " TYPED";
213  }
214  break;
215 
216  case node_t::NODE_IMPORT:
217  sub_function::display_str(out, f_str);
218  if(f_flags[static_cast<size_t>(flag_t::NODE_IMPORT_FLAG_IMPLEMENTS)])
219  {
220  out << " IMPLEMENTS";
221  }
222  break;
223 
225  sub_function::display_str(out, f_str);
226  if(f_flags[static_cast<size_t>(flag_t::NODE_PACKAGE_FLAG_FOUND_LABELS)])
227  {
228  out << " FOUND-LABELS";
229  }
230  if(f_flags[static_cast<size_t>(flag_t::NODE_PACKAGE_FLAG_REFERENCED)])
231  {
232  out << " REFERENCED";
233  }
234  break;
235 
236  case node_t::NODE_INT64:
237  out << ": " << f_int.get() << ", 0x" << std::hex << std::setw(16) << std::setfill('0') << f_int.get() << std::dec << std::setw(0) << std::setfill('\0');
238  break;
239 
241  out << ": " << f_float.get();
242  break;
243 
245  sub_function::display_str(out, f_str);
246  if(f_flags[static_cast<size_t>(flag_t::NODE_FUNCTION_FLAG_GETTER)])
247  {
248  out << " GETTER";
249  }
250  if(f_flags[static_cast<size_t>(flag_t::NODE_FUNCTION_FLAG_SETTER)])
251  {
252  out << " SETTER";
253  }
254  if(f_flags[static_cast<size_t>(flag_t::NODE_FUNCTION_FLAG_OUT)])
255  {
256  out << " OUT";
257  }
258  if(f_flags[static_cast<size_t>(flag_t::NODE_FUNCTION_FLAG_VOID)])
259  {
260  out << " VOID";
261  }
262  if(f_flags[static_cast<size_t>(flag_t::NODE_FUNCTION_FLAG_NEVER)])
263  {
264  out << " NEVER";
265  }
266  if(f_flags[static_cast<size_t>(flag_t::NODE_FUNCTION_FLAG_NOPARAMS)])
267  {
268  out << " NOPARAMS";
269  }
270  if(f_flags[static_cast<size_t>(flag_t::NODE_FUNCTION_FLAG_OPERATOR)])
271  {
272  out << " OPERATOR";
273  }
274  break;
275 
276  case node_t::NODE_PARAM:
277  sub_function::display_str(out, f_str);
278  out << ":";
279  if(f_flags[static_cast<size_t>(flag_t::NODE_PARAM_FLAG_CONST)])
280  {
281  out << " CONST";
282  }
283  if(f_flags[static_cast<size_t>(flag_t::NODE_PARAM_FLAG_IN)])
284  {
285  out << " IN";
286  }
287  if(f_flags[static_cast<size_t>(flag_t::NODE_PARAM_FLAG_OUT)])
288  {
289  out << " OUT";
290  }
291  if(f_flags[static_cast<size_t>(flag_t::NODE_PARAM_FLAG_NAMED)])
292  {
293  out << " NAMED";
294  }
295  if(f_flags[static_cast<size_t>(flag_t::NODE_PARAM_FLAG_REST)])
296  {
297  out << " REST";
298  }
299  if(f_flags[static_cast<size_t>(flag_t::NODE_PARAM_FLAG_UNCHECKED)])
300  {
301  out << " UNCHECKED";
302  }
303  if(f_flags[static_cast<size_t>(flag_t::NODE_PARAM_FLAG_UNPROTOTYPED)])
304  {
305  out << " UNPROTOTYPED";
306  }
307  if(f_flags[static_cast<size_t>(flag_t::NODE_PARAM_FLAG_REFERENCED)])
308  {
309  out << " REFERENCED";
310  }
311  if(f_flags[static_cast<size_t>(flag_t::NODE_PARAM_FLAG_PARAMREF)])
312  {
313  out << " PARAMREF";
314  }
315  if(f_flags[static_cast<size_t>(flag_t::NODE_PARAM_FLAG_CATCH)])
316  {
317  out << " CATCH";
318  }
319  break;
320 
322  out << ":";
323  if(f_flags[static_cast<size_t>(flag_t::NODE_PARAM_MATCH_FLAG_UNPROTOTYPED)])
324  {
325  out << " UNPROTOTYPED";
326  }
327  break;
328 
329  case node_t::NODE_SWITCH:
330  out << ":";
331  if(f_flags[static_cast<size_t>(flag_t::NODE_SWITCH_FLAG_DEFAULT)])
332  {
333  out << " DEFAULT";
334  }
335  break;
336 
337  case node_t::NODE_TYPE:
338  out << ":";
339  if(f_flags[static_cast<size_t>(flag_t::NODE_TYPE_FLAG_MODULO)])
340  {
341  out << " MODULO";
342  }
343  break;
344 
347  sub_function::display_str(out, f_str);
348  if(f_flags[static_cast<size_t>(flag_t::NODE_VARIABLE_FLAG_CONST)])
349  {
350  out << " CONST";
351  }
352  if(f_flags[static_cast<size_t>(flag_t::NODE_VARIABLE_FLAG_FINAL)])
353  {
354  out << " FINAL";
355  }
356  if(f_flags[static_cast<size_t>(flag_t::NODE_VARIABLE_FLAG_LOCAL)])
357  {
358  out << " LOCAL";
359  }
360  if(f_flags[static_cast<size_t>(flag_t::NODE_VARIABLE_FLAG_MEMBER)])
361  {
362  out << " MEMBER";
363  }
364  if(f_flags[static_cast<size_t>(flag_t::NODE_VARIABLE_FLAG_ATTRIBUTES)])
365  {
366  out << " ATTRIBUTES";
367  }
368  if(f_flags[static_cast<size_t>(flag_t::NODE_VARIABLE_FLAG_ENUM)])
369  {
370  out << " ENUM";
371  }
372  if(f_flags[static_cast<size_t>(flag_t::NODE_VARIABLE_FLAG_COMPILED)])
373  {
374  out << " COMPILED";
375  }
376  if(f_flags[static_cast<size_t>(flag_t::NODE_VARIABLE_FLAG_INUSE)])
377  {
378  out << " INUSE";
379  }
380  if(f_flags[static_cast<size_t>(flag_t::NODE_VARIABLE_FLAG_ATTRS)])
381  {
382  out << " ATTRS";
383  }
384  if(f_flags[static_cast<size_t>(flag_t::NODE_VARIABLE_FLAG_DEFINED)])
385  {
386  out << " DEFINED";
387  }
388  if(f_flags[static_cast<size_t>(flag_t::NODE_VARIABLE_FLAG_DEFINING)])
389  {
390  out << " DEFINING";
391  }
392  if(f_flags[static_cast<size_t>(flag_t::NODE_VARIABLE_FLAG_TOADD)])
393  {
394  out << " TOADD";
395  }
396  break;
397 
398  default:
399  break;
400 
401  }
402 }
403 
404 
425 void Node::display(std::ostream& out, int indent, char c) const
426 {
427  // safely save the output stream flags
428  raii_stream_flags stream_flags(out);
429 
430  // this pointer and indentation
431  out << this << ": " << std::setfill('0') << std::setw(2) << indent << std::setfill(' ') << c << std::setw(indent) << "";
432 
433  // display node data (integer, string, float, etc.)
434  display_data(out);
435 
436  // display information about the links
437  {
438  pointer_t node(f_instance.lock());
439  if(node)
440  {
441  out << " Instance: " << node.get();
442  }
443  }
444  {
445  pointer_t node(f_type_node.lock());
446  if(node)
447  {
448  out << " Type Node: " << node.get();
449  }
450  }
451  {
452  if(f_attribute_node)
453  {
454  out << " Attribute Node: " << f_attribute_node.get();
455  }
456  }
457  {
458  pointer_t node(f_goto_exit.lock());
459  if(node)
460  {
461  out << " Goto Exit: " << node.get();
462  }
463  }
464  {
465  pointer_t node(f_goto_enter.lock());
466  if(node)
467  {
468  out << " Goto Enter: " << node.get();
469  }
470  }
471 
472  // display the different attributes if any
473  struct display_attributes
474  {
475  display_attributes(std::ostream& out, attribute_set_t attrs)
476  : f_out(out)
477  , f_attributes(attrs)
478  {
479  display_attribute(attribute_t::NODE_ATTR_PUBLIC);
480  display_attribute(attribute_t::NODE_ATTR_PRIVATE);
481  display_attribute(attribute_t::NODE_ATTR_PROTECTED);
482  display_attribute(attribute_t::NODE_ATTR_INTERNAL);
483  display_attribute(attribute_t::NODE_ATTR_TRANSIENT);
484  display_attribute(attribute_t::NODE_ATTR_VOLATILE);
485 
486  display_attribute(attribute_t::NODE_ATTR_STATIC);
487  display_attribute(attribute_t::NODE_ATTR_ABSTRACT);
488  display_attribute(attribute_t::NODE_ATTR_VIRTUAL);
489  display_attribute(attribute_t::NODE_ATTR_ARRAY);
490  display_attribute(attribute_t::NODE_ATTR_INLINE);
491 
492  display_attribute(attribute_t::NODE_ATTR_REQUIRE_ELSE);
493  display_attribute(attribute_t::NODE_ATTR_ENSURE_THEN);
494 
495  display_attribute(attribute_t::NODE_ATTR_NATIVE);
496 
497  display_attribute(attribute_t::NODE_ATTR_DEPRECATED);
498  display_attribute(attribute_t::NODE_ATTR_UNSAFE);
499 
500  display_attribute(attribute_t::NODE_ATTR_CONSTRUCTOR);
501 
502  //display_attribute(attribute_t::NODE_ATTR_CONST); -- this is a flag, not needed here
503  display_attribute(attribute_t::NODE_ATTR_FINAL);
504  display_attribute(attribute_t::NODE_ATTR_ENUMERABLE);
505 
506  display_attribute(attribute_t::NODE_ATTR_TRUE);
507  display_attribute(attribute_t::NODE_ATTR_FALSE);
508  display_attribute(attribute_t::NODE_ATTR_UNUSED);
509 
510  display_attribute(attribute_t::NODE_ATTR_DYNAMIC);
511 
512  display_attribute(attribute_t::NODE_ATTR_FOREACH);
513  display_attribute(attribute_t::NODE_ATTR_NOBREAK);
514  display_attribute(attribute_t::NODE_ATTR_AUTOBREAK);
515 
516  display_attribute(attribute_t::NODE_ATTR_TYPE);
517 
518  display_attribute(attribute_t::NODE_ATTR_DEFINED);
519  }
520 
521  void display_attribute(attribute_t a)
522  {
523  if(f_attributes[static_cast<size_t>(a)])
524  {
525  if(f_first)
526  {
527  f_first = false;
528  f_out << " attrs:";
529  }
530  f_out << " " << Node::attribute_to_string(a);
531  }
532  }
533 
534  std::ostream& f_out;
535  bool f_first = true;
537  } display_attr(out, f_attributes);
538 
539  // end the line with our position
540  out << " (" << f_position << ")";
541 
542  if(f_lock > 0)
543  {
544  out << " Locked: " << static_cast<int32_t>(f_lock);
545  }
546 
547  out << std::endl;
548 
549  // now print children
550  for(size_t idx(0); idx < f_children.size(); ++idx)
551  {
552  f_children[idx]->display(out, indent + 1, '-');
553  }
554 
555  // now print variables
556  for(size_t idx(0); idx < f_variables.size(); ++idx)
557  {
558  pointer_t variable(f_variables[idx].lock());
559  if(variable)
560  {
561  variable->display(out, indent + 1, '=');
562  }
563  }
564 
565  // now print labels
566  for(auto const & it : f_labels)
567  {
568  pointer_t label(it.second.lock());
569  if(label)
570  {
571  label->display(out, indent + 1, ':');
572  }
573  }
574 }
575 
576 
588 std::ostream& operator << (std::ostream& out, Node const& node)
589 {
590  node.display(out, 2, '.');
591  return out;
592 }
593 
594 
595 }
596 // namespace as2js
597 
598 // vim: ts=4 sw=4 et
float64_type get() const
Definition: float64.h:71
int32_t as_char_t
Definition: string.h:47
weak_pointer_t f_goto_enter
Definition: node.h:623
weak_pointer_t f_type_node
Definition: node.h:595
A class used to safely handle stream flags, width, and precision.
Definition: os_raii.h:42
weak_pointer_t f_goto_exit
Definition: node.h:624
node_t f_type
Definition: node.h:594
weak_pointer_t f_instance
Definition: node.h:620
void display_data(std::ostream &out) const
Display a node.
String f_str
Definition: node.h:610
void lock()
Lock this node.
Definition: node_lock.cpp:164
int32_t f_lock
Definition: node.h:602
flag_set_t f_flags
Definition: node.h:596
static char const * attribute_to_string(attribute_t const attr)
Convert an attribute to a string.
attribute_t
Definition: node.h:352
vector_of_pointers_t f_children
Definition: node.h:619
void display(std::ostream &out, int indent, char c) const
Display a node tree.
int64_type get() const
Definition: int64.h:69
std::shared_ptr< Node > pointer_t
Definition: node.h:67
attribute_set_t f_attributes
Definition: node.h:598
std::bitset< static_cast< int >attribute_t::NODE_ATTR_max)> attribute_set_t
Definition: node.h:421
std::ostream & operator<<(std::ostream &out, Node const &node)
Send a node to the specified output stream.
Float64 f_float
Definition: node.h:609
vector_of_weak_pointers_t f_variables
Definition: node.h:627
map_of_weak_pointers_t f_labels
Definition: node.h:628
Int64 f_int
Definition: node.h:608
Position f_position
Definition: node.h:605
The AlexScript to JavaScript namespace.
Definition: compiler.cpp:37
pointer_t f_attribute_node
Definition: node.h:597
char const * get_type_name() const
Retrieve the type of this node.
Definition: node_type.cpp:475

This document is part of the Snap! Websites Project.

Copyright by Made to Order Software Corp.

Syndicate content

Snap! Websites
An Open Source CMS System in C++

Contact Us Directly