diff options
| author | Shinya Sato <shinnya.sato@gmail.com> | 2022-05-30 20:36:38 +0900 |
|---|---|---|
| committer | Shinya Sato <shinnya.sato@gmail.com> | 2022-05-30 20:36:38 +0900 |
| commit | e18b27f43ac23689822d4aaaaa3e8d550e41017a (patch) | |
| tree | 262150d7ad6abc6759f41a7adbb6dec4a7c90cb5 /src | |
| parent | 04cbbcc0649dfc80d8dbf8c4bc567285df7a9da4 (diff) | |
| download | inpla-e18b27f43ac23689822d4aaaaa3e8d550e41017a.tar.gz inpla-e18b27f43ac23689822d4aaaaa3e8d550e41017a.zip | |
v0.8.2-2
Diffstat (limited to '')
| -rw-r--r-- | src/config.h | 4 | ||||
| -rw-r--r-- | src/id_table.h | 7 | ||||
| -rw-r--r-- | src/inpla.y | 719 |
3 files changed, 401 insertions, 329 deletions
diff --git a/src/config.h b/src/config.h index 1f878e0..23afdc0 100644 --- a/src/config.h +++ b/src/config.h @@ -1,5 +1,9 @@ // Configurations --------------------------------------------------- +// To show the computation process: +//#define DEBUG + + // ------------------------------------------------ // Heaps // ------------------------------------------------ diff --git a/src/id_table.h b/src/id_table.h index a7bb795..c08732e 100644 --- a/src/id_table.h +++ b/src/id_table.h @@ -31,9 +31,10 @@ #define ID_INTAGENT 10 // This is an experimental dummy agent // to show the use effect of Int agent. +#define START_ID_OF_BUILTIN_CONSTRUCTOR_AGENT 10 -#define START_ID_OF_BUILTIN_AGENT 15 +#define START_ID_OF_BUILTIN_OP_AGENT 15 #define ID_APPEND 15 #define ID_MERGER 16 #define ID_MERGER_P 17 @@ -48,10 +49,10 @@ #define ID_MOD 26 #define ID_MOD2 27 #define ID_ERASER 28 -#define END_ID_OF_BUILTIN_AGENT 28 +#define END_ID_OF_BUILTIN_OP_AGENT 28 -#define START_ID_OF_AGENT END_ID_OF_BUILTIN_AGENT+1 +#define START_ID_OF_AGENT END_ID_OF_BUILTIN_OP_AGENT+1 //#define NUM_AGENTS 1024 #define END_ID_OF_AGENT 255 #define NUM_AGENTS END_ID_OF_AGENT+1 // 256 diff --git a/src/inpla.y b/src/inpla.y index b681b03..b68ee4c 100644 --- a/src/inpla.y +++ b/src/inpla.y @@ -22,14 +22,13 @@ // ---------------------------------------------- -#define VERSION "0.8.2-1" -#define BUILT_DATE "2 May 2022" +#define VERSION "0.8.2-2" +#define BUILT_DATE "29 May 2022" // ------------------------------------------------------------------ -//#define DEBUG // For experiments of the tail recursion optimisation. //#define COUNT_CNCT // count of execution of JMP_CNCT @@ -1750,7 +1749,7 @@ typedef struct { int eqStack_size; #ifdef COUNT_INTERACTION - unsigned int count_interaction; + unsigned long count_interaction; #endif @@ -1963,7 +1962,7 @@ VALUE make_Name(VirtualMachine * restrict vm) { // Count for Interaction operation // ------------------------------------------------------ #ifdef COUNT_INTERACTION -int VM_Get_InteractionCount(VirtualMachine *vm) { +unsigned long VM_Get_InteractionCount(VirtualMachine *vm) { return(vm->count_interaction); } @@ -2335,7 +2334,8 @@ typedef enum { // These are used for translation from intermediate codes to Bytecodes OP_LABEL, OP_DEAD_CODE, OP_BEGIN_BLOCK, OP_BEGIN_JMPCNCT_BLOCK, - OP_LOAD_META // keep dest as it is + OP_LOAD_META, // keep the `dest' in `OP_LOAD_META src dest' as it is + OP_LOADI_SHARED // The same register will be assigned for the `dest`. } Code; @@ -2468,7 +2468,8 @@ void IMCode_puts(int n) { "NOP", "LABEL", "__DEAD_CODE", "BEGIN_BLOCK", "BEGIN_CNCT_BLOCK", - "LOAD_META" + "LOAD_META", + "LOADI_SHARED" }; @@ -2641,6 +2642,7 @@ void IMCode_puts(int n) { case OP_PUSHI: case OP_LOADI: case OP_EQI_R0: + case OP_LOADI_SHARED: printf("%s $%ld var%ld\n", string_opcode[imcode->opcode], imcode->operand1, imcode->operand2); break; @@ -3532,15 +3534,14 @@ void CmEnv_retrieve_MKGNAME(void) { -int CmEnv_using_reg(int localvar) { +int CmEnv_using_reg_with_nothing_info(int localvar) { #ifndef OPTIMISE_TWO_ADDRESS for (int i=0; i<VM_REG_SIZE; i++) { if (CmEnv.tmpRegState[i] == localvar) { return i; } } - printf("ERROR[CmEnv_using_reg]: No register assigned to var%d\n", localvar); - exit(1); + return -1; // nothing #else // For two address @@ -3558,14 +3559,39 @@ int CmEnv_using_reg(int localvar) { } } } + return -1; // nothing +#endif +} + + + +int CmEnv_using_reg(int localvar) { +#ifndef OPTIMISE_TWO_ADDRESS + int retval = CmEnv_using_reg_with_nothing_info(localvar); + if (retval != -1) { + return retval; + } + printf("ERROR[CmEnv_using_reg]: No register assigned to var%d\n", localvar); + exit(1); +#else + + // For two address + int retval = CmEnv_using_reg_with_nothing_info(localvar); + if (retval != -1) { + return retval; + } printf("ERROR[CmEnv_using_reg]: No register assigned to var%d\n", localvar); - printf("is_in:%d\n", CmEnv.is_in_jmpcnctBlock); + printf("is_in_jmpcnctBlock:%d\n", CmEnv.is_in_jmpcnctBlock); exit(1); #endif } + + + + int CmEnv_get_newreg(int localvar) { #ifndef OPTIMISE_TWO_ADDRESS // for (int i=VM_OFFSET_LOCALVAR; i<VM_REG_SIZE; i++) { @@ -3614,8 +3640,10 @@ void CmEnv_free_reg(int reg) { CmEnv.jmpcnctBlockRegState[reg] = -1; return; } else { - // if (reg >= VM_OFFSET_LOCALVAR) - CmEnv.tmpRegState[reg] = -1; + // if (reg >= VM_OFFSET_LOCALVAR) // removed this comment out for v0.8.2-2 + // // so, regs for meta variables are not freed. + if (reg >= VM_OFFSET_LOCALVAR) + CmEnv.tmpRegState[reg] = -1; } #endif } @@ -3843,6 +3871,10 @@ int CmEnv_Optimise_VMCode_CopyPropagation_LOADI(int target_imcode_addr) { // This optimisation will last until OP_BEGIN_BLOCK return 0; } + if (imcode->opcode == OP_LABEL) { + // This optimisation will last until OP_LABEL + return 0; + } // if (imcode->opcode == OP_BEGIN_JMPCNCT_BLOCK) { // // This optimisation will last until OP_BEGIN_BLOCK // return 0; @@ -3962,13 +3994,13 @@ int CmEnv_Optimise_VMCode_CopyPropagation(int target_imcode_addr) { load_from = IMCode[target_imcode_addr].operand1; load_to = IMCode[target_imcode_addr].operand2; - // When the given line is: LOAD src src + // When the given line is: LOAD src1 src1 if ((load_from == load_to) && (IMCode[target_imcode_addr].opcode == OP_LOAD)) { IMCode[target_imcode_addr].opcode = OP_DEAD_CODE; return 1; } - // When the given line is: LOAD_META src src + // When the given line is: LOAD_META src1 src1 if ((load_from == load_to) && (IMCode[target_imcode_addr].opcode == OP_LOAD_META)) { IMCode[target_imcode_addr].opcode = OP_DEAD_CODE; @@ -4190,6 +4222,11 @@ int CmEnv_generate_VMCode(void **code) { for (int line_num=0; line_num<IMCode_n; line_num++) { imcode = &IMCode[line_num]; + // DEBUG + // printf("%d\n", line_num); + // VMCode_puts(code, addr); + + #ifdef OPTIMISE_IMCODE // optimisation // Copy Propagation for OP_LOAD reg1, reg2 --> [reg2/reg1]. @@ -4756,6 +4793,33 @@ int CmEnv_generate_VMCode(void **code) { break; } + + case OP_LOADI_SHARED: { + // OP_LOADI int1 dest + long dest = imcode->operand2; + +#ifdef OPTIMISE_IMCODE + // dest = CmEnv_get_newreg(dest); + { + dest = CmEnv_using_reg_with_nothing_info(dest); + if (dest == -1) { + dest = CmEnv_get_newreg(imcode->operand2); + } + } +#endif + + code[addr++] = CodeAddr[OP_LOADI]; + code[addr++] = (void *)INT2FIX(imcode->operand1); + code[addr++] = (void *)(unsigned long)dest; + + break; + } + + + // OP_LOADI_META を入れよう + // META ではなく、KEEP_REG とか、OPT を遠ざける意味としよう。 + // TODO: and と or の LABEL分岐による結果導出 loadi $1 reg1, load $0 reg1 + // の reg1 を同じものに割り当てたい。だから、この KEEP_REG を使いたい case OP_PUSH: @@ -5784,13 +5848,13 @@ int Compile_expr_on_ast(Ast *ptr, int target) { if (!Compile_expr_on_ast(ptr->right, newreg2)) return 0; IMCode_genCode2(OP_JMPEQ0, newreg2, label1); - IMCode_genCode2(OP_LOADI, 1, target); + IMCode_genCode2(OP_LOADI_SHARED, 1, target); int label2 = CmEnv_get_newlabel(); IMCode_genCode1(OP_JMP, label2); IMCode_genCode1(OP_LABEL, label1); - IMCode_genCode2(OP_LOADI, 0, target); + IMCode_genCode2(OP_LOADI_SHARED, 0, target); IMCode_genCode1(OP_LABEL, label2); @@ -5819,13 +5883,13 @@ int Compile_expr_on_ast(Ast *ptr, int target) { if (!Compile_expr_on_ast(ptr->right, newreg2)) return 0; IMCode_genCode2(OP_JMPNEQ0, newreg2, label1); - IMCode_genCode2(OP_LOADI, 0, target); + IMCode_genCode2(OP_LOADI_SHARED, 0, target); int label2 = CmEnv_get_newlabel(); IMCode_genCode1(OP_JMP, label2); IMCode_genCode1(OP_LABEL, label1); - IMCode_genCode2(OP_LOADI, 1, target); + IMCode_genCode2(OP_LOADI_SHARED, 1, target); IMCode_genCode1(OP_LABEL, label2); @@ -7249,7 +7313,7 @@ int make_rule_oneway(Ast *ast) { #endif - // #define MKRULE_DEBUG + // #define MKRULE_DEBUG #ifndef MKRULE_DEBUG gencode_num += CmEnv_generate_VMCode(&code[2]); #else @@ -8674,7 +8738,8 @@ loop_a2IsFixnum: RuleTable_get_code_for_Int(a1, &code); if (code == NULL) { - // built-in + // built-in: BUILT-IN_OP >< int + switch (BASIC(a1)->id) { case ID_ADD: { @@ -8944,362 +9009,366 @@ loop_a2IsAgent: code = RuleTable_get_code(a1, a2, &result); if (result == 0) { +loop_agent_a1_a2_this_order: - - if (BASIC(a2)->id < START_ID_OF_BUILTIN_AGENT) { - // a2 is a constructor - switch (BASIC(a1)->id) { - - case ID_TUPLE0: - if (BASIC(a2)->id == ID_TUPLE0) { - // [] ~ [] --> nothing - COUNTUP_INTERACTION(vm); - - // free_Agent(a1); - // free_Agent(a2); - free_Agent2(a1, a2); - return; - } + // suppose that a2 is a constructor + switch (BASIC(a1)->id) { - break; // end ID_TUPLE0 - - - case ID_TUPLE2: - if (BASIC(a2)->id == ID_TUPLE2) { - // (x1,x2) ~ (y1,y2) --> x1~y1, x2~y2 - COUNTUP_INTERACTION(vm); + case ID_ERASER: + { + // Eps ~ Alpha(a1,...,a5) + COUNTUP_INTERACTION(vm); + + int arity = IdTable_get_arity(BASIC(a2)->id); + switch (arity) { + case 0: + { + free_Agent2(a1, a2); + return; + } - VALUE a1p1 = AGENT(a1)->port[1]; - VALUE a2p1 = AGENT(a2)->port[1]; - PUSH(vm, a1p1, a2p1); - - // free_Agent(a1); - // free_Agent(a2); - free_Agent2(a1,a2); - a1 = AGENT(a1)->port[0]; - a2 = AGENT(a2)->port[0]; - goto loop; - } - - break; // end ID_TUPLE2 - - case ID_TUPLE3: - if (BASIC(a2)->id == ID_TUPLE3) { - // (x1,x2,x3) ~ (y1,y2,y3) --> x1~y1, x2~y2, x3~y3 - COUNTUP_INTERACTION(vm); + case 1: + { + VALUE a2p0 = AGENT(a2)->port[0]; + free_Agent(a2); + a2 = a2p0; + goto loop; + } - PUSH(vm, AGENT(a1)->port[2], AGENT(a2)->port[2]); - PUSH(vm, AGENT(a1)->port[1], AGENT(a2)->port[1]); - - // free_Agent(a1); - // free_Agent(a2); - free_Agent2(a1, a2); - a1 = AGENT(a1)->port[0]; - a2 = AGENT(a2)->port[0]; - goto loop; - } - - break; // end ID_TUPLE2 - - - case ID_TUPLE4: - if (BASIC(a2)->id == ID_TUPLE4) { - // (x1,x2,x3) ~ (y1,y2,y3) --> x1~y1, x2~y2, x3~y3 - COUNTUP_INTERACTION(vm); + default: + for (int i=1; i<arity; i++) { + VALUE a2port = AGENT(a2)->port[1]; + VALUE eps = make_Agent(vm, ID_ERASER); + PUSH(vm, eps, a2port); + } - PUSH(vm, AGENT(a1)->port[3], AGENT(a2)->port[3]); - PUSH(vm, AGENT(a1)->port[2], AGENT(a2)->port[2]); - PUSH(vm, AGENT(a1)->port[1], AGENT(a2)->port[1]); - - // free_Agent(a1); - // free_Agent(a2); - free_Agent2(a1, a2); - a1 = AGENT(a1)->port[0]; - a2 = AGENT(a2)->port[0]; + VALUE a2p0 = AGENT(a2)->port[0]; + free_Agent(a2); + a2 = a2p0; goto loop; } + } + break; - break; // end ID_TUPLE2 - + case ID_TUPLE0: + if (BASIC(a2)->id == ID_TUPLE0) { + // [] ~ [] --> nothing + COUNTUP_INTERACTION(vm); + + // free_Agent(a1); + // free_Agent(a2); + free_Agent2(a1, a2); + return; + } - case ID_TUPLE5: - if (BASIC(a2)->id == ID_TUPLE5) { - // (x1,x2,x3) ~ (y1,y2,y3) --> x1~y1, x2~y2, x3~y3 - COUNTUP_INTERACTION(vm); - - PUSH(vm, AGENT(a1)->port[4], AGENT(a2)->port[4]); - PUSH(vm, AGENT(a1)->port[3], AGENT(a2)->port[3]); - PUSH(vm, AGENT(a1)->port[2], AGENT(a2)->port[2]); - PUSH(vm, AGENT(a1)->port[1], AGENT(a2)->port[1]); - - // free_Agent(a1); - // free_Agent(a2); - free_Agent2(a1, a2); - a1 = AGENT(a1)->port[0]; - a2 = AGENT(a2)->port[0]; - goto loop; - } + break; // end ID_TUPLE0 - break; // end ID_TUPLE2 - + case ID_TUPLE2: + if (BASIC(a2)->id == ID_TUPLE2) { + // (x1,x2) ~ (y1,y2) --> x1~y1, x2~y2 + COUNTUP_INTERACTION(vm); + + VALUE a1p1 = AGENT(a1)->port[1]; + VALUE a2p1 = AGENT(a2)->port[1]; + PUSH(vm, a1p1, a2p1); + + // free_Agent(a1); + // free_Agent(a2); + free_Agent2(a1,a2); + a1 = AGENT(a1)->port[0]; + a2 = AGENT(a2)->port[0]; + goto loop; + } + + break; // end ID_TUPLE2 + + case ID_TUPLE3: + if (BASIC(a2)->id == ID_TUPLE3) { + // (x1,x2,x3) ~ (y1,y2,y3) --> x1~y1, x2~y2, x3~y3 + COUNTUP_INTERACTION(vm); + + PUSH(vm, AGENT(a1)->port[2], AGENT(a2)->port[2]); + PUSH(vm, AGENT(a1)->port[1], AGENT(a2)->port[1]); + + // free_Agent(a1); + // free_Agent(a2); + free_Agent2(a1, a2); + a1 = AGENT(a1)->port[0]; + a2 = AGENT(a2)->port[0]; + goto loop; + } + + break; // end ID_TUPLE2 + + + case ID_TUPLE4: + if (BASIC(a2)->id == ID_TUPLE4) { + // (x1,x2,x3) ~ (y1,y2,y3) --> x1~y1, x2~y2, x3~y3 + COUNTUP_INTERACTION(vm); + + PUSH(vm, AGENT(a1)->port[3], AGENT(a2)->port[3]); + PUSH(vm, AGENT(a1)->port[2], AGENT(a2)->port[2]); + PUSH(vm, AGENT(a1)->port[1], AGENT(a2)->port[1]); + + // free_Agent(a1); + // free_Agent(a2); + free_Agent2(a1, a2); + a1 = AGENT(a1)->port[0]; + a2 = AGENT(a2)->port[0]; + goto loop; + } + + break; // end ID_TUPLE2 + + + case ID_TUPLE5: + if (BASIC(a2)->id == ID_TUPLE5) { + // (x1,x2,x3) ~ (y1,y2,y3) --> x1~y1, x2~y2, x3~y3 + COUNTUP_INTERACTION(vm); + + PUSH(vm, AGENT(a1)->port[4], AGENT(a2)->port[4]); + PUSH(vm, AGENT(a1)->port[3], AGENT(a2)->port[3]); + PUSH(vm, AGENT(a1)->port[2], AGENT(a2)->port[2]); + PUSH(vm, AGENT(a1)->port[1], AGENT(a2)->port[1]); + + // free_Agent(a1); + // free_Agent(a2); + free_Agent2(a1, a2); + a1 = AGENT(a1)->port[0]; + a2 = AGENT(a2)->port[0]; + goto loop; + } + + break; // end ID_TUPLE2 + + + case ID_NIL: + if (BASIC(a2)->id == ID_NIL) { + // [] ~ [] --> nothing + COUNTUP_INTERACTION(vm); + + // free_Agent(a1); + // free_Agent(a2); + free_Agent2(a1, a2); + + return; + } + + break; // end ID_NIL + + + case ID_CONS: + if (BASIC(a2)->id == ID_CONS) { + // a:b ~ c:d --> a~c, b~d + COUNTUP_INTERACTION(vm); + + VALUE a1p1 = AGENT(a1)->port[1]; + VALUE a2p1 = AGENT(a2)->port[1]; + PUSH(vm, a1p1, a2p1); + + // free_Agent(a1); + // free_Agent(a2); + free_Agent2(a1, a2); + a1 = AGENT(a1)->port[0]; + a2 = AGENT(a2)->port[0]; + goto loop; + } + + break; // end ID_CONS + + + + // built-in funcAgent for lists and tuples + case ID_APPEND: + switch (BASIC(a2)->id) { case ID_NIL: - if (BASIC(a2)->id == ID_NIL) { - // [] ~ [] --> nothing + { + // App(r,a) >< [] => r~a; COUNTUP_INTERACTION(vm); - // free_Agent(a1); - // free_Agent(a2); + VALUE a1p0 = AGENT(a1)->port[0]; + VALUE a1p1 = AGENT(a1)->port[1]; + // free_Agent(a1); + // free_Agent(a2); free_Agent2(a1, a2); - - return; + a1=a1p0; + a2=a1p1; + goto loop; } - - break; // end ID_NIL - - + case ID_CONS: - if (BASIC(a2)->id == ID_CONS) { - // a:b ~ c:d --> a~c, b~d + { + // App(r,a) >< [x|xs] => r~(*R)[x|w], (*L)App(w,a)~xs; COUNTUP_INTERACTION(vm); - VALUE a1p1 = AGENT(a1)->port[1]; + VALUE a1p0 = AGENT(a1)->port[0]; VALUE a2p1 = AGENT(a2)->port[1]; - PUSH(vm, a1p1, a2p1); - - // free_Agent(a1); - // free_Agent(a2); - free_Agent2(a1, a2); - a1 = AGENT(a1)->port[0]; - a2 = AGENT(a2)->port[0]; + VALUE w = make_Name(vm); + + AGENT(a2)->port[1] = w; + PUSH(vm, a1p0, a2); + //VM_EQStack_Push(vm, a1p1, a2); + + AGENT(a1)->port[0] = w; + a2 = a2p1; goto loop; } + } - break; // end ID_CONS - - + break; // end ID_APPEND - // built-in funcAgent for lists and tuples - case ID_APPEND: - switch (BASIC(a2)->id) { - case ID_NIL: - { - // App(r,a) >< [] => r~a; - COUNTUP_INTERACTION(vm); + + case ID_MERGER: + switch (BASIC(a2)->id) { + case ID_TUPLE2: + { + // MG(r) ~ (a|b) => *MGp(*r)~a, *MGp(*r)~b + COUNTUP_INTERACTION(vm); - VALUE a1p0 = AGENT(a1)->port[0]; - VALUE a1p1 = AGENT(a1)->port[1]; - // free_Agent(a1); - // free_Agent(a2); - free_Agent2(a1, a2); - a1=a1p0; - a2=a1p1; - goto loop; - } - - case ID_CONS: - { - // App(r,a) >< [x|xs] => r~(*R)[x|w], (*L)App(w,a)~xs; - COUNTUP_INTERACTION(vm); - - VALUE a1p0 = AGENT(a1)->port[0]; - VALUE a2p1 = AGENT(a2)->port[1]; - VALUE w = make_Name(vm); + BASIC(a1)->id = ID_MERGER_P; + AGENT(a1)->port[1] = (VALUE)NULL; + AGENT(a1)->port[2] = (VALUE)NULL; + PUSH(vm, a1, AGENT(a2)->port[1]); + PUSH(vm, a1, AGENT(a2)->port[0]); + free_Agent(a2); + return; - AGENT(a2)->port[1] = w; - PUSH(vm, a1p0, a2); - //VM_EQStack_Push(vm, a1p1, a2); - AGENT(a1)->port[0] = w; - a2 = a2p1; - goto loop; - } } - - break; // end ID_APPEND - + } + break; // end ID_MG - case ID_MERGER: - switch (BASIC(a2)->id) { - case ID_TUPLE2: - { - // MG(r) ~ (a|b) => *MGp(*r)~a, *MGp(*r)~b - COUNTUP_INTERACTION(vm); + case ID_MERGER_P: + switch (BASIC(a2)->id) { + case ID_NIL: + // *MGP(r)~[] +#ifndef THREAD + + COUNTUP_INTERACTION(vm); + + if (AGENT(a1)->port[1] == (VALUE)NULL) { + AGENT(a1)->port[1] = a2; + return; + } else { + VALUE a1p0 = AGENT(a1)->port[0]; + // free_Agent(AGENT(a1)->port[1]); + // free_Agent(a1); + free_Agent2(AGENT(a1)->port[1], a1); + + a1 = a1p0; + goto loop; + } +#else + // AGENT(a1)->port[2] is used as a lock for NIL case + if (AGENT(a1)->port[2] == (VALUE)NULL) { + if (!(__sync_bool_compare_and_swap(&(AGENT(a1)->port[2]), + NULL, a2))) { + // something exists already + goto loop; - BASIC(a1)->id = ID_MERGER_P; - AGENT(a1)->port[1] = (VALUE)NULL; - AGENT(a1)->port[2] = (VALUE)NULL; - PUSH(vm, a1, AGENT(a2)->port[1]); - PUSH(vm, a1, AGENT(a2)->port[0]); - free_Agent(a2); + } else { return; - - } + } else if ((AGENT(a1)->port[2] != (VALUE)NULL) && + (BASIC(AGENT(a1)->port[2])->id == ID_NIL)) { + + COUNTUP_INTERACTION(vm); + + VALUE a1p0 = AGENT(a1)->port[0]; + // free_Agent(AGENT(a1)->port[2]); + // free_Agent(a1); + free_Agent2(AGENT(a1)->port[2], a1); + a1 = a1p0; + goto loop; + } else { + goto loop; } - break; // end ID_MG - - case ID_MERGER_P: - switch (BASIC(a2)->id) { - case ID_NIL: - // *MGP(r)~[] + +#endif + case ID_CONS: + // *MGP(r)~x:xs => r~x:w, *MGP(w)~xs; + { #ifndef THREAD - + COUNTUP_INTERACTION(vm); - if (AGENT(a1)->port[1] == (VALUE)NULL) { - AGENT(a1)->port[1] = a2; - return; - } else { - VALUE a1p0 = AGENT(a1)->port[0]; - // free_Agent(AGENT(a1)->port[1]); - // free_Agent(a1); - free_Agent2(AGENT(a1)->port[1], a1); - - a1 = a1p0; - goto loop; - } + VALUE a1p0 = AGENT(a1)->port[0]; + VALUE w = make_Name(vm); + AGENT(a1)->port[0] = w; + PUSH(vm, a1, AGENT(a2)->port[1]); + + AGENT(a2)->port[1] = w; + a1 = a1p0; + goto loop; #else + // AGENT(a1)->port[1] is used as a lock for CONS case // AGENT(a1)->port[2] is used as a lock for NIL case - if (AGENT(a1)->port[2] == (VALUE)NULL) { - if (!(__sync_bool_compare_and_swap(&(AGENT(a1)->port[2]), - NULL, a2))) { - // something exists already - goto loop; - - } else { - return; - } - } else if ((AGENT(a1)->port[2] != (VALUE)NULL) && - (BASIC(AGENT(a1)->port[2])->id == ID_NIL)) { - + + if (AGENT(a1)->port[2] != (VALUE)NULL) { + // The other MGP finished still, so: + // *MGP(r)~x:xs => r~x:xs; + COUNTUP_INTERACTION(vm); VALUE a1p0 = AGENT(a1)->port[0]; - // free_Agent(AGENT(a1)->port[2]); - // free_Agent(a1); - free_Agent2(AGENT(a1)->port[2], a1); + // free_Agent(AGENT(a1)->port[2]); // free the lock for NIL + // free_Agent(a1); + free_Agent2(AGENT(a1)->port[2], a1); a1 = a1p0; goto loop; - } else { - goto loop; - } - -#endif - case ID_CONS: - // *MGP(r)~x:xs => r~x:w, *MGP(w)~xs; - { -#ifndef THREAD - + + } else if (AGENT(a1)->port[1] == (VALUE)NULL) { + if (!(__sync_bool_compare_and_swap(&(AGENT(a1)->port[1]), + NULL, + a2))) { + // Failure to be locked. + goto loop; + } + + // Succeed the lock COUNTUP_INTERACTION(vm); - VALUE a1p0 = AGENT(a1)->port[0]; + VALUE a1p0 = AGENT(a1)->port[0]; VALUE w = make_Name(vm); AGENT(a1)->port[0] = w; PUSH(vm, a1, AGENT(a2)->port[1]); AGENT(a2)->port[1] = w; - a1 = a1p0; - goto loop; -#else - // AGENT(a1)->port[1] is used as a lock for CONS case - // AGENT(a1)->port[2] is used as a lock for NIL case - - if (AGENT(a1)->port[2] != (VALUE)NULL) { - // The other MGP finished still, so: - // *MGP(r)~x:xs => r~x:xs; - - COUNTUP_INTERACTION(vm); - - VALUE a1p0 = AGENT(a1)->port[0]; - // free_Agent(AGENT(a1)->port[2]); // free the lock for NIL - // free_Agent(a1); - free_Agent2(AGENT(a1)->port[2], a1); - a1 = a1p0; - goto loop; - - } else if (AGENT(a1)->port[1] == (VALUE)NULL) { - if (!(__sync_bool_compare_and_swap(&(AGENT(a1)->port[1]), - NULL, - a2))) { - // Failure to be locked. - goto loop; - } - - // Succeed the lock - COUNTUP_INTERACTION(vm); - - VALUE a1p0 = AGENT(a1)->port[0]; - VALUE w = make_Name(vm); - AGENT(a1)->port[0] = w; - PUSH(vm, a1, AGENT(a2)->port[1]); - - AGENT(a2)->port[1] = w; - - AGENT(a1)->port[1] = (VALUE)NULL; // free the lock - - a1 = a1p0; - - goto loop; - - } else { - // MPG works for the other now. - - goto loop; - } + AGENT(a1)->port[1] = (VALUE)NULL; // free the lock -#endif - } - } - break; // end ID_MERGER_P - - - } // end switch(BASIC(a1)->id) - - } else { - // a2 is not a constructor - - switch (BASIC(a1)->id) { - case ID_ERASER: - { - // Eps ~ Alpha(a1,...,a5) - COUNTUP_INTERACTION(vm); - - int arity = IdTable_get_arity(BASIC(a2)->id); - switch (arity) { - case 0: - { - free_Agent2(a1, a2); - return; - } + a1 = a1p0; - case 1: - { - VALUE a2p0 = AGENT(a2)->port[0]; - free_Agent(a2); - a2 = a2p0; - goto loop; - } + goto loop; - default: - for (int i=1; i<arity; i++) { - VALUE a2port = AGENT(a2)->port[1]; - VALUE eps = make_Agent(vm, ID_ERASER); - PUSH(vm, eps, a2port); - } + } else { + // MPG works for the other now. - VALUE a2p0 = AGENT(a2)->port[0]; - free_Agent(a2); - a2 = a2p0; goto loop; } + + +#endif } - break; // end case ID_ERASER } - } + break; // end ID_MERGER_P + + + } // end switch(BASIC(a1)->id) + + + if ((BASIC(a1)->id < BASIC(a2)->id) + || (BASIC(a2)->id == ID_ERASER)){ + VALUE tmp; + tmp = a1; + a1 = a2; + a2 = tmp; + goto loop_agent_a1_a2_this_order; + } + printf("Runtime Error: There is no interaction rule for the following pair:\n "); puts_term(a1); @@ -9620,15 +9689,13 @@ int exec(Ast *at) { CmEnv_retrieve_MKGNAME(); CmEnv_generate_VMCode(code); - /* - // for debug - CmEnv_retrieve_MKGNAME(); - IMCode_puts(0); //exit(1); - - int codenum = CmEnv_generate_VMCode(code); - VMCode_puts(code, codenum-2); //exit(1); - // end for debug - */ + // // for debug + // CmEnv_retrieve_MKGNAME(); + // IMCode_puts(0); //exit(1); + // + // int codenum = CmEnv_generate_VMCode(code); + // VMCode_puts(code, codenum-2); //exit(1); + // // end for debug #ifdef COUNT_MKAGENT NumberOfMkAgent=0; @@ -9671,7 +9738,7 @@ int exec(Ast *at) { time=stop_timer(&t); #ifdef COUNT_INTERACTION - printf("(%d interactions, %.2f sec)\n", VM_Get_InteractionCount(&VM), + printf("(%lu interactions, %.2f sec)\n", VM_Get_InteractionCount(&VM), (double)(time)/1000000); #else printf("(%.2f sec)\n", |
