aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShinya Sato <shinnya.sato@gmail.com>2026-03-24 18:14:09 +0900
committerShinya Sato <shinnya.sato@gmail.com>2026-03-24 18:14:09 +0900
commit3db7ebc0d503511e255926d105aa0d5f6cbfdadd (patch)
tree785f7fbb384e1757271405ee6a35fcf169224933 /src
parent11dd49da1625e1a8197c6d9f8d22743a974ddb72 (diff)
downloadinpla-3db7ebc0d503511e255926d105aa0d5f6cbfdadd.tar.gz
inpla-3db7ebc0d503511e255926d105aa0d5f6cbfdadd.zip
v0.13.3
Diffstat (limited to 'src')
-rw-r--r--src/ast.c4
-rw-r--r--src/ast.h5
-rw-r--r--src/config.h31
-rw-r--r--src/id_table.h4
-rw-r--r--src/inpla.h4
-rw-r--r--src/inpla.y286
-rw-r--r--src/mytype.h4
-rw-r--r--src/name_table.h4
-rw-r--r--src/timer.h4
-rw-r--r--src/unlikely.h8
10 files changed, 257 insertions, 97 deletions
diff --git a/src/ast.c b/src/ast.c
index e1c6d9a..3d37857 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -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);
}
diff --git a/src/ast.h b/src/ast.h
index 6124de8..44bc597 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -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