# New Ticket Created by  Leopold Toetsch 
# Please include the string:  [perl #20315]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org/rt2/Ticket/Display.html?id=20315 >


Attached is a first try towards eval.

- interpreter has a new data member Parrot_compreg_hash
- parrot registers the PASM1 type i.e. what PDB_eval can parse
- the new B<compile> opcode (ab)uses nci to build a function for calling 
PDB_eval
- nci is extended (jit/i386 only), to understand an 'I' param as interpreter
- the string is evaled immediately, we don't have multiple byte code 
segments yet

No registers, which nci uses, are preserved, no error checking and so 
on, but works ;-)

Some questions arise here:
- Should the B<compreg> opcode also have a form with a label to build 
PASM compilers, ook?
- is using the NCI interface ok for evals purpose?
- how should a byte code segment (PMC) look like?

Comment welcome
leo


-- attachment  1 ------------------------------------------------------
url: http://rt.perl.org/rt2/attach/48556/37739/ade5a5/eval.patch

--- parrot/classes/csub.pmc     Fri Jan 10 18:05:02 2003
+++ parrot-leo/classes/csub.pmc Tue Jan 14 19:06:24 2003
@@ -49,7 +49,7 @@
         return SELF->cache.struct_val != NULL;
     }
 
-    void * invoke (void * next) {
+    void* invoke (void * next) {
         Parrot_csub_t func = (Parrot_csub_t)SELF->cache.struct_val;
         func(INTERP, SELF);
         return next;
--- parrot/core.ops     Tue Jan 14 09:09:55 2003
+++ parrot-leo/core.ops Tue Jan 14 19:25:19 2003
@@ -4485,6 +4485,10 @@
 
 Call the subroutine in P0, as described in PDD03.
 
+=item B<compile>(out PMC, in STR, in STR)
+
+Compile source code $2 of a registered source type $3 into PMC $1.
+
 =cut
 
 inline op loadext(in STR, in STR) {
@@ -4547,6 +4551,19 @@
 
   goto ADDRESS(dest);
 }
+
+inline op compile(OUT PMC, in STR, in STR) {
+  opcode_t *dest;
+  PMC *key = key_new_string(interpreter, $3);
+  PMC *func = interpreter->Parrot_compreg_hash->vtable->get_pmc_keyed(
+    interpreter, interpreter->Parrot_compreg_hash, key);
+  /* XXX undef */
+  interpreter->ctx.string_reg.registers[5] = $2;       /* XXX */
+  dest = (opcode_t *)func->vtable->invoke(interpreter, func, expr NEXT());
+  /* XXX retval */
+  goto ADDRESS(dest);
+}
+
 
 =item B<find_method>(out PMC, in PMC, in STR)
 
--- parrot/dod.c        Tue Jan 14 09:09:55 2003
+++ parrot-leo/dod.c    Tue Jan 14 18:51:15 2003
@@ -104,6 +104,8 @@
     /* mark it as used  */
     pobject_lives(interpreter, (PObj *)current);
 
+    if (interpreter->Parrot_compreg_hash)
+        pobject_lives(interpreter, (PObj *)interpreter->Parrot_compreg_hash);
     /* Now, go run through the PMC registers and mark them as live */
     /* First mark the current set. */
     for (i = 0; i < NUM_REGISTERS; i++) {
--- parrot/include/parrot/interpreter.h Sat Jan  4 12:35:22 2003
+++ parrot-leo/include/parrot/interpreter.h     Tue Jan 14 18:13:08 2003
@@ -169,6 +169,7 @@
     INTVAL world_inited;        /* Parrot_init is done */
     PMC *mark_ptr;             /* last PMC marked used in DOD runs */
     PMC *Parrot_base_classname_hash;    /* hash containing name->base_type */
+    PMC *Parrot_compreg_hash;   /* hash containing assembler/compilers */
 } Interp;
 
 #define PCONST(i) PF_CONST(interpreter->code, (i))
@@ -189,6 +190,7 @@
 VAR_SCOPE opcode_t *(*run_native)(struct Parrot_Interp * interpreter,
                                   opcode_t * cur_opcode,
                                   opcode_t * start_code);
+void Parrot_compreg(Parrot_Interp interpreter, STRING *type, PMC *func);
 
 #endif   /* Parrot core */
 
--- parrot/interpreter.c        Sat Jan 11 09:39:08 2003
+++ parrot-leo/interpreter.c    Tue Jan 14 19:21:00 2003
@@ -21,11 +21,13 @@
 #ifdef HAVE_COMPUTED_GOTO
 #  include "parrot/oplib/core_ops_cg.h"
 #endif
+#include "parrot/method_util.h"
 
 #define ATEXIT_DESTROY
 
 extern op_lib_t *PARROT_CORE_PREDEREF_OPLIB_INIT(void);
 
+static void setup_default_compreg(Parrot_Interp interpreter);
 
 /*=for api interpreter runops_generic
  * TODO: Not really part of the API, but here's the docs.
@@ -512,6 +514,10 @@
     SET_NULL_P(interpreter->prederef_code, void **);
     SET_NULL(interpreter->jit_info);
 
+    SET_NULL_P(interpreter->Parrot_compreg_hash, PMC *);
+    /* register assembler/compilers */
+    setup_default_compreg(interpreter);
+
     /* Done. Return and be done with it */
 
     /* Okay, we've finished doing anything that might trigger GC.
@@ -686,6 +692,42 @@
     }
     return ret;
 }
+
+/*=for api interpreter Parrot_compreg
+ * register a parser/compiler function
+ */
+
+void Parrot_compreg(Parrot_Interp interpreter, STRING *type, PMC *func)
+{
+    PMC* key, *hash;
+    if (!interpreter->Parrot_compreg_hash) {
+        hash = interpreter->Parrot_compreg_hash =
+            pmc_new_noinit(interpreter, enum_class_PerlHash);
+        hash->vtable->init(interpreter, hash);
+    }
+    key = key_new_string(interpreter, type);
+    hash->vtable->set_pmc_keyed(interpreter, hash, key, func, NULL);
+}
+
+void PDB_eval_wrapper(Parrot_Interp interpreter, STRING *code);
+void PDB_eval_wrapper(Parrot_Interp interpreter, STRING *code)
+{
+    char *s = string_to_cstring(interpreter, code);
+    PDB_eval(interpreter, s);
+    free(s);
+}
+
+static void setup_default_compreg(Parrot_Interp interpreter)
+{
+    STRING *pasm1 = string_make(interpreter, "PASM1", 5, NULL,0,NULL);
+    PMC * func;
+    Parrot_csub_t p = (Parrot_csub_t) F2DPTR(PDB_eval);
+    func = Parrot_new_nci(interpreter, p,
+          string_make(interpreter, "pIt", 3, NULL,0,NULL));
+    Parrot_compreg(interpreter, pasm1, func);
+}
+
+
 /*
  * Local variables:
  * c-indentation-style: bsd
--- parrot/jit/i386/jit_emit.h  Tue Jan 14 10:34:02 2003
+++ parrot-leo/jit/i386/jit_emit.h      Tue Jan 14 21:10:53 2003
@@ -2137,6 +2137,9 @@
                 emitm_addb_i_r(pc, 8, emit_ESP);
                 emitm_pushl_r(pc, emit_EAX);
                 break;
+            case 'I':
+                emitm_pushl_i(pc, interpreter);
+                break;
             default:
                 internal_exception(1,
                         "Parrot_jit_build_call_func: unimp argument\n");
--- /dev/null   Tue Oct 10 22:47:19 2000
+++ parrot-leo/eval.pasm        Tue Jan 14 19:33:57 2003
@@ -0,0 +1,4 @@
+       compile P1, "set_s_sc S1, '42\n'", "PASM1"
+       compile P1, "print_s S1", "PASM1"
+       print "\n"
+       end

Reply via email to