mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2025-02-07 06:51:10 +00:00
Cleanups
This commit is contained in:
parent
d5dcb3aff7
commit
639fc8a32b
7 changed files with 134 additions and 200 deletions
2
Makefile
2
Makefile
|
@ -5,7 +5,7 @@ OBJ = main.o \
|
||||||
error.o \
|
error.o \
|
||||||
parse.o \
|
parse.o \
|
||||||
typedef.o \
|
typedef.o \
|
||||||
alloc.o
|
util.o
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(CC) -c $< -o $@ $(CFLAGS)
|
$(CC) -c $< -o $@ $(CFLAGS)
|
||||||
|
|
6
README
6
README
|
@ -30,9 +30,9 @@ typedef.c
|
||||||
complicated than it sounds. This handles all typedefs, and even recrusive
|
complicated than it sounds. This handles all typedefs, and even recrusive
|
||||||
typedefs.
|
typedefs.
|
||||||
|
|
||||||
alloc.c
|
util.c
|
||||||
This is just an allocator for the compiler, it's used for debugging reasons
|
These are utilities for the compiler, some things in here include a
|
||||||
only.
|
allocator used for debugging, and some string functions.
|
||||||
|
|
||||||
README
|
README
|
||||||
This is the file you're currently reading
|
This is the file you're currently reading
|
||||||
|
|
54
alloc.c
54
alloc.c
|
@ -1,54 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "gmqcc.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The compiler has it's own memory tracker / allocator for debugging
|
|
||||||
* reasons. It will help find things like buggy CSE or OOMs (if this
|
|
||||||
* compiler ever grows to that point.)
|
|
||||||
*/
|
|
||||||
struct memblock_t {
|
|
||||||
const char *file;
|
|
||||||
unsigned int line;
|
|
||||||
unsigned int byte;
|
|
||||||
};
|
|
||||||
|
|
||||||
void *memory_a(unsigned int byte, unsigned int line, const char *file) {
|
|
||||||
struct memblock_t *data = malloc(sizeof(struct memblock_t) + byte);
|
|
||||||
if (!data) return NULL;
|
|
||||||
data->line = line;
|
|
||||||
data->byte = byte;
|
|
||||||
data->file = file;
|
|
||||||
printf("[MEM] allocation: %08u (bytes) at %s:%u\n", byte, file, line);
|
|
||||||
return (void*)((uintptr_t)data+sizeof(struct memblock_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
void memory_d(void *ptrn, unsigned int line, const char *file) {
|
|
||||||
if (!ptrn) return;
|
|
||||||
void *data = (void*)((uintptr_t)ptrn-sizeof(struct memblock_t));
|
|
||||||
struct memblock_t *info = (struct memblock_t*)data;
|
|
||||||
printf("[MEM] released: %08u (bytes) at %s:%u\n", info->byte, file, line);
|
|
||||||
free(data);
|
|
||||||
}
|
|
224
gmqcc.h
224
gmqcc.h
|
@ -24,7 +24,109 @@
|
||||||
#define GMQCC_HDR
|
#define GMQCC_HDR
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
/* The types supported by the language */
|
//===================================================================
|
||||||
|
//============================ lex.c ================================
|
||||||
|
//===================================================================
|
||||||
|
struct lex_file {
|
||||||
|
FILE *file;
|
||||||
|
char peek [5];
|
||||||
|
char lastok[8192];
|
||||||
|
|
||||||
|
int last;
|
||||||
|
int current;
|
||||||
|
int length;
|
||||||
|
int size;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* It's important that this table never exceed 32 keywords, the ascii
|
||||||
|
* table starts at 33 (and we don't want conflicts)
|
||||||
|
*/
|
||||||
|
#define TOKEN_DO 0
|
||||||
|
#define TOKEN_ELSE 1
|
||||||
|
#define TOKEN_IF 2
|
||||||
|
#define TOKEN_WHILE 3
|
||||||
|
#define TOKEN_BREAK 4
|
||||||
|
#define TOKEN_CONTINUE 5
|
||||||
|
#define TOKEN_RETURN 6
|
||||||
|
#define TOKEN_GOTO 7
|
||||||
|
#define TOKEN_FOR 8 // extension
|
||||||
|
#define TOKEN_TYPEDEF 9 // extension
|
||||||
|
|
||||||
|
// ensure the token types are out of the
|
||||||
|
// bounds of anyothers that may conflict.
|
||||||
|
#define TOKEN_FLOAT 110
|
||||||
|
#define TOKEN_VECTOR 111
|
||||||
|
#define TOKEN_STRING 112
|
||||||
|
#define TOKEN_ENTITY 113
|
||||||
|
#define TOKEN_VOID 114
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lexer state constants, these are numbers for where exactly in
|
||||||
|
* the lexing the lexer is at. Or where it decided to stop if a lexer
|
||||||
|
* error occurs. These numbers must be > where the ascii-table ends
|
||||||
|
* and > the last type token which is TOKEN_VOID
|
||||||
|
*/
|
||||||
|
#define LEX_COMMENT 1128
|
||||||
|
#define LEX_CHRLIT 1129
|
||||||
|
#define LEX_STRLIT 1130
|
||||||
|
#define LEX_IDENT 1131
|
||||||
|
|
||||||
|
int lex_token(struct lex_file *);
|
||||||
|
void lex_reset(struct lex_file *);
|
||||||
|
void lex_close(struct lex_file *);
|
||||||
|
struct lex_file *lex_open (FILE *);
|
||||||
|
|
||||||
|
//===================================================================
|
||||||
|
//========================== error.c ================================
|
||||||
|
//===================================================================
|
||||||
|
#define ERROR_LEX (SHRT_MAX+0)
|
||||||
|
#define ERROR_PARSE (SHRT_MAX+1)
|
||||||
|
#define ERROR_INTERNAL (SHRT_MAX+2)
|
||||||
|
#define ERROR_COMPILER (SHRT_MAX+3)
|
||||||
|
#define ERROR_PREPRO (SHRT_MAX+4)
|
||||||
|
int error(int, const char *, ...);
|
||||||
|
|
||||||
|
//===================================================================
|
||||||
|
//========================== parse.c ================================
|
||||||
|
//===================================================================
|
||||||
|
int parse_tree(struct lex_file *);
|
||||||
|
struct parsenode {
|
||||||
|
struct parsenode *next;
|
||||||
|
int type; /* some token */
|
||||||
|
};
|
||||||
|
|
||||||
|
//===================================================================
|
||||||
|
//========================== typedef.c ==============================
|
||||||
|
//===================================================================
|
||||||
|
typedef struct typedef_node_t {
|
||||||
|
char *name;
|
||||||
|
} typedef_node;
|
||||||
|
|
||||||
|
void typedef_init();
|
||||||
|
void typedef_clear();
|
||||||
|
typedef_node *typedef_find(const char *);
|
||||||
|
int typedef_add (const char *, const char *);
|
||||||
|
|
||||||
|
|
||||||
|
//===================================================================
|
||||||
|
//=========================== util.c ================================
|
||||||
|
//===================================================================
|
||||||
|
void *util_memory_a(unsigned int, unsigned int, const char *);
|
||||||
|
void util_memory_d(void *, unsigned int, const char *);
|
||||||
|
char *util_strdup (const char *);
|
||||||
|
|
||||||
|
#ifdef NOTRACK
|
||||||
|
# define mem_a(x) malloc(x)
|
||||||
|
# define mem_d(x) free (x)
|
||||||
|
#else
|
||||||
|
# define mem_a(x) util_memory_a((x), __LINE__, __FILE__)
|
||||||
|
# define mem_d(x) util_memory_d((x), __LINE__, __FILE__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//===================================================================
|
||||||
|
//=========================== code.c ================================
|
||||||
|
//===================================================================
|
||||||
#define TYPE_VOID 0
|
#define TYPE_VOID 0
|
||||||
#define TYPE_STRING 1
|
#define TYPE_STRING 1
|
||||||
#define TYPE_FLOAT 2
|
#define TYPE_FLOAT 2
|
||||||
|
@ -34,33 +136,17 @@
|
||||||
#define TYPE_FUNCTION 6
|
#define TYPE_FUNCTION 6
|
||||||
#define TYPE_POINTER 7
|
#define TYPE_POINTER 7
|
||||||
|
|
||||||
/*
|
|
||||||
* there are 3 accessible memory zones -
|
|
||||||
* globals
|
|
||||||
* array of 32bit ints/floats, mixed, LE,
|
|
||||||
* entities
|
|
||||||
* structure is up to the engine but the fields are a linear array
|
|
||||||
* of mixed ints/floats, there are globals referring to the offsets
|
|
||||||
* of these in the entity struct so there are ADDRESS and STOREP and
|
|
||||||
* LOAD instructions that use globals containing field offsets.
|
|
||||||
* strings
|
|
||||||
* a static array in the progs.dat, with file parsing creating
|
|
||||||
* additional constants, and some engine fields are mapped by
|
|
||||||
* address as well to unique string offsets
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Instructions
|
* Instructions
|
||||||
* These are the external instructions supported by the interperter
|
* These are the external instructions supported by the interperter
|
||||||
* this is what things compile to (from the C code). This is not internal
|
* this is what things compile to (from the C code).
|
||||||
* instructions for support like int, and such (which are translated)
|
|
||||||
*/
|
*/
|
||||||
#define INSTR_DONE 0
|
#define INSTR_DONE 0
|
||||||
// math
|
// math
|
||||||
#define INSTR_MUL_F 1 /* multiplication float */
|
#define INSTR_MUL_F 1
|
||||||
#define INSTR_MUL_V 2 /* multiplication vector */
|
#define INSTR_MUL_V 2
|
||||||
#define INSTR_MUL_FV 3 /* multiplication float->vector */
|
#define INSTR_MUL_FV 3
|
||||||
#define INSTR_MUL_VF 4 /* multiplication vector->float */
|
#define INSTR_MUL_VF 4
|
||||||
#define INSTR_DIV_F 5
|
#define INSTR_DIV_F 5
|
||||||
#define INSTR_ADD_F 6
|
#define INSTR_ADD_F 6
|
||||||
#define INSTR_ADD_V 7
|
#define INSTR_ADD_V 7
|
||||||
|
@ -120,98 +206,4 @@
|
||||||
#define INSTR_OR 57
|
#define INSTR_OR 57
|
||||||
#define INSTR_BITAND 59
|
#define INSTR_BITAND 59
|
||||||
#define INSTR_BITOR 60
|
#define INSTR_BITOR 60
|
||||||
|
|
||||||
/*
|
|
||||||
* This is the smallest lexer I've ever wrote: and I must say, it's quite
|
|
||||||
* more nicer than those large bulky complex parsers that most people write
|
|
||||||
* which has some sort of a complex state.
|
|
||||||
*/
|
|
||||||
struct lex_file {
|
|
||||||
/*
|
|
||||||
* This is a simple state for lexing, no need to be complex for qc
|
|
||||||
* code. It's trivial stuff.
|
|
||||||
*/
|
|
||||||
FILE *file;
|
|
||||||
char peek[5]; /* extend for depthier peeks */
|
|
||||||
int last;
|
|
||||||
int current;
|
|
||||||
int length;
|
|
||||||
int size;
|
|
||||||
char lastok[8192]; /* No token shall ever be bigger than this! */
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* It's important that this table never exceed 32 keywords, the ascii
|
|
||||||
* table starts at 33 (and we don't want conflicts)
|
|
||||||
*/
|
|
||||||
#define TOKEN_DO 0
|
|
||||||
#define TOKEN_ELSE 1
|
|
||||||
#define TOKEN_IF 2
|
|
||||||
#define TOKEN_WHILE 3
|
|
||||||
#define TOKEN_BREAK 4
|
|
||||||
#define TOKEN_CONTINUE 5
|
|
||||||
#define TOKEN_RETURN 6
|
|
||||||
#define TOKEN_GOTO 7
|
|
||||||
#define TOKEN_FOR 8 // extension
|
|
||||||
#define TOKEN_TYPEDEF 9 // extension
|
|
||||||
|
|
||||||
// ensure the token types are out of the
|
|
||||||
// bounds of anyothers that may conflict.
|
|
||||||
#define TOKEN_FLOAT 110
|
|
||||||
#define TOKEN_VECTOR 111
|
|
||||||
#define TOKEN_STRING 112
|
|
||||||
#define TOKEN_ENTITY 113
|
|
||||||
#define TOKEN_VOID 114
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Lexer state constants, these are numbers for where exactly in
|
|
||||||
* the lexing the lexer is at. Or where it decided to stop if a lexer
|
|
||||||
* error occurs. These numbers must be > where the ascii-table ends
|
|
||||||
* and > the last type token which is TOKEN_VOID
|
|
||||||
*/
|
|
||||||
#define LEX_COMMENT 1128
|
|
||||||
#define LEX_CHRLIT 1129
|
|
||||||
#define LEX_STRLIT 1130
|
|
||||||
#define LEX_IDENT 1131
|
|
||||||
|
|
||||||
int lex_token(struct lex_file *);
|
|
||||||
void lex_reset(struct lex_file *);
|
|
||||||
void lex_close(struct lex_file *);
|
|
||||||
struct lex_file *lex_open (FILE *);
|
|
||||||
|
|
||||||
/* errors */
|
|
||||||
#define ERROR_LEX (SHRT_MAX+0)
|
|
||||||
#define ERROR_PARSE (SHRT_MAX+1)
|
|
||||||
#define ERROR_INTERNAL (SHRT_MAX+2)
|
|
||||||
#define ERROR_COMPILER (SHRT_MAX+3)
|
|
||||||
#define ERROR_PREPRO (SHRT_MAX+4)
|
|
||||||
int error(int, const char *, ...);
|
|
||||||
|
|
||||||
/* parse.c */
|
|
||||||
int parse_tree(struct lex_file *);
|
|
||||||
struct parsenode {
|
|
||||||
struct parsenode *next;
|
|
||||||
int type; /* some token */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* typedef.c */
|
|
||||||
typedef struct typedef_node_t {
|
|
||||||
char *name; /* name of actual type */
|
|
||||||
} typedef_node;
|
|
||||||
|
|
||||||
void typedef_init();
|
|
||||||
void typedef_clear();
|
|
||||||
typedef_node *typedef_find(const char *);
|
|
||||||
int typedef_add (const char *, const char *);
|
|
||||||
|
|
||||||
/* alloc.c */
|
|
||||||
void *memory_a(unsigned int, unsigned int, const char *);
|
|
||||||
void memory_d(void *, unsigned int, const char *);
|
|
||||||
#ifdef NOTRACK
|
|
||||||
# define mem_a(x) malloc(x)
|
|
||||||
# define mem_d(x) free (x)
|
|
||||||
#else
|
|
||||||
# define mem_a(x) memory_a((x), __LINE__, __FILE__)
|
|
||||||
# define mem_d(x) memory_d((x), __LINE__, __FILE__)
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
2
lex.c
2
lex.c
|
@ -293,7 +293,7 @@ int lex_token(struct lex_file *file) {
|
||||||
if (!strncmp(X, "entity", sizeof("entity"))) \
|
if (!strncmp(X, "entity", sizeof("entity"))) \
|
||||||
return TOKEN_ENTITY; \
|
return TOKEN_ENTITY; \
|
||||||
if (!strncmp(X, "void" , sizeof("void"))) \
|
if (!strncmp(X, "void" , sizeof("void"))) \
|
||||||
return TOKEN_VOID; \
|
return TOKEN_VOID; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
TEST_TYPE(file->lastok);
|
TEST_TYPE(file->lastok);
|
||||||
|
|
43
parse.c
43
parse.c
|
@ -83,7 +83,7 @@
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These are all the punctuation handled in the parser, these don't
|
* This is all the punctuation handled in the parser, these don't
|
||||||
* need tokens, they're already tokens.
|
* need tokens, they're already tokens.
|
||||||
*/
|
*/
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -158,13 +158,13 @@ void parse_debug(struct parsenode *tree) {
|
||||||
* and everything will fail.
|
* and everything will fail.
|
||||||
*/
|
*/
|
||||||
#define PARSE_PERFORM(X,C) { \
|
#define PARSE_PERFORM(X,C) { \
|
||||||
token = lex_token(file); \
|
token = lex_token(file); \
|
||||||
{ C } \
|
{ C } \
|
||||||
while (token != '\n') { \
|
while (token != '\n') { \
|
||||||
token = lex_token(file); \
|
token = lex_token(file); \
|
||||||
} \
|
} \
|
||||||
PARSE_TREE_ADD(X); \
|
PARSE_TREE_ADD(X); \
|
||||||
break; \
|
break; \
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse_clear(struct parsenode *tree) {
|
void parse_clear(struct parsenode *tree) {
|
||||||
|
@ -230,17 +230,17 @@ int parse_tree(struct lex_file *file) {
|
||||||
* the tokens accordingly here.
|
* the tokens accordingly here.
|
||||||
*/
|
*/
|
||||||
case TOKEN_TYPEDEF: {
|
case TOKEN_TYPEDEF: {
|
||||||
char *f = NULL;
|
char *f,*t;
|
||||||
char *t = NULL;
|
|
||||||
token = lex_token(file);
|
token = lex_token(file);
|
||||||
token = lex_token(file); f = strdup(file->lastok);
|
token = lex_token(file); f = util_strdup(file->lastok);
|
||||||
token = lex_token(file);
|
token = lex_token(file);
|
||||||
token = lex_token(file); t = strdup(file->lastok);
|
token = lex_token(file); t = util_strdup(file->lastok);
|
||||||
|
|
||||||
typedef_add(f, t);
|
typedef_add(f, t);
|
||||||
|
|
||||||
free(f);
|
mem_d(f);
|
||||||
free(t);
|
mem_d(t);
|
||||||
|
|
||||||
while (token != '\n')
|
while (token != '\n')
|
||||||
token = lex_token(file);
|
token = lex_token(file);
|
||||||
|
@ -254,8 +254,6 @@ int parse_tree(struct lex_file *file) {
|
||||||
case TOKEN_RETURN:
|
case TOKEN_RETURN:
|
||||||
PARSE_TREE_ADD(PARSE_TYPE_RETURN);
|
PARSE_TREE_ADD(PARSE_TYPE_RETURN);
|
||||||
break;
|
break;
|
||||||
//PARSE_PERFORM(PARSE_TYPE_RETURN, {});
|
|
||||||
|
|
||||||
|
|
||||||
case TOKEN_DO: PARSE_PERFORM(PARSE_TYPE_DO, {});
|
case TOKEN_DO: PARSE_PERFORM(PARSE_TYPE_DO, {});
|
||||||
case TOKEN_WHILE: PARSE_PERFORM(PARSE_TYPE_WHILE, {});
|
case TOKEN_WHILE: PARSE_PERFORM(PARSE_TYPE_WHILE, {});
|
||||||
|
@ -293,7 +291,6 @@ int parse_tree(struct lex_file *file) {
|
||||||
token = lex_token(file);
|
token = lex_token(file);
|
||||||
PARSE_TREE_ADD(PARSE_TYPE_DOT);
|
PARSE_TREE_ADD(PARSE_TYPE_DOT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '(':
|
case '(':
|
||||||
token = lex_token(file);
|
token = lex_token(file);
|
||||||
PARSE_TREE_ADD(PARSE_TYPE_LPARTH);
|
PARSE_TREE_ADD(PARSE_TYPE_LPARTH);
|
||||||
|
@ -303,7 +300,7 @@ int parse_tree(struct lex_file *file) {
|
||||||
PARSE_TREE_ADD(PARSE_TYPE_RPARTH);
|
PARSE_TREE_ADD(PARSE_TYPE_RPARTH);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '&': /* & */
|
case '&': /* & */
|
||||||
token = lex_token(file);
|
token = lex_token(file);
|
||||||
if (token == '&') { /* && */
|
if (token == '&') { /* && */
|
||||||
token = lex_token(file);
|
token = lex_token(file);
|
||||||
|
@ -312,7 +309,7 @@ int parse_tree(struct lex_file *file) {
|
||||||
}
|
}
|
||||||
PARSE_TREE_ADD(PARSE_TYPE_BAND);
|
PARSE_TREE_ADD(PARSE_TYPE_BAND);
|
||||||
break;
|
break;
|
||||||
case '|': /* | */
|
case '|': /* | */
|
||||||
token = lex_token(file);
|
token = lex_token(file);
|
||||||
if (token == '|') { /* || */
|
if (token == '|') { /* || */
|
||||||
token = lex_token(file);
|
token = lex_token(file);
|
||||||
|
@ -321,7 +318,7 @@ int parse_tree(struct lex_file *file) {
|
||||||
}
|
}
|
||||||
PARSE_TREE_ADD(PARSE_TYPE_BOR);
|
PARSE_TREE_ADD(PARSE_TYPE_BOR);
|
||||||
break;
|
break;
|
||||||
case '!':
|
case '!': /* ! */
|
||||||
token = lex_token(file);
|
token = lex_token(file);
|
||||||
if (token == '=') { /* != */
|
if (token == '=') { /* != */
|
||||||
token = lex_token(file);
|
token = lex_token(file);
|
||||||
|
@ -330,7 +327,7 @@ int parse_tree(struct lex_file *file) {
|
||||||
}
|
}
|
||||||
PARSE_TREE_ADD(PARSE_TYPE_LNOT);
|
PARSE_TREE_ADD(PARSE_TYPE_LNOT);
|
||||||
break;
|
break;
|
||||||
case '<': /* < */
|
case '<': /* < */
|
||||||
token = lex_token(file);
|
token = lex_token(file);
|
||||||
if (token == '=') { /* <= */
|
if (token == '=') { /* <= */
|
||||||
token = lex_token(file);
|
token = lex_token(file);
|
||||||
|
@ -339,7 +336,7 @@ int parse_tree(struct lex_file *file) {
|
||||||
}
|
}
|
||||||
PARSE_TREE_ADD(PARSE_TYPE_LT);
|
PARSE_TREE_ADD(PARSE_TYPE_LT);
|
||||||
break;
|
break;
|
||||||
case '>': /* > */
|
case '>': /* > */
|
||||||
token = lex_token(file);
|
token = lex_token(file);
|
||||||
if (token == '=') { /* >= */
|
if (token == '=') { /* >= */
|
||||||
token = lex_token(file);
|
token = lex_token(file);
|
||||||
|
@ -348,7 +345,7 @@ int parse_tree(struct lex_file *file) {
|
||||||
}
|
}
|
||||||
PARSE_TREE_ADD(PARSE_TYPE_GT);
|
PARSE_TREE_ADD(PARSE_TYPE_GT);
|
||||||
break;
|
break;
|
||||||
case '=':
|
case '=': /* = */
|
||||||
token = lex_token(file);
|
token = lex_token(file);
|
||||||
if (token == '=') { /* == */
|
if (token == '=') { /* == */
|
||||||
token = lex_token(file);
|
token = lex_token(file);
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include "gmqcc.h"
|
#include "gmqcc.h"
|
||||||
static typedef_node *typedef_table[1024];
|
static typedef_node *typedef_table[1024];
|
||||||
|
|
||||||
void typedef_init() {
|
void typedef_init() {
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < sizeof(typedef_table)/sizeof(*typedef_table); i++)
|
for(i = 0; i < sizeof(typedef_table)/sizeof(*typedef_table); i++)
|
||||||
|
@ -66,7 +65,7 @@ int typedef_add(const char *from, const char *to) {
|
||||||
unsigned int hash = typedef_hash(to);
|
unsigned int hash = typedef_hash(to);
|
||||||
typedef_node *find = typedef_table[hash];
|
typedef_node *find = typedef_table[hash];
|
||||||
if (find)
|
if (find)
|
||||||
return error(ERROR_PARSE, "typedef for %s already exists\n", to);
|
return error(ERROR_PARSE, "typedef for %s already exists or conflicts\n", to);
|
||||||
|
|
||||||
/* check if the type exists first */
|
/* check if the type exists first */
|
||||||
if (strncmp(from, "float", sizeof("float")) == 0 ||
|
if (strncmp(from, "float", sizeof("float")) == 0 ||
|
||||||
|
|
Loading…
Reference in a new issue