Cthulhu  0.2.10
Cthulhu compiler collection
tree.c
Go to the documentation of this file.
1 #include "base/panic.h"
3 #include "cthulhu/tree/query.h"
4 #include "debug/target.h"
5 
7 #include "fs/fs.h"
8 #include "os/os.h"
9 #include "io/io.h"
10 #include "std/map.h"
11 
12 typedef struct dbg_emit_t
13 {
14  io_t *io;
15  size_t indent;
16 } dbg_emit_t;
17 
18 static void dbg_emit(dbg_emit_t *emit, const char *fmt, ...)
19 {
20  for (size_t i = 0; i < emit->indent; ++i)
21  io_write(emit->io, " ", 2);
22 
23  va_list args;
24  va_start(args, fmt);
25  io_vprintf(emit->io, fmt, args);
26  va_end(args);
27 
28  io_write(emit->io, "\n", 1);
29 }
30 
31 static void dbg_emit_tree(dbg_emit_t *emit, const tree_t *tree, const char *name)
32 {
33  dbg_emit(emit, "%s: %s (%p)", name, tree_kind_to_string(tree_get_kind(tree)), tree);
34 }
35 
36 static void dbg_indent(dbg_emit_t *emit)
37 {
38  emit->indent += 1;
39 }
40 
41 static void dbg_dedent(dbg_emit_t *emit)
42 {
43  CTASSERTF(emit->indent > 0, "cannot dedent past 0");
44  emit->indent -= 1;
45 }
46 
47 static void emit_tree(dbg_emit_t *dbg, const tree_t *tree);
48 
49 static void emit_storage(dbg_emit_t *dbg, tree_storage_t storage)
50 {
51  dbg_emit(dbg, "type: %s", tree_to_string(storage.storage));
52  dbg_emit(dbg, "length: %zu", storage.length);
53  dbg_emit(dbg, "qualifiers: %s", quals_string(storage.quals));
54 }
55 
56 static void emit_section(dbg_emit_t *dbg, const char *name, map_t *section)
57 {
58  dbg_emit(dbg, "%s:", name);
59  dbg_indent(dbg);
60 
61  map_iter_t iter = map_iter(section);
62  while (map_has_next(&iter))
63  {
64  map_entry_t entry = map_next(&iter);
65  const tree_t *tree = entry.key;
66  emit_tree(dbg, tree);
67  }
68 
69  dbg_dedent(dbg);
70 }
71 
72 static void emit_module(dbg_emit_t *dbg, const tree_t *tree)
73 {
74  dbg_emit_tree(dbg, tree, tree_get_name(tree));
75  dbg_indent(dbg);
76 
77  emit_section(dbg, "types", tree_module_tag(tree, eSemaTypes));
78  emit_section(dbg, "values", tree_module_tag(tree, eSemaValues));
79  emit_section(dbg, "functions", tree_module_tag(tree, eSemaProcs));
80  emit_section(dbg, "modules", tree_module_tag(tree, eSemaModules));
81 
82  dbg_dedent(dbg);
83 }
84 
85 static void emit_global(dbg_emit_t *dbg, const tree_t *tree)
86 {
87  dbg_emit_tree(dbg, tree, tree_get_name(tree));
88  dbg_indent(dbg);
89  dbg_emit(dbg, "type:");
90  dbg_indent(dbg);
91  emit_tree(dbg, tree_get_type(tree));
92  dbg_dedent(dbg);
93  dbg_emit(dbg, "storage:");
94  dbg_indent(dbg);
95  emit_storage(dbg, tree_get_storage(tree));
96  dbg_dedent(dbg);
97 
98  dbg_emit(dbg, "value:");
99  dbg_indent(dbg);
100  emit_tree(dbg, tree->initial);
101  dbg_dedent(dbg);
102 
103  dbg_dedent(dbg);
104 }
105 
106 static void emit_tree(dbg_emit_t *dbg, const tree_t *tree)
107 {
108  if (tree == NULL)
109  {
110  dbg_emit(dbg, "NULL");
111  return;
112  }
113 
114  tree_kind_t kind = tree_get_kind(tree);
115  switch (tree_get_kind(tree))
116  {
117  case eTreeDeclModule:
118  emit_module(dbg, tree);
119  break;
120  case eTreeDeclGlobal:
121  emit_global(dbg, tree);
122  break;
123  default:
124  dbg_emit(dbg, "%s unimplemented (%p)", tree_kind_to_string(kind), tree);
125  break;
126  }
127 }
128 
129 void debug_tree(target_runtime_t *runtime, const tree_t *tree, target_emit_t *emit)
130 {
131  io_t *io = fs_open(emit->fs, "debug.tree", eOsAccessWrite | eOsAccessTruncate);
132  os_error_t err = eOsSuccess;
133  if ((err = io_error(io)) != eOsSuccess)
134  {
135  evt_os_error(runtime->logger, &kEvent_FailedToCreateOutputFile, err, "failed to create debug.tree");
136  return;
137  }
138 
139  dbg_emit_t dbg = {
140  .io = io,
141  .indent = 0,
142  };
143 
144  emit_tree(&dbg, tree);
145 
146  io_close(io);
147 }
CT_PUREFN CT_TREE_API tree_kind_t tree_get_kind(const tree_t *tree)
Definition: context.c:143
CT_PUREFN CT_TREE_API const char * tree_get_name(const tree_t *tree)
Definition: context.c:102
CT_PUREFN CT_TREE_API const tree_t * tree_get_type(const tree_t *tree)
Definition: context.c:132
CT_TREE_API tree_storage_t tree_get_storage(const tree_t *tree)
Definition: context.c:70
CT_TREE_API const char * tree_to_string(const tree_t *self)
Definition: query.c:40
CT_BEGIN_API CT_TREE_API const char * tree_kind_to_string(tree_kind_t kind)
Definition: query.c:23
CT_EVENTS_API event_builder_t evt_os_error(logger_t *logger, const diagnostic_t *diagnostic, os_error_t error, const char *msg)
signal that an os error has occurred
Definition: events.c:59
CT_NODISCARD CT_FS_API io_t * fs_open(fs_t *fs, const char *path, os_access_t flags)
open a file at a given location in the filesystem
Definition: fs.c:254
CT_NODISCARD CT_PUREFN CT_STD_API bool map_has_next(const map_iter_t *iter)
check if a map iterator has more elements
Definition: map.c:509
CT_NODISCARD CT_PUREFN CT_STD_API map_iter_t map_iter(const map_t *map)
create a new map iterator
Definition: map.c:456
CT_NODISCARD CT_NOALIAS CT_STD_API map_entry_t map_next(map_iter_t *iter)
get the next key-value pair from a map iterator
Definition: map.c:476
CT_IO_API size_t io_write(io_t *io, STA_READS(size) const void *src, size_t size)
write to an io object
CT_NODISCARD CT_IO_API os_error_t io_error(const io_t *io)
get the last error from the io object
Definition: io.c:144
CT_IO_API size_t io_vprintf(io_t *io, const char *fmt, va_list args)
vprintf to an io object
Definition: io.c:79
CT_IO_API os_error_t io_close(INOUT_NOTNULL io_t *io)
destroy an IO object
#define CTASSERTF(expr,...)
assert a condition with a message and optional format arguments
Definition: panic.h:116
CT_NODISCARD STA_FORMAT_STRING const char * fmt
Definition: str.h:68
CT_TREE_API const char * quals_string(tree_quals_t quals)
get the name of a set of qualifiers
Definition: ops.c:109
CT_TREE_API map_t * tree_module_tag(const tree_t *self, size_t tag)
Definition: sema.c:125
tree_kind_t
all tree node types
Definition: ops.h:17
@ eSemaValues
Definition: tree.h:36
@ eSemaProcs
Definition: tree.h:42
@ eSemaModules
Definition: tree.h:45
@ eSemaTypes
Definition: tree.h:39
@ eOsSuccess
Definition: posix.h:24
size_t indent
Definition: tree.c:15
io_t * io
Definition: tree.c:14
io object implementation
Definition: impl.h:122
a key-value pair in a map
Definition: map.h:175
const void * key
the key of this entry
Definition: map.h:176
a map iterator handle
Definition: map.h:183
an unordered hash map
Definition: map.h:38
fs_t * fs
Definition: broker.h:311
logger_t * logger
Definition: broker.h:304
storage for a value
Definition: context.h:23
tree_quals_t quals
the qualifiers for the storage
Definition: context.h:31
size_t length
the count of elements
Definition: context.h:28
const tree_t * storage
the underlying storage type
Definition: context.h:25
Definition: tree.h:67
tree_t * initial
Definition: tree.h:218
void debug_tree(target_runtime_t *runtime, const tree_t *tree, target_emit_t *emit)
Definition: tree.c:129