diff options
Diffstat (limited to 'include')
| -rw-r--r-- | include/fwd/ast.h | 189 | ||||
| -rw-r--r-- | include/fwd/debug.h | 5 | ||||
| -rw-r--r-- | include/fwd/mod.h | 4 | ||||
| -rw-r--r-- | include/fwd/rewrite.h | 9 | ||||
| -rw-r--r-- | include/fwd/scope.h | 7 |
5 files changed, 175 insertions, 39 deletions
diff --git a/include/fwd/ast.h b/include/fwd/ast.h index 69f7bf1..0fd1118 100644 --- a/include/fwd/ast.h +++ b/include/fwd/ast.h @@ -32,12 +32,47 @@ struct src_loc { struct ast; enum type_kind { - TYPE_ID = 1, TYPE_CONSTRUCT, TYPE_REF, TYPE_PTR, TYPE_CLOSURE, - TYPE_PURE_CLOSURE, TYPE_FUNC_PTR, TYPE_VOID, + TYPE_ID = 1, TYPE_REF, TYPE_PTR, TYPE_CLOSURE, + TYPE_PURE_CLOSURE, TYPE_FUNC_PTR, TYPE_VOID, TYPE_NIL, TYPE_I8, TYPE_I16, TYPE_I32, TYPE_I64, - TYPE_U8, TYPE_U16, TYPE_U32, TYPE_U64 + TYPE_U8, TYPE_U16, TYPE_U32, TYPE_U64, + TYPE_BOOL }; +static inline bool is_int_type(enum type_kind k) +{ + switch (k) { + case TYPE_I8: + case TYPE_I16: + case TYPE_I32: + case TYPE_I64: + case TYPE_U8: + case TYPE_U16: + case TYPE_U32: + case TYPE_U64: + return true; + + default: + return false; + } + + return false; +} + +static inline bool is_ptr_type(enum type_kind k) +{ + switch (k) { + case TYPE_PTR: + case TYPE_FUNC_PTR: + return true; + + default: + return false; + } + + return false; +} + struct type { enum type_kind k; @@ -70,9 +105,13 @@ enum ast_kind { AST_IMPORT, /** Creating new variable */ AST_LET, + AST_PUT, + AST_WRITE, /** If statement */ AST_IF, /** Nil check */ + AST_NIL_CHECK, + /** Nil */ AST_NIL, /** Call procedure. */ AST_CALL, @@ -80,8 +119,6 @@ enum ast_kind { AST_PROC_DEF, /** Variable declaration/definition. */ AST_VAR_DEF, - /** Dot. \c a.b; */ - AST_DOT, /* Closure */ AST_CLOSURE, /** Construct new type, something!{} */ @@ -124,12 +161,30 @@ enum ast_kind { AST_EQ, /** Negation, \c - */ AST_NEG, + /** Bitwise negation, \c ~ */ + AST_BNEG, /** Logical negation, \c ! */ AST_LNOT, /** Bitwise negation, \c ~ */ AST_NOT, /** Reference (note, not addrof!) */ AST_REF, + /** Sizeof */ + AST_SIZEOF, + AST_AS, + AST_CONSTRUCTION, + AST_CONSTRUCT, + AST_DECONSTRUCTION, + AST_DECONSTRUCT, + AST_EXPLODE, + AST_SELF, + AST_FORGET, + AST_PASTE, + AST_IMPLEMENTS, + AST_TEMPLATE, + AST_INSTANCE, + AST_SUPERTEMPLATE, + AST_INSTANCE_CONT, /** Dereferencing. * @todo should references and pointers both use this? */ @@ -149,6 +204,7 @@ enum ast_flag { AST_FLAG_NOMOVES = (1 << 2), AST_FLAG_PUBLIC = (1 << 3), AST_REQ_FRAME = (1 << 4), + AST_FLAG_LOWERED = (1 << 5) }; struct ast { @@ -270,11 +326,12 @@ static inline bool is_const(struct ast *x) static inline bool is_lvalue(struct ast *node) { switch (node->k) { + case AST_DEREF: case AST_ID: - /** @todo others */ return true; - default: return false; + default: + return false; } return false; @@ -292,16 +349,11 @@ static inline bool is_trivially_copyable(struct type *type) case TYPE_U32: case TYPE_U64: case TYPE_REF: - case TYPE_PTR: + case TYPE_BOOL: case TYPE_FUNC_PTR: case TYPE_PURE_CLOSURE: - /** @todo primitive types */ return true; - case TYPE_ID: - /* very special, bad bad bad */ - return strcmp(type->id, "int") == 0; - default: return false; } @@ -318,11 +370,11 @@ static inline bool is_trivially_copyable(struct type *type) #define gen_str(k, s, loc) gen_ast(k, NULL, NULL, NULL, NULL, NULL, s, -1, 0., \ loc) - #define gen4(k, a, b, c, d, loc) gen_ast(k, a, b, c, d, NULL, NULL, -1, 0., loc) #define gen3(k, a, b, c, loc) gen4(k, a, b, c, NULL, loc) #define gen2(k, a, b, loc) gen3(k, a, b, NULL, loc) #define gen1(k, a, loc) gen2(k, a, NULL, loc) +#define gen0(k, loc) gen1(k, NULL, loc) /* kind of hacky but I guess it works, and allows us to check that the type is @@ -340,17 +392,12 @@ static inline bool is_trivially_copyable(struct type *type) #define tgen_void(loc) \ tgen_type(TYPE_VOID, NULL, NULL, loc) -#define tgen_err(loc) \ - tgen_type(TYPE_ERR, NULL, NULL, loc) - #define tid_str(x) return_id(x, TYPE_ID) #define tgen_id(id, loc) \ tgen_type(TYPE_ID, NULL, id, loc) -#define tconstruct_id(x) return_id(x, TYPE_CONSTRUCT) -#define tconstruct_args(x) return_t0(x, TYPE_CONSTRUCT) -#define tgen_construct(id, args, loc) \ - tgen_type(TYPE_CONSTRUCT, args, id, loc) +#define tgen_nil(loc) \ + tgen_type(TYPE_NIL, NULL, NULL, loc) #define tptr_base(x) return_t0(x, TYPE_PTR) #define tgen_ptr(base, loc) \ @@ -364,7 +411,7 @@ static inline bool is_trivially_copyable(struct type *type) #define tgen_closure(args, loc) \ tgen_type(TYPE_CLOSURE, args, NULL, loc) -#define tpure_closure_args(x) return_t0(x, TYPE_CLOSURE) +#define tpure_closure_args(x) return_t0(x, TYPE_PURE_CLOSURE) #define tgen_pure_closure(args, loc) \ tgen_type(TYPE_PURE_CLOSURE, args, NULL, loc) @@ -387,6 +434,59 @@ static inline bool is_trivially_copyable(struct type *type) #define gen_comparison(op, left, right, loc) \ gen2(op, left, right, loc) +#define construction_id(x) return_s(x, AST_CONSTRUCTION) +#define construction_expr(x) return_a0(x, AST_CONSTRUCTION) +#define gen_construction(id, expr, loc) \ + gen_str1(AST_CONSTRUCTION, id, expr, loc) + +#define construct_id(x) return_s(x, AST_CONSTRUCT) +#define construct_members(x) return_a0(x, AST_CONSTRUCT) +#define gen_construct(id, members, loc) \ + gen_str1(AST_CONSTRUCT, id, members, loc) + +#define deconstruction_id(x) return_s(x, AST_DECONSTRUCTION) +#define deconstruction_var(x) return_a0(x, AST_DECONSTRUCTION) +#define gen_deconstruction(id, expr, loc) \ + gen_str1(AST_DECONSTRUCTION, id, expr, loc) + +#define deconstruct_members(x) return_a0(x, AST_DECONSTRUCT) +#define gen_deconstruct(members, loc) \ + gen1(AST_DECONSTRUCT, members, loc) + +#define gen_paste(l, r, loc) \ + gen2(AST_PASTE, l, r, loc) + +#define forget_id(x) return_s(x, AST_FORGET) +#define gen_forget(id, loc) \ + gen_str(AST_FORGET, id, loc) + +#define gen_implements(id, loc) \ + gen_str(AST_IMPLEMENTS, id, loc) + +#define template_type_params(x) return_a0(x, AST_TEMPLATE) +#define template_body(x) return_a2(x, AST_TEMPLATE) +#define gen_template(id, types, params, body, loc) \ + gen_str3(AST_TEMPLATE, id, types, params, body, loc) + +#define gen_supertemplate(id, types, params, inst, body, loc) \ + gen_ast(AST_SUPERTEMPLATE, types, params, inst, body, NULL, id, 0, 0., loc) + +#define gen_self(loc) \ + gen0(AST_SELF, loc) + +#define instance_id(x) return_s(x, AST_INSTANCE) +#define instance_templ(x) return_a1(x, AST_INSTANCE) +#define instance_type_args(x) return_t2(x, AST_INSTANCE) +#define gen_instance(name, templ, types, exprs, loc) \ + gen_ast(AST_INSTANCE, exprs, templ, NULL, NULL, types, name, 0, 0., loc) + +#define gen_instance_cont(name, body, loc) \ + gen_str1(AST_INSTANCE_CONT, name, body, loc) + +#define sizeof_type(x) return_t2(x, AST_SIZEOF) +#define gen_sizeof(type, loc) \ + gen_ast(AST_SIZEOF, NULL, NULL, NULL, NULL, type, NULL, 0, 0., loc) + #define unop_expr(x) ({assert(is_unop(x)); x->a0;}) #define gen_unop(op, expr, loc) \ gen1(op, expr, loc) @@ -403,11 +503,6 @@ static inline bool is_trivially_copyable(struct type *type) #define gen_proc(id, params, rtype, body, loc) \ gen_ast(AST_PROC_DEF, params, body, NULL, NULL, rtype, id, 0, 0., loc) -#define dot_id(x) return_s(x, AST_DOT) -#define dot_expr(x) return_a0(x, AST_DOT) -#define gen_dot(id, expr, loc) \ - gen_str1(AST_DOT, id, expr, loc) - #define var_id(x) return_s(x, AST_VAR_DEF) #define var_type(x) return_t2(x, AST_VAR_DEF) #define gen_var(id, type, loc) \ @@ -427,10 +522,9 @@ static inline bool is_trivially_copyable(struct type *type) gen_str(AST_TRAIT_DEF, id, loc) #define struct_id(x) return_s(x, AST_STRUCT_DEF) -#define struct_params(x) return_a0(x, AST_STRUCT_DEF) -#define struct_body(x) return_a1(x, AST_STRUCT_DEF) -#define gen_struct(id, params, body, loc) \ - gen_str2(AST_STRUCT_DEF, id, params, body, loc) +#define struct_body(x) return_a0(x, AST_STRUCT_DEF) +#define gen_struct(id, body, loc) \ + gen_str1(AST_STRUCT_DEF, id, body, loc) #define import_file(x) return_s(x, AST_IMPORT) #define gen_import(file, loc) \ @@ -467,6 +561,20 @@ static inline bool is_trivially_copyable(struct type *type) #define gen_let(var, from, loc) \ gen2(AST_LET, var, from, loc) +#define put_dst(x) return_a0(x, AST_PUT) +#define gen_put(dst, loc) \ + gen1(AST_PUT, dst, loc) + +#define write_dst(x) return_a0(x, AST_WRITE) +#define write_src(x) return_a1(x, AST_WRITE) +#define gen_write(dst, src, loc) \ + gen2(AST_WRITE, dst, src, loc) + +#define explode_deconstruct(x) return_a0(x, AST_EXPLODE) +#define explode_expr(x) return_a1(x, AST_EXPLODE) +#define gen_explode(deconstruct, expr, loc) \ + gen2(AST_EXPLODE, deconstruct, expr, loc) + #define init_args(x) return_t2(x, AST_INIT) #define init_body(x) return_a0(x, AST_INIT) #define init_id(x) return_s(x, AST_INIT) @@ -479,11 +587,20 @@ static inline bool is_trivially_copyable(struct type *type) #define gen_if(cond, body, els, loc) \ gen3(AST_IF, cond, body, els, loc) -#define nil_var(x) return_s(x, AST_NIL) -#define nil_body(x) return_a1(x, AST_NIL) -#define nil_ref(x) return_a2(x, AST_NIL) -#define gen_nil(var, body, ref, loc) \ - gen_ast(AST_NIL, NULL, body, ref, NULL, NULL, var, 0, 0., loc) +#define nil_check_expr(x) return_a0(x, AST_NIL_CHECK) +#define nil_check_body(x) return_a1(x, AST_NIL_CHECK) +#define nil_check_ref(x) return_a2(x, AST_NIL_CHECK) +#define nil_check_rest(x) return_a3(x, AST_NIL_CHECK) +#define gen_nil_check(expr, body, ref, loc) \ + gen3(AST_NIL_CHECK, expr, body, ref, loc) + +#define gen_nil(loc) \ + gen0(AST_NIL, loc) + +#define as_expr(x) return_a0(x, AST_AS) +#define as_type(x) return_t2(x, AST_AS) +#define gen_as(expr, type, loc) \ + gen_ast(AST_AS, expr, NULL, NULL, NULL, type, NULL, 0, 0., loc) #define own_id(x) return_s(x, AST_OWN) #define own_body(x) return_a1(x, AST_OWN) diff --git a/include/fwd/debug.h b/include/fwd/debug.h index c3dce63..ac4dfdf 100644 --- a/include/fwd/debug.h +++ b/include/fwd/debug.h @@ -96,6 +96,9 @@ void semantic_warn(struct scope *scope, struct ast *node, const char *fmt, ...); void semantic_error(struct scope *scope, struct ast *node, const char *fmt, ...); +void type_error(struct scope *scope, struct type *type, const char *fmt, + ...); + void loc_error(struct scope *scope, struct src_loc loc, const char *fmt, ...); /** @@ -141,6 +144,6 @@ void type_mismatch(struct scope *scope, struct ast *node, 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); +char *type_str(struct type *t); #endif /* FWD_DEBUG_H */ diff --git a/include/fwd/mod.h b/include/fwd/mod.h index 6031c92..51aa9c4 100644 --- a/include/fwd/mod.h +++ b/include/fwd/mod.h @@ -61,6 +61,10 @@ static inline void *fwd_arg(fwd_extern_args_t args, size_t idx, fwd_type_t id) #define FWD_ARG_T(args, idx, type) \ FWD_ARG(args, idx, type, FWD_T(type)) +/* unimplemented as of yet */ +#define FWD_RET(id, x) \ + abort() + static inline fwd_type_t fwd_t_signed(size_t s) { switch (s) { diff --git a/include/fwd/rewrite.h b/include/fwd/rewrite.h new file mode 100644 index 0000000..d9c4129 --- /dev/null +++ b/include/fwd/rewrite.h @@ -0,0 +1,9 @@ +#ifndef FWD_REWRITE_H +#define FWD_REWRITE_H + +#include <fwd/ast.h> + +int rewrite_types(struct ast *node, char *orig, char *new); +int rewrite_holes(struct ast *node, char *new); + +#endif /* FWD_REWRITE_H */ diff --git a/include/fwd/scope.h b/include/fwd/scope.h index ab268bc..c3bafa0 100644 --- a/include/fwd/scope.h +++ b/include/fwd/scope.h @@ -55,6 +55,7 @@ struct scope { /** List of child scopes. */ struct scope *children; + struct visible templates; struct visible symbols; struct visible traits; struct visible types; @@ -113,13 +114,11 @@ int scope_add_scratch(struct scope *scope, struct ast *scratch); */ void scope_add_scope(struct scope *parent, struct scope *child); - int scope_add_symbol(struct scope *scope, struct ast *symbol); struct ast *scope_find_symbol(struct scope *scope, char *id); struct ast *file_scope_find_symbol(struct scope *scope, char *id); int scope_add_type(struct scope *scope, struct ast *type); -int scope_add_chain(struct scope *scope, struct ast *type); struct ast *scope_find_type(struct scope *scope, char *id); struct ast *file_scope_find_type(struct scope *scope, char *id); @@ -127,4 +126,8 @@ int scope_add_trait(struct scope *scope, struct ast *trait); struct ast *scope_find_trait(struct scope *scope, char *id); struct ast *file_scope_find_trait(struct scope *scope, char *id); +int scope_add_template(struct scope *scope, struct ast *trait); +struct ast *scope_find_template(struct scope *scope, char *id); +struct ast *file_scope_find_template(struct scope *scope, char *id); + #endif /* SCOPE_H */ |
