diff options
| author | Shinya Sato <shinnya.sato@gmail.com> | 2022-02-09 14:35:55 +0900 |
|---|---|---|
| committer | Shinya Sato <shinnya.sato@gmail.com> | 2022-02-09 14:35:55 +0900 |
| commit | f867b11f97b105ccb563e1157fe480ad63712df0 (patch) | |
| tree | 71e6b93d0d5df6c8fb5c13258b8511e0455a55c2 /src | |
| parent | 224274a8c7d00588ecb2471b425e249e38af90fc (diff) | |
| parent | be334c15c2718a66378666358eaefabbda21bff9 (diff) | |
| download | inpla-f867b11f97b105ccb563e1157fe480ad63712df0.tar.gz inpla-f867b11f97b105ccb563e1157fe480ad63712df0.zip | |
Merge branch 'develop'
Diffstat (limited to 'src')
| -rw-r--r-- | src/id_table.c | 88 | ||||
| -rw-r--r-- | src/id_table.h | 24 | ||||
| -rw-r--r-- | src/inpla.h | 7 | ||||
| -rw-r--r-- | src/inpla.y | 222 | ||||
| -rw-r--r-- | src/name_table.c | 262 | ||||
| -rw-r--r-- | src/name_table.h | 36 |
6 files changed, 345 insertions, 294 deletions
diff --git a/src/id_table.c b/src/id_table.c index f0e006a..e113c8f 100644 --- a/src/id_table.c +++ b/src/id_table.c @@ -1,7 +1,6 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include "ast.h" #include "id_table.h" @@ -19,35 +18,39 @@ void IdTable_init() { // START_IS_OF_AGENT .. NUM_AGENTS-1: user defined agents // NUM_AGENTS(=ID_NAME) .. : names - for (i=0; i<IDTABLE_SIZE; i++) { - IdTable[i].arity = -1; + for (i=0; i<=END_ID_OF_AGENT; i++) { IdTable[i].name = NULL; + IdTable[i].aux.arity = -1; + } + for (i=START_ID_OF_GNAME; i<IDTABLE_SIZE; i++) { + IdTable[i].name = NULL; + IdTable[i].aux.heap = (VALUE)NULL; } // built-in agent - IdTable[ID_TUPLE0].arity = 0; - IdTable[ID_TUPLE1].arity = 1; - IdTable[ID_TUPLE2].arity = 2; - IdTable[ID_TUPLE3].arity = 3; - IdTable[ID_TUPLE4].arity = 4; - IdTable[ID_TUPLE5].arity = 5; - IdTable[ID_NIL].arity = 0; - IdTable[ID_CONS].arity = 2; - IdTable[ID_INTAGENT].arity = 1; - - IdTable[ID_APPEND].arity = 2; - IdTable[ID_MERGER].arity = 1; - IdTable[ID_MERGER_P].arity = 1; - IdTable[ID_ADD].arity = 2; - IdTable[ID_ADD2].arity = 2; - IdTable[ID_SUB].arity = 2; - IdTable[ID_SUB2].arity = 2; - IdTable[ID_MUL].arity = 2; - IdTable[ID_MUL2].arity = 2; - IdTable[ID_DIV].arity = 2; - IdTable[ID_DIV2].arity = 2; - IdTable[ID_MOD].arity = 2; - IdTable[ID_MOD2].arity = 2; + IdTable[ID_TUPLE0].aux.arity = 0; + IdTable[ID_TUPLE1].aux.arity = 1; + IdTable[ID_TUPLE2].aux.arity = 2; + IdTable[ID_TUPLE3].aux.arity = 3; + IdTable[ID_TUPLE4].aux.arity = 4; + IdTable[ID_TUPLE5].aux.arity = 5; + IdTable[ID_NIL].aux.arity = 0; + IdTable[ID_CONS].aux.arity = 2; + IdTable[ID_INTAGENT].aux.arity = 1; + + IdTable[ID_APPEND].aux.arity = 2; + IdTable[ID_MERGER].aux.arity = 1; + IdTable[ID_MERGER_P].aux.arity = 1; + IdTable[ID_ADD].aux.arity = 2; + IdTable[ID_ADD2].aux.arity = 2; + IdTable[ID_SUB].aux.arity = 2; + IdTable[ID_SUB2].aux.arity = 2; + IdTable[ID_MUL].aux.arity = 2; + IdTable[ID_MUL2].aux.arity = 2; + IdTable[ID_DIV].aux.arity = 2; + IdTable[ID_DIV2].aux.arity = 2; + IdTable[ID_MOD].aux.arity = 2; + IdTable[ID_MOD2].aux.arity = 2; IdTable[ID_INT].name = "int"; IdTable[ID_TUPLE0].name = "Tuple0"; @@ -162,29 +165,46 @@ void IdTable_set_name(int id, char *symname) IdTable[id].name = symname; } +char *IdTable_get_name(int id) +{ + return IdTable[id].name; +} + void IdTable_set_arity(int id, int arity) { - if ((IdTable[id].arity == -1) || (IdTable[id].arity == arity)) { - IdTable[id].arity = arity; + if ((IdTable[id].aux.arity == -1) || (IdTable[id].aux.arity == arity)) { + IdTable[id].aux.arity = arity; } else { printf("Warning: The agent '%s' has been already defined as whose arity is %d, but now used as the arity is %d.\n", - IdTable[id].name, IdTable[id].arity, arity); - IdTable[id].arity = arity; + IdTable[id].name, IdTable[id].aux.arity, arity); + IdTable[id].aux.arity = arity; } } +int IdTable_get_arity(int id) +{ + return IdTable[id].aux.arity; +} -char *IdTable_get_name(int id) + +void IdTable_set_heap(int id, VALUE heap) { - return IdTable[id].name; + if (id > IDTABLE_SIZE) { + printf("Error: The given id %d was beyond of the size of IdTable (%d)\n", + id, IDTABLE_SIZE); + exit(-1); + } + IdTable[id].aux.heap = heap; } -int IdTable_get_arity(int id) +VALUE IdTable_get_heap(int id) { - return IdTable[id].arity; + return IdTable[id].aux.heap; } + + int IdTable_new_agentid() { NextAgentId++; if (NextAgentId > ID_NAME) { diff --git a/src/id_table.h b/src/id_table.h index ae97c75..02ac9e6 100644 --- a/src/id_table.h +++ b/src/id_table.h @@ -1,6 +1,7 @@ #ifndef _ID_TABLE_ #define _ID_TABLE_ - +#include "ast.h" +#include "mytype.h" // When NUM_AGENT is 256: // 0 .. 255: AGENT @@ -52,11 +53,11 @@ #define END_ID_OF_AGENT 255 #define NUM_AGENTS END_ID_OF_AGENT+1 // 256 -#define ID_NAME NUM_AGENTS // 256 +#define ID_NAME NUM_AGENTS // starts from 256 (NUM_AGENTS) #define START_ID_OF_GNAME ID_NAME+1 -#define NUM_NAMES NUM_AGENTS // 256 +#define NUM_GNAMES NUM_AGENTS // 256: the same as the size of AGENT //#define IS_AGENTID(a) (a < ID_NAME) @@ -74,16 +75,27 @@ **************************************/ typedef struct { char *name; - int arity; + union { + int arity; + VALUE heap; + } aux; } IdTableT; -#define IDTABLE_SIZE (NUM_AGENTS + NUM_NAMES) // AGENT + NAME + +#define IDTABLE_SIZE (NUM_AGENTS + NUM_GNAMES) // AGENT + GNAME void IdTable_init(); + void IdTable_set_name(int id, char *symname); -void IdTable_set_arity(int id, int arity); char *IdTable_get_name(int id); + +void IdTable_set_arity(int id, int arity); int IdTable_get_arity(int id); + +void IdTable_set_heap(int id, VALUE heap); +VALUE IdTable_get_heap(int id); + + int IdTable_new_agentid(); int IdTable_new_gnameid(); diff --git a/src/inpla.h b/src/inpla.h new file mode 100644 index 0000000..2c3f463 --- /dev/null +++ b/src/inpla.h @@ -0,0 +1,7 @@ +#ifndef _INPLA_ +#define _INPLA_ + +void flush_name_port0(VALUE ptr); +void puts_name_port0(VALUE ptr); + +#endif diff --git a/src/inpla.y b/src/inpla.y index 398d84e..7bf6404 100644 --- a/src/inpla.y +++ b/src/inpla.y @@ -13,7 +13,11 @@ #include "ast.h" #include "id_table.h" #include "name_table.h" +#include "name_table.h" #include "mytype.h" +#include "inpla.h" + + @@ -75,7 +79,7 @@ void freeAgent(VALUE ptr); void puts_names_ast(Ast *ast); void free_names_ast(Ast *ast); -void puts_name_port0_nat(VALUE ptr); +void puts_name_port0_nat(char *sym); void puts_term(VALUE ptr); void puts_aplist(EQList *at); @@ -302,7 +306,7 @@ command: | PRNAT NAME DELIMITER { - puts_name_port0_nat(NameTable_get_heap($2)); + puts_name_port0_nat($2); } | INTERFACE DELIMITER { @@ -1278,7 +1282,13 @@ void puts_names_ast(Ast *ast) { while (param != NULL) { char *sym = param->left->sym; - puts_name_port0(NameTable_get_heap(sym)); + int sym_id = NameTable_get_id(sym); + if (IS_GNAMEID(sym_id)) { + puts_name_port0(IdTable_get_heap(sym_id)); + } else { + puts_name_port0((VALUE)NULL); + } + param = ast_getTail(param); if (param != NULL) printf(" "); @@ -1289,11 +1299,22 @@ void puts_names_ast(Ast *ast) { PutIndirection = preserve; } -void puts_name_port0_nat(VALUE a1) { +//void puts_name_port0_nat(VALUE a1) { +void puts_name_port0_nat(char *sym) { int result=0; int idS, idZ; - idS = NameTable_get_set_id("S"); - idZ = NameTable_get_set_id("Z"); + + int sym_id = NameTable_get_id(sym); + if (!IS_GNAMEID(sym_id)) { + printf("<NOT-DEFINED>\n"); + fflush(stdout); + return; + } + + VALUE a1 = IdTable_get_heap(sym_id); + + idS = NameTable_get_set_id_with_IdTable_forAgent("S"); + idZ = NameTable_get_set_id_with_IdTable_forAgent("Z"); if (a1 == (VALUE)NULL) { printf("<NUll>"); @@ -1317,6 +1338,7 @@ void puts_name_port0_nat(VALUE a1) { } } printf("%d\n", result); + fflush(stdout); } } @@ -1334,12 +1356,6 @@ void puts_eqlist(EQList *at) { } -// ---------------------------------------- -// Flush - - - - /********************************** @@ -1595,9 +1611,10 @@ void freeName(VALUE ptr) { } else { // Global name - NameTable_erase(IdTable_get_name(BASIC(ptr)->id)); - // BASIC(ptr)->id = ID_NAME; - SET_LOCAL_NAMEID(BASIC(ptr)->id); + NameTable_erase_id(IdTable_get_name(BASIC(ptr)->id)); + IdTable_set_heap(BASIC(ptr)->id, (VALUE)NULL); + + SET_LOCAL_NAMEID(BASIC(ptr)->id); // BASIC(ptr)->id = ID_NAME; myfree(ptr); } @@ -1706,9 +1723,12 @@ 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); + int sym_id = NameTable_get_id(param->left->sym); + if (IS_GNAMEID(sym_id)) { + flush_name_port0(IdTable_get_heap(sym_id)); + } else { + flush_name_port0((VALUE)NULL); + } param = ast_getTail(param); } } @@ -1716,15 +1736,6 @@ void free_names_ast(Ast *ast) { -/************************************** - NAME TABLE -**************************************/ -//#include "name_table.h" -// Just include it, because the object file version causes *inefficiency* ! -#include "name_table.c" - - - @@ -2305,21 +2316,33 @@ int CmEnv_check_name_reference_times(void) { void CmEnv_Retrieve_GNAME(void) { - int reg_name; + int local_var; for (int i=0; i<IMCode_n; i++) { if (IMCode[i].opcode != OP_MKNAME) { continue; } - reg_name = IMCode[i].operand1; + local_var = IMCode[i].operand1; for (int j=0; j<CmEnv.bindPtr; j++) { if ((CmEnv.bind[j].type == NB_NAME) && - (CmEnv.bind[j].reg == reg_name) && + (CmEnv.bind[j].reg == local_var) && (CmEnv.bind[j].refnum == 0)) { - IMCode[i].opcode = OP_MKGNAME; - IMCode[i].operand2 = j; + + // ==> OP_MKGNAME id dest + char *sym = CmEnv.bind[j].name; + int sym_id = NameTable_get_id(sym); + if (!IS_GNAMEID(sym_id)) { + // new occurrence + sym_id = IdTable_new_gnameid(); + NameTable_set_id(sym, sym_id); + IdTable_set_name(sym_id, sym); + } + + IMCode[i].opcode = OP_MKGNAME; + IMCode[i].operand2 = IMCode[i].operand1; + IMCode[i].operand1 = sym_id; } } } @@ -2889,19 +2912,18 @@ int CmEnv_generate_VMCode(void **code) { break; } case OP_MKGNAME: { - // printf("OP_MKGNAME var%d sym:%d (as `%s')\n", + // printf("OP_MKGNAME sym:%d var%d (as `%s')\n", // imcode->operand1, imcode->operand2, - // CmEnv.bind[imcode->operand2].name); - int dest = imcode->operand1; + // CmEnv.bind[imcode->operand1].name); + int dest = imcode->operand2; #ifdef OPTIMISE_IMCODE dest = CmEnv_get_newreg(dest); #endif code[addr++] = CodeAddr[imcode->opcode]; + code[addr++] = (void *)(unsigned long)imcode->operand1; code[addr++] = (void *)(unsigned long)dest; - // char* - code[addr++] = CmEnv.bind[imcode->operand2].name; break; } @@ -3781,9 +3803,9 @@ void IMCode_puts(int n) { break; case OP_MKGNAME: - printf("%s var%d sym:%d (as \"%s\")\n", string_opcode[imcode->opcode], + printf("%s id:%d var%d; \"%s\"\n", string_opcode[imcode->opcode], imcode->operand1, imcode->operand2, - CmEnv.bind[imcode->operand2].name); + IdTable_get_name(imcode->operand1)); break; case OP_MKAGENT0: @@ -3992,9 +4014,10 @@ void VMCode_puts(void **code, int n) { i+=1; } else if (code[i] == CodeAddr[OP_MKGNAME]) { - printf("mkgname reg%lu \"%s\"\n", + printf("mkgname id:%lu reg%lu; \"%s\"\n", (unsigned long)code[i+1], - (char *)code[i+2]); + (unsigned long)code[i+2], + IdTable_get_name((unsigned long)code[i+1])); i+=2; } else if (code[i] == CodeAddr[OP_MKAGENT0]) { @@ -4800,7 +4823,7 @@ int CompileTermFromAst(Ast *ptr, int target) { int id = IdTable_getid_builtin_funcAgent(ptr); if (id == -1) { - id = NameTable_get_set_id((char *)ptr->left->sym); + id = NameTable_get_set_id_with_IdTable_forAgent((char *)ptr->left->sym); } arity=0; @@ -4954,12 +4977,12 @@ int check_invalid_occurrence(Ast *ast) { int count; if (ast->id == AST_NAME) { - char *sym = ast->left->sym; + int sym_id = NameTable_get_id(ast->left->sym); - VALUE aheap = NameTable_get_heap(sym); - if (aheap != (VALUE)NULL) { + if (IS_GNAMEID(sym_id)) { // already exists as a global + VALUE aheap = IdTable_get_heap(sym_id); /* // it is connected with something. @@ -4974,7 +4997,7 @@ int check_invalid_occurrence(Ast *ast) { count = keynode_exists_in_another_term(aheap, NULL); if (count == 2) { // already twice - printf("ERROR: '%s' occurs twice already. \n", sym); + printf("ERROR: '%s' occurs twice already. \n", ast->left->sym); printf(" Use 'ifce' command to see the occurrence.\n"); return 1; } @@ -5582,7 +5605,7 @@ int getRuleAgentID(Ast *ruleAgent) { id = IdTable_getid_builtin_funcAgent(ruleAgent); if (id == -1) { - id=NameTable_get_set_id(ruleAgent->left->sym); + id=NameTable_get_set_id_with_IdTable_forAgent(ruleAgent->left->sym); } } @@ -6077,22 +6100,22 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { goto *code[pc]; E_MKGNAME: - // puts("mkgname dest sym"); - - //a1 = makeGlobalName(vm, (char *)code[pc+1]); - - a1 = NameTable_get_heap((char *)code[pc+2]); + // puts("mkgname id dest"); + pc++; + + i = (unsigned long)code[pc++]; + a1 = IdTable_get_heap(i); + // a1 = NameTable_get_heap((char *)code[pc+2]); if (a1 == (VALUE)NULL) { a1 = makeName(vm); // set GID obtained by IdTable_new_gnameid() - i = IdTable_new_gnameid(); - BASIC(a1)->id = i; - NameTable_set_heap_id((char *)code[pc+2], a1, i); + BASIC(a1)->id = i; + IdTable_set_heap(i, a1); + } - reg[(unsigned long)code[pc+1]] = a1; - pc +=3; + reg[(unsigned long)code[pc++]] = a1; goto *code[pc]; @@ -6933,80 +6956,6 @@ void *ExecCode(int mode, VirtualMachine *restrict vm, void *restrict *code) { ******************************************/ #ifndef THREAD -/* 30bit目が 1 ならば、Garbage Collection の Mark&Sweep にて、 - Mark されたことを意味する*/ -#define FLAG_MARKED 0x01 << 30 -#define IS_FLAG_MARKED(a) ((a) & FLAG_MARKED) -#define SET_FLAG_MARKED(a) ((a) = ((a) | FLAG_MARKED)) -#define TOGGLE_FLAG_MARKED(a) ((a) = ((a) ^ FLAG_MARKED)) - - -void markHeapRec(VALUE ptr) { - loop: - if ((ptr == (VALUE)NULL) || (IS_FIXNUM(ptr))) { - return; - } else if (IS_NAMEID(BASIC(ptr)->id)) { - if (ptr == ShowNameHeap) return; - - SET_FLAG_MARKED(BASIC(ptr)->id); - if (NAME(ptr)->port != (VALUE)NULL) { - ptr = NAME(ptr)->port; - goto loop; - } - } else { - if (BASIC(ptr)->id == ID_CONS) { - if (IS_FIXNUM(AGENT(ptr)->port[0])) { - SET_FLAG_MARKED(BASIC(ptr)->id); - ptr = AGENT(ptr)->port[1]; - goto loop; - } - } - - int arity = IdTable_get_arity(BASIC(ptr)->id); - SET_FLAG_MARKED(BASIC(ptr)->id); - if (arity == 1) { - ptr = AGENT(ptr)->port[0]; - goto loop; - } else { // it also contains the case that arity = 0. - int i; - for(i=0; i<arity; i++) { - markHeapRec(AGENT(ptr)->port[i]); - } - } - } -} - - -void mark_name_port0(VALUE ptr) { - if (ptr != (VALUE)NULL) { - - SET_FLAG_MARKED(BASIC(ptr)->id); - if (NAME(ptr)->port != (VALUE)NULL) { - ShowNameHeap=ptr; - markHeapRec(NAME(ptr)->port); - ShowNameHeap=(VALUE)NULL; - } - } -} - - -void mark_allHash(void) { - int i; - NameList *at; - - for (i=0; i<NAME_HASHSIZE; i++) { - at = NameHashTable[i]; - while (at != NULL) { - if (at->heap != (VALUE)NULL) { - if (IS_NAMEID(BASIC(at->heap)->id)) { - mark_name_port0(at->heap); - } - } - at = at->next; - } - } -} - #ifdef EXPANDABLE_HEAP void sweep_AgentHeap(Heap *hp) { @@ -7832,11 +7781,11 @@ loop_a2IsAgent: void select_kind_of_push(Ast *ast, int p1, int p2) { - char *sym = ast->left->sym; - VALUE aheap = NameTable_get_heap(sym); + int sym_id = NameTable_get_id(ast->left->sym); - if (aheap != (VALUE)NULL) { + if (IS_GNAMEID(sym_id)) { // aheap already exists as a global + VALUE aheap = IdTable_get_heap(sym_id); // aheap is connected with something such as aheap->t // ==> p2 should be conncected with t, so OP_CNCTGN(p1,p2) @@ -7992,11 +7941,11 @@ int exec(Ast *at) { return 0; } - + CmEnv_Retrieve_GNAME(); CmEnv_generate_VMCode(code); - + /* // for debug CmEnv_Retrieve_GNAME(); @@ -8006,7 +7955,6 @@ int exec(Ast *at) { VMCode_puts(code, codenum-2); //exit(1); // end for debug */ - #ifdef COUNT_MKAGENT diff --git a/src/name_table.c b/src/name_table.c index b6ed9a1..06ff955 100644 --- a/src/name_table.c +++ b/src/name_table.c @@ -51,73 +51,9 @@ int getHash(char *key) -void NameTable_set_heap_id(char *key, VALUE heap, IDTYPE id) { - // Set (id, heap) for the key in the name table. - - int hash; - NameList *add; - hash = getHash(key); - - if (NameHashTable[hash] == NULL) { - // When the linear list of the hash table is EMPTY - - // Make a new linear list - add = NameList_new(); - - // Set (id, heap) for the key - add->name = key; - add->id = id; - IdTable_set_name(id, key); - add->heap = heap; - add->next = NULL; - - // Store the liner list to the hash table - NameHashTable[hash] = add; - return; - } - // linear search for the key - NameList *at = NameHashTable[hash]; - - while (at != NULL) { - - if (strcmp(at->name, key) == 0) { - // already exists - - // set (id, heap) for the key - at->id = id; - IdTable_set_name(at->id, key); - at->heap = heap; - return; - - } - at = at->next; - } - - - // The case of no entries - - // Make a new linear list - add = NameList_new(); - - // Set (id, heap) for the key - add->name = key; - add->id = id; - IdTable_set_name(add->id, key); - add->heap = heap; - - // Change the first element of the hash table into me. - add->next = NameHashTable[hash]; - NameHashTable[hash] = add; - - return; -} - - - - -void NameTable_erase(char *key) { +void NameTable_erase_id(char *key) { // Delete the entry for the key int hash; @@ -140,17 +76,7 @@ void NameTable_erase(char *key) { if (strcmp(at->name, key) == 0) { // already exists - // No need to be freed - // because it stores just a pointer to the heap, - // and this function is expected to remove only the information. - at->heap = (VALUE)NULL; - //at->id = -1; // id stores -1 for the deleted condition. - // It is not mandatory, - // but 10% less performance causes - // if we omit this. WHY? - // 2021-10-06: it was not caused, - // so it was commented out. - + at->id = -1; return; } @@ -162,32 +88,32 @@ void NameTable_erase(char *key) { -VALUE NameTable_get_heap(char *key) { +int NameTable_get_id(char *key) { int hash; hash = getHash(key); if (NameHashTable[hash] == NULL) { - return (VALUE)NULL; + return -1; } NameList *at = NameHashTable[hash]; while (at != NULL) { if (strcmp(at->name, key) == 0) { // already exists - return at->heap; + return at->id; } at = at->next; } // There is no entry for the key - return (VALUE)NULL; + return -1; } -IDTYPE NameTable_get_set_id(char *key) { +IDTYPE NameTable_get_set_id_with_IdTable_forAgent(char *key) { int hash; NameList *add; @@ -200,7 +126,6 @@ IDTYPE NameTable_get_set_id(char *key) { add->name = key; add->id = IdTable_new_agentid(); IdTable_set_name(add->id, add->name); - add->heap = (VALUE)NULL; add->next = NULL; NameHashTable[hash] = add; return (add->id); @@ -221,7 +146,6 @@ IDTYPE NameTable_get_set_id(char *key) { add->name = key; add->id = IdTable_new_agentid(); IdTable_set_name(add->id, add->name); - add->heap = (VALUE)NULL; add->next = NameHashTable[hash]; NameHashTable[hash] = add; @@ -231,6 +155,47 @@ IDTYPE NameTable_get_set_id(char *key) { +void NameTable_set_id(char *key, IDTYPE id) { + int hash; + NameList *add; + + + hash = getHash(key); + + if (NameHashTable[hash] == NULL) { + + add = NameList_new(); + add->name = key; + add->id = id; + add->next = NULL; + NameHashTable[hash] = add; + return; + + } + + NameList *at = NameHashTable[hash]; + while (at != NULL) { + if (strcmp(at->name, key) == 0) { + at->id = id; + return; + + } + at = at->next; + } + + + add = NameList_new(); + add->name = key; + add->id = id; + + add->next = NameHashTable[hash]; + NameHashTable[hash] = add; + + return; +} + + + @@ -282,12 +247,13 @@ int keynode_exists_in_another_term(VALUE keynode, VALUE *connected_from) { for (i=0; i<NAME_HASHSIZE; i++) { at = NameHashTable[i]; while (at != NULL) { - if (at->heap != (VALUE)NULL) { - if (at->heap != keynode) { - if (term_has_keynode(keynode, at->heap)) { + if (IS_GNAMEID(at->id)) { + VALUE heap = IdTable_get_heap(at->id); + if (heap != keynode) { + if (term_has_keynode(keynode, heap)) { result++; if (connected_from != NULL) { - *connected_from = at->heap; + *connected_from = heap; } /* PutIndirection=1; @@ -348,14 +314,19 @@ void global_replace_keynode_in_another_term(VALUE keynode, VALUE term) { for (i=0; i<NAME_HASHSIZE; i++) { at = NameHashTable[i]; while (at != NULL) { - if (at->heap != (VALUE)NULL) { - if (at->heap != keynode) { + if (IS_GNAMEID(at->id)) { + VALUE heap = IdTable_get_heap(at->id); + + if (heap != keynode) { - if (term_has_keynode(keynode, at->heap)) { + if (term_has_keynode(keynode, heap)) { + + // replaced <- heap[term/keynode] + VALUE replaced = replace_keynode(keynode, term, heap); + IdTable_set_heap(at->id, replaced); + + //freeName(keynode); <-- this is called at the calling function. - VALUE replaced = replace_keynode(keynode, term, at->heap); - at->heap = replaced; - return; } } @@ -376,9 +347,10 @@ void NameTable_puts_all() { for (i=0; i<NAME_HASHSIZE; i++) { at = NameHashTable[i]; while (at != NULL) { - if (at->heap != (VALUE)NULL) { - if (IS_NAMEID(BASIC(at->heap)->id)) { - printf("%s ", IdTable_get_name(BASIC(at->heap)->id)); + if (IS_GNAMEID(at->id)) { + VALUE heap = IdTable_get_heap(at->id); + if (IS_NAMEID(BASIC(heap)->id)) { + printf("%s ", IdTable_get_name(BASIC(heap)->id)); count++; } } @@ -395,10 +367,11 @@ void NameTable_puts_all() { for (i=0; i<NAME_HASHSIZE; i++) { at = NameHashTable[i]; while (at != NULL) { - if (at->heap != (VALUE)NULL) { - if (IS_NAMEID(BASIC(at->heap)->id)) { - printf("%s ->", IdTable_get_name(BASIC(at->heap)->id)); - puts_name_port0(at->heap); + if (IS_GNAMEID(at->id)) { + VALUE heap = IdTable_get_heap(at->id); + if (IS_NAMEID(BASIC(heap)->id)) { + printf("%s ->", IdTable_get_name(BASIC(heap)->id)); + puts_name_port0(heap); printf("\n"); } } @@ -416,9 +389,10 @@ void NameTable_free_all() { for (i=0; i<NAME_HASHSIZE; i++) { at = NameHashTable[i]; while (at != NULL) { - if (at->heap != (VALUE)NULL) { - if (IS_NAMEID(BASIC(at->heap)->id)) { - flush_name_port0(at->heap); + if (IS_GNAMEID(at->id)) { + VALUE heap = IdTable_get_heap(at->id); + if (IS_NAMEID(BASIC(heap)->id)) { + flush_name_port0(heap); } } at = at->next; @@ -430,13 +404,13 @@ void NameTable_free_all() { int NameTable_check_if_term_has_gname(VALUE term) { int i; NameList *at; - VALUE ptr; for (i=0; i<NAME_HASHSIZE; i++) { at = NameHashTable[i]; while (at != NULL) { - if (at->heap != (VALUE)NULL) { - ptr = at->heap; + if (IS_GNAMEID(at->id)) { + VALUE ptr = IdTable_get_heap(at->id); + while ((ptr != (VALUE)NULL) && (! IS_FIXNUM(ptr)) && (IS_NAMEID(BASIC(ptr)->id))) { @@ -458,3 +432,79 @@ int NameTable_check_if_term_has_gname(VALUE term) { return 0; } + + +/****************************************** + Mark and Sweep for error recovery +******************************************/ +#ifndef THREAD +static VALUE CyclicNameHeap=(VALUE)NULL; + +void markHeapRec(VALUE ptr) { + loop: + if ((ptr == (VALUE)NULL) || (IS_FIXNUM(ptr))) { + return; + } else if (IS_NAMEID(BASIC(ptr)->id)) { + if (ptr == CyclicNameHeap) return; + + SET_FLAG_MARKED(BASIC(ptr)->id); + if (NAME(ptr)->port != (VALUE)NULL) { + ptr = NAME(ptr)->port; + goto loop; + } + } else { + if (BASIC(ptr)->id == ID_CONS) { + if (IS_FIXNUM(AGENT(ptr)->port[0])) { + SET_FLAG_MARKED(BASIC(ptr)->id); + ptr = AGENT(ptr)->port[1]; + goto loop; + } + } + + int arity = IdTable_get_arity(BASIC(ptr)->id); + SET_FLAG_MARKED(BASIC(ptr)->id); + if (arity == 1) { + ptr = AGENT(ptr)->port[0]; + goto loop; + } else { // it also contains the case that arity = 0. + int i; + for(i=0; i<arity; i++) { + markHeapRec(AGENT(ptr)->port[i]); + } + } + } +} + + +void mark_name_port0(VALUE ptr) { + if (ptr != (VALUE)NULL) { + + SET_FLAG_MARKED(BASIC(ptr)->id); + if (NAME(ptr)->port != (VALUE)NULL) { + CyclicNameHeap=ptr; + markHeapRec(NAME(ptr)->port); + CyclicNameHeap=(VALUE)NULL; + } + } +} + + +void mark_allHash(void) { + int i; + NameList *at; + + for (i=0; i<NAME_HASHSIZE; i++) { + at = NameHashTable[i]; + while (at != NULL) { + if (IS_GNAMEID(at->id)) { + VALUE heap = IdTable_get_heap(at->id); + + if (IS_NAMEID(BASIC(heap)->id)) { + mark_name_port0(heap); + } + } + at = at->next; + } + } +} +#endif diff --git a/src/name_table.h b/src/name_table.h index 4bc1361..70d71cc 100644 --- a/src/name_table.h +++ b/src/name_table.h @@ -3,7 +3,7 @@ #include "mytype.h" #include "id_table.h" - +#include "inpla.h" /************************************** NAME TABLE @@ -15,13 +15,9 @@ typedef struct NameList { - char *name; // KEY - IDTYPE id; + char *name; // KEY + int id; // -1: no entry - // `heap' stores a heap only of a global name, - // that is, is kept having NULL for other nodes, such as agents. - VALUE heap; - struct NameList *next; } NameList; @@ -35,12 +31,16 @@ void NameTable_init(); void NameTable_set_heap_id(char *key, VALUE heap, IDTYPE id); -// Erace key entry from NameHashTable -void NameTable_erase(char *key); +// Set id at key entry to -1 +void NameTable_erase_id(char *key); + + +int NameTable_get_id(char *key); +void NameTable_set_id(char *key, IDTYPE id); -VALUE NameTable_get_heap(char *key); -IDTYPE NameTable_get_set_id(char *key); +IDTYPE NameTable_get_set_id_with_IdTable_forAgent(char *key); + void NameTable_puts_all(); void NameTable_free_all(); @@ -52,4 +52,18 @@ int keynode_exists_in_another_term(VALUE keynode, VALUE *connected_from); void global_replace_keynode_in_another_term(VALUE keynode, VALUE term); +#ifndef THREAD +// Mark and Sweep for error recovery + +/* 30bit目が 1 ならば、Garbage Collection の Mark&Sweep にて、 + Mark されたことを意味する*/ +#define FLAG_MARKED 0x01 << 30 +#define IS_FLAG_MARKED(a) ((a) & FLAG_MARKED) +#define SET_FLAG_MARKED(a) ((a) = ((a) | FLAG_MARKED)) +#define TOGGLE_FLAG_MARKED(a) ((a) = ((a) ^ FLAG_MARKED)) + +void mark_allHash(void); +#endif + + #endif |
