Revamp the array module not to use nasty macros any more. Slightly more verbose
to use, but definitely cleaner.
This commit is contained in:
parent
3671892c34
commit
c4b8e00ae2
|
@ -74,15 +74,15 @@ struct procedure
|
||||||
const char* name;
|
const char* name;
|
||||||
struct basicblock* root_bb;
|
struct basicblock* root_bb;
|
||||||
size_t nlocals;
|
size_t nlocals;
|
||||||
ARRAY(struct basicblock, blocks);
|
ARRAYOF(struct basicblock) blocks;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct basicblock
|
struct basicblock
|
||||||
{
|
{
|
||||||
const char* name;
|
const char* name;
|
||||||
ARRAY(struct em, ems);
|
ARRAYOF(struct em) ems;
|
||||||
ARRAY(struct ir, irs);
|
ARRAYOF(struct ir) irs;
|
||||||
ARRAY(struct hop, hops);
|
ARRAYOF(struct hop) hops;
|
||||||
bool is_fake : 1;
|
bool is_fake : 1;
|
||||||
bool is_root : 1;
|
bool is_root : 1;
|
||||||
bool is_terminated : 1;
|
bool is_terminated : 1;
|
||||||
|
|
|
@ -77,7 +77,7 @@ static void queue_insn_simple(int opcode)
|
||||||
{
|
{
|
||||||
struct em* em = new_insn(opcode);
|
struct em* em = new_insn(opcode);
|
||||||
em->paramtype = PARAM_NONE;
|
em->paramtype = PARAM_NONE;
|
||||||
APPEND(code_bb->ems, em);
|
array_append(&code_bb->ems, em);
|
||||||
|
|
||||||
switch (opcode)
|
switch (opcode)
|
||||||
{
|
{
|
||||||
|
@ -92,7 +92,7 @@ static void queue_insn_value(int opcode, arith value)
|
||||||
struct em* em = new_insn(opcode);
|
struct em* em = new_insn(opcode);
|
||||||
em->paramtype = PARAM_IVALUE;
|
em->paramtype = PARAM_IVALUE;
|
||||||
em->u.ivalue = value;
|
em->u.ivalue = value;
|
||||||
APPEND(code_bb->ems, em);
|
array_append(&code_bb->ems, em);
|
||||||
|
|
||||||
switch (opcode)
|
switch (opcode)
|
||||||
{
|
{
|
||||||
|
@ -110,7 +110,7 @@ static void queue_insn_label(int opcode, const char* label, arith offset)
|
||||||
em->paramtype = PARAM_LVALUE;
|
em->paramtype = PARAM_LVALUE;
|
||||||
em->u.lvalue.label = label;
|
em->u.lvalue.label = label;
|
||||||
em->u.lvalue.offset = offset;
|
em->u.lvalue.offset = offset;
|
||||||
APPEND(code_bb->ems, em);
|
array_append(&code_bb->ems, em);
|
||||||
|
|
||||||
switch (opcode)
|
switch (opcode)
|
||||||
{
|
{
|
||||||
|
@ -126,14 +126,14 @@ static void queue_insn_block(int opcode, struct basicblock* left, struct basicbl
|
||||||
em->paramtype = PARAM_BVALUE;
|
em->paramtype = PARAM_BVALUE;
|
||||||
em->u.bvalue.left = left;
|
em->u.bvalue.left = left;
|
||||||
em->u.bvalue.right = right;
|
em->u.bvalue.right = right;
|
||||||
APPEND(code_bb->ems, em);
|
array_append(&code_bb->ems, em);
|
||||||
|
|
||||||
terminate_block();
|
terminate_block();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void change_basicblock(struct basicblock* newbb)
|
static void change_basicblock(struct basicblock* newbb)
|
||||||
{
|
{
|
||||||
APPENDU(current_proc->blocks, newbb);
|
array_appendu(¤t_proc->blocks, newbb);
|
||||||
|
|
||||||
if (code_bb && !code_bb->is_terminated)
|
if (code_bb && !code_bb->is_terminated)
|
||||||
queue_insn_block(op_bra, newbb, NULL);
|
queue_insn_block(op_bra, newbb, NULL);
|
||||||
|
@ -252,7 +252,7 @@ static void parse_pseu(void)
|
||||||
struct em* em = new_insn(op_bra);
|
struct em* em = new_insn(op_bra);
|
||||||
em->paramtype = PARAM_BVALUE;
|
em->paramtype = PARAM_BVALUE;
|
||||||
em->u.bvalue.left = bb_get(label);
|
em->u.bvalue.left = bb_get(label);
|
||||||
APPEND(data_bb->ems, em);
|
array_append(&data_bb->ems, em);
|
||||||
}
|
}
|
||||||
|
|
||||||
data_offset(label, 0, ro);
|
data_offset(label, 0, ro);
|
||||||
|
@ -289,7 +289,7 @@ static void parse_pseu(void)
|
||||||
current_proc->nlocals = em.em_nlocals;
|
current_proc->nlocals = em.em_nlocals;
|
||||||
code_bb = current_proc->root_bb;
|
code_bb = current_proc->root_bb;
|
||||||
code_bb->is_root = true;
|
code_bb->is_root = true;
|
||||||
APPEND(current_proc->blocks, code_bb);
|
array_append(¤t_proc->blocks, code_bb);
|
||||||
|
|
||||||
symbol = symbol_get(current_proc->name);
|
symbol = symbol_get(current_proc->name);
|
||||||
symbol->section = SECTION_TEXT;
|
symbol->section = SECTION_TEXT;
|
||||||
|
@ -351,7 +351,7 @@ static void create_data_label(const char* label)
|
||||||
{
|
{
|
||||||
data_bb = bb_get(label);
|
data_bb = bb_get(label);
|
||||||
data_bb->is_fake = true;
|
data_bb->is_fake = true;
|
||||||
APPEND(current_proc->blocks, data_bb);
|
array_append(¤t_proc->blocks, data_bb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
#include "mcg.h"
|
#include "mcg.h"
|
||||||
|
|
||||||
STATICMAP(graph);
|
STATICMAP(graph);
|
||||||
STATICARRAY(struct ir, pops);
|
static ARRAYOF(struct ir) pops;
|
||||||
STATICARRAY(struct ir, pushes);
|
static ARRAYOF(struct ir) pushes;
|
||||||
|
|
||||||
static struct ir* get_last_push(struct basicblock* bb)
|
static struct ir* get_last_push(struct basicblock* bb)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=bb->irs_count-1; i>=0; i--)
|
for (i=bb->irs.count-1; i>=0; i--)
|
||||||
{
|
{
|
||||||
struct ir* ir = bb->irs[i];
|
struct ir* ir = bb->irs.item[i];
|
||||||
|
|
||||||
if (ir->opcode == IR_PUSH)
|
if (ir->opcode == IR_PUSH)
|
||||||
return ir;
|
return ir;
|
||||||
|
@ -25,10 +25,10 @@ static struct ir* get_first_pop(struct basicblock* bb)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0; i<bb->irs_count; i++)
|
for (i=0; i<bb->irs.count; i++)
|
||||||
{
|
{
|
||||||
struct ir* irr;
|
struct ir* irr;
|
||||||
struct ir* ir = bb->irs[i];
|
struct ir* ir = bb->irs.item[i];
|
||||||
|
|
||||||
if (ir->opcode == IR_PUSH)
|
if (ir->opcode == IR_PUSH)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -55,11 +55,11 @@ static void make_bb_graph(struct procedure* proc)
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
graph_count = 0;
|
graph_count = 0;
|
||||||
for (i=0; i<proc->blocks_count; i++)
|
for (i=0; i<proc->blocks.count; i++)
|
||||||
{
|
{
|
||||||
struct basicblock* bb = proc->blocks[i];
|
struct basicblock* bb = proc->blocks.item[i];
|
||||||
for (j=0; j<bb->irs_count; j++)
|
for (j=0; j<bb->irs.count; j++)
|
||||||
ir_walk(bb->irs[j], collect_outputs_cb, bb);
|
ir_walk(bb->irs.item[j], collect_outputs_cb, bb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ static void convert_block(struct procedure* proc, struct basicblock* bb)
|
||||||
int i, j;
|
int i, j;
|
||||||
struct ir* ir;
|
struct ir* ir;
|
||||||
|
|
||||||
pushes_count = pops_count = 0;
|
pushes.count = pops.count = 0;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
struct ir* lastpush = get_last_push(bb);
|
struct ir* lastpush = get_last_push(bb);
|
||||||
|
@ -87,7 +87,7 @@ static void convert_block(struct procedure* proc, struct basicblock* bb)
|
||||||
ir = get_first_pop(outbb);
|
ir = get_first_pop(outbb);
|
||||||
if (!ir || (ir->size != lastpush->size))
|
if (!ir || (ir->size != lastpush->size))
|
||||||
return;
|
return;
|
||||||
APPENDU(pops, ir);
|
array_appendu(&pops, ir);
|
||||||
|
|
||||||
/* Also abort unless *every* predecessor block of the one we've
|
/* Also abort unless *every* predecessor block of the one we've
|
||||||
* just found *also* ends in a push of the same size. */
|
* just found *also* ends in a push of the same size. */
|
||||||
|
@ -101,7 +101,7 @@ static void convert_block(struct procedure* proc, struct basicblock* bb)
|
||||||
ir = get_last_push(inbb);
|
ir = get_last_push(inbb);
|
||||||
if (!ir || (ir->size != lastpush->size))
|
if (!ir || (ir->size != lastpush->size))
|
||||||
return;
|
return;
|
||||||
APPENDU(pushes, ir);
|
array_appendu(&pushes, ir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,22 +109,22 @@ static void convert_block(struct procedure* proc, struct basicblock* bb)
|
||||||
|
|
||||||
/* Okay, now we can wire them all up. */
|
/* Okay, now we can wire them all up. */
|
||||||
|
|
||||||
for (i=0; i<pushes_count; i++)
|
for (i=0; i<pushes.count; i++)
|
||||||
{
|
{
|
||||||
struct ir* ir = pushes[i];
|
struct ir* ir = pushes.item[i];
|
||||||
assert(ir->is_sequence);
|
assert(ir->is_sequence);
|
||||||
*ir = *ir->left;
|
*ir = *ir->left;
|
||||||
ir->is_sequence = true;
|
ir->is_sequence = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0; i<pops_count; i++)
|
for (i=0; i<pops.count; i++)
|
||||||
{
|
{
|
||||||
struct ir* ir = pops[i];
|
struct ir* ir = pops.item[i];
|
||||||
struct ir* pushir = pushes[0];
|
struct ir* pushir = pushes.item[0];
|
||||||
struct ir* phi = new_ir1(IR_PHI, ir->size, pushir);
|
struct ir* phi = new_ir1(IR_PHI, ir->size, pushir);
|
||||||
|
|
||||||
for (j=1; j<pushes_count; j++)
|
for (j=1; j<pushes.count; j++)
|
||||||
phi = new_ir2(IR_PHI, ir->size, phi, pushes[j]);
|
phi = new_ir2(IR_PHI, ir->size, phi, pushes.item[j]);
|
||||||
|
|
||||||
phi->is_sequence = ir->is_sequence;
|
phi->is_sequence = ir->is_sequence;
|
||||||
*ir = *phi;
|
*ir = *phi;
|
||||||
|
@ -138,8 +138,8 @@ void pass_convert_stack_ops(struct procedure* proc)
|
||||||
|
|
||||||
make_bb_graph(proc);
|
make_bb_graph(proc);
|
||||||
|
|
||||||
for (i=0; i<proc->blocks_count; i++)
|
for (i=0; i<proc->blocks.count; i++)
|
||||||
convert_block(proc, proc->blocks[i]);
|
convert_block(proc, proc->blocks.item[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* vim: set sw=4 ts=4 expandtab : */
|
/* vim: set sw=4 ts=4 expandtab : */
|
||||||
|
|
|
@ -6,11 +6,11 @@ static bool rewrite_jumps_cb(struct ir* ir, void* user)
|
||||||
{
|
{
|
||||||
struct basicblock* bb = ir->u.bvalue;
|
struct basicblock* bb = ir->u.bvalue;
|
||||||
if (!bb->is_fake
|
if (!bb->is_fake
|
||||||
&& (bb->irs_count > 0)
|
&& (bb->irs.count > 0)
|
||||||
&& (bb->irs[0]->opcode == IR_JUMP)
|
&& (bb->irs.item[0]->opcode == IR_JUMP)
|
||||||
&& (bb->irs[0]->left->opcode == IR_BLOCK))
|
&& (bb->irs.item[0]->left->opcode == IR_BLOCK))
|
||||||
{
|
{
|
||||||
ir->u.bvalue = bb->irs[0]->left->u.bvalue;
|
ir->u.bvalue = bb->irs.item[0]->left->u.bvalue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,9 +21,9 @@ static void rewrite_jumps(struct basicblock* bb)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0; i<bb->irs_count; i++)
|
for (i=0; i<bb->irs.count; i++)
|
||||||
{
|
{
|
||||||
struct ir* ir = bb->irs[i];
|
struct ir* ir = bb->irs.item[i];
|
||||||
ir_walk(ir, rewrite_jumps_cb, NULL);
|
ir_walk(ir, rewrite_jumps_cb, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,9 +32,9 @@ void pass_eliminate_trivial_blocks(struct procedure* proc)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0; i<proc->blocks_count; i++)
|
for (i=0; i<proc->blocks.count; i++)
|
||||||
{
|
{
|
||||||
struct basicblock* bb = proc->blocks[i];
|
struct basicblock* bb = proc->blocks.item[i];
|
||||||
rewrite_jumps(bb);
|
rewrite_jumps(bb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,10 +125,10 @@ static void select_instructions(struct basicblock* bb)
|
||||||
|
|
||||||
tracef('I', "I: BLOCK: %s\n", bb->name);
|
tracef('I', "I: BLOCK: %s\n", bb->name);
|
||||||
|
|
||||||
for (i=0; i<bb->irs_count; i++)
|
for (i=0; i<bb->irs.count; i++)
|
||||||
{
|
{
|
||||||
int insnno;
|
int insnno;
|
||||||
struct ir* ir = bb->irs[i];
|
struct ir* ir = bb->irs.item[i];
|
||||||
burm_label(ir);
|
burm_label(ir);
|
||||||
|
|
||||||
insnno = burm_rule(ir->state_label, 1);
|
insnno = burm_rule(ir->state_label, 1);
|
||||||
|
@ -145,9 +145,9 @@ void pass_instruction_selector(struct procedure* proc)
|
||||||
|
|
||||||
vregcount = 1;
|
vregcount = 1;
|
||||||
|
|
||||||
for (i=0; i<proc->blocks_count; i++)
|
for (i=0; i<proc->blocks.count; i++)
|
||||||
{
|
{
|
||||||
struct basicblock* bb = proc->blocks[i];
|
struct basicblock* bb = proc->blocks.item[i];
|
||||||
select_instructions(bb);
|
select_instructions(bb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include "mcg.h"
|
#include "mcg.h"
|
||||||
|
|
||||||
STATICARRAY(struct basicblock, used);
|
static ARRAYOF(struct basicblock) used;
|
||||||
|
|
||||||
static void walk_blocks(struct basicblock* bb);
|
static void walk_blocks(struct basicblock* bb);
|
||||||
|
|
||||||
|
@ -15,12 +15,12 @@ static void walk_blocks(struct basicblock* bb)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!CONTAINS(used, bb))
|
if (!array_contains(&used, bb))
|
||||||
{
|
{
|
||||||
APPENDU(used, bb);
|
array_append(&used, bb);
|
||||||
|
|
||||||
for (i=0; i<bb->irs_count; i++)
|
for (i=0; i<bb->irs.count; i++)
|
||||||
ir_walk(bb->irs[i], walk_blocks_cb, NULL);
|
ir_walk(bb->irs.item[i], walk_blocks_cb, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,12 +28,12 @@ void pass_remove_dead_blocks(struct procedure* proc)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
used_count = 0;
|
used.count = 0;
|
||||||
walk_blocks(proc->blocks[0]);
|
walk_blocks(proc->blocks.item[0]);
|
||||||
|
|
||||||
proc->blocks_count = 0;
|
proc->blocks.count = 0;
|
||||||
for (i=0; i<used_count; i++)
|
for (i=0; i<used.count; i++)
|
||||||
APPEND(proc->blocks, used[i]);
|
array_append(&proc->blocks, used.item[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* vim: set sw=4 ts=4 expandtab : */
|
/* vim: set sw=4 ts=4 expandtab : */
|
||||||
|
|
|
@ -43,9 +43,9 @@ static void push_types_up(struct basicblock* bb)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0; i<bb->irs_count; i++)
|
for (i=0; i<bb->irs.count; i++)
|
||||||
{
|
{
|
||||||
struct ir* ir = bb->irs[i];
|
struct ir* ir = bb->irs.item[i];
|
||||||
ir->type = search_for_type(ir, ir->type);
|
ir->type = search_for_type(ir, ir->type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,8 +54,8 @@ void pass_type_inference(struct procedure* proc)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0; i<proc->blocks_count; i++)
|
for (i=0; i<proc->blocks.count; i++)
|
||||||
push_types_up(proc->blocks[i]);
|
push_types_up(proc->blocks.item[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* vim: set sw=4 ts=4 expandtab : */
|
/* vim: set sw=4 ts=4 expandtab : */
|
||||||
|
|
|
@ -5,9 +5,9 @@ static void print_blocks(char k, struct procedure* proc)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
tracef(k, "%c: procedure %s\n", k, proc->name);
|
tracef(k, "%c: procedure %s\n", k, proc->name);
|
||||||
for (int i=0; i<proc->blocks_count; i++)
|
for (int i=0; i<proc->blocks.count; i++)
|
||||||
{
|
{
|
||||||
struct basicblock* bb = proc->blocks[i];
|
struct basicblock* bb = proc->blocks.item[i];
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
tracef(k, "%c:\n", k);
|
tracef(k, "%c:\n", k);
|
||||||
|
@ -15,8 +15,8 @@ static void print_blocks(char k, struct procedure* proc)
|
||||||
bb->is_fake ? "FAKE " : "",
|
bb->is_fake ? "FAKE " : "",
|
||||||
bb->name);
|
bb->name);
|
||||||
|
|
||||||
for (int j=0; j<bb->irs_count; j++)
|
for (int j=0; j<bb->irs.count; j++)
|
||||||
ir_print(k, bb->irs[j]);
|
ir_print(k, bb->irs.item[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ static struct ir* appendir(struct ir* ir)
|
||||||
|
|
||||||
assert(current_bb != NULL);
|
assert(current_bb != NULL);
|
||||||
ir->is_sequence = true;
|
ir->is_sequence = true;
|
||||||
APPEND(current_bb->irs, ir);
|
array_append(¤t_bb->irs, ir);
|
||||||
|
|
||||||
ir_print('0', ir);
|
ir_print('0', ir);
|
||||||
return ir;
|
return ir;
|
||||||
|
@ -323,9 +323,9 @@ static struct ir* extract_block_refs(struct basicblock* bb)
|
||||||
struct ir* outir = NULL;
|
struct ir* outir = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0; i<bb->ems_count; i++)
|
for (i=0; i<bb->ems.count; i++)
|
||||||
{
|
{
|
||||||
struct em* em = bb->ems[i];
|
struct em* em = bb->ems.item[i];
|
||||||
assert(em->opcode == op_bra);
|
assert(em->opcode == op_bra);
|
||||||
assert(em->paramtype == PARAM_BVALUE);
|
assert(em->paramtype == PARAM_BVALUE);
|
||||||
|
|
||||||
|
@ -651,9 +651,9 @@ static void generate_tree(struct basicblock* bb)
|
||||||
current_bb = bb;
|
current_bb = bb;
|
||||||
reset_stack();
|
reset_stack();
|
||||||
|
|
||||||
for (i=0; i<bb->ems_count; i++)
|
for (i=0; i<bb->ems.count; i++)
|
||||||
{
|
{
|
||||||
struct em* em = bb->ems[i];
|
struct em* em = bb->ems.item[i];
|
||||||
tracef('E', "E: read %s ", em_mnem[em->opcode - sp_fmnem]);
|
tracef('E', "E: read %s ", em_mnem[em->opcode - sp_fmnem]);
|
||||||
switch (em->paramtype)
|
switch (em->paramtype)
|
||||||
{
|
{
|
||||||
|
@ -696,8 +696,8 @@ void tb_procedure(struct procedure* current_proc)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0; i<current_proc->blocks_count; i++)
|
for (i=0; i<current_proc->blocks.count; i++)
|
||||||
generate_tree(current_proc->blocks[i]);
|
generate_tree(current_proc->blocks.item[i]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,52 +2,56 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "array.h"
|
#include "array.h"
|
||||||
|
|
||||||
void array_append(void*** array, int* count, int* max, void* value)
|
void array_append(void* arrayp, void* value)
|
||||||
{
|
{
|
||||||
if (*count == *max)
|
struct array* array = arrayp;
|
||||||
{
|
|
||||||
int newmax = (*max == 0) ? 8 : (*max * 2);
|
|
||||||
void** newarray = realloc(*array, newmax * sizeof(void*));
|
|
||||||
|
|
||||||
*max = newmax;
|
if (array->count == array->max)
|
||||||
*array = newarray;
|
{
|
||||||
|
int newmax = (array->max == 0) ? 8 : (array->max * 2);
|
||||||
|
void** newarray = realloc(array->item, newmax * sizeof(void*));
|
||||||
|
|
||||||
|
array->max = newmax;
|
||||||
|
array->item = newarray;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*array)[*count] = value;
|
array->item[array->count] = value;
|
||||||
(*count)++;
|
array->count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool array_contains(void** array, int count, void* value)
|
bool array_contains(void* arrayp, void* value)
|
||||||
{
|
{
|
||||||
|
struct array* array = arrayp;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0; i<count; i++)
|
for (i=0; i<array->count; i++)
|
||||||
if (array[i] == value)
|
if (array->item[i] == value)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void array_appendu(void*** array, int* count, int* max, void* value)
|
void array_appendu(void* arrayp, void* value)
|
||||||
{
|
{
|
||||||
if (!array_contains(*array, *count, value))
|
if (!array_contains(arrayp, value))
|
||||||
array_append(array, count, max, value);
|
array_append(arrayp, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void array_remove(void** array, int* count, void* value)
|
void array_remove(void* arrayp, void* value)
|
||||||
{
|
{
|
||||||
|
struct array* array = arrayp;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0; i<*count; i++)
|
for (i=0; i<array->count; i++)
|
||||||
{
|
{
|
||||||
if (array[i] == value)
|
if (array->item[i] == value)
|
||||||
{
|
{
|
||||||
while (i < (*count-1))
|
while (i < (array->count-1))
|
||||||
{
|
{
|
||||||
array[i] = array[i+1];
|
array->item[i] = array->item[i+1];
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
(*count)--;
|
array->count--;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,32 +1,26 @@
|
||||||
#ifndef ARRAY_H
|
#ifndef ARRAY_H
|
||||||
#define ARRAY_H
|
#define ARRAY_H
|
||||||
|
|
||||||
#define ARRAY(TYPE, NAME) \
|
/* Danger, Will Robinson! The type and the macro must be compatible. */
|
||||||
TYPE** NAME; \
|
|
||||||
int NAME##_count; \
|
|
||||||
int NAME##_max
|
|
||||||
|
|
||||||
#define STATICARRAY(TYPE, NAME) \
|
struct array
|
||||||
static TYPE** NAME; \
|
{
|
||||||
static int NAME##_count; \
|
void** item;
|
||||||
static int NAME##_max
|
int count;
|
||||||
|
int max;
|
||||||
|
};
|
||||||
|
|
||||||
#define APPEND(ARRAY, VALUE) \
|
#define ARRAYOF(TYPE) \
|
||||||
array_append((void***) &ARRAY, &ARRAY##_count, &ARRAY##_max, VALUE)
|
struct { \
|
||||||
|
TYPE** item; \
|
||||||
|
int count; \
|
||||||
|
int max; \
|
||||||
|
}
|
||||||
|
|
||||||
#define CONTAINS(ARRAY, VALUE) \
|
extern void array_append(void* array, void* value);
|
||||||
array_contains((void**) ARRAY, ARRAY##_count, VALUE)
|
extern void array_appendu(void* array, void* value);
|
||||||
|
extern void array_remove(void* array, void* value);
|
||||||
#define APPENDU(ARRAY, VALUE) \
|
extern bool array_contains(void* array, void* value);
|
||||||
array_appendu((void***) &ARRAY, &ARRAY##_count, &ARRAY##_max, VALUE)
|
|
||||||
|
|
||||||
#define REMOVE(ARRAY, VALUE) \
|
|
||||||
array_remove((void**) ARRAY, &ARRAY##_count, VALUE)
|
|
||||||
|
|
||||||
extern void array_append(void*** array, int* count, int* max, void* value);
|
|
||||||
extern bool array_contains(void** array, int count, void* value);
|
|
||||||
extern void array_appendu(void*** array, int* count, int* max, void* value);
|
|
||||||
extern void array_remove(void** array, int* count, void* value);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue