Author: kjs
Date: Tue Dec 2 12:39:42 2008
New Revision: 33446
Modified:
trunk/compilers/pirc/new/bcgen.c
Log:
[pirc] more bcgen work. this whole thing needs more thought and work, but this
is a start.
Modified: trunk/compilers/pirc/new/bcgen.c
==============================================================================
--- trunk/compilers/pirc/new/bcgen.c (original)
+++ trunk/compilers/pirc/new/bcgen.c Tue Dec 2 12:39:42 2008
@@ -24,11 +24,11 @@
/* Note that typedef of struct bytecode is already done in the header file */
struct bytecode {
- int num_constants;
- bc_const *constants;
- PackFile *packfile;
- opcode_t *opcursor;
- Interp *interp;
+ int num_constants; /* for assigning indices to the constants,
also counter. */
+ bc_const *constants; /* list of constants */
+ PackFile *packfile; /* the actual packfile */
+ opcode_t *opcursor; /* for writing ops into the code segment */
+ Interp *interp; /* parrot interpreter */
};
@@ -91,6 +91,32 @@
/*
+Add a number constant to the constants list.
+
+*/
+bc_const *
+add_num_const(bytecode * const bc, FLOATVAL f) {
+ bc_const *bcc = new_const(bc);
+ bcc->value->type = PFC_NUMBER;
+ bcc->value->u.number = f;
+ return bcc;
+}
+
+/*
+
+Add a key constant to the constants list.
+
+*/
+bc_const *
+add_key_const(bytecode * const bc, PMC *key) {
+ bc_const *bcc = new_const(bc);
+ bcc->value->type = PFC_KEY;
+ bcc->value->u.key = key;
+ return bcc;
+}
+
+/*
+
=item new_bytecode
Create a new bytecode struct and return a pointer to it.
@@ -99,10 +125,9 @@
*/
bytecode *
-new_bytecode(Interp *interp, char const * const filename) {
+new_bytecode(Interp *interp, char const * const filename, int bytes, int
codesize) {
PMC *self;
bytecode *bc = (bytecode *)mem_sys_allocate(sizeof (bytecode));
- int bytes = 12;
bc->packfile = PackFile_new(interp, 0);
bc->constants = NULL;
@@ -119,7 +144,7 @@
add_pmc_const(bc, self);
interp->code->base.data = (opcode_t
*)mem_sys_realloc(interp->code->base.data, bytes);
- interp->code->base.size = 3;
+ interp->code->base.size = codesize;
/* initialize the cursor to write opcodes into the code segment */
bc->opcursor = (opcode_t *)interp->code->base.data;
@@ -165,6 +190,18 @@
emit_opcode(bc, op);
}
+/*
+
+XXX think of better name.
+Add a string constant to the constants list, and return the STRING variant
+
+*/
+static STRING *
+add_string_const_from_cstring(bytecode * const bc, char const * const str) {
+ bc_const *strconst = add_string_const(bc, str);
+ return strconst->value->u.string;
+}
+
/*
@@ -172,14 +209,26 @@
*/
static void
-add_sub_pmc(bytecode * const bc, char const * const subname) {
+add_sub_pmc(bytecode * const bc,
+ char const * const subname, /* .sub foo --> "foo" */
+ char const * const nsentry, /* .sub foo :nsentry('bar') --> "bar"
*/
+ char const * const subid, /* .sub foo :subid('baz') --> "baz" */
+ int vtable_index, /* vtable entry index */
+ int regs_used[]) /* register usage */
+{
Interp *interp = bc->interp;
PMC *sub_pmc = pmc_new(bc->interp, enum_class_Sub);
Parrot_sub *sub = PMC_sub(sub_pmc);
bc_const *subconst;
+ bc_const *subname_const;
+
int i;
- bc_const *subid = add_string_const(bc, subname);
+
+
+
+ subname_const = add_string_const(bc, subname);
+
sub->start_offs = 0;
sub->end_offs = 3;
@@ -188,21 +237,45 @@
sub->lex_info = NULL;
sub->outer_sub = NULL;
- sub->vtable_index = -1;
+ sub->vtable_index = vtable_index;
sub->multi_signature = NULL;
for (i = 0; i < 4; ++i)
- sub->n_regs_used[i] = 0;
+ sub->n_regs_used[i] = regs_used[i];
+
+ sub->name = subname_const->value->u.string;
+
+ /* If there was a :nsentry, add it to the constants table, and set
+ * the ns_entry_name attribute to that STRING. Default value is the sub's
name.
+ */
+ if (nsentry)
+ sub->ns_entry_name = add_string_const_from_cstring(bc, nsentry);
+ else
+ sub->ns_entry_name = subname_const->value->u.string;
+
+ /* if there was a :subid, add it to the constants table, and set the subid
+ * attribute to that STRING. Default value is the sub's name.
+ */
+ if (subid)
+ sub->subid = add_string_const_from_cstring(bc, subid);
+ else
+ sub->subid = subname_const->value->u.string;
- sub->name = subid->value->u.string;
- sub->ns_entry_name = subid->value->u.string;
- sub->subid = subid->value->u.string;
- subconst = add_pmc_const(bc, sub_pmc);
Parrot_store_sub_in_namespace(bc->interp, sub_pmc);
- /* PackFile_FixupTable_new_entry(bc->interp, subname, enum_fixup_sub,
subconst->index);
- */ /* doesn't
work?? */
+ subconst = add_pmc_const(bc, sub_pmc);
+
+ fprintf(stderr, "subconst index: %d\n", subconst->index);
+
+ /* doesn't work?? */
+
+ /* this /does/ work in pirc/bctest.c!! Why not here??
+ */
+ /*
+ PackFile_FixupTable_new_entry(bc->interp, "main", enum_fixup_sub,
subconst->index);
+ */
+
}
/*
@@ -272,13 +345,14 @@
int
main(int argc, char **argv) {
Interp *interp = Parrot_new(NULL);
- bytecode *bc = new_bytecode(interp, "test.pir");
-
+ bytecode *bc = new_bytecode(interp, "test.pir", 12, 3);
+ int regs_used[4] = {0,0,0,0};
+ add_sub_pmc(bc, "main", NULL, NULL, -1, regs_used);
emit_op_by_name(bc, "print_ic");
emit_int_arg(bc, 42);
emit_op_by_name(bc, "end");
- add_sub_pmc(bc, "main");
+
fprintf(stderr, "writing pbc...");
write_pbc_file(bc, "test.pbc");