From ad18c24e7223b1c0d48a20ba9b618c4eaf1e3a84 Mon Sep 17 00:00:00 2001 From: Kimplul Date: Sat, 1 Apr 2023 10:53:44 +0300 Subject: fix gitignore --- .gitignore | 1 + include/cu/actualize.h | 33 +++ include/cu/ast.h | 579 +++++++++++++++++++++++++++++++++++++++++++++++++ include/cu/compiler.h | 11 + include/cu/debug.h | 56 +++++ include/cu/imports.h | 12 + include/cu/parser.h | 44 ++++ include/cu/path.h | 10 + include/cu/res.h | 57 +++++ include/cu/scope.h | 169 +++++++++++++++ include/cu/string.h | 28 +++ 11 files changed, 1000 insertions(+) create mode 100644 include/cu/actualize.h create mode 100644 include/cu/ast.h create mode 100644 include/cu/compiler.h create mode 100644 include/cu/debug.h create mode 100644 include/cu/imports.h create mode 100644 include/cu/parser.h create mode 100644 include/cu/path.h create mode 100644 include/cu/res.h create mode 100644 include/cu/scope.h create mode 100644 include/cu/string.h diff --git a/.gitignore b/.gitignore index 69334a2..daafc0e 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ deps.mk docs/output build cu +!include/cu diff --git a/include/cu/actualize.h b/include/cu/actualize.h new file mode 100644 index 0000000..ea736ac --- /dev/null +++ b/include/cu/actualize.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ + +#ifndef ANALYZE_H +#define ANALYZE_H + +#include + +#include "ast.h" +#include "scope.h" + +int types_match(struct ast_node *a, struct ast_node *b); + +/* these three might be better off in some ast_utils.c or something */ +void replace_type(struct ast_node *type, + struct ast_node *from, struct ast_node *to); + +void replace_param_types(struct ast_node *param, + struct ast_node *param_type, + struct ast_node *arg_type); + +void init_template_type(struct ast_node *type, struct ast_node *param_type, + struct ast_node *arg_type); +void init_template_types(struct ast_node *param, struct ast_node *param_type, + struct ast_node *arg_type); + +struct ast_node *extract_template(struct ast_node *type); +struct ast_node *extract_typeof(struct ast_node *type); + +int analyze_root(struct scope *scope, struct ast_node *tree); +int actualize_main(struct scope *scope); +int actualize_temp_type(struct scope *scope, struct ast_node *type); + +#endif /* ANALYZE_H */ diff --git a/include/cu/ast.h b/include/cu/ast.h new file mode 100644 index 0000000..f9e8492 --- /dev/null +++ b/include/cu/ast.h @@ -0,0 +1,579 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ + +#ifndef AST_H +#define AST_H + +enum ast_binops { + AST_ADD, + AST_SUB, + AST_MUL, + AST_DIV, + AST_REM, + AST_XOR, + AST_POW, + AST_AND, + AST_LAND, + AST_OR, + AST_LOR, + AST_LSHIFT, + AST_RSHIFT, + AST_ASSIGN_ADD, + AST_ASSIGN_SUB, + AST_ASSIGN_MUL, + AST_ASSIGN_DIV, + AST_ASSIGN_REM, + AST_ASSIGN_AND, + AST_ASSIGN_OR, + AST_ASSIGN_XOR, + AST_ASSIGN_LSHIFT, + AST_ASSIGN_RSHIFT, + AST_LT, + AST_GT, + AST_LE, + AST_GE, + AST_NE, + AST_EQ, +}; + +enum ast_unops { + AST_NEG, + AST_LNOT, + AST_REF, + AST_DEREF, + AST_NOT +}; + +/* should this also have file name? Probably? */ +struct src_loc { + int first_line; + int last_line; + int first_col; + int last_col; +}; + +enum ast_node_type { + AST_BINOP = 1, + AST_UNOP, + AST_FETCH, + AST_INIT, + AST_ASSIGN, + AST_CALL, + AST_SIZEOF, + AST_CAST, + AST_DEFER, + AST_MACRO, + AST_LAST, + AST_PROC, + AST_GOTO, + AST_LABEL, + AST_VAR, + AST_LAMBDA, + AST_FOR, + AST_EMBED, + AST_DOT, + AST_WHILE, + AST_CTRL, + AST_RETURN, + AST_ALIAS, + AST_TEMPLATE, + AST_STRUCT, + AST_IF, + AST_TYPE, + AST_BLOCK, + AST_IMPORT, + AST_ENUM, + AST_UNION, + AST_VAL, + AST_SWITCH, + AST_CASE, + AST_CONST, + AST_ID, + AST_AS, + AST_EMPTY, +}; + +enum ast_ctrl_kind { + AST_CTRL_BREAK, + AST_CTRL_CONTINUE +}; + +enum ast_const_kind { + AST_CONST_INTEGER, + AST_CONST_STRING, + AST_CONST_FLOAT, +}; + +enum ast_type_kind { + AST_TYPE_ID, + AST_TYPE_ARR, + AST_TYPE_TYPEOF, + AST_TYPE_TEMPLATE, + AST_TYPE_ALIAS, + AST_TYPE_MEMBER, + AST_TYPE_POINTER, + AST_TYPE_UNION, + AST_TYPE_LAMBDA, + AST_TYPE_PROC, + AST_TYPE_STRUCT, + AST_TYPE_ENUM, + AST_TYPE_SIGN, +}; + +enum ast_typedef_kind { + AST_TYPEDEF_ALIAS, + AST_TYPEDEF_TEMPLATE, +}; + +enum ast_flag { + AST_FLAG_MUTABLE = (1 << 0), + AST_FLAG_CONST = (1 << 1), + AST_FLAG_EXTERN = (1 << 2), + AST_FLAG_VARIADIC = (1 << 3), + AST_FLAG_DELAYED = (1 << 4), + AST_FLAG_PUBLIC = (1 << 5), + /* Is untyped necessary? It's fairly easy to just look at the type of an + * expression... */ + AST_FLAG_UNTYPED = (1 << 6), + AST_FLAG_FALLTHROUGH = (1 << 7), + AST_FLAG_UNHYGIENIC = (1 << 8), + AST_FLAG_ACTUAL = (1 << 9), + AST_FLAG_INIT = (1 << 10), + AST_FLAG_MEMBER = (1 << 11), + AST_FLAG_SHARED = (1 << 12), +}; + +struct ast_node; + +struct ast_if { + struct ast_node *cond; + struct ast_node *body; + struct ast_node *els; +}; + +struct ast_fetch { + struct ast_node *id; + struct ast_node *type; +}; + +struct ast_label { + struct ast_node *id; + struct ast_node *defers; +}; + +struct ast_goto { + struct ast_node *label; + struct ast_node *defers; +}; + +struct ast_alias { + struct ast_node *id; + struct ast_node *type; +}; + +struct template_implemented { + struct ast_node *type; + struct template_implemented *next; +}; + +/* should templates take decls or should it just be for structures? */ +struct ast_template { + struct ast_node *id; + struct ast_node *body; + + struct template_implemented *impl_by; +}; + +struct ast_cast { + struct ast_node *expr; + struct ast_node *type; +}; + +struct ast_binop { + enum ast_binops op; + struct ast_node *left; + struct ast_node *right; +}; + +struct ast_unop { + enum ast_unops op; + struct ast_node *expr; +}; + +struct ast_call { + struct ast_node *id; + struct ast_node *args; +}; + +struct ast_defer { + struct ast_node *expr; +}; + +struct ast_macro { + struct ast_node *id; + struct ast_node *params; + struct ast_node *body; +}; + +struct ast_proc { + struct ast_node *id; + struct ast_node *sign; + struct ast_node *body; +}; + +struct ast_dot { + struct ast_node *expr; + struct ast_node *id; +}; + +struct ast_as { + struct ast_node *type; +}; + +struct ast_sizeof { + struct ast_node *expr; +}; + +struct ast_var { + struct ast_node *id; + struct ast_node *type; + struct ast_node *init; +}; + +struct ast_lambda { + struct ast_node *captures; + struct ast_node *sign; + struct ast_node *body; +}; + +struct ast_for { + struct ast_node *pre; + struct ast_node *cond; + struct ast_node *post; + struct ast_node *body; +}; + +struct ast_while { + struct ast_node *cond; + struct ast_node *body; +}; + +struct ast_ctrl { + enum ast_ctrl_kind kind; + struct ast_node *defers; +}; + +struct ast_return { + struct ast_node *expr; + struct ast_node *defers; +}; + +struct ast_type { + enum ast_type_kind kind; + struct ast_node *next; + union { + struct ast_node *id; + + struct { + struct ast_node *size; + } arr; + + struct { + struct ast_node *expr; + struct ast_node *actual; + } typeo; + + struct { + struct ast_node *id; + struct ast_node *params; + struct ast_node *ret; + } proc; + + struct { + struct ast_node *alias; + struct ast_node *actual; + } alias; + + struct { + struct ast_node *id; + struct ast_node *expr; + } member; + + struct { + struct ast_node *template; + struct ast_node *actual; + } template; + + struct { + struct ast_node *params; + struct ast_node *ret; + } lambda; + + struct { + struct ast_node *id; + struct ast_node *impls; + } struc; + + struct { + struct ast_node *id; + struct ast_node *type; + } enu; + + struct { + struct ast_node *id; + struct ast_node *impls; + } unio; + + /* a signature can be either a procedure or a lambda, to be + * determined later. */ + struct { + struct ast_node *params; + struct ast_node *ret; + } sign; + + struct { + struct ast_node *id; + struct ast_node *types; + } impl; + }; +}; + +struct ast_block { + struct ast_node *body; + struct ast_node *defers; +}; + +struct ast_import { + const char *file; +}; + +struct ast_embed { + const char *file; +}; + +struct ast_paste { + struct ast_node *id1; + struct ast_node *id2; +}; + +struct ast_enum { + struct ast_node *id; + struct ast_node *type; + struct ast_node *body; +}; + +struct ast_struct { + struct ast_node *id; + struct ast_node *generics; + struct ast_node *body; +}; + +struct ast_union { + struct ast_node *id; + struct ast_node *generics; + struct ast_node *body; +}; + +struct ast_val { + struct ast_node *id; + struct ast_node *val; +}; + +struct ast_switch { + struct ast_node *cond; + struct ast_node *cases; +}; + +struct ast_case { + struct ast_node *cond; + struct ast_node *body; +}; + +struct ast_const { + enum ast_const_kind kind; + union { + long long integer; + const char *str; + double dbl; + }; +}; + +struct ast_init { + struct ast_node *body; +}; + +struct ast_assign { + struct ast_node *to; + struct ast_node *from; +}; + +struct ast_id { + const char *id; +}; + +struct ast_empty { +}; + +struct ast_node { + enum ast_node_type node_type; + enum ast_flag flags; + struct ast_node *next; + + struct src_loc loc; + + /* scope ast node belongs to */ + struct scope *scope; + /* type of ast node */ + struct ast_node *type; + + union { + struct ast_binop _binop; + struct ast_unop _unop; + struct ast_call _call; + struct ast_cast _cast; + struct ast_macro _macro; + struct ast_proc _proc; + struct ast_goto _goto; + struct ast_label _label; + struct ast_var _var; + struct ast_lambda _lambda; + struct ast_if _if; + struct ast_for _for; + struct ast_while _while; + struct ast_ctrl _ctrl; + struct ast_defer _defer; + struct ast_type _type; + struct ast_dot _dot; + struct ast_block _block; + struct ast_import _import; + struct ast_embed _embed; + struct ast_return _return; + struct ast_switch _switch; + struct ast_paste _paste; + struct ast_alias _alias; + struct ast_template _template; + struct ast_enum _enum; + struct ast_struct _struct; + struct ast_union _union; + struct ast_val _val; + struct ast_case _case; + struct ast_const _const; + struct ast_init _init; + struct ast_assign _assign; + struct ast_id _id; + struct ast_as _as; + struct ast_sizeof _sizeof; + struct ast_fetch _fetch; + struct ast_empty _empty; + }; +}; + +struct ast_node *gen_binop(enum ast_binops op, + struct ast_node *left, struct ast_node *right); + +struct ast_node *gen_unop(enum ast_unops op, struct ast_node *expr); + +struct ast_node *gen_call(struct ast_node *id, struct ast_node *args); + +struct ast_node *gen_id(const char *id); + +struct ast_node *gen_int(long long integer); +struct ast_node *gen_string(const char *str); +struct ast_node *gen_float(double dbl); + +struct ast_node *gen_assign(struct ast_node *to, struct ast_node *from); +struct ast_node *gen_init(struct ast_node *body); + +struct ast_node *gen_while(struct ast_node *cond, struct ast_node *body); + +struct ast_node *gen_for(struct ast_node *pre, struct ast_node *cond, + struct ast_node *post, struct ast_node *body); + +struct ast_node *gen_return(struct ast_node *expr); + +struct ast_node *gen_ctrl(enum ast_ctrl_kind kind, struct src_loc loc); + +struct ast_node *gen_macro(struct ast_node *id, struct ast_node *params, + struct ast_node *body); + +struct ast_node *gen_if(struct ast_node *cond, struct ast_node *body, + struct ast_node *els); + +struct ast_node *gen_switch(struct ast_node *cond, struct ast_node *cases); + +struct ast_node *gen_case(struct ast_node *expr, struct ast_node *body); + +struct ast_node *gen_type(enum ast_type_kind kind, struct ast_node *id, + struct ast_node *decl, struct ast_node *rets); + +struct ast_node *gen_block(struct ast_node *body); + +struct ast_node *gen_var(struct ast_node *id, struct ast_node *type, + struct ast_node *init); + +struct ast_node *gen_lambda(struct ast_node *captures, + struct ast_node *type, struct ast_node * body); + +struct ast_node *gen_proc(struct ast_node *id, struct ast_node *type, + struct ast_node *body); + +struct ast_node *gen_dot(struct ast_node *expr, struct ast_node *id); + +struct ast_node *gen_enum(struct ast_node *id, struct ast_node *type, + struct ast_node *body); + +struct ast_node *gen_val(struct ast_node *id, struct ast_node *val); + +struct ast_node *gen_alias(struct ast_node *id, struct ast_node *type); + +struct ast_node *gen_template(struct ast_node *id, struct ast_node *body); + +struct ast_node *gen_import(const char *file); + +struct ast_node *gen_cast(struct ast_node *expr, struct ast_node *type); + +struct ast_node *gen_embed(const char *file); + +struct ast_node *gen_goto(struct ast_node *label); + +struct ast_node *gen_label(struct ast_node *id); + +struct ast_node *gen_defer(struct ast_node *expr); + +struct ast_node *gen_as(struct ast_node *type); + +struct ast_node *gen_sizeof(struct ast_node *expr); + +struct ast_node *gen_struct(struct ast_node *id, struct ast_node *generics, + struct ast_node *body); + +struct ast_node *gen_union(struct ast_node *id, struct ast_node *generics, + struct ast_node *body); + +struct ast_node *gen_fetch(struct ast_node *id, struct ast_node *type); + +/* might have to come up with a better name for this */ +struct ast_node *gen_last(); + +struct ast_node *gen_empty(); + +struct ast_node *clone_ast_node(struct ast_node *node); +int identical_ast_nodes(int exact, struct ast_node *left, + struct ast_node *right); + +void destroy_ast_node(struct ast_node *node); +void destroy_ast_tree(struct ast_node *root); + +void dump_ast(int depth, struct ast_node *root); +void ast_append(struct ast_node *list, struct ast_node *elem); +void ast_set_flags(struct ast_node *node, enum ast_flag flags); +void ast_clear_flags(struct ast_node *node, enum ast_flag flags); +int ast_flags(struct ast_node *node, enum ast_flag flags); + +int ast_call_on(int (*call)(struct ast_node *node, void *data), + struct ast_node *node, void *data); + +size_t ast_list_len(struct ast_node *list); +struct ast_node *ast_last_node(struct ast_node *node); +struct ast_node *ast_block_last(struct ast_node *node); + +#endif /* AST_H */ diff --git a/include/cu/compiler.h b/include/cu/compiler.h new file mode 100644 index 0000000..325c746 --- /dev/null +++ b/include/cu/compiler.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ + +#ifndef CT_COMPILER_H +#define CT_COMPILER_H + +#include + +int compile(const char *file); +int process_file(struct scope **parent, int public, const char *file); + +#endif /* CT_COMPILER_H */ diff --git a/include/cu/debug.h b/include/cu/debug.h new file mode 100644 index 0000000..3099b3c --- /dev/null +++ b/include/cu/debug.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ + +#ifndef CT_DEBUG_H +#define CT_DEBUG_H + +#include + +#include + +#if DEBUG +#define debug(x, ...) \ + do {fprintf(stderr, "debug: " x "\n",##__VA_ARGS__);} while(0) +#else +#define debug(x, ...) +#endif + +#define error(x, ...) \ + do {fprintf(stderr, "error: " x "\n",##__VA_ARGS__);} while(0) + +#define warn(x, ...) \ + do {fprintf(stderr, "warn: " x "\n",##__VA_ARGS__);} while(0) + +#define info(x, ...) \ + do {fprintf(stderr, "info: " x "\n",##__VA_ARGS__);} while(0) + + +struct file_ctx { + const char *fname; + const char *fbuf; +}; + +char *type_str(struct ast_node *type); +char *call_str(struct ast_node *call); +void semantic_info(struct file_ctx ctx, struct ast_node *node, const char *fmt, + ...); +void semantic_warn(struct file_ctx ctx, struct ast_node *node, const char *fmt, + ...); +void semantic_error(struct file_ctx ctx, struct ast_node *node, const char *fmt, + ...); +void internal_error(const char *fmt, ...); + +enum issue_level { + SRC_INFO, + SRC_WARN, + SRC_ERROR +}; + +struct src_issue { + enum issue_level level; + struct src_loc loc; + struct file_ctx fctx; + size_t offset; +}; + +void src_issue(struct src_issue issue, const char *err_msg, ...); +#endif /* CT_DEBUG_H */ diff --git a/include/cu/imports.h b/include/cu/imports.h new file mode 100644 index 0000000..1043cef --- /dev/null +++ b/include/cu/imports.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ + +#ifndef CT_IMPORTS_H +#define CT_IMPORTS_H + +#include + +void add_import_path(const char *dir); +const char *find_import(const char *file); +bool already_imported(const char *file); + +#endif /* CT_IMPORTS_H */ diff --git a/include/cu/parser.h b/include/cu/parser.h new file mode 100644 index 0000000..dfc2b6a --- /dev/null +++ b/include/cu/parser.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ + +#ifndef PARSER_H +#define PARSER_H + +#include +#include +#include + +struct parser { + bool failed; + void *lexer; + size_t buf_offset; + const char *buf; + const char *fname; + size_t comment_nesting; + struct ast_node *tree; +}; + +#define YY_DECL int yylex(YYSTYPE *yylval, YYLTYPE *yylloc, \ + yyscan_t yyscanner, struct parser *parser) + +#include <../gen/gen_parser.h> +#ifndef FROM_LEXER +#include <../gen/gen_lexer.h> +#endif + +YY_DECL; + +struct parser *create_parser(); +void destroy_parser(struct parser *p); +void parse(struct parser *p, const char *fname, const char *buf); +int next_interesting_feature(YYSTYPE *yylval, YYLTYPE *yylloc, + void *scanner, struct parser *parser); + +struct src_loc to_src_loc(YYLTYPE *yylloc); + +void yyerror(YYLTYPE *yylloc, void *lexer, struct parser *parser, + const char *msg); + +long long match_escape(char c); +const char *clone_string(const char *s); + +#endif /* PARSER_H */ diff --git a/include/cu/path.h b/include/cu/path.h new file mode 100644 index 0000000..700f77f --- /dev/null +++ b/include/cu/path.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ + +#ifndef CT_PATH +#define CT_PATH + +char *cu_basename(const char *file); +char *cu_dirname(const char *file); +char *cu_cwdname(); + +#endif /* CT_PATH */ diff --git a/include/cu/res.h b/include/cu/res.h new file mode 100644 index 0000000..e1a1fc3 --- /dev/null +++ b/include/cu/res.h @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ + +/** + * @file res.h + * Simple resource manager header. + */ + +#ifndef CT_RES_H +#define CT_RES_H + +#include + +/** + * Very simple resource manager. + * Keeps track of all allocations and frees them all at once. + */ +struct res { + /** Number of allocations. */ + size_t n; + /** Maximum number of allocations. */ + size_t max; + /** Pointer to array of pointers to allocations. */ + void **p; +}; + +/** + * Create new resource manager. + * + * @return Pointer to resource manager. + */ +struct res *res_create(); + +/** + * Resource manager wrapper around malloc(). + * + * @param r Resource manager. + * @param size Size of allocation. + * @return Pointer to newly allocated area. + */ +void *res_alloc(struct res *r, size_t size); + +/** + * Add already alloced pointer to manager. + * + * @param r Resource manager. + * @param p Pointer to manage. + */ +void res_add(struct res *r, void *p); + +/** + * Destroy resource manager and free all associated allocations. + * + * @param r Resource manager to destroy. + */ +void res_destroy(struct res *r); + +#endif /* CT_RES_H */ diff --git a/include/cu/scope.h b/include/cu/scope.h new file mode 100644 index 0000000..5a75427 --- /dev/null +++ b/include/cu/scope.h @@ -0,0 +1,169 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ + +#ifndef SCOPE_H +#define SCOPE_H + +#include "ast.h" +#include "debug.h" + +enum scope_flags { + SCOPE_PUBLIC = (1 << 0), + SCOPE_FILE = (1 << 1), +}; + +/* basic linked list for now, can probably be optimized into some kind of hash + * table later */ +struct visible { + struct ast_node *node; + struct scope *owner; + struct visible *next; +}; + +struct scratch { + struct ast_node *node; + struct scratch *next; +}; + +struct actual { + struct ast_node *node; + struct actual *next; +}; + +struct callable { + struct proc_node *root; + struct ast_node *id; + struct callable *next; +}; + +struct param_node { + struct ast_node *type; + struct proc_node *proc; + struct param_node *next; +}; + +struct proc_node { + struct param_node *primitives; + + struct param_node *referential; + struct param_node *fallback; + + struct ast_node *proc; +}; + + +struct scope { + struct scope *parent; + enum scope_flags flags; + size_t number; + + struct file_ctx fctx; + + /* used by the parent to keep track of all its children */ + struct scope *next; + struct scope *children; + + /* list of actualized functions, shared between all scopes in the + * compilation unit */ + struct actual *actuals; + + /* for temp stuff */ + struct scratch *scratch; + + /* types */ + /* TODO: add actualized types maybe? */ + struct visible *enums; + struct visible *structs; + struct visible *aliases; + struct visible *builtins; + struct visible *templates; + + /* basic variables */ + struct visible *vars; + struct visible *macros; + + /* collect procedures */ + struct visible *procs; + + /* callables */ + struct callable *callable; +}; + +enum match_flags { + MATCH_GLOBAL = (1 << 0), + MATCH_CALL = (1 << 1), +}; + +struct scope *create_scope(); +struct actual *create_actuals(); +void destroy_actuals(struct actual *actuals); +void destroy_visible(struct scope *scope, struct visible *visible); +void destroy_scope(struct scope *scope); + +struct scope *create_temp_scope(struct scope *parent); + +int scope_add_defaults(struct scope *root); +/* not sure if this should be public */ +void scope_destroy_defaults(struct scope *root); + +int scope_add_scratch(struct scope *scope, struct ast_node *scratch); + +void scope_set_flags(struct scope *scope, enum scope_flags flags); +int scope_flags(struct scope *scope, enum scope_flags flags); + +void scope_add_scope(struct scope *parent, struct scope *child); + +int scope_add_actual(struct scope *scope, struct ast_node *node); +/* sets a node's owner as scope, and as needed propagates references to public + * things up the file scope chain. */ +int scope_add_var(struct scope *scope, struct ast_node *var); +int scope_add_type(struct scope *scope, struct ast_node *type); +int scope_add_proc(struct scope *scope, struct ast_node *proc); +int scope_add_macro(struct scope *scope, struct ast_node *macro); +int scope_add_alias(struct scope *scope, struct ast_node *alias); +int scope_add_template(struct scope *scope, struct ast_node *type_template); + +int scope_add_existing_var(struct scope *scope, struct visible *var); +int scope_add_existing_proc(struct scope *scope, struct visible *proc); + +/* actuals are global, so technically no need for a file_* */ +struct ast_node *scope_find_actual(struct scope *scope, struct ast_node *id); + +struct ast_node *scope_find(struct scope *scope, struct ast_node *id); +struct ast_node *scope_find_var(struct scope *scope, struct ast_node *id); +struct ast_node *scope_find_type(struct scope *scope, struct ast_node *id); +struct ast_node *scope_find_proc(struct scope *scope, struct ast_node *id); +struct ast_node *scope_find_macro(struct scope *scope, struct ast_node *id); +struct ast_node *scope_find_alias(struct scope *scope, struct ast_node *id); +struct ast_node *scope_find_template(struct scope *scope, struct ast_node *id); + +struct ast_node *file_scope_find(struct scope *scope, struct ast_node *id); +struct ast_node *file_scope_find_var(struct scope *scope, struct ast_node *id); +struct ast_node *file_scope_find_type(struct scope *scope, struct ast_node *id); +struct ast_node *file_scope_find_proc(struct scope *scope, struct ast_node *id); +struct ast_node *file_scope_find_macro(struct scope *scope, + struct ast_node *id); +struct ast_node *file_scope_find_alias(struct scope *scope, + struct ast_node *id); +struct ast_node *file_scope_find_override(struct scope *scope, + struct ast_node *id); +struct ast_node *file_scope_find_template(struct scope *scope, + struct ast_node *id); + +struct ast_node *scope_resolve_arr(struct scope *scope, struct ast_node *call); +struct ast_node *scope_resolve_macro(struct scope *scope, + struct ast_node *call); +struct ast_node *scope_resolve_actual(struct scope *scope, + struct ast_node *call); +struct ast_node *scope_resolve_proc(struct scope *scope, struct ast_node *call); +struct ast_node *scope_resolve_call(struct scope *scope, struct ast_node *call); + +struct ast_node *scope_resolve_type(struct scope *scope, struct ast_node *type); +struct ast_node *file_scope_resolve_type(struct scope *scope, + struct ast_node *type); + +struct ast_node *file_scope_resolve_call(struct scope *scope, + struct ast_node *call); +int implements(enum match_flags flags, struct scope *scope, + struct ast_node *arg_type, + struct ast_node *param_type); +#endif /* SCOPE_H */ diff --git a/include/cu/string.h b/include/cu/string.h new file mode 100644 index 0000000..75d7c62 --- /dev/null +++ b/include/cu/string.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ + +#ifndef CT_STRING_H +#define CT_STRING_H + +#include +#include +#include + +struct string { + size_t len; + char *buf; +}; + +struct string *new_string(const char *s); +void destroy_string(struct string *s); + +int str_append(struct string *s, char c); +int str_concat(struct string *s, const char *c); +int str_add(struct string *s, struct string *c); + +char str_index(struct string *s, size_t i); +char str_rindex(struct string *s, size_t i); + +bool str_compare(struct string *s, const char *c); +void str_clear(struct string *s); + +#endif /* CT_STRING_H */ -- cgit v1.3