Merge branch 'master' into blub/bc3

This commit is contained in:
Wolfgang (Blub) Bumiller 2012-08-08 12:05:08 +02:00
commit ae251d3914
7 changed files with 131 additions and 24 deletions

5
ast.c
View file

@ -32,7 +32,7 @@
if (!self) { \
return NULL; \
} \
ast_node_init((ast_node*)self, ctx); \
ast_node_init((ast_node*)self, ctx, TYPE_##T); \
( (ast_node*)self )->node.destroy = (ast_node_delete*)destroyfn
/* It must not be possible to get here. */
@ -43,11 +43,12 @@ static GMQCC_NORETURN void _ast_node_destroy(ast_node *self)
}
/* Initialize main ast node aprts */
static void ast_node_init(ast_node *self, lex_ctx ctx)
static void ast_node_init(ast_node *self, lex_ctx ctx, int nodetype)
{
self->node.context = ctx;
self->node.destroy = &_ast_node_destroy;
self->node.keep = false;
self->node.nodetype = nodetype;
}
/* General expression initialization */

20
ast.h
View file

@ -44,6 +44,25 @@ typedef struct ast_call_s ast_call;
typedef struct ast_unary_s ast_unary;
typedef struct ast_return_s ast_return;
enum {
TYPE_ast_node,
TYPE_ast_expression,
TYPE_ast_value,
TYPE_ast_function,
TYPE_ast_block,
TYPE_ast_binary,
TYPE_ast_store,
TYPE_ast_entfield,
TYPE_ast_ifthen,
TYPE_ast_ternary,
TYPE_ast_loop,
TYPE_ast_call,
TYPE_ast_unary,
TYPE_ast_return
};
#define ast_istype(x, t) ( ((ast_node_common*)x)->nodetype == (t) )
/* Node interface with common components
*/
typedef void ast_node_delete(ast_node*);
@ -52,6 +71,7 @@ typedef struct
lex_ctx context;
/* I don't feel comfortable using keywords like 'delete' as names... */
ast_node_delete *destroy;
int nodetype;
/* keep: if a node contains this node, 'keep'
* prevents its dtor from destroying this node as well.
*/

13
code.c
View file

@ -63,6 +63,8 @@ VECTOR_MAKE(prog_section_function, code_functions );
VECTOR_MAKE(int, code_globals );
VECTOR_MAKE(char, code_chars );
uint32_t code_entfields;
void code_init() {
prog_section_function empty_function = {0,0,0,0,0,0,0,{0}};
prog_section_statement empty_statement = {0,{0},{0},{0}};
@ -82,6 +84,8 @@ void code_init() {
code_chars_add ('\0');
code_functions_add (empty_function);
code_statements_add(empty_statement);
code_entfields = 0;
}
uint32_t code_genstring(const char *str)
@ -152,6 +156,13 @@ void code_test() {
code_statements_add(s3);
}
qcint code_alloc_field (size_t qcsize)
{
qcint pos = (qcint)code_entfields;
code_entfields += qcsize;
return pos;
}
bool code_write(const char *filename) {
prog_header code_header;
FILE *fp = NULL;
@ -173,7 +184,7 @@ bool code_write(const char *filename) {
code_header.strings.length = code_chars_elements;
code_header.version = 6;
code_header.crc16 = 0; /* TODO: */
code_header.entfield = 0; /* TODO: */
code_header.entfield = code_entfields;
if (OPTS_FLAG(DARKPLACES_STRING_TABLE_BUG)) {
util_debug("GEN", "Patching stringtable for -fdarkplaces-stringtablebug\n");

View file

@ -253,7 +253,7 @@ uint32_t util_crc32(const char *, int, register const short);
while (N##_add(*++elements) != -1 && len--); \
return N##_elements; \
} \
typedef char VECTOR_FILL(extra_semicolon_,__COUNTER__)
typedef char VECTOR_FILL(extra_semicolon_##N,__COUNTER__)
#define VECTOR_PROT(T,N) \
extern T* N##_data ; \
extern long N##_elements ; \
@ -516,6 +516,9 @@ VECTOR_PROT(prog_section_function, code_functions );
VECTOR_PROT(int, code_globals );
VECTOR_PROT(char, code_chars );
typedef float qcfloat;
typedef int32_t qcint;
/*
* code_write -- writes out the compiled file
* code_init -- prepares the code file
@ -524,6 +527,7 @@ bool code_write (const char *filename);
void code_init ();
uint32_t code_genstring (const char *string);
uint32_t code_cachedstring(const char *string);
qcint code_alloc_field (size_t qcsize);
/*===================================================================*/
/*========================= assembler.c =============================*/
@ -834,9 +838,6 @@ typedef struct {
* Since we may want to support that as well, let's redefine
* float and int here.
*/
typedef float qcfloat;
typedef int32_t qcint;
typedef union {
qcint _int;
qcint string;

95
ir.c
View file

@ -115,6 +115,7 @@ ir_builder* ir_builder_new(const char *modulename)
MEM_VECTOR_INIT(self, functions);
MEM_VECTOR_INIT(self, globals);
MEM_VECTOR_INIT(self, fields);
self->name = NULL;
if (!ir_builder_set_name(self, modulename)) {
mem_d(self);
@ -130,6 +131,7 @@ ir_builder* ir_builder_new(const char *modulename)
}
MEM_VEC_FUNCTIONS(ir_builder, ir_value*, globals)
MEM_VEC_FUNCTIONS(ir_builder, ir_value*, fields)
MEM_VEC_FUNCTIONS(ir_builder, ir_function*, functions)
void ir_builder_delete(ir_builder* self)
@ -143,7 +145,11 @@ void ir_builder_delete(ir_builder* self)
for (i = 0; i != self->globals_count; ++i) {
ir_value_delete(self->globals[i]);
}
MEM_VECTOR_CLEAR(self, globals);
MEM_VECTOR_CLEAR(self, fields);
for (i = 0; i != self->fields_count; ++i) {
ir_value_delete(self->fields[i]);
}
MEM_VECTOR_CLEAR(self, fields);
mem_d(self);
}
@ -224,6 +230,33 @@ ir_value* ir_builder_create_global(ir_builder *self, const char *name, int vtype
return ve;
}
ir_value* ir_builder_get_field(ir_builder *self, const char *name)
{
size_t i;
for (i = 0; i < self->fields_count; ++i) {
if (!strcmp(self->fields[i]->name, name))
return self->fields[i];
}
return NULL;
}
ir_value* ir_builder_create_field(ir_builder *self, const char *name, int vtype)
{
ir_value *ve = ir_builder_get_field(self, name);
if (ve) {
return NULL;
}
ve = ir_value_var(name, store_global, TYPE_FIELD);
ve->fieldtype = vtype;
if (!ir_builder_fields_add(self, ve)) {
ir_value_delete(ve);
return NULL;
}
return ve;
}
/***********************************************************************
*IR Function
*/
@ -1284,6 +1317,8 @@ on_error:
ir_value* ir_block_create_fieldaddress(ir_block *self, const char *label, ir_value *ent, ir_value *field)
{
ir_value *v;
/* Support for various pointer types todo if so desired */
if (ent->vtype != TYPE_ENTITY)
return NULL;
@ -1291,7 +1326,9 @@ ir_value* ir_block_create_fieldaddress(ir_block *self, const char *label, ir_val
if (field->vtype != TYPE_FIELD)
return NULL;
return ir_block_create_general_instr(self, label, INSTR_ADDRESS, ent, field, TYPE_POINTER);
v = ir_block_create_general_instr(self, label, INSTR_ADDRESS, ent, field, TYPE_POINTER);
v->fieldtype = field->fieldtype;
return v;
}
ir_value* ir_block_create_load_from_ent(ir_block *self, const char *label, ir_value *ent, ir_value *field, int outype)
@ -2105,21 +2142,7 @@ static bool gen_global_field(ir_value *global)
}
else
{
prog_section_field fld;
fld.name = global->code.name;
fld.offset = code_fields_elements;
fld.type = global->fieldtype;
if (fld.type == TYPE_VOID) {
printf("Field is missing a type: %s\n", global->name);
return false;
}
if (code_fields_add(fld) < 0)
return false;
global->code.globaladdr = code_globals_add(fld.offset);
global->code.globaladdr = code_globals_add(0);
}
if (global->code.globaladdr < 0)
return false;
@ -2553,12 +2576,50 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global)
}
}
static bool ir_builder_gen_field(ir_builder *self, ir_value *field)
{
prog_section_def def;
prog_section_field fld;
def.type = field->vtype;
def.offset = code_globals_elements;
def.name = field->code.name = code_genstring(field->name);
if (code_defs_add(def) < 0)
return false;
fld.name = def.name;
fld.offset = code_fields_elements;
fld.type = field->fieldtype;
if (fld.type == TYPE_VOID) {
printf("field is missing a type: %s - don't know its size\n", field->name);
return false;
}
if (code_fields_add(fld) < 0)
return false;
if (!code_globals_add(code_alloc_field(type_sizeof[field->fieldtype])))
return false;
field->code.globaladdr = code_globals_add(fld.offset);
return field->code.globaladdr >= 0;
}
bool ir_builder_generate(ir_builder *self, const char *filename)
{
size_t i;
code_init();
for (i = 0; i < self->fields_count; ++i)
{
if (!ir_builder_gen_field(self, self->fields[i])) {
return false;
}
}
for (i = 0; i < self->globals_count; ++i)
{
if (!ir_builder_gen_global(self, self->globals[i])) {

4
ir.h
View file

@ -290,6 +290,7 @@ typedef struct ir_builder_s
char *name;
MEM_VECTOR_MAKE(ir_function*, functions);
MEM_VECTOR_MAKE(ir_value*, globals);
MEM_VECTOR_MAKE(ir_value*, fields);
} ir_builder;
ir_builder* ir_builder_new(const char *modulename);
@ -299,12 +300,15 @@ bool ir_builder_set_name(ir_builder *self, const char *name);
MEM_VECTOR_PROTO(ir_builder, ir_function*, functions);
MEM_VECTOR_PROTO(ir_builder, ir_value*, globals);
MEM_VECTOR_PROTO(ir_builder, ir_value*, fields);
ir_function* ir_builder_get_function(ir_builder*, const char *fun);
ir_function* ir_builder_create_function(ir_builder*, const char *name, int outtype);
ir_value* ir_builder_get_global(ir_builder*, const char *fun);
ir_value* ir_builder_create_global(ir_builder*, const char *name, int vtype);
ir_value* ir_builder_get_field(ir_builder*, const char *fun);
ir_value* ir_builder_create_field(ir_builder*, const char *name, int vtype);
bool ir_builder_generate(ir_builder *self, const char *filename);

View file

@ -12,6 +12,15 @@
VECTOR_MAKE(ast_value*, globals);
VECTOR_MAKE(ast_function*, functions);
uint32_t opts_flags[1 + (COUNT_FLAGS / 32)];
uint32_t opts_warn [1 + (COUNT_WARNINGS / 32)];
uint32_t opts_O = 1;
const char *opts_output = "progs.dat";
int opts_standard = COMPILER_GMQCC;
bool opts_debug = false;
bool opts_memchk = false;
#include "ast-macros.h"
int main()