cvsuser 03/11/03 16:03:52
Modified: imcc imc.h class.c imcc.y instructions.c
Log:
Some IMCC cleanup in preparation for rework.
Revision Changes Path
1.52 +1 -0 parrot/imcc/imc.h
Index: imc.h
===================================================================
RCS file: /cvs/public/parrot/imcc/imc.h,v
retrieving revision 1.51
retrieving revision 1.52
diff -u -w -r1.51 -r1.52
--- imc.h 27 Oct 2003 07:26:52 -0000 1.51
+++ imc.h 4 Nov 2003 00:03:52 -0000 1.52
@@ -46,6 +46,7 @@
#define MAX_COLOR NUM_REGISTERS
void imc_compile_unit(struct Parrot_Interp *, Instruction * unit);
+
void free_reglist(struct Parrot_Interp *);
const char * get_neg_op(char *op, int *nargs);
1.4 +13 -0 parrot/imcc/class.c
Index: class.c
===================================================================
RCS file: /cvs/public/parrot/imcc/class.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -w -r1.3 -r1.4
--- class.c 31 Oct 2003 03:51:09 -0000 1.3
+++ class.c 4 Nov 2003 00:03:52 -0000 1.4
@@ -8,6 +8,7 @@
* Class management. Really quick and dirty.
*/
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -24,6 +25,15 @@
return cl;
}
+Method * new_method(Symbol * sym, Symbol * label)
+{
+ Method * meth = calloc(1, sizeof(Method));
+ sym->symtype = SYMTYPE_METHOD;
+ meth->sym = sym;
+ meth->label = label;
+ sym->p = (void*)meth;
+ return meth;
+}
/*
* XXX: I suppose this is inadequate since there are
@@ -32,6 +42,9 @@
*/
void store_field_symbol(Class * cl, Symbol * sym)
{
+#if 0
+ fprintf(stderr, "%s.store_field_symbol %s\n", cl->sym->name, sym->name);
+#endif
sym->symtype = SYMTYPE_FIELD;
store_symbol(cl->members, sym);
}
1.104 +91 -27 parrot/imcc/imcc.y
Index: imcc.y
===================================================================
RCS file: /cvs/public/parrot/imcc/imcc.y,v
retrieving revision 1.103
retrieving revision 1.104
diff -u -w -r1.103 -r1.104
--- imcc.y 27 Oct 2003 06:39:20 -0000 1.103
+++ imcc.y 4 Nov 2003 00:03:52 -0000 1.104
@@ -257,16 +257,16 @@
%%
-program: { open_comp_unit(); $$ = 0;}
- compilation_units { close_comp_unit(interp); $$ = 0; }
+program: { /*imc_open_unit();*/ $$ = 0;}
+ compilation_units { /*imc_close_unit(interp);*/ $$ = 0; }
;
compilation_unit:
- class
- | sub
- | pcc_sub
- | emit
- | MACRO '\n' { $$ = 0; }
+ class { $$ = $1; imc_close_unit(interp); }
+ | sub { $$ = $1; imc_close_unit(interp); }
+ | pcc_sub { $$ = $1; imc_close_unit(interp); }
+ | emit { $$ = $1; imc_close_unit(interp); }
+ | MACRO '\n' { $$ = 0; imc_close_unit(interp); }
| '\n' { $$ = 0; }
;
@@ -289,8 +289,7 @@
free($2); }
| PCC_SUB LABEL {
char *name = str_dup($2);
- $$ = iSUBROUTINE(
- mk_address($2, U_add_uniq_sub));
+ $$ = iSUBROUTINE(mk_address($2, U_add_uniq_sub));
$$->r[1] = mk_pcc_sub(name, 0);
}
| /* none */ { $$ = 0;}
@@ -301,26 +300,85 @@
;
emit:
- EMIT { open_comp_unit();
- function = "(emit)"; }
+ EMIT { imc_open_unit(IMC_PASM);
+ function = "(emit)";
+ }
pasmcode
EOM { if (optimizer_level & OPT_PASM)
imc_compile_unit(interp,
instructions);
- emit_flush(interp); $$=0;}
+ emit_flush(interp);
+ $$=0;
+ }
;
class:
CLASS IDENTIFIER
{
Symbol * sym = new_symbol($2);
+
+ imc_open_unit(IMC_CLASS);
+
current_class = new_class(sym);
sym->p = (void*)current_class;
store_symbol(&global_sym_tab, sym);
}
'\n' class_body ENDCLASS
{
- $$ = 0;
+ /* XXX EVIL XXX
+ * Don't look behind the curtain, the wizard is fat and ugly.
+ * After 0.0.12 IMCC gets a long overdue rewrite. I
+ * just want a quick hack for 0.0.12 for "fake" classes
+ * We are using SymReg where we should be using Symbols
+ * and the APIs are done all wrong and we are doing all sorts
+ * of backflips. (And its my fault -Melvin)
+ */
+ SymbolList * list;
+ char buf[256];
+ SymReg * t1;
+ SymReg * p0 = mk_pasm_reg(str_dup("P0"));
+ sprintf(buf, "\"%s\"", $2);
+ t1 = mk_const(str_dup(buf), 'S');
+
+ /* make class and store PMC globally */
+ iNEW(interp, p0, str_dup("PerlHash"), NULL, 1);
+ MK_I(interp, "store_global", 2, t1, p0);
+
+ /* foreach class.members generate */
+ list = symtab_to_symlist(current_class->members);
+ {
+ Symbol * s;
+ SymReg * t2;
+ for(s = list->head; s; s = s->nextinlist) {
+ if(s->symtype == SYMTYPE_FIELD) {
+ sprintf(buf, "\"%s\"", s->name);
+ t1 = mk_const(str_dup(buf), 'S');
+ if(s->type == 'I' || s->type == 'N') {
+ t2 = mk_const(str_dup("0"), s->type);
+ iINDEXSET(interp, p0, t1, t2);
+ }
+ else if(s->type == 'S') {
+ t2 = mk_const(str_dup("\"\""), s->type);
+ iINDEXSET(interp, p0, t1, t2);
+ }
+ else {
+
+ }
+ }
+ else if(s->symtype == SYMTYPE_METHOD) {
+ SymReg * p1;
+ sprintf(buf, "\"%s\"", s->name);
+ t1 = mk_const(str_dup(buf), 'S');
+ p1 = mk_pasm_reg(str_dup("P1"));
+ iNEWSUB(interp, p1, NEWSUB,
+ mk_address(((Method*)s->p)->label->name, U_add_once), 1);
+ iINDEXSET(interp, p0, t1, p1);
+ }
+ }
+ }
+ MK_I(interp, "end" ,0);
+ emit_flush(interp);
current_class = NULL;
+ $$ = 0;
}
;
@@ -349,20 +407,23 @@
"field '%s' previously declared in class '%s'\n",
$3, current_class->sym->name);
}
+ sym->type = $2;
store_field_symbol(current_class, sym);
$$ = 0;
}
;
method_decl:
- METHOD IDENTIFIER '\n'
+ METHOD IDENTIFIER IDENTIFIER '\n'
{
+ Method * meth;
Symbol * sym = new_symbol($2);
if(lookup_method_symbol(current_class, $2)) {
fataly(EX_SOFTWARE, sourcefile, line,
"method '%s' previously declared in class '%s'\n",
$2, current_class->sym->name);
}
+ meth = new_method(sym, new_symbol($3));
store_method_symbol(current_class, sym);
$$ = 0;
}
@@ -381,13 +442,16 @@
}
;
-sub_start: SUB { open_comp_unit(); }
+sub_start:
+ SUB { imc_open_unit(IMC_SUB); }
IDENTIFIER '\n'
{ $$ = 0;
iSUBROUTINE(mk_address($3, U_add_uniq_sub));
}
;
-pcc_sub: PCC_SUB { open_comp_unit(); }
+
+pcc_sub:
+ PCC_SUB { imc_open_unit(IMC_SUB); }
IDENTIFIER pcc_sub_proto '\n'
{
char *name = str_dup($3);
1.47 +96 -34 parrot/imcc/instructions.c
Index: instructions.c
===================================================================
RCS file: /cvs/public/parrot/imcc/instructions.c,v
retrieving revision 1.46
retrieving revision 1.47
diff -u -w -r1.46 -r1.47
--- instructions.c 23 Oct 2003 17:02:49 -0000 1.46
+++ instructions.c 4 Nov 2003 00:03:52 -0000 1.47
@@ -22,25 +22,68 @@
/* Global variables , forward def */
+static IMC_Unit * imc_units;
+static IMC_Unit * cur_unit;
+
+static Instruction * last_ins;
+
+int n_comp_units;
+
+static int e_file_open(void *);
+static int e_file_close(void *);
+static int e_file_emit(void *param, Instruction *);
+
+Emitter emitters[2] = {
+ {e_file_open, e_file_emit, (int (*)(void *))NULLfunc, e_file_close},
+ {e_pbc_open, e_pbc_emit, e_pbc_new_sub, e_pbc_close},
+};
+
+static int emitter;
+
/* all code is collected in compilation units, which may be:
* - .sub/.end
* - .emit/.eom
* - stuff outside of these
*/
-static Instruction * last_ins;
-int n_comp_units;
+/*
+ * Create a new IMC_Unit.
+ */
+IMC_Unit *
+imc_new_unit(IMC_Unit_Type t)
+{
+ IMC_Unit * unit = calloc(1, sizeof(IMC_Unit));
+ unit->type = t;
+ return unit;
+}
-void
-open_comp_unit(void)
+/*
+ * Create a new IMC_Unit and "open" it for construction.
+ * This sets the current state of the parser. The unit
+ * can be closed later retaining all the current state.
+ */
+IMC_Unit *
+imc_open_unit(IMC_Unit_Type t)
{
+ IMC_Unit * unit;
+ unit = imc_new_unit(t);
+ if(!cur_unit)
+ imc_units = unit;
+ unit->prev = cur_unit;
+ if(cur_unit)
+ cur_unit->next = unit;
+ cur_unit = unit;
n_comp_units++;
+#if 0
+ fprintf(stderr, "imc_open_unit()\n");
+#endif
+ return cur_unit;
}
void
-close_comp_unit(Parrot_Interp interpreter)
+imc_close_unit(Parrot_Interp interpreter)
{
free_reglist(interpreter);
clear_basic_blocks(interpreter); /* and cfg ... */
@@ -48,13 +91,17 @@
fatal(1, "close_comp_unit", "non existent comp_unit\n");
n_comp_units--;
clear_tables(interpreter, hash);
+#if 0
+ fprintf(stderr, "imc_close_unit()\n");
+#endif
instructions = last_ins = NULL;
}
/* Creates a new instruction */
-Instruction * _mk_instruction(const char *op, const char * fmt,
+Instruction *
+_mk_instruction(const char *op, const char * fmt,
SymReg ** r, int flags)
{
int i;
@@ -151,7 +198,8 @@
#ifdef HAS_INLINE
inline
#endif
-int instruction_reads(Instruction* ins, SymReg* r) {
+int
+instruction_reads(Instruction* ins, SymReg* r) {
int f, i;
SymReg *key;
SymReg *ri;
@@ -181,7 +229,8 @@
#ifdef HAS_INLINE
inline
#endif
-int instruction_writes(Instruction* ins, SymReg* r) {
+int
+instruction_writes(Instruction* ins, SymReg* r) {
int f, i;
f = ins->flags;
@@ -200,7 +249,8 @@
}
/* get the reg no of address, where a branch targets to */
-int get_branch_regno(Instruction * ins)
+int
+get_branch_regno(Instruction * ins)
{
int j;
for (j = ins->opsize - 2; j >= 0 && ins->r[j] ; --j)
@@ -210,7 +260,8 @@
}
/* get the reg no of address, where a branch targets to */
-SymReg *get_branch_reg(Instruction * ins)
+SymReg *
+get_branch_reg(Instruction * ins)
{
int r = get_branch_regno(ins);
if (r >= 0)
@@ -224,7 +275,8 @@
* delete and free *ins
* actual new ins is returned
*/
-Instruction * delete_ins(Instruction *ins, int needs_freeing)
+Instruction *
+delete_ins(Instruction *ins, int needs_freeing)
{
Instruction *next, *prev;
@@ -245,7 +297,8 @@
* insert tmp after ins
*/
-void insert_ins(Instruction *ins, Instruction * tmp)
+void
+insert_ins(Instruction *ins, Instruction * tmp)
{
Instruction *next;
if (!ins) {
@@ -271,7 +324,8 @@
* subst tmp for ins
*/
-void subst_ins(Instruction *ins, Instruction * tmp, int needs_freeing)
+void
+subst_ins(Instruction *ins, Instruction * tmp, int needs_freeing)
{
Instruction *prev = ins->prev;
if (prev)
@@ -287,8 +341,10 @@
if (needs_freeing)
free_ins(ins);
}
+
/* move instruction ins to to */
-Instruction *move_ins(Instruction *ins, Instruction *to)
+Instruction *
+move_ins(Instruction *ins, Instruction *to)
{
Instruction *next = delete_ins(ins, 0);
insert_ins(to, ins);
@@ -297,7 +353,9 @@
/* Emits the instructions buffered in 'instructions' */
-Instruction * emitb(Instruction * i) {
+Instruction *
+emitb(Instruction * i)
+{
if (!i)
return 0;
@@ -312,7 +370,8 @@
return i;
}
-void free_ins(Instruction *ins)
+void
+free_ins(Instruction *ins)
{
free(ins->fmt);
free(ins->op);
@@ -320,8 +379,9 @@
}
-int ins_print(FILE *fd, Instruction * ins) {
-
+int
+ins_print(FILE *fd, Instruction * ins)
+{
char regb[IMCC_MAX_REGS][256]; /* XXX */
/* only long key constants can overflow */
char *regstr[IMCC_MAX_REGS];
@@ -406,7 +466,8 @@
/* for debug */
static char *output;
-static int e_file_open(void *param)
+static int
+e_file_open(void *param)
{
char *file = (char *) param;
@@ -416,16 +477,19 @@
return 1;
}
-static int e_file_close(void *param) {
+static int
+e_file_close(void *param)
+{
struct Parrot_Interp *interpreter = (struct Parrot_Interp *)param;
printf("\n\n");
fclose(stdout);
info(interpreter, 1, "assembly module %s written.\n", output);
return 0;
-
}
-static int e_file_emit(void *param, Instruction * ins) {
+static int
+e_file_emit(void *param, Instruction * ins)
+{
UNUSED(param);
if ((ins->type & ITLABEL) || ! *ins->op)
ins_print(stdout, ins);
@@ -436,14 +500,8 @@
return 0;
}
-Emitter emitters[2] = {
- {e_file_open, e_file_emit, (int (*)(void *))NULLfunc, e_file_close},
- {e_pbc_open, e_pbc_emit, e_pbc_new_sub, e_pbc_close},
-};
-
-static int emitter;
-
-int emit_open(int type, void *param)
+int
+emit_open(int type, void *param)
{
emitter = type;
has_compile = 0;
@@ -451,8 +509,9 @@
return (emitters[emitter]).open(param);
}
-int emit_flush(void *param) {
-
+int
+emit_flush(void *param)
+{
Instruction * ins, *next;
struct Parrot_Interp *interpreter = (struct Parrot_Interp *)param;
if (emitters[emitter].new_sub)
@@ -466,13 +525,16 @@
free_ins(ins);
ins = next;
}
- close_comp_unit(interpreter);
+ /*imc_close_unit(interpreter);*/
return 0;
}
-int emit_close(void *param)
+
+int
+emit_close(void *param)
{
return (emitters[emitter]).close(param);
}
+
/*
* Local variables:
* c-indentation-style: bsd