aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2025-01-09 22:26:02 +0200
committerKimplul <kimi.h.kuparinen@gmail.com>2025-01-09 22:26:02 +0200
commit598be4cd1bdd79e4859ae30291f4d65682cc672a (patch)
tree6e7e7ad537214c78049c4b3b2ee694c3b549fa4e /include
parent6f7c2d6daa5c706d441ddc42c5c6409e5266049a (diff)
downloadfwd-598be4cd1bdd79e4859ae30291f4d65682cc672a.tar.gz
fwd-598be4cd1bdd79e4859ae30291f4d65682cc672a.zip
initial reference checking
Diffstat (limited to 'include')
-rw-r--r--include/fwd/ast.h68
-rw-r--r--include/fwd/debug.h1
2 files changed, 51 insertions, 18 deletions
diff --git a/include/fwd/ast.h b/include/fwd/ast.h
index f8ad67a..8eb39b7 100644
--- a/include/fwd/ast.h
+++ b/include/fwd/ast.h
@@ -31,8 +31,8 @@ struct src_loc {
struct ast;
enum type_kind {
- TYPE_ID = 1, TYPE_CONSTRUCT, TYPE_REF, TYPE_PTR, TYPE_CALLABLE,
- TYPE_VOID
+ TYPE_ID = 1, TYPE_CONSTRUCT, TYPE_REF, TYPE_PTR, TYPE_CLOSURE,
+ TYPE_PURE_CLOSURE, TYPE_FUNC_PTR, TYPE_VOID
};
struct type {
@@ -113,6 +113,12 @@ enum ast_kind {
AST_LNOT,
/** Bitwise negation, \c ~ */
AST_NOT,
+ /** Reference (note, not addrof!) */
+ AST_REF,
+ /** Dereferencing.
+ * @todo should references and pointers both use this?
+ */
+ AST_DEREF,
AST_CONST_INT,
AST_CONST_FLOAT,
AST_CONST_CHAR,
@@ -125,6 +131,7 @@ const char *ast_str(enum ast_kind k);
enum ast_flag {
AST_FLAG_ANALYZED = (1 << 0),
AST_FLAG_PREANALYZIS = (1 << 1),
+ AST_FLAG_NOMOVES = (1 << 2),
};
struct ast {
@@ -241,6 +248,20 @@ static inline bool is_const(struct ast *x)
return false;
}
+static inline bool is_lvalue(struct ast *node)
+{
+ switch (node->k) {
+ case AST_ID:
+ /** @todo others */
+ return true;
+
+ default:
+ return false;
+ }
+
+ return false;
+}
+
#define gen_str_type1(k, s, t, a, loc) gen_ast(k, a, NULL, NULL, NULL, \
t, s, -1, 0., loc)
#define gen_str_type(k, s, t, loc) gen_str_type1(k, s, t, NULL, loc)
@@ -290,9 +311,17 @@ static inline bool is_const(struct ast *x)
#define tgen_ref(base, loc) \
tgen_type(TYPE_REF, base, NULL, loc)
-#define tcallable_args(x) return_t0(x, TYPE_CALLABLE)
-#define tgen_callable(args, loc) \
- tgen_type(TYPE_CALLABLE, args, NULL, loc)
+#define tclosure_args(x) return_t0(x, TYPE_CLOSURE)
+#define tgen_closure(args, loc) \
+ tgen_type(TYPE_CLOSURE, args, NULL, loc)
+
+#define tpure_closure_args(x) return_t0(x, TYPE_CLOSURE)
+#define tgen_pure_closure(args, loc) \
+ tgen_type(TYPE_PURE_CLOSURE, args, NULL, loc)
+
+#define tfunc_ptr_args(x) return_t0(x, TYPE_FUNC_PTR)
+#define tgen_func_ptr(args, loc) \
+ tgen_type(TYPE_FUNC_PTR, args, NULL, loc)
#define closure_bindings(x) return_a0(x, AST_CLOSURE)
#define closure_body(x) return_a1(x, AST_CLOSURE)
@@ -380,6 +409,14 @@ static inline bool is_const(struct ast *x)
#define gen_id(id, loc) \
gen_str(AST_ID, id, loc)
+#define ref_base(x) return_a0(x, AST_REF)
+#define gen_ref(expr, loc) \
+ gen1(AST_REF, expr, loc)
+
+#define deref_base(x) return_a0(x, AST_DEREF)
+#define gen_deref(expr, loc) \
+ gen1(AST_DEREF, expr, loc)
+
#define gen_empty(loc) \
gen1(AST_EMPTY, NULL, loc)
@@ -452,25 +489,20 @@ void fix_closures(struct ast *root);
static inline bool is_callable(struct type *t)
{
- if (t->k == TYPE_PTR)
- return (tptr_base(t))->k == TYPE_CALLABLE;
-
- if (t->k == TYPE_REF)
- return (tref_base(t))->k == TYPE_CALLABLE;
+ switch (t->k) {
+ case TYPE_CLOSURE: return true;
+ case TYPE_PURE_CLOSURE: return true;
+ case TYPE_FUNC_PTR: return true;
+ default: return false;
+ }
- return t->k == TYPE_CALLABLE;
+ return false;
}
static inline struct type *callable_types(struct type *t)
{
assert(is_callable(t));
- if (t->k == TYPE_REF)
- return callable_types(tptr_base(t));
-
- if (t->k == TYPE_PTR)
- return callable_types(tref_base(t));
-
- return tcallable_args(t);
+ return t->t0;
}
void opt_group(struct ast *a, struct ast *b);
diff --git a/include/fwd/debug.h b/include/fwd/debug.h
index 5123635..c3dce63 100644
--- a/include/fwd/debug.h
+++ b/include/fwd/debug.h
@@ -139,6 +139,7 @@ void type_mismatch(struct scope *scope, struct ast *node,
struct type *l, struct type *r);
void move_error(struct ast *new_use, struct ast *prev_use);
+void reference_error(struct ast *new_use, struct ast *prev_use);
const char *type_str(struct type *t);