diff options
| -rw-r--r-- | Changelog.md | 125 | ||||
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | src/ast.c | 4 | ||||
| -rw-r--r-- | src/ast.h | 5 | ||||
| -rw-r--r-- | src/config.h | 31 | ||||
| -rw-r--r-- | src/id_table.h | 4 | ||||
| -rw-r--r-- | src/inpla.h | 4 | ||||
| -rw-r--r-- | src/inpla.y | 286 | ||||
| -rw-r--r-- | src/mytype.h | 4 | ||||
| -rw-r--r-- | src/name_table.h | 4 | ||||
| -rw-r--r-- | src/timer.h | 4 | ||||
| -rw-r--r-- | src/unlikely.h | 8 |
12 files changed, 380 insertions, 101 deletions
diff --git a/Changelog.md b/Changelog.md index a9c7d5c..d4366d7 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,12 +1,131 @@ # Change log +### v0.13.3 (released on 24 March 2026) +#### Bug fix + +- **Fixed a bug in the arity check function for rule agents**: Previously, rule definitions allowed rule agents to exceed the maximum number of ports defined by `MAX_PORT`. This caused Inpla to output a confusing error message, such as the following (where `MAX_PORT` is 5): + + ``` + >>> A(a,b,c,d,e,f) >< Z => a~Z, b~Z, c~Z, d~Z, e~Z, f~Z; + 1:ERROR: `f' is referred not twice in the right-hand side of the rule: + A >< Z + ``` + + Now, it has been fixed by checking the arity correctly: + + ``` + Inpla 0.13.2-1 : Interaction nets as a programming language [built: 16 March 2026] + >>> A(a,b,c,d,e,f) >< Z => a~Z, b~Z, c~Z, d~Z, e~Z, f~Z; + 1:ERROR: The rule agent `A' has too many arguments. It should be MAX_PORT(=5) or less. + ``` + +#### Polished +- **The compilation method for nested agents has been changed**: Following the bottom-up compilation approach introduced for lists in v0.13.2, the compilation order for general nested agents (e.g., `S(S(Z))`) has also been inverted to prevent register exhaustion. Previously, nested agents were compiled top-down: + + ``` + compile(S(S(Z))) + + --> MKAGENT ID_S reg13 + compile(S(Z), reg14) + LOADP reg14, 0, reg13 + + --> MKAGENT ID_S reg13 + MKAGENT ID_S reg14 + compile(Z, reg15) + LOADP reg15, 0, reg14 + LOADP reg14, 0, reg13 + + --> MKAGENT ID_S reg13 + MKAGENT ID_S reg14 + MKAGENT ID_Z reg15 + LOADP reg15, 0, reg14 + LOADP reg14, 0, reg13 + + == MKAGENT ID_S reg13 + MKAGENT ID_S reg14 + MKAGENT ID_Z reg15 + LOADP reg15, 0, reg14 // reg15 can be freed + LOADP reg14, 0, reg13 // reg14 can be freed + // thus reg13 must be kept + ``` + + In this old approach, the register for the outermost agent (`reg13`) had to be kept alive until all inner agents were compiled. To solve this, the compilation order has been changed to compile the inner agents first (bottom-up): + + ``` + compile(S(S(Z))) + + --> compile(S(Z), reg13) + MKAGENT ID_S reg14 + LOADP reg13, 0, reg14 + + --> compile(Z, reg15) + MKAGENT ID_S reg13 + LOADP reg15, 0, reg13 + MKAGENT ID_S reg14 + LOADP reg13, 0, reg14 + + --> MKAGENT ID_Z reg15 + MKAGENT ID_S reg13 + LOADP reg15, 0, reg13 + MKAGENT ID_S reg14 + LOADP reg13, 0, reg14 + + == MKAGENT ID_Z reg15 + MKAGENT ID_S reg13 + LOADP reg15, 0, reg13 // reg15 can be freed + MKAGENT ID_S reg14 + LOADP reg13, 0, reg14 // reg13 can be freed + + Optimised: + == MKAGENT ID_Z reg15 + + MKAGENT ID_S reg13 + LOADP reg15, 0, reg13 // reg15 is freed + + MKAGENT ID_S reg15 // reg15 is re-used! + LOADP reg13, 0, reg15 // reg13 is freed and can be re-used quickly! + ``` + + Because inner agents are evaluated before their parent agents are created, their registers can be freed and immediately reused by the optimiser. This drastically reduces register consumption for deeply nested agents. + +- **Safely exit on memory exhaustion (Infinite loop detection)**: Previously, if an interaction rule fell into an infinite loop, the VM would continuously expand the agent and name hoops until the operating system forcibly terminated the process (e.g., Segmentation Fault). To prevent this crash, a maximum size check has been introduced during hoop expansion. The VM now monitors the requested size and safely terminates itself with a descriptive error message before the OS terminates it. + +- **Configurable AST and VMCode limits**: To support parsing larger programs, the maximum size of the AST buffer (`MAX_AST_HEAP`) has been increased from 10,000 to 100,000. Additionally, this definition, along with `MAX_IMCODE_SEQUENCE`, has been moved to `config.h` to allow users to easily customise these limits. (In future updates, these fixed-size buffers are planned to be replaced with dynamically expanding linked lists or `realloc`.) + + ``` + src/config.h + ... + // ------------------------------------------------ + // AST Heap + // ------------------------------------------------ + // MAX_AST_HEAP defines the heap size of AST. + // Increase this value if the parser runs out of heap space. + // Default: 100000 + #define MAX_AST_HEAP 100000 + + ... + + // ------------------------------------------------ + // IMCode Sequence + // ------------------------------------------------ + // MAX_IMCODE_SEQUENCE defines the maximum line number of intermediate codes. + // This buffer is statically allocated. + // Increase this value if the compiler runs out of heap space. + // Default: 1024. + //#define MAX_IMCODE_SEQUENCE 1024 + #define MAX_IMCODE_SEQUENCE 1024 + + ... + ``` + + + ### v0.13.2-1 (released on 21 March 2026) #### Bug fix -- **Fixed a register reallocation bug during intermediate code optimisation** - During the register reallocation pass, the optimiser correctly reuses a source register (`src`) in a `LOAD src, dest` instruction if it is no longer used later in the block. However, a bug caused the optimiser to incorrectly apply this same logic to `LOADI $i, dest` instructions, mistakenly interpreting the immediate value (`$i`) as a register ID. This version fixes this optimisation bug. As a result, parsing and compiling long lists with distinct elements (e.g., `1..100`) can now finally be completed without crashing! - +- **Fixed a register reallocation bug during intermediate code optimisation:** During the register reallocation pass, the optimiser correctly reuses a source register (`src`) in a `LOAD src, dest` instruction if it is no longer used later in the block. However, a bug caused the optimiser to incorrectly apply this same logic to `LOADI $i, dest` instructions, mistakenly interpreting the immediate value (`$i`) as a register ID. This version fixes this optimisation bug. As a result, parsing and compiling long lists with distinct elements (e.g., `1..100`) can now finally be completed without crashing! + ```c int CmEnv_Optimise_check_occurence_in_block(int localvar, int target_imcode_addr) { @@ -6,7 +6,7 @@ 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.13.2-1, released on **21 March 2026**. (See [Changelog.md](Changelog.md) for details.) +* The current version is 0.13.3, released on **24 March 2026**. (See [Changelog.md](Changelog.md) for details.) * The below graph shows speed-up ratio to threads numbers for programs in the following benchmark table.  @@ -100,7 +100,7 @@ void recordVal(SymbolTable *table, char *name, long val) { static Ast *AstHeap; static int NextPtr_AstHeap; -#define MAX_AST_HEAP 10000 +//#define MAX_AST_HEAP 10000 void ast_heapInit(void) { @@ -126,7 +126,7 @@ static Ast *ast_myalloc(void) { ptr=&AstHeap[NextPtr_AstHeap]; NextPtr_AstHeap++; } else { - printf("[Error] All memory for AST was run out.\n"); + printf("Error: All memory for AST was run out.\n"); exit(-1); } @@ -1,7 +1,8 @@ // http://www.hpcs.cs.tsukuba.ac.jp/~msato/lecture-note/comp-lecture/tiny-c/AST.h -#ifndef _AST_ -#define _AST_ +#ifndef AST_H_ +#define AST_H_ +#include "config.h" typedef enum { AST_SYM=0, AST_NAME, AST_INTVAR, AST_AGENT, diff --git a/src/config.h b/src/config.h index 5365829..2f20bea 100644 --- a/src/config.h +++ b/src/config.h @@ -1,4 +1,6 @@ // Configurations --------------------------------------------------- +#ifndef CONFIG_H_ +#define CONFIG_H_ // ------------------------------------------------ // Number of Agent Ports @@ -10,11 +12,21 @@ // ------------------------------------------------ -// Maximum Number of VMCode Sequence +// AST Heap +// ------------------------------------------------ +// MAX_AST_HEAP defines the heap size of AST. +// Increase this value if the parser runs out of heap space. +// Default: 100000 +#define MAX_AST_HEAP 100000 + + + +// ------------------------------------------------ +// VMCode Sequence // ------------------------------------------------ // MAX_VMCODE_SEQUENCE defines the maximum number of VM codes // for each rule. This value limits the code size stored in the RuleTable. -// Default is 1024. +// Default: 1024. #define MAX_VMCODE_SEQUENCE 1024 // MAX_EXEC_VMCODE_SEQUENCE defines the maximum number of VM codes @@ -22,10 +34,19 @@ // This buffer for this is dynamically allocated // at the start of the top-level execution // and de-allocated immediately after the compilation and execution finish. -// Default is 1000000. +// Default: 1000000. #define MAX_EXEC_VMCODE_SEQUENCE 1000000 +// ------------------------------------------------ +// IMCode Sequence +// ------------------------------------------------ +// MAX_IMCODE_SEQUENCE defines the maximum line number of intermediate codes. +// This buffer is statically allocated. +// Increase this value if the compiler runs out of heap space. +// Default: 1024. +//#define MAX_IMCODE_SEQUENCE 1024 +#define MAX_IMCODE_SEQUENCE 1024 // ------------------------------------------------ @@ -141,3 +162,7 @@ #define COUNT_INTERACTION // Count the amount of interactions. + + +#endif + diff --git a/src/id_table.h b/src/id_table.h index 2aa785f..809a814 100644 --- a/src/id_table.h +++ b/src/id_table.h @@ -1,5 +1,5 @@ -#ifndef _ID_TABLE_ -#define _ID_TABLE_ +#ifndef ID_TABLE_H_ +#define ID_TABLE_H_ #include "ast.h" #include "mytype.h" diff --git a/src/inpla.h b/src/inpla.h index 2c3f463..7dd2639 100644 --- a/src/inpla.h +++ b/src/inpla.h @@ -1,5 +1,5 @@ -#ifndef _INPLA_ -#define _INPLA_ +#ifndef INPLA_H_ +#define INPLA_H_ void flush_name_port0(VALUE ptr); void puts_name_port0(VALUE ptr); diff --git a/src/inpla.y b/src/inpla.y index 799a974..b71c971 100644 --- a/src/inpla.y +++ b/src/inpla.y @@ -22,8 +22,8 @@ // ---------------------------------------------- -#define VERSION "0.13.2-1" -#define BUILT_DATE "16 March 2026" +#define VERSION "0.13.3" +#define BUILT_DATE "24 March 2026" // ------------------------------------------------------------------ @@ -851,16 +851,27 @@ VALUE myalloc_Agent(Heap *hp) { // -->|......|-->|oooooo|-->|......|-- #ifdef VERBOSE_HOOP_EXPANSION - puts("(Agent hoop is expanded)"); + puts("(Agent hoop is BEING expanded)"); + fflush(stdout) #endif HoopList *new_hoop_list; new_hoop_list = HoopList_new_forAgent(); + + +#ifdef VERBOSE_HOOP_EXPANSION + puts("(Agent hoop has been expanded!)"); + fflush(stdout) +#endif + + HoopList *last_alloc = hoop_list->next; hoop_list->next = new_hoop_list; new_hoop_list->next = last_alloc; + + /* // Another way: insert new_hoop into the next of the top. // But, it does not work so well. @@ -929,16 +940,24 @@ VALUE myalloc_Name(Heap *hp) { // -->|......|-->|oooooo|-->|xxxxxx|-- #ifdef VERBOSE_HOOP_EXPANSION - puts("(Name hoop is expanded)"); + puts("(Name hoop is BEING expanded)"); + fflush(stdout); #endif HoopList *new_hoop_list; new_hoop_list = HoopList_new_forName(); +#ifdef VERBOSE_HOOP_EXPANSION + puts("(Name hoop has been expanded!)"); + fflush(stdout); +#endif + + + HoopList *last_alloc = hoop_list->next; hoop_list->next = new_hoop_list; new_hoop_list->next = last_alloc; - + hoop_list = new_hoop_list; idx=0; } @@ -997,13 +1016,23 @@ typedef struct Heap_tag { } Heap; +#define MAX_HOOP_SIZE 50000000 HoopList *HoopList_new_forName(unsigned int size) { HoopList *hp_list; + if (size > MAX_HOOP_SIZE) { + fprintf(stderr, "\n[Inpla VM Fatal Error] Memory limit exceeded!\n"); + fprintf(stderr, "Requested size for Name Hoop (%u) exceeds the maximum limit (%u).\n", size, MAX_HOOP_SIZE); + fprintf(stderr, "Possible infinite loop detected in Interaction Rules!\n"); + exit(-1); // Exit safely with an error code + } + + hp_list = (HoopList *)malloc(sizeof(HoopList)); if (hp_list == NULL) { printf("[HoopList]Malloc error\n"); + fflush(stdout); exit(-1); } @@ -1012,12 +1041,16 @@ HoopList *HoopList_new_forName(unsigned int size) { hp_list->hoop = (VALUE *)malloc(size * sizeof(Name)); if (hp_list->hoop == (VALUE *)NULL) { printf("[HoopList->Hoop (name)]Malloc error\n"); + fflush(stdout); exit(-1); - } + } + + for (unsigned int i=0; i<size; i++) { RESET_HOOPFLAG_READYFORUSE_NAME(((Name *)(hp_list->hoop))[i].basic.id); } hp_list->size = size; + // hp->next = NULL; // this should be executed only for the first creation. return hp_list; @@ -1036,6 +1069,14 @@ HoopList *HoopList_new_forAgent(unsigned int size) { start_timer(&t); #endif + if (size > MAX_HOOP_SIZE) { + fprintf(stderr, "\n[Inpla VM Fatal Error] Memory limit exceeded!\n"); + fprintf(stderr, "Requested size for Agent Hoop (%u) exceeds the maximum limit (%u).\n", size, MAX_HOOP_SIZE); + fprintf(stderr, "Possible infinite loop detected in Interaction Rules!\n"); + exit(-1); // Exit safely with an error code + } + + hp_list = (HoopList *)malloc(sizeof(HoopList)); if (hp_list == NULL) { @@ -1173,7 +1214,8 @@ VALUE myalloc_Agent(Heap *hp) { // printf("(Agent hoop is expanded [%d])\n", hoop_list->size); #ifdef VERBOSE_HOOP_EXPANSION - puts("(Agent hoop is expanded)"); + puts("(Agent hoop is BEING expanded...)"); + fflush(stdout); #endif //puts("!"); @@ -1214,7 +1256,14 @@ VALUE myalloc_Agent(Heap *hp) { */ hoop_list = new_hoop_list; - idx = 0; + idx = 0; + +#ifdef VERBOSE_HOOP_EXPANSION + puts("(Agent hoop has been expanded!)"); + fflush(stdout); +#endif + + } } @@ -1274,7 +1323,8 @@ VALUE myalloc_Name(Heap *hp) { // -->|......|-->|oooooo|-->|xxxxxx|-- #ifdef VERBOSE_HOOP_EXPANSION - puts("(Name hoop is expanded)"); + puts("(Name hoop is BEING expanded...)"); + fflush(stdout); #endif HoopList *new_hoop_list; @@ -1288,7 +1338,14 @@ VALUE myalloc_Name(Heap *hp) { new_hoop_list->next = last_alloc; hoop_list = new_hoop_list; - idx=0; + idx=0; + +#ifdef VERBOSE_HOOP_EXPANSION + puts("(Name hoop has been BEING expanded)"); + fflush(stdout); +#endif + + } } @@ -2029,14 +2086,23 @@ void VM_EQStack_Push(VirtualMachine * restrict vm, VALUE l, VALUE r) { vm->nextPtr_eqStack++; - if (unlikely(vm->nextPtr_eqStack >= vm->eqStack_size)) { - vm->eqStack_size += vm->eqStack_size; - vm->eqStack = realloc(vm->eqStack, sizeof(EQ)*vm->eqStack_size); + if (vm->nextPtr_eqStack >= vm->eqStack_size) { #ifdef VERBOSE_EQSTACK_EXPANSION puts("(EQStack is expanded)"); #endif + vm->eqStack_size += vm->eqStack_size; + void *new_stack = realloc(vm->eqStack, sizeof(EQ)*vm->eqStack_size); + //vm->eqStack = realloc(vm->eqStack, sizeof(EQ)*vm->eqStack_size); + + if (new_stack == NULL) { + fprintf(stderr, "\n[VM FATAL ERROR] Out of memory for eqStack!\n"); + exit(-1); + } + vm->eqStack = new_stack; + + } vm->eqStack[vm->nextPtr_eqStack].l = l; vm->eqStack[vm->nextPtr_eqStack].r = r; @@ -2056,14 +2122,14 @@ void VM_EQStack_Push(VirtualMachine * restrict vm, VALUE l, VALUE r) { } int VM_EQStack_Pop(VirtualMachine * restrict vm, VALUE *l, VALUE *r) { - if (unlikely(vm->nextPtr_eqStack < 0)) { - return 0; - } + if (vm->nextPtr_eqStack >= 0) { + *l = vm->eqStack[vm->nextPtr_eqStack].l; + *r = vm->eqStack[vm->nextPtr_eqStack].r; + vm->nextPtr_eqStack--; + return 1; + } - *l = vm->eqStack[vm->nextPtr_eqStack].l; - *r = vm->eqStack[vm->nextPtr_eqStack].r; - vm->nextPtr_eqStack--; - return 1; + return 0; } @@ -2520,7 +2586,7 @@ void CodeAddr_init(void) { } //http://www.hpcs.cs.tsukuba.ac.jp/~msato/lecture-note/comp-lecture/note10.html -#define MAX_IMCODE_SEQUENCE 1024 +//#define MAX_IMCODE_SEQUENCE 1024 struct IMCode_tag { int opcode; long operand1, operand2, operand3, operand4, operand5, operand6, operand7; @@ -2532,7 +2598,12 @@ void IMCode_init(void) { IMCode_n = 0; } -#define IMCODE_OVERFLOW_CHECK if(IMCode_n>MAX_IMCODE_SEQUENCE) {puts("IMCODE overflow");exit(1);} +#define IMCODE_OVERFLOW_CHECK \ + if (IMCode_n >= MAX_IMCODE_SEQUENCE) { \ + fprintf(stderr, "ERROR[IMCode]: Sequence overflow. Increase MAX_IMCODE_SEQUENCE in config.h.\n"); \ + exit(1); \ + } + void IMCode_genCode0(int opcode) { IMCode[IMCode_n++].opcode = opcode; @@ -5943,6 +6014,7 @@ int Compile_term_on_ast(Ast *ptr, int target) { ptr=ptr->right; if (target == -1) { + /* result = CmEnv_newvar(); IMCode_genCode2(OP_MKAGENT, id, result); @@ -5953,6 +6025,31 @@ int Compile_term_on_ast(Ast *ptr, int target) { IMCode_genCode3(OP_LOADP, alloc, i, result); } + */ + + Ast *children[MAX_PORT]; + int child_regs[MAX_PORT]; // Register table for children + + // Store each child pointer to children[] + for (i = 0; i < arity; i++) { + children[i] = ptr->left; + ptr = ast_getTail(ptr); + } + + // Compile children from tail to head + for (i = arity-1; i >= 0; i--) { + child_regs[i] = Compile_term_on_ast(children[i], -1); + } + + // Connect childen to this agent + result = CmEnv_newvar(); + IMCode_genCode2(OP_MKAGENT, id, result); + + for (i=0; i<arity; i++) { + IMCode_genCode3(OP_LOADP, child_regs[i], i, result); + } + + } else { result = target; @@ -5972,7 +6069,7 @@ int Compile_term_on_ast(Ast *ptr, int target) { } else { - + // VM_OFFSET_ANNOTATE_R if (CmEnv.idR != id) { IMCode_genCode1(OP_CHID_R, id); } @@ -6615,6 +6712,54 @@ int Compile_body_on_ast(Ast *body) { +int check_ast_arity(Ast *ast) { + int i; + Ast *ptr; + char *sym; + + if (ast == NULL) { + return 1; + } + + if (ast->id == AST_AGENT) { + ptr = ast->right; + sym = ast->left->sym; + + for (i=0; i<MAX_PORT; i++) { + if (ptr == NULL) { + return 1; + } + if (!check_ast_arity(ptr->left)) { + return 0; + } + ptr = ast_getTail(ptr); + } + + if (ptr != NULL) { + printf("%d:Error: `%s' has too many arguments. It should be MAX_PORT(=%d) or less.\n", yylineno, sym, MAX_PORT); + return 0; + } + + } else if (ast->id == AST_TUPLE) { + // We support upto 5-tuples. + if ((ast->intval <= MAX_PORT) && (ast->intval <= 5)) { + return 1; + } else { + if (MAX_PORT <= 5) { + printf("%d:Error: A tuple has too many arguments. It should be MAX_PORT(=%d) or less.\n", yylineno, MAX_PORT); + } else { + printf("%d:Error: A tuple has too many arguments. 6 more tubles are not supported.\n", yylineno); + } + return 0; + } + } + + return 1; +} + + + + int Compile_rule_mainbody_on_ast(Ast *mainbody) { // return 1: success @@ -6634,8 +6779,28 @@ int Compile_rule_mainbody_on_ast(Ast *mainbody) { if ((mainbody == NULL) || (mainbody->id == AST_BODY)) { // Compilation without guards - Ast *body = mainbody; + Ast *body; + + // Check if the arity <= MAX_PORT + if (mainbody != NULL) { + body = mainbody->right; + + while (body != NULL) { + + if (!(check_ast_arity(body->left->left)) + || !(check_ast_arity(body->left->right))) { + + // invalid case + if (yyin != stdin) exit(-1); + return 0; + } + + body = ast_getTail(body); + } + } + + body = mainbody; if (!Compile_body_on_ast(body)) return 0; if (!CmEnv_check_linearity_in_rule()) { @@ -6991,15 +7156,23 @@ void RuleTable_get_code_for_Int(VALUE heap_syml, void ***code) { // ------------------------------------------------------------- int get_arity_on_ast(Ast *ast) { - int i; + int i=0; Ast *ptr; ptr = ast->right; + while (ptr != NULL) { + ptr = ast_getTail(ptr); + ++i; + } + return i; + + /* for (i=0; i<MAX_PORT; i++) { if (ptr == NULL) break; ptr = ast_getTail(ptr); } return i; + */ } @@ -7128,6 +7301,10 @@ int get_ruleagentID(Ast *ruleAgent) { } + + + + int make_rule_oneway(Ast *ast) { // (ASTRULE // (AST_CNCT agentL agentR) @@ -7242,7 +7419,7 @@ int make_rule_oneway(Ast *ast) { arity = get_arity_on_ast(ruleAgent_L); } if (arity > MAX_PORT) { - printf("%d:ERROR: Too many arguments of `%s'. It should be MAX_PORT(=%d) or less.\n", + printf("%d:ERROR: The rule agent `%s' has too many arguments. It should be MAX_PORT(=%d) or less.\n", yylineno, ruleAgent_L->left->sym, MAX_PORT); return 0; @@ -7256,7 +7433,7 @@ int make_rule_oneway(Ast *ast) { arity = get_arity_on_ast(ruleAgent_R); } if (arity > MAX_PORT) { - printf("%d:ERROR: Too many arguments of `%s'. It should be MAX_PORT(=%d) or less.\n", + printf("%d:ERROR: The rule agent `%s' has too many arguments. It should be MAX_PORT(=%d) or less.\n", yylineno, ruleAgent_R->left->sym, MAX_PORT); return 0; @@ -7478,23 +7655,25 @@ int make_rule(Ast *ast) { */ + // Remove tuple1 ast->left->left = ast_remove_tuple1(ruleAgent_L); ast->left->right = ast_remove_tuple1(ruleAgent_R); - - Ast *rule_mainbody = ast->right; Ast_remove_tuple1_in_mainbody(rule_mainbody); - + + // For annotations (*L), (*R) set_annotation_LR(VM_OFFSET_ANNOTATE_L, VM_OFFSET_ANNOTATE_R); + + // Compile and record the rule L><R if (!make_rule_oneway(ast)) { return 0; } - // another way + // another way: R><L int preserve_CmEnv_put_compiled_codes = CmEnv.put_compiled_codes; CmEnv.put_compiled_codes = 0; // without outputting codes @@ -9910,51 +10089,6 @@ void select_kind_of_push(Ast *ast, int p1, int p2) { } -int check_ast_arity(Ast *ast) { - int i; - Ast *ptr; - char *sym; - - if (ast == NULL) { - return 1; - } - - if (ast->id == AST_AGENT) { - ptr = ast->right; - sym = ast->left->sym; - - for (i=0; i<MAX_PORT; i++) { - if (ptr == NULL) { - return 1; - } - if (!check_ast_arity(ptr->left)) { - return 0; - } - ptr = ast_getTail(ptr); - } - - if (ptr != NULL) { - printf("Error!: `%s' has too many arguments. It should be MAX_PORT(=%d) or less.\n", sym, MAX_PORT); - return 0; - } - - } else if (ast->id == AST_TUPLE) { - // We support upto 5-tuples. - if ((ast->intval <= MAX_PORT) && (ast->intval <= 5)) { - return 1; - } else { - if (MAX_PORT <= 5) { - printf("Error: A tuple has too many arguments. It should be MAX_PORT(=%d) or less.\n", MAX_PORT); - } else { - printf("Error: A tuple has too many arguments. It should be 5 or less.\n"); - } - return 0; - } - } - - return 1; -} - #ifndef THREAD diff --git a/src/mytype.h b/src/mytype.h index 4cc3909..bdfbfee 100644 --- a/src/mytype.h +++ b/src/mytype.h @@ -1,5 +1,5 @@ -#ifndef _TYPE_ -#define _TYPE_ +#ifndef MYTYPE_H_ +#define MYTYPE_H_ #include "config.h" diff --git a/src/name_table.h b/src/name_table.h index 70d71cc..a739908 100644 --- a/src/name_table.h +++ b/src/name_table.h @@ -1,5 +1,5 @@ -#ifndef _NAME_TABLE_ -#define _NAME_TABLE_ +#ifndef NAME_TABLE_H_ +#define NAME_TABLE_H_ #include "mytype.h" #include "id_table.h" diff --git a/src/timer.h b/src/timer.h index 904bd6a..bee777b 100644 --- a/src/timer.h +++ b/src/timer.h @@ -1,7 +1,7 @@ //https://github.com/zuqqhi2/numerical_simulation/blob/master/multithread/laytrace/timer.h -#ifndef _H_TIMER -#define _H_TIMER +#ifndef TIMER_H_ +#define TIMER_H_ #include <stdio.h> #include <sys/time.h> diff --git a/src/unlikely.h b/src/unlikely.h index 602c723..72f51b6 100644 --- a/src/unlikely.h +++ b/src/unlikely.h @@ -1,12 +1,12 @@ -#ifndef INPLA_UNLIKELY_H -#define INPLA_UNLIKELY_H +#ifndef INPLA_UNLIKELY_H_ +#define INPLA_UNLIKELY_H_ #if defined(__GNUC__) || defined(__clang__) - // GCC と Clang の場合は、極限まで最適化! + // For GCC, Clang #define likely(x) __builtin_expect(!!(x), 1) #define unlikely(x) __builtin_expect(!!(x), 0) #else - // それ以外のコンパイラ(MSVCなど)では、ただの素通り(無害化) + // Otherwise #define likely(x) (x) #define unlikely(x) (x) #endif |
