20 static void ensure_block_names_match(
scan_t *scan,
const node_t *node,
const char *type,
21 const char *name,
const char *end)
23 CTASSERTF(type != NULL && name != NULL,
"(type=%s, name=%s)", type, name);
34 "mismatching %s block BEGIN and END names", type);
35 msg_note(
id,
"BEGIN name `%s` does not match END name `%s`", name, end);
55 obr_t *
self = obr_new(scan, where, kind);
57 self->visibility = vis;
64 return obr_decl(scan, where, kind, symbol->
name, symbol->
visibility);
76 self->imports = imports;
80 ensure_block_names_match(scan, self->node,
"MODULE", name, end);
88 self->symbol = symbol;
124 ensure_block_names_match(scan, self->node,
"PROCEDURE", symbol->
name, end);
127 self->receiver = receiver;
129 self->result = result;
213 mpz_init_set(self->digit, digit);
221 self->length = length;
257 self->repeat = repeat;
282 self->branch_else = other;
299 self->symbol = symbol;
306 self->pointer = type;
314 self->array_element = type;
321 self->fields = fields;
359 self->visibility = visibility;
363 #define EXPAND_INNER(fn, scan, ...) \
366 scan_context_t *ctx = scan_get_context(scan); \
367 arena_t *arena = ctx->arena; \
368 size_t len = vector_len(symbols); \
369 vector_t *result = vector_of(len, arena); \
370 for (size_t i = 0; i < len; i++) \
372 obr_symbol_t *symbol = vector_get(symbols, i); \
373 obr_t *decl = fn(symbol, __VA_ARGS__); \
374 vector_set(result, i, decl); \
CT_NODISCARD CT_PUREFN CT_SCAN_API void * scan_get_context(const scan_t *scan)
get the context of a scanner
CT_BROKER_API logger_t * ctx_get_logger(const scan_t *scan)
CT_BROKER_API arena_t * ctx_get_ast_arena(const scan_t *scan)
CT_NODISCARD CT_PUREFN CT_BASE_API bool str_equal(const char *lhs, const char *rhs)
compare strings equality
CT_NODISCARD CT_SCAN_API node_t * node_new(const scan_t *scan, where_t where)
create a new node on the heap
#define ARENA_IDENTIFY(ptr, name, parent, arena)
rename and reparent a pointer in a custom allocator
#define ARENA_MALLOC(size, name, parent, arena)
allocate memory from a custom allocator
CT_NOTIFY_API event_builder_t msg_notify(INOUT_NOTNULL logger_t *logs, const diagnostic_t *diagnostic, const node_t *node, STA_FORMAT_STRING const char *fmt,...)
notify the logger of a new message
CT_NOTIFY_API void msg_note(event_builder_t builder, STA_FORMAT_STRING const char *fmt,...)
add a note to an existing message
#define CTASSERTF(expr,...)
assert a condition with a message and optional format arguments
binary_t
all binary operators
unary_t
all unary operators
compare_t
all comparison operators
obr_t * obr_param(obr_symbol_t *symbol, obr_t *type, bool mut)
obr_t * obr_expr_digit(scan_t *scan, where_t where, const mpz_t digit)
obr_t * obr_import(scan_t *scan, where_t where, char *name, char *symbol)
obr_t * obr_expr_cast(scan_t *scan, where_t where, obr_t *expr, obr_t *cast)
obr_t * obr_expr_name(scan_t *scan, where_t where, char *name)
obr_symbol_t * obr_symbol(scan_t *scan, where_t where, char *name, obr_visibility_t visibility)
obr_t * obr_stmt_block(scan_t *scan, where_t where, vector_t *stmts)
obr_t * obr_decl_type(scan_t *scan, where_t where, obr_symbol_t *symbol, obr_t *type)
obr_t * obr_expr_string(scan_t *scan, where_t where, char *text, size_t length)
vector_t * obr_expand_fields(scan_t *scan, vector_t *symbols, obr_t *type)
obr_t * obr_decl_const(scan_t *scan, where_t where, obr_symbol_t *symbol, obr_t *value)
obr_t * obr_type_qual(scan_t *scan, where_t where, char *name, char *symbol)
obr_t * obr_field(obr_symbol_t *symbol, obr_t *type)
obr_t * obr_stmt_loop(scan_t *scan, where_t where, vector_t *loop)
obr_t * obr_stmt_return(scan_t *scan, where_t where, obr_t *expr)
obr_t * obr_type_record(scan_t *scan, where_t where, vector_t *fields)
obr_t * obr_stmt_repeat(scan_t *scan, where_t where, vector_t *repeat, obr_t *until)
obr_t * obr_stmt_assign(scan_t *scan, where_t where, obr_t *dst, obr_t *src)
obr_t * obr_expr_call(scan_t *scan, where_t where, obr_t *expr, const vector_t *args)
obr_t * obr_expr_is(scan_t *scan, where_t where, obr_t *lhs, obr_t *rhs)
obr_t * obr_type_array(scan_t *scan, where_t where, const vector_t *sizes, obr_t *type)
obr_t * obr_type_name(scan_t *scan, where_t where, char *name)
obr_t * obr_expr_compare(scan_t *scan, where_t where, compare_t op, obr_t *lhs, obr_t *rhs)
obr_t * obr_expr_unary(scan_t *scan, where_t where, unary_t op, obr_t *expr)
obr_t * obr_expr_in(scan_t *scan, where_t where, obr_t *lhs, obr_t *rhs)
obr_t * obr_expr_field(scan_t *scan, where_t where, obr_t *expr, char *field)
vector_t * obr_expand_vars(scan_t *scan, vector_t *symbols, obr_t *type)
#define EXPAND_INNER(fn, scan,...)
obr_t * obr_decl_procedure(scan_t *scan, where_t where, obr_symbol_t *symbol, obr_t *receiver, const vector_t *params, obr_t *result, vector_t *locals, vector_t *body, char *end)
obr_t * obr_stmt_while(scan_t *scan, where_t where, obr_t *cond, vector_t *then)
obr_t * obr_decl_var(obr_symbol_t *symbol, obr_t *type)
obr_t * obr_expr_binary(scan_t *scan, where_t where, binary_t op, obr_t *lhs, obr_t *rhs)
obr_t * obr_stmt_break(scan_t *scan, where_t where)
obr_t * obr_type_pointer(scan_t *scan, where_t where, obr_t *type)
vector_t * obr_expand_params(scan_t *scan, vector_t *symbols, obr_t *type, bool mut)
obr_t * obr_stmt_branch(scan_t *scan, where_t where, obr_t *cond, vector_t *then, obr_t *other)
obr_t * obr_receiver(scan_t *scan, where_t where, bool mut, char *name, char *type)
obr_t * obr_module(scan_t *scan, where_t where, char *name, char *end, const vector_t *imports, vector_t *decls, vector_t *init)
an event builder handles adding additional information to an event
a position in a source file
obr_visibility_t visibility
a generic vector of pointers
a location inside a scanner locations are inclusive and 0-based