From: Dale Weiler Date: Mon, 9 Apr 2012 23:47:20 +0000 (-0400) Subject: Implemented typedefs X-Git-Tag: 0.1-rc1~709 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=b10d1005fbb6c1c9505f995968297f2ad97f213b;p=xonotic%2Fgmqcc.git Implemented typedefs --- diff --git a/Makefile b/Makefile index 98f79a1..7690c66 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CC = gcc CFLAGS = -O3 -Wall -OBJ = main.o lex.o error.o parse.o cpp.o +OBJ = main.o lex.o error.o parse.o cpp.o typedef.o %.o: %.c $(CC) -c -o $@ $< $(CFLAGS) @@ -9,4 +9,4 @@ gmqcc: $(OBJ) $(CC) -o $@ $^ $(CFLAGS) clean: - rm -f *.o dpqcc + rm -f *.o gmqcc diff --git a/gmqcc b/gmqcc deleted file mode 100755 index d00f3c7..0000000 Binary files a/gmqcc and /dev/null differ diff --git a/gmqcc.h b/gmqcc.h index bd1d715..142e6a1 100644 --- a/gmqcc.h +++ b/gmqcc.h @@ -140,6 +140,7 @@ struct lex_file { int current; int length; int size; + long line; /* Line the lexer is on */ char lastok[8192]; /* No token shall ever be bigger than this! */ }; @@ -197,4 +198,12 @@ struct parsenode { /* cpp.c */ int cpp (struct lex_file *); +/* typedef.c */ +typedef struct typedef_node_t { + struct typedef_node_t *next; + char *name; /* name of actual type */ +} typedef_node; +void typedef_init(); +typedef_node *typedef_find(const char *); + #endif diff --git a/lex.c b/lex.c index 62067bb..2d453d4 100644 --- a/lex.c +++ b/lex.c @@ -164,8 +164,10 @@ static int lex_get(struct lex_file *file) { while (isspace(ch) && ch != '\n') ch = lex_getch(file); - if (ch == '\n') + if (ch == '\n') { + file->line ++; return ch; + } lex_unget(ch, file); return ' '; @@ -291,6 +293,12 @@ int lex_token(struct lex_file *file) { if (!strncmp(file->lastok, lex_keywords[it], sizeof(lex_keywords[it]))) return it; + /* try the hashtable for typedefs? */ + if (typedef_find(file->lastok)) + for (it = 0; it < sizeof(lex_keywords)/sizeof(*lex_keywords); it++) + if (!strncmp(typedef_find(file->lastok)->name, lex_keywords[it], sizeof(lex_keywords[it]))) + return it; + return LEX_IDENT; } return ch; diff --git a/parse.c b/parse.c index 7320c9e..f2566d6 100644 --- a/parse.c +++ b/parse.c @@ -208,6 +208,12 @@ int parse(struct lex_file *file) { PARSE_TREE_ADD(PARSE_TYPE_FOR); break; + case LEX_IDENT: + token = lex_token(file); + printf("FOO: %s\n", file->lastok); + break; + + case TOKEN_DO: PARSE_TODO(PARSE_TYPE_DO); case TOKEN_WHILE: PARSE_TODO(PARSE_TYPE_WHILE); case TOKEN_BREAK: PARSE_TODO(PARSE_TYPE_BREAK); @@ -243,17 +249,16 @@ int parse(struct lex_file *file) { if (token == '&') { /* && */ token = lex_token(file); PARSE_TREE_ADD(PARSE_TYPE_LAND); - goto end; + break; } PARSE_TREE_ADD(PARSE_TYPE_BAND); - printf("--> BITWISE AND\n"); break; case '|': /* | */ token = lex_token(file); if (token == '|') { /* || */ token = lex_token(file); PARSE_TREE_ADD(PARSE_TYPE_LOR); - goto end; + break; } PARSE_TREE_ADD(PARSE_TYPE_BOR); break; @@ -262,7 +267,7 @@ int parse(struct lex_file *file) { if (token == '=') { /* != */ token = lex_token(file); PARSE_TREE_ADD(PARSE_TYPE_LNEQ); - goto end; + break; } PARSE_TREE_ADD(PARSE_TYPE_LNOT); break; @@ -271,7 +276,7 @@ int parse(struct lex_file *file) { if (token == '=') { /* <= */ token = lex_token(file); PARSE_TREE_ADD(PARSE_TYPE_LTEQ); - goto end; + break; } PARSE_TREE_ADD(PARSE_TYPE_LT); break; @@ -280,7 +285,7 @@ int parse(struct lex_file *file) { if (token == '=') { /* >= */ token = lex_token(file); PARSE_TREE_ADD(PARSE_TYPE_GTEQ); - goto end; + break; } PARSE_TREE_ADD(PARSE_TYPE_GT); break; @@ -289,7 +294,7 @@ int parse(struct lex_file *file) { if (token == '=') { /* == */ token = lex_token(file); PARSE_TREE_ADD(PARSE_TYPE_EQEQ); - goto end; + break; } PARSE_TREE_ADD(PARSE_TYPE_EQUAL); break; @@ -322,7 +327,6 @@ int parse(struct lex_file *file) { PARSE_TREE_ADD(PARSE_TYPE_RBS); break; } - end:; } parse_debug(parseroot); lex_reset(file); diff --git a/typedef.c b/typedef.c new file mode 100644 index 0000000..70a2fe4 --- /dev/null +++ b/typedef.c @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2012 + * Dale Weiler + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include +#include /* replace if stdint.h doesn't exist! */ +#include "gmqcc.h" + +/* + * This implements a hashtable for typedef type keywords which end up + * being translated to their full-expressed type. This uses a singly + * linked list with a fast hash function. + */ +static typedef_node *typedef_table[1024]; + +void typedef_init() { + int i; + for(i = 0; i < sizeof(typedef_table)/sizeof(*typedef_table); i++) + typedef_table[i] = NULL; +} + +/* + * Fast collisionless hashfunction based off of: + * http://www.azillionmonkeys.com/qed/hash.html + * By: Paul Hsieh + * + * The code is licensed under LGPL 2.1 or Paul + * Hsieh's derivative license. Stated on his page + * quote: + * + * The LGPL 2.1 is not necessarily a more liberal license than my + * derivative license, but this additional licensing makes the code + * available to more developers. Note that this does not give you + * multi-licensing rights. You can only use the code under one of + * the licenses at a time. + * + * Paul Hsieh derivative license + * + * The derivative content includes raw computer source code, ideas, + * opinions, and excerpts whose original source is covered under + * another license and transformations of such derivatives. + * Note that mere excerpts by themselves (with the exception of raw + * source code) are not considered derivative works under this license. + * Use and redistribution is limited to the following conditions: + * + * One may not create a derivative work which, in any way, violates the + * Paul Hsieh exposition license described above on the original content. + * + * One may not apply a license to a derivative work that precludes anyone + * else from using and redistributing derivative content. + * + * One may not attribute any derivative content to authors not involved + * in the creation of the content, though an attribution to the author + * is not necessary. + * + * Paul Hsieh exposition license + * + * The content of all text, figures, tables and displayed layout is + * copyrighted by its author and owner Paul Hsieh unless specifically + * denoted otherwise. Redistribution is limited to the following conditions: + * + * The redistributor must fully attribute the content's authorship and + * make a good faith effort to cite the original location of the original + * content. + * + * The content may not be modified via excerpt or otherwise with the + * exception of additional citations such as described above without prior + * consent of Paul Hsieh. + * + * The content may not be subject to a change in license without prior + * consent of Paul Hsieh. + * + * The content may be used for commercial purposes. + */ + +#if (defined(__GNUC__) && defined(__i386__)) || defined(_MSC_VER) +/* + * Unalligned loads are faster if we can do them, otherwise fall back + * to safer version below. + */ +# define load16(D) (*((const uint16_t*)(D))) +#else +# define load16(D) ((((uint32_t)(((const uint8_t*)(D))[1])) << 8) + \ + (uint32_t)(((const uint8_t*)(D))[0])) +#endif +unsigned int inline typedef_hash(const char *data) { + uint32_t hash = strlen(data); + uint32_t size = hash; + uint32_t temp = 0; + + int last; + if (size <= 0|| data == NULL) + return -1; + + last = size & 3; + size >>= 2; + + /* main loop */ + for (;size > 0; size--) { + hash += (load16(data)); + temp = (load16(data+2) << 11) ^ hash; + hash = (hash << 16) ^ temp; + data += sizeof(uint16_t) << 1; + hash += hash >> 11; + } + + /* ends */ + switch (last) { + case 3: + hash += load16(data); + hash ^= hash << 16; + hash ^= ((signed char)data[sizeof(uint16_t)]) << 8; + hash += hash >> 11; + break; + case 2: + hash += load16(data); + hash ^= hash << 11; + hash += hash >> 17; + break; + case 1: + hash += (signed char)*data; + hash ^= hash << 10; + hash += hash >> 1; + break; + } + + /* force avalanching of final 127 bits */ + hash ^= hash << 3; + hash += hash >> 5; + hash ^= hash << 4; + hash += hash >> 17; + hash ^= hash << 25; + hash += hash >> 6; + + return hash % 1024; +} + +typedef_node *typedef_find(const char *s) { + unsigned int hash = typedef_hash(s); + typedef_node *find = typedef_table[hash]; + return find; +}