From: Michael Wallner Date: Tue, 27 Oct 2015 11:33:52 +0000 (+0100) Subject: fliush X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-psi;a=commitdiff_plain;h=4aa8ade5313ba77e903223d44fa81898350b677f fliush --- diff --git a/src/module.c b/src/module.c index 4d6e5c9..3e7de89 100644 --- a/src/module.c +++ b/src/module.c @@ -142,6 +142,65 @@ void psi_to_string(impl_val *ret_val, decl_arg *func, zval *return_value) } } +size_t psi_t_alignment(token_t t) +{ + size_t align; +# define PSI_TAS_D(T) struct TAS_ ##T { \ + char c; \ + ##T x; \ +} +# define PSI_TAS_C(T) align = offsetof(struct TAS_ ##T, x) +# define PSI_TAS_CASE(T) { \ + PSI_TAS_D(T); \ + PSI_TAS_C(T); \ +} + switch (t) { + case PSI_T_CHAR: + PSI_TAS_CASE(char); + break; + case PSI_T_SINT8: + PSI_TAS_CASE(int8_t); + break; + case PSI_T_UINT8: + PSI_TAS_CASE(uint8_t); + break; + case PSI_T_SHORT: + PSI_TAS_CASE(short); + break; + case PSI_T_SINT16: + PSI_TAS_CASE(int16_t); + break; + case PSI_T_UINT16: + PSI_TAS_CASE(uint16_t); + break; + case PSI_T_INT: + PSI_TAS_CASE(int); + break; + case PSI_T_SINT32: + PSI_TAS_CASE(int32_t); + break; + case PSI_T_UINT32: + PSI_TAS_CASE(uint32_t); + break; + case PSI_T_LONG: + PSI_TAS_CASE(long); + break; + case PSI_T_SINT64: + PSI_TAS_CASE(int64_t); + break; + case PSI_T_UINT64: + PSI_TAS_CASE(uint64_t); + break; + case PSI_T_FLOAT: + PSI_TAS_CASE(float); + break; + case PSI_T_DOUBLE: + PSI_TAS_CASE(double); + break; + EMPTY_SWITCH_DEFAULT_CASE(); + } +} + size_t psi_t_size(token_t t) { size_t size; @@ -186,6 +245,12 @@ size_t psi_t_size(token_t t) return size; } +size_t psi_t_align(token_t t, size_t s) +{ + size_t a = psi_t_alignment(t); + return ((s - 1) | (a - 1)) + 1; +} + static impl_val *iterate(impl_val *val, token_t t, unsigned i, impl_val *tmp) { size_t size = psi_t_size(t); diff --git a/src/parser.re b/src/parser.re index 9cd39fa..c134ffd 100644 --- a/src/parser.re +++ b/src/parser.re @@ -201,6 +201,7 @@ token_t PSI_ParserScan(PSI_Parser *P) ARRAY = 'array'; FUNCTION = 'function'; TYPEDEF = 'typedef'; + STRUCT = 'struct'; CONST = 'const'; LIB = 'lib'; LET = 'let'; @@ -260,6 +261,7 @@ token_t PSI_ParserScan(PSI_Parser *P) ARRAY {RETURN(PSI_T_ARRAY);} FUNCTION {RETURN(PSI_T_FUNCTION);} TYPEDEF {RETURN(PSI_T_TYPEDEF);} + STRUCT {RETURN(PSI_T_STRUCT);} CONST {RETURN(PSI_T_CONST);} LIB {RETURN(PSI_T_LIB);} LET {RETURN(PSI_T_LET);} diff --git a/src/validator.c b/src/validator.c index 44ea4ab..19956b7 100644 --- a/src/validator.c +++ b/src/validator.c @@ -61,6 +61,7 @@ static int validate_lib(PSI_Validator *V) { } return 1; } + static inline int locate_decl_type_alias(decl_typedefs *defs, decl_type *type) { size_t i; @@ -75,14 +76,38 @@ static inline int locate_decl_type_alias(decl_typedefs *defs, decl_type *type) { } return 0; } +static inline int locate_decl_type_struct(decl_structs *structs, decl_type *type) { + size_t i; + + if (type->strct) { + return 1; + } + for (i = 0; i < structs->count; ++i) { + if (!strcmp(structs->list[i]->name, type->name)) { + type->strct = structs->list[i]; + return 1; + } + } + return 0; +} static inline int validate_decl_type(PSI_Validator *V, decl_arg *arg, decl_type *type) { - if (type->type == PSI_T_NAME) { + switch (type->type) { + case PSI_T_NAME: if (!V->defs || !locate_decl_type_alias(V->defs, type)) { V->error(PSI_WARNING, "Cannot use '%s' as type for '%s';" - " Use 'typedef ;' statement", + " Use 'typedef ;' statement", + type->name, arg->var->name); + return 0; + } + return validate_decl_type(V, arg, type->real); + case PSI_T_STRUCT: + if (!V->structs || !locate_decl_type_struct(V->structs, type)) { + V->error(PSI_WARNING, "Cannot use '%s' as type for '%s';" + " Use 'typedef struct ;' statement", type->name, arg->var->name); return 0; } + break; } return 1; } @@ -142,17 +167,17 @@ static inline int validate_decl_abi(PSI_Validator *V, decl_abi *abi) { V->error(PSI_WARNING, "Invalid calling convention: '%s'", abi->convention); return 0; } -static inline int validate_decl_arg(PSI_Validator *V, decl *decl, decl_arg *arg) { +static inline int validate_decl_arg(PSI_Validator *V, decl_arg *arg) { if (!validate_decl_type(V, arg, arg->type)) { return 0; } return 1; } -static inline int validate_decl_args(PSI_Validator *V, decl *decl, decl_args *args) { +static inline int validate_decl_args(PSI_Validator *V, decl_args *args) { size_t i; for (i = 0; i < args->count; ++i) { - if (!validate_decl_arg(V, decl, args->args[i])) { + if (!validate_decl_arg(V, args->args[i])) { return 0; } } @@ -165,7 +190,7 @@ static inline int validate_decl(PSI_Validator *V, decl *decl) { if (!validate_decl_func(V, decl, decl->func)) { return 0; } - if (decl->args && !validate_decl_args(V, decl, decl->args)) { + if (decl->args && !validate_decl_args(V, decl->args)) { return 0; } return 1; @@ -180,6 +205,37 @@ static inline int validate_decls(PSI_Validator *V) { } return 1; } +static inline int validate_struct(PSI_Validator *V, decl_struct *s) { + size_t i; + + if (!validate_decl_args(V, s->args)) { + return 0; + } + + s->layout = calloc(s->args->count, sizeof(*s->layout)); + for (i = 0; i < s->args->count; ++i) { + decl_type *t = real_decl_type(s->args->args[i]->type); + + if (i) { + decl_struct_layout *l = &s->layout[i-1]; + s->layout[i].pos = psi_t_align(t->type, l->pos + l->size); + } else { + s->layout[i].pos = 0; + } + s->layout[i].len = psi_t_size(t->type); + } + return 1; +} +static inline int validate_structs(PSI_Validator *V) { + size_t i; + + for (i = 0; i < V->structs->count; ++i) { + if (!validate_struct(V->structs->list[i])) { + return 0; + } + } + return 1; +} static inline int validate_impl_type(PSI_Validator *V, impl *impl, impl_type *type) { /* FIXME */ @@ -406,6 +462,9 @@ int PSI_ValidatorValidate(PSI_Validator *V) if (V->defs && !validate_typedefs(V)) { return 0; } + if (V->structs && !validate_structs(V)) { + return 0; + } if (V->decls && !validate_decls(V)) { return 0; }