diff options
| author | Shinya Sato <shinnya.sato@gmail.com> | 2022-02-09 14:35:38 +0900 |
|---|---|---|
| committer | Shinya Sato <shinnya.sato@gmail.com> | 2022-02-09 14:35:38 +0900 |
| commit | be334c15c2718a66378666358eaefabbda21bff9 (patch) | |
| tree | 71e6b93d0d5df6c8fb5c13258b8511e0455a55c2 | |
| parent | 03d7d92b4c401b553bc64da535b0621da67f6cc4 (diff) | |
| download | inpla-be334c15c2718a66378666358eaefabbda21bff9.tar.gz inpla-be334c15c2718a66378666358eaefabbda21bff9.zip | |
v0.7.2
| -rw-r--r-- | Changelog.md | 98 | ||||
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | README.md | 20 | ||||
| -rw-r--r-- | pic/benchmark_reuse_v0.7.1.png | bin | 29877 -> 0 bytes | |||
| -rw-r--r-- | pic/benchmark_reuse_v0.7.2.png | bin | 0 -> 30094 bytes | |||
| -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 |
11 files changed, 402 insertions, 357 deletions
diff --git a/Changelog.md b/Changelog.md index bc5b110..d51beb0 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,28 +1,32 @@ # Change log -### v0.7.1 (released on 4 February 2022) +### v0.7.2 (released on 9 February 2022) #### Polished: +- **Bytecodes for global names**: To obtain a global name whose name is `sym` on a `dest` register, the following bytecode is executed: `MKGNAME dest sym` where the type of `sym` is `char*`. Every symbol for agents and global names is assigned to the unique ID number managed by `IdTable`, so by introducing the ID number `id` for the `sym`, the bytecode is changed into `MKGNAME id dest`. +- **Separation of source codes of NameTable**: The `NameTable` is used to lookup ID numbers for symbol chars in compilation and interpreter execution. By changing the bytecode of `MKGNAME`, there becomes no need to be used in virtual machine execution directly, so the source codes for the `NameTable` is separated from `src/inpla.y`. This contributes quite a little speed-up at most 1%. + -- **Bytecodes**: Bytecodes of virtual machines are expressed by three address codes ordered as `op dest src1 src2`. The order is changed to the ordinary one `op src1 src2 dest`. -- **Bytecode optimisation**: The following is introduced: +### v0.7.1 (released on 4 February 2022) +#### Polished: +* **Bytecodes**: Bytecodes of virtual machines are expressed by three address codes ordered as `op dest src1 src2`. The order is changed to the ordinary one `op src1 src2 dest`. + +* **Bytecode optimisation**: The following is introduced: - A sequence `OP_EQI_RO reg` `OP_JMPEQ0_R0 pc` is optimised into a code `JMPNEQ0 reg pc`. - By introducing a bytecode `OP_INC src dest`, a code `OP_ADDI src $1 dest` and a code`OP_ADDI $1 src dest` are optimised into `OP_INC src dest`. - By introducing a bytecode `OP_DEC src dest`, a code `OP_SUBI src $1 dest` is optimised into `OP_DEC src dest`. -- **Intermediate code for blocks**: To show areas of blocks, an intermediate code `OP_BEGIN_BLOCK` is introduced. Copy Propagation for `OP_LOAD` and `OP_LOADI` is performed until the next `OP_BEGIN_BLOCK` occurs. +* **Intermediate code for blocks**: To show areas of blocks, an intermediate code `OP_BEGIN_BLOCK` is introduced. Copy Propagation for `OP_LOAD` and `OP_LOADI` is performed until the next `OP_BEGIN_BLOCK` occurs. ### v0.7.0 (released on 30 January 2022) - #### New Features: +* **Logical operators on integers**: Not `!` (`not`), And `&&` (`and`) and Or `||` (`or`) are available. Only `0` is regarded as False and these operators return `1` for Truth, `0` for False. -- **Logical operators on integers**: Not `!` (`not`), And `&&` (`and`) and Or `||` (`or`) are available. Only `0` is regarded as False and these operators return `1` for Truth, `0` for False. - -- **Bytecode optimisations**: Bytecodes are optimised by Copy propagation, Dead code elimination methods. In addition, Register0 is used to store comparison results, and conditional branches are performed according to the value of Register0. To prevent those optimisation, comment out the following definition `OPTIMISE_IMCODE` in `src/inpla.y`: +* **Bytecode optimisations**: Bytecodes are optimised by Copy propagation, Dead code elimination methods. In addition, Register0 is used to store comparison results, and conditional branches are performed according to the value of Register0. To prevent those optimisation, comment out the following definition `OPTIMISE_IMCODE` in `src/inpla.y`: ``` #define OPTIMISE_IMCODE // Optimise the intermediate codes @@ -30,12 +34,9 @@ - - ### v0.6.2 (released on 20 January 2022) - #### New Features: -- **Retaining the big ring buffer**: The new expandable buffer for agents and names require extra costs sometimes, so the old one, that is the big ring buffer, is embedded into programs sources. Comment out the following definition `EXPANDABLE_HEAP` in `src/inpla.y` when the old one is needed: +* **Retaining the big ring buffer**: The new expandable buffer for agents and names require extra costs sometimes, so the old one, that is the big ring buffer, is embedded into programs sources. Comment out the following definition `EXPANDABLE_HEAP` in `src/inpla.y` when the old one is needed: ``` #define EXPANDABLE_HEAP // Expandable heaps for agents and names @@ -45,9 +46,8 @@ ### 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 `-e`. For instance, Inpla invoked with `-e 1024` assigns a 1024-size equation stack for each thread. As for the global equation stack, it is also automatically expandable, but the initial size is specified as `(the number of threads) * 8` in the `main` function as follows, so change it to improve the execution performance if it is needed: +* **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 `-e`. For instance, Inpla invoked with `-e 1024` assigns a 1024-size equation stack for each thread. As for the global equation stack, it is also automatically expandable, but the initial size is specified as `(the number of threads) * 8` in the `main` function as follows, so change it to improve the execution performance if it is needed: ``` GlobalEQStack_Init(MaxThreadsNum*8); @@ -59,64 +59,66 @@ ### 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. ### v0.5.6 (released on 6 January 2022) - #### Bug Fix: +* The index of the ring buffer for agents had not been correctly initialised. It was fixed the same as the way of the ring buffer for names. -- The index of the ring buffer for agents had not been correctly initialised. It was fixed the same as the way of the ring buffer for names. ### Logo of Inpla (released on 27 December 2021) - -- A logo is released as an idea: +* A logo is released as an idea:  -### v0.5.5 (released on 19 December 2021) + +### v0.5.5 (released on 19 December 2021) #### Bug Fix (minor): +* The name `x` in a connection `x~s` should be substituted if the `x` occurs on a term in other connections, but it should be done if the `x` is specified by `int` modification. But every name had been a target of the substitution, so it was fixed. + -- The name `x` in a connection `x~s` should be substituted if the `x` occurs on a term in other connections, but it should be done if the `x` is specified by `int` modification. But every name had been a target of the substitution, so it was fixed. ### v0.5.4 (released on 18 November 2021) #### Bug Fix (minor): +* When there is a connection `x~s` in nets or rules, the other occurrence of the name `x` will be replaced with the `s`, as one of optimisations. It had been done only when the other is just a name, that is, not a subterm, so it was fixed now. + -- When there is a connection `x~s` in nets or rules, the other occurrence of the name `x` will be replaced with the `s`, as one of optimisations. It had been done only when the other is just a name, that is, not a subterm, so it was fixed now. ### v0.5.3 (released on 14 November 2021) #### New Features (for constants): -- Constants are also specified by an execution option switch `-d` in the format *NAME*=*i*. For instance, when Inpla is invoked with `-d ELEM=1000`, then the `ELEM` is replaced with `1000` during the execution. +* Constants are also specified by an execution option switch `-d` in the format *NAME*=*i*. For instance, when Inpla is invoked with `-d ELEM=1000`, then the `ELEM` is replaced with `1000` during the execution. + +* Constants are defined as immutable, so these values cannot be changed. When a file specified by the `-f` option has constant names specified by the `-d` options, these names are bound to the values given by the `-d` options. -- Constants are defined as immutable, so these values cannot be changed. When a file specified by the `-f` option has constant names specified by the `-d` options, these names are bound to the values given by the `-d` options. - ### v0.5.2 (released on 10 November 2021) #### Bug Fix (minor): -- `Free` command did not work for integer numbers, due to the change by v0.5.1, and it was fixed. +* `Free` command did not work for integer numbers, due to the change by v0.5.1, and it was fixed. + ### v0.5.1 (released on 2 November 2021) #### Bug Fix: -- Terms in which the same name occurs twice, such as `A(x,x)`, can be freed safely by the `free` command. +* Terms in which the same name occurs twice, such as `A(x,x)`, can be freed safely by the `free` command. ### v0.5.0 (released on 28 October 2021) #### New Features: -- **Abbreviation notation**: An abbreviation notation `<<` is introduced. The following description: +* **Abbreviation notation**: An abbreviation notation `<<` is introduced. The following description: ``` a,b,...,z << Agent(aa,bb,...,yy,zz) @@ -134,7 +136,7 @@ ret << Append(a,b) --- rewritten as ---> Append(ret,b)~a ``` -- **Merger agent that merges two lists into one**: Merger agent is implemented, such that it has two principal ports for the two lists, and whose interactions are performed as soon as one of the principal ports is ready for the interaction, that is to say, connected to a list. So, the merged result is decided non-deterministically, especially in multi-threaded execution. +* **Merger agent that merges two lists into one**: Merger agent is implemented, such that it has two principal ports for the two lists, and whose interactions are performed as soon as one of the principal ports is ready for the interaction, that is to say, connected to a list. So, the merged result is decided non-deterministically, especially in multi-threaded execution.  @@ -144,7 +146,7 @@ ret << Merger(alist, blist) ``` -- **Built-in rules for arithmetic operations between two agents**: These are implemented, and these operations are managed agents `Sub`, `Mul`, `Div`, `Mod`: +* **Built-in rules for arithmetic operations between two agents**: These are implemented, and these operations are managed agents `Sub`, `Mul`, `Div`, `Mod`: ``` >>> r1 << Add(3,5), r2 << Sub(r1,2); @@ -160,33 +162,29 @@ ### v0.4.2 (released on 16 October 2021) #### Improved: - - Line edit was improved to support multi-line paste, according to the following suggestion: https://github.com/antirez/linenoise/issues/43 - - History in Line edit becomes available. +* Line edit was improved to support multi-line paste, according to the following suggestion: https://github.com/antirez/linenoise/issues/43 +* History in Line edit becomes available. #### Bug Fix: - - Long length lists are printed out as abbreviation of 14-length lists. +* Long length lists are printed out as abbreviation of 14-length lists. ### v0.4.1 (released on 24 September 2021) #### Improved: - -- Line edit is improved so that history can be handled by linenoise: +* Line edit is improved so that history can be handled by linenoise: https://github.com/antirez/linenoise -- The priority of rules are changed so that user defined rules can be taken before built-in rules. +* The priority of rules are changed so that user defined rules can be taken before built-in rules. #### Bug Fix: - -- Constants, which cannot be deleted, had been deleted when they are referred to. It was fixed to be kept. +* Constants, which cannot be deleted, had been deleted when they are referred to. It was fixed to be kept. ### v0.4.0 (released on 17 September 2021) - #### New Features: - -- Nested guards are supported. As shown in below, nested guards are supported now: +* Nested guards are supported. As shown in below, nested guards are supported now: ``` A(r)><B(int a, int b) @@ -198,10 +196,10 @@ | _ => r~100; ``` -- Strings that have brackets, such as `inc(x)`, are recognised as agents even if these starts from a not capital letter. +* Strings that have brackets, such as `inc(x)`, are recognised as agents even if these starts from a not capital letter. -- Built-in rules that match each element for the same built-in agents are implemented. For instance, the following rules are realised as built-in: +* Built-in rules that match each element for the same built-in agents are implemented. For instance, the following rules are realised as built-in: ``` a:b >< x:y => a~x, b~y; @@ -212,10 +210,8 @@ ### v0.3.2 (released on 3 August 2021) - #### New Features: - -- WHNF strategy is supported with -w option. Weak Head Normal Form strategy is available when the Inpla is invoked with -w option. The following is an execution log: +* WHNF strategy is supported with -w option. Weak Head Normal Form strategy is available when the Inpla is invoked with -w option. The following is an execution log: ``` $ ./inpla -w @@ -240,10 +236,8 @@ ### v0.3.1 (released on 7 May 2021) - #### New Features: - -- New notation for the built-in `Cons` agent, `h:t`. The built-in Cons agent is also written as `h:t`, besides `[h|t]`. For instance, a reverse list operation is written as follows: +* New notation for the built-in `Cons` agent, `h:t`. The built-in Cons agent is also written as `h:t`, besides `[h|t]`. For instance, a reverse list operation is written as follows: ``` Rev(ret, acc) >< [] => ret ~ acc; @@ -253,7 +247,7 @@ ret; // -> [8,5,3,1] ``` -- The built-in agent for integer numbers is introduced. Integer numbers are recognised as agents. In addition: +* The built-in agent for integer numbers is introduced. Integer numbers are recognised as agents. In addition: - expressions on attributes are written as agents. - `Add(ret, m)><(int n)` is implemented as a built-in rule. @@ -281,7 +275,7 @@ r; // it should be 7 ``` -- Append for two lists is implemented as built-in as follows: +* Append for two lists is implemented as built-in as follows: ``` Append(r,[1,2,3])~[7,8,9]; @@ -6,7 +6,7 @@ INCLUDE = -I ./src SRC_DIR = ./src OBJ_DIR = ./build TARGET = inpla -OBJS = $(OBJ_DIR)/inpla.tab.c $(OBJ_DIR)/ast.o $(OBJ_DIR)/id_table.o $(OBJ_DIR)/linenoise.o +OBJS = $(OBJ_DIR)/inpla.tab.c $(OBJ_DIR)/ast.o $(OBJ_DIR)/id_table.o $(OBJ_DIR)/name_table.o $(OBJ_DIR)/linenoise.o #MYOPTION = -DHAND_FIB -DHAND_FIB_INT -DHAND_I_CONS -DHAND_IS_CONS -DHAND_Apnd_CONS -DHAND_Part_CONS -DHAND_Split_CONS -DHAND_MergeCC_CONS -DHAND_B_CONS -DHAND_DUP_S -DHAND_ADD_S -DHAND_ACK_S #MYOPTION = -DHAND_Split_CONS -DHAND_MergeCC_CONS @@ -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.7.1 released on **4 February 2022**. (See [Changelog.md](Changelog.md) for details.) +* The current version is 0.7.2 released on **9 February 2022**. (See [Changelog.md](Changelog.md) for details.) - + -| | Haskell | SML | Python | Inpla1 | Inpla1_r | Inpla7 | Inpla7_r | +| | Haskell | SML | Python | Inpla1 | Inpla1_r | Inpla8 | Inpla8_r | | -------------- | :------: | :------: | :----: | :----: | :------: | :----: | :------: | -| ack(3,11) | 2.31 | **0.41** | - | 4.78 | 3.55 | 1.51 | 0.74 | -| fib 38 | 1.60 | **0.26** | 8.49 | 3.10 | 2.95 | 0.60 | 0.50 | -| bsort 40000 | 34.81 | 11.17 | 76.72 | 24.85 | 18.22 | 7.39 | **2.92** | -| isort 40000 | **0.02** | 2.97 | 36.63 | 11.85 | 8.71 | 3.65 | 1.41 | -| qsort 800000 | **0.15** | 1.16 | 97.30 | 3.54 | 1.88 | 0.83 | 0.34 | -| msort 800000 | 0.46 | 1.00 | 98.27 | 2.26 | 1.32 | 0.60 | **0.33** | +| ack(3,11) | 2.31 | **0.41** | - | 4.79 | 3.48 | 1.53 | 0.70 | +| fib 38 | 1.60 | **0.26** | 8.49 | 3.04 | 2.89 | 0.60 | 0.46 | +| bsort 40000 | 34.81 | 11.17 | 76.72 | 24.37 | 17.10 | 7.39 | **2.50** | +| isort 40000 | **0.02** | 2.97 | 36.63 | 11.74 | 8.31 | 3.65 | 1.23 | +| qsort 800000 | **0.15** | 1.16 | 97.30 | 3.41 | 1.79 | 0.81 | 0.33 | +| msort 800000 | 0.46 | 1.00 | 98.27 | 2.23 | 1.31 | 0.60 | **0.33** | - **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. @@ -96,7 +96,7 @@ Inpla is a multi-threaded parallel interpreter of interaction nets. Once you wri ``` ### Interactive mode (multi-thread version) -* There is an execution option `-t` that specifies the number of threads in a thread pool. For instance, by invoking with `-t 4` Inpla populates 4 threads in the thread pool: +* There is an execution option `-t` that specifies the number of threads in a thread pool. For instance, by invoking with `-t 4` Inpla populates 4 threads in the pool: ``` $ ./inpla -t 4 diff --git a/pic/benchmark_reuse_v0.7.1.png b/pic/benchmark_reuse_v0.7.1.png Binary files differdeleted file mode 100644 index a2d9672..0000000 --- a/pic/benchmark_reuse_v0.7.1.png +++ /dev/null diff --git a/pic/benchmark_reuse_v0.7.2.png b/pic/benchmark_reuse_v0.7.2.png Binary files differnew file mode 100644 index 0000000..ed7bf2c --- /dev/null +++ b/pic/benchmark_reuse_v0.7.2.png 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 |
