From: Michael Wallner Date: Thu, 28 Jan 2016 13:46:18 +0000 (+0100) Subject: flush X-Git-Url: https://git.m6w6.name/?a=commitdiff_plain;h=1c837573a87e0d375768e990a28d1b2706dbaf43;p=m6w6%2Fext-psi flush --- diff --git a/src/parser.h b/src/parser.h index 6710996..41741c0 100644 --- a/src/parser.h +++ b/src/parser.h @@ -22,7 +22,7 @@ size_t psi_t_size(token_t); typedef struct PSI_Token { token_t type; - unsigned size, line; + unsigned size, line, col; char *text, *file; char buf[1]; } PSI_Token; @@ -61,6 +61,7 @@ typedef struct decl_type { struct decl_type *real; struct decl_struct *strct; struct decl_enum *enm; + struct decl *func; } decl_type; static inline decl_type *init_decl_type(token_t type, const char *name) { @@ -1441,6 +1442,7 @@ static inline PSI_Token *PSI_TokenAlloc(PSI_Parser *P) { T->text = &T->buf[0]; T->file = &T->buf[token_len + 1]; T->line = P->line; + T->col = P->col; memcpy(T->text, P->tok, token_len); memcpy(T->file, P->psi.file.fn, fname_len); @@ -1488,8 +1490,59 @@ static inline PSI_Token *PSI_TokenCat(unsigned argc, ...) { return T; } -static inline const char *PSI_TokenLocation(PSI_Token *t) { - return t ? t->file : ":0:0"; +static inline PSI_Token *PSI_TokenAppend(PSI_Token *T, unsigned argc, ...) { + va_list argv; + unsigned i; + + va_start(argv, argc); + for (i = 0; i < argc; ++i) { + char *str = va_arg(argv, char *); + size_t str_len = strlen(str), token_len = T->size, fname_len = strlen(T->file); + + T = realloc(T, PSI_TokenAllocSize(T->size += str_len + 1, fname_len)); + T->text = &T->buf[0]; + T->file = &T->buf[T->size + 1]; + T->buf[token_len] = ' '; + memmove(&T->buf[T->size + 1], &T->buf[token_len + 1], fname_len + 1); + memcpy(&T->buf[token_len + 1], str, str_len + 1); + } + va_end(argv); + + return T; +} + +static inline PSI_Token *PSI_TokenTranslit(PSI_Token *T, char *from, char *to) { + php_strtr(T->text, T->size, from, to, MIN(strlen(from), strlen(to))); + return T; +} + +static inline uint64_t psi_hash(char *digest_buf, ...) +{ + uint64_t hash = 5381; + uint8_t c; + const uint8_t *ptr; + va_list argv; + + va_start(argv, digest_buf); + while ((ptr = va_arg(argv, const uint8_t *))) { + while ((c = *ptr++)) { + hash = ((hash << 5) + hash) + c; + } + } + va_end(argv); + + if (digest_buf) { + sprintf(digest_buf, "%" PRIx64, hash); + } + + return hash; +} + +static inline uint64_t PSI_TokenHash(PSI_Token *t, char *digest_buf) { + char loc_buf[48]; + + sprintf(loc_buf, "%u%u", t->line, t->col); + return psi_hash(digest_buf, t->file, loc_buf, NULL); } #define PSI_PARSER_DEBUG 0x1 diff --git a/src/parser.re b/src/parser.re index 50d15aa..5b7e80e 100644 --- a/src/parser.re +++ b/src/parser.re @@ -209,10 +209,10 @@ void PSI_ParserFree(PSI_Parser **P) #define ADDCOLS \ P->col += P->cur - P->tok -#define NEWLINE \ +#define NEWLINE(label) \ P->col = 1; \ ++P->line; \ - goto nextline + goto label token_t PSI_ParserScan(PSI_Parser *P) { @@ -236,7 +236,8 @@ token_t PSI_ParserScan(PSI_Parser *P) QUOTED_STRING = "\"" ([^\"])+ "\""; NUMBER = [+-]? [0-9]* "."? [0-9]+ ([eE] [+-]? [0-9]+)?; - ("#"|"//") .* "\n" { NEWLINE; } + "/*" { goto comment; } + ("#"|"//") .* "\n" { NEWLINE(nextline); } "(" {RETURN(PSI_T_LPAREN);} ")" {RETURN(PSI_T_RPAREN);} ";" {RETURN(PSI_T_EOS);} @@ -254,7 +255,7 @@ token_t PSI_ParserScan(PSI_Parser *P) "-" {RETURN(PSI_T_MINUS);} "/" {RETURN(PSI_T_SLASH);} "..." {RETURN(PSI_T_ELLIPSIS);} - [\r\n] { NEWLINE; } + [\r\n] { NEWLINE(nextline); } [\t ]+ { continue; } 'TRUE' {RETURN(PSI_T_TRUE);} 'FALSE' {RETURN(PSI_T_FALSE);} @@ -284,6 +285,7 @@ token_t PSI_ParserScan(PSI_Parser *P) 'FUNCTION' {RETURN(PSI_T_FUNCTION);} 'TYPEDEF' {RETURN(PSI_T_TYPEDEF);} 'STRUCT' {RETURN(PSI_T_STRUCT);} + 'UNION' {RETURN(PSI_T_UNION);} 'ENUM' {RETURN(PSI_T_ENUM);} 'CONST' {RETURN(PSI_T_CONST);} 'LIB' {RETURN(PSI_T_LIB);} @@ -313,6 +315,14 @@ token_t PSI_ParserScan(PSI_Parser *P) QUOTED_STRING {RETURN(PSI_T_QUOTED_STRING);} [^] {break;} */ + + comment: + P->tok = P->cur; + /*!re2c + "\n" { NEWLINE(comment); } + "*" "/" { continue; } + [^] { goto comment; } + */ } return -1; } diff --git a/src/parser_proc.h b/src/parser_proc.h index c6fe15a..4749e82 100644 --- a/src/parser_proc.h +++ b/src/parser_proc.h @@ -10,64 +10,65 @@ #define PSI_T_RETURN 10 #define PSI_T_LIB 11 #define PSI_T_STRING 12 -#define PSI_T_EOF 13 -#define PSI_T_EOS 14 -#define PSI_T_QUOTED_STRING 15 -#define PSI_T_ENUM 16 -#define PSI_T_LBRACE 17 -#define PSI_T_RBRACE 18 -#define PSI_T_COMMA 19 -#define PSI_T_EQUALS 20 -#define PSI_T_STRUCT 21 -#define PSI_T_COLON 22 -#define PSI_T_LPAREN 23 -#define PSI_T_NUMBER 24 -#define PSI_T_RPAREN 25 -#define PSI_T_BOOL 26 -#define PSI_T_INT 27 -#define PSI_T_FLOAT 28 -#define PSI_T_CONST 29 -#define PSI_T_NSNAME 30 -#define PSI_T_TYPEDEF 31 -#define PSI_T_VOID 32 -#define PSI_T_LBRACKET 33 -#define PSI_T_RBRACKET 34 -#define PSI_T_ELLIPSIS 35 -#define PSI_T_CHAR 36 -#define PSI_T_SHORT 37 -#define PSI_T_LONG 38 -#define PSI_T_DOUBLE 39 -#define PSI_T_UNSIGNED 40 -#define PSI_T_SIGNED 41 -#define PSI_T_INT8 42 -#define PSI_T_UINT8 43 -#define PSI_T_INT16 44 -#define PSI_T_UINT16 45 -#define PSI_T_INT32 46 -#define PSI_T_UINT32 47 -#define PSI_T_INT64 48 -#define PSI_T_UINT64 49 -#define PSI_T_FUNCTION 50 -#define PSI_T_NULL 51 -#define PSI_T_TRUE 52 -#define PSI_T_FALSE 53 -#define PSI_T_DOLLAR 54 -#define PSI_T_CALLOC 55 -#define PSI_T_OBJVAL 56 -#define PSI_T_ARRVAL 57 -#define PSI_T_PATHVAL 58 -#define PSI_T_STRLEN 59 -#define PSI_T_STRVAL 60 -#define PSI_T_FLOATVAL 61 -#define PSI_T_INTVAL 62 -#define PSI_T_BOOLVAL 63 -#define PSI_T_TO_OBJECT 64 -#define PSI_T_TO_ARRAY 65 -#define PSI_T_TO_STRING 66 -#define PSI_T_TO_INT 67 -#define PSI_T_TO_FLOAT 68 -#define PSI_T_TO_BOOL 69 -#define PSI_T_MIXED 70 -#define PSI_T_ARRAY 71 -#define PSI_T_OBJECT 72 -#define PSI_T_AMPERSAND 73 +#define PSI_T_STRUCT 13 +#define PSI_T_UNION 14 +#define PSI_T_EOF 15 +#define PSI_T_EOS 16 +#define PSI_T_QUOTED_STRING 17 +#define PSI_T_ENUM 18 +#define PSI_T_LBRACE 19 +#define PSI_T_RBRACE 20 +#define PSI_T_COMMA 21 +#define PSI_T_EQUALS 22 +#define PSI_T_COLON 23 +#define PSI_T_LPAREN 24 +#define PSI_T_NUMBER 25 +#define PSI_T_RPAREN 26 +#define PSI_T_BOOL 27 +#define PSI_T_INT 28 +#define PSI_T_FLOAT 29 +#define PSI_T_CONST 30 +#define PSI_T_NSNAME 31 +#define PSI_T_TYPEDEF 32 +#define PSI_T_VOID 33 +#define PSI_T_LBRACKET 34 +#define PSI_T_RBRACKET 35 +#define PSI_T_ELLIPSIS 36 +#define PSI_T_CHAR 37 +#define PSI_T_SHORT 38 +#define PSI_T_LONG 39 +#define PSI_T_DOUBLE 40 +#define PSI_T_UNSIGNED 41 +#define PSI_T_SIGNED 42 +#define PSI_T_INT8 43 +#define PSI_T_UINT8 44 +#define PSI_T_INT16 45 +#define PSI_T_UINT16 46 +#define PSI_T_INT32 47 +#define PSI_T_UINT32 48 +#define PSI_T_INT64 49 +#define PSI_T_UINT64 50 +#define PSI_T_FUNCTION 51 +#define PSI_T_NULL 52 +#define PSI_T_TRUE 53 +#define PSI_T_FALSE 54 +#define PSI_T_DOLLAR 55 +#define PSI_T_CALLOC 56 +#define PSI_T_OBJVAL 57 +#define PSI_T_ARRVAL 58 +#define PSI_T_PATHVAL 59 +#define PSI_T_STRLEN 60 +#define PSI_T_STRVAL 61 +#define PSI_T_FLOATVAL 62 +#define PSI_T_INTVAL 63 +#define PSI_T_BOOLVAL 64 +#define PSI_T_TO_OBJECT 65 +#define PSI_T_TO_ARRAY 66 +#define PSI_T_TO_STRING 67 +#define PSI_T_TO_INT 68 +#define PSI_T_TO_FLOAT 69 +#define PSI_T_TO_BOOL 70 +#define PSI_T_MIXED 71 +#define PSI_T_ARRAY 72 +#define PSI_T_OBJECT 73 +#define PSI_T_AMPERSAND 74 diff --git a/src/parser_proc.y b/src/parser_proc.y index 2068105..ac856ed 100644 --- a/src/parser_proc.y +++ b/src/parser_proc.y @@ -30,6 +30,7 @@ void psi_error(int, const char *, int, const char *, ...); %left PLUS MINUS. %left SLASH ASTERISK. %fallback NAME TEMP FREE SET LET RETURN LIB STRING. +%fallback STRUCT UNION. file ::= blocks. @@ -71,9 +72,24 @@ block ::= decl_enum(e). { P->enums = add_decl_enum(P->enums, e); } -enum_name(n) ::= ENUM NAME(N). { +optional_name(n) ::= .{ + n = NULL; +} +optional_name(n) ::= NAME(N). { n = N; } +enum_name(n) ::= ENUM(E) optional_name(N). { + if (N) { + n = N; + free(E); + } else { + char digest[17]; + + PSI_TokenHash(E, digest); + n = PSI_TokenTranslit(PSI_TokenAppend(E, 1, digest), " ", "@"); + } +} + %type decl_enum {decl_enum *} %destructor decl_enum {free_decl_enum($$);} @@ -102,8 +118,16 @@ decl_enum_item(i) ::= NAME(N). { i->token = N; } -struct_name(n) ::= STRUCT NAME(N). { - n = N; +struct_name(n) ::= STRUCT(S) optional_name(N). { + if (N) { + n = N; + free(S); + } else { + char digest[17]; + + PSI_TokenHash(S, digest); + n = PSI_TokenTranslit(PSI_TokenAppend(S, 1, digest), " ", "@"); + } } %type decl_struct_args_block {decl_args*} @@ -157,15 +181,27 @@ constant(constant) ::= CONST const_type(type) NSNAME(T) EQUALS impl_def_val(val) decl_typedef(def) ::= TYPEDEF decl_typedef_body(def_) EOS. { def = def_; } -%type decl_typedef_body {decl_typedef*} -%destructor decl_typedef_body {free_decl_typedef($$);} -decl_typedef_body(def) ::= struct_name(N) struct_size(size_) decl_struct_args_block(args) NAME(ALIAS). { +%type decl_typedef_body_ex {decl_typedef*} +%destructor decl_typedef_body_ex {free_decl_typedef($$);} +decl_typedef_body_ex(def) ::= struct_name(N) struct_size(size_) decl_struct_args_block(args) NAME(ALIAS). { def = init_decl_typedef(ALIAS->text, init_decl_type(PSI_T_STRUCT, N->text)); def->token = ALIAS; + def->type->token = PSI_TokenCopy(N); def->type->strct = init_decl_struct(N->text, args); def->type->strct->token = N; def->type->strct->size = size_; } +decl_typedef_body_ex(def) ::= decl_enum(e) NAME(ALIAS). { + def = init_decl_typedef(ALIAS->text, init_decl_type(PSI_T_ENUM, e->name)); + def->type->token = PSI_TokenCopy(e->token); + def->token = ALIAS; + def->type->enm = e; +} +%type decl_typedef_body {decl_typedef*} +%destructor decl_typedef_body {free_decl_typedef($$);} +decl_typedef_body(def) ::= decl_typedef_body_ex(def_). { + def = def_; +} decl_typedef_body(def) ::= decl_type(type) NAME(ALIAS). { def = init_decl_typedef(ALIAS->text, type); def->token = ALIAS; @@ -176,6 +212,12 @@ decl_typedef_body(def) ::= VOID(V) indirection(i) NAME(ALIAS). { def->token = ALIAS; def->type->token = V; } +decl_typedef_body(def) ::= decl_func(func) LPAREN decl_args(args) RPAREN. { + def = init_decl_typedef(func->var->name, init_decl_type(PSI_T_FUNCTION, func->var->name)); + def->type->token = PSI_TokenCopy(func->token); + def->type->func = init_decl(init_decl_abi("default"), func, args); + def->token = PSI_TokenCopy(func->token); +} %type decl {decl*} %destructor decl {free_decl($$);} @@ -276,6 +318,14 @@ struct_args(args) ::= struct_args(args_) struct_arg(arg). { } %type struct_arg {decl_arg*} %destructor struct_arg {free_decl_arg($$);} +struct_arg(arg_) ::= decl_typedef_body_ex(def) EOS. { + arg_ = init_decl_arg(def->type, init_decl_var(def->alias, 0, 0)); + arg_->var->arg = arg_; + arg_->token = PSI_TokenCopy(def->type->token); + arg_->var->token = def->token; + free(def->alias); + free(def); +} struct_arg(arg) ::= decl_arg(arg_) struct_layout(layout_) EOS. { arg_->layout = layout_; arg = arg_;