代码拉取完成,页面将自动刷新
/*
* code generator for LPC->C compiled code
*/
#include "std.h"
#ifdef LPC_TO_C
#include "lpc_incl.h"
#include "ccode.h"
#include "compiler.h"
#include "generate.h"
#define f_out compilation_output_file
static int current_num_values;
static int switch_type, string_switches, range_switches;
static int catch_number, num_functionals;
static int case_number, case_table_size;
static int foreach_depth = 0;
static int *forward_branch_ptr;
static int forward_branch_stack[100];
static int label;
static int notreached;
static int current_block;
static parse_node_t *branch_list[2];
static void c_generate_forward_branch PROT((char));
static void c_update_forward_branch_links PROT((char, parse_node_t *));
static void c_branch_backwards PROT((char, int));
static void c_update_forward_branch PROT((void));
static void c_update_branch_list PROT((parse_node_t *));
static void c_generate_loop PROT((int, parse_node_t *, parse_node_t *,
parse_node_t *));
static void c_generate_else PROT((void));
#define CURRENT_BLOCK_SIZE (prog_code - mem_block[current_block].block)
#define UPDATE_BLOCK_SIZE mem_block[current_block].current_size = CURRENT_BLOCK_SIZE
#define switch_to_block(x) { \
UPDATE_BLOCK_SIZE; \
prog_code = mem_block[x].block + mem_block[x].current_size; \
prog_code_max = mem_block[x].block + mem_block[x].max_size; \
current_block = x; \
}
typedef struct switch_table_s {
struct switch_table_s *next;
int kind;
int num_cases;
int data[1];
} switch_table_t;
static switch_table_t *switch_tables;
static int *add_switch_table P2(int, kind, int, num_cases) {
switch_table_t *st;
switch_table_t **stp;
st = (switch_table_t *)DXALLOC(sizeof(switch_table_t) + (2*num_cases - 1) * sizeof(int), TAG_COMPILER, "switch_table");
st->next = 0;
st->kind = kind;
st->num_cases = num_cases;
stp = &switch_tables;
while (*stp)
stp = &((*stp)->next);
*stp = st;
return &st->data[0];
}
static void upd_jump P2(int, addr, int, label) {
char *p;
if (!addr) return;
p = mem_block[current_block].block + addr + 10;
*p++ = label/100 + '0';
*p++ = (label/10) % 10 + '0';
*p++ = label % 10 + '0';
}
static int add_label PROT((void)) {
if (prog_code + 12 > prog_code_max) {
mem_block_t *mbp = &mem_block[current_block];
UPDATE_BLOCK_SIZE;
realloc_mem_block(mbp);
prog_code = mbp->block + mbp->current_size;
prog_code_max = mbp->block + mbp->max_size;
}
notreached = 0;
sprintf(prog_code, "label%03i:;\n", label);
prog_code += 11;
return label++;
}
static void ins_string P1(char *, s) {
int l = strlen(s);
if (notreached) return;
if (prog_code + l + 1 > prog_code_max) {
mem_block_t *mbp = &mem_block[current_block];
UPDATE_BLOCK_SIZE;
realloc_mem_block(mbp);
prog_code = mbp->block + mbp->current_size;
prog_code_max = mbp->block + mbp->max_size;
}
strcpy(prog_code, s);
prog_code += l;
}
static void ins_vstring P1V(char *, format)
{
va_list args;
char buf[1024];
V_DCL(char *format);
V_START(args, format);
V_VAR(char *, format, args);
vsprintf(buf, format, args);
va_end(args);
ins_string(buf);
}
static int ins_jump PROT((void)) {
int ret = CURRENT_BLOCK_SIZE;
if (notreached) return 0;
ins_string("goto label???;\n");
notreached = 1;
return ret;
}
static void
generate_expr_list P1(parse_node_t *, expr) {
parse_node_t *pn;
int n, flag;
if (!expr) return;
pn = expr;
flag = n = 0;
do {
if (pn->type & 1) flag = 1;
c_generate_node(pn->v.expr);
} while ((pn = pn->r.expr));
if (flag) {
pn = expr;
do {
n--;
if (pn->type & 1)
ins_vstring("c_expand_varargs(%i);\n", n);
} while ((pn = pn->r.expr));
}
}
static void
generate_lvalue_list P1(parse_node_t *, expr) {
while ((expr = expr->r.expr)) {
c_generate_node(expr->l.expr);
ins_string("c_void_assign();\n");
}
}
static void
f_quoted_string P2(FILE *, f, char *, s) {
while (1) {
switch (*s) {
case 0: return;
case '\n':
fputs("\\n", f);
s++;
break;
case '\t':
fputs("\\t", f);
s++;
break;
case '\r':
fputs("\\r", f);
s++;
break;
case '\b':
fputs("\\b", f);
s++;
break;
case '"':
fputs("\\\"", f);
s++;
break;
case '\\':
fputs("\\\\", f);
s++;
break;
default:
fputc(*s++, f);
}
}
}
void
c_generate_node P1(parse_node_t *, expr) {
if (!expr) return;
switch (expr->kind) {
case NODE_FUNCTION:
{
unsigned short num;
num = FUNCTION_TEMP(expr->v.number)->u.index;
FUNC(num)->address = generate_function(FUNC(num),
expr->r.expr, expr->l.number);
break;
}
case NODE_TERNARY_OP:
c_generate_node(expr->l.expr);
expr = expr->r.expr;
case NODE_BINARY_OP:
c_generate_node(expr->l.expr);
/* fall through */
case NODE_UNARY_OP:
c_generate_node(expr->r.expr);
/* fall through */
case NODE_OPCODE:
ins_string(instrs[expr->v.number].routine);
break;
case NODE_TERNARY_OP_1:
c_generate_node(expr->l.expr);
expr = expr->r.expr;
/* fall through */
case NODE_BINARY_OP_1:
c_generate_node(expr->l.expr);
c_generate_node(expr->r.expr);
ins_vstring(instrs[expr->v.number].routine, expr->type);
break;
case NODE_UNARY_OP_1:
c_generate_node(expr->r.expr);
/* fall through */
case NODE_OPCODE_1:
ins_vstring(instrs[expr->v.number].routine, expr->l.number);
break;
case NODE_OPCODE_2:
ins_vstring(instrs[expr->v.number].routine, expr->l.number, expr->r.number);
break;
case NODE_RETURN:
{
int n = foreach_depth;
while (n--)
ins_string("c_exit_foreach();\n");
if (expr->r.expr) {
c_generate_node(expr->r.expr);
ins_string(instrs[F_RETURN].routine);
} else ins_string(instrs[F_RETURN_ZERO].routine);
notreached = 1;
break;
}
case NODE_STRING:
ins_vstring("C_STRING(%i);\n", expr->v.number);
break;
case NODE_REAL:
ins_vstring("push_real(%f);\n", expr->v.real);
break;
case NODE_NUMBER:
ins_vstring("push_number(%i);\n", expr->v.number);
break;
case NODE_LAND_LOR:
c_generate_node(expr->l.expr);
c_generate_forward_branch(expr->v.number);
c_generate_node(expr->r.expr);
if (expr->l.expr->kind == NODE_BRANCH_LINK) {
c_update_forward_branch_links(expr->v.number,expr->l.expr);
}
else c_update_forward_branch();
break;
case NODE_BRANCH_LINK:
c_generate_node(expr->l.expr);
ins_string("BRANCH_LINK(?, ");
expr->v.number = ins_jump();
prog_code -= 2;
notreached = 0;
ins_string(");\n");
c_generate_node(expr->r.expr);
break;
case NODE_CALL_2:
generate_expr_list(expr->r.expr);
ins_vstring(instrs[expr->v.number].routine, expr->l.number >> 16,
expr->l.number & 0xffff,
(expr->r.expr ? expr->r.expr->kind : 0));
break;
case NODE_CALL_1:
generate_expr_list(expr->r.expr);
if (expr->v.number == F_CALL_FUNCTION_BY_ADDRESS){
expr->l.number = comp_def_index_map[expr->l.number];
}
ins_vstring(instrs[expr->v.number].routine, expr->l.number,
(expr->r.expr ? expr->r.expr->kind : 0));
break;
case NODE_CALL:
generate_expr_list(expr->r.expr);
ins_vstring(instrs[expr->v.number].routine, expr->l.number);
break;
case NODE_TWO_VALUES:
c_generate_node(expr->l.expr);
c_generate_node(expr->r.expr);
break;
case NODE_CONTROL_JUMP:
{
int kind = expr->v.number;
if (kind == CJ_BREAK_SWITCH) {
ins_string("break;\n");
break;
}
expr->v.expr = branch_list[kind];
expr->l.number = ins_jump();
branch_list[kind] = expr;
break;
}
case NODE_PARAMETER:
ins_vstring("C_LOCAL(%i);\n", expr->v.number + current_num_values);
break;
case NODE_PARAMETER_LVALUE:
ins_vstring("C_LVALUE(fp + %i);\n",
expr->v.number + current_num_values);
break;
case NODE_IF:
if (IS_NODE(expr->v.expr, NODE_UNARY_OP, F_NOT)) {
c_generate_node(expr->v.expr->r.expr);
c_generate_forward_branch(F_BRANCH_WHEN_NON_ZERO);
} else {
c_generate_node(expr->v.expr);
c_generate_forward_branch(F_BRANCH_WHEN_ZERO);
}
c_generate_node(expr->l.expr);
if (expr->r.expr) {
c_generate_else();
c_generate_node(expr->r.expr);
}
c_update_forward_branch();
break;
case NODE_LOOP:
c_generate_loop(expr->type, expr->v.expr, expr->l.expr, expr->r.expr);
break;
case NODE_FOREACH:
{
int tmp = 0;
c_generate_node(expr->v.expr);
if (expr->l.expr->v.number == F_GLOBAL_LVALUE) tmp |= 1;
if (expr->r.expr) {
tmp |= 4;
if (expr->r.expr->v.number == F_GLOBAL_LVALUE) tmp |= 2;
ins_vstring("c_foreach(%i, %i, %i);\n", tmp, expr->l.expr->l.number, expr->r.expr->l.number);
} else
ins_vstring("c_foreach(%i, 0, %i);\n", tmp, expr->l.expr->l.number);
}
break;
case NODE_CASE_NUMBER:
case_table_size++;
notreached = 0;
if (switch_type == NODE_SWITCH_RANGES) {
ins_vstring("case %i:;\n", case_number);
if (expr->v.expr) {
parse_node_t *other = expr->v.expr;
case_table_size++;
expr->v.number = -1;
other->l.expr = expr->l.expr;
other->v.number = case_number++;
expr->l.expr = other;
} else {
expr->v.number = case_number++;
}
} else ins_vstring("case %i:;\n", expr->r.number);
break;
case NODE_CASE_STRING:
notreached = 0;
case_table_size++;
expr->v.number = case_number;
ins_vstring("case %i:;\n", case_number++);
break;
case NODE_DEFAULT:
notreached = 0;
ins_string("default:;\n");
break;
case NODE_SWITCH_STRINGS:
case NODE_SWITCH_NUMBERS:
case NODE_SWITCH_RANGES:
case NODE_SWITCH_DIRECT:
{
int position;
parse_node_t *pn;
int save_switch_type = switch_type;
int save_case_number = case_number;
int save_case_table_size = case_table_size;
int *p, *stable;
switch_type = expr->kind;
case_number = 0;
case_table_size = 0;
position = 0;
c_generate_node(expr->l.expr);
switch (switch_type) {
case NODE_SWITCH_STRINGS:
ins_vstring("lpc_int = c_string_switch_lookup(sp, string_switch_table_%s_%02i, ", compilation_ident, string_switches++);
position = prog_code - mem_block[current_block].block;
ins_string("xxx);\nfree_string_svalue(sp--);\n");
break;
case NODE_SWITCH_DIRECT:
case NODE_SWITCH_NUMBERS:
ins_string("lpc_int = (sp--)->u.number;\n");
break;
case NODE_SWITCH_RANGES:
ins_vstring("lpc_int = c_range_switch_lookup((sp--)->u.number, range_switch_table_%s_%02i, ", compilation_ident, range_switches++);
position = prog_code - mem_block[current_block].block;
ins_string("xxx);\n");
break;
}
ins_string("switch (lpc_int) {\n");
c_generate_node(expr->r.expr);
notreached = 0;
ins_string("}\n");
if (switch_type == NODE_SWITCH_STRINGS || switch_type == NODE_SWITCH_RANGES) {
stable = p = add_switch_table(switch_type, case_table_size);
pn = expr->v.expr;
while (pn) {
if (pn->kind != NODE_DEFAULT) {
*p++ = pn->r.number;
*p++ = pn->v.number;
}
pn = pn->l.expr;
}
DEBUG_CHECK(p - stable != case_table_size * 2,
"case_table_size was incorrect.\n");
}
if (position) {
sprintf(mem_block[current_block].block + position,
"%3i", case_table_size);
/* restore the char smashed by the trailing null */
mem_block[current_block].block[position + 3] = ')';
}
switch_type = save_switch_type;
case_number = save_case_number;
case_table_size = save_case_table_size;
break;
}
case NODE_CATCH:
{
ins_vstring("{ error_context_t econ%02i;\nc_prepare_catch(&econ%02i);\nif (SETJMP(econ%02i.context)) {\nc_caught_error(&econ%02i);\n} else {\n",
catch_number, catch_number, catch_number, catch_number);
c_generate_node(expr->r.expr);
ins_vstring("c_end_catch(&econ%02i);\n}\n}\n", catch_number++);
break;
}
case NODE_TIME_EXPRESSION:
{
ins_string("{ int start_sec,start_usec,end_sec,end_usec;\nget_usec_clock(&start_sec,&start_usec);\n");
c_generate_node(expr->r.expr);
ins_string("get_usec_clock(&end_sec,&end_usec);\nend_usec=(end_sec - start_sec) * 1000000 + end_usec - start_usec;\npush_number(end_usec);\n}\n");
break;
}
case NODE_LVALUE_EFUN:
c_generate_node(expr->l.expr);
generate_lvalue_list(expr->r.expr);
break;
case NODE_FUNCTION_CONSTRUCTOR:
if (expr->r.expr) {
generate_expr_list(expr->r.expr);
ins_vstring("C_AGGREGATE(%i);\n", expr->r.expr->kind);
} else
ins_string("push_number(0);\n");
switch (expr->v.number & 0xff) {
case FP_SIMUL:
ins_vstring("c_function_constructor(%i, %i);\n",
expr->v.number & 0xff, expr->v.number >> 8);
break;
case FP_LOCAL:
ins_vstring("c_function_constructor(%i, %i);\n",
expr->v.number & 0xff, comp_def_index_map[expr->v.number >> 8]);
break;
case FP_EFUN:
ins_vstring("c_function_constructor(%i, %i);\n",
expr->v.number & 0xff, predefs[expr->v.number >> 8].token);
break;
case FP_FUNCTIONAL:
case FP_FUNCTIONAL | FP_NOT_BINDABLE:
{
int save_current_num_values = current_num_values;
int save_current_block = current_block;
ins_vstring("c_functional(%i, %i, (POINTER_INT)LPCFUNCTIONAL_%03i);\n",
expr->v.number & 0xff, expr->v.number >> 8, num_functionals);
current_num_values = expr->r.expr ? expr->r.expr->kind : 0;
switch_to_block(A_FUNCTIONALS);
ins_vstring("static void LPCFUNCTIONAL_%03i PROT((void)) {\n", num_functionals++);
c_generate_node(expr->l.expr);
ins_vstring("c_return();\n}\n\n");
switch_to_block(save_current_block);
current_num_values = save_current_num_values;
break;
}
}
break;
case NODE_ANON_FUNC:
{
int save_fd = foreach_depth;
int save_current_block = current_block;
int save_notreached = notreached;
foreach_depth = 0;
ins_vstring("c_anonymous(%i, %i, (POINTER_INT)LPCFUNCTIONAL_%03i);\n",
expr->v.number, expr->l.number, num_functionals);
switch_to_block(A_FUNCTIONALS);
ins_vstring("void LPCFUNCTIONAL_%03i PROT((void)) {\n", num_functionals++);
c_generate_node(expr->r.expr);
notreached = 0;
ins_string("\n}\n\n");
switch_to_block(save_current_block);
foreach_depth = save_fd;
notreached = save_notreached;
break;
}
case NODE_EFUN:
{
parse_node_t *node = expr->r.expr;
int num_arg = expr->l.number;
int novalue_used = expr->v.number & NOVALUE_USED_FLAG;
int f = expr->v.number & ~NOVALUE_USED_FLAG;
int idx = 1;
generate_expr_list(node);
while (node) {
if (idx == 5) break;
ins_vstring("CHECK_TYPES(sp - %i, %i, %i, %i);\n",
num_arg - idx, instrs[f].type[idx - 1],
idx, f);
idx++;
node = node->r.expr;
}
if (instrs[f].max_arg == -1) {
ins_vstring("st_num_arg = %i + num_varargs;\nnum_varargs = 0;\n", num_arg);
} else {
ins_vstring("st_num_arg = %i;\n", num_arg);
}
ins_vstring("f_%s();\n", instrs[f].name);
if (novalue_used) {
/* the value of a void efun was used. Put in a zero. */
ins_string("push_number(0);\n");
}
}
break;
default:
fatal("Unknown node %i in c_generate_node.\n", expr->kind);
}
}
static void c_generate_loop P4(int, test_first, parse_node_t *, block,
parse_node_t *, inc, parse_node_t *, test) {
parse_node_t *save_breaks = branch_list[CJ_BREAK];
parse_node_t *save_continues = branch_list[CJ_CONTINUE];
int forever = node_always_true(test);
int pos;
if (test_first == 2) foreach_depth++;
branch_list[CJ_BREAK] = branch_list[CJ_CONTINUE] = 0;
if (!forever && test_first)
c_generate_forward_branch(F_BRANCH);
pos = add_label();
c_generate_node(block);
c_update_branch_list(branch_list[CJ_CONTINUE]);
if (inc) c_generate_node(inc);
if (!forever && test_first)
c_update_forward_branch();
if (test && (test->v.number == F_LOOP_COND_LOCAL ||
test->v.number == F_LOOP_COND_NUMBER)) {
c_generate_node(test);
ins_vstring("goto label%03i;\n", pos);
} else {
if (test_first == 2)
ins_vstring("if (c_next_foreach())\ngoto label%03i;\n", pos);
else
c_branch_backwards(generate_conditional_branch(test), pos);
}
c_update_branch_list(branch_list[CJ_BREAK]);
branch_list[CJ_BREAK] = save_breaks;
branch_list[CJ_CONTINUE] = save_continues;
if (test_first == 2) foreach_depth--;
}
void
c_generate_inherited_init_call P2(int, index, short, f) {
ins_vstring("c_call_inherited(%i, %i, 0);\npop_stack();\n", index, (int)f);
}
void c_start_function P1(char *, fname) {
notreached = 0;
if (fname[0] == APPLY___INIT_SPECIAL_CHAR)
ins_vstring("static void LPC_%s__LPCinit() {\n",
compilation_ident);
else
ins_vstring("static void LPC_%s__%s() {\n", compilation_ident, fname);
}
void c_end_function() {
notreached = 0;
ins_string("}\n\n");
}
void c_generate___INIT() {
}
static void c_generate_forward_branch P1(char, b) {
switch (b) {
case F_LAND:
ins_string("C_LAND(");
break;
case F_LOR:
ins_string("C_LOR(");
break;
case F_BRANCH_WHEN_NON_ZERO:
ins_string("C_BRANCH_WHEN_NON_ZERO(");
break;
case F_BRANCH_WHEN_ZERO:
ins_string("C_BRANCH_WHEN_ZERO(");
break;
case F_BRANCH:
*forward_branch_ptr++ = ins_jump();
case 0:
return;
break;
default:
fatal("Unknown opcode %i in generate_forward_branch\n", (int)b);
}
*forward_branch_ptr++ = ins_jump();
prog_code -= 2;
notreached = 0;
ins_string(");\n");
}
static void
c_update_forward_branch() {
int i = *--forward_branch_ptr;
upd_jump(i, label);
add_label();
}
static void c_update_forward_branch_links P2(char, kind, parse_node_t *, link_start) {
int i = *--forward_branch_ptr;
int our_label;
char *p;
upd_jump(i, our_label = add_label());
do {
i = link_start->v.number;
p = mem_block[current_block].block + i - 3;
if (kind == F_LOR)
*p = '!';
else
*p = ' ';
upd_jump(i, our_label);
link_start = link_start->l.expr;
} while (link_start->kind == NODE_BRANCH_LINK);
}
static void
c_branch_backwards P2(char, b, int, addr) {
switch (b) {
case F_BBRANCH_WHEN_ZERO:
ins_vstring("C_BRANCH_WHEN_ZERO(goto label%03i);\n", addr);
break;
case F_BBRANCH_WHEN_NON_ZERO:
ins_vstring("C_BRANCH_WHEN_NON_ZERO(goto label%03i);\n", addr);
break;
case F_BBRANCH:
ins_vstring("goto label%03i;\n", addr);
notreached = 1;
break;
case F_BBRANCH_LT:
ins_vstring("C_BBRANCH_LT(goto label%03i);\n", addr);
break;
case F_WHILE_DEC:
ins_vstring("goto label%03i;\n", addr);
}
}
static void
c_update_branch_list P1(parse_node_t *, bl) {
if (bl) {
do {
upd_jump(bl->l.number, label);
} while ((bl = bl->v.expr));
add_label();
}
}
static void
c_generate_else() {
int tmp = ins_jump();
upd_jump(forward_branch_ptr[-1], label);
add_label();
forward_branch_ptr[-1] = tmp;
}
void
c_initialize_parser() {
branch_list[CJ_BREAK] = 0;
branch_list[CJ_CONTINUE] = 0;
forward_branch_ptr = &forward_branch_stack[0];
foreach_depth = 0;
current_block = A_PROGRAM;
prog_code = mem_block[A_PROGRAM].block;
prog_code_max = mem_block[A_PROGRAM].block + mem_block[A_PROGRAM].max_size;
num_functionals = catch_number = string_switches = range_switches = 0;
switch_tables = 0;
label = 0;
notreached = 0;
}
void
c_uninitialize_parser() {
}
#if 0
static char *protect_allocated_string = 0;
static char *
protect P1(char *, str) {
static char buf[1024];
char *p;
int size = 0;
if (protect_allocated_string)
FREE(protect_allocated_string);
p = str;
while (*p) {
if (*p == '"' || *p == '\\') size += 2;
else size++;
p++;
}
if (size < 1024) {
p = buf;
while (*str) {
if (*str == '"' || *str == '\\') *p++ = '\\';
*p++ = *str++;
}
*p = 0;
return buf;
} else {
p = protect_allocated_string = DXALLOC(size + 1, TAG_STRING, "protect");
while (*str) {
if (*str == '"' || *str == '\\') *p++ = '\\';
*p++ = *str++;
}
*p++ = 0;
return protect_allocated_string;
}
}
#endif
void
c_generate_final_program P1(int, x) {
switch_table_t *st, *next;
int i;
int index = 0;
int num_func;
if (!x) {
if (string_switches) {
st = switch_tables;
while (st) {
if (st->kind == NODE_SWITCH_STRINGS) {
fprintf(f_out, "static string_switch_entry_t string_switch_table_%s_%02i[] = {\n", compilation_ident, index++);
for (i = 0; i < st->num_cases; i++) {
fprintf(f_out, "{\"");
f_quoted_string(f_out, PROG_STRING(st->data[i*2]));
fprintf(f_out, "\", %i },\n", st->data[i*2+1]);
}
fprintf(f_out, "{ 0, 0 }\n};\n\n");
}
st = st->next;
}
fprintf(f_out, "static string_switch_entry_t *string_switch_tables[] = {\n");
for (i = 0; i < index; i++)
fprintf(f_out, "string_switch_table_%s_%02i,\n", compilation_ident, i);
fprintf(f_out, "0\n};\n\n");
}
if (range_switches) {
index = 0;
st = switch_tables;
while (st) {
if (st->kind == NODE_SWITCH_RANGES) {
fprintf(f_out, "static range_switch_entry_t range_switch_table_%s_%02i[] = {\n", compilation_ident, index++);
for (i = 0; i < st->num_cases; i++) {
fprintf(f_out, "{ %i, %i },\n",
st->data[i*2], st->data[i*2+1]);
}
fprintf(f_out, "{ 0, -2 }\n};\n\n");
}
st = st->next;
}
fprintf(f_out, "static range_switch_entry_t *range_switch_tables_%s[] = {\n", compilation_ident);
for (i = 0; i < index; i++)
fprintf(f_out, "range_switch_table_%s_%02i,\n", compilation_ident, i);
fprintf(f_out, "};\n\n");
}
st = switch_tables;
while (st) {
next = st->next;
FREE((char *)st);
st = next;
}
fwrite(mem_block[A_FUNCTIONALS].block,
mem_block[A_FUNCTIONALS].current_size, 1, f_out);
UPDATE_PROGRAM_SIZE;
fwrite(mem_block[A_PROGRAM].block,
mem_block[A_PROGRAM].current_size, 1, f_out);
current_block = A_PROGRAM;
prog_code = mem_block[A_PROGRAM].block;
fprintf(f_out, "\n\nstatic void (*functions[])() = {\n");
num_func = mem_block[A_FUNCTIONS].current_size/sizeof(function_t);
while (num_func &&
FUNC(func_index_map[num_func - 1])->address == USHRT_MAX)
num_func--;
for (i = 0; i < num_func; i++){
char *func_name = FUNC(func_index_map[i])->name;
if (!FUNC(func_index_map[i])->address)
continue;
if (func_name[0] == APPLY___INIT_SPECIAL_CHAR)
fprintf(f_out, "LPC_%s__LPCinit,\n", compilation_ident);
else
fprintf(f_out, "LPC_%s__%s,\n", compilation_ident,
FUNC(func_index_map[i])->name);
}
fprintf(f_out, "0\n};\n");
{
char buf[1024];
int l;
strcpy(buf, current_file);
l = strlen(current_file);
if (buf[l-1] == 'c' && buf[l-2] == '.')
buf[l-2] = 0;
fprintf(f_out, "\ninterface_t LPCINFO_%s = {\n \"%s\",\n",
compilation_ident, buf);
}
fprintf(f_out, " functions,\n");
if (string_switches)
fprintf(f_out, " string_switch_tables\n};\n");
else
fprintf(f_out, " 0\n};\n");
}
}
void c_analyze P1(parse_node_t *, node) {
/* future work */
}
#endif
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。