From 0046c814982216855922c0ce5eb76a8f33f1d83c Mon Sep 17 00:00:00 2001 From: Shinya Sato Date: Mon, 10 Jan 2022 22:22:31 +0900 Subject: v0.7.0_dev --- src/inpla.y | 5264 +++++++++++++++++++++++++---------------------------------- 1 file changed, 2211 insertions(+), 3053 deletions(-) diff --git a/src/inpla.y b/src/inpla.y index de894ae..11d7565 100644 --- a/src/inpla.y +++ b/src/inpla.y @@ -1656,8 +1656,21 @@ typedef enum { PUSHI, MKNAME, MKGNAME, - MKAGENT, - REUSEAGENT, + + MKAGENT0, + MKAGENT1, + MKAGENT2, + MKAGENT3, + MKAGENT4, + MKAGENT5, + + REUSEAGENT0, + REUSEAGENT1, + REUSEAGENT2, + REUSEAGENT3, + REUSEAGENT4, + REUSEAGENT5, + MYPUSH, RET, @@ -1724,6 +1737,86 @@ typedef struct { } NameBind; +//http://www.hpcs.cs.tsukuba.ac.jp/~msato/lecture-note/comp-lecture/note10.html +#define MAX_IMCODE 1024 +struct IMCode_tag { + int opcode; + int operand1, operand2, operand3, operand4, operand5, operand6, operand7; +} IMCode[MAX_IMCODE]; + +int IMCode_n; + +void IMCode_Init(void) { + IMCode_n = 0; +} + +#define IMCODE_OVERFLOW_CHECK if(IMCode_n>MAX_IMCODE) {puts("IMCODE overflow");exit(1);} + +void IMCode_genCode0(int opcode) { + IMCode[IMCode_n++].opcode = opcode; + IMCODE_OVERFLOW_CHECK +} +void IMCode_genCode1(int opcode, int operand1) { + IMCode[IMCode_n].operand1 = operand1; + IMCode[IMCode_n++].opcode = opcode; + IMCODE_OVERFLOW_CHECK +} +void IMCode_genCode2(int opcode, int operand1, int operand2) { + IMCode[IMCode_n].operand1 = operand1; + IMCode[IMCode_n].operand2 = operand2; + IMCode[IMCode_n++].opcode = opcode; + IMCODE_OVERFLOW_CHECK +} +void IMCode_genCode3(int opcode, int operand1, int operand2, int operand3) { + IMCode[IMCode_n].operand1 = operand1; + IMCode[IMCode_n].operand2 = operand2; + IMCode[IMCode_n].operand3 = operand3; + IMCode[IMCode_n++].opcode = opcode; + IMCODE_OVERFLOW_CHECK +} +void IMCode_genCode4(int opcode, int operand1, int operand2, int operand3, + int operand4) { + IMCode[IMCode_n].operand1 = operand1; + IMCode[IMCode_n].operand2 = operand2; + IMCode[IMCode_n].operand3 = operand3; + IMCode[IMCode_n].operand4 = operand4; + IMCode[IMCode_n++].opcode = opcode; + IMCODE_OVERFLOW_CHECK +} +void IMCode_genCode5(int opcode, int operand1, int operand2, int operand3, + int operand4, int operand5) { + IMCode[IMCode_n].operand1 = operand1; + IMCode[IMCode_n].operand2 = operand2; + IMCode[IMCode_n].operand3 = operand3; + IMCode[IMCode_n].operand4 = operand4; + IMCode[IMCode_n].operand5 = operand5; + IMCode[IMCode_n++].opcode = opcode; + IMCODE_OVERFLOW_CHECK +} +void IMCode_genCode6(int opcode, int operand1, int operand2, int operand3, + int operand4, int operand5, int operand6) { + IMCode[IMCode_n].operand1 = operand1; + IMCode[IMCode_n].operand2 = operand2; + IMCode[IMCode_n].operand3 = operand3; + IMCode[IMCode_n].operand4 = operand4; + IMCode[IMCode_n].operand5 = operand5; + IMCode[IMCode_n].operand6 = operand6; + IMCode[IMCode_n++].opcode = opcode; + IMCODE_OVERFLOW_CHECK +} +void IMCode_genCode7(int opcode, int operand1, int operand2, int operand3, + int operand4, int operand5, int operand6, int operand7) { + IMCode[IMCode_n].operand1 = operand1; + IMCode[IMCode_n].operand2 = operand2; + IMCode[IMCode_n].operand3 = operand3; + IMCode[IMCode_n].operand4 = operand4; + IMCode[IMCode_n].operand5 = operand5; + IMCode[IMCode_n].operand6 = operand6; + IMCode[IMCode_n].operand7 = operand7; + IMCode[IMCode_n++].opcode = opcode; + IMCODE_OVERFLOW_CHECK +} + #define MAX_CODE_SIZE 1024 typedef struct { @@ -1738,11 +1831,6 @@ typedef struct { // Index for local and global names in Regs int localNamePtr; // It starts from VM_OFFSET_LOCALVAR int vmStackSize; // the array size of the Regs. - - - // Compiled code and its index - void *code[MAX_CODE_SIZE]; - int codeptr; // For rule agents @@ -1817,9 +1905,8 @@ void CmEnv_clear_all() // reset the beginning number for local vars. CmEnv_clear_localnamePtr(); - // reset the index of code array in CmEnv. - CmEnv.codeptr = 0; - + // reset the index of storage for imtermediate codes. + IMCode_Init(); } void CmEnv_clear_keeping_rule_properties() @@ -1838,9 +1925,8 @@ void CmEnv_clear_keeping_rule_properties() // reset the beginning number for local vars. CmEnv_clear_localnamePtr(); - // reset the index of code array in CmEnv. - CmEnv.codeptr = 0; - + // reset the index of storage for imtermediate codes. + IMCode_Init(); } @@ -1965,88 +2051,6 @@ int CmEnv_newreg() { -#define EnvAddCode(c)\ - if (CmEnv.codeptr >= MAX_CODE_SIZE) {\ - puts("SYSTEM ERROR: The codeptr exceeded MAX_CODE_SIZE");\ - exit(-1);\ - }\ - CmEnv.code[CmEnv.codeptr] = c;\ - CmEnv.codeptr++; - -#define EnvAddCode2(c1,c2) \ - if (CmEnv.codeptr+1 >= MAX_CODE_SIZE) {\ - puts("SYSTEM ERROR: The codeptr exceeded MAX_CODE_SIZE");\ - exit(-1);\ - }\ - CmEnv.code[CmEnv.codeptr++] = c1;\ - CmEnv.code[CmEnv.codeptr++] = c2; - -#define EnvAddCode3(c1,c2,c3) \ - if (CmEnv.codeptr+2 >= MAX_CODE_SIZE) {\ - puts("SYSTEM ERROR: The codeptr exceeded MAX_CODE_SIZE");\ - exit(-1);\ - }\ - CmEnv.code[CmEnv.codeptr++] = c1;\ - CmEnv.code[CmEnv.codeptr++] = c2;\ - CmEnv.code[CmEnv.codeptr++] = c3; - -#define EnvAddCode4(c1,c2,c3,c4) \ - if (CmEnv.codeptr+3 >= MAX_CODE_SIZE) {\ - puts("SYSTEM ERROR: The codeptr exceeded MAX_CODE_SIZE");\ - exit(-1);\ - }\ - CmEnv.code[CmEnv.codeptr++] = c1;\ - CmEnv.code[CmEnv.codeptr++] = c2;\ - CmEnv.code[CmEnv.codeptr++] = c3;\ - CmEnv.code[CmEnv.codeptr++] = c4; - -#define EnvAddCode5(c1,c2,c3,c4,c5) \ - if (CmEnv.codeptr+4 >= MAX_CODE_SIZE) {\ - puts("SYSTEM ERROR: The codeptr exceeded MAX_CODE_SIZE");\ - exit(-1);\ - }\ - CmEnv.code[CmEnv.codeptr++] = c1;\ - CmEnv.code[CmEnv.codeptr++] = c2;\ - CmEnv.code[CmEnv.codeptr++] = c3;\ - CmEnv.code[CmEnv.codeptr++] = c4;\ - CmEnv.code[CmEnv.codeptr++] = c5; - - -#define EnvAddCode6(c1,c2,c3,c4,c5,c6) \ - if (CmEnv.codeptr+5 >= MAX_CODE_SIZE) {\ - puts("SYSTEM ERROR: The codeptr exceeded MAX_CODE_SIZE");\ - exit(-1);\ - }\ - CmEnv.code[CmEnv.codeptr++] = c1;\ - CmEnv.code[CmEnv.codeptr++] = c2;\ - CmEnv.code[CmEnv.codeptr++] = c3;\ - CmEnv.code[CmEnv.codeptr++] = c4;\ - CmEnv.code[CmEnv.codeptr++] = c5;\ - CmEnv.code[CmEnv.codeptr++] = c6; - - - -#define EnvCodeClear() CmEnv.codeptr=0 - - -void EnvAddCodePUSH(void* c1, void* c2) { - EnvAddCode3(CodeAddr[PUSH],c1,c2); -} - - -void EnvAddCodeMYPUSH(void* c1, void* c2) { - EnvAddCode3(CodeAddr[MYPUSH],c1,c2); -} - -void EnvAddCodeCNCTGN(void* c1, void* c2) { - EnvAddCode3(CodeAddr[CNCTGN],c1,c2); -} - -void EnvAddCodeSUBSTGN(void* c1, void* c2) { - EnvAddCode3(CodeAddr[SUBSTGN],c1,c2); -} - - int CmEnv_check_meta_occur_once() { int i; @@ -2084,3247 +2088,2271 @@ int CmEnv_check_name_reference_times() { return 1; } -int CmEnv_generate_code_with_nameinfo(void **code, int offset) { - // return: the number of produced codes - int i; +void CmEnv_Retrieve_GNAME() { + int reg_name; - /* - // check whether the code size estimation is exceeded. - { - int count_names=0; - for (i=0; i MAX_CODE_SIZE) { - puts("System ERROR: Generated codes were too big."); - return -1; + for (int i=0; i 0) { - code[ptr++] = CodeAddr[MKNAME]; - - } else { - code[ptr++] = CodeAddr[MKGNAME]; - code[ptr++] = CmEnv.bind[i].name; - } - code[ptr++] = (void *)(unsigned long)CmEnv.bind[i].reg; + reg_name = IMCode[i].operand1; + + for (int j=0; j MAX_CODE_SIZE) { - puts("System ERROR: Generated codes were too big."); - return -1; - } - - for (i=0; iopcode) { + case MKNAME: + // printf("MKNAME var%d\n", imcode->operand1); + code[ptr++] = CodeAddr[imcode->opcode]; + code[ptr++] = (void *)(unsigned long)imcode->operand1; + break; -void CopyCode(int byte, void **source, void **target) { - int i; - for (i=0; ioperand1, imcode->operand2, + // CmEnv.bind[imcode->operand2].name); + code[ptr++] = CodeAddr[imcode->opcode]; + code[ptr++] = (void *)(unsigned long)imcode->operand1; + code[ptr++] = CmEnv.bind[imcode->operand2].name; + break; + case MKAGENT0: + case REUSEAGENT0: + // printf("MKAGENT0 var%d id:%d\n", + // imcode->operand1, imcode->operand2); + code[ptr++] = CodeAddr[imcode->opcode]; + code[ptr++] = (void *)(unsigned long)imcode->operand1; + code[ptr++] = (void *)(unsigned long)imcode->operand2; + break; + case MKAGENT1: + case REUSEAGENT1: + // printf("MKAGENT1 var%d id:%d var%d\n", + // imcode->operand1, imcode->operand2, imcode->operand3); + code[ptr++] = CodeAddr[imcode->opcode]; + code[ptr++] = (void *)(unsigned long)imcode->operand1; + code[ptr++] = (void *)(unsigned long)imcode->operand2; + code[ptr++] = (void *)(unsigned long)imcode->operand3; + break; + case MKAGENT2: + case REUSEAGENT2: + // printf("MKAGENT2 var%d id:%d var%d var%d\n", + // imcode->operand1, imcode->operand2, + // imcode->operand3, imcode->operand4); + code[ptr++] = CodeAddr[imcode->opcode]; + code[ptr++] = (void *)(unsigned long)imcode->operand1; + code[ptr++] = (void *)(unsigned long)imcode->operand2; + code[ptr++] = (void *)(unsigned long)imcode->operand3; + code[ptr++] = (void *)(unsigned long)imcode->operand4; + break; -void PutsCodeN(void **code, int n) { - int i,j; - unsigned long arity; - i=0; + case MKAGENT3: + case REUSEAGENT3: + // printf("MKAGENT3 var%d id:%d var%d var%d var%d\n", + // imcode->operand1, imcode->operand2, + // imcode->operand3, imcode->operand4, imcode->operand5); + code[ptr++] = CodeAddr[imcode->opcode]; + code[ptr++] = (void *)(unsigned long)imcode->operand1; + code[ptr++] = (void *)(unsigned long)imcode->operand2; + code[ptr++] = (void *)(unsigned long)imcode->operand3; + code[ptr++] = (void *)(unsigned long)imcode->operand4; + code[ptr++] = (void *)(unsigned long)imcode->operand5; + break; - puts("[PutsCode]"); - if (n==-1) n = MAX_CODE_SIZE; - for (i=0; ioperand1, imcode->operand2, + // imcode->operand3, imcode->operand4, imcode->operand5); + code[ptr++] = CodeAddr[imcode->opcode]; + code[ptr++] = (void *)(unsigned long)imcode->operand1; + code[ptr++] = (void *)(unsigned long)imcode->operand2; + code[ptr++] = (void *)(unsigned long)imcode->operand3; + code[ptr++] = (void *)(unsigned long)imcode->operand4; + code[ptr++] = (void *)(unsigned long)imcode->operand5; + code[ptr++] = (void *)(unsigned long)imcode->operand6; + break; - } else if (code[i] == CodeAddr[LOOP_RREC]) { - printf("LOOP_RREC var%lu $%lu\n", - (unsigned long)code[i+1], - (unsigned long)code[i+2]); - i+=2; + case MKAGENT5: + case REUSEAGENT5: + // printf("MKAGENT3 var%d id:%d var%d var%d var%d\n", + // imcode->operand1, imcode->operand2, + // imcode->operand3, imcode->operand4, imcode->operand5); + code[ptr++] = CodeAddr[imcode->opcode]; + code[ptr++] = (void *)(unsigned long)imcode->operand1; + code[ptr++] = (void *)(unsigned long)imcode->operand2; + code[ptr++] = (void *)(unsigned long)imcode->operand3; + code[ptr++] = (void *)(unsigned long)imcode->operand4; + code[ptr++] = (void *)(unsigned long)imcode->operand5; + code[ptr++] = (void *)(unsigned long)imcode->operand6; + code[ptr++] = (void *)(unsigned long)imcode->operand7; + break; - } else if (code[i] == CodeAddr[LOOP_RREC1]) { - printf("LOOP_RREC1 var%lu\n", - (unsigned long)code[i+1]); - i+=1; + + case PUSH: + case MYPUSH: + case LOAD: + case OP_JMPEQ0: + case OP_JMPCNCT_CONS: + // printf("PUSH var%d var%d\n", + // imcode->operand1, imcode->operand2); + code[ptr++] = CodeAddr[imcode->opcode]; + code[ptr++] = (void *)(unsigned long)imcode->operand1; + code[ptr++] = (void *)(unsigned long)imcode->operand2; + break; + + case OP_ADD: + case OP_SUB: + case OP_MUL: + case OP_DIV: + case OP_MOD: + case OP_LT: + case OP_LE: + case OP_EQ: + case OP_NE: + case OP_SUBI: + case OP_EQI: + code[ptr++] = CodeAddr[imcode->opcode]; + code[ptr++] = (void *)(unsigned long)imcode->operand1; + code[ptr++] = (void *)(unsigned long)imcode->operand2; + code[ptr++] = (void *)(unsigned long)imcode->operand3; + break; + - } else if (code[i] == CodeAddr[LOOP_RREC2]) { - printf("LOOP_RREC2 var%lu\n", - (unsigned long)code[i+1]); - i+=1; + case PUSHI: + // printf("PUSH var%d $%d\n", + // imcode->operand1, imcode->operand2); + code[ptr++] = CodeAddr[imcode->opcode]; + code[ptr++] = (void *)(unsigned long)imcode->operand1; + code[ptr++] = (void *)INT2FIX(imcode->operand2); - } else if (code[i] == CodeAddr[LOAD]) { - printf("LOAD var%lu var%lu\n", (unsigned long)code[i+1], - (unsigned long)code[i+2]); - i+=2; - } else if (code[i] == CodeAddr[LOADP]) { - printf("LOADP var%lu var%lu[%lu]\n", - (unsigned long)code[i+1], - (unsigned long)code[i+2], - (unsigned long)code[i+3]); - i+=3; - } else if (code[i] == CodeAddr[OP_ADD]) { - printf("ADD var%lu var%lu var%lu\n", (unsigned long)code[i+1], (unsigned long)code[i+2], (unsigned long)code[i+3]); - i+=3; - } else if (code[i] == CodeAddr[OP_SUB]) { - printf("SUB var%lu var%lu var%lu\n", (unsigned long)code[i+1], (unsigned long)code[i+2], (unsigned long)code[i+3]); - i+=3; - } else if (code[i] == CodeAddr[OP_SUBI]) { - printf("SUBI var%lu var%lu $%ld\n", (unsigned long)code[i+1], (unsigned long)code[i+2], (long int)code[i+3]); - i+=3; - } else if (code[i] == CodeAddr[OP_MUL]) { - printf("MUL var%lu var%lu var%lu\n", (unsigned long)code[i+1], (unsigned long)code[i+2], (unsigned long)code[i+3]); - i+=3; - } else if (code[i] == CodeAddr[OP_DIV]) { - printf("DIV var%lu var%lu var%lu\n", (unsigned long)code[i+1], (unsigned long)code[i+2], (unsigned long)code[i+3]); - i+=3; - } else if (code[i] == CodeAddr[OP_MOD]) { - printf("MOD var%lu var%lu var%lu\n", (unsigned long)code[i+1], (unsigned long)code[i+2], (unsigned long)code[i+3]); - i+=3; - } else if (code[i] == CodeAddr[OP_LT]) { - printf("LT var%lu var%lu var%lu\n", (unsigned long)code[i+1], (unsigned long)code[i+2], (unsigned long)code[i+3]); - i+=3; - } else if (code[i] == CodeAddr[OP_LE]) { - printf("LE var%lu var%lu var%lu\n", (unsigned long)code[i+1], (unsigned long)code[i+2], (unsigned long)code[i+3]); - i+=3; - } else if (code[i] == CodeAddr[OP_EQ]) { - printf("EQ var%lu var%lu var%lu\n", (unsigned long)code[i+1], (unsigned long)code[i+2], (unsigned long)code[i+3]); - i+=3; - } else if (code[i] == CodeAddr[OP_EQI]) { - printf("EQI var%lu var%lu $%ld\n", (unsigned long)code[i+1], (unsigned long)code[i+2], (long int)code[i+3]); - i+=3; - } else if (code[i] == CodeAddr[OP_NE]) { - printf("NE var%lu var%lu var%lu\n", (unsigned long)code[i+1], (unsigned long)code[i+2], (unsigned long)code[i+3]); - i+=3; - } else if (code[i] == CodeAddr[OP_JMPEQ0]) { - printf("JMPEQ0 var%lu $%lu\n", (unsigned long)code[i+1], (unsigned long)code[i+2]); - i+=2; - } else if (code[i] == CodeAddr[OP_JMPCNCT_CONS]) { - printf("JMPCNCT_CONS var%lu $%lu\n", (unsigned long)code[i+1], (unsigned long)code[i+2]); - i+=2; - } else if (code[i] == CodeAddr[OP_JMPCNCT]) { - printf("JMPCNCT var%lu $%lu $%lu\n", - (unsigned long)code[i+1], - (unsigned long)code[i+2], - (unsigned long)code[i+3]); - i+=3; - } else if (code[i] == CodeAddr[OP_JMP]) { - printf("JMP $%lu\n", (unsigned long)code[i+1]); - i+=1; - } else if (code[i] == CodeAddr[OP_UNM]) { - printf("UNM var%lu var%lu\n", (unsigned long)code[i+1], (unsigned long)code[i+2]); - i+=2; - } else if (code[i] == CodeAddr[OP_RAND]) { - printf("RND var%lu var%lu\n", (unsigned long)code[i+1], (unsigned long)code[i+2]); - i+=2; - } else if (code[i] == CodeAddr[CNCTGN]) { - printf("CNCTGN var%lu var%lu\n", (unsigned long)code[i+1], (unsigned long)code[i+2]); - i +=2; - } else if (code[i] == CodeAddr[SUBSTGN]) { - printf("SUBSTGN var%lu var%lu\n", (unsigned long)code[i+1], (unsigned long)code[i+2]); - i +=2; - } else if (code[i] == CodeAddr[NOP]) { - printf("NOP\n"); - } else { - printf("CODE %lu\n", (unsigned long)code[i]); + break; + + case RET: + case RET_FREE_L: + case RET_FREE_R: + case RET_FREE_LR: + case LOOP: + case NOP: + code[ptr++] = CodeAddr[imcode->opcode]; + break; + + + case LOADI: + // printf("LOADI var%d $%d\n", + // imcode->operand1, imcode->operand2); + code[ptr++] = CodeAddr[imcode->opcode]; + code[ptr++] = (void *)(unsigned long)imcode->operand1; + code[ptr++] = (void *)(unsigned long)imcode->operand2; + break; + + + case LOOP_RREC1: + case LOOP_RREC2: + // printf("LOOP_RREC1 var%d\n", + // imcode->operand1); + code[ptr++] = CodeAddr[imcode->opcode]; + code[ptr++] = (void *)(unsigned long)imcode->operand1; + break; + + case LOADP: + case OP_JMPCNCT: + // printf("LOADP var%d var%d[%d]\n", + // imcode->operand1, imcode->operand2, imcode->operand3); + code[ptr++] = CodeAddr[imcode->opcode]; + code[ptr++] = (void *)(unsigned long)imcode->operand1; + code[ptr++] = (void *)(unsigned long)imcode->operand2; + code[ptr++] = (void *)(unsigned long)imcode->operand3; + break; + + + case OP_JMP: + // printf("JMP $%d\n", + // imcode->operand1); + code[ptr++] = CodeAddr[imcode->opcode]; + code[ptr++] = (void *)(unsigned long)imcode->operand1; + break; + + case OP_UNM: + case OP_RAND: + // printf("UNM var%d $%d\n", + // imcode->operand1, imcode->operand2); + code[ptr++] = CodeAddr[imcode->opcode]; + code[ptr++] = (void *)(unsigned long)imcode->operand1; + code[ptr++] = (void *)(unsigned long)imcode->operand2; + break; + + case CNCTGN: + case SUBSTGN: + // printf("CNCTGN var%d $%d\n", + // imcode->operand1, imcode->operand2); + code[ptr++] = CodeAddr[imcode->opcode]; + code[ptr++] = (void *)(unsigned long)imcode->operand1; + code[ptr++] = (void *)(unsigned long)imcode->operand2; + break; + + default: + printf("Error[CmEnv_Generate_VMCode]: %d does not match any opcode\n", + imcode->opcode); + exit(-1); } } + + return (ptr-offset); } -void PutsCode(void **code) { - PutsCodeN(code, -1); +void CopyCode(int byte, void **source, void **target) { + int i; + for (i=0; iopcode) { + case MKNAME: + printf("MKNAME var%d\n", imcode->operand1); + break; -int is_expr(Ast *ptr) { + case MKGNAME: + printf("MKGNAME var%d sym:%d (as `%s')\n", + imcode->operand1, imcode->operand2, + CmEnv.bind[imcode->operand2].name); + break; - if (ptr == NULL) { - return 0; - } + case MKAGENT0: + printf("MKAGENT0 var%d id:%d\n", + imcode->operand1, imcode->operand2); + break; - switch (ptr->id) { - case AST_INT: - return 1; - break; + case MKAGENT1: + printf("MKAGENT1 var%d id:%d var%d\n", + imcode->operand1, imcode->operand2, imcode->operand3); + break; - case AST_NAME: { - NB_TYPE type; - int result = CmEnv_gettype_forname(ptr->left->sym, &type); - if (result == 0) { - return 9; - } - if (type != NB_INTVAR) { - return 0; - } + case MKAGENT2: + printf("MKAGENT2 var%d id:%d var%d var%d\n", + imcode->operand1, imcode->operand2, + imcode->operand3, imcode->operand4); + break; - return 1; - break; - } - - case AST_RAND: - case AST_UNM: { - if (!is_expr(ptr->left)) return 0; + case MKAGENT3: + printf("MKAGENT3 var%d id:%d var%d var%d var%d\n", + imcode->operand1, imcode->operand2, + imcode->operand3, imcode->operand4, imcode->operand5); + break; - return 1; - break; - } - - case AST_PLUS: - case AST_SUB: - case AST_MUL: - case AST_DIV: - case AST_MOD: - case AST_LT: - case AST_LE: - case AST_EQ: - case AST_NE: { - if (!is_expr(ptr->left)) return 0; - if (!is_expr(ptr->right)) return 0; + case MKAGENT4: + printf("MKAGENT4 var%d id:%d var%d var%d var%d var%d\n", + imcode->operand1, imcode->operand2, + imcode->operand3, imcode->operand4, imcode->operand5, + imcode->operand6); + break; - return 1; - break; - } - default: - return 0; - } -} + case MKAGENT5: + printf("MKAGENT5 var%d id:%d var%d var%d var%d var%d var%d\n", + imcode->operand1, imcode->operand2, + imcode->operand3, imcode->operand4, imcode->operand5, + imcode->operand6, imcode->operand7); + break; + + case REUSEAGENT0: + printf("REUSEAGENT0 var%d id:%d\n", + imcode->operand1, imcode->operand2); + break; + case REUSEAGENT1: + printf("REUSEAGENT1 var%d id:%d var%d\n", + imcode->operand1, imcode->operand2, imcode->operand3); + break; -int CompileExprFromAst(int target, Ast *ptr) { + case REUSEAGENT2: + printf("REUSEAGENT2 var%d id:%d var%d var%d\n", + imcode->operand1, imcode->operand2, + imcode->operand3, imcode->operand4); + break; - if (ptr == NULL) { - return 1; - } + case REUSEAGENT3: + printf("REUSEAGENT3 var%d id:%d var%d var%d var%d\n", + imcode->operand1, imcode->operand2, + imcode->operand3, imcode->operand4, imcode->operand5); + break; - switch (ptr->id) { - case AST_INT: - EnvAddCode3(CodeAddr[LOADI], - (void *)(unsigned long)target, - (void *)(unsigned long)(ptr->intval)); - return 1; - break; + case REUSEAGENT4: + printf("REUSEAGENT4 var%d id:%d var%d var%d var%d var%d\n", + imcode->operand1, imcode->operand2, + imcode->operand3, imcode->operand4, imcode->operand5, + imcode->operand6); + break; - case AST_NAME: { - int result = CmEnv_reg_search(ptr->left->sym); - if (result == -1) { - // result=CmEnv_set_as_INTVAR(ptr->left->sym); - printf("ERROR: '%s' has not been defined previously.\n", - ptr->left->sym); - return 0; - } - EnvAddCode3(CodeAddr[LOAD], - (void *)(unsigned long)target, - (void *)(unsigned long)result); - return 1; - break; - } - case AST_RAND: { - int newreg = CmEnv_newreg(); - if (!CompileExprFromAst(newreg, ptr->left)) return 0; - EnvAddCode3(CodeAddr[OP_RAND], - (void *)(unsigned long)target, - (void *)(unsigned long)newreg); + case REUSEAGENT5: + printf("REUSEAGENT5 var%d id:%d var%d var%d var%d var%d var%d\n", + imcode->operand1, imcode->operand2, + imcode->operand3, imcode->operand4, imcode->operand5, + imcode->operand6, imcode->operand7); + break; - return 1; - break; - } - case AST_UNM: { - int newreg = CmEnv_newreg(); - if (!CompileExprFromAst(newreg, ptr->left)) return 0; - EnvAddCode3(CodeAddr[OP_UNM], - (void *)(unsigned long)target, - (void *)(unsigned long)newreg); + + case PUSH: + printf("PUSH var%d var%d\n", + imcode->operand1, imcode->operand2); + break; - return 1; - break; - } - case AST_PLUS: - case AST_SUB: - case AST_MUL: - case AST_DIV: - case AST_MOD: - case AST_LT: - case AST_LE: - case AST_EQ: - case AST_NE: { - int newreg = CmEnv_newreg(); - int newreg2 = CmEnv_newreg(); - if (!CompileExprFromAst(newreg, ptr->left)) return 0; - if (!CompileExprFromAst(newreg2, ptr->right)) return 0; + case PUSHI: + printf("PUSH var%d $%d\n", + imcode->operand1, imcode->operand2); + break; - switch (ptr->id) { - case AST_PLUS: - EnvAddCode(CodeAddr[OP_ADD]); + case MYPUSH: + printf("MYPUSH var%d var%d\n", + imcode->operand1, imcode->operand2); break; - case AST_SUB: - EnvAddCode(CodeAddr[OP_SUB]); + + case RET: + puts("RET"); break; - case AST_MUL: - EnvAddCode(CodeAddr[OP_MUL]); + + case RET_FREE_L: + puts("RET_FREE_L"); break; - case AST_DIV: - EnvAddCode(CodeAddr[OP_DIV]); + + case RET_FREE_R: + puts("RET_FREE_R"); break; - case AST_MOD: - EnvAddCode(CodeAddr[OP_MOD]); + + case RET_FREE_LR: + puts("RET_FREE_LR"); break; - case AST_LT: - EnvAddCode(CodeAddr[OP_LT]); + + case LOADI: + printf("LOADI var%d $%d\n", + imcode->operand1, imcode->operand2); break; - case AST_LE: - EnvAddCode(CodeAddr[OP_LE]); + + case LOOP: + printf("LOOP\n"); break; - case AST_EQ: - EnvAddCode(CodeAddr[OP_EQ]); + + case LOOP_RREC: + printf("LOOP_RREC var%d $%d\n", + imcode->operand1, imcode->operand2); break; - case AST_NE: - EnvAddCode(CodeAddr[OP_NE]); + + case LOOP_RREC1: + printf("LOOP_RREC1 var%d\n", + imcode->operand1); break; - default: - EnvAddCode(CodeAddr[OP_MOD]); - } - EnvAddCode3((void *)(unsigned long)target, - (void *)(unsigned long)newreg, - (void *)(unsigned long)newreg2); - return 1; - break; - } - default: - puts("System ERROR: Wrong AST was given to CompileExpr."); - return 0; + case LOOP_RREC2: + printf("LOOP_RREC2 var%d\n", + imcode->operand1); + break; - } + case LOAD: + printf("LOAD var%d var%d\n", + imcode->operand1, imcode->operand2); + break; -} + case LOADP: + printf("LOADP var%d var%d[%d]\n", + imcode->operand1, imcode->operand2, imcode->operand3); + break; -// Rule や eq の中の term をコンパイルするときに使う -int CompileTermFromAst(Ast *ptr, int target) { - // input: - // target == -1 => a new node is allocated from localHeap. - // othereise => a node specified by the `target' is reused as a new node. - // - // output: - // return: offset in localHeap + case OP_ADD: + printf("ADD var%d var%d var%d\n", + imcode->operand1, imcode->operand2, imcode->operand3); + break; - int result, mkagent; - int i, arity; + case OP_SUB: + printf("SUB var%d var%d var%d\n", + imcode->operand1, imcode->operand2, imcode->operand3); + break; - int alloc[MAX_PORT]; - - if (ptr == NULL) { - return -1; - } + case OP_SUBI: + printf("SUBI var%d var%d $%d\n", + imcode->operand1, imcode->operand2, imcode->operand3); + break; - switch (ptr->id) { - case AST_NAME: - - result = CmEnv_reg_search(ptr->left->sym); - if (result == -1) { - result=CmEnv_set_symbol_as_name(ptr->left->sym); + case OP_MUL: + printf("MUL var%d var%d var%d\n", + imcode->operand1, imcode->operand2, imcode->operand3); + break; + + case OP_DIV: + printf("DIV var%d var%d var%d\n", + imcode->operand1, imcode->operand2, imcode->operand3); + break; + + case OP_MOD: + printf("MOD var%d var%d var%d\n", + imcode->operand1, imcode->operand2, imcode->operand3); + break; + + case OP_LT: + printf("LT var%d var%d var%d\n", + imcode->operand1, imcode->operand2, imcode->operand3); + break; + + case OP_LE: + printf("LE var%d var%d var%d\n", + imcode->operand1, imcode->operand2, imcode->operand3); + break; + + case OP_EQ: + printf("EQ var%d var%d var%d\n", + imcode->operand1, imcode->operand2, imcode->operand3); + break; + + case OP_EQI: + printf("EQI var%d var%d $%d\n", + imcode->operand1, imcode->operand2, imcode->operand3); + break; + + case OP_NE: + printf("NE var%d var%d var%d\n", + imcode->operand1, imcode->operand2, imcode->operand3); + break; + + case OP_JMPEQ0: + printf("JMPEQ0 var%d $%d\n", + imcode->operand1, imcode->operand2); + break; + + case OP_JMPCNCT_CONS: + printf("JMPCNCT_CONS var%d $%d\n", + imcode->operand1, imcode->operand2); + break; + + case OP_JMPCNCT: + printf("JMPCNCT var%d $%d $%d\n", + imcode->operand1, imcode->operand2, imcode->operand3); + break; + + case OP_JMP: + printf("JMP $%d\n", + imcode->operand1); + break; + + case OP_UNM: + printf("UNM var%d $%d\n", + imcode->operand1, imcode->operand2); + break; + + case OP_RAND: + printf("RAND var%d $%d\n", + imcode->operand1, imcode->operand2); + break; + + case CNCTGN: + printf("CNCTGN var%d $%d\n", + imcode->operand1, imcode->operand2); + break; + + case SUBSTGN: + printf("SUBSTGN var%d $%d\n", + imcode->operand1, imcode->operand2); + break; + + case NOP: + printf("NOP\n"); + break; + + default: + printf("CODE %d %d %d %d %d %d\n", + imcode->operand1, imcode->operand2, imcode->operand3, + imcode->operand4, imcode->operand5, imcode->operand6); } - return result; - break; + } +} - case AST_INT: - result = CmEnv_newreg(); - EnvAddCode3(CodeAddr[LOADI], - (void *)(unsigned long)result, - (void *)(unsigned long)(ptr->intval)); - return result; - break; - case AST_NIL: - if (target == -1) { - result = CmEnv_newreg(); - mkagent = MKAGENT; - } else { - result = target; - mkagent = REUSEAGENT; - } - EnvAddCode4(CodeAddr[mkagent], - (void *)(unsigned long)result, - (void *)(unsigned long)(ID_NIL), - (void *)(unsigned long)0); - return result; - break; +void PutsCodeN(void **code, int n) { + int i; + + puts("[PutsCode]"); + if (n==-1) n = MAX_CODE_SIZE; + + for (i=0; ileft, -1); - alloc[1] = CompileTermFromAst(ptr->right, -1); - EnvAddCode6(CodeAddr[mkagent], - (void *)(unsigned long)result, - (void *)(unsigned long)(ID_CONS), - (void *)(unsigned long)(2), - (void *)(unsigned long)alloc[0], - (void *)(unsigned long)alloc[1]); - return result; - break; - - case AST_OPCONS: - if (target == -1) { - result = CmEnv_newreg(); - mkagent = MKAGENT; - } else { - result = target; - mkagent = REUSEAGENT; - } - ptr = ptr->right; - alloc[0] = CompileTermFromAst(ptr->left, -1); - alloc[1] = CompileTermFromAst(ptr->right->left, -1); - EnvAddCode6(CodeAddr[mkagent], - (void *)(unsigned long)result, - (void *)(unsigned long)(ID_CONS), - (void *)(unsigned long)(2), - (void *)(unsigned long)alloc[0], - (void *)(unsigned long)alloc[1]); - return result; - break; + if (code[i] == CodeAddr[MKNAME]) { + printf("MKNAME var%lu\n", (unsigned long)code[i+1]); + i+=1; + + } else if (code[i] == CodeAddr[MKGNAME]) { + printf("MKGNAME var%lu `%s'\n", + (unsigned long)code[i+1], + (char *)code[i+2]); + i+=2; - /* - case AST_TUPLE: - if (target == -1) { - result = CmEnv_newreg(); - mkagent = MKAGENT; - } else { - result = target; - mkagent = REUSEAGENT; - } - arity = ptr->intval; - ptr=ptr->right; - for(i=0; i< MAX_PORT; i++) { - if (ptr == NULL) break; - alloc[i] = CompileTermFromAst(ptr->left, -1); - ptr = ast_getTail(ptr); - } + } else if (code[i] == CodeAddr[MKAGENT0]) { + printf("MKAGENT0 var%lu id:%lu\n", + (unsigned long)code[i+1], + (unsigned long)code[i+2]); + i+=2; - EnvAddCode4(CodeAddr[mkagent], - (void *)(unsigned long)result, - (void *)(unsigned long)(GET_TUPLEID(arity)), - (void *)(unsigned long)(arity)); - for(i=0; i< arity; i++) { - EnvAddCode((void *)(unsigned long)alloc[i]); - } - return result; - break; - */ + } else if (code[i] == CodeAddr[MKAGENT1]) { + printf("MKAGENT1 var%lu id:%lu var%lu\n", + (unsigned long)code[i+1], + (unsigned long)code[i+2], + (unsigned long)code[i+3]); + i+=3; - - case AST_TUPLE: - arity = ptr->intval; + } else if (code[i] == CodeAddr[MKAGENT2]) { + printf("MKAGENT2 var%lu id:%lu var%lu var%lu\n", + (unsigned long)code[i+1], + (unsigned long)code[i+2], + (unsigned long)code[i+3], + (unsigned long)code[i+4]); + i+=4; - if (arity == 1) { - // The case of (A), - // `A' is recognised not as an argument, as a first-class object. - ptr=ptr->right; - alloc[0] = CompileTermFromAst(ptr->left, target); - result = alloc[0]; - - } else { - // normal case - - if (target == -1) { - result = CmEnv_newreg(); - mkagent = MKAGENT; - } else { - result = target; - mkagent = REUSEAGENT; - } + } else if (code[i] == CodeAddr[MKAGENT3]) { + printf("MKAGENT3 var%lu id:%lu var%lu var%lu var%lu\n", + (unsigned long)code[i+1], + (unsigned long)code[i+2], + (unsigned long)code[i+3], + (unsigned long)code[i+4], + (unsigned long)code[i+5]); + i+=5; - ptr=ptr->right; - /* - for(i=0; i< MAX_PORT; i++) { - if (ptr == NULL) break; - alloc[i] = CompileTermFromAst(ptr->left, -1); - ptr = ast_getTail(ptr); - } - */ - for(i=0; i< arity; i++) { - alloc[i] = CompileTermFromAst(ptr->left, -1); - ptr = ast_getTail(ptr); - } - - EnvAddCode4(CodeAddr[mkagent], - (void *)(unsigned long)result, - (void *)(unsigned long)(GET_TUPLEID(arity)), - (void *)(unsigned long)(arity)); - for(i=0; i< arity; i++) { - EnvAddCode((void *)(unsigned long)alloc[i]); - } - - } - - return result; - break; - - - - case AST_AGENT: - - if (target == -1) { - result = CmEnv_newreg(); - mkagent = MKAGENT; - } else { - result = target; - mkagent = REUSEAGENT; - } - - int id = IdTable_getid_builtin_funcAgent(ptr); - if (id == -1) { - id = NameTable_get_set_id((char *)ptr->left->sym); - } - - /* For arity */ - // result->arity = ptr->arity; - arity=0; - ptr=ptr->right; - for(i=0; i< MAX_PORT; i++) { - if (ptr == NULL) break; - alloc[i] = CompileTermFromAst(ptr->left, -1); - arity++; - ptr = ast_getTail(ptr); - } - // MKAGENT var ID ARITY var0 var1 ... - EnvAddCode4(CodeAddr[mkagent], - (void *)(unsigned long)result, - (void *)(unsigned long)id, - (void *)(unsigned long)arity); - IdTable_set_arity(id, arity); - - for(i=0; i< arity; i++) { - EnvAddCode((void *)(unsigned long)alloc[i]); - } - return result; - break; - - case AST_ANNOTATION_L: - case AST_ANNOTATION_R: - if (ptr->id == AST_ANNOTATION_L) { - CmEnv.annotateL = ANNOTATE_REUSE; // *L が出現したことを示す - result = CmEnv.reg_agentL; //VM_OFFSET_ANNOTATE_L; - } else { - CmEnv.annotateR = ANNOTATE_REUSE; // *L が出現したことを示す - result = CmEnv.reg_agentR; // VM_OFFSET_ANNOTATE_R; - } - - - result = CompileTermFromAst(ptr->left, result); - return result; - break; - - - - default: - // expression case - result = CmEnv_newreg(); - int compile_result = CompileExprFromAst(result, ptr); - if (compile_result != 0) { - return result; - } else { - puts("ERROR: something strange in CompileTermFromAst."); - ast_puts(ptr); - exit(1); - } - } - -} - - - - -// rule の中の eqs をコンパイルするときに使う -// この関数が呼ばれる前に、rule agents の meta names は -// Environment に積まれている。 -int check_invalid_occurrence_as_rule(Ast *ast) { - NB_TYPE type; - - if (ast->id == AST_NAME) { - - if (CmEnv_gettype_forname(ast->left->sym, &type)) { - /* - if (type == NB_INTVAR) { - printf("ERROR: The variable '%s' for an integer cannot be used as an agent ", - ast->left->sym); - return 0; - } - */ - } else { - // printf("ERROR: The name '%s' is not bound ", ast->left->sym); - // return 0; - } - } else if (ast->id == AST_INT) { - // printf("ERROR: The integer '%d' is used as an agent ", - // ast->intval); - // return 0; - } - - return 1; -} - - -int check_invalid_occurrence(Ast *ast) { - // communication with global names - int count; - - if (ast->id == AST_NAME) { - char *sym = ast->left->sym; - - - VALUE aheap = NameTable_get_heap(sym); - if (aheap != (VALUE)NULL) { - // already exists as a global - - /* - // it is connected with something. - if (NAME(aheap)->port != (VALUE)NULL) { - printf("ERROR: '%s' is already connected with ", sym); - puts_term(NAME(aheap)->port); - puts("."); - return 1; - } - */ - - count = keynode_exists_in_another_term(aheap, NULL); - if (count == 2) { - // already twice - printf("ERROR: '%s' occurs twice already. \n", sym); - printf(" Use 'ifce' command to see the occurrence.\n"); - return 1; - } - - } - } - - - return 0; -} - - - -int CompileEQListFromAst(Ast *at) { - int t1,t2; - Ast *next; - - while (at!=NULL) { - if (!check_invalid_occurrence_as_rule(at->left->left) || - !check_invalid_occurrence_as_rule(at->left->right)) { - return 0; - } - - t1 = CompileTermFromAst(at->left->left, -1); - t2 = CompileTermFromAst(at->left->right, -1); - - next = ast_getTail(at); - - // 2021/9/6: It seems, always EnvAddCodePUSH is selected - // because at is not NULL in this step. Should be (next == NULL)? - // - // 2021/9/12: It is found that at==NULL faster than next==NULL - // in parallel execution. - - /* - if (at == NULL) { - EnvAddCodeMYPUSH((void *)(unsigned long)t1, (void *)(unsigned long)t2); - } else { - EnvAddCodePUSH((void *)(unsigned long)t1, (void *)(unsigned long)t2); - } - */ - EnvAddCodePUSH((void *)(unsigned long)t1, (void *)(unsigned long)t2); - - at = next; - } - - return 1; -} - -void Compile_Put_Ret_ForRuleBody() { - - if ((CmEnv.annotateL == ANNOTATE_NOTHING) && - (CmEnv.annotateR == ANNOTATE_NOTHING)) { - EnvAddCode(CodeAddr[RET_FREE_LR]); - - } else if ((CmEnv.annotateL == ANNOTATE_NOTHING) && - (CmEnv.annotateR != ANNOTATE_NOTHING)) { - // FreeL - if (CmEnv.reg_agentL == VM_OFFSET_ANNOTATE_L) { - EnvAddCode(CodeAddr[RET_FREE_L]); - } else { - EnvAddCode(CodeAddr[RET_FREE_R]); - } - - } else if ((CmEnv.annotateL != ANNOTATE_NOTHING) && - (CmEnv.annotateR == ANNOTATE_NOTHING)) { - // FreeR - if (CmEnv.reg_agentL == VM_OFFSET_ANNOTATE_L) { - EnvAddCode(CodeAddr[RET_FREE_R]); - } else { - EnvAddCode(CodeAddr[RET_FREE_L]); - } - } else { - EnvAddCode(CodeAddr[RET]); - } - -} - - -int CompileStmListFromAst(Ast *at) { - Ast *ptr; - int toRegLeft; - - while (at!=NULL) { - ptr=at->left; - - // (AST_LD (AST_NAME sym NULL) some) - if (ptr->id != AST_LD) { - puts("System ERROR: The given StmList contains something besides statements."); - exit(-1); - } - // operation of x=y: - // for the x - toRegLeft = CmEnv_reg_search(ptr->left->left->sym); - if (toRegLeft == -1) { - toRegLeft = CmEnv_set_as_INTVAR(ptr->left->left->sym); - } else { - printf("Warning: '%s' has been already defined.\n", ptr->left->left->sym); - } - - // for the y - if (ptr->right->id == AST_NAME) { - // y is a name - int toRegRight = CmEnv_reg_search(ptr->right->left->sym); - if (toRegRight == -1) { - toRegRight = CmEnv_set_as_INTVAR(ptr->right->left->sym); - } - EnvAddCode3(CodeAddr[LOAD], - (void *)(unsigned long)toRegLeft, - (void *)(unsigned long)toRegRight); + } else if (code[i] == CodeAddr[MKAGENT4]) { + printf("MKAGENT4 var%lu id:%lu var%lu var%lu var%lu var%lu\n", + (unsigned long)code[i+1], + (unsigned long)code[i+2], + (unsigned long)code[i+3], + (unsigned long)code[i+4], + (unsigned long)code[i+5], + (unsigned long)code[i+6]); + i+=6; + + } else if (code[i] == CodeAddr[MKAGENT5]) { + printf("MKAGENT5 var%lu id:%lu var%lu var%lu var%lu var%lu var%lu\n", + (unsigned long)code[i+1], + (unsigned long)code[i+2], + (unsigned long)code[i+3], + (unsigned long)code[i+4], + (unsigned long)code[i+5], + (unsigned long)code[i+6], + (unsigned long)code[i+7]); + i+=7; + + } else if (code[i] == CodeAddr[REUSEAGENT0]) { + printf("REUSEAGENT0 var%lu as id=%lu", + (unsigned long)code[i+1], + (unsigned long)code[i+2]); + puts(""); + i+=2; - } else if (ptr->right->id == AST_INT) { - // y is an integer - EnvAddCode3(CodeAddr[LOADI], - (void *)(unsigned long)toRegLeft, - (void *)(unsigned long)ptr->right->intval); + } else if (code[i] == CodeAddr[REUSEAGENT1]) { + printf("REUSEAGENT0 var%lu as id=%lu", + (unsigned long)code[i+1], + (unsigned long)code[i+2]); + printf(" var%lu", (unsigned long)code[i+3]); + puts(""); + i+=3; - } else { - // y is an expression - if (!CompileExprFromAst(toRegLeft, ptr->right)) return 0; - - } - - - - at = ast_getTail(at); - } - - return 1; -} - - - - -// --- BEGIN: Rewrite Optimisation --- -Ast* Ast_Subst(char *sym, Ast *aterm, Ast *target, int *result) { - // target is astterm: (AST asttermL asttermR) - // this function replaces sym with aterm in target, i.e. tgs[aterm/sym]. - - switch (target->id) { - case AST_NAME: - - if (strcmp(target->left->sym, sym) == 0) { - *result = 1; - return aterm; + } else if (code[i] == CodeAddr[REUSEAGENT2]) { + printf("REUSEAGENT2 var%lu as id=%lu", + (unsigned long)code[i+1], + (unsigned long)code[i+2]); + printf(" var%lu", (unsigned long)code[i+3]); + printf(" var%lu", (unsigned long)code[i+4]); + puts(""); + i+=4; + + } else if (code[i] == CodeAddr[REUSEAGENT3]) { + printf("REUSEAGENT3 var%lu as id=%lu", + (unsigned long)code[i+1], + (unsigned long)code[i+2]); + printf(" var%lu", (unsigned long)code[i+3]); + printf(" var%lu", (unsigned long)code[i+4]); + printf(" var%lu", (unsigned long)code[i+5]); + puts(""); + i+=5; - } else { - return target; - } - break; + } else if (code[i] == CodeAddr[REUSEAGENT4]) { + printf("REUSEAGENT4 var%lu as id=%lu", + (unsigned long)code[i+1], + (unsigned long)code[i+2]); + printf(" var%lu", (unsigned long)code[i+3]); + printf(" var%lu", (unsigned long)code[i+4]); + printf(" var%lu", (unsigned long)code[i+5]); + printf(" var%lu", (unsigned long)code[i+6]); + puts(""); + i+=6; - case AST_OPCONS: - target->right = Ast_Subst(sym, aterm, target->right, result); - return target; - - case AST_CONS: - target->left = Ast_Subst(sym, aterm, target->left, result); - if (*result) { - return target; - } else { - target->right = Ast_Subst(sym, aterm, target->right, result); - return target; - } + } else if (code[i] == CodeAddr[REUSEAGENT5]) { + printf("REUSEAGENT5 var%lu as id=%lu", + (unsigned long)code[i+1], + (unsigned long)code[i+2]); + printf(" var%lu", (unsigned long)code[i+3]); + printf(" var%lu", (unsigned long)code[i+4]); + printf(" var%lu", (unsigned long)code[i+5]); + printf(" var%lu", (unsigned long)code[i+6]); + printf(" var%lu", (unsigned long)code[i+7]); + puts(""); + i+=7; + + } else if (code[i] == CodeAddr[PUSH]) { + printf("PUSH var%lu var%lu\n", + (unsigned long)code[i+1], + (unsigned long)code[i+2]); + i+=2; + } else if (code[i] == CodeAddr[PUSHI]) { + printf("PUSHI var%lu $%d\n", + (unsigned long)code[i+1], + FIX2INT((unsigned long)code[i+2])); + i+=2; - case AST_ANNOTATION_L: - case AST_ANNOTATION_R: + } else if (code[i] == CodeAddr[MYPUSH]) { + printf("MYPUSH var%lu var%lu\n", + (unsigned long)code[i+1], + (unsigned long)code[i+2]); + i+=2; - - case AST_TUPLE: - case AST_AGENT: - { - Ast *port; - if ((target->id == AST_ANNOTATION_L) || - (target->id == AST_ANNOTATION_R)) { + } else if (code[i] == CodeAddr[RET]) { + puts("RET"); - // (AST_ANNOTATION (AST_AGENT (ID_SYM sym NULL) paramlist) NULL) - port = target->left->right; - } else { - - // (AST_AGENT (ID_SYM sym NULL) paramlist) - port = target->right; - } - - for(int i=0; i< MAX_PORT; i++) { - if (port == NULL) break; - - port->left = Ast_Subst(sym, aterm, port->left, result); - if (*result) break; - - port = ast_getTail(port); - } - } - return target; - - case AST_LIST: - { - Ast *elem = target->right; + } else if (code[i] == CodeAddr[RET_FREE_L]) { + puts("RET_FREE_L"); - while (elem != NULL) { - elem = Ast_Subst(sym, aterm, elem, result); - if (*result) break; - - elem = ast_getTail(elem); - } - } - return target; + } else if (code[i] == CodeAddr[RET_FREE_R]) { + puts("RET_FREE_R"); - default: - return target; - } + } else if (code[i] == CodeAddr[RET_FREE_LR]) { + puts("RET_FREE_LR"); -} + } else if (code[i] == CodeAddr[LOADI]) { + printf("LOADI var%lu $%lu\n", + (unsigned long)code[i+1], + (unsigned long)code[i+2]); + i+=2; + + } else if (code[i] == CodeAddr[LOOP]) { + puts("LOOP\n"); + } else if (code[i] == CodeAddr[LOOP_RREC]) { + printf("LOOP_RREC var%lu $%lu\n", + (unsigned long)code[i+1], + (unsigned long)code[i+2]); + i+=2; -int Ast_Subst_EQList(int nth, char *sym, Ast *aterm, Ast *eqlist) { - // eqlist[aterm/sym] except for n-th eq + } else if (code[i] == CodeAddr[LOOP_RREC1]) { + printf("LOOP_RREC1 var%lu\n", + (unsigned long)code[i+1]); + i+=1; - Ast *eq, *at = eqlist; - int ct = 0; - int result; + } else if (code[i] == CodeAddr[LOOP_RREC2]) { + printf("LOOP_RREC2 var%lu\n", + (unsigned long)code[i+1]); + i+=1; - while (at != NULL) { - eq = at->left; + } else if (code[i] == CodeAddr[LOAD]) { + printf("LOAD var%lu var%lu\n", + (unsigned long)code[i+1], + (unsigned long)code[i+2]); + i+=2; - if (ct == nth) { - ct++; - at = ast_getTail(at); - continue; - } - - result=0; - eq->left = Ast_Subst(sym, aterm, eq->left, &result); - - if (result) { - return 1; - } - - result=0; - eq->right = Ast_Subst(sym, aterm, eq->right, &result); + } else if (code[i] == CodeAddr[LOADP]) { + printf("LOADP var%lu var%lu[%lu]\n", + (unsigned long)code[i+1], + (unsigned long)code[i+2], + (unsigned long)code[i+3]); + i+=3; - if (result) { - return 1; - } + } else if (code[i] == CodeAddr[OP_ADD]) { + printf("ADD var%lu var%lu var%lu\n", + (unsigned long)code[i+1], + (unsigned long)code[i+2], + (unsigned long)code[i+3]); + i+=3; - ct++; - at = ast_getTail(at); + } else if (code[i] == CodeAddr[OP_SUB]) { + printf("SUB var%lu var%lu var%lu\n", + (unsigned long)code[i+1], + (unsigned long)code[i+2], + (unsigned long)code[i+3]); + i+=3; - } + } else if (code[i] == CodeAddr[OP_SUBI]) { + printf("SUBI var%lu var%lu $%ld\n", + (unsigned long)code[i+1], + (unsigned long)code[i+2], + (long int)code[i+3]); + i+=3; - return 0; -} + } else if (code[i] == CodeAddr[OP_MUL]) { + printf("MUL var%lu var%lu var%lu\n", + (unsigned long)code[i+1], + (unsigned long)code[i+2], + (unsigned long)code[i+3]); + i+=3; + } else if (code[i] == CodeAddr[OP_DIV]) { + printf("DIV var%lu var%lu var%lu\n", + (unsigned long)code[i+1], + (unsigned long)code[i+2], + (unsigned long)code[i+3]); + i+=3; -void Ast_RewriteOptimisation_EQList(Ast *eqlist) { - // Every eq such as x~t in eqlist is replaced as eqlist[t/x]. - // - // Structure - // eqlist : (AST_LIST eq1 (AST_LIST eq2 (AST_LIST eq3 NULL))) - // eq : (AST_CNCT astterm1 astterm2) - - Ast *at, *prev, *target, *term; - char *sym; - int nth=0, exists_in_table; - NB_TYPE type = NB_NAME; + } else if (code[i] == CodeAddr[OP_MOD]) { + printf("MOD var%lu var%lu var%lu\n", + (unsigned long)code[i+1], + (unsigned long)code[i+2], + (unsigned long)code[i+3]); + i+=3; - at = prev = eqlist; - - while (at != NULL) { - // (id, left, right) - // at : (AST_LIST, x1, NULL) - // at : (AST_LIST, x1, (AST_LIST, x2, NULL)) - target = at->left; + } else if (code[i] == CodeAddr[OP_LT]) { + printf("LT var%lu var%lu var%lu\n", + (unsigned long)code[i+1], + (unsigned long)code[i+2], + (unsigned long)code[i+3]); + i+=3; - // printf("\n[target] "); ast_puts(target); - // printf("\n%dnth in ", nth); ast_puts(eqlist); printf("\n\n"); + } else if (code[i] == CodeAddr[OP_LE]) { + printf("LE var%lu var%lu var%lu\n", + (unsigned long)code[i+1], + (unsigned long)code[i+2], + (unsigned long)code[i+3]); + i+=3; + } else if (code[i] == CodeAddr[OP_EQ]) { + printf("EQ var%lu var%lu var%lu\n", + (unsigned long)code[i+1], + (unsigned long)code[i+2], + (unsigned long)code[i+3]); + i+=3; - // NB_NAME=0, - // NB_META, - // NB_INTVAR, + } else if (code[i] == CodeAddr[OP_EQI]) { + printf("EQI var%lu var%lu $%ld\n", + (unsigned long)code[i+1], + (unsigned long)code[i+2], + (long int)code[i+3]); + i+=3; - if (target->left->id == AST_NAME) { + } else if (code[i] == CodeAddr[OP_NE]) { + printf("NE var%lu var%lu var%lu\n", + (unsigned long)code[i+1], + (unsigned long)code[i+2], + (unsigned long)code[i+3]); + i+=3; - sym = target->left->left->sym; - exists_in_table=CmEnv_gettype_forname(sym, &type); - - if ((!exists_in_table) || - (type == NB_NAME)){ - // When no entry in CmEnv table or its type is NB_NAME - - term = target->right; - // printf("%s~",sym); ast_puts(term); puts(""); - - if (Ast_Subst_EQList(nth, sym, term, eqlist)) { - // printf("=== hit %dth\n", nth); - - if (prev != at) { - // 前のリストの接続先を、現在地を省いて、その次の要素に変更。 - prev->right = at->right; - at = at->right; - } else { - // 先頭の要素が代入に使われたので、 - // body 内の eqlist から先頭を削除 - // (AST_LIST, x1, (AST_LIST, x2, *next)) ==> (AST_LIST, x2, *next) - eqlist->left = eqlist->right->left; - eqlist->right = eqlist->right->right; - eqlist = eqlist->right; - // 対象 at を次の要素に更新し、prev も at とする - prev = at = at->right; - } - - continue; - } - } - - } + } else if (code[i] == CodeAddr[OP_JMPEQ0]) { + printf("JMPEQ0 var%lu $%lu\n", + (unsigned long)code[i+1], + (unsigned long)code[i+2]); + i+=2; - - if (target->right->id == AST_NAME) { - sym = target->right->left->sym; - exists_in_table=CmEnv_gettype_forname(sym, &type); + } else if (code[i] == CodeAddr[OP_JMPCNCT_CONS]) { + printf("JMPCNCT_CONS var%lu $%lu\n", + (unsigned long)code[i+1], + (unsigned long)code[i+2]); + i+=2; - if ((!exists_in_table) || - (type == NB_NAME)){ - // When no entry in CmEnv table or its type is NB_NAME - - term = target->left; - // ast_puts(term); printf("~%s",sym);puts(""); + } else if (code[i] == CodeAddr[OP_JMPCNCT]) { + printf("JMPCNCT var%lu $%lu $%lu\n", + (unsigned long)code[i+1], + (unsigned long)code[i+2], + (unsigned long)code[i+3]); + i+=2; - if (Ast_Subst_EQList(nth, sym, term, eqlist)) { - // printf("=== hit %dth\n", nth); - - if (prev != at) { - // 前のリストの接続先を、現在地を省いて、その次の要素に変更。 - prev->right = at->right; - at = at->right; - } else { - // 先頭の要素が代入に使われたので、 - // body 内の eqlist から先頭を削除 - // (AST_LIST, x1, (AST_LIST, x2, *next)) ==> (AST_LIST, x2, *next) - eqlist->left = eqlist->right->left; - eqlist->right = eqlist->right->right; - eqlist = eqlist->right; - // 対象 at を次の要素に更新し、prev も at とする - prev = at = at->right; - } + } else if (code[i] == CodeAddr[OP_JMP]) { + printf("JMP $%lu\n", (unsigned long)code[i+1]); + i+=1; - continue; + } else if (code[i] == CodeAddr[OP_UNM]) { + printf("UNM var%lu var%lu\n", + (unsigned long)code[i+1], + (unsigned long)code[i+2]); + i+=1; - } - } - } + } else if (code[i] == CodeAddr[OP_RAND]) { + printf("RND var%lu var%lu\n", + (unsigned long)code[i+1], + (unsigned long)code[i+2]); + i+=2; - nth++; - prev = at; - at = at->right; - + } else if (code[i] == CodeAddr[CNCTGN]) { + printf("CNCTGN var%lu var%lu\n", + (unsigned long)code[i+1], + (unsigned long)code[i+2]); + i+=2; + + } else if (code[i] == CodeAddr[SUBSTGN]) { + printf("SUBSTGN var%lu var%lu\n", + (unsigned long)code[i+1], + (unsigned long)code[i+2]); + i+=2; + + } else if (code[i] == CodeAddr[NOP]) { + puts("NOP"); + + } else { + printf("CODE %lu\n", (unsigned long)code[i]); + } } } -// --- END: Rewrite Optimisation --- +void PutsCode(void **code) { + PutsCodeN(code, -1); +} -int CompileBodyFromAst(Ast *body) { - Ast *stms, *eqs; - if (body == NULL) return 1; - - stms = body->left; - eqs = body->right; - - Ast_RewriteOptimisation_EQList(eqs); - if (!CompileStmListFromAst(stms)) return 0; - if (!CompileEQListFromAst(eqs)) { - printf("in the rule:\n %s >< %s\n", - IdTable_get_name(CmEnv.idL), - IdTable_get_name(CmEnv.idR)); +int is_expr(Ast *ptr) { + + if (ptr == NULL) { return 0; } - return 1; + switch (ptr->id) { + case AST_INT: + return 1; + break; + + case AST_NAME: { + NB_TYPE type; + int result = CmEnv_gettype_forname(ptr->left->sym, &type); + if (result == 0) { + return 9; + } + if (type != NB_INTVAR) { + return 0; + } + + return 1; + break; + } + + case AST_RAND: + case AST_UNM: { + if (!is_expr(ptr->left)) return 0; + + return 1; + break; + } + + case AST_PLUS: + case AST_SUB: + case AST_MUL: + case AST_DIV: + case AST_MOD: + case AST_LT: + case AST_LE: + case AST_EQ: + case AST_NE: { + if (!is_expr(ptr->left)) return 0; + if (!is_expr(ptr->right)) return 0; + + return 1; + break; + } + default: + return 0; + } } - +int CompileExprFromAst(Ast *ptr, int target) { + if (ptr == NULL) { + return 1; + } -/************************************** - TABLE for RULES -**************************************/ -typedef struct RuleList { - int sym; - int available; - void* code[MAX_CODE_SIZE]; - struct RuleList *next; -} RuleList; + switch (ptr->id) { + case AST_INT: + IMCode_genCode2(LOADI, target, ptr->intval); + return 1; + break; -RuleList *RuleList_new() { - RuleList *alist; - alist = malloc(sizeof(RuleList)); - if (alist == NULL) { - printf("Malloc error\n"); - exit(-1); + case AST_NAME: { + int result = CmEnv_reg_search(ptr->left->sym); + if (result == -1) { + // result=CmEnv_set_as_INTVAR(ptr->left->sym); + printf("ERROR: '%s' has not been defined previously.\n", + ptr->left->sym); + return 0; + } + + IMCode_genCode2(LOAD, target, result); + return 1; + break; } - alist->available = 0; - return alist; -} + case AST_RAND: { + int newreg = CmEnv_newreg(); + if (!CompileExprFromAst(ptr->left, newreg)) return 0; + + IMCode_genCode2(OP_RAND, target, newreg); + return 1; + break; + } + case AST_UNM: { + int newreg = CmEnv_newreg(); + if (!CompileExprFromAst(ptr->left, newreg)) return 0; + + IMCode_genCode2(OP_UNM, target, newreg); + return 1; + break; + } + case AST_PLUS: + case AST_SUB: + case AST_MUL: + case AST_DIV: + case AST_MOD: + case AST_LT: + case AST_LE: + case AST_EQ: + case AST_NE: { + int newreg = CmEnv_newreg(); + int newreg2 = CmEnv_newreg(); + if (!CompileExprFromAst(ptr->left, newreg)) return 0; + if (!CompileExprFromAst(ptr->right, newreg2)) return 0; -void RuleList_set_code(RuleList *at, int sym, void **code, int byte, RuleList *next) { - at->sym = sym; - at->available = 1; - CopyCode(byte, code, at->code); - at->next = next; -} + int opcode; + switch (ptr->id) { + case AST_PLUS: + opcode = OP_ADD; + break; + case AST_SUB: + opcode = OP_SUB; + break; + case AST_MUL: + opcode = OP_MUL; + break; + case AST_DIV: + opcode = OP_DIV; + break; + case AST_MOD: + opcode = OP_MOD; + break; + case AST_LT: + opcode = OP_LT; + break; + case AST_LE: + opcode = OP_LE; + break; + case AST_EQ: + opcode = OP_EQ; + break; + case AST_NE: + opcode = OP_NE; + break; + default: + opcode = OP_MOD; + } + + IMCode_genCode3(opcode, target, newreg, newreg2); + return 1; + break; + } + default: + puts("System ERROR: Wrong AST was given to CompileExpr."); + return 0; + + } -void RuleList_inavailable(RuleList *at) { - at->available = 0; } +// Rule や eq の中の term をコンパイルするときに使う +int CompileTermFromAst(Ast *ptr, int target) { + // input: + // target == -1 => a new node is allocated from localHeap. + // otherwise => a node specified by the `target' is reused as a new node. + // + // output: + // return: offset in localHeap -#define RULEHASH_SIZE NUM_AGENTS -static RuleList *RuleTable[RULEHASH_SIZE]; + int result, mkagent; + int i, arity; -void RuleTable_init() { - int i; - for (i=0; iid) { + case AST_NAME: + + result = CmEnv_reg_search(ptr->left->sym); + if (result == -1) { + result=CmEnv_set_symbol_as_name(ptr->left->sym); + IMCode_genCode1(MKNAME, result); + } + return result; + break; -void RuleTable_record(int symlID, int symrID, int byte, void **code) { + case AST_INT: + result = CmEnv_newreg(); + + IMCode_genCode2(LOADI, result, ptr->intval); + return result; + break; - RuleList *add; + case AST_NIL: + if (target == -1) { + result = CmEnv_newreg(); + mkagent = MKAGENT0; + } else { + result = target; + mkagent = REUSEAGENT0; + } - if (RuleTable[symlID] == NULL) { /* もしテーブルが空ならば */ - add = RuleList_new(); /* データノードを作成し */ + IMCode_genCode2(mkagent, result, ID_NIL); + return result; + break; - RuleList_set_code(add, symrID, code, byte, NULL); - RuleTable[symlID] = add; /* 単にセット */ - return; - } + case AST_CONS: + if (target == -1) { + result = CmEnv_newreg(); + mkagent = MKAGENT2; + } else { + result = target; + mkagent = REUSEAGENT2; + } + alloc[0] = CompileTermFromAst(ptr->left, -1); + alloc[1] = CompileTermFromAst(ptr->right, -1); + + IMCode_genCode4(mkagent, result, ID_CONS, alloc[0], alloc[1]); + return result; + break; - /* 線形探査が必要 */ - RuleList *at = RuleTable[symlID]; // 先頭をセット - while( at != NULL ) { - if( at->sym == symrID) { // すでにあれば書き換える - CopyCode(byte, code, at->code); - return; + case AST_OPCONS: + if (target == -1) { + result = CmEnv_newreg(); + mkagent = MKAGENT2; + } else { + result = target; + mkagent = REUSEAGENT2; } - at = at->next; - } - - // key がなかったら、 先頭に追加 - - /* 以前の先頭を自分の次にする */ - add = RuleList_new(); - RuleList_set_code(add, symrID, code, byte, RuleTable[symlID]); - RuleTable[symlID] = add; - return; -} + ptr = ptr->right; + alloc[0] = CompileTermFromAst(ptr->left, -1); + alloc[1] = CompileTermFromAst(ptr->right->left, -1); + IMCode_genCode4(mkagent, result, ID_CONS, alloc[0], alloc[1]); + return result; + break; -void RuleTable_delete(int symlID, int symrID) { - - if (RuleTable[symlID] == NULL) { /* もしテーブルが空ならば */ - // 何もしない - return; - - } - - /* 線形探査が必要 */ - RuleList *at = RuleTable[symlID]; /* 先頭をセット */ - while( at != NULL ) { - if( at->sym == symrID) { /* すでにあれば書き換える */ - RuleList_inavailable(at); - return; + case AST_TUPLE: + arity = ptr->intval; + + if (arity == 1) { + // The case of the single tuple such as `(A)'. + // The `A' is recognised as not an argument, but as a first-class object. + ptr=ptr->right; + alloc[0] = CompileTermFromAst(ptr->left, target); + result = alloc[0]; + + } else { + // normal case + ptr=ptr->right; + for(i=0; i< arity; i++) { + alloc[i] = CompileTermFromAst(ptr->left, -1); + ptr = ast_getTail(ptr); + } + + if (target == -1) { + result = CmEnv_newreg(); + } else { + result = target; + } + + switch (arity) { + case 0: + if (target == -1) { + mkagent = MKAGENT0; + } else { + mkagent = REUSEAGENT0; + } + IMCode_genCode2(mkagent, result, GET_TUPLEID(arity)); + break; + + + case 2: + if (target == -1) { + mkagent = MKAGENT2; + } else { + mkagent = REUSEAGENT2; + } + IMCode_genCode4(mkagent, result, GET_TUPLEID(arity), + alloc[0], alloc[1]); + break; + + case 3: + if (target == -1) { + mkagent = MKAGENT3; + } else { + mkagent = REUSEAGENT3; + } + IMCode_genCode5(mkagent, result, GET_TUPLEID(arity), + alloc[0], alloc[1], alloc[2]); + break; + + case 4: + if (target == -1) { + mkagent = MKAGENT4; + } else { + mkagent = REUSEAGENT4; + } + IMCode_genCode6(mkagent, result, GET_TUPLEID(arity), + alloc[0], alloc[1], alloc[2], alloc[3]); + break; + + default: + if (target == -1) { + mkagent = MKAGENT5; + } else { + mkagent = REUSEAGENT5; + } + IMCode_genCode7(mkagent, result, GET_TUPLEID(arity), + alloc[0], alloc[1], alloc[2], alloc[3], alloc[4]); + + } + } - at = at->next; /* 次のチェーンを辿る */ - } -} + return result; + break; + + + case AST_AGENT: + if (target == -1) { + result = CmEnv_newreg(); + } else { + result = target; + } + + int id = IdTable_getid_builtin_funcAgent(ptr); + if (id == -1) { + id = NameTable_get_set_id((char *)ptr->left->sym); + } + arity=0; + ptr=ptr->right; + for(i=0; i< MAX_PORT; i++) { + if (ptr == NULL) break; + alloc[i] = CompileTermFromAst(ptr->left, -1); + arity++; + ptr = ast_getTail(ptr); + } + + IdTable_set_arity(id, arity); + switch (arity) { + case 0: + if (target == -1) { + mkagent = MKAGENT0; + } else { + mkagent = REUSEAGENT0; + } + IMCode_genCode2(mkagent, result, id); + break; + + case 1: + if (target == -1) { + mkagent = MKAGENT1; + } else { + mkagent = REUSEAGENT1; + } + IMCode_genCode3(mkagent, result, id, alloc[0]); + break; + + case 2: + if (target == -1) { + mkagent = MKAGENT2; + } else { + mkagent = REUSEAGENT2; + } + IMCode_genCode4(mkagent, result, id, alloc[0], alloc[1]); + break; + + case 3: + if (target == -1) { + mkagent = MKAGENT3; + } else { + mkagent = REUSEAGENT3; + } + IMCode_genCode5(mkagent, result, id, alloc[0], alloc[1], alloc[2]); + break; -// ------------------------------------------------------------- + case 4: + if (target == -1) { + mkagent = MKAGENT4; + } else { + mkagent = REUSEAGENT4; + } + IMCode_genCode6(mkagent, result, id, alloc[0], alloc[1], alloc[2], + alloc[3]); + break; + + default: + if (target == -1) { + mkagent = MKAGENT5; + } else { + mkagent = REUSEAGENT5; + } + IMCode_genCode7(mkagent, result, id, alloc[0], alloc[1], alloc[2], + alloc[3], alloc[4]); + break; + } + + return result; + break; -int getArityFromAST(Ast *ast) { - int i; - Ast *ptr; + + case AST_ANNOTATION_L: + case AST_ANNOTATION_R: + if (ptr->id == AST_ANNOTATION_L) { + CmEnv.annotateL = ANNOTATE_REUSE; // *L が出現したことを示す + result = CmEnv.reg_agentL; //VM_OFFSET_ANNOTATE_L; + } else { + CmEnv.annotateR = ANNOTATE_REUSE; // *L が出現したことを示す + result = CmEnv.reg_agentR; // VM_OFFSET_ANNOTATE_R; + } - ptr = ast->right; - for (i=0; ileft, result); + return result; + break; -// setMetaL(Ast *ast) -// A(x1,x2) が ast に与えられれば、rule 内で x1, x2 が -// VM のレジスタである VM_OFFSET_META_L(0)番、VM_OFFSET_META_L(1)番を -// 参照できるようにする。 -void setMetaL(Ast *ast) { - int i; - Ast *ptr; - NB_TYPE type; - - ptr = ast->right; - for (i=0; ileft->id == AST_NAME) { - type = NB_META; - } else { - type = NB_INTVAR; - } - CmEnv_set_symbol_as_meta(ptr->left->left->sym, VM_OFFSET_META_L(i), type); - ptr = ast_getTail(ptr); - } -} -void setMetaR(Ast *ast) { - int i; - Ast *ptr; - NB_TYPE type; - - ptr = ast->right; - for (i=0; ileft->id == AST_NAME) { - type = NB_META; + + default: + // expression case + result = CmEnv_newreg(); + int compile_result = CompileExprFromAst(ptr, result); + if (compile_result != 0) { + return result; } else { - type = NB_INTVAR; - } - CmEnv_set_symbol_as_meta(ptr->left->left->sym, VM_OFFSET_META_R(i), type); - ptr = ast_getTail(ptr); + puts("ERROR: something strange in CompileTermFromAst."); + ast_puts(ptr); + exit(1); + } } -} -void setMetaL_asIntName(Ast *ast) { - //CmEnv_set_symbol_as_meta(ast->left->sym, VM_OFFSET_META_L(0), NB_INTVAR); - CmEnv_set_symbol_as_meta(ast->left->sym, CmEnv.reg_agentL, NB_INTVAR); - } -void setMetaR_asIntName(Ast *ast) { - // CmEnv_set_symbol_as_meta(ast->left->sym, VM_OFFSET_META_R(0), NB_INTVAR); - CmEnv_set_symbol_as_meta(ast->left->sym, CmEnv.reg_agentR, NB_INTVAR); -} -void setAnnotateLR(int left, int right) { - CmEnv.reg_agentL = left; - CmEnv.reg_agentR = right; +// rule の中の eqs をコンパイルするときに使う +// この関数が呼ばれる前に、rule agents の meta names は +// Environment に積まれている。 +int check_invalid_occurrence_as_rule(Ast *ast) { + NB_TYPE type; + + if (ast->id == AST_NAME) { + + if (CmEnv_gettype_forname(ast->left->sym, &type)) { + /* + if (type == NB_INTVAR) { + printf("ERROR: The variable '%s' for an integer cannot be used as an agent ", + ast->left->sym); + return 0; + } + */ + } else { + // printf("ERROR: The name '%s' is not bound ", ast->left->sym); + // return 0; + } + } else if (ast->id == AST_INT) { + // printf("ERROR: The integer '%d' is used as an agent ", + // ast->intval); + // return 0; + } + + return 1; } +int check_invalid_occurrence(Ast *ast) { + // communication with global names + int count; -int getRuleAgentID(Ast *ruleAgent) { - // Returns agents ids of ast type. - // This is called from makeRule to get ids of rule agents. - - int id; + if (ast->id == AST_NAME) { + char *sym = ast->left->sym; - if (ruleAgent->id == AST_TUPLE) { - id = GET_TUPLEID(ruleAgent->intval); - - } else if (ruleAgent->id == AST_OPCONS) { - id = ID_CONS; - } else if (ruleAgent->id == AST_NIL) { - id = ID_NIL; - - } else if (ruleAgent->id == AST_INTVAR) { - id = ID_INT; - - } else if (strcmp((char *)ruleAgent->left->sym, "Int") == 0) { - id = ID_INTAGENT; - } else { + VALUE aheap = NameTable_get_heap(sym); + if (aheap != (VALUE)NULL) { + // already exists as a global - id = IdTable_getid_builtin_funcAgent(ruleAgent); - if (id == -1) { - id=NameTable_get_set_id(ruleAgent->left->sym); + /* + // it is connected with something. + if (NAME(aheap)->port != (VALUE)NULL) { + printf("ERROR: '%s' is already connected with ", sym); + puts_term(NAME(aheap)->port); + puts("."); + return 1; + } + */ + + count = keynode_exists_in_another_term(aheap, NULL); + if (count == 2) { + // already twice + printf("ERROR: '%s' occurs twice already. \n", sym); + printf(" Use 'ifce' command to see the occurrence.\n"); + return 1; + } + } } - - return id; -} + + return 0; +} +int CompileEQListFromAst(Ast *at) { + int t1,t2; + Ast *next; + + while (at!=NULL) { + if (!check_invalid_occurrence_as_rule(at->left->left) || + !check_invalid_occurrence_as_rule(at->left->right)) { + return 0; + } + t1 = CompileTermFromAst(at->left->left, -1); + t2 = CompileTermFromAst(at->left->right, -1); -int CompileIfSentenceFromAST(Ast *if_sentence_top, - void **code, int offset_code) { - // return - // generated codesize - // -1 : compile error - - // ::= (AST_IF guard (AST_BRANCH )) - // | - // ::= - // ::= + next = ast_getTail(at); - Ast *if_sentence; - - int generated_codesize; // コンパイルで生成されたコード数保存用 + // 2021/9/6: It seems, always EnvAddCodePUSH is selected + // because at is not NULL in this step. Should be (next == NULL)? + // + // 2021/9/12: It is found that at==NULL faster than next==NULL + // in parallel execution. - if_sentence = if_sentence_top; + /* + if (at == NULL) { + EnvAddCodeMYPUSH((void *)(unsigned long)t1, (void *)(unsigned long)t2); + } else { + EnvAddCodePUSH((void *)(unsigned long)t1, (void *)(unsigned long)t2); + } + */ + IMCode_genCode2(PUSH, t1, t2); - CmEnv_clear_keeping_rule_properties(); + + at = next; + } + return 1; +} - if ((if_sentence == NULL) || (if_sentence->id == AST_BODY)) { - // 通常コンパイル - Ast *body = if_sentence; +void Compile_Put_Ret_ForRuleBody() { + + if ((CmEnv.annotateL == ANNOTATE_NOTHING) && + (CmEnv.annotateR == ANNOTATE_NOTHING)) { + IMCode_genCode0(RET_FREE_LR); - if (!CompileBodyFromAst(body)) return -1; - Compile_Put_Ret_ForRuleBody(); + } else if ((CmEnv.annotateL == ANNOTATE_NOTHING) && + (CmEnv.annotateR != ANNOTATE_NOTHING)) { + // FreeL + if (CmEnv.reg_agentL == VM_OFFSET_ANNOTATE_L) { + IMCode_genCode0(RET_FREE_L); + + } else { + IMCode_genCode0(RET_FREE_R); + } + + } else if ((CmEnv.annotateL != ANNOTATE_NOTHING) && + (CmEnv.annotateR == ANNOTATE_NOTHING)) { + // FreeR + if (CmEnv.reg_agentL == VM_OFFSET_ANNOTATE_L) { + IMCode_genCode0(RET_FREE_R); - generated_codesize = CmEnv_generate_code_with_nameinfo(code, offset_code); + } else { + IMCode_genCode0(RET_FREE_L); - if (generated_codesize < 0) { - puts("System ERROR: Generated codes were too long."); - return -1; } + } else { + IMCode_genCode0(RET); - if (!CmEnv_check_meta_occur_once()) { - printf("in the rule:\n %s >< %s.\n", - IdTable_get_name(CmEnv.idL), - IdTable_get_name(CmEnv.idR)); - return -1; + } + +} + + +int CompileStmListFromAst(Ast *at) { + Ast *ptr; + int toRegLeft; + + while (at!=NULL) { + ptr=at->left; + + // (AST_LD (AST_NAME sym NULL) some) + if (ptr->id != AST_LD) { + puts("System ERROR: The given StmList contains something besides statements."); + exit(-1); + } + // operation of x=y: + // for the x + toRegLeft = CmEnv_reg_search(ptr->left->left->sym); + if (toRegLeft == -1) { + // the sym is new + toRegLeft = CmEnv_set_as_INTVAR(ptr->left->left->sym); + } else { + printf("Warning: '%s' has been already defined.\n", ptr->left->left->sym); } - - return generated_codesize; - - } else { - // if_sentence - Ast *guard, *then_branch, *else_branch; - int label; // 飛び先指定用 - int offset = offset_code; + // for the y + if (ptr->right->id == AST_NAME) { + // y is a name + int toRegRight = CmEnv_reg_search(ptr->right->left->sym); + if (toRegRight == -1) { + toRegRight = CmEnv_set_as_INTVAR(ptr->right->left->sym); + } + IMCode_genCode2(LOAD, toRegLeft, toRegRight); + - guard = if_sentence->left; - then_branch = if_sentence->right->left; - else_branch = if_sentence->right->right; + } else if (ptr->right->id == AST_INT) { + // y is an integer + IMCode_genCode2(LOADI, toRegLeft, ptr->right->intval); + + } else { + // y is an expression + if (!CompileExprFromAst(ptr->right, toRegLeft)) return 0; - // Gurad のコンパイル - int newreg = CmEnv_newreg(); - if (!CompileExprFromAst(newreg, guard)) return -1; - generated_codesize = CmEnv_generate_code(code, offset); - offset += generated_codesize; + } - //JMPEQ0 用コードを作成 - code[offset++] = CodeAddr[OP_JMPEQ0]; - code[offset++] = (void *)(unsigned long)newreg; - label = offset++; // 飛び先を格納するアドレスを記憶しておく - // then_branch のコンパイル - EnvCodeClear(); - CmEnv_clear_localnamePtr(); // 局所変数としての reg番号を初期化 + at = ast_getTail(at); + } - generated_codesize = CompileIfSentenceFromAST(then_branch, code, offset); - if (generated_codesize < 0) return -1; - - offset += generated_codesize; + return 1; +} - if (offset > MAX_CODE_SIZE) { - puts("System ERROR: Generated codes were too big."); - return -1; - } - // JMPEQ0 のとび先を格納(相対ジャンプ) - code[label]=(void *)(unsigned long)generated_codesize; - // else_branch のコンパイル - EnvCodeClear(); - CmEnv_clear_localnamePtr(); // 局所変数としての reg番号を初期化 - - generated_codesize = CompileIfSentenceFromAST(else_branch, code, offset); - if (generated_codesize < 0) return -1; +// --- BEGIN: Rewrite Optimisation --- +Ast* Ast_Subst(char *sym, Ast *aterm, Ast *target, int *result) { + // target is astterm: (AST asttermL asttermR) + // this function replaces sym with aterm in target, i.e. tgs[aterm/sym]. + + switch (target->id) { + case AST_NAME: - offset += generated_codesize; + if (strcmp(target->left->sym, sym) == 0) { + *result = 1; + return aterm; + + } else { + return target; + } + break; - if (offset > MAX_CODE_SIZE) { - puts("System ERROR: Generated codes were too big."); - return -1; + case AST_OPCONS: + target->right = Ast_Subst(sym, aterm, target->right, result); + return target; + + case AST_CONS: + target->left = Ast_Subst(sym, aterm, target->left, result); + if (*result) { + return target; + } else { + target->right = Ast_Subst(sym, aterm, target->right, result); + return target; } - return offset - offset_code; - } - - -} - - + case AST_ANNOTATION_L: + case AST_ANNOTATION_R: -int makeRule(Ast *ast) { - // (ASTRULE (AST_CNCT agentL agentR) - // ) - // - // WHERE - // ::= (AST_IF guard (AST_BRANCH )) - // | - // ::= - // ::= - - - int idR, idL; - Ast *ruleL, *ruleR, *if_sentence; + + case AST_TUPLE: + case AST_AGENT: + { + Ast *port; + if ((target->id == AST_ANNOTATION_L) || + (target->id == AST_ANNOTATION_R)) { - void* code[MAX_CODE_SIZE]; - int code_size=0; + // (AST_ANNOTATION (AST_AGENT (ID_SYM sym NULL) paramlist) NULL) + port = target->left->right; + } else { + + // (AST_AGENT (ID_SYM sym NULL) paramlist) + port = target->right; + } + + for(int i=0; i< MAX_PORT; i++) { + if (port == NULL) break; + + port->left = Ast_Subst(sym, aterm, port->left, result); + if (*result) break; + + port = ast_getTail(port); + } + } + return target; + + case AST_LIST: + { + Ast *elem = target->right; - ruleL = ast->left->left; - ruleR = ast->left->right; + while (elem != NULL) { + elem = Ast_Subst(sym, aterm, elem, result); + if (*result) break; + + elem = ast_getTail(elem); + } + } + return target; - if (ruleL->id == AST_NAME) { - printf("ERROR: The name '%s' was specified as the left-hand side of rule agents. It should be an agent.\n", ruleL->left->sym); - return 0; - } - if (ruleR->id == AST_NAME) { - printf("ERROR: The name '%s' was specified as the right-hand side of rule agents. It should be an agent.\n", ruleR->left->sym); - return 0; + default: + return target; } - - - if_sentence = ast->right; - ruleL = ast_remove_tuple1(ruleL); - ruleR = ast_remove_tuple1(ruleR); - - - // #define MYDEBUG1 -#ifdef MYDEBUG1 - ast_puts(ruleL); puts(""); - ast_puts(ruleR); puts(""); - ast_puts(bodies); - exit(1); -#endif +} - - // store ids of rule agent - idL = getRuleAgentID(ruleL); - idR = getRuleAgentID(ruleR); +int Ast_Subst_EQList(int nth, char *sym, Ast *aterm, Ast *eqlist) { + // eqlist[aterm/sym] except for n-th eq + Ast *eq, *at = eqlist; + int ct = 0; + int result; - /* - // prevent re-defining of built-in agents. - if (IdTable_is_builtin_rule(ruleL, ruleR)) { - printf("Warning: %s >< %s is already defined as built-in.\n", - IdTable_get_name(idL), IdTable_get_name(idR)); + while (at != NULL) { + eq = at->left; - } else { - - if (IdTable_is_builtin_rule(ruleR, ruleL)) { - printf("Warning: %s >< %s is already defined as built-in.\n", - IdTable_get_name(idR), IdTable_get_name(idL)); + if (ct == nth) { + ct++; + at = ast_getTail(at); + continue; } - - } - */ - - - // >< (int i) 対策 - // int i は (AST_INTVAR (AST_SYM sym NULL) NULL) として構築されているので - // ID_TUPLE1 である間は読み飛ばす - while (idL == ID_TUPLE1) { - ruleL = ruleL->right->left; - idL = getRuleAgentID(ruleL); - } - while (idR == ID_TUPLE1) { - ruleR = ruleR->right->left; - idR = getRuleAgentID(ruleR); - } - - - // Annotation (*L)、(*R) の処理があるため - // 単純に ruleAgentL、ruleAgentR を入れ替えれば良いわけではない。 - - if (idL > idR) { - // Generally the order should be as Append(xs,r) >< y:ys, - // so idL should be greater than idR. - // JAPANESE: 標準では Append(xs, r) >< [y|ys] なので - // idL の方が大きくなって欲しい - + result=0; + eq->left = Ast_Subst(sym, aterm, eq->left, &result); - // (*L) is interpreted as the left-hand side agent, (*R) is the right one. - // JAPANESE: annotation が (*L) なら左側、(*R) なら右側を指すものとする - setAnnotateLR(VM_OFFSET_ANNOTATE_L, VM_OFFSET_ANNOTATE_R); + if (result) { + return 1; + } - } else { - Ast *tmp; - tmp = ruleL; - ruleL = ruleR; - ruleR = tmp; + result=0; + eq->right = Ast_Subst(sym, aterm, eq->right, &result); - int idTmp; - idTmp = idL; - idL = idR; - idR = idTmp; + if (result) { + return 1; + } - // Keep the occurrence (*L) and (*R) in aplist, - // change the interpretation of (*L) as (*R), vice versa. + ct++; + at = ast_getTail(at); - // JAPANESE: aplist 内の (*L) (*R) はそのままにしておき、 - // annotation が (*L) なら右側、(*R) なら左側を指すものとする - setAnnotateLR(VM_OFFSET_ANNOTATE_R, VM_OFFSET_ANNOTATE_L); } - { - int arity; - - // IMPORTANT: - // The first two codes store arities of idL and idR. - if (idL == ID_INT) { - arity = 0; - } else { - arity = getArityFromAST(ruleL); - } - IdTable_set_arity(idL, arity); - code[0] = (void *)(unsigned long)arity; + return 0; +} - if (idR == ID_INT) { - arity = 0; - } else { - arity = getArityFromAST(ruleR); - } - IdTable_set_arity(idR, arity); - code[1] = (void *)(unsigned long)arity; - code_size = 2; - } - +void Ast_RewriteOptimisation_EQList(Ast *eqlist) { + // Every eq such as x~t in eqlist is replaced as eqlist[t/x]. + // + // Structure + // eqlist : (AST_LIST eq1 (AST_LIST eq2 (AST_LIST eq3 NULL))) + // eq : (AST_CNCT astterm1 astterm2) + Ast *at, *prev, *target, *term; + char *sym; + int nth=0, exists_in_table; + NB_TYPE type = NB_NAME; - CmEnv_clear_all(); - - if (idL == ID_INT) { - setMetaL_asIntName(ruleL); - CmEnv.annotateL = ANNOTATE_AS_INT_AGENT; // to prevent putting FreeL out - } else { - setMetaL(ruleL); - } - - if (idR == ID_INT) { - setMetaR_asIntName(ruleR); - CmEnv.annotateR = ANNOTATE_AS_INT_AGENT; // to prevent putting FreeR out - } else { - setMetaR(ruleR); - } + at = prev = eqlist; - CmEnv.idL = idL; - CmEnv.idR = idR; + while (at != NULL) { + // (id, left, right) + // at : (AST_LIST, x1, NULL) + // at : (AST_LIST, x1, (AST_LIST, x2, NULL)) + target = at->left; + + // printf("\n[target] "); ast_puts(target); + // printf("\n%dnth in ", nth); ast_puts(eqlist); printf("\n\n"); - { - int generated_codesize = CompileIfSentenceFromAST(if_sentence, code, code_size); - if (generated_codesize < 0) { - return 0; + // NB_NAME=0, + // NB_META, + // NB_INTVAR, + + if (target->left->id == AST_NAME) { + + sym = target->left->left->sym; + exists_in_table=CmEnv_gettype_forname(sym, &type); + + if ((!exists_in_table) || + (type == NB_NAME)){ + // When no entry in CmEnv table or its type is NB_NAME + + term = target->right; + // printf("%s~",sym); ast_puts(term); puts(""); + + if (Ast_Subst_EQList(nth, sym, term, eqlist)) { + // printf("=== hit %dth\n", nth); + + if (prev != at) { + // 前のリストの接続先を、現在地を省いて、その次の要素に変更。 + prev->right = at->right; + at = at->right; + } else { + // 先頭の要素が代入に使われたので、 + // body 内の eqlist から先頭を削除 + // (AST_LIST, x1, (AST_LIST, x2, *next)) ==> (AST_LIST, x2, *next) + eqlist->left = eqlist->right->left; + eqlist->right = eqlist->right->right; + eqlist = eqlist->right; + // 対象 at を次の要素に更新し、prev も at とする + prev = at = at->right; + } + + continue; + } + } + } - code_size += generated_codesize; - } -#ifdef MYDEBUG - PutsCodeN(code, code_size); exit(1); -#endif - - // printf("Rule: %s(id:%d) >< %s(id:%d).\n", - // IdTable_get_name(idL), idL, - // IdTable_get_name(idR), idR); - // PutsCodeN(&code[2], code_size-2); - // exit(1); - - -// -------------------------------------------------------------- -// For Fibonacci (as much as possible) -// #define HAND_FIB_AS_MUCH_AS_POSSIBLE -// -------------------------------------------------------------- -#ifdef HAND_FIB_AS_MUCH_AS_POSSIBLE - if ((strcmp(IdTable_get_name(idL), "Fib") == 0) && - (idR == ID_INT)) { - - printf("Rule is optimised: %s >< %s.\n", - IdTable_get_name(idL), - IdTable_get_name(idR)); - - // PutsCodeN(&code[2], code_size-2); - - int i=2; - // code[i++] = CodeAddr[MKVAL]; - // code[i++] = (void *)14; - // code[i++] = (void *)0; - // code[i++] = (void *)0; - // - // code[i++] = CodeAddr[OP_EQ]; - // code[i++] = (void *)12; - // code[i++] = (void *)11; - // code[i++] = (void *)14; - - code[i++] = CodeAddr[OP_EQI]; - //code[i++] = (void *)11; // ここで 11(OFFSET_R)を壊してしまうと他で影響あり - code[i++] = (void *)12; - code[i++] = (void *)11; - code[i++] = (void *)0; - - code[i++] = CodeAddr[OP_JMPEQ0]; - code[i++] = (void *)12; - // code[i++] = (void *)8; - code[i++] = (void *)4; - - // code[i++] = CodeAddr[MKVAL]; - // code[i++] = (void *)12; - // code[i++] = (void *)0; - // code[i++] = (void *)1; - // - // code[i++] = CodeAddr[PUSH]; - // code[i++] = (void *)0; - // code[i++] = (void *)12; - - code[i++] = CodeAddr[PUSHI]; - code[i++] = (void *)0; - code[i++] = (void *)INT2FIX(1); - - code[i++] = CodeAddr[RET_FREE_L]; - - - - - // code[i++] = CodeAddr[MKVAL]; - // code[i++] = (void *)14; - // code[i++] = (void *)0; - // code[i++] = (void *)1; - // - // code[i++] = CodeAddr[OP_EQ]; - // code[i++] = (void *)12; - // code[i++] = (void *)11; - // code[i++] = (void *)14; - - code[i++] = CodeAddr[OP_EQI]; - code[i++] = (void *)12; - code[i++] = (void *)11; - code[i++] = (void *)1; - - code[i++] = CodeAddr[OP_JMPEQ0]; - code[i++] = (void *)12; - // code[i++] = (void *)8; - code[i++] = (void *)4; - - // code[i++] = CodeAddr[MKVAL]; - // code[i++] = (void *)12; - // code[i++] = (void *)0; - // code[i++] = (void *)1; - // - // code[i++] = CodeAddr[PUSH]; - // code[i++] = (void *)0; - // code[i++] = (void *)12; - - code[i++] = CodeAddr[PUSHI]; - code[i++] = (void *)0; - code[i++] = (void *)INT2FIX(1); - - - code[i++] = CodeAddr[RET_FREE_L]; - - - - - code[i++] = CodeAddr[MKNAME]; - code[i++] = (void *)16; - - - // code[i++] = CodeAddr[MKVAL]; - // code[i++] = (void *)14; - // code[i++] = (void *)0; - // code[i++] = (void *)1; - // - // code[i++] = CodeAddr[OP_SUB]; - // code[i++] = (void *)12; - // code[i++] = (void *)11; - // code[i++] = (void *)14; - - code[i++] = CodeAddr[OP_SUBI]; - code[i++] = (void *)12; - code[i++] = (void *)11; - code[i++] = (void *)1; - - - // code[i++] = CodeAddr[MKVAL]; - // code[i++] = (void *)17; - // code[i++] = (void *)0; - // code[i++] = (void *)2; - // - // code[i++] = CodeAddr[OP_SUB]; - // code[i++] = (void *)15; - // code[i++] = (void *)11; - // code[i++] = (void *)17; - - code[i++] = CodeAddr[OP_SUBI]; - code[i++] = (void *)13; - code[i++] = (void *)11; - code[i++] = (void *)2; - - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)14; - code[i++] = (void *)10; - code[i++] = (void *)2; - code[i++] = (void *)16; - code[i++] = (void *)0; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)14; - code[i++] = (void *)20; - code[i++] = (void *)1; - code[i++] = (void *)14; - - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)14; - code[i++] = (void *)12; - - - // code[i++] = CodeAddr[REUSEAGENT]; - // code[i++] = (void *)10; - // code[i++] = (void *)21; - // code[i++] = (void *)1; - // code[i++] = (void *)20; - // - // code[i++] = CodeAddr[PUSH]; - // code[i++] = (void *)10; - // code[i++] = (void *)15; - // - // code[i++] = CodeAddr[RET]; - - - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)VM_OFFSET_META_L(0); - code[i++] = (void *)16; - - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)VM_OFFSET_ANNOTATE_R; - code[i++] = (void *)13; - - code[i++] = CodeAddr[LOOP]; - - code_size = i; - // PutsCodeN(&code[2], i-2); - // exit(1); - } -#endif + if (target->right->id == AST_NAME) { + sym = target->right->left->sym; + exists_in_table=CmEnv_gettype_forname(sym, &type); + + if ((!exists_in_table) || + (type == NB_NAME)){ + // When no entry in CmEnv table or its type is NB_NAME + + term = target->left; + // ast_puts(term); printf("~%s",sym);puts(""); + if (Ast_Subst_EQList(nth, sym, term, eqlist)) { + // printf("=== hit %dth\n", nth); + + if (prev != at) { + // 前のリストの接続先を、現在地を省いて、その次の要素に変更。 + prev->right = at->right; + at = at->right; + } else { + // 先頭の要素が代入に使われたので、 + // body 内の eqlist から先頭を削除 + // (AST_LIST, x1, (AST_LIST, x2, *next)) ==> (AST_LIST, x2, *next) + eqlist->left = eqlist->right->left; + eqlist->right = eqlist->right->right; + eqlist = eqlist->right; + // 対象 at を次の要素に更新し、prev も at とする + prev = at = at->right; + } -// -------------------------------------------------------------- -// For Fibonacci (naive) -// #define HAND_FIB -// -------------------------------------------------------------- -#ifdef HAND_FIB - if ((strcmp(IdTable_get_name(idL), "Fib") == 0) && - (idR == ID_INT)) { + continue; - printf("Rule is optimised: %s >< %s.\n", - IdTable_get_name(idL), - IdTable_get_name(idR)); - - // PutsCodeN(&code[2], code_size-2); - - int i=2; - - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)13; - code[i++] = (void *)VM_OFFSET_ANNOTATE_R; + } + } + } - code[i++] = CodeAddr[LOADI]; - code[i++] = (void *)14; - code[i++] = (void *)0; - - code[i++] = CodeAddr[OP_EQ]; - code[i++] = (void *)12; - code[i++] = (void *)13; - code[i++] = (void *)14; - - code[i++] = CodeAddr[OP_JMPEQ0]; - code[i++] = (void *)12; - code[i++] = (void *)7; - - code[i++] = CodeAddr[LOADI]; - code[i++] = (void *)12; - code[i++] = (void *)0; - - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)0; - code[i++] = (void *)12; - - code[i++] = CodeAddr[RET_FREE_L]; + nth++; + prev = at; + at = at->right; + + } +} +// --- END: Rewrite Optimisation --- - - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)13; - code[i++] = (void *)VM_OFFSET_ANNOTATE_R; - code[i++] = CodeAddr[LOADI]; - code[i++] = (void *)14; - code[i++] = (void *)1; - - code[i++] = CodeAddr[OP_EQ]; - code[i++] = (void *)12; - code[i++] = (void *)13; - code[i++] = (void *)14; - - code[i++] = CodeAddr[OP_JMPEQ0]; - code[i++] = (void *)12; - code[i++] = (void *)7; - - code[i++] = CodeAddr[LOADI]; - code[i++] = (void *)12; - code[i++] = (void *)1; - - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)0; - code[i++] = (void *)12; - - code[i++] = CodeAddr[RET_FREE_L]; - - - - - code[i++] = CodeAddr[MKNAME]; - code[i++] = (void *)14; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)13; - code[i++] = (void *)21; - code[i++] = (void *)2; - code[i++] = (void *)0; - code[i++] = (void *)14; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)12; - code[i++] = (void *)20; - code[i++] = (void *)1; - code[i++] = (void *)13; - - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)16; - code[i++] = (void *)VM_OFFSET_ANNOTATE_R; - - code[i++] = CodeAddr[LOADI]; - code[i++] = (void *)17; - code[i++] = (void *)1; - - code[i++] = CodeAddr[OP_SUB]; - code[i++] = (void *)15; - code[i++] = (void *)16; - code[i++] = (void *)17; - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)12; - code[i++] = (void *)15; - - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)VM_OFFSET_META_L(0); - code[i++] = (void *)14; - - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)20; - code[i++] = (void *)VM_OFFSET_ANNOTATE_R; - - code[i++] = CodeAddr[LOADI]; - code[i++] = (void *)21; - code[i++] = (void *)2; - - code[i++] = CodeAddr[OP_SUB]; - code[i++] = (void *)19; - code[i++] = (void *)20; - code[i++] = (void *)21; +int CompileBodyFromAst(Ast *body) { + Ast *stms, *eqs; + if (body == NULL) return 1; + + stms = body->left; + eqs = body->right; + + Ast_RewriteOptimisation_EQList(eqs); - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)VM_OFFSET_ANNOTATE_R; - code[i++] = (void *)19; - - code[i++] = CodeAddr[LOOP]; - - code_size = i; - - // PutsCodeN(&code[2], i-2); - // exit(1); - } -#endif + if (!CompileStmListFromAst(stms)) return 0; + if (!CompileEQListFromAst(eqs)) { + printf("in the rule:\n %s >< %s\n", + IdTable_get_name(CmEnv.idL), + IdTable_get_name(CmEnv.idR)); + return 0; + } + return 1; +} + -// -------------------------------------------------------------- -// For Fibonacci (naive) -// #define HAND_FIB_INT -// -------------------------------------------------------------- -#ifdef HAND_FIB_INT - if ((strcmp(IdTable_get_name(idL), "Fibi") == 0) && - (strcmp(IdTable_get_name(idR), "Int") == 0)) { - printf("Rule is optimised: %s >< %s.\n", - IdTable_get_name(idL), - IdTable_get_name(idR)); - - // PutsCodeN(&code[2], code_size-2); - - int i=2; - - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)13; - code[i++] = (void *)VM_OFFSET_META_R(0); - code[i++] = CodeAddr[LOADI]; - code[i++] = (void *)14; - code[i++] = (void *)0; - - code[i++] = CodeAddr[OP_EQ]; - code[i++] = (void *)12; - code[i++] = (void *)13; - code[i++] = (void *)14; - - code[i++] = CodeAddr[OP_JMPEQ0]; - code[i++] = (void *)12; - code[i++] = (void *)12; - - code[i++] = CodeAddr[LOADI]; - code[i++] = (void *)13; - code[i++] = (void *)0; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)12; - code[i++] = (void *)(unsigned long)idR; - code[i++] = (void *)1; - code[i++] = (void *)13; - - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)0; - code[i++] = (void *)12; - - code[i++] = CodeAddr[RET_FREE_LR]; +/************************************** + TABLE for RULES +**************************************/ +typedef struct RuleList { + int sym; + int available; + void* code[MAX_CODE_SIZE]; + struct RuleList *next; +} RuleList; - - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)13; - code[i++] = (void *)VM_OFFSET_META_R(0); +RuleList *RuleList_new() { + RuleList *alist; + alist = malloc(sizeof(RuleList)); + if (alist == NULL) { + printf("Malloc error\n"); + exit(-1); + } + alist->available = 0; + return alist; +} - code[i++] = CodeAddr[LOADI]; - code[i++] = (void *)14; - code[i++] = (void *)1; - - code[i++] = CodeAddr[OP_EQ]; - code[i++] = (void *)12; - code[i++] = (void *)13; - code[i++] = (void *)14; - - code[i++] = CodeAddr[OP_JMPEQ0]; - code[i++] = (void *)12; - code[i++] = (void *)12; - - code[i++] = CodeAddr[LOADI]; - code[i++] = (void *)13; - code[i++] = (void *)1; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)12; - code[i++] = (void *)(unsigned long)idR; - code[i++] = (void *)1; - code[i++] = (void *)13; - - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)0; - code[i++] = (void *)12; - - code[i++] = CodeAddr[RET_FREE_LR]; - - - code[i++] = CodeAddr[MKNAME]; - code[i++] = (void *)20; - - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)13; - code[i++] = (void *)VM_OFFSET_META_R(0); - - code[i++] = CodeAddr[LOADI]; - code[i++] = (void *)14; - code[i++] = (void *)1; - - code[i++] = CodeAddr[OP_SUB]; - code[i++] = (void *)12; - code[i++] = (void *)13; - code[i++] = (void *)14; +void RuleList_set_code(RuleList *at, int sym, void **code, int byte, RuleList *next) { + at->sym = sym; + at->available = 1; + CopyCode(byte, code, at->code); + at->next = next; +} +void RuleList_inavailable(RuleList *at) { + at->available = 0; +} - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)16; - code[i++] = (void *)VM_OFFSET_META_R(0); - - code[i++] = CodeAddr[LOADI]; - code[i++] = (void *)17; - code[i++] = (void *)2; - - code[i++] = CodeAddr[OP_SUB]; - code[i++] = (void *)15; - code[i++] = (void *)16; - code[i++] = (void *)17; - - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)19; - code[i++] = (void *)21; - code[i++] = (void *)2; - code[i++] = (void *)0; - code[i++] = (void *)20; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)18; - code[i++] = (void *)20; - code[i++] = (void *)1; - code[i++] = (void *)19; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)21; - code[i++] = (void *)9; - code[i++] = (void *)1; - code[i++] = (void *)12; - - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)18; - code[i++] = (void *)21; - - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)VM_OFFSET_META_L(0); - code[i++] = (void *)20; - - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)VM_OFFSET_META_R(0); - code[i++] = (void *)15; - - code[i++] = CodeAddr[LOOP]; - - - code_size = i; - - // PutsCodeN(&code[2], i-2); - // exit(1); - } -#endif - - -// -------------------------------------------------------------- -// For Fibonacci (tail call version) -// #define HAND_FIB_TAIL -// -------------------------------------------------------------- -#ifdef HAND_FIB_TAIL - if (strcmp(IdTable_get_name(idL), "Fibt") == 0) { - printf("Rule is optimised: %s >< %s.\n", - IdTable_get_name(idL), - IdTable_get_name(idR)); - - // PutsCodeN(&code[2], code_size-2); - - int i=2; - - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)13; - code[i++] = (void *)VM_OFFSET_ANNOTATE_R; - code[i++] = CodeAddr[LOADI]; - code[i++] = (void *)14; - code[i++] = (void *)0; - - code[i++] = CodeAddr[OP_EQ]; - code[i++] = (void *)12; - code[i++] = (void *)13; - code[i++] = (void *)14; - - code[i++] = CodeAddr[OP_JMPEQ0]; - code[i++] = (void *)12; - code[i++] = (void *)7; - - code[i++] = CodeAddr[LOADI]; - code[i++] = (void *)12; - code[i++] = (void *)1; - - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)0; - code[i++] = (void *)12; - - code[i++] = CodeAddr[RET_FREE_L]; +#define RULEHASH_SIZE NUM_AGENTS +static RuleList *RuleTable[RULEHASH_SIZE]; + +void RuleTable_init() { + int i; + for (i=0; i< %s.\n", - IdTable_get_name(idL), - IdTable_get_name(idR)); - - // PutsCodeN(&code[2], code_size-2); - - int i=2; - - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)13; - code[i++] = (void *)1; - - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)14; - code[i++] = (void *)5; - - code[i++] = CodeAddr[OP_LE]; - code[i++] = (void *)12; - code[i++] = (void *)13; - code[i++] = (void *)14; - - code[i++] = CodeAddr[OP_JMPEQ0]; - code[i++] = (void *)12; - code[i++] = (void *)16; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)13; - code[i++] = (void *)8; - code[i++] = (void *)2; - code[i++] = (void *)5; - code[i++] = (void *)6; - - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)12; - code[i++] = (void *)8; - code[i++] = (void *)2; - code[i++] = (void *)1; - code[i++] = (void *)13; - - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)0; - code[i++] = (void *)12; - - code[i++] = CodeAddr[RET_FREE_LR]; + while( at != NULL ) { + if( at->sym == symrID) { + // already exists + // overwrite + CopyCode(byte, code, at->code); + return; + } + at = at->next; + } + + // No entry for symlID in the linear list + // Make a new linear list + // and add it as the top of the list (that is RuleTable[symlID]). + add = RuleList_new(); + RuleList_set_code(add, symrID, code, byte, RuleTable[symlID]); + RuleTable[symlID] = add; + return; +} - - code[i++] = CodeAddr[MKNAME]; - code[i++] = (void *)13; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)12; - code[i++] = (void *)8; - code[i++] = (void *)2; - code[i++] = (void *)5; - code[i++] = (void *)13; - - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)0; - code[i++] = (void *)12; - - code[i++] = CodeAddr[OP_JMPCNCT_CONS]; - code[i++] = (void *)VM_OFFSET_META_R(1); - code[i++] = (void *)10; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)14; - code[i++] = (void *)21; - code[i++] = (void *)2; - code[i++] = (void *)13; - code[i++] = (void *)1; - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)14; - code[i++] = (void *)6; - code[i++] = CodeAddr[RET_FREE_LR]; +void RuleTable_delete(int symlID, int symrID) { + + if (RuleTable[symlID] == NULL) { + // No entry for symlID + return; + + } - - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)VM_OFFSET_META_L(0); - code[i++] = (void *)13; + // Linear Search + RuleList *at = RuleTable[symlID]; + + while( at != NULL ) { + if( at->sym == symrID) { + // already exists - code[i++] = CodeAddr[LOOP_RREC2]; - code[i++] = (void *)VM_OFFSET_META_R(1); - - code_size = i; - - // PutsCodeN(&code[2], i-2); - // exit(1); + // Make it void + RuleList_inavailable(at); + return; } -#endif - + at = at->next; + } + +} -#ifdef HAND_IS_CONS - if ((strcmp(IdTable_get_name(idL), "IS") == 0) && - (strcmp(IdTable_get_name(idR), "Cons") == 0)) { - printf("Rule is optimised: %s >< %s.\n", - IdTable_get_name(idL), - IdTable_get_name(idR)); - - // PutsCodeN(&code[2], code_size-2); - - int i=2; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)13; - code[i++] = (void *)21; - code[i++] = (void *)2; - code[i++] = (void *)VM_OFFSET_META_L(0); - code[i++] = (void *)VM_OFFSET_META_R(0); - - code[i++] = CodeAddr[OP_JMPCNCT_CONS]; - code[i++] = (void *)VM_OFFSET_META_R(1); - code[i++] = (void *)9; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)12; - code[i++] = (void *)20; - code[i++] = (void *)1; - code[i++] = (void *)13; - - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)12; - code[i++] = (void *)VM_OFFSET_META_R(1);; - - code[i++] = CodeAddr[RET_FREE_LR]; - - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)VM_OFFSET_META_L(0); - code[i++] = (void *)13; - code[i++] = CodeAddr[LOOP_RREC2]; - code[i++] = (void *)VM_OFFSET_META_R(1); - - code_size = i; - - // PutsCodeN(&code[2], i-2); - // exit(1); - } -#endif +// ------------------------------------------------------------- -// -------------------------------------------------------------- -// For Quick Sort -// #define HAND_Apnd_CONS -// #define HAND_Part_CONS -// -------------------------------------------------------------- - -#ifdef HAND_Apnd_CONS - if ((strcmp(IdTable_get_name(idL), "Apnd") == 0) && - (idR == ID_CONS)) { +int getArityFromAST(Ast *ast) { + int i; + Ast *ptr; - printf("Rule is optimised: %s >< %s.\n", - IdTable_get_name(idL), - IdTable_get_name(idR)); - - // PutsCodeN(&code[2], code_size-2); - - int i=2; + ptr = ast->right; + for (i=0; iright; + for (i=0; ileft->id == AST_NAME) { + type = NB_META; + } else { + type = NB_INTVAR; + } + CmEnv_set_symbol_as_meta(ptr->left->left->sym, VM_OFFSET_META_L(i), type); + + ptr = ast_getTail(ptr); + } +} +void setMetaR(Ast *ast) { + int i; + Ast *ptr; + NB_TYPE type; + + ptr = ast->right; + for (i=0; ileft->id == AST_NAME) { + type = NB_META; + } else { + type = NB_INTVAR; + } + CmEnv_set_symbol_as_meta(ptr->left->left->sym, VM_OFFSET_META_R(i), type); + ptr = ast_getTail(ptr); + } +} - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)12; - code[i++] = (void *)8; - code[i++] = (void *)2; - code[i++] = (void *)5; - code[i++] = (void *)13; +void setMetaL_asIntName(Ast *ast) { + //CmEnv_set_symbol_as_meta(ast->left->sym, VM_OFFSET_META_L(0), NB_INTVAR); + CmEnv_set_symbol_as_meta(ast->left->sym, CmEnv.reg_agentL, NB_INTVAR); + +} - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)0; - code[i++] = (void *)12; +void setMetaR_asIntName(Ast *ast) { + // CmEnv_set_symbol_as_meta(ast->left->sym, VM_OFFSET_META_R(0), NB_INTVAR); + CmEnv_set_symbol_as_meta(ast->left->sym, CmEnv.reg_agentR, NB_INTVAR); +} - code[i++] = CodeAddr[OP_JMPCNCT_CONS]; - code[i++] = (void *)VM_OFFSET_META_R(1); - code[i++] = (void *)10; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)14; - code[i++] = (void *)(unsigned long)idL; - code[i++] = (void *)2; - code[i++] = (void *)13; - code[i++] = (void *)1; - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)14; - code[i++] = (void *)6; +void setAnnotateLR(int left, int right) { + CmEnv.reg_agentL = left; + CmEnv.reg_agentR = right; +} - code[i++] = CodeAddr[RET_FREE_LR]; - - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)VM_OFFSET_META_L(0); - code[i++] = (void *)13; - code[i++] = CodeAddr[LOOP_RREC2]; - code[i++] = (void *)VM_OFFSET_META_R(1); - - code_size = i; - - // PutsCodeN(&code[2], i-2); - // exit(1); - } -#endif +int getRuleAgentID(Ast *ruleAgent) { + // Returns agents ids of ast type. + // This is called from makeRule to get ids of rule agents. + + int id; + if (ruleAgent->id == AST_TUPLE) { + id = GET_TUPLEID(ruleAgent->intval); -#ifdef HAND_Part_CONS - if ((strcmp(IdTable_get_name(idL), "Part") == 0) && - (strcmp(IdTable_get_name(idR), "Cons") == 0)) { - - printf("Rule is optimised: %s >< %s.\n", - IdTable_get_name(idL), - IdTable_get_name(idR)); - - // PutsCodeN(&code[2], code_size-2); - - int i=2; + } else if (ruleAgent->id == AST_OPCONS) { + id = ID_CONS; + + } else if (ruleAgent->id == AST_NIL) { + id = ID_NIL; + + } else if (ruleAgent->id == AST_INTVAR) { + id = ID_INT; - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)13; - code[i++] = (void *)VM_OFFSET_META_R(0); + } else if (strcmp((char *)ruleAgent->left->sym, "Int") == 0) { + id = ID_INTAGENT; + } else { - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)14; - code[i++] = (void *)VM_OFFSET_META_L(0); + id = IdTable_getid_builtin_funcAgent(ruleAgent); + if (id == -1) { + id=NameTable_get_set_id(ruleAgent->left->sym); + } + } - code[i++] = CodeAddr[OP_LT]; - code[i++] = (void *)12; - code[i++] = (void *)13; - code[i++] = (void *)14; - - code[i++] = CodeAddr[OP_JMPEQ0]; - code[i++] = (void *)12; - code[i++] = (void *)30; - - code[i++] = CodeAddr[MKNAME]; - code[i++] = (void *)13; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)12; - code[i++] = (void *)8; - code[i++] = (void *)2; - code[i++] = (void *)5; - code[i++] = (void *)13; - - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)VM_OFFSET_META_L(2); - code[i++] = (void *)12; - - code[i++] = CodeAddr[OP_JMPCNCT_CONS]; - code[i++] = (void *)VM_OFFSET_META_R(1); - code[i++] = (void *)11; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)14; - code[i++] = (void *)(unsigned long)idL; - code[i++] = (void *)3; - code[i++] = (void *)VM_OFFSET_META_L(0); - code[i++] = (void *)VM_OFFSET_META_L(1); - code[i++] = (void *)13; + return id; +} + - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)14; - code[i++] = (void *)VM_OFFSET_META_R(1); - code[i++] = CodeAddr[RET_FREE_LR]; - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)VM_OFFSET_META_L(2); - code[i++] = (void *)13; - code[i++] = CodeAddr[LOOP_RREC2]; - code[i++] = (void *)VM_OFFSET_META_R(1); +int CompileIfSentenceFromAST(Ast *if_sentence_top, + void **code, int offset_code) { + // return + // generated codesize + // -1 : compile error - - code[i++] = CodeAddr[MKNAME]; - code[i++] = (void *)13; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)12; - code[i++] = (void *)8; - code[i++] = (void *)2; - code[i++] = (void *)5; - code[i++] = (void *)13; - - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)VM_OFFSET_META_L(1); - code[i++] = (void *)12; - - code[i++] = CodeAddr[OP_JMPCNCT_CONS]; - code[i++] = (void *)VM_OFFSET_META_L(2); - code[i++] = (void *)11; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)14; - code[i++] = (void *)(unsigned long)idL; - code[i++] = (void *)3; - code[i++] = (void *)VM_OFFSET_META_L(0); - code[i++] = (void *)13; - code[i++] = (void *)VM_OFFSET_META_L(2); + // ::= (AST_IF guard (AST_BRANCH )) + // | + // ::= + // ::= - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)14; - code[i++] = (void *)VM_OFFSET_META_R(1); + Ast *if_sentence; + + int generated_codesize; // コンパイルで生成されたコード数保存用 - code[i++] = CodeAddr[RET_FREE_LR]; + if_sentence = if_sentence_top; - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)VM_OFFSET_META_L(1); - code[i++] = (void *)13; + CmEnv_clear_keeping_rule_properties(); - code[i++] = CodeAddr[LOOP_RREC2]; - code[i++] = (void *)VM_OFFSET_META_R(1); + if ((if_sentence == NULL) || (if_sentence->id == AST_BODY)) { + // 通常コンパイル + Ast *body = if_sentence; + + if (!CompileBodyFromAst(body)) return -1; + Compile_Put_Ret_ForRuleBody(); - - code_size = i; - - // PutsCodeN(&code[2], i-2); - // exit(1); - } -#endif + CmEnv_Retrieve_GNAME(); + generated_codesize = CmEnv_Generate_VMCode(code, offset_code); - -// -------------------------------------------------------------- -// For Merge Sort -// #define HAND_Split_CONS -// #define HAND_MergeCC_CONS -// -------------------------------------------------------------- + if (generated_codesize < 0) { + puts("System ERROR: Generated codes were too long."); + return -1; + } -#ifdef HAND_Split_CONS - if ((strcmp(IdTable_get_name(idL), "Split") == 0) && - (strcmp(IdTable_get_name(idR), "Cons") == 0)) { - - printf("Rule is optimised: %s >< %s.\n", - IdTable_get_name(idL), - IdTable_get_name(idR)); - - //PutsCodeN(&code[2], code_size-2); - - int i=2; - - code[i++] = CodeAddr[MKNAME]; - code[i++] = (void *)13; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)12; - code[i++] = (void *)8; - code[i++] = (void *)2; - code[i++] = (void *)5; - code[i++] = (void *)13; - - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)0; - code[i++] = (void *)12; - - code[i++] = CodeAddr[OP_JMPCNCT_CONS]; - code[i++] = (void *)VM_OFFSET_META_R(1); - code[i++] = (void *)10; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)14; - code[i++] = (void *)22; - code[i++] = (void *)2; - code[i++] = (void *)1; - code[i++] = (void *)13; - - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)14; - code[i++] = (void *)6; - - code[i++] = CodeAddr[RET_FREE_LR]; - - - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)VM_OFFSET_META_L(0); - code[i++] = (void *)VM_OFFSET_META_L(1); - - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)VM_OFFSET_META_L(1); - code[i++] = (void *)13; - - code[i++] = CodeAddr[LOOP_RREC2]; - code[i++] = (void *)VM_OFFSET_META_R(1); - - code_size = i; - - // PutsCodeN(&code[2], i-2); - // exit(1); + if (!CmEnv_check_meta_occur_once()) { + printf("in the rule:\n %s >< %s.\n", + IdTable_get_name(CmEnv.idL), + IdTable_get_name(CmEnv.idR)); + return -1; } -#endif - - - // #define HAND_MergeCC_CONS -#ifdef HAND_MergeCC_CONS - if ((strcmp(IdTable_get_name(idL), "MergeCC") == 0) && - (strcmp(IdTable_get_name(idR), "Cons") == 0)) { - - printf("Rule is optimised: %s >< %s.\n", - IdTable_get_name(idL), - IdTable_get_name(idR)); - - PutsCodeN(&code[2], code_size-2); - //exit(1); - - int i=2; - - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)13; - code[i++] = (void *)VM_OFFSET_META_R(0); - - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)14; - code[i++] = (void *)VM_OFFSET_META_L(1); - - code[i++] = CodeAddr[OP_LE]; - code[i++] = (void *)12; - code[i++] = (void *)13; - code[i++] = (void *)14; - - code[i++] = CodeAddr[OP_JMPEQ0]; - code[i++] = (void *)12; - code[i++] = (void *)30; - - code[i++] = CodeAddr[MKNAME]; - code[i++] = (void *)13; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)12; - code[i++] = (void *)8; - code[i++] = (void *)2; - code[i++] = (void *)5; - code[i++] = (void *)13; - - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)0; - code[i++] = (void *)12; - - code[i++] = CodeAddr[OP_JMPCNCT_CONS]; - code[i++] = (void *)VM_OFFSET_META_R(1); - code[i++] = (void *)11; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)14; - code[i++] = (void *)(unsigned long)idL; - code[i++] = (void *)3; - code[i++] = (void *)13; - code[i++] = (void *)1; - code[i++] = (void *)2; - - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)14; - code[i++] = (void *)6; - - code[i++] = CodeAddr[RET_FREE_LR]; - - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)VM_OFFSET_META_L(0); - code[i++] = (void *)13; - - code[i++] = CodeAddr[LOOP_RREC2]; - code[i++] = (void *)VM_OFFSET_META_R(1); - - + + return generated_codesize; - code[i++] = CodeAddr[MKNAME]; - code[i++] = (void *)13; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)12; - code[i++] = (void *)8; - code[i++] = (void *)2; - code[i++] = (void *)1; - code[i++] = (void *)13; - - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)0; - code[i++] = (void *)12; - - code[i++] = CodeAddr[OP_JMPCNCT_CONS]; - code[i++] = (void *)VM_OFFSET_META_L(2); - code[i++] = (void *)11; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)14; - code[i++] = (void *)(unsigned long)idL; - code[i++] = (void *)3; - code[i++] = (void *)13; - code[i++] = (void *)5; - code[i++] = (void *)6; - - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)14; - code[i++] = (void *)2; + } else { + // if_sentence + Ast *guard, *then_branch, *else_branch; + int label; // 飛び先指定用 - code[i++] = CodeAddr[RET_FREE_LR]; + int offset = offset_code; - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)14; - code[i++] = (void *)VM_OFFSET_META_L(2); // ys + guard = if_sentence->left; + then_branch = if_sentence->right->left; + else_branch = if_sentence->right->right; - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)VM_OFFSET_META_L(0); - code[i++] = (void *)13; + // Gurad のコンパイル + int newreg = CmEnv_newreg(); + if (!CompileExprFromAst(guard, newreg)) return -1; + + // CmEnv_Retrieve_GNAME(); + generated_codesize = CmEnv_Generate_VMCode(code, offset_code); + offset += generated_codesize; - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)VM_OFFSET_META_L(1); - code[i++] = (void *)VM_OFFSET_META_R(0); - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)VM_OFFSET_META_L(2); - code[i++] = (void *)VM_OFFSET_META_R(1); + //JMPEQ0 用コードを作成 + code[offset++] = CodeAddr[OP_JMPEQ0]; + code[offset++] = (void *)(unsigned long)newreg; + label = offset++; // 飛び先を格納するアドレスを記憶しておく - code[i++] = CodeAddr[LOOP_RREC2]; - code[i++] = (void *)14; + // then_branch のコンパイル + CmEnv_clear_localnamePtr(); // 局所変数としての reg番号を初期化 + generated_codesize = CompileIfSentenceFromAST(then_branch, code, offset); + if (generated_codesize < 0) return -1; + + offset += generated_codesize; - - - code_size = i; - - // PutsCodeN(&code[2], i-2); - // exit(1); + if (offset > MAX_CODE_SIZE) { + puts("System ERROR: Generated codes were too big."); + return -1; } -#endif - + // JMPEQ0 のとび先を格納(相対ジャンプ) + code[label]=(void *)(unsigned long)generated_codesize; -// -------------------------------------------------------------- -// For Bubble Sort -// #define HAND_B_CONS -// -------------------------------------------------------------- + // else_branch のコンパイル + CmEnv_clear_localnamePtr(); // 局所変数としての reg番号を初期化 -#ifdef HAND_B_CONS - if ((strcmp(IdTable_get_name(idL), "B") == 0) && - (strcmp(IdTable_get_name(idR), "Cons") == 0)) { - - printf("Rule is optimised: %s >< %s.\n", - IdTable_get_name(idL), - IdTable_get_name(idR)); - - // PutsCodeN(&code[2], code_size-2); - - int i=2; - - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)13; - code[i++] = (void *)VM_OFFSET_META_L(1); - - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)14; - code[i++] = (void *)VM_OFFSET_META_R(0); - - code[i++] = CodeAddr[OP_LT]; - code[i++] = (void *)12; - code[i++] = (void *)13; - code[i++] = (void *)14; - - code[i++] = CodeAddr[OP_JMPEQ0]; - code[i++] = (void *)12; - code[i++] = (void *)32; - - code[i++] = CodeAddr[MKNAME]; - code[i++] = (void *)13; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)12; - code[i++] = (void *)8; - code[i++] = (void *)2; - code[i++] = (void *)1; - code[i++] = (void *)13; - - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)0; - code[i++] = (void *)12; - - code[i++] = CodeAddr[OP_JMPCNCT_CONS]; - code[i++] = (void *)VM_OFFSET_META_R(1); - code[i++] = (void *)10; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)14; - code[i++] = (void *)(unsigned long)idL; - code[i++] = (void *)2; - code[i++] = (void *)13; - code[i++] = (void *)5; - - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)14; - code[i++] = (void *)6; + generated_codesize = CompileIfSentenceFromAST(else_branch, code, offset); + if (generated_codesize < 0) return -1; + + offset += generated_codesize; - code[i++] = CodeAddr[RET_FREE_LR]; + if (offset > MAX_CODE_SIZE) { + puts("System ERROR: Generated codes were too big."); + return -1; + } - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)VM_OFFSET_META_L(0); - code[i++] = (void *)13; + return offset - offset_code; + } - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)VM_OFFSET_META_L(1); - code[i++] = (void *)VM_OFFSET_META_R(0); + +} - code[i++] = CodeAddr[LOOP_RREC2]; - code[i++] = (void *)VM_OFFSET_META_R(1); - - code[i++] = CodeAddr[MKNAME]; - code[i++] = (void *)13; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)12; - code[i++] = (void *)8; - code[i++] = (void *)2; - code[i++] = (void *)5; - code[i++] = (void *)13; - - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)0; - code[i++] = (void *)12; - - code[i++] = CodeAddr[OP_JMPCNCT_CONS]; - code[i++] = (void *)VM_OFFSET_META_R(1); - code[i++] = (void *)10; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)14; - code[i++] = (void *)(unsigned long)idL; - code[i++] = (void *)2; - code[i++] = (void *)13; - code[i++] = (void *)1; - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)14; - code[i++] = (void *)6; +int makeRule(Ast *ast) { + // (ASTRULE (AST_CNCT agentL agentR) + // ) + // + // WHERE + // ::= (AST_IF guard (AST_BRANCH )) + // | + // ::= + // ::= - code[i++] = CodeAddr[RET_FREE_LR]; + + int idR, idL; + Ast *ruleL, *ruleR, *if_sentence; - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)VM_OFFSET_META_L(0); - code[i++] = (void *)13; + void* code[MAX_CODE_SIZE]; + int code_offset=0; - code[i++] = CodeAddr[LOOP_RREC2]; - code[i++] = (void *)VM_OFFSET_META_R(1); + ruleL = ast->left->left; + ruleR = ast->left->right; + if (ruleL->id == AST_NAME) { + printf("ERROR: The name '%s' was specified as the left-hand side of rule agents. It should be an agent.\n", ruleL->left->sym); + return 0; + } + if (ruleR->id == AST_NAME) { + printf("ERROR: The name '%s' was specified as the right-hand side of rule agents. It should be an agent.\n", ruleR->left->sym); + return 0; + } + + + if_sentence = ast->right; - - - code_size = i; - - // PutsCodeN(&code[2], i-2); - // exit(1); - } + ruleL = ast_remove_tuple1(ruleL); + ruleR = ast_remove_tuple1(ruleR); + + + // #define MYDEBUG1 +#ifdef MYDEBUG1 + ast_puts(ruleL); puts(""); + ast_puts(ruleR); puts(""); + ast_puts(bodies); + exit(1); #endif + + // store ids of rule agent + idL = getRuleAgentID(ruleL); + idR = getRuleAgentID(ruleR); -// -------------------------------------------------------------- -// For Dup_SZ -// #define HAND_DUP_S -// -------------------------------------------------------------- -#ifdef HAND_DUP_S - if ((strcmp(IdTable_get_name(idL), "Dup") == 0) && - (strcmp(IdTable_get_name(idR), "S") == 0)) { - - printf("Rule is optimised: %s >< %s.\n", - IdTable_get_name(idL), - IdTable_get_name(idR)); - // PutsCodeN(&code[2], code_size-2); - - int i=2; - - code[i++] = CodeAddr[MKNAME]; - code[i++] = (void *)13; + /* + // prevent re-defining of built-in agents. + if (IdTable_is_builtin_rule(ruleL, ruleR)) { + printf("Warning: %s >< %s is already defined as built-in.\n", + IdTable_get_name(idL), IdTable_get_name(idR)); - code[i++] = CodeAddr[MKNAME]; - code[i++] = (void *)15; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)12; - code[i++] = (void *)(unsigned long)idR; - code[i++] = (void *)1; - code[i++] = (void *)13; - - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)VM_OFFSET_META_L(0); - code[i++] = (void *)12; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)14; - code[i++] = (void *)(unsigned long)idR; - code[i++] = (void *)1; - code[i++] = (void *)15; - - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)VM_OFFSET_META_L(1); - code[i++] = (void *)14; + } else { + + if (IdTable_is_builtin_rule(ruleR, ruleL)) { + printf("Warning: %s >< %s is already defined as built-in.\n", + IdTable_get_name(idR), IdTable_get_name(idL)); + } - - code[i++] = CodeAddr[OP_JMPCNCT]; - code[i++] = (void *)VM_OFFSET_META_R(0); - code[i++] = (void *)(unsigned long)idR; - code[i++] = (void *)10; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)16; - code[i++] = (void *)(unsigned long)idL; - code[i++] = (void *)2; - code[i++] = (void *)13; - code[i++] = (void *)15; - - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)16; - code[i++] = (void *)VM_OFFSET_META_R(0); - - code[i++] = CodeAddr[RET_FREE_LR]; + } + */ + + + // >< (int i) 対策 + // int i は (AST_INTVAR (AST_SYM sym NULL) NULL) として構築されているので + // ID_TUPLE1 である間は読み飛ばす + while (idL == ID_TUPLE1) { + ruleL = ruleL->right->left; + idL = getRuleAgentID(ruleL); + } + while (idR == ID_TUPLE1) { + ruleR = ruleR->right->left; + idR = getRuleAgentID(ruleR); + } + + + // Annotation (*L)、(*R) の処理があるため + // 単純に ruleAgentL、ruleAgentR を入れ替えれば良いわけではない。 - - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)VM_OFFSET_META_L(0); - code[i++] = (void *)13; + if (idL > idR) { + // Generally the order should be as Append(xs,r) >< y:ys, + // so idL should be greater than idR. + + // JAPANESE: 標準では Append(xs, r) >< [y|ys] なので + // idL の方が大きくなって欲しい - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)VM_OFFSET_META_L(1); - code[i++] = (void *)15; - - code[i++] = CodeAddr[LOOP_RREC1]; - code[i++] = (void *)VM_OFFSET_META_R(0); - //code[i++] = (void *)1; - - code_size = i; - - //PutsCodeN(&code[2], i-2); - // exit(1); - } -#endif + // (*L) is interpreted as the left-hand side agent, (*R) is the right one. + // JAPANESE: annotation が (*L) なら左側、(*R) なら右側を指すものとする + setAnnotateLR(VM_OFFSET_ANNOTATE_L, VM_OFFSET_ANNOTATE_R); + + } else { + Ast *tmp; + tmp = ruleL; + ruleL = ruleR; + ruleR = tmp; + int idTmp; + idTmp = idL; + idL = idR; + idR = idTmp; -// -------------------------------------------------------------- -// For ADD_SZ -//#define HAND_ADD_S -// -------------------------------------------------------------- -#ifdef HAND_ADD_S - if ((strcmp(IdTable_get_name(idL), "AddSZ") == 0) && - (strcmp(IdTable_get_name(idR), "S") == 0)) { + // Keep the occurrence (*L) and (*R) in aplist, + // change the interpretation of (*L) as (*R), vice versa. - printf("Rule is optimised: %s >< %s.\n", - IdTable_get_name(idL), - IdTable_get_name(idR)); - //PutsCodeN(&code[2], code_size-2); - - int i=2; - - code[i++] = CodeAddr[MKNAME]; - code[i++] = (void *)13; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)12; - code[i++] = (void *)(unsigned long)idR; - code[i++] = (void *)1; - code[i++] = (void *)13; - - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)VM_OFFSET_META_L(0);; - code[i++] = (void *)12; - - code[i++] = CodeAddr[OP_JMPCNCT]; - code[i++] = (void *)VM_OFFSET_META_R(0); - code[i++] = (void *)(unsigned long)idR; - code[i++] = (void *)10; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)14; - code[i++] = (void *)(unsigned long)idL; - code[i++] = (void *)2; - code[i++] = (void *)13; - code[i++] = (void *)VM_OFFSET_META_L(1); - - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)14; - code[i++] = (void *)VM_OFFSET_META_R(0); - - code[i++] = CodeAddr[RET_FREE_LR]; + // JAPANESE: aplist 内の (*L) (*R) はそのままにしておき、 + // annotation が (*L) なら右側、(*R) なら左側を指すものとする + setAnnotateLR(VM_OFFSET_ANNOTATE_R, VM_OFFSET_ANNOTATE_L); + } - - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)VM_OFFSET_META_L(0); - code[i++] = (void *)13; + { + int arity; - code[i++] = CodeAddr[LOOP_RREC1]; - code[i++] = (void *)VM_OFFSET_META_R(0); - - code_size = i; - // PutsCodeN(&code[2], i-2); - // exit(1); + // IMPORTANT: + // At the first two codes, arities of idL and idR are stored. + if (idL == ID_INT) { + arity = 0; + } else { + arity = getArityFromAST(ruleL); } -#endif - + IdTable_set_arity(idL, arity); + code[0] = (void *)(unsigned long)arity; -// -------------------------------------------------------------- -// For ACK_Sx -// #define HAND_ACK_S -// -------------------------------------------------------------- -#ifdef HAND_ACK_S - if ((strcmp(IdTable_get_name(idL), "Ack_Sx") == 0) && - (strcmp(IdTable_get_name(idR), "S") == 0)) { + if (idR == ID_INT) { + arity = 0; + } else { + arity = getArityFromAST(ruleR); + } + IdTable_set_arity(idR, arity); + code[1] = (void *)(unsigned long)arity; - printf("Rule is optimised: %s >< %s.\n", - IdTable_get_name(idL), - IdTable_get_name(idR)); - // PutsCodeN(&code[2], code_size-2); - - int i=2; - - code[i++] = CodeAddr[MKNAME]; - code[i++] = (void *)14; - - code[i++] = CodeAddr[MKNAME]; - code[i++] = (void *)15; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)13; - code[i++] = (void *)20; // Ack - code[i++] = (void *)2; - code[i++] = (void *)VM_OFFSET_META_L(0); - code[i++] = (void *)14; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)12; - code[i++] = (void *)24; // Dup - code[i++] = (void *)2; - code[i++] = (void *)13; - code[i++] = (void *)15; - - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)12; - code[i++] = (void *)1; - - code[i++] = CodeAddr[OP_JMPCNCT]; - code[i++] = (void *)VM_OFFSET_META_R(0); - code[i++] = (void *)(unsigned long)idR; - code[i++] = (void *)10; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)16; - code[i++] = (void *)(unsigned long)idL; - code[i++] = (void *)2; - code[i++] = (void *)14; - code[i++] = (void *)15; - - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)16; - code[i++] = (void *)5; + code_offset = 2; + } + + - code[i++] = CodeAddr[RET_FREE_LR]; - - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)VM_OFFSET_META_L(0); - code[i++] = (void *)14; + CmEnv_clear_all(); + + if (idL == ID_INT) { + setMetaL_asIntName(ruleL); + CmEnv.annotateL = ANNOTATE_AS_INT_AGENT; // to prevent putting FreeL out + } else { + setMetaL(ruleL); + } + + if (idR == ID_INT) { + setMetaR_asIntName(ruleR); + CmEnv.annotateR = ANNOTATE_AS_INT_AGENT; // to prevent putting FreeR out + } else { + setMetaR(ruleR); + } + + CmEnv.idL = idL; + CmEnv.idR = idR; - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)VM_OFFSET_META_L(1); - code[i++] = (void *)15; - code[i++] = CodeAddr[LOOP_RREC1]; - code[i++] = (void *)VM_OFFSET_META_R(0); - - code_size = i; - // PutsCodeN(&code[2], i-2); - // exit(1); + { + int generated_codesize = CompileIfSentenceFromAST(if_sentence, + code, code_offset); + if (generated_codesize < 0) { + return 0; } + code_offset += generated_codesize; + } + +#ifdef MYDEBUG + PutsCodeN(code, code_offset); exit(1); #endif - - - - - // #define HAND_FIB2 -#ifdef HAND_FIB2 - PutsCodeN(&code[2], code_size-2); - int i=2; - // code[i++] = CodeAddr[MKVAL]; - // code[i++] = (void *)14; - // code[i++] = (void *)0; - // code[i++] = (void *)0; - // - // code[i++] = CodeAddr[OP_EQ]; - // code[i++] = (void *)12; - // code[i++] = (void *)11; - // code[i++] = (void *)14; - - code[i++] = CodeAddr[OP_EQI]; - //code[i++] = (void *)11; // ここで 11(OFFSET_R)を壊してしまうと他で影響あり - code[i++] = (void *)12; - code[i++] = (void *)11; - code[i++] = (void *)0; - - code[i++] = CodeAddr[OP_JMPEQ0]; - code[i++] = (void *)12; - // code[i++] = (void *)8; - code[i++] = (void *)4; - - // code[i++] = CodeAddr[MKVAL]; - // code[i++] = (void *)12; - // code[i++] = (void *)0; - // code[i++] = (void *)1; - // - // code[i++] = CodeAddr[PUSH]; - // code[i++] = (void *)0; - // code[i++] = (void *)12; - - code[i++] = CodeAddr[PUSHI]; - code[i++] = (void *)0; - code[i++] = (void *)INT2FIX(1); - - code[i++] = CodeAddr[RET_FREE_L]; - - - - - // code[i++] = CodeAddr[MKVAL]; - // code[i++] = (void *)14; - // code[i++] = (void *)0; - // code[i++] = (void *)1; - // - // code[i++] = CodeAddr[OP_EQ]; - // code[i++] = (void *)12; - // code[i++] = (void *)11; - // code[i++] = (void *)14; - - code[i++] = CodeAddr[OP_EQI]; - code[i++] = (void *)12; - code[i++] = (void *)11; - code[i++] = (void *)1; - - code[i++] = CodeAddr[OP_JMPEQ0]; - code[i++] = (void *)12; - // code[i++] = (void *)8; - code[i++] = (void *)4; - - // code[i++] = CodeAddr[MKVAL]; - // code[i++] = (void *)12; - // code[i++] = (void *)0; - // code[i++] = (void *)1; - // - // code[i++] = CodeAddr[PUSH]; - // code[i++] = (void *)0; - // code[i++] = (void *)12; - - code[i++] = CodeAddr[PUSHI]; - code[i++] = (void *)0; - code[i++] = (void *)INT2FIX(1); - - - code[i++] = CodeAddr[RET_FREE_L]; - - - - // Fib(Add(n2,r))~b, Fib(n2)~c - // ------------------------------- - // Fib(n2)~c - code[i++] = CodeAddr[MKNAME]; - code[i++] = (void *)16; - - - code[i++] = CodeAddr[OP_SUBI]; - code[i++] = (void *)12; - code[i++] = (void *)11; - code[i++] = (void *)2; - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)13; - code[i++] = (void *)20; - code[i++] = (void *)1; - code[i++] = (void *)16; - - code[i++] = CodeAddr[PUSH]; - code[i++] = (void *)13; - code[i++] = (void *)12; - - - // ------------------------------- - // Fib(Add(n2,r))~b - code[i++] = CodeAddr[OP_SUBI]; - code[i++] = (void *)13; - code[i++] = (void *)11; - code[i++] = (void *)1; - - - code[i++] = CodeAddr[MKAGENT]; - code[i++] = (void *)14; - code[i++] = (void *)10; - code[i++] = (void *)2; - code[i++] = (void *)16; - code[i++] = (void *)0; - - - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)VM_OFFSET_META_L(0); - code[i++] = (void *)14; - - code[i++] = CodeAddr[LOAD]; - code[i++] = (void *)VM_OFFSET_ANNOTATE_R; - code[i++] = (void *)13; - - code[i++] = CodeAddr[LOOP]; - - code_size = i; - PutsCodeN(&code[2], i-2); - // exit(1); -#endif - - - - //ast_puts(ruleL); printf("><"); - //ast_puts(ruleR); puts(""); + PutsCodeN(code, code_offset); exit(1); + // printf("Rule: %s(id:%d) >< %s(id:%d).\n", + // IdTable_get_name(idL), idL, + // IdTable_get_name(idR), idR); + // PutsCodeN(&code[2], code_offset-2); + // exit(1); + + //ast_puts(ruleL); printf("><"); + //ast_puts(ruleR); puts(""); + // Record the rule code for idR >< idL - RuleTable_record(idL, idR, code_size, code); - + RuleTable_record(idL, idR, code, code_offset); + if (idL != idR) { // Delete the rule code for idR >< idL // because we need only the rule idL >< idR. @@ -5418,8 +4446,12 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { //http://magazine.rubyist.net/?0008-YarvManiacs static const void *table[] = { - &&E_PUSH, &&E_PUSHI, &&E_MKNAME, &&E_MKGNAME, &&E_MKAGENT, - &&E_REUSEAGENT, &&E_MYPUSH, + &&E_PUSH, &&E_PUSHI, &&E_MKNAME, &&E_MKGNAME, + &&E_MKAGENT0, &&E_MKAGENT1, &&E_MKAGENT2, + &&E_MKAGENT3, &&E_MKAGENT4, &&E_MKAGENT5, + &&E_REUSEAGENT0 ,&&E_REUSEAGENT1, &&E_REUSEAGENT2, + &&E_REUSEAGENT3, &&E_REUSEAGENT4, &&E_REUSEAGENT5, + &&E_MYPUSH, &&E_RET, &&E_RET_FREE_LR, &&E_RET_FREE_L, &&E_RET_FREE_R, &&E_LOOP, &&E_LOOP_RREC, &&E_LOOP_RREC1, &&E_LOOP_RREC2, &&E_LOADI, &&E_LOAD, &&E_LOADP, @@ -5438,7 +4470,7 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { return table; } - int arity, i, pc=0; + int i, pc=0; VALUE a1; goto *code[0]; @@ -5446,65 +4478,178 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { E_MKNAME: // puts("mkname"); - vm->reg[(unsigned long)code[pc+1]] = makeName(vm); - pc +=2; + pc++; + vm->reg[(unsigned long)code[pc++]] = makeName(vm); goto *code[pc]; E_MKGNAME: - // puts("mkgname"); + // puts("mkgname reg sym"); //a1 = makeGlobalName(vm, (char *)code[pc+1]); - a1 = NameTable_get_heap((char *)code[pc+1]); + a1 = NameTable_get_heap((char *)code[pc+2]); if (a1 == (VALUE)NULL) { i = IdTable_new_gnameid(); a1 = makeName(vm); // set GID obtained by IdTable_new_gnameid() BASIC(a1)->id = i; - NameTable_set_heap_id((char *)code[pc+1], a1, i); + NameTable_set_heap_id((char *)code[pc+2], a1, i); } - vm->reg[(unsigned long)code[pc+2]] = a1; + vm->reg[(unsigned long)code[pc+1]] = a1; pc +=3; goto *code[pc]; - E_MKAGENT: - // puts("mkagent"); - arity = (unsigned long)code[pc+3]; + E_MKAGENT0: + // puts("mkagent0 reg id"); + vm->reg[(unsigned long)code[pc+1]] = + makeAgent(vm, (unsigned long)code[pc+2]);; + + pc+=3; + goto *code[pc]; + + E_MKAGENT1: + // puts("mkagent0 reg id"); + a1 = makeAgent(vm, (unsigned long)code[pc+2]); + vm->reg[(unsigned long)code[pc+1]] = a1; + pc+=3; + AGENT(a1)->port[0] = vm->reg[(unsigned long)code[pc++]]; + + goto *code[pc]; + + E_MKAGENT2: + // puts("mkagent0 reg id"); a1 = makeAgent(vm, (unsigned long)code[pc+2]); vm->reg[(unsigned long)code[pc+1]] = a1; + pc+=3; { volatile VALUE *a1port = AGENT(a1)->port; - - pc +=4; - - for(i=0; iport[i] = vm->reg[(unsigned long)code[pc]]; - a1port[i] = vm->reg[(unsigned long)code[pc++]]; - } - + a1port[0] = vm->reg[(unsigned long)code[pc++]]; + a1port[1] = vm->reg[(unsigned long)code[pc++]]; + } + goto *code[pc]; + + + E_MKAGENT3: + // puts("mkagent0 reg id"); + a1 = makeAgent(vm, (unsigned long)code[pc+2]); + vm->reg[(unsigned long)code[pc+1]] = a1; + pc+=3; + { + volatile VALUE *a1port = AGENT(a1)->port; + a1port[0] = vm->reg[(unsigned long)code[pc++]]; + a1port[1] = vm->reg[(unsigned long)code[pc++]]; + a1port[2] = vm->reg[(unsigned long)code[pc++]]; + } + goto *code[pc]; + + E_MKAGENT4: + // puts("mkagent0 reg id"); + a1 = makeAgent(vm, (unsigned long)code[pc+2]); + vm->reg[(unsigned long)code[pc+1]] = a1; + pc+=3; + { + volatile VALUE *a1port = AGENT(a1)->port; + a1port[0] = vm->reg[(unsigned long)code[pc++]]; + a1port[1] = vm->reg[(unsigned long)code[pc++]]; + a1port[2] = vm->reg[(unsigned long)code[pc++]]; + a1port[3] = vm->reg[(unsigned long)code[pc++]]; + } + goto *code[pc]; + + E_MKAGENT5: + // puts("mkagent0 reg id"); + a1 = makeAgent(vm, (unsigned long)code[pc+2]); + vm->reg[(unsigned long)code[pc+1]] = a1; + pc+=3; + { + volatile VALUE *a1port = AGENT(a1)->port; + a1port[0] = vm->reg[(unsigned long)code[pc++]]; + a1port[1] = vm->reg[(unsigned long)code[pc++]]; + a1port[2] = vm->reg[(unsigned long)code[pc++]]; + a1port[3] = vm->reg[(unsigned long)code[pc++]]; + a1port[4] = vm->reg[(unsigned long)code[pc++]]; } goto *code[pc]; - E_REUSEAGENT: // reuseagent target id arity - // puts("reuseagent"); + + + E_REUSEAGENT0: + // puts("reuseagent target id"); a1 = vm->reg[(unsigned long)code[pc+1]]; AGENT(a1)->basic.id = (unsigned long)code[pc+2]; + pc+=3; + + goto *code[pc]; + + E_REUSEAGENT1: + // puts("reuseagent target id"); + pc++; + a1 = vm->reg[(unsigned long)code[pc++]]; + AGENT(a1)->basic.id = (unsigned long)code[pc++]; + AGENT(a1)->port[0] = vm->reg[(unsigned long)code[pc++]]; + + goto *code[pc]; + + + E_REUSEAGENT2: + // puts("reuseagent target id"); + pc++; + a1 = vm->reg[(unsigned long)code[pc++]]; + AGENT(a1)->basic.id = (unsigned long)code[pc++]; { volatile VALUE *a1port = AGENT(a1)->port; - arity = (unsigned long)code[pc+3]; - pc +=4; - for(i=0; iport[i] = vm->reg[(unsigned long)code[pc]]; - a1port[i] = vm->reg[(unsigned long)code[pc]]; - pc++; - } - } + a1port[0] = vm->reg[(unsigned long)code[pc++]]; + a1port[1] = vm->reg[(unsigned long)code[pc++]]; + } goto *code[pc]; + E_REUSEAGENT3: + // puts("reuseagent target id"); + pc++; + a1 = vm->reg[(unsigned long)code[pc++]]; + AGENT(a1)->basic.id = (unsigned long)code[pc++]; + { + volatile VALUE *a1port = AGENT(a1)->port; + a1port[0] = vm->reg[(unsigned long)code[pc++]]; + a1port[1] = vm->reg[(unsigned long)code[pc++]]; + a1port[2] = vm->reg[(unsigned long)code[pc++]]; + } + goto *code[pc]; + + E_REUSEAGENT4: + // puts("reuseagent target id"); + pc++; + a1 = vm->reg[(unsigned long)code[pc++]]; + AGENT(a1)->basic.id = (unsigned long)code[pc++]; + { + volatile VALUE *a1port = AGENT(a1)->port; + a1port[0] = vm->reg[(unsigned long)code[pc++]]; + a1port[1] = vm->reg[(unsigned long)code[pc++]]; + a1port[2] = vm->reg[(unsigned long)code[pc++]]; + a1port[3] = vm->reg[(unsigned long)code[pc++]]; + } + goto *code[pc]; + + E_REUSEAGENT5: + // puts("reuseagent target id"); + pc++; + a1 = vm->reg[(unsigned long)code[pc++]]; + AGENT(a1)->basic.id = (unsigned long)code[pc++]; + { + volatile VALUE *a1port = AGENT(a1)->port; + a1port[0] = vm->reg[(unsigned long)code[pc++]]; + a1port[1] = vm->reg[(unsigned long)code[pc++]]; + a1port[2] = vm->reg[(unsigned long)code[pc++]]; + a1port[3] = vm->reg[(unsigned long)code[pc++]]; + a1port[4] = vm->reg[(unsigned long)code[pc++]]; + } + goto *code[pc]; + + /* ===TODO=== @@ -5994,18 +5139,6 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { -void errprintf(int tid) { - printf("%2d:", tid); -} - -void errputs(char *s, int tid) { - /* - errprintf(tid); - puts(s); - */ -} - - /****************************************** Mark and Sweep for error recovery ******************************************/ @@ -6887,6 +6020,32 @@ void VM_Init(VirtualMachine *vm, unsigned int eqStackSize) { + +void select_kind_of_push(Ast *ast, int p1, int p2) { + char *sym = ast->left->sym; + VALUE aheap = NameTable_get_heap(sym); + + if (aheap != (VALUE)NULL) { + // aheap already exists as a global + + // aheap is connected with something such as aheap->t + // ==> p2 should be conncected with t, so CNCTGN(p1,p2) + if (NAME(aheap)->port != (VALUE)NULL) { + IMCode_genCode2(CNCTGN, p1, p2); + + } else { + // aheap occurs somewhere, so it should be replaced by SUBSTGN(p1,p2) + IMCode_genCode2(SUBSTGN, p1, p2); + } + } else { + IMCode_genCode2(PUSH, p1, p2); + } + +} + + + + #ifndef THREAD @@ -6944,29 +6103,6 @@ void WHNF_execution_loop() { } -void select_kind_of_push(Ast *ast, int p1, int p2) { - char *sym = ast->left->sym; - VALUE aheap = NameTable_get_heap(sym); - - if (aheap != (VALUE)NULL) { - // aheap already exists as a global - - // aheap is connected with something such as aheap->t - // ==> p2 should be conncected with t, so CNCTGN(p1,p2) - if (NAME(aheap)->port != (VALUE)NULL) { - EnvAddCodeCNCTGN((void *)(unsigned long)p1, - (void *)(unsigned long)p2); - } else { - // aheap occurs somewhere, so it should be replaced by SUBSTGN(p1,p2) - EnvAddCodeSUBSTGN((void *)(unsigned long)p1, - (void *)(unsigned long)p2); - } - } else { - EnvAddCodePUSH((void *)(unsigned long)p1, (void *)(unsigned long)p2); - } - - -} int exec(Ast *at) { @@ -6984,6 +6120,7 @@ int exec(Ast *at) { // for `where' expression if (!CompileStmListFromAst(at->left)) return 0; + // aplist at = at->right; @@ -7020,11 +6157,6 @@ int exec(Ast *at) { p2 = CompileTermFromAst(right, -1); - /* - EnvAddCodePUSH((void *)(unsigned long)p1, (void *)(unsigned long)p2); - at = ast_getTail(at); - */ - if (left->id == AST_NAME) { select_kind_of_push(left, p1, p2); @@ -7032,7 +6164,7 @@ int exec(Ast *at) { select_kind_of_push(right, p2, p1); } else { - EnvAddCodePUSH((void *)(unsigned long)p1, (void *)(unsigned long)p2); + IMCode_genCode2(PUSH, p1, p2); } at = ast_getTail(at); @@ -7040,7 +6172,9 @@ int exec(Ast *at) { } - EnvAddCode(CodeAddr[RET]); + IMCode_genCode0(RET); + + // checking whether names occur more than twice if (!CmEnv_check_name_reference_times()) { @@ -7048,12 +6182,15 @@ int exec(Ast *at) { return 0; } + // Generate codes from CmEnv, where '0' means index of the `code', // so here codes are stored from code[0]. - CmEnv_generate_code_with_nameinfo(code,0); + CmEnv_Retrieve_GNAME(); + // IMCode_Puts(0); + CmEnv_Generate_VMCode(code, 0); + // PutsCode(code); exit(1); - //PutsCode(code); exit(1); #ifdef COUNT_MKAGENT NumberOfMkAgent=0; @@ -7249,14 +6386,17 @@ int exec(Ast *at) { #endif void* code[MAX_CODE_SIZE]; + int eqsnum = 0; start_timer(&t); + CmEnv_clear_all(); // for `where' expression if (!CompileStmListFromAst(at->left)) return 0; + // aplist at = at->right; @@ -7280,22 +6420,40 @@ int exec(Ast *at) { while (at!=NULL) { int p1,p2; - p1 = CompileTermFromAst(at->left->left, -1); - p2 = CompileTermFromAst(at->left->right, -1); - EnvAddCodeMYPUSH((void *)(unsigned long)p1, (void *)(unsigned long)p2); + Ast *left, *right; + left = at->left->left; + right = at->left->right; + p1 = CompileTermFromAst(left, -1); + p2 = CompileTermFromAst(right, -1); + + if (left->id == AST_NAME) { + select_kind_of_push(left, p1, p2); + + } else if (right->id == AST_NAME) { + select_kind_of_push(right, p2, p1); + + } else { + IMCode_genCode2(PUSH, p1, p2); + } + eqsnum++; //分散用 at = ast_getTail(at); } - EnvAddCode(CodeAddr[RET]); + IMCode_genCode0(RET); + // checking whether names occur more than twice if (!CmEnv_check_name_reference_times()) { return 0; } + // '0' means that generated codes are stored in code[0,...]. - CmEnv_generate_code_with_nameinfo(code,0); + CmEnv_Retrieve_GNAME(); + CmEnv_Generate_VMCode(code, 0); - //PutsCode(code); exit(1); + // int codenum = CmEnv_Generate_VMCode(code, 0); + // PutsCodeN(code, codenum); exit(1); + ExecCode(1, VMs[0], code); -- cgit v1.2.3 From da1be1b095fbf26eaad1d29539d1c03f5e84fd7b Mon Sep 17 00:00:00 2001 From: Shinya Sato Date: Mon, 10 Jan 2022 23:34:22 +0900 Subject: Update inpla.y --- src/inpla.y | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/inpla.y b/src/inpla.y index 11d7565..3a1f7de 100644 --- a/src/inpla.y +++ b/src/inpla.y @@ -50,8 +50,8 @@ int SleepingThreadsNum=0; //#define YYDEBUG 1 -#define VERSION "0.6.0" -#define BUILT_DATE "9 Jan. 2022" +#define VERSION "0.7.0(dev)" +#define BUILT_DATE "10 Jan. 2022" extern FILE *yyin; @@ -707,7 +707,7 @@ HoopList *HoopList_New_forName(void) { -HoopList *HoopList_New_forAgent() { +HoopList *HoopList_New_forAgent(void) { int i; HoopList *hp_list; @@ -1853,7 +1853,7 @@ static CmEnvironment CmEnv; void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code); -void CmEnv_clear_all(); +void CmEnv_clear_all(void); void CmEnv_Init(int vm_heapsize) { @@ -1870,7 +1870,7 @@ void CmEnv_Init(int vm_heapsize) { static inline -void CmEnv_clear_localnamePtr() { +void CmEnv_clear_localnamePtr(void) { CmEnv.localNamePtr = VM_OFFSET_LOCALVAR; } @@ -1892,7 +1892,7 @@ void CmEnv_clear_bind(int preserve_idx) { } -void CmEnv_clear_all() +void CmEnv_clear_all(void) { // clear all the information of names. CmEnv_clear_bind(-1); @@ -1909,7 +1909,7 @@ void CmEnv_clear_all() IMCode_Init(); } -void CmEnv_clear_keeping_rule_properties() +void CmEnv_clear_keeping_rule_properties(void) { // clear the information of names EXCEPT meta ones. CmEnv_clear_bind(CmEnv.bindPtr_metanames); @@ -2036,7 +2036,7 @@ int CmEnv_gettype_forname(char *key, NB_TYPE *type) { // Agent用の RegNo を取得する (just for newreg) //(これらは、Envコンパイル時に mkName、mkGname の対象にならないため // 一時的な変数として使われる) -int CmEnv_newreg() { +int CmEnv_newreg(void) { int result; result = CmEnv.localNamePtr; @@ -2051,7 +2051,7 @@ int CmEnv_newreg() { -int CmEnv_check_meta_occur_once() { +int CmEnv_check_meta_occur_once(void) { int i; for (i=0; i< %s(id:%d).\n", // IdTable_get_name(idL), idL, @@ -5201,7 +5201,7 @@ void mark_name_port0(VALUE ptr) { } -void mark_allHash() { +void mark_allHash(void) { int i; NameList *at; @@ -5260,7 +5260,7 @@ void sweep_NameHeap(Heap *hp) { -void mark_and_sweep() { +void mark_and_sweep(void) { mark_allHash(); sweep_AgentHeap(&(VM.agentHeap)); @@ -6059,7 +6059,7 @@ typedef struct { } WHNF_Info; WHNF_Info WHNFinfo; -void Init_WHNFinfo() { +void Init_WHNFinfo(void) { WHNFinfo.eqs_index = 0; WHNFinfo.size = WHNF_UNUSED_STACK_SIZE; WHNFinfo.enabled = 0; // not Enabled @@ -6082,7 +6082,7 @@ void WHNFInfo_push_equation(VALUE t1, VALUE t2) { } -void WHNF_execution_loop() { +void WHNF_execution_loop(void) { VALUE t1, t2; while (EQStack_Pop(&VM, &t1, &t2)) { @@ -6361,7 +6361,7 @@ void tpool_init(unsigned int eqstack_size) { } } -void tpool_destroy() { +void tpool_destroy(void) { int i; for (i=0; i Date: Wed, 12 Jan 2022 22:43:02 +0900 Subject: v0.6.1 --- Changelog.md | 17 +- README.md | 32 +- pic/benchmark_reuse.png | Bin 30089 -> 0 bytes pic/benchmark_reuse_v0.6.0.png | Bin 29390 -> 0 bytes pic/benchmark_reuse_v0.6.1.png | Bin 0 -> 29626 bytes src/.#-emacsisVpxW | 1 + src/inpla.y | 1022 ++++++++++++++++++++-------------------- src/mytype.h | 14 + src/name_table.c | 1 + src/name_table.h | 2 +- 10 files changed, 553 insertions(+), 536 deletions(-) delete mode 100644 pic/benchmark_reuse.png delete mode 100644 pic/benchmark_reuse_v0.6.0.png create mode 100644 pic/benchmark_reuse_v0.6.1.png create mode 100644 src/.#-emacsisVpxW diff --git a/Changelog.md b/Changelog.md index a1cf2aa..37c0a2a 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,15 +1,28 @@ # Change log + +### v0.6.1 (released on 12 January 2022) + +#### New Features: +- **Introduced automatically expandable equation stacks**: Stacks for equations are automatically expanded when the stacks overflow. The unit size is 256, so each stack size in virtual machines starts from 256, and these will be twice (256), triple (768) and so on. The unit size is specified by the execution option `-x`. For instance, Inpla invoked with `-x 1024` assigns a 1024-size equation stack for each thread. As for the global equation stack, the size is specified as `(the number of threads) * 8` in the `main` function as follows, so change it to improve the execution performance: + + ``` + GlobalEQStack_Init(MaxThreadsNum*8); + ``` + + + + ### v0.6.0 (released on 9 January 2022) #### New Features: -- Introduced new data structure for ring buffers for agents and names: The ring buffers are automatically expanded when all elements of these are used up. Each size starts from 2^18 (=262144), and it will be twice, triple and so on automatically. To adjust the unit size, change the following definition in `src/inpla.y`: +- **Introduced new data structure for ring buffers for agents and names**: The ring buffers are automatically expanded when all elements of these are used up. Each size starts from 2^18 (=262144), and it will be twice, triple and so on automatically. To adjust the unit size, change the following definition in `src/inpla.y`: ``` #define HOOP_SIZE (1 << 18) ``` -- Deleted the execution option `-c` that specifies the size of these ring buffers: This execution option is deleted because these buffers are expanded as needed. +- **Deleted the execution option `-c` that specifies the size of these ring buffers**: This execution option is deleted because these buffers are expanded as needed. diff --git a/README.md b/README.md index da1c641..bd4beb3 100644 --- a/README.md +++ b/README.md @@ -6,18 +6,18 @@ Inpla is a multi-threaded parallel interpreter of interaction nets. Once you write programs for sequential execution, it works also in multi-threaded parallel execution. Each thread is managed on each CPU-core with POSIX-thread library. -* The current version is 0.6.0 released on **9 January 2022**. (See [Changelog.md](Changelog.md) for details.) +* The current version is 0.6.1 released on **12 January 2022**. (See [Changelog.md](Changelog.md) for details.) -![speedup-ratio](pic/benchmark_reuse_v0.6.0.png) +![speedup-ratio](pic/benchmark_reuse_v0.6.1.png) | | Haskell | SML | Python | Inpla1 | Inpla1_r | Inpla7 | Inpla7_r | | -------------- | :------: | :------: | :----: | :----: | :------: | :----: | :------: | -| ack(3,11) | 2.31 | **0.41** | - | 5.54 | 4.57 | 1.58 | 0.92 | -| fib 38 | 1.60 | **0.26** | 8.49 | 3.96 | 3.83 | 0.67 | 0.62 | -| bsort 40000 | 34.81 | 11.17 | 76.72 | 26.31 | 21.07 | 7.39 | **3.41** | -| isort 40000 | **0.02** | 2.97 | 36.63 | 12.59 | 10.03 | 3.65 | 1.63 | -| qsort 800000 | **0.15** | 1.16 | 97.30 | 3.79 | 2.04 | 0.77 | 0.37 | -| msort 800000 | 0.46 | 1.00 | 98.27 | 2.50 | 1.45 | 0.64 | **0.39** | +| ack(3,11) | 2.31 | **0.41** | - | 5.46 | 4.16 | 1.56 | 0.86 | +| fib 38 | 1.60 | **0.26** | 8.49 | 3.93 | 3.68 | 0.69 | 0.62 | +| bsort 40000 | 34.81 | 11.17 | 76.72 | 25.75 | 19.06 | 7.32 | **3.14** | +| isort 40000 | **0.02** | 2.97 | 36.63 | 12.38 | 9.25 | 3.64 | 1.53 | +| qsort 800000 | **0.15** | 1.16 | 97.30 | 3.83 | 1.91 | 0.77 | 0.35 | +| msort 800000 | 0.46 | 1.00 | 98.27 | 2.39 | 1.39 | 0.69 | **0.41** | - **Comparison in execution time** with other implementations: **Haskell** (GHC version 8.10.7), **Standard ML of New Jersey** v110.74 (interpreter mode) and **Python** 3.8.5 in execution time. @@ -73,7 +73,7 @@ Inpla is a multi-threaded parallel interpreter of interaction nets. Once you wri ``` $ ./inpla - Inpla 0.6.0 : Interaction nets as a programming language [built: 9 Jan. 2022] + Inpla 0.6.1 : Interaction nets as a programming language [built: 12 Jan. 2022] >>> ``` @@ -130,7 +130,7 @@ Inpla is a multi-threaded parallel interpreter of interaction nets. Once you wri ``` $ ./inpla -f sample/gcd.in - Inpla 0.6.0 : Interaction nets as a programming language [built: 9 Jan. 2022] + Inpla 0.6.1 : Interaction nets as a programming language [built: 12 Jan. 2022] (4 interactions, 0.00 sec) 7 @@ -163,7 +163,7 @@ Inpla is a multi-threaded parallel interpreter of interaction nets. Once you wri ``` $ ./inpla -f sample/isort.in - Inpla 0.6.0 : Interaction nets as a programming language [built: 9 Jan. 2022] + Inpla 0.6.1 : Interaction nets as a programming language [built: 12 Jan. 2022] (16 interactions, 0.00 sec) [1,2,3,6,9] @@ -233,7 +233,7 @@ Inpla is a multi-threaded parallel interpreter of interaction nets. Once you wri ``` $ ./inpla -f sample/qsort.in - Inpla 0.6.0 : Interaction nets as a programming language [built: 9 Jan. 2022] + Inpla 0.6.1 : Interaction nets as a programming language [built: 12 Jan. 2022] (22 interactions, 0.00 sec) [1,2,3,6,9] @@ -259,13 +259,13 @@ Inpla is a multi-threaded parallel interpreter of interaction nets. Once you wri ``` $ ./inpla -h - Inpla version 0.6.0 + Inpla version 0.6.1 Usage: inpla [options] Options: - -f Set input file name (Defalut: STDIN) - -x Set the size of the EQ stack (Default: 10000) - -t Set the number of threads (Default: 1) + -f Set input file name (Defalut: STDIN) + -x Set the unit size of the EQ stack (Default: 256) + -t Set the number of threads (Default: 1) -d = Bind to -h Print this help message ``` diff --git a/pic/benchmark_reuse.png b/pic/benchmark_reuse.png deleted file mode 100644 index 14004d5..0000000 Binary files a/pic/benchmark_reuse.png and /dev/null differ diff --git a/pic/benchmark_reuse_v0.6.0.png b/pic/benchmark_reuse_v0.6.0.png deleted file mode 100644 index 29f03c2..0000000 Binary files a/pic/benchmark_reuse_v0.6.0.png and /dev/null differ diff --git a/pic/benchmark_reuse_v0.6.1.png b/pic/benchmark_reuse_v0.6.1.png new file mode 100644 index 0000000..58a66fd Binary files /dev/null and b/pic/benchmark_reuse_v0.6.1.png differ diff --git a/src/.#-emacsisVpxW b/src/.#-emacsisVpxW new file mode 100644 index 0000000..2dce138 --- /dev/null +++ b/src/.#-emacsisVpxW @@ -0,0 +1 @@ +shinya@DESKTOP-O24CQQG.15520:1641730776 \ No newline at end of file diff --git a/src/inpla.y b/src/inpla.y index 3a1f7de..d7bb8ab 100644 --- a/src/inpla.y +++ b/src/inpla.y @@ -7,34 +7,44 @@ #include #include +#include "timer.h" //#include #include "linenoise/linenoise.h" #include "ast.h" #include "id_table.h" #include "name_table.h" +#include "mytype.h" -#include "timer.h" //#include -//#define DEBUG -#define COUNT_INTERACTION // count of interaction -//#define NODE_USE_VERBOSE // count of memory access + +// Configuration --------------------------------------------------- +#define COUNT_INTERACTION // Count interaction. +//#define VERBOSE_NODE_USE // Put memory usage of agents and names. +//#define VERBOSE_HOOP_EXPANSION // Put messages when hoops are expanded. + +//#define VERBOSE_EQSTACK_EXPANSION // Put messages when Eqstacks are expanded. +// ---------------------------------------------- + +//#define DEBUG + // For experiments of the tail recursion optimisation. //#define COUNT_CNCT // count of execution of JMP_CNCT //#define COUNT_MKAGENT // count of execution fo mkagent +#define VERSION "0.6.1" +#define BUILT_DATE "12 Jan. 2022" +// ------------------------------------------------------------------ + - -/************************************** - NAME TABLE -**************************************/ -//#include "name_table.h" -// ---------------------------------------------- + + +// For threads --------------------------------- int MaxThreadsNum=1; #ifdef THREAD @@ -48,33 +58,9 @@ int SleepingThreadsNum=0; #endif -//#define YYDEBUG 1 - -#define VERSION "0.7.0(dev)" -#define BUILT_DATE "10 Jan. 2022" - +// ---------------------------------------------- +// For parsing -extern FILE *yyin; - - -#include "mytype.h" - -// Equation -typedef struct EQ_tag { - VALUE l, r; -} EQ; - -typedef struct EQList_tag { - EQ eq; - struct EQList_tag *next; -} EQList; - - - - - - - int makeRule(Ast *ast); void freeAgentRec(VALUE ptr); @@ -89,17 +75,13 @@ void free_names_ast(Ast *ast); void puts_name_port0_nat(VALUE ptr); void puts_term(VALUE ptr); void puts_aplist(EQList *at); -void PushEQStack(VALUE l, VALUE r); - int exec(Ast *st); int destroy(void); -int AstHeap_MakeAgent(int arity, char *name, int *port); -int AstHeap_MakeTerm(char *name); -int AstHeap_MakeName(char *name); - - + +//#define YYDEBUG 1 +extern FILE *yyin; extern int yylex(); int yyerror(); #define YY_NO_INPUT @@ -153,25 +135,11 @@ extern void pushFP(FILE *fp); extern int popFP(); -// In order to prevent from putting yyerror message, -// the message will be stored here. +// Messages from yyerror will be stored here. +// This works to prevent puting the message. static char *Errormsg = NULL; -//#define YYDEBUG 1 -//#define YYERROR_VERBOSE 1 -//int yydebug = 1; - -/* -extern void eat_to_newline(void); -void eat_to_newline(void) -{ - int c; - while ((c = getchar()) != EOF && c != '\n') - ; -} -*/ - %} %union{ int intval; @@ -587,27 +555,30 @@ int yyerror(char *s) { -/************************************** - TABLE for SYMBOLS -**************************************/ -//#include "id_table.h" - - /********************************** - Heap + AGENT and NAME Heaps *********************************/ //#define HOOP_SIZE (1 << 14) #define HOOP_SIZE (1 << 18) #define HOOP_SIZE_MASK ((HOOP_SIZE) -1) + typedef struct HoopList_tag { VALUE *hoop; struct HoopList_tag *next; } HoopList; +// Nodes with '1' on the 31bit in hoops are ready for use and +// '0' are occupied, that is to say, using now. +#define HOOPFLAG_READYFORUSE 0x01 << 31 +#define IS_READYFORUSE(a) ((a) & HOOPFLAG_READYFORUSE) +#define SET_HOOPFLAG_READYFORUSE(a) ((a) = ((a) | HOOPFLAG_READYFORUSE)) +#define TOGGLE_HOOPFLAG_READYFORUSE(a) ((a) = ((a) ^ HOOPFLAG_READYFORUSE)) + + typedef struct Heap_tag { HoopList *last_alloc_list; int last_alloc_idx; @@ -615,69 +586,6 @@ typedef struct Heap_tag { -/********************************** - VIRTUAL MACHINE -*********************************/ -#define VM_LOCALVAR_SIZE 200 -#define VM_OFFSET_META_L(a) (a) -#define VM_OFFSET_META_R(a) (MAX_PORT+(a)) -#define VM_OFFSET_ANNOTATE_L (MAX_PORT*2) -#define VM_OFFSET_ANNOTATE_R (MAX_PORT*2+1) -#define VM_OFFSET_LOCALVAR (MAX_PORT*2+2) - - - -typedef struct { - // Heaps for agents and names - Heap agentHeap, nameHeap; - - // EQStack - EQ *eqStack; - int nextPtr_eqStack; - unsigned int eqStack_size; - - - // code execution - VALUE reg[VM_LOCALVAR_SIZE+(MAX_PORT*2 + 2)]; - - unsigned int id; -#ifdef COUNT_INTERACTION - unsigned int count_interaction; - -#endif - -} VirtualMachine; - -#ifdef COUNT_INTERACTION -#define COUNTUP_INTERACTION(vm) vm->count_interaction++ -#else -#define COUNTUP_INTERACTION(vm) -#endif - - -#ifndef THREAD -static VirtualMachine VM; -#endif - -#ifdef COUNT_MKAGENT - unsigned int NumberOfMkAgent; - // unsigned int id; -#endif - - -/************************************* - AGENT and NAME Heaps -**************************************/ - -// Nodes in hoops with '1' on the 31bit are ready for use and -// '0' are occupied, that is to say, using now. -#define HEAPFLAG_READYFORUSE 0x01 << 31 -#define IS_READYFORUSE(a) ((a) & HEAPFLAG_READYFORUSE) -#define SET_HEAPFLAG_READYFORUSE(a) ((a) = ((a) | HEAPFLAG_READYFORUSE)) -#define TOGGLE_HEAPFLAG_READYFORUSE(a) ((a) = ((a) ^ HEAPFLAG_READYFORUSE)) - - - HoopList *HoopList_New_forName(void) { int i; HoopList *hp_list; @@ -697,7 +605,7 @@ HoopList *HoopList_New_forName(void) { } for (i=0; ihoop))[i].basic.id = ID_NAME; - SET_HEAPFLAG_READYFORUSE(((Name *)(hp_list->hoop))[i].basic.id); + SET_HOOPFLAG_READYFORUSE(((Name *)(hp_list->hoop))[i].basic.id); } // hp->next = NULL; // this should be executed only for the first creation. @@ -725,7 +633,7 @@ HoopList *HoopList_New_forAgent(void) { exit(-1); } for (i=0; ihoop))[i].basic.id); + SET_HOOPFLAG_READYFORUSE(((Agent *)(hp_list->hoop))[i].basic.id); } // hp->next = NULL; // this should be executed only for the first creation. @@ -735,27 +643,6 @@ HoopList *HoopList_New_forAgent(void) { -void VM_Buffer_Init(VirtualMachine *vm) { - - // Agent Heap - /* - vm->agentHeap.hoop_list = HoopList_New_forAgent(); - vm->agentHeap.hoop_list->next = vm->agentHeap.hoop_list; - vm->agentHeap.last_alloc_idx = 0; - vm->agentHeap.last_alloc_list = vm->agentHeap.hoop_list; - */ - - vm->agentHeap.last_alloc_list = HoopList_New_forAgent(); - vm->agentHeap.last_alloc_list->next = vm->agentHeap.last_alloc_list; - vm->agentHeap.last_alloc_idx = 0; - - - // Name Heap - vm->nameHeap.last_alloc_list = HoopList_New_forName(); - vm->nameHeap.last_alloc_list->next = vm->nameHeap.last_alloc_list; - vm->nameHeap.last_alloc_idx = 0; - -} unsigned long Heap_GetNum_Usage_forAgent(Heap *hp) { @@ -822,7 +709,7 @@ VALUE myallocAgent(Heap *hp) { while (idx < HOOP_SIZE) { if (IS_READYFORUSE(hoop[idx].basic.id)) { - TOGGLE_HEAPFLAG_READYFORUSE(hoop[idx].basic.id); + TOGGLE_HOOPFLAG_READYFORUSE(hoop[idx].basic.id); hp->last_alloc_idx = idx; hp->last_alloc_list = hoop_list; @@ -854,7 +741,10 @@ VALUE myallocAgent(Heap *hp) { // new last_alloc // -->|......|-->|oooooo|-->|......|-- - +#ifdef VERBOSE_HOOP_EXPANSION + puts("(Agent hoop is expanded)"); +#endif + HoopList *new_hoop_list; new_hoop_list = HoopList_New_forAgent(); @@ -896,7 +786,7 @@ VALUE myallocName(Heap *hp) { while (idx < HOOP_SIZE) { if (IS_READYFORUSE(hoop[idx].basic.id)) { - TOGGLE_HEAPFLAG_READYFORUSE(hoop[idx].basic.id); + TOGGLE_HOOPFLAG_READYFORUSE(hoop[idx].basic.id); hp->last_alloc_idx = idx; //hp->last_alloc_idx = (idx+1) & HOOP_SIZE_MASK; @@ -927,7 +817,11 @@ VALUE myallocName(Heap *hp) { // new current // new last_alloc // -->|......|-->|oooooo|-->|xxxxxx|-- - + +#ifdef VERBOSE_HOOP_EXPANSION + puts("(Name hoop is expanded)"); +#endif + HoopList *new_hoop_list; new_hoop_list = HoopList_New_forName(); @@ -941,12 +835,8 @@ VALUE myallocName(Heap *hp) { } - -} - - - +} @@ -954,58 +844,11 @@ VALUE myallocName(Heap *hp) { static inline void myfree(VALUE ptr) { - SET_HEAPFLAG_READYFORUSE(BASIC(ptr)->id); + SET_HOOPFLAG_READYFORUSE(BASIC(ptr)->id); } -//static inline -VALUE makeAgent(VirtualMachine *vm, int id) { - VALUE ptr; - ptr = myallocAgent(&vm->agentHeap); - -#ifdef COUNT_MKAGENT - NumberOfMkAgent++; -#endif - - AGENT(ptr)->basic.id = id; - return ptr; -} - - - -//static inline -VALUE makeName(VirtualMachine *vm) { - VALUE ptr; - - ptr = myallocName(&vm->nameHeap); - // AGENT(ptr)->basic.id = ID_NAME; - NAME(ptr)->port = (VALUE)NULL; - - return ptr; -} - - - -/********************************** - Counter for Interaction operation -*********************************/ -#ifdef COUNT_INTERACTION -int VM_Get_InteractionCount(VirtualMachine *vm) { - return(vm->count_interaction); -} - -void VM_Clear_InteractionCount(VirtualMachine *vm) { - vm->count_interaction = 0; -} -#endif - - - - - - - @@ -1227,142 +1070,277 @@ void puts_term(VALUE ptr) { } -void puts_name_port0(VALUE ptr) { - - if (ptr == (VALUE)NULL) { - printf(""); +void puts_name_port0(VALUE ptr) { + + if (ptr == (VALUE)NULL) { + printf(""); + + } else if (IS_NAMEID(BASIC(ptr)->id)) { + if (NAME(ptr)->port == (VALUE)NULL) { + printf(""); + } else { + ShowNameHeap=ptr; + puts_term(NAME(ptr)->port); + ShowNameHeap=(VALUE)NULL; + } + } else { + puts("ERROR: it is not a name."); + } + +} + +void puts_names_ast(Ast *ast) { + Ast *param = ast; + + int preserve = PutIndirection; + PutIndirection = 0; + + while (param != NULL) { + char *sym = param->left->sym; + puts_name_port0(NameTable_get_heap(sym)); + param = ast_getTail(param); + if (param != NULL) + printf(" "); + + } + puts(""); + + PutIndirection = preserve; +} + +void puts_name_port0_nat(VALUE a1) { + int result=0; + int idS, idZ; + idS = NameTable_get_set_id("S"); + idZ = NameTable_get_set_id("Z"); + + if (a1 == (VALUE)NULL) { + printf(""); + } else if (!IS_NAMEID(BASIC(a1)->id)) { + printf(""); + } else { + if (NAME(a1)->port == (VALUE)NULL) { + printf(""); + } else { + + a1=NAME(a1)->port; + while (BASIC(a1)->id != idZ) { + if (BASIC(a1)->id == idS) { + result++; + a1=AGENT(a1)->port[0]; + } else if (IS_NAMEID(BASIC(a1)->id)) { + a1=NAME(a1)->port; + } else { + puts("ERROR: puts_name_port0_nat"); + exit(-1); + } + } + printf("%d\n", result); + } + } + +} + + +void puts_eqlist(EQList *at) { + while (at != NULL) { + puts_term(at->eq.l); + printf("~"); + puts_term(at->eq.r); + printf(","); + at=at->next; + } +} + + +// ---------------------------------------- +// Flush + + + + + + +/********************************** + VIRTUAL MACHINE +*********************************/ +#define VM_LOCALVAR_SIZE 200 +#define VM_OFFSET_META_L(a) (a) +#define VM_OFFSET_META_R(a) (MAX_PORT+(a)) +#define VM_OFFSET_ANNOTATE_L (MAX_PORT*2) +#define VM_OFFSET_ANNOTATE_R (MAX_PORT*2+1) +#define VM_OFFSET_LOCALVAR (MAX_PORT*2+2) + + + +typedef struct { + // Heaps for agents and names + Heap agentHeap, nameHeap; + + // EQStack + EQ *eqStack; + int nextPtr_eqStack; + int eqStack_size; + + + // code execution + VALUE reg[VM_LOCALVAR_SIZE+(MAX_PORT*2 + 2)]; + + // flag + // VALUE flag; + + + unsigned int id; +#ifdef COUNT_INTERACTION + unsigned int count_interaction; + +#endif + +} VirtualMachine; + +#ifdef COUNT_INTERACTION +#define COUNTUP_INTERACTION(vm) vm->count_interaction++ +#else +#define COUNTUP_INTERACTION(vm) +#endif + + +#ifndef THREAD +static VirtualMachine VM; +#endif + +#ifdef COUNT_MKAGENT + unsigned int NumberOfMkAgent; + // unsigned int id; +#endif + + +void VM_Buffer_Init(VirtualMachine *vm) { + // Agent Heap + vm->agentHeap.last_alloc_list = HoopList_New_forAgent(); + vm->agentHeap.last_alloc_list->next = vm->agentHeap.last_alloc_list; + vm->agentHeap.last_alloc_idx = 0; + + // Name Heap + vm->nameHeap.last_alloc_list = HoopList_New_forName(); + vm->nameHeap.last_alloc_list->next = vm->nameHeap.last_alloc_list; + vm->nameHeap.last_alloc_idx = 0; +} + + +void VM_EQStack_Init(VirtualMachine *vm, int size) { + vm->nextPtr_eqStack = -1; + vm->eqStack = malloc(sizeof(EQ)*size); + vm->eqStack_size = size; + if (vm->eqStack == NULL) { + printf("Malloc error\n"); + exit(-1); + } +} + + +void VM_EQStack_Push(VirtualMachine *vm, VALUE l, VALUE r) { + + vm->nextPtr_eqStack++; + + if (vm->nextPtr_eqStack >= vm->eqStack_size) { + vm->eqStack_size += vm->eqStack_size; + vm->eqStack = realloc(vm->eqStack, sizeof(EQ)*vm->eqStack_size); + +#ifdef VERBOSE_EQSTACK_EXPANSION + puts("(EQStack is expanded)"); +#endif + + } + vm->eqStack[vm->nextPtr_eqStack].l = l; + vm->eqStack[vm->nextPtr_eqStack].r = r; + +#ifdef DEBUG + //DEBUG + printf(" PUSH:"); + puts_term(l); + puts(""); + puts(" ><"); + printf(" ");puts_term(r); + puts(""); + // printf("VM%d:pushed\n", vm->id); +#endif + + +} + +int VM_EQStack_Pop(VirtualMachine *vm, VALUE *l, VALUE *r) { + if (vm->nextPtr_eqStack >= 0) { + *l = vm->eqStack[vm->nextPtr_eqStack].l; + *r = vm->eqStack[vm->nextPtr_eqStack].r; + vm->nextPtr_eqStack--; + return 1; + } + return 0; +} + + +void VM_Init(VirtualMachine *vm, unsigned int eqStackSize) { + VM_Buffer_Init(vm); + VM_EQStack_Init(vm, eqStackSize); +} + + + + +//static inline +VALUE makeAgent(VirtualMachine *vm, int id) { + VALUE ptr; + ptr = myallocAgent(&vm->agentHeap); + +#ifdef COUNT_MKAGENT + NumberOfMkAgent++; +#endif + + AGENT(ptr)->basic.id = id; + return ptr; +} + + - } else if (IS_NAMEID(BASIC(ptr)->id)) { - if (NAME(ptr)->port == (VALUE)NULL) { - printf(""); - } else { - ShowNameHeap=ptr; - puts_term(NAME(ptr)->port); - ShowNameHeap=(VALUE)NULL; - } - } else { - puts("ERROR: it is not a name."); - } +//static inline +VALUE makeName(VirtualMachine *vm) { + VALUE ptr; + ptr = myallocName(&vm->nameHeap); + // AGENT(ptr)->basic.id = ID_NAME; + NAME(ptr)->port = (VALUE)NULL; + + return ptr; } -void puts_names_ast(Ast *ast) { - Ast *param = ast; - int preserve = PutIndirection; - PutIndirection = 0; - - while (param != NULL) { - char *sym = param->left->sym; - puts_name_port0(NameTable_get_heap(sym)); - param = ast_getTail(param); - if (param != NULL) - printf(" "); - - } - puts(""); - PutIndirection = preserve; +/********************************** + Counter for Interaction operation +*********************************/ +#ifdef COUNT_INTERACTION +int VM_Get_InteractionCount(VirtualMachine *vm) { + return(vm->count_interaction); } -void flush_name_port0(VALUE ptr) { - if (ptr == (VALUE)NULL) { - return; - } +void VM_Clear_InteractionCount(VirtualMachine *vm) { + vm->count_interaction = 0; +} +#endif + - if (IS_FIXNUM(ptr)) { - return; - } - // When the given name nodes (ptr) occurs somewhere also, - // these are not freed. - // JAPANESE: ptr の name nodes が他の場所で出現するなら flush しない。 - VALUE connected_from; - if (keynode_exists_in_another_term(ptr, &connected_from) >= 1) { - printf("Error: '%s' cannot be freed because it is referred to by '%s'.\n", - IdTable_get_name(BASIC(ptr)->id), - IdTable_get_name(BASIC(connected_from)->id)); - - return; - } - - if (NAME(ptr)->port == (VALUE)NULL) { - freeName(ptr); - } else { - ShowNameHeap=ptr; - freeAgentRec(NAME(ptr)->port); - freeName(ptr); - ShowNameHeap=(VALUE)NULL; - } - -#ifdef NODE_USE_VERBOSE -#ifndef THREAD - printf("(%lu agents and %lu names nodes are used.)\n", - Heap_GetNum_Usage_forAgent(&VM.agentHeap), - Heap_GetNum_Usage_forName(&VM.nameHeap)); -#endif -#endif -} -void free_names_ast(Ast *ast) { - Ast *param = ast; - while (param != NULL) { - char *sym = param->left->sym; - VALUE heap = NameTable_get_heap(sym); - flush_name_port0(heap); - param = ast_getTail(param); - } -} -void puts_name_port0_nat(VALUE a1) { - int result=0; - int idS, idZ; - idS = NameTable_get_set_id("S"); - idZ = NameTable_get_set_id("Z"); - - if (a1 == (VALUE)NULL) { - printf(""); - } else if (!IS_NAMEID(BASIC(a1)->id)) { - printf(""); - } else { - if (NAME(a1)->port == (VALUE)NULL) { - printf(""); - } else { - - a1=NAME(a1)->port; - while (BASIC(a1)->id != idZ) { - if (BASIC(a1)->id == idS) { - result++; - a1=AGENT(a1)->port[0]; - } else if (IS_NAMEID(BASIC(a1)->id)) { - a1=NAME(a1)->port; - } else { - puts("ERROR: puts_name_port0_nat"); - exit(-1); - } - } - printf("%d\n", result); - } - } - -} -void puts_eqlist(EQList *at) { - while (at != NULL) { - puts_term(at->eq.l); - printf("~"); - puts_term(at->eq.r); - printf(","); - at=at->next; - } -} /************************************** @@ -1457,6 +1435,59 @@ void freeAgentRec(VALUE ptr) { +void flush_name_port0(VALUE ptr) { + if (ptr == (VALUE)NULL) { + return; + } + + if (IS_FIXNUM(ptr)) { + return; + } + + // When the given name nodes (ptr) occurs somewhere also, + // these are not freed. + // JAPANESE: ptr の name nodes が他の場所で出現するなら flush しない。 + VALUE connected_from; + if (keynode_exists_in_another_term(ptr, &connected_from) >= 1) { + printf("Error: '%s' cannot be freed because it is referred to by '%s'.\n", + IdTable_get_name(BASIC(ptr)->id), + IdTable_get_name(BASIC(connected_from)->id)); + + return; + } + + + if (NAME(ptr)->port == (VALUE)NULL) { + freeName(ptr); + } else { + ShowNameHeap=ptr; + freeAgentRec(NAME(ptr)->port); + freeName(ptr); + ShowNameHeap=(VALUE)NULL; + } + + +#ifdef VERBOSE_NODE_USE +#ifndef THREAD + printf("(%lu agents and %lu names nodes are used.)\n", + Heap_GetNum_Usage_forAgent(&VM.agentHeap), + Heap_GetNum_Usage_forName(&VM.nameHeap)); +#endif +#endif + +} + +void free_names_ast(Ast *ast) { + Ast *param = ast; + + while (param != NULL) { + char *sym = param->left->sym; + VALUE heap = NameTable_get_heap(sym); + flush_name_port0(heap); + param = ast_getTail(param); + } +} + @@ -1469,8 +1500,12 @@ void freeAgentRec(VALUE ptr) { + + + + /************************************* - Exec STACK + Global Exec STACK **************************************/ #ifdef THREAD @@ -1507,67 +1542,22 @@ void GlobalEQStack_Init(int size) { } #endif -void VM_EQStack_Init(VirtualMachine *vm, int size) { - vm->nextPtr_eqStack = -1; - vm->eqStack = malloc(sizeof(EQ)*size); - vm->eqStack_size = size; - if (vm->eqStack == NULL) { - printf("Malloc error\n"); - exit(-1); - } -} - - -void VM_EQStack_Push(VirtualMachine *vm, VALUE l, VALUE r) { - - vm->nextPtr_eqStack++; - - if (vm->nextPtr_eqStack >= vm->eqStack_size) { - printf("Critical ERROR: Overflow of the EQ stack.\n"); - printf("You should have larger size by '-x option'.\n"); - printf("Please see help by using -h option.\n"); - exit(-1); - } - vm->eqStack[vm->nextPtr_eqStack].l = l; - vm->eqStack[vm->nextPtr_eqStack].r = r; - -#ifdef DEBUG - //DEBUG - printf(" PUSH:"); - puts_term(l); - puts(""); - puts(" ><"); - printf(" ");puts_term(r); - puts(""); - // printf("VM%d:pushed\n", vm->id); -#endif - - -} - -int VM_EQStack_Pop(VirtualMachine *vm, VALUE *l, VALUE *r) { - if (vm->nextPtr_eqStack >= 0) { - *l = vm->eqStack[vm->nextPtr_eqStack].l; - *r = vm->eqStack[vm->nextPtr_eqStack].r; - vm->nextPtr_eqStack--; - return 1; - } - return 0; -} - #ifdef THREAD void GlobalEQStack_Push(VALUE l, VALUE r) { - - lock(&GlobalEQS.lock); GlobalEQS.nextPtr++; if (GlobalEQS.nextPtr >= GlobalEQS.size) { - printf("Critical ERROR: Overflow of the global execution stack.\n"); - exit(-1); + GlobalEQS.size += GlobalEQS.size; + GlobalEQS.stack = realloc(GlobalEQS.stack, sizeof(EQ)*GlobalEQS.size); + +#ifdef VERBOSE_EQSTACK_EXPANSION + puts("(Global EQStack is expanded)"); +#endif } + GlobalEQS.stack[GlobalEQS.nextPtr].l = l; GlobalEQS.stack[GlobalEQS.nextPtr].r = r; @@ -1648,7 +1638,7 @@ void VM_EQStack_allputs(VirtualMachine *vm) { /************************************** - BYTECODE + BYTECODE and Compilation **************************************/ // *** The occurrence order must be the same in labels in ExecCode. *** typedef enum { @@ -1704,11 +1694,14 @@ typedef enum { OP_UNM, OP_RAND, - // connect operation for global names in given nets in the interactive mode. + // Connection operation for global names of given nets in the interactive mode. CNCTGN, SUBSTGN, - NOP, + NOP, + + // This will be used for translation from intermediate codes to Bytecodes + VOID_CODE } Code; @@ -4472,6 +4465,7 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { int i, pc=0; VALUE a1; + VALUE *reg = vm->reg; goto *code[0]; @@ -4479,7 +4473,7 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { E_MKNAME: // puts("mkname"); pc++; - vm->reg[(unsigned long)code[pc++]] = makeName(vm); + reg[(unsigned long)code[pc++]] = makeName(vm); goto *code[pc]; E_MKGNAME: @@ -4497,14 +4491,15 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { NameTable_set_heap_id((char *)code[pc+2], a1, i); } - vm->reg[(unsigned long)code[pc+1]] = a1; + reg[(unsigned long)code[pc+1]] = a1; pc +=3; goto *code[pc]; E_MKAGENT0: // puts("mkagent0 reg id"); - vm->reg[(unsigned long)code[pc+1]] = + + reg[(unsigned long)code[pc+1]] = makeAgent(vm, (unsigned long)code[pc+2]);; pc+=3; @@ -4513,21 +4508,21 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { E_MKAGENT1: // puts("mkagent0 reg id"); a1 = makeAgent(vm, (unsigned long)code[pc+2]); - vm->reg[(unsigned long)code[pc+1]] = a1; + reg[(unsigned long)code[pc+1]] = a1; pc+=3; - AGENT(a1)->port[0] = vm->reg[(unsigned long)code[pc++]]; + AGENT(a1)->port[0] = reg[(unsigned long)code[pc++]]; goto *code[pc]; E_MKAGENT2: // puts("mkagent0 reg id"); a1 = makeAgent(vm, (unsigned long)code[pc+2]); - vm->reg[(unsigned long)code[pc+1]] = a1; + reg[(unsigned long)code[pc+1]] = a1; pc+=3; { volatile VALUE *a1port = AGENT(a1)->port; - a1port[0] = vm->reg[(unsigned long)code[pc++]]; - a1port[1] = vm->reg[(unsigned long)code[pc++]]; + a1port[0] = reg[(unsigned long)code[pc++]]; + a1port[1] = reg[(unsigned long)code[pc++]]; } goto *code[pc]; @@ -4535,42 +4530,42 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { E_MKAGENT3: // puts("mkagent0 reg id"); a1 = makeAgent(vm, (unsigned long)code[pc+2]); - vm->reg[(unsigned long)code[pc+1]] = a1; + reg[(unsigned long)code[pc+1]] = a1; pc+=3; { volatile VALUE *a1port = AGENT(a1)->port; - a1port[0] = vm->reg[(unsigned long)code[pc++]]; - a1port[1] = vm->reg[(unsigned long)code[pc++]]; - a1port[2] = vm->reg[(unsigned long)code[pc++]]; + a1port[0] = reg[(unsigned long)code[pc++]]; + a1port[1] = reg[(unsigned long)code[pc++]]; + a1port[2] = reg[(unsigned long)code[pc++]]; } goto *code[pc]; E_MKAGENT4: // puts("mkagent0 reg id"); a1 = makeAgent(vm, (unsigned long)code[pc+2]); - vm->reg[(unsigned long)code[pc+1]] = a1; + reg[(unsigned long)code[pc+1]] = a1; pc+=3; { volatile VALUE *a1port = AGENT(a1)->port; - a1port[0] = vm->reg[(unsigned long)code[pc++]]; - a1port[1] = vm->reg[(unsigned long)code[pc++]]; - a1port[2] = vm->reg[(unsigned long)code[pc++]]; - a1port[3] = vm->reg[(unsigned long)code[pc++]]; + a1port[0] = reg[(unsigned long)code[pc++]]; + a1port[1] = reg[(unsigned long)code[pc++]]; + a1port[2] = reg[(unsigned long)code[pc++]]; + a1port[3] = reg[(unsigned long)code[pc++]]; } goto *code[pc]; E_MKAGENT5: // puts("mkagent0 reg id"); a1 = makeAgent(vm, (unsigned long)code[pc+2]); - vm->reg[(unsigned long)code[pc+1]] = a1; + reg[(unsigned long)code[pc+1]] = a1; pc+=3; { volatile VALUE *a1port = AGENT(a1)->port; - a1port[0] = vm->reg[(unsigned long)code[pc++]]; - a1port[1] = vm->reg[(unsigned long)code[pc++]]; - a1port[2] = vm->reg[(unsigned long)code[pc++]]; - a1port[3] = vm->reg[(unsigned long)code[pc++]]; - a1port[4] = vm->reg[(unsigned long)code[pc++]]; + a1port[0] = reg[(unsigned long)code[pc++]]; + a1port[1] = reg[(unsigned long)code[pc++]]; + a1port[2] = reg[(unsigned long)code[pc++]]; + a1port[3] = reg[(unsigned long)code[pc++]]; + a1port[4] = reg[(unsigned long)code[pc++]]; } goto *code[pc]; @@ -4578,7 +4573,7 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { E_REUSEAGENT0: // puts("reuseagent target id"); - a1 = vm->reg[(unsigned long)code[pc+1]]; + a1 = reg[(unsigned long)code[pc+1]]; AGENT(a1)->basic.id = (unsigned long)code[pc+2]; pc+=3; @@ -4587,9 +4582,9 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { E_REUSEAGENT1: // puts("reuseagent target id"); pc++; - a1 = vm->reg[(unsigned long)code[pc++]]; + a1 = reg[(unsigned long)code[pc++]]; AGENT(a1)->basic.id = (unsigned long)code[pc++]; - AGENT(a1)->port[0] = vm->reg[(unsigned long)code[pc++]]; + AGENT(a1)->port[0] = reg[(unsigned long)code[pc++]]; goto *code[pc]; @@ -4597,12 +4592,12 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { E_REUSEAGENT2: // puts("reuseagent target id"); pc++; - a1 = vm->reg[(unsigned long)code[pc++]]; + a1 = reg[(unsigned long)code[pc++]]; AGENT(a1)->basic.id = (unsigned long)code[pc++]; { volatile VALUE *a1port = AGENT(a1)->port; - a1port[0] = vm->reg[(unsigned long)code[pc++]]; - a1port[1] = vm->reg[(unsigned long)code[pc++]]; + a1port[0] = reg[(unsigned long)code[pc++]]; + a1port[1] = reg[(unsigned long)code[pc++]]; } goto *code[pc]; @@ -4610,42 +4605,42 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { E_REUSEAGENT3: // puts("reuseagent target id"); pc++; - a1 = vm->reg[(unsigned long)code[pc++]]; + a1 = reg[(unsigned long)code[pc++]]; AGENT(a1)->basic.id = (unsigned long)code[pc++]; { volatile VALUE *a1port = AGENT(a1)->port; - a1port[0] = vm->reg[(unsigned long)code[pc++]]; - a1port[1] = vm->reg[(unsigned long)code[pc++]]; - a1port[2] = vm->reg[(unsigned long)code[pc++]]; + a1port[0] = reg[(unsigned long)code[pc++]]; + a1port[1] = reg[(unsigned long)code[pc++]]; + a1port[2] = reg[(unsigned long)code[pc++]]; } goto *code[pc]; E_REUSEAGENT4: // puts("reuseagent target id"); pc++; - a1 = vm->reg[(unsigned long)code[pc++]]; + a1 = reg[(unsigned long)code[pc++]]; AGENT(a1)->basic.id = (unsigned long)code[pc++]; { volatile VALUE *a1port = AGENT(a1)->port; - a1port[0] = vm->reg[(unsigned long)code[pc++]]; - a1port[1] = vm->reg[(unsigned long)code[pc++]]; - a1port[2] = vm->reg[(unsigned long)code[pc++]]; - a1port[3] = vm->reg[(unsigned long)code[pc++]]; + a1port[0] = reg[(unsigned long)code[pc++]]; + a1port[1] = reg[(unsigned long)code[pc++]]; + a1port[2] = reg[(unsigned long)code[pc++]]; + a1port[3] = reg[(unsigned long)code[pc++]]; } goto *code[pc]; E_REUSEAGENT5: // puts("reuseagent target id"); pc++; - a1 = vm->reg[(unsigned long)code[pc++]]; + a1 = reg[(unsigned long)code[pc++]]; AGENT(a1)->basic.id = (unsigned long)code[pc++]; { volatile VALUE *a1port = AGENT(a1)->port; - a1port[0] = vm->reg[(unsigned long)code[pc++]]; - a1port[1] = vm->reg[(unsigned long)code[pc++]]; - a1port[2] = vm->reg[(unsigned long)code[pc++]]; - a1port[3] = vm->reg[(unsigned long)code[pc++]]; - a1port[4] = vm->reg[(unsigned long)code[pc++]]; + a1port[0] = reg[(unsigned long)code[pc++]]; + a1port[1] = reg[(unsigned long)code[pc++]]; + a1port[2] = reg[(unsigned long)code[pc++]]; + a1port[3] = reg[(unsigned long)code[pc++]]; + a1port[4] = reg[(unsigned long)code[pc++]]; } goto *code[pc]; @@ -4712,14 +4707,14 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { E_PUSH: // puts("push"); - PUSH(vm, vm->reg[(unsigned long)code[pc+1]], vm->reg[(unsigned long)code[pc+2]]); + PUSH(vm, reg[(unsigned long)code[pc+1]], reg[(unsigned long)code[pc+2]]); pc +=3; goto *code[pc]; E_PUSHI: // puts("pushi reg int"); - PUSH(vm, vm->reg[(unsigned long)code[pc+1]], (unsigned long)code[pc+2]); + PUSH(vm, reg[(unsigned long)code[pc+1]], (unsigned long)code[pc+2]); pc +=3; goto *code[pc]; @@ -4758,8 +4753,8 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { E_MYPUSH: // puts("mypush"); - // VM_EQStack_Push(vm, vm->reg[(unsigned long)code[pc+1]], vm->reg[(unsigned long)code[pc+2]]); - MYPUSH(vm, vm->reg[(unsigned long)code[pc+1]], vm->reg[(unsigned long)code[pc+2]]); + // VM_EQStack_Push(vm, reg[(unsigned long)code[pc+1]], reg[(unsigned long)code[pc+2]]); + MYPUSH(vm, reg[(unsigned long)code[pc+1]], reg[(unsigned long)code[pc+2]]); pc +=3; goto *code[pc]; @@ -4767,9 +4762,8 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { E_LOADI: // puts("loadi reg num"); - //a1 = makeVal_int(vm, (unsigned long)code[pc+3]); a1 = INT2FIX((long)code[pc+2]); - vm->reg[(unsigned long)code[pc+1]] = a1; + reg[(unsigned long)code[pc+1]] = a1; pc +=3; goto *code[pc]; @@ -4782,8 +4776,8 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { E_RET_FREE_LR: // puts("ret"); - freeAgent(vm->reg[VM_OFFSET_ANNOTATE_L]); - freeAgent(vm->reg[VM_OFFSET_ANNOTATE_R]); + freeAgent(reg[VM_OFFSET_ANNOTATE_L]); + freeAgent(reg[VM_OFFSET_ANNOTATE_R]); // // freeAgent(vm->L); @@ -4792,13 +4786,13 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { E_RET_FREE_L: // puts("ret"); - freeAgent(vm->reg[VM_OFFSET_ANNOTATE_L]); + freeAgent(reg[VM_OFFSET_ANNOTATE_L]); // freeAgent(vm->L); return NULL; E_RET_FREE_R: // puts("ret"); - freeAgent(vm->reg[VM_OFFSET_ANNOTATE_R]); + freeAgent(reg[VM_OFFSET_ANNOTATE_R]); // freeAgent(vm->R); return NULL; @@ -4811,14 +4805,14 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { E_LOOP_RREC: // puts("looprrec reg ar"); - freeAgent(vm->reg[VM_OFFSET_ANNOTATE_R]); + freeAgent(reg[VM_OFFSET_ANNOTATE_R]); - a1 = vm->reg[(unsigned long)code[pc+1]]; + a1 = reg[(unsigned long)code[pc+1]]; for (int i=0; i<(unsigned long)code[pc+2]; i++) { - vm->reg[VM_OFFSET_META_R(i)] = AGENT(a1)->port[i]; + reg[VM_OFFSET_META_R(i)] = AGENT(a1)->port[i]; } - vm->reg[VM_OFFSET_ANNOTATE_R] = a1; + reg[VM_OFFSET_ANNOTATE_R] = a1; pc = 0; goto *code[0]; @@ -4826,13 +4820,13 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { E_LOOP_RREC1: // puts("looprrec reg ar"); - freeAgent(vm->reg[VM_OFFSET_ANNOTATE_R]); + freeAgent(reg[VM_OFFSET_ANNOTATE_R]); - a1 = vm->reg[(unsigned long)code[pc+1]]; + a1 = reg[(unsigned long)code[pc+1]]; - vm->reg[VM_OFFSET_META_R(0)] = AGENT(a1)->port[0]; + reg[VM_OFFSET_META_R(0)] = AGENT(a1)->port[0]; - vm->reg[VM_OFFSET_ANNOTATE_R] = a1; + reg[VM_OFFSET_ANNOTATE_R] = a1; pc = 0; goto *code[0]; @@ -4840,14 +4834,14 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { E_LOOP_RREC2: // puts("looprrec reg ar"); - freeAgent(vm->reg[VM_OFFSET_ANNOTATE_R]); + freeAgent(reg[VM_OFFSET_ANNOTATE_R]); - a1 = vm->reg[(unsigned long)code[pc+1]]; + a1 = reg[(unsigned long)code[pc+1]]; - vm->reg[VM_OFFSET_META_R(0)] = AGENT(a1)->port[0]; - vm->reg[VM_OFFSET_META_R(1)] = AGENT(a1)->port[1]; + reg[VM_OFFSET_META_R(0)] = AGENT(a1)->port[0]; + reg[VM_OFFSET_META_R(1)] = AGENT(a1)->port[1]; - vm->reg[VM_OFFSET_ANNOTATE_R] = a1; + reg[VM_OFFSET_ANNOTATE_R] = a1; pc = 0; goto *code[0]; @@ -4859,38 +4853,38 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { E_LOAD: // puts("load reg reg"); //a1 = makeVal_int(vm, (unsigned long)code[pc+3]); - vm->reg[(unsigned long)code[pc+1]] = - vm->reg[(unsigned long)code[pc+2]]; + reg[(unsigned long)code[pc+1]] = + reg[(unsigned long)code[pc+2]]; pc +=3; goto *code[pc]; E_LOADP: // puts("loadp reg reg port"); - vm->reg[(unsigned long)code[pc+1]] = - AGENT(vm->reg[(unsigned long)code[pc+2]])->port[vm->reg[(unsigned long)code[pc+3]]]; + reg[(unsigned long)code[pc+1]] = + AGENT(reg[(unsigned long)code[pc+2]])->port[reg[(unsigned long)code[pc+3]]]; pc +=4; goto *code[pc]; E_ADD: // puts("ADD reg reg reg"); - vm->reg[(unsigned long)code[pc+1]] = - INT2FIX(FIX2INT(vm->reg[(unsigned long)code[pc+2]])+FIX2INT(vm->reg[(unsigned long)code[pc+3]])); + reg[(unsigned long)code[pc+1]] = + INT2FIX(FIX2INT(reg[(unsigned long)code[pc+2]])+FIX2INT(reg[(unsigned long)code[pc+3]])); pc +=4; goto *code[pc]; E_SUB: // puts("SUB reg reg reg"); - vm->reg[(unsigned long)code[pc+1]] = - INT2FIX(FIX2INT(vm->reg[(unsigned long)code[pc+2]])- - FIX2INT(vm->reg[(unsigned long)code[pc+3]])); + reg[(unsigned long)code[pc+1]] = + INT2FIX(FIX2INT(reg[(unsigned long)code[pc+2]])- + FIX2INT(reg[(unsigned long)code[pc+3]])); pc +=4; goto *code[pc]; E_SUBI: //puts("SUBI reg reg int");exit(1); - vm->reg[(unsigned long)code[pc+1]] = - INT2FIX(FIX2INT(vm->reg[(unsigned long)code[pc+2]])- + reg[(unsigned long)code[pc+1]] = + INT2FIX(FIX2INT(reg[(unsigned long)code[pc+2]])- (unsigned long)code[pc+3]); pc +=4; goto *code[pc]; @@ -4898,57 +4892,57 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { E_MUL: // puts("SUB reg reg reg"); - vm->reg[(unsigned long)code[pc+1]] = - INT2FIX(FIX2INT(vm->reg[(unsigned long)code[pc+2]])* - FIX2INT(vm->reg[(unsigned long)code[pc+3]])); + reg[(unsigned long)code[pc+1]] = + INT2FIX(FIX2INT(reg[(unsigned long)code[pc+2]])* + FIX2INT(reg[(unsigned long)code[pc+3]])); pc +=4; goto *code[pc]; E_DIV: // puts("SUB reg reg reg"); - vm->reg[(unsigned long)code[pc+1]] = - INT2FIX(FIX2INT(vm->reg[(unsigned long)code[pc+2]])/ - FIX2INT(vm->reg[(unsigned long)code[pc+3]])); + reg[(unsigned long)code[pc+1]] = + INT2FIX(FIX2INT(reg[(unsigned long)code[pc+2]])/ + FIX2INT(reg[(unsigned long)code[pc+3]])); pc +=4; goto *code[pc]; E_MOD: // puts("SUB reg reg reg"); - vm->reg[(unsigned long)code[pc+1]] = - INT2FIX(FIX2INT(vm->reg[(unsigned long)code[pc+2]])% - FIX2INT(vm->reg[(unsigned long)code[pc+3]])); + reg[(unsigned long)code[pc+1]] = + INT2FIX(FIX2INT(reg[(unsigned long)code[pc+2]])% + FIX2INT(reg[(unsigned long)code[pc+3]])); pc +=4; goto *code[pc]; E_LT: // puts("SUB reg reg reg"); - if (FIX2INT(vm->reg[(unsigned long)code[pc+2]]) < - FIX2INT(vm->reg[(unsigned long)code[pc+3]])) { - vm->reg[(unsigned long)code[pc+1]] = INT2FIX(1); + if (FIX2INT(reg[(unsigned long)code[pc+2]]) < + FIX2INT(reg[(unsigned long)code[pc+3]])) { + reg[(unsigned long)code[pc+1]] = INT2FIX(1); } else { - vm->reg[(unsigned long)code[pc+1]] = INT2FIX(0); + reg[(unsigned long)code[pc+1]] = INT2FIX(0); } pc +=4; goto *code[pc]; E_LE: // puts("SUB reg reg reg"); - if (FIX2INT(vm->reg[(unsigned long)code[pc+2]]) <= - FIX2INT(vm->reg[(unsigned long)code[pc+3]])) { - vm->reg[(unsigned long)code[pc+1]] = INT2FIX(1); + if (FIX2INT(reg[(unsigned long)code[pc+2]]) <= + FIX2INT(reg[(unsigned long)code[pc+3]])) { + reg[(unsigned long)code[pc+1]] = INT2FIX(1); } else { - vm->reg[(unsigned long)code[pc+1]] = INT2FIX(0); + reg[(unsigned long)code[pc+1]] = INT2FIX(0); } pc +=4; goto *code[pc]; E_EQ: // puts("SUB reg reg reg"); - if (vm->reg[(unsigned long)code[pc+2]] == - vm->reg[(unsigned long)code[pc+3]]) { - vm->reg[(unsigned long)code[pc+1]] = INT2FIX(1); + if (reg[(unsigned long)code[pc+2]] == + reg[(unsigned long)code[pc+3]]) { + reg[(unsigned long)code[pc+1]] = INT2FIX(1); } else { - vm->reg[(unsigned long)code[pc+1]] = INT2FIX(0); + reg[(unsigned long)code[pc+1]] = INT2FIX(0); } pc +=4; goto *code[pc]; @@ -4956,11 +4950,11 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { E_EQI: // puts("SUB reg reg int"); - if (FIX2INT(vm->reg[(unsigned long)code[pc+2]]) == + if (FIX2INT(reg[(unsigned long)code[pc+2]]) == (unsigned long)code[pc+3]) { - vm->reg[(unsigned long)code[pc+1]] = INT2FIX(1); + reg[(unsigned long)code[pc+1]] = INT2FIX(1); } else { - vm->reg[(unsigned long)code[pc+1]] = INT2FIX(0); + reg[(unsigned long)code[pc+1]] = INT2FIX(0); } pc +=4; @@ -4970,11 +4964,11 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { E_NE: // puts("SUB reg reg reg"); - if (vm->reg[(unsigned long)code[pc+2]] != - vm->reg[(unsigned long)code[pc+3]]) { - vm->reg[(unsigned long)code[pc+1]] = INT2FIX(1); + if (reg[(unsigned long)code[pc+2]] != + reg[(unsigned long)code[pc+3]]) { + reg[(unsigned long)code[pc+1]] = INT2FIX(1); } else { - vm->reg[(unsigned long)code[pc+1]] = INT2FIX(0); + reg[(unsigned long)code[pc+1]] = INT2FIX(0); } pc +=4; goto *code[pc]; @@ -4982,7 +4976,7 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { E_JMPEQ0: // puts("JMPEQ0 reg pc"); // pc is a relative address, not absolute one! - if (!FIX2INT(vm->reg[(unsigned long)code[pc+1]])) { + if (!FIX2INT(reg[(unsigned long)code[pc+1]])) { pc += (unsigned long)code[pc+2]; } pc +=3; @@ -4995,7 +4989,7 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { Count_cnct++; #endif - a1 = vm->reg[(unsigned long)code[pc+1]]; + a1 = reg[(unsigned long)code[pc+1]]; if (IS_FIXNUM(a1)) { pc +=3; goto *code[pc]; @@ -5014,7 +5008,7 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { VALUE a2 = NAME(a1)->port; freeName(a1); a1 = a2; - vm->reg[(unsigned long)code[pc+1]] = a2; + reg[(unsigned long)code[pc+1]] = a2; } if (BASIC(a1)->id == ID_CONS) { @@ -5037,7 +5031,7 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { Count_cnct++; #endif - a1 = vm->reg[(unsigned long)code[pc+1]]; + a1 = reg[(unsigned long)code[pc+1]]; if (IS_FIXNUM(a1)) { pc +=4; goto *code[pc]; @@ -5056,7 +5050,7 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { VALUE a2 = NAME(a1)->port; freeName(a1); a1 = a2; - vm->reg[(unsigned long)code[pc+1]] = a2; + reg[(unsigned long)code[pc+1]] = a2; } if (BASIC(a1)->id == (unsigned long)code[pc+2]) { @@ -5075,7 +5069,7 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { E_JMP: // puts("JMP pc"); - pc += vm->reg[(unsigned long)code[pc+1]]; + pc += reg[(unsigned long)code[pc+1]]; pc +=2; goto *code[pc]; @@ -5083,15 +5077,15 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { E_UNM: // puts("UNM reg reg"); - vm->reg[(unsigned long)code[pc+1]] = - INT2FIX(-1 * FIX2INT(vm->reg[(unsigned long)code[pc+2]])); + reg[(unsigned long)code[pc+1]] = + INT2FIX(-1 * FIX2INT(reg[(unsigned long)code[pc+2]])); pc +=3; goto *code[pc]; E_RAND: // puts("RAND reg reg"); - vm->reg[(unsigned long)code[pc+1]] = - INT2FIX(rand()%FIX2INT(vm->reg[(unsigned long)code[pc+2]])); + reg[(unsigned long)code[pc+1]] = + INT2FIX(rand()%FIX2INT(reg[(unsigned long)code[pc+2]])); pc +=3; goto *code[pc]; @@ -5100,10 +5094,10 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { // puts("CNCTGN reg reg"); // "x"~s, "x"->t ==> push(s,t), free("x") where "x" is a global name. { - VALUE x = vm->reg[(unsigned long)code[pc+1]]; + VALUE x = reg[(unsigned long)code[pc+1]]; a1 = NAME(x)->port; freeName(x); - PUSH(vm, vm->reg[(unsigned long)code[pc+2]], a1); + PUSH(vm, reg[(unsigned long)code[pc+2]], a1); } pc +=3; goto *code[pc]; @@ -5114,8 +5108,8 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { // puts("SUBSTGN reg reg"); // "x"~s, t->u("x") ==> t->u(s), free("x") where "x" is a global name. { - VALUE x = vm->reg[(unsigned long)code[pc+1]]; - global_replace_keynode_in_another_term(x,vm->reg[(unsigned long)code[pc+2]]); + VALUE x = reg[(unsigned long)code[pc+1]]; + global_replace_keynode_in_another_term(x,reg[(unsigned long)code[pc+2]]); freeName(x); } pc +=3; @@ -5228,7 +5222,7 @@ void sweep_AgentHeap(Heap *hp) { for (int i = 0; i < HOOP_SIZE; i++) { if (!IS_FLAG_MARKED(hoop[i].basic.id)) { - SET_HEAPFLAG_READYFORUSE(hoop[i].basic.id); + SET_HOOPFLAG_READYFORUSE(hoop[i].basic.id); } else { TOGGLE_FLAG_MARKED(hoop[i].basic.id); } @@ -5247,7 +5241,7 @@ void sweep_NameHeap(Heap *hp) { for (int i = 0; i < HOOP_SIZE; i++) { if (!IS_FLAG_MARKED(hoop[i].basic.id)) { - SET_HEAPFLAG_READYFORUSE(hoop[i].basic.id); + SET_HOOPFLAG_READYFORUSE(hoop[i].basic.id); } else { TOGGLE_FLAG_MARKED(hoop[i].basic.id); } @@ -6013,11 +6007,6 @@ loop_a2IsAgent: -void VM_Init(VirtualMachine *vm, unsigned int eqStackSize) { - VM_Buffer_Init(vm); - VM_EQStack_Init(vm, eqStackSize); -} - @@ -6245,7 +6234,7 @@ int exec(Ast *at) { #endif -#ifdef NODE_USE_VERBOSE +#ifdef VERBOSE_NODE_USE printf("(%lu agents and %lu names nodes are used.)\n", Heap_GetNum_Usage_forAgent(&VM.agentHeap), Heap_GetNum_Usage_forName(&VM.nameHeap)); @@ -6552,8 +6541,8 @@ int main(int argc, char *argv[]) int i, param; char *fname = NULL; - //int max_EQStack=10000; - int max_EQStack=1 << 13; + // int max_EQStack=1<<12; // 512 + int max_EQStack=1<<8; // 512 #ifndef THREAD @@ -6577,19 +6566,19 @@ int main(int argc, char *argv[]) printf("Inpla version %s\n", VERSION); puts("Usage: inpla [options]\n"); puts("Options:"); - printf(" -f Set input file name (Defalut: STDIN)\n"); + printf(" -f Set input file name (Defalut: STDIN)\n"); - printf(" -x Set the size of the EQ stack (Default: %8u)\n", + printf(" -x Set the unit size of the EQ stack (Default: %8u)\n", max_EQStack); // Extended Options for threads or non-threads #ifdef THREAD - printf(" -t Set the number of threads (Default: %8d)\n", + printf(" -t Set the number of threads (Default: %8d)\n", MaxThreadsNum); #else - printf(" -w Enable Weak Reduction strategy (Default: false)\n" + printf(" -w Enable Weak Reduction strategy (Default: false)\n" ); @@ -6753,8 +6742,7 @@ int main(int argc, char *argv[]) RuleTable_init(); #ifdef THREAD - // GlobalEQStack_Init(max_EQStack); - GlobalEQStack_Init(MaxThreadsNum*1024); + GlobalEQStack_Init(MaxThreadsNum*8); #endif diff --git a/src/mytype.h b/src/mytype.h index 7e55a20..ab72df0 100644 --- a/src/mytype.h +++ b/src/mytype.h @@ -36,6 +36,20 @@ typedef struct { #endif + +// Equation +typedef struct EQ_tag { + VALUE l, r; +} EQ; + +typedef struct EQList_tag { + EQ eq; + struct EQList_tag *next; +} EQList; + + + + #define FIXNUM_FLAG 0x01 #define INT2FIX(i) ((VALUE)(((long)(i) << 1) | FIXNUM_FLAG)) #define FIX2INT(i) ((int)(i) >> 1) diff --git a/src/name_table.c b/src/name_table.c index 3cbaee3..b6ed9a1 100644 --- a/src/name_table.c +++ b/src/name_table.c @@ -4,6 +4,7 @@ #include "name_table.h" +static NameList *NameHashTable[NAME_HASHSIZE]; // HashTable for name strings /* NameTable[] <-- hashtable diff --git a/src/name_table.h b/src/name_table.h index 1ba31a5..4bc1361 100644 --- a/src/name_table.h +++ b/src/name_table.h @@ -26,7 +26,7 @@ typedef struct NameList { } NameList; #define NAME_HASHSIZE 127 -static NameList *NameHashTable[NAME_HASHSIZE]; // HashTable for name strings +//static NameList *NameHashTable[NAME_HASHSIZE]; // HashTable for name strings // It should be called at first, and never called after that. void NameTable_init(); -- cgit v1.2.3