From 45cbef1b8f50648a066efd9d48e24a04b64975eb Mon Sep 17 00:00:00 2001 From: Dale Weiler Date: Mon, 9 Apr 2012 20:10:52 -0400 Subject: [PATCH] Typedefs can now be registered, and even typedef a typedef. --- gmqcc.h | 18 ++++++++++-------- lex.c | 2 +- parse.c | 17 +++++++++++++++++ typedef.c | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 9 deletions(-) diff --git a/gmqcc.h b/gmqcc.h index 142e6a1..0aecd5c 100644 --- a/gmqcc.h +++ b/gmqcc.h @@ -157,12 +157,13 @@ struct lex_file { #define TOKEN_RETURN 6 #define TOKEN_GOTO 7 #define TOKEN_FOR 8 // extension -#define TOKEN_INT 9 // extension -#define TOKEN_VOID 10 -#define TOKEN_STRING 11 -#define TOKEN_FLOAT 12 -#define TOKEN_VECTOR 13 -#define TOKEN_ENTITY 14 +#define TOKEN_TYPEDEF 9 // extension +#define TOKEN_INT 10 // extension +#define TOKEN_VOID 11 +#define TOKEN_STRING 12 +#define TOKEN_FLOAT 13 +#define TOKEN_VECTOR 14 +#define TOKEN_ENTITY 15 /* * Lexer state constants, these are numbers for where exactly in @@ -200,10 +201,11 @@ int cpp (struct lex_file *); /* typedef.c */ typedef struct typedef_node_t { - struct typedef_node_t *next; - char *name; /* name of actual type */ + char *name; /* name of actual type */ } typedef_node; + void typedef_init(); typedef_node *typedef_find(const char *); +int typedef_add (const char *, const char *); #endif diff --git a/lex.c b/lex.c index 2d453d4..48d01c4 100644 --- a/lex.c +++ b/lex.c @@ -34,7 +34,7 @@ static const char *const lex_keywords[] = { "do", "else", "if", "while", "break", "continue", "return", "goto", - "for", + "for", "typedef", /* types */ "int", diff --git a/parse.c b/parse.c index f2566d6..4ec2569 100644 --- a/parse.c +++ b/parse.c @@ -22,6 +22,7 @@ */ #include #include +#include #include "gmqcc.h" /* @@ -213,6 +214,22 @@ int parse(struct lex_file *file) { printf("FOO: %s\n", file->lastok); break; + case TOKEN_TYPEDEF: { + char *f = NULL; + char *t = NULL; + token = lex_token(file); + token = lex_token(file); f = strdup(file->lastok); + token = lex_token(file); + token = lex_token(file); t = strdup(file->lastok); + + typedef_add(f, t); + + /* free new strings */ + mem_d(f); + mem_d(t); + break; + } + case TOKEN_DO: PARSE_TODO(PARSE_TYPE_DO); case TOKEN_WHILE: PARSE_TODO(PARSE_TYPE_WHILE); diff --git a/typedef.c b/typedef.c index 9994e55..fcd2b18 100644 --- a/typedef.c +++ b/typedef.c @@ -22,6 +22,7 @@ */ #include #include /* replace if stdint.h doesn't exist! */ +#include #include "gmqcc.h" /* @@ -158,3 +159,34 @@ typedef_node *typedef_find(const char *s) { typedef_node *find = typedef_table[hash]; return find; } + +int typedef_add(const char *from, const char *to) { + unsigned int hash = typedef_hash(to); + typedef_node *find = typedef_table[hash]; + if (find) + return error(ERROR_PARSE, "typedef for %s already exists\n", to); + + /* check if the type exists first */ + if (strncmp(from, "void", sizeof("void")) == 0 || + strncmp(from, "string", sizeof("string")) == 0 || + strncmp(from, "float", sizeof("float")) == 0 || + strncmp(from, "vector", sizeof("vector")) == 0 || + strncmp(from, "entity", sizeof("entity")) == 0) { + + typedef_table[hash] = mem_a(sizeof(typedef_node)); + typedef_table[hash]->name = strdup(from); + return -100; + } else { + /* search the typedefs for it (typedef-a-typedef?) */ + typedef_node *find = typedef_table[typedef_hash(from)]; + if (find) { + typedef_table[hash] = mem_a(sizeof(typedef_node)); + typedef_table[hash]->name = strdup(find->name); + return -100; + } + } + return error(ERROR_PARSE, "cannot typedef %s (not a type)\n", from); +} + + + -- 2.39.2