Typedefs can now be registered, and even typedef a typedef.

This commit is contained in:
Dale Weiler 2012-04-09 20:10:52 -04:00
parent 2017af5713
commit 45cbef1b8f
4 changed files with 60 additions and 9 deletions

18
gmqcc.h
View file

@ -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

2
lex.c
View file

@ -34,7 +34,7 @@
static const char *const lex_keywords[] = {
"do", "else", "if", "while",
"break", "continue", "return", "goto",
"for",
"for", "typedef",
/* types */
"int",

17
parse.c
View file

@ -22,6 +22,7 @@
*/
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#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);

View file

@ -22,6 +22,7 @@
*/
#include <string.h>
#include <stdint.h> /* replace if stdint.h doesn't exist! */
#include <limits.h>
#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);
}