aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ast.c4
-rw-r--r--src/ast.h2
-rw-r--r--src/inpla.y1439
-rw-r--r--src/lex.l7
4 files changed, 1014 insertions, 438 deletions
diff --git a/src/ast.c b/src/ast.c
index a0ca2da..7ce917c 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -265,7 +265,9 @@ void ast_puts(Ast *p) {
// extension
"TUPLE", "PPAIR",
"INT", "LD", "ADD", "SUB", "MUL", "DIV", "MOD",
- "LT", "LE", "EQ", "NE", "UNM",
+ "LT", "LE", "EQ", "NE", "UNM", "AND", "OR", "NOT",
+
+
"CONS", "NIL", "OPCONS",
"RAND", "SRAND",
diff --git a/src/ast.h b/src/ast.h
index d116c0b..9dab583 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -18,7 +18,7 @@ typedef enum {
// operation
AST_INT, AST_LD, AST_PLUS, AST_SUB, AST_MUL, AST_DIV, AST_MOD,
- AST_LT, AST_LE, AST_EQ, AST_NE, AST_UNM,
+ AST_LT, AST_LE, AST_EQ, AST_NE, AST_UNM, AST_AND, AST_OR, AST_NOT,
// for built-in lists
AST_CONS, AST_NIL, AST_OPCONS,
diff --git a/src/inpla.y b/src/inpla.y
index 90b7278..5303bdd 100644
--- a/src/inpla.y
+++ b/src/inpla.y
@@ -20,6 +20,8 @@
// Configuration ---------------------------------------------------
#define COUNT_INTERACTION // Count interaction.
#define EXPANDABLE_HEAP // Expandable heaps for agents and names
+#define OPTIMISE_IMCODE // Optimise the intermediate codes
+
//#define VERBOSE_NODE_USE // Put memory usage of agents and names.
//#define VERBOSE_HOOP_EXPANSION // Put messages when hoops are expanded.
@@ -35,8 +37,8 @@
//#define COUNT_MKAGENT // count of execution fo mkagent
-#define VERSION "0.6.2"
-#define BUILT_DATE "20 Jan. 2022"
+#define VERSION "0.7.0"
+#define BUILT_DATE "30 Jan. 2022"
// ------------------------------------------------------------------
@@ -157,7 +159,8 @@ static char *Errormsg = NULL;
%token ANNOTATE_L ANNOTATE_R
-%token PIPE AMP LD EQUAL NE GT GE LT LE
+%token PIPE
+%token NOT AND OR LD EQUAL NE GT GE LT LE
%token ADD SUB MUL DIV MOD INT LET IN END IF THEN ELSE ANY WHERE RAND DEF
%token INTERFACE IFCE PRNAT FREE EXIT
%token END_OF_FILE USE
@@ -168,7 +171,7 @@ rule
ap aplist
stm stmlist_nondelimiter
stmlist
-expr additive_expr equational_expr relational_expr unary_expr
+expr additive_expr equational_expr logical_expr relational_expr unary_expr
multiplicative_expr primary_expr agent_tuple agent_list agent_cons
bodyguard bd_else bd_elif bd_compound
if_sentence if_compound
@@ -483,9 +486,16 @@ expr
;
equational_expr
+: logical_expr
+| equational_expr EQUAL logical_expr { $$ = ast_makeAST(AST_EQ, $1, $3); }
+| equational_expr NE logical_expr { $$ = ast_makeAST(AST_NE, $1, $3); }
+
+logical_expr
: relational_expr
-| equational_expr EQUAL relational_expr { $$ = ast_makeAST(AST_EQ, $1, $3); }
-| equational_expr NE relational_expr { $$ = ast_makeAST(AST_NE, $1, $3); }
+| NOT relational_expr { $$ = ast_makeAST(AST_NOT, $2, NULL); }
+| logical_expr AND relational_expr { $$ = ast_makeAST(AST_AND, $1, $3); }
+| logical_expr OR relational_expr { $$ = ast_makeAST(AST_OR, $1, $3); }
+;
relational_expr
: additive_expr
@@ -1335,13 +1345,21 @@ void puts_eqlist(EQList *at) {
/**********************************
VIRTUAL MACHINE
*********************************/
-#define VM_LOCALVAR_SIZE 200
+#define VM_REG_SIZE 128
+
+/*
#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)
+*/
+#define VM_OFFSET_META_L(a) (a+1)
+#define VM_OFFSET_META_R(a) (MAX_PORT+1+(a))
+#define VM_OFFSET_ANNOTATE_L (MAX_PORT*2+1)
+#define VM_OFFSET_ANNOTATE_R (MAX_PORT*2+2)
+#define VM_OFFSET_LOCALVAR (MAX_PORT*2+2+1)
typedef struct {
@@ -1353,20 +1371,21 @@ typedef struct {
int nextPtr_eqStack;
int eqStack_size;
+#ifdef COUNT_INTERACTION
+ unsigned int count_interaction;
+#endif
- // code execution
- VALUE reg[VM_LOCALVAR_SIZE+(MAX_PORT*2 + 2)];
- // flag
- // VALUE flag;
+ // register
+ // VALUE reg[VM_REG_SIZE+(MAX_PORT*2 + 2)];
+ // VALUE reg[VM_REG_SIZE];
+ VALUE *reg;
-
+
+#ifdef THREAD
unsigned int id;
-#ifdef COUNT_INTERACTION
- unsigned int count_interaction;
-
#endif
-
+
} VirtualMachine;
#ifdef COUNT_INTERACTION
@@ -1397,6 +1416,8 @@ void VM_Buffer_Init(VirtualMachine *vm) {
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;
+
+ vm->reg = malloc(sizeof(VALUE) * VM_REG_SIZE);
}
#else
@@ -1414,6 +1435,7 @@ void VM_InitBuffer(VirtualMachine *vm, int size) {
//vm->nameHeap.lastAlloc = 0;
vm->nameHeap.size = size;
+ vm->reg = malloc(sizeof(VALUE) * VM_REG_SIZE);
}
#endif
@@ -1885,15 +1907,28 @@ typedef enum {
OP_MUL,
OP_DIV,
OP_MOD,
+
OP_LT,
OP_LE,
OP_EQ,
OP_EQI,
OP_NE,
+
+ OP_LT_R0,
+ OP_LE_R0,
+ OP_EQ_R0,
+ OP_EQI_R0,
+ OP_NE_R0,
+
+
OP_JMPEQ0,
+ OP_JMPEQ0_R0,
+ OP_JMP,
+ OP_JMPNEQ0,
+
OP_JMPCNCT_CONS,
OP_JMPCNCT,
- OP_JMP,
+
OP_UNM,
OP_RAND,
@@ -1904,7 +1939,8 @@ typedef enum {
NOP,
// This will be used for translation from intermediate codes to Bytecodes
- VOID_CODE
+ LABEL,
+ DEAD_CODE
} Code;
@@ -1912,6 +1948,22 @@ typedef enum {
static void* CodeAddr[NOP+1];
+//void *ExecCode(int arg, VirtualMachine *vm, void **code);
+void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code);
+
+void CodeAddr_init(void) {
+ // Set CodeAddr
+ void **table;
+ table = ExecCode(0, NULL, NULL);
+ for (int i=0; i<NOP; i++) {
+ CodeAddr[i] = table[i];
+ }
+}
+
+
+
+
+
typedef enum {
NB_NAME=0,
NB_META,
@@ -2026,7 +2078,7 @@ 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.
+ int vmRegSize; // the array size of the Regs.
// For rule agents
@@ -2035,6 +2087,9 @@ typedef struct {
// ruleAgentL, ruleAgentR
int annotateL, annotateR; // `Annotation properties' such as (*L) (*R) (int)
+
+ // labels
+ int label;
} CmEnvironment;
// The annotation properties
@@ -2045,25 +2100,6 @@ typedef struct {
static CmEnvironment CmEnv;
-//void *ExecCode(int arg, VirtualMachine *vm, void **code);
-void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code);
-
-
-void CmEnv_clear_all(void);
-
-
-void CmEnv_Init(int vm_heapsize) {
- CmEnv.vmStackSize = vm_heapsize;
-
- void **table;
- table = ExecCode(0, NULL, NULL);
- for (int i=0; i<NOP; i++) {
- CodeAddr[i] = table[i];
- }
-
- CmEnv_clear_all();
-}
-
static inline
void CmEnv_clear_localnamePtr(void) {
@@ -2103,6 +2139,9 @@ void CmEnv_clear_all(void)
// reset the index of storage for imtermediate codes.
IMCode_Init();
+
+ // reset the index of labels;
+ CmEnv.label = 0;
}
void CmEnv_clear_keeping_rule_properties(void)
@@ -2121,11 +2160,16 @@ void CmEnv_clear_keeping_rule_properties(void)
// reset the beginning number for local vars.
CmEnv_clear_localnamePtr();
+ /*
// reset the index of storage for imtermediate codes.
IMCode_Init();
+ */
}
+int CmEnv_get_newlabel(void) {
+ return CmEnv.label++;
+}
int CmEnv_set_symbol_as_name(char *name) {
@@ -2147,8 +2191,8 @@ int CmEnv_set_symbol_as_name(char *name) {
result = CmEnv.localNamePtr;
CmEnv.localNamePtr++;
- if (CmEnv.localNamePtr > CmEnv.vmStackSize) {
- puts("SYSTEM ERROR: CmEnv.localNamePtr exceeded CmEnv.vmStackSize.");
+ if (CmEnv.localNamePtr > VM_REG_SIZE) {
+ puts("SYSTEM ERROR: CmEnv.localNamePtr exceeded VM_REG_SIZE.");
exit(-1);
}
@@ -2195,8 +2239,8 @@ int CmEnv_set_as_INTVAR(char *name) {
}
CmEnv.localNamePtr++;
- if (CmEnv.localNamePtr > CmEnv.vmStackSize) {
- puts("SYSTEM ERROR: CmEnv.localNamePtr exceeded CmEnv.vmStackSize.");
+ if (CmEnv.localNamePtr > VM_REG_SIZE) {
+ puts("SYSTEM ERROR: CmEnv.localNamePtr exceeded VM_REG_SIZE.");
exit(-1);
}
@@ -2237,8 +2281,8 @@ int CmEnv_newreg(void) {
int result;
result = CmEnv.localNamePtr;
CmEnv.localNamePtr++;
- if (CmEnv.localNamePtr > CmEnv.vmStackSize) {
- puts("SYSTEM ERROR: CmEnv.localNamePtr exceeded CmEnv.vmStackSize.");
+ if (CmEnv.localNamePtr > VM_REG_SIZE) {
+ puts("SYSTEM ERROR: CmEnv.localNamePtr exceeded VM_REG_SIZE.");
exit(-1);
}
@@ -2307,47 +2351,209 @@ void CmEnv_Retrieve_GNAME(void) {
}
-int CmEnv_Generate_VMCode(void **code, int offset) {
- int ptr = offset;
+int CmEnv_Optimise_VMCode_CopyPropagation(int target_imcode_addr) {
+
struct IMCode_tag *imcode;
+ int load_from, load_to;
+ load_from = IMCode[target_imcode_addr].operand2;
+ load_to = IMCode[target_imcode_addr].operand1;
- for (int i=0; i<IMCode_n; i++) {
+ for (int i=target_imcode_addr+1; i<IMCode_n; i++) {
imcode = &IMCode[i];
switch (imcode->opcode) {
case MKNAME:
+ case MKGNAME:
+ break;
+
+ case MKAGENT5:
+ case REUSEAGENT5:
+ if (imcode->operand7 == load_to) {
+ imcode->operand7 = load_from;
+ IMCode[target_imcode_addr].opcode = DEAD_CODE;
+ return 1;
+ }
+ case MKAGENT4:
+ case REUSEAGENT4:
+ if (imcode->operand6 == load_to) {
+ imcode->operand6 = load_from;
+ IMCode[target_imcode_addr].opcode = DEAD_CODE;
+ return 1;
+ }
+ case MKAGENT3:
+ case REUSEAGENT3:
+ if (imcode->operand5 == load_to) {
+ imcode->operand5 = load_from;
+ IMCode[target_imcode_addr].opcode = DEAD_CODE;
+ return 1;
+ }
+ case MKAGENT2:
+ case REUSEAGENT2:
+ if (imcode->operand4 == load_to) {
+ imcode->operand4 = load_from;
+ IMCode[target_imcode_addr].opcode = DEAD_CODE;
+ return 1;
+ }
+ case MKAGENT1:
+ case REUSEAGENT1:
+ if (imcode->operand3 == load_to) {
+ imcode->operand3 = load_from;
+ IMCode[target_imcode_addr].opcode = DEAD_CODE;
+ return 1;
+ }
+ case MKAGENT0:
+ case REUSEAGENT0:
+ break;
+
+
+ case PUSH:
+ case MYPUSH:
+ if (imcode->operand1 == load_to) {
+ imcode->operand1 = load_from;
+ IMCode[target_imcode_addr].opcode = DEAD_CODE;
+ return 1;
+ }
+ if (imcode->operand2 == load_to) {
+ imcode->operand2 = load_from;
+ IMCode[target_imcode_addr].opcode = DEAD_CODE;
+ return 1;
+ }
+ break;
+
+ case OP_JMPEQ0:
+ case OP_JMPNEQ0:
+ case OP_JMPCNCT_CONS:
+ case OP_JMPCNCT:
+ case PUSHI:
+ if (imcode->operand1 == load_to) {
+ imcode->operand1 = load_from;
+ IMCode[target_imcode_addr].opcode = DEAD_CODE;
+ return 1;
+ }
+ break;
+
+ case OP_MUL:
+ case OP_DIV:
+ case OP_MOD:
+ case OP_LT:
+ case OP_LE:
+ case OP_EQ:
+ case OP_NE:
+ case OP_ADD:
+ case OP_SUB:
+ if (imcode->operand2 == load_to) {
+ imcode->operand2 = load_from;
+ IMCode[target_imcode_addr].opcode = DEAD_CODE;
+ return 1;
+ }
+ if (imcode->operand3 == load_to) {
+ imcode->operand3 = load_from;
+ IMCode[target_imcode_addr].opcode = DEAD_CODE;
+ return 1;
+ }
+ break;
+
+ case OP_SUBI:
+ case OP_EQI:
+ if (imcode->operand2 == load_to) {
+ imcode->operand2 = load_from;
+ IMCode[target_imcode_addr].opcode = DEAD_CODE;
+ return 1;
+ }
+ break;
+
+ case OP_LT_R0:
+ case OP_LE_R0:
+ case OP_EQ_R0:
+ case OP_NE_R0:
+ if (imcode->operand1 == load_to) {
+ imcode->operand1 = load_from;
+ IMCode[target_imcode_addr].opcode = DEAD_CODE;
+ return 1;
+ }
+ if (imcode->operand2 == load_to) {
+ imcode->operand2 = load_from;
+ IMCode[target_imcode_addr].opcode = DEAD_CODE;
+ return 1;
+ }
+ break;
+
+ case OP_EQI_R0:
+ if (imcode->operand1 == load_to) {
+ imcode->operand1 = load_from;
+ IMCode[target_imcode_addr].opcode = DEAD_CODE;
+ return 1;
+ }
+ break;
+
+ }
+
+ }
+
+ return 0;
+
+}
+
+
+#define MAX_LABEL 50
+#define MAX_BACKPATCH MAX_LABEL*2
+int CmEnv_generate_VMcode(void **code) {
+ int addr = 0;
+ struct IMCode_tag *imcode;
+
+ int label_table[MAX_LABEL];
+ int backpatch_num = 0;
+ int backpatch_table[MAX_BACKPATCH];
+
+ for (int i=0; i<IMCode_n; i++) {
+ imcode = &IMCode[i];
+
+#ifdef OPTIMISE_IMCODE
+
+ // optimisation
+ // Copy Propagation for LOAD reg1, reg2 --> [reg2/reg1]
+ // and Dead Code Optimisation
+ if (imcode->opcode == LOAD) {
+ if (CmEnv_Optimise_VMCode_CopyPropagation(i)) {
+ continue;
+ }
+ }
+#endif
+
+ switch (imcode->opcode) {
+ case MKNAME:
// printf("MKNAME var%d\n", imcode->operand1);
- code[ptr++] = CodeAddr[imcode->opcode];
- code[ptr++] = (void *)(unsigned long)imcode->operand1;
+ code[addr++] = CodeAddr[imcode->opcode];
+ code[addr++] = (void *)(unsigned long)imcode->operand1;
break;
case MKGNAME:
// printf("MKGNAME var%d sym:%d (as `%s')\n",
// imcode->operand1, 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;
+ code[addr++] = CodeAddr[imcode->opcode];
+ code[addr++] = (void *)(unsigned long)imcode->operand1;
+ code[addr++] = 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;
+ code[addr++] = CodeAddr[imcode->opcode];
+ code[addr++] = (void *)(unsigned long)imcode->operand1;
+ code[addr++] = (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;
+ code[addr++] = CodeAddr[imcode->opcode];
+ code[addr++] = (void *)(unsigned long)imcode->operand1;
+ code[addr++] = (void *)(unsigned long)imcode->operand2;
+ code[addr++] = (void *)(unsigned long)imcode->operand3;
break;
case MKAGENT2:
@@ -2355,11 +2561,11 @@ int CmEnv_Generate_VMCode(void **code, int offset) {
// 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;
+ code[addr++] = CodeAddr[imcode->opcode];
+ code[addr++] = (void *)(unsigned long)imcode->operand1;
+ code[addr++] = (void *)(unsigned long)imcode->operand2;
+ code[addr++] = (void *)(unsigned long)imcode->operand3;
+ code[addr++] = (void *)(unsigned long)imcode->operand4;
break;
case MKAGENT3:
@@ -2367,12 +2573,12 @@ int CmEnv_Generate_VMCode(void **code, int offset) {
// 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[addr++] = CodeAddr[imcode->opcode];
+ code[addr++] = (void *)(unsigned long)imcode->operand1;
+ code[addr++] = (void *)(unsigned long)imcode->operand2;
+ code[addr++] = (void *)(unsigned long)imcode->operand3;
+ code[addr++] = (void *)(unsigned long)imcode->operand4;
+ code[addr++] = (void *)(unsigned long)imcode->operand5;
break;
case MKAGENT4:
@@ -2380,13 +2586,13 @@ int CmEnv_Generate_VMCode(void **code, int offset) {
// 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[addr++] = CodeAddr[imcode->opcode];
+ code[addr++] = (void *)(unsigned long)imcode->operand1;
+ code[addr++] = (void *)(unsigned long)imcode->operand2;
+ code[addr++] = (void *)(unsigned long)imcode->operand3;
+ code[addr++] = (void *)(unsigned long)imcode->operand4;
+ code[addr++] = (void *)(unsigned long)imcode->operand5;
+ code[addr++] = (void *)(unsigned long)imcode->operand6;
break;
case MKAGENT5:
@@ -2394,29 +2600,49 @@ int CmEnv_Generate_VMCode(void **code, int offset) {
// 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;
+ code[addr++] = CodeAddr[imcode->opcode];
+ code[addr++] = (void *)(unsigned long)imcode->operand1;
+ code[addr++] = (void *)(unsigned long)imcode->operand2;
+ code[addr++] = (void *)(unsigned long)imcode->operand3;
+ code[addr++] = (void *)(unsigned long)imcode->operand4;
+ code[addr++] = (void *)(unsigned long)imcode->operand5;
+ code[addr++] = (void *)(unsigned long)imcode->operand6;
+ code[addr++] = (void *)(unsigned long)imcode->operand7;
break;
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;
+ code[addr++] = CodeAddr[imcode->opcode];
+ code[addr++] = (void *)(unsigned long)imcode->operand1;
+ code[addr++] = (void *)(unsigned long)imcode->operand2;
+ break;
+
+
+
+ case OP_JMPEQ0:
+ case OP_JMPNEQ0:
+ // JMPEQ0 reg label
+ code[addr++] = CodeAddr[imcode->opcode];
+ code[addr++] = (void *)(unsigned long)imcode->operand1;
+
+ backpatch_table[backpatch_num++] = addr;
+ code[addr++] = (void *)(unsigned long)imcode->operand2;
+ break;
+
+
+ case OP_JMPEQ0_R0:
+ code[addr++] = CodeAddr[imcode->opcode];
+
+ backpatch_table[backpatch_num++] = addr;
+ code[addr++] = (void *)(unsigned long)imcode->operand1;
break;
+
case OP_ADD:
case OP_SUB:
case OP_MUL:
@@ -2428,19 +2654,30 @@ int CmEnv_Generate_VMCode(void **code, int offset) {
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;
+ code[addr++] = CodeAddr[imcode->opcode];
+ code[addr++] = (void *)(unsigned long)imcode->operand1;
+ code[addr++] = (void *)(unsigned long)imcode->operand2;
+ code[addr++] = (void *)(unsigned long)imcode->operand3;
break;
+
+ case OP_LT_R0:
+ case OP_LE_R0:
+ case OP_EQ_R0:
+ case OP_NE_R0:
+ case OP_EQI_R0:
+ code[addr++] = CodeAddr[imcode->opcode];
+ code[addr++] = (void *)(unsigned long)imcode->operand1;
+ code[addr++] = (void *)(unsigned long)imcode->operand2;
+ break;
+
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);
+ code[addr++] = CodeAddr[imcode->opcode];
+ code[addr++] = (void *)(unsigned long)imcode->operand1;
+ code[addr++] = (void *)INT2FIX(imcode->operand2);
break;
@@ -2450,16 +2687,16 @@ int CmEnv_Generate_VMCode(void **code, int offset) {
case RET_FREE_LR:
case LOOP:
case NOP:
- code[ptr++] = CodeAddr[imcode->opcode];
+ code[addr++] = 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 *)INT2FIX(imcode->operand2);
+ code[addr++] = CodeAddr[imcode->opcode];
+ code[addr++] = (void *)(unsigned long)imcode->operand1;
+ code[addr++] = (void *)INT2FIX(imcode->operand2);
break;
@@ -2467,54 +2704,77 @@ int CmEnv_Generate_VMCode(void **code, int offset) {
case LOOP_RREC2:
// printf("LOOP_RREC1 var%d\n",
// imcode->operand1);
- code[ptr++] = CodeAddr[imcode->opcode];
- code[ptr++] = (void *)(unsigned long)imcode->operand1;
+ code[addr++] = CodeAddr[imcode->opcode];
+ code[addr++] = (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;
+ code[addr++] = CodeAddr[imcode->opcode];
+ code[addr++] = (void *)(unsigned long)imcode->operand1;
+ code[addr++] = (void *)(unsigned long)imcode->operand2;
+ code[addr++] = (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;
+ code[addr++] = CodeAddr[imcode->opcode];
+
+ backpatch_table[backpatch_num++] = addr;
+ code[addr++] = (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;
+ code[addr++] = CodeAddr[imcode->opcode];
+ code[addr++] = (void *)(unsigned long)imcode->operand1;
+ code[addr++] = (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;
+ code[addr++] = CodeAddr[imcode->opcode];
+ code[addr++] = (void *)(unsigned long)imcode->operand1;
+ code[addr++] = (void *)(unsigned long)imcode->operand2;
+ break;
+
+
+ case DEAD_CODE:
+ break;
+
+ case LABEL:
+ if (imcode->operand1 > MAX_LABEL) {
+ printf("Critical Error: Label number overfllow.");
+ exit(-1);
+ }
+ label_table[imcode->operand1] = addr;
break;
default:
- printf("Error[CmEnv_Generate_VMCode]: %d does not match any opcode\n",
+ printf("Error[CmEnv_generate_VMcode]: %d does not match any opcode\n",
imcode->opcode);
exit(-1);
}
}
- return (ptr-offset);
+
+ // two pass for label
+ for (int i=0; i<backpatch_num; i++) {
+ int hole_addr = backpatch_table[i];
+ int jmp_label = (unsigned long)code[hole_addr];
+ code[hole_addr] = (void *)(unsigned long)
+ (label_table[jmp_label]-(hole_addr+1));
+ }
+
+ return addr;
}
@@ -2715,36 +2975,68 @@ void IMCode_Puts(int n) {
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_LT_R0:
+ printf("LT_R0 var%d var%d\n",
+ imcode->operand1, imcode->operand2);
break;
case OP_LE:
printf("LE var%d var%d var%d\n",
imcode->operand1, imcode->operand2, imcode->operand3);
break;
+ case OP_LE_R0:
+ printf("LE_R0 var%d var%d\n",
+ imcode->operand1, imcode->operand2);
+ break;
case OP_EQ:
printf("EQ var%d var%d var%d\n",
imcode->operand1, imcode->operand2, imcode->operand3);
break;
+ case OP_EQ_R0:
+ printf("EQ_R0 var%d var%d\n",
+ imcode->operand1, imcode->operand2);
+ break;
case OP_EQI:
printf("EQI var%d var%d $%d\n",
imcode->operand1, imcode->operand2, imcode->operand3);
break;
+ case OP_EQI_R0:
+ printf("EQI_R0 var%d $%d\n",
+ imcode->operand1, imcode->operand2);
+ break;
case OP_NE:
printf("NE var%d var%d var%d\n",
imcode->operand1, imcode->operand2, imcode->operand3);
break;
+ case OP_NE_R0:
+ printf("NE_R0 var%d var%d\n",
+ imcode->operand1, imcode->operand2);
+ break;
+
+
+ case OP_JMPNEQ0:
+ printf("JMPNEQ0 var%d LABEL%d\n",
+ imcode->operand1, imcode->operand2);
+ break;
case OP_JMPEQ0:
- printf("JMPEQ0 var%d $%d\n",
+ printf("JMPEQ0 var%d LABEL%d\n",
imcode->operand1, imcode->operand2);
break;
+
+ case OP_JMPEQ0_R0:
+ printf("JMPEQ0_RO LABEL%d\n",
+ imcode->operand1);
+ break;
case OP_JMPCNCT_CONS:
printf("JMPCNCT_CONS var%d $%d\n",
@@ -2757,7 +3049,7 @@ void IMCode_Puts(int n) {
break;
case OP_JMP:
- printf("JMP $%d\n",
+ printf("JMP LABEL%d\n",
imcode->operand1);
break;
@@ -2785,6 +3077,15 @@ void IMCode_Puts(int n) {
printf("NOP\n");
break;
+ case DEAD_CODE:
+ printf("DEAD\n");
+ break;
+
+ case LABEL:
+ printf(":LABEL%d\n",
+ imcode->operand1);
+ break;
+
default:
printf("CODE %d %d %d %d %d %d\n",
imcode->operand1, imcode->operand2, imcode->operand3,
@@ -3039,13 +3340,6 @@ void PutsCodeN(void **code, int n) {
(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],
@@ -3066,6 +3360,42 @@ void PutsCodeN(void **code, int n) {
(unsigned long)code[i+2],
(unsigned long)code[i+3]);
i+=3;
+
+ } else if (code[i] == CodeAddr[OP_LT_R0]) {
+ printf("lt_r0 var%lu var%lu\n",
+ (unsigned long)code[i+1],
+ (unsigned long)code[i+2]);
+ i+=2;
+
+ } else if (code[i] == CodeAddr[OP_LE_R0]) {
+ printf("le_r0 var%lu var%lu\n",
+ (unsigned long)code[i+1],
+ (unsigned long)code[i+2]);
+ i+=2;
+
+ } else if (code[i] == CodeAddr[OP_EQ_R0]) {
+ printf("eq_r0 var%lu var%lu\n",
+ (unsigned long)code[i+1],
+ (unsigned long)code[i+2]);
+ i+=2;
+
+ } else if (code[i] == CodeAddr[OP_EQI_R0]) {
+ printf("eqi_r0 var%lu var%ld\n",
+ (unsigned long)code[i+1],
+ (long int)code[i+2]);
+ i+=2;
+
+ } else if (code[i] == CodeAddr[OP_NE_R0]) {
+ printf("ne_r0 var%lu var%lu\n",
+ (unsigned long)code[i+1],
+ (unsigned long)code[i+2]);
+ i+=2;
+
+ } else if (code[i] == CodeAddr[OP_JMPNEQ0]) {
+ printf("jmpneq0 var%lu $%lu\n",
+ (unsigned long)code[i+1],
+ (unsigned long)code[i+2]);
+ i+=2;
} else if (code[i] == CodeAddr[OP_JMPEQ0]) {
printf("jmpeq0 var%lu $%lu\n",
@@ -3073,6 +3403,11 @@ void PutsCodeN(void **code, int n) {
(unsigned long)code[i+2]);
i+=2;
+ } else if (code[i] == CodeAddr[OP_JMPEQ0_R0]) {
+ printf("jmpeq0_r0 $%lu\n",
+ (unsigned long)code[i+1]);
+ i+=1;
+
} else if (code[i] == CodeAddr[OP_JMPCNCT_CONS]) {
printf("jmpcnct_cons var%lu $%lu\n",
(unsigned long)code[i+1],
@@ -3188,7 +3523,7 @@ int is_expr(Ast *ptr) {
int CompileExprFromAst(Ast *ptr, int target) {
-
+
if (ptr == NULL) {
return 1;
}
@@ -3276,11 +3611,109 @@ int CompileExprFromAst(Ast *ptr, int target) {
}
IMCode_genCode3(opcode, target, newreg, newreg2);
- return 1;
+ return 1;
+ break;
+ }
+ case AST_AND: {
+ // compilation of expr1 && expr2
+
+ // if (expr1 == 0) goto L1;
+ // if (expr2 == 0) goto L1;
+ // target = 1;
+ // goto L2;
+ // L1:
+ // target = 0;
+ // L2;
+
+ int newreg = CmEnv_newreg();
+ if (!CompileExprFromAst(ptr->left, newreg)) return 0;
+
+ int label1 = CmEnv_get_newlabel();
+ IMCode_genCode2(OP_JMPEQ0, newreg, label1);
+
+ int newreg2 = CmEnv_newreg();
+ if (!CompileExprFromAst(ptr->right, newreg2)) return 0;
+ IMCode_genCode2(OP_JMPEQ0, newreg2, label1);
+
+ IMCode_genCode2(LOADI, target, 1);
+
+ int label2 = CmEnv_get_newlabel();
+ IMCode_genCode1(OP_JMP, label2);
+
+ IMCode_genCode1(LABEL, label1);
+ IMCode_genCode2(LOADI, target, 0);
+
+ IMCode_genCode1(LABEL, label2);
+
+ return 1;
break;
}
+ case AST_OR: {
+ // compilation of expr1 || expr2
+
+ // calc expr1
+ // if (expr1 != 0) goto L1;
+ // if (expr2 != 0) goto L1;
+ // target = 0;
+ // goto L2;
+ // L1:
+ // target = 1;
+ // L2;
+
+ int newreg = CmEnv_newreg();
+ if (!CompileExprFromAst(ptr->left, newreg)) return 0;
+
+ int label1 = CmEnv_get_newlabel();
+ IMCode_genCode2(OP_JMPNEQ0, newreg, label1);
+
+ int newreg2 = CmEnv_newreg();
+ if (!CompileExprFromAst(ptr->right, newreg2)) return 0;
+ IMCode_genCode2(OP_JMPNEQ0, newreg2, label1);
+
+ IMCode_genCode2(LOADI, target, 0);
+
+ int label2 = CmEnv_get_newlabel();
+ IMCode_genCode1(OP_JMP, label2);
+
+ IMCode_genCode1(LABEL, label1);
+ IMCode_genCode2(LOADI, target, 1);
+
+ IMCode_genCode1(LABEL, label2);
+
+ return 1;
+ break;
+ }
+ case AST_NOT: {
+ // compilation of !(expr1)
+ // if (expr1 == 0) goto L1;
+ // target = 0;
+ // goto L2;
+ // L1:
+ // target = 1;
+ // L2;
+
+ int newreg = CmEnv_newreg();
+ if (!CompileExprFromAst(ptr->left, newreg)) return 0;
+
+ int label1 = CmEnv_get_newlabel();
+ IMCode_genCode2(OP_JMPEQ0, newreg, label1);
+
+ IMCode_genCode2(LOADI, target, 0);
+
+ int label2 = CmEnv_get_newlabel();
+ IMCode_genCode1(OP_JMP, label2);
+
+ IMCode_genCode1(LABEL, label1);
+ IMCode_genCode2(LOADI, target, 1);
+
+ IMCode_genCode1(LABEL, label2);
+
+ return 1;
+ break;
+ }
+
default:
- puts("System ERROR: Wrong AST was given to CompileExpr.");
+ puts("System ERROR: Wrong AST was given to CompileExpr.\n");
return 0;
}
@@ -4253,11 +4686,12 @@ int getRuleAgentID(Ast *ruleAgent) {
-int CompileIfSentenceFromAST(Ast *if_sentence_top,
- void **code, int offset_code) {
- // return
- // generated codesize
- // -1 : compile error
+//int CompileIfSentenceFromAST(Ast *if_sentence_top,
+// void **code, int offset_code) {
+
+int CompileIfSentenceFromAST(Ast *if_sentence_top) {
+ // return 1: success
+ // 0: compile error
// <if-sentence> ::= (AST_IF guard (AST_BRANCH <then> <else>))
// | <body>
@@ -4266,8 +4700,6 @@ int CompileIfSentenceFromAST(Ast *if_sentence_top,
Ast *if_sentence;
- int generated_codesize; // コンパイルで生成されたコード数保存用
-
if_sentence = if_sentence_top;
CmEnv_clear_keeping_rule_properties();
@@ -4277,83 +4709,103 @@ int CompileIfSentenceFromAST(Ast *if_sentence_top,
// 通常コンパイル
Ast *body = if_sentence;
- if (!CompileBodyFromAst(body)) return -1;
+ if (!CompileBodyFromAst(body)) return 0;
Compile_Put_Ret_ForRuleBody();
CmEnv_Retrieve_GNAME();
- generated_codesize = CmEnv_Generate_VMCode(code, offset_code);
- if (generated_codesize < 0) {
- puts("System ERROR: Generated codes were too long.");
- return -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;
+ return 0;
}
- return generated_codesize;
+ return 1;
} else {
// if_sentence
Ast *guard, *then_branch, *else_branch;
- int label; // 飛び先指定用
+ int label; // jump label
- int offset = offset_code;
guard = if_sentence->left;
then_branch = if_sentence->right->left;
else_branch = if_sentence->right->right;
- // Gurad のコンパイル
+ // Compilation of Guard expressions
int newreg = CmEnv_newreg();
if (!CompileExprFromAst(guard, newreg)) return -1;
-
- // CmEnv_Retrieve_GNAME();
- generated_codesize = CmEnv_Generate_VMCode(code, offset_code);
- offset += generated_codesize;
- //JMPEQ0 用コードを作成
- code[offset++] = CodeAddr[OP_JMPEQ0];
- code[offset++] = (void *)(unsigned long)newreg;
- label = offset++; // 飛び先を格納するアドレスを記憶しておく
+#ifdef OPTIMISE_IMCODE
+ // optimisation for R0
+ int opt = 0;
+ struct IMCode_tag *imcode = &IMCode[IMCode_n-1];
+ switch(imcode->opcode) {
+ case OP_LT:
+ imcode->opcode = OP_LT_R0;
+ opt=1;
+ break;
- // then_branch のコンパイル
- CmEnv_clear_localnamePtr(); // 局所変数としての reg番号を初期化
+ case OP_LE:
+ imcode->opcode = OP_LE_R0;
+ opt=1;
+ break;
- generated_codesize = CompileIfSentenceFromAST(then_branch, code, offset);
- if (generated_codesize < 0) return -1;
-
- offset += generated_codesize;
+ case OP_EQ:
+ imcode->opcode = OP_EQ_R0;
+ opt=1;
+ break;
+
+ case OP_EQI:
+ imcode->opcode = OP_EQI_R0;
+ opt=1;
+ break;
- if (offset > MAX_CODE_SIZE) {
- puts("System ERROR: Generated codes were too big.");
- return -1;
+ case OP_NE:
+ imcode->opcode = OP_NE_R0;
+ opt=1;
+ }
+
+ if (opt == 1) {
+ imcode->operand1 = imcode->operand2;
+ imcode->operand2 = imcode->operand3;
}
+#endif
- // JMPEQ0 のとび先を格納(相対ジャンプ)
- code[label]=(void *)(unsigned long)generated_codesize;
+ // CmEnv_Retrieve_GNAME(); // <- no need for guard expressions
- // else_branch のコンパイル
+ // Generate JMPEQ0 for VM
+ label = CmEnv_get_newlabel();
+#ifdef OPTIMISE_IMCODE
+ if (opt != 1) {
+ IMCode_genCode2(OP_JMPEQ0, newreg, label);
+
+ } else {
+ IMCode_genCode1(OP_JMPEQ0_R0, label);
+ }
+#else
+ IMCode_genCode2(OP_JMPEQ0, newreg, label);
+#endif
+
+
+ // Compilation of then_branch
CmEnv_clear_localnamePtr(); // 局所変数としての reg番号を初期化
+ if (!CompileIfSentenceFromAST(then_branch)) return 0;
+
- generated_codesize = CompileIfSentenceFromAST(else_branch, code, offset);
- if (generated_codesize < 0) return -1;
+ IMCode_genCode1(LABEL, label);
- offset += generated_codesize;
- if (offset > MAX_CODE_SIZE) {
- puts("System ERROR: Generated codes were too big.");
- return -1;
- }
- return offset - offset_code;
+ // else_branch のコンパイル
+ CmEnv_clear_localnamePtr(); // 局所変数としての reg番号を初期化
+ if (!CompileIfSentenceFromAST(else_branch)) return 0;
+
+ return 1;
}
@@ -4377,7 +4829,7 @@ int makeRule(Ast *ast) {
Ast *ruleL, *ruleR, *if_sentence;
void* code[MAX_CODE_SIZE];
- int code_offset=0;
+ int gencode_num=0;
ruleL = ast->left->left;
ruleR = ast->left->right;
@@ -4477,32 +4929,31 @@ int makeRule(Ast *ast) {
setAnnotateLR(VM_OFFSET_ANNOTATE_R, VM_OFFSET_ANNOTATE_L);
}
- {
- int arity;
-
- // IMPORTANT:
- // At the first two codes, arities of idL and idR are stored.
- if (idL == ID_INT) {
- arity = 0;
- } else {
- arity = getArityFromAST(ruleL);
- }
- IdTable_set_arity(idL, arity);
- code[0] = (void *)(unsigned long)arity;
-
- if (idR == ID_INT) {
- arity = 0;
- } else {
- arity = getArityFromAST(ruleR);
- }
- IdTable_set_arity(idR, arity);
- code[1] = (void *)(unsigned long)arity;
-
- code_offset = 2;
+ int arity;
+
+ // IMPORTANT:
+ // The first two codes stores arities of idL and idR, respectively.
+ if (idL == ID_INT) {
+ arity = 0;
+ } else {
+ arity = getArityFromAST(ruleL);
+ }
+ IdTable_set_arity(idL, arity);
+ code[0] = (void *)(unsigned long)arity;
+
+ if (idR == ID_INT) {
+ arity = 0;
+ } else {
+ arity = getArityFromAST(ruleR);
}
+ IdTable_set_arity(idR, arity);
+ code[1] = (void *)(unsigned long)arity;
+ gencode_num = 2;
+
+
CmEnv_clear_all();
if (idL == ID_INT) {
@@ -4523,31 +4974,29 @@ int makeRule(Ast *ast) {
CmEnv.idR = idR;
- {
- int generated_codesize = CompileIfSentenceFromAST(if_sentence,
- code, code_offset);
- if (generated_codesize < 0) {
- return 0;
- }
- code_offset += generated_codesize;
- }
+ if (!CompileIfSentenceFromAST(if_sentence)) return 0;
+
+ // IMCode_Puts(0);
+ gencode_num += CmEnv_generate_VMcode(&code[2]);
+
#ifdef MYDEBUG
- PutsCodeN(code, code_offset); exit(1);
+ PutsCodeN(code, gencode_num); exit(1);
#endif
- // PutsCodeN(code, code_offset); exit(1);
+ // PutsCodeN(code, gencode_num); 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);
+ // PutsCodeN(&code[2], gencode_num-2);
// exit(1);
//ast_puts(ruleL); printf("><");
//ast_puts(ruleR); puts("");
+
// Record the rule code for idR >< idL
- RuleTable_record(idL, idR, code, code_offset);
+ RuleTable_record(idL, idR, code, gencode_num);
if (idL != idR) {
// Delete the rule code for idR >< idL
@@ -4556,6 +5005,31 @@ int makeRule(Ast *ast) {
}
+
+ //#define DEBUG_PUT_RULE_CODE
+#ifdef DEBUG_PUT_RULE_CODE
+ if (((strcmp(IdTable_get_name(idL), "Fib") == 0) &&
+ (idR == ID_INT))
+ ||
+ ((strcmp(IdTable_get_name(idL), "fib") == 0) &&
+ (idR == ID_INT))
+ ||
+ ((strcmp(IdTable_get_name(idL), "MergeCC") == 0) &&
+ (idR == ID_CONS))
+ ) {
+
+ printf("Rule: %s >< %s.\n",
+ IdTable_get_name(idL),
+ IdTable_get_name(idR));
+
+ PutsCodeN(code, gencode_num+2);
+ // exit(1);
+ }
+#endif
+
+
+
+
return 1;
}
@@ -4652,8 +5126,10 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) {
&&E_LOOP, &&E_LOOP_RREC, &&E_LOOP_RREC1, &&E_LOOP_RREC2,
&&E_LOADI, &&E_LOAD, &&E_LOADP,
&&E_ADD, &&E_SUB, &&E_SUBI, &&E_MUL, &&E_DIV, &&E_MOD,
- &&E_LT, &&E_LE, &&E_EQ, &&E_EQI, &&E_NE,
- &&E_JMPEQ0, &&E_JMPCNCT_CONS, &&E_JMPCNCT, &&E_JMP,
+ &&E_LT, &&E_LE, &&E_EQ, &&E_EQI, &&E_NE,
+ &&E_LT_R0, &&E_LE_R0, &&E_EQ_R0, &&E_EQI_R0, &&E_NE_R0,
+ &&E_JMPEQ0, &&E_JMPEQ0_R0, &&E_JMP, &&E_JMPNEQ0,
+ &&E_JMPCNCT_CONS, &&E_JMPCNCT,
&&E_UNM, &&E_RAND,
&&E_CNCTGN, &&E_SUBSTGN,
&&E_NOP,
@@ -5177,6 +5653,69 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) {
pc +=4;
goto *code[pc];
+
+
+ E_LT_R0:
+ // puts("lt_r0 reg reg");
+ if (FIX2INT(reg[(unsigned long)code[pc+1]]) <
+ FIX2INT(reg[(unsigned long)code[pc+2]])) {
+ reg[0] = INT2FIX(1);
+ } else {
+ reg[0] = INT2FIX(0);
+ }
+ pc +=3;
+ goto *code[pc];
+
+ E_LE_R0:
+ // puts("SUB reg reg");
+ if (FIX2INT(reg[(unsigned long)code[pc+1]]) <=
+ FIX2INT(reg[(unsigned long)code[pc+2]])) {
+ reg[0] = INT2FIX(1);
+ } else {
+ reg[0] = INT2FIX(0);
+ }
+ pc +=3;
+ goto *code[pc];
+
+ E_EQ_R0:
+ // puts("SUB reg reg");
+ if (reg[(unsigned long)code[pc+1]] ==
+ reg[(unsigned long)code[pc+2]]) {
+ reg[0] = INT2FIX(1);
+ } else {
+ reg[0] = INT2FIX(0);
+ }
+ pc +=3;
+ goto *code[pc];
+
+
+ E_EQI_R0:
+ // puts("SUB reg int");
+ if (FIX2INT(reg[(unsigned long)code[pc+1]]) ==
+ (unsigned long)code[pc+2]) {
+ reg[0] = INT2FIX(1);
+ } else {
+ reg[0] = INT2FIX(0);
+ }
+
+ pc +=3;
+ goto *code[pc];
+
+
+
+ E_NE_R0:
+ // puts("SUB reg reg");
+ if (reg[(unsigned long)code[pc+1]] !=
+ reg[(unsigned long)code[pc+2]]) {
+ reg[0] = INT2FIX(1);
+ } else {
+ reg[0] = INT2FIX(0);
+ }
+ pc +=4;
+ goto *code[pc];
+
+
+
E_JMPEQ0:
// puts("JMPEQ0 reg pc");
// pc is a relative address, not absolute one!
@@ -5187,6 +5726,25 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) {
goto *code[pc];
+ E_JMPEQ0_R0:
+ // puts("JMPEQ0 pc");
+ if (!FIX2INT(reg[0])) {
+ pc += (unsigned long)code[pc+1];
+ }
+ pc +=2;
+ goto *code[pc];
+
+
+ E_JMPNEQ0:
+ // puts("JMPNEQ0 reg pc");
+ if (FIX2INT(reg[(unsigned long)code[pc+1]])) {
+ pc += (unsigned long)code[pc+2];
+ }
+ pc +=3;
+ goto *code[pc];
+
+
+
E_JMPCNCT_CONS:
// puts("JMPCNCT_CONS reg pc");
#ifdef COUNT_CNCT
@@ -5272,8 +5830,8 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) {
E_JMP:
- // puts("JMP pc");
- pc += reg[(unsigned long)code[pc+1]];
+ // puts("JMP pc");
+ pc += (unsigned long)code[pc+1];
pc +=2;
goto *code[pc];
@@ -6402,15 +6960,14 @@ int exec(Ast *at) {
}
- // Generate codes from CmEnv, where '0' means index of the `code',
- // so here codes are stored from code[0].
-
CmEnv_Retrieve_GNAME();
// IMCode_Puts(0);
- CmEnv_Generate_VMCode(code, 0);
+ CmEnv_generate_VMcode(code);
// PutsCode(code); exit(1);
+
+
#ifdef COUNT_MKAGENT
NumberOfMkAgent=0;
#endif
@@ -6494,24 +7051,30 @@ void *tpool_thread(void *arg) {
vm = (VirtualMachine *)arg;
+
#ifdef CPU_ZERO
cpu_set_t mask;
CPU_ZERO(&mask);
CPU_SET((vm->id)%CpuNum, &mask);
if(sched_setaffinity(0, sizeof(mask), &mask)==-1) {
- printf("WARNING:");
- printf("CPUNUM=%d, id=%d, cpuid=%d\n", CpuNum, vm->id, (vm->id)%CpuNum);
+ printf("WARNING:");
+ printf("Thread%d works on Core%d/%d\n", vm->id, (vm->id)%CpuNum, CpuNum-1);
}
- //printf("CPUNUM=%d, id=%d, cpuid=%d\n", CpuNum, vm->id, (vm->id)%CpuNum);
+ // printf("Thread%d works on Core%d/%d\n", vm->id, (vm->id)%CpuNum, CpuNum-1);
#endif
+
while (1) {
VALUE t1, t2;
while (!EQStack_Pop(vm, &t1, &t2)) {
+
+ // Not sure, but it works well. Perhaps it can reduce race condition.
+ usleep(CAS_LOCK_USLEEP);
+
pthread_mutex_lock(&Sleep_lock);
SleepingThreadsNum++;
-
+
if (SleepingThreadsNum == MaxThreadsNum) {
pthread_mutex_lock(&AllSleep_lock);
pthread_cond_signal(&ActiveThread_all_sleep);
@@ -6679,12 +7242,13 @@ int exec(Ast *at) {
return 0;
}
- // '0' means that generated codes are stored in code[0,...].
CmEnv_Retrieve_GNAME();
- CmEnv_Generate_VMCode(code, 0);
+ // IMCode_Puts(0); exit(1);
+
+ CmEnv_generate_VMcode(code);
- // int codenum = CmEnv_Generate_VMCode(code, 0);
- // PutsCodeN(code, codenum); exit(1);
+ // int codenum = CmEnv_generate_VMcode(code);
+ // PutsCodeN(code, codenum-2); //exit(1);
ExecCode(1, VMs[0], code);
@@ -6712,8 +7276,9 @@ int exec(Ast *at) {
pthread_cond_broadcast(&EQStack_not_empty);
pthread_mutex_unlock(&Sleep_lock);
- //usleep(CAS_LOCK_USLEEP); // a little wait untill threads start.
- usleep(10000);
+ // a little wait until all threads start.
+ //usleep(CAS_LOCK_USLEEP);
+ usleep(10000); // 0.01 sec wait
// if some threads are working, wait for all of these to sleep.
@@ -6768,286 +7333,290 @@ int yywrap() {
int main(int argc, char *argv[])
{
- int retrieve_flag = 1; // 1:エラー時にインタプリタへ復帰, 0:終了
+ int i, param;
+ char *fname = NULL;
+ int max_EQStack=1<<8; // 512
+ int retrieve_flag = 1; // 1: retrieve to interpreter even if error occurs
+#ifndef EXPANDABLE_HEAP
+ // v0.5.6
+ unsigned int heap_size=100000;
+#endif
+
#ifdef MY_YYLINENO
- InfoLineno_Init();
+ InfoLineno_Init();
#endif
// Pritty printing for local variables
#ifdef PRETTY_VAR
- Pretty_init();
+ Pretty_init();
#endif
- {
- int i, param;
- char *fname = NULL;
-
- int max_EQStack=1<<8; // 512
-
-
-#ifndef EXPANDABLE_HEAP
- // v0.5.6
- unsigned int heap_size=100000;
-#endif
-
+
#ifndef THREAD
- Init_WHNFinfo();
+ Init_WHNFinfo();
#endif
- ast_heapInit();
+ ast_heapInit();
- for (i=1; i<argc; i++) {
- if (*argv[i] == '-') {
- switch (*(argv[i] +1)) {
- case 'v':
- printf("Inpla version %s\n", VERSION);
- exit(-1);
- break;
- case '-':
- case 'h':
- case '?':
- printf("Inpla version %s\n", VERSION);
- puts("Usage: inpla [options]\n");
- puts("Options:");
- printf(" -f <filename> Set input file name (Defalut: STDIN)\n");
+ for (i=1; i<argc; i++) {
+ if (*argv[i] == '-') {
+ switch (*(argv[i] +1)) {
+ case 'v':
+ printf("Inpla version %s\n", VERSION);
+ exit(-1);
+ break;
+ case '-':
+ case 'h':
+ case '?':
+ printf("Inpla version %s\n", VERSION);
+ puts("Usage: inpla [options]\n");
+ puts("Options:");
+ printf(" -f <filename> Set input file name (Defalut: STDIN)\n");
+
#ifndef EXPANDABLE_HEAP
- //v0.5.6
- printf(" -c <number> Set the size of heaps (Defalut: %8u)\n",
- heap_size);
+ //v0.5.6
+ printf(" -c <number> Set the size of heaps (Defalut: %8u)\n", heap_size);
#endif
-
- printf(" -e <number> Set the unit size of the EQ stack (Default: %8u)\n",
- max_EQStack);
-
+
+ printf(" -e <number> Set the unit size of the EQ stack (Default: %8u)\n", max_EQStack);
+
- // Special Options
+ // Special Options
#ifdef THREAD
- printf(" -t <number> Set the number of threads (Default: %8d)\n",
- MaxThreadsNum);
+ printf(" -t <number> 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");
#endif
- printf(" -d <Name>=<val> Bind <val> to <Name>\n"
- );
-
- printf(" -h Print this help message\n\n");
- exit(-1);
- break;
-
- case 'd':
- i++;
- if (i < argc) {
- char varname[100], val[100];
- char *tp;
- tp = strtok(argv[i], "=");
- snprintf(varname, sizeof(varname)-1, "%s", tp);
-
- if ((varname == NULL)
- || (varname[0] < 'A')
- || (varname[0] > 'Z')) {
- puts("ERROR: 'id' in the format 'id=value' must start from a capital letter.");
- exit(-1);
- }
+ printf(" -d <Name>=<val> Bind <val> to <Name>\n");
+ printf(" -h Print this help message\n\n");
+ exit(-1);
+ break;
+
+
+ case 'd':
+ i++;
+ if (i < argc) {
+ char varname[100], val[100];
+ char *tp;
+ tp = strtok(argv[i], "=");
- tp = strtok(NULL, "=");
- snprintf(val, sizeof(val)-1, "%s", tp);
- if (val == NULL) {
- puts("ERROR: 'value' in the format 'id=value' must an integer value.");
- exit(-1);
- }
+ // parsing for an identifier
+ snprintf(varname, sizeof(varname)-1, "%s", tp);
+ if ((varname == NULL) || (varname[0] < 'A') || (varname[0] > 'Z')) {
+ puts("ERROR: 'id' in the format 'id=value' must start from a capital letter.");
+ exit(-1);
+ }
- int offset = 0;
- if (val[0] == '-') {
- offset = 1;
- }
- int valid = 1;
- for (int idx = offset; idx < strlen(val); idx++) {
- if ((val[idx] < '0') || (val[idx] > '9')) {
- valid = 0;
- break;
- }
- }
+
+ tp = strtok(NULL, "=");
- if (!valid) {
- puts("ERROR: 'value' in the format 'id=value' must an integer value.");
- exit(-1);
- }
+ // parsing for a number
+ snprintf(val, sizeof(val)-1, "%s", tp);
+ if (val == NULL) {
+ puts("ERROR: 'value' in the format 'id=value' must an integer value.");
+ exit(-1);
+ }
- ast_recordConst(varname, atoi(val));
+ int offset = 0;
+ if (val[0] == '-') {
+ offset = 1;
+ }
+ int valid = 1;
+ for (int idx = offset; idx < strlen(val); idx++) {
+ if ((val[idx] < '0') || (val[idx] > '9')) {
+ valid = 0;
+ break;
+ }
+ }
-
-
- } else {
- puts("ERROR: The option switch '-d' needs a string such as VarName=value.");
- exit(-1);
+ if (!valid) {
+ puts("ERROR: 'value' in the format 'id=value' must an integer value.");
+ exit(-1);
}
- break;
- case 'f':
- i++;
- if (i < argc) {
- fname = argv[i];
- retrieve_flag = 0;
- } else {
- printf("ERROR: The option switch '-f' needs a string of an input file name.");
- exit(-1);
- }
- break;
+ ast_recordConst(varname, atoi(val));
+
+ } else {
+ puts("ERROR: The option switch '-d' needs a string such as VarName=value.");
+ exit(-1);
+ }
+ break;
+
+ case 'f':
+ i++;
+ if (i < argc) {
+ fname = argv[i];
+ retrieve_flag = 0;
+ } else {
+ printf("ERROR: The option switch '-f' needs a string of an input file name.");
+ exit(-1);
+ }
+ break;
#ifndef EXPANDABLE_HEAP
+ case 'c':
// v0.5.6
- case 'c':
- i++;
- if (i < argc) {
- param = atoi(argv[i]);
- if (param == 0) {
- printf("ERROR: '%s' is illegal parameter for -c\n", argv[i]);
- exit(-1);
- }
- } else {
- printf("ERROR: The option switch '-c' needs a number as an argument.");
- exit(-1);
- }
- heap_size=param;
- break;
+ i++;
+ if (i < argc) {
+ param = atoi(argv[i]);
+ if (param == 0) {
+ printf("ERROR: '%s' is illegal parameter for -c\n", argv[i]);
+ exit(-1);
+ }
+ } else {
+ printf("ERROR: The option switch '-c' needs a number as an argument.");
+ exit(-1);
+ }
+ heap_size=param;
+ break;
#endif
- case 'e':
- i++;
- if (i < argc) {
- param = atoi(argv[i]);
- if (param == 0) {
- printf("ERROR: '%s' is illegal parameter for -e\n", argv[i]);
- exit(-1);
- }
- } else {
- printf("ERROR: The option switch '-e' needs a natural number.");
- exit(-1);
- }
- max_EQStack=param;
- break;
+ case 'e':
+ i++;
+ if (i < argc) {
+ param = atoi(argv[i]);
+ if (param == 0) {
+ printf("ERROR: '%s' is illegal parameter for -e\n", argv[i]);
+ exit(-1);
+ }
+ } else {
+ printf("ERROR: The option switch '-e' needs a natural number.");
+ exit(-1);
+ }
+ max_EQStack=param;
+ break;
#ifdef THREAD
- case 't':
- i++;
- if (i < argc) {
- param = atoi(argv[i]);
- if (param == 0) {
- printf("ERROR: '%s' is illegal parameter for -t\n", argv[i]);
- exit(-1);
- }
- } else {
- printf("ERROR: The option switch '-t' needs a number of threads.");
- exit(-1);
- }
-
- MaxThreadsNum=param;
- break;
+ case 't':
+ i++;
+ if (i < argc) {
+ param = atoi(argv[i]);
+ if (param == 0) {
+ printf("ERROR: '%s' is illegal parameter for -t\n", argv[i]);
+ exit(-1);
+ }
+ } else {
+ printf("ERROR: The option switch '-t' needs a number of threads.");
+ exit(-1);
+ }
+
+ MaxThreadsNum=param;
+ break;
#else
- case 'w':
- WHNFinfo.enabled = 1;
- break;
+ case 'w':
+ WHNFinfo.enabled = 1;
+ break;
#endif
- default:
- printf("ERROR: Unrecognized option %s\n", argv[i]);
- printf("Please use -h option for getting more information.\n\n");
- exit(-1);
- }
- } else {
- printf("ERROR: Unrecognized option %s\n", argv[i]);
- printf("Please use -h option for getting more information.\n\n");
- exit(-1);
+ default:
+ printf("ERROR: Unrecognized option %s\n", argv[i]);
+ printf("Use -h option for getting more information.\n\n");
+ exit(-1);
}
+ } else {
+ printf("ERROR: Unrecognized option %s\n", argv[i]);
+ printf("Use -h option for getting more information.\n\n");
+ exit(-1);
}
+ }
- // Dealing with fname
- if (fname == NULL) {
- yyin = stdin;
-
- } else {
- if (!(yyin = fopen(fname, "r"))) {
- printf("Error: The file '%s' can not be opened.\n", fname);
- exit(-1);
- }
+ // Dealing with fname
+ if (fname == NULL) {
+ yyin = stdin;
+
+ } else {
+ if (!(yyin = fopen(fname, "r"))) {
+ printf("Error: The file '%s' can not be opened.\n", fname);
+ exit(-1);
}
+ }
#ifndef THREAD
- if (WHNFinfo.enabled) {
- printf("Inpla %s (Weak Strategy) : Interaction nets as a programming language",
- VERSION);
- printf(" [%s]\n", BUILT_DATE);
- } else {
- printf("Inpla %s : Interaction nets as a programming language",
- VERSION);
- printf(" [built: %s]\n", BUILT_DATE);
- }
+ if (WHNFinfo.enabled) {
+ printf("Inpla %s (Weak Strategy) : Interaction nets as a programming language", VERSION);
+ printf(" [%s]\n", BUILT_DATE);
+ } else {
+ printf("Inpla %s : Interaction nets as a programming language", VERSION);
+ printf(" [built: %s]\n", BUILT_DATE);
+ }
#else
- printf("Inpla %s : Interaction nets as a programming language",
- VERSION);
- printf(" [built: %s]\n", BUILT_DATE);
+ printf("Inpla %s : Interaction nets as a programming language", VERSION);
+ printf(" [built: %s]\n", BUILT_DATE);
#endif
#ifndef EXPANDABLE_HEAP
- // v0.5.6
- heap_size = heap_size/MaxThreadsNum;
+ // v0.5.6
+ heap_size = heap_size/MaxThreadsNum;
#endif
- IdTable_init();
- NameTable_init();
- RuleTable_init();
-
+ IdTable_init();
+ NameTable_init();
+ RuleTable_init();
+ CodeAddr_init();
+
#ifdef THREAD
- GlobalEQStack_Init(MaxThreadsNum*8);
+ GlobalEQStack_Init(MaxThreadsNum*8);
#endif
+
- CmEnv_Init(VM_LOCALVAR_SIZE);
-
#ifdef EXPANDABLE_HEAP
#ifndef THREAD
- VM_Init(&VM, max_EQStack);
+ VM_Init(&VM, max_EQStack);
#else
- tpool_init(max_EQStack);
+ tpool_init(max_EQStack);
#endif
+
#else // ifndef EXPANDABLE_HEAP
- //v0.5.6
+ //v0.5.6
#ifndef THREAD
- VM_Init(&VM, heap_size, max_EQStack);
+ VM_Init(&VM, heap_size, max_EQStack);
#else
- tpool_init(heap_size, max_EQStack);
+ tpool_init(heap_size, max_EQStack);
#endif
+
#endif
+
+
+
+
+#ifdef THREAD
+ // if some threads invoked by the initialise are still working,
+ // wait for all of these to sleep.
+ if (SleepingThreadsNum < MaxThreadsNum) {
+ pthread_mutex_lock(&AllSleep_lock);
+ pthread_cond_wait(&ActiveThread_all_sleep, &AllSleep_lock);
+ pthread_mutex_unlock(&AllSleep_lock);
}
-
+#endif
+
+
linenoiseHistoryLoad(".inpla.history.txt");
+
// the main loop of parsing and execution
while(1) {
@@ -7055,26 +7624,26 @@ int main(int argc, char *argv[])
// When errors occur during parsing
if (yyparse()!=0) {
-
+
if (!retrieve_flag) {
- exit(0);
+ exit(0);
}
-
+
if (yyin != stdin) {
- fclose(yyin);
- while (yyin!=stdin) {
- popFP();
- }
+ fclose(yyin);
+ while (yyin!=stdin) {
+ popFP();
+ }
#ifdef MY_YYLINENO
- InfoLineno_AllDestroy();
+ InfoLineno_AllDestroy();
#endif
}
-
+
}
}
-
+
exit(0);
}
-
+
#include "lex.yy.c"
diff --git a/src/lex.l b/src/lex.l
index 85bf522..aec662b 100644
--- a/src/lex.l
+++ b/src/lex.l
@@ -89,8 +89,13 @@ char *Parse_closeStringBuffer() {
<INITIAL>"=>" return (TO);
<INITIAL>"~" return (CNCT);
<INITIAL>"-" return (SUB);
+<INITIAL>"&&" return(AND);
+<INITIAL>"and" return(AND);
+<INITIAL>"||" return(OR);
+<INITIAL>"or" return(OR);
+<INITIAL>"!" return(NOT);
+<INITIAL>"not" return(NOT);
<INITIAL>"|" return(PIPE);
-<INITIAL>"&" return(AMP);
<INITIAL>"=" return(LD);
<INITIAL>"==" return(EQUAL);
<INITIAL>"!=" return(NE);