mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2025-01-18 14:21:36 +00:00
Typedefs can now be registered, and even typedef a typedef.
This commit is contained in:
parent
2017af5713
commit
45cbef1b8f
4 changed files with 60 additions and 9 deletions
18
gmqcc.h
18
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
|
||||
|
|
2
lex.c
2
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",
|
||||
|
|
17
parse.c
17
parse.c
|
@ -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);
|
||||
|
|
32
typedef.c
32
typedef.c
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue