chore: remove trailing whitespace from README.md line 42

This commit is contained in:
2025-11-25 00:25:16 +00:00
parent 67852ee59d
commit 793d9b66c0
15 changed files with 1538 additions and 45 deletions
+31 -19
View File
@@ -7,6 +7,7 @@
#include "parser.h"
#include "error.h"
#include "debug.h"
#include "memory.h"
void error(char *msg) {
error_with_context("ParseError", msg, NULL);
@@ -111,29 +112,38 @@ void statement() {
Token *t = &tokens[pc];
match(Id);
if (loc_cnt >= VAR_MAX) {
DEBUG_LOG("ERROR: Too many local variables: loc_cnt=%d (max=%d)", loc_cnt, VAR_MAX);
char var_name[64];
int name_len = t->val;
if (name_len < 0) name_len = 0;
if (name_len > 31) name_len = 31;
strncpy(var_name, t->text, name_len);
var_name[name_len] = 0;
char alloc_ctx[128];
snprintf(alloc_ctx, sizeof(alloc_ctx), "declare variable '%s'", var_name);
if (!mem_check_loc_cnt(loc_cnt + 1, alloc_ctx)) {
error("Too many local variables");
}
if (sp >= MEM_SIZE) {
DEBUG_LOG("ERROR: Stack overflow: sp=%d (max=%d)", sp, MEM_SIZE);
DEBUG_STACK_STATE();
if (!mem_check_sp(sp + 1, alloc_ctx)) {
error("Stack overflow");
}
int addr = sp;
Symbol *s = &locals[loc_cnt++];
if (!t->text) {
error("Invalid token text");
}
int name_len = t->val;
if (name_len < 0) name_len = 0;
if (name_len > 31) name_len = 31;
strncpy(s->name, t->text, name_len);
s->name[name_len] = 0;
strncpy(s->name, var_name, 32);
s->name[31] = 0;
s->type = var_type;
s->addr = addr;
s->is_array = 0;
if (loc_cnt > mem_stats.loc_cnt_high_water) {
mem_stats.loc_cnt_high_water = loc_cnt;
}
if (pc < MAX_TOK && pc < tk_idx && tokens[pc].type == '[') {
pc++;
long size_val = expression();
@@ -148,27 +158,29 @@ void statement() {
int size = (int)size_val;
s->is_array = 1;
if (sp + size >= MEM_SIZE) {
snprintf(alloc_ctx, sizeof(alloc_ctx), "allocate array '%s[%d]'", var_name, size);
if (!mem_check_sp(sp + size, alloc_ctx)) {
error("Stack overflow during array allocation");
}
if (sp + size < sp) {
error("Integer overflow in array allocation");
}
sp += size;
mem_stats.total_allocations += size;
} else {
if (sp + 1 >= MEM_SIZE) {
error("Stack overflow during variable allocation");
}
sp++;
mem_stats.total_allocations++;
}
if (sp > mem_stats.sp_high_water) {
mem_stats.sp_high_water = sp;
}
if (pc < MAX_TOK && pc < tk_idx && tokens[pc].type == '=') {
pc++;
if (addr >= 0 && addr < MEM_SIZE) {
memory[addr] = expression();
} else {
error("Memory access out of bounds");
}
snprintf(alloc_ctx, sizeof(alloc_ctx), "initialize '%s'", var_name);
mem_write(addr, expression(), alloc_ctx);
}
if (pc < MAX_TOK && pc < tk_idx && tokens[pc].type == ',') pc++;
}
+2
View File
@@ -10,10 +10,12 @@
#include "preprocessor.h"
#include "oop.h"
#include "debug.h"
#include "memory.h"
int main(int argc, char **argv) {
DEBUG_INIT();
DEBUG_LOG("RC Interpreter starting");
mem_init();
pthread_rwlock_init(&tokens_rwlock, NULL);
pthread_mutex_init(&str_pool_mutex, NULL);
+267
View File
@@ -0,0 +1,267 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "memory.h"
#include "types.h"
#include "error.h"
MemoryStats mem_stats = {0, 0, 0, 0, 0, 0};
extern long memory[];
extern int sp;
extern int bp;
extern Symbol locals[];
extern int loc_cnt;
extern int pc;
extern long ax;
static void mem_error(const char *msg, const char *context) {
fprintf(stderr, "\n");
fprintf(stderr, "╔════════════════════════════════════════════════════════════════╗\n");
fprintf(stderr, "║ MEMORY ERROR DETECTED ║\n");
fprintf(stderr, "╚════════════════════════════════════════════════════════════════╝\n");
fprintf(stderr, "\n Error: %s\n", msg);
fprintf(stderr, " Context: %s\n", context);
fprintf(stderr, "\n");
fprintf(stderr, "╔════════════════════════════════════════════════════════════════╗\n");
fprintf(stderr, "║ MEMORY STATE ║\n");
fprintf(stderr, "╚════════════════════════════════════════════════════════════════╝\n");
fprintf(stderr, " Stack Pointer (sp): %d\n", sp);
fprintf(stderr, " Base Pointer (bp): %d\n", bp);
fprintf(stderr, " Program Counter (pc): %d\n", pc);
fprintf(stderr, " Local Count (loc_cnt): %d\n", loc_cnt);
fprintf(stderr, " Accumulator (ax): %ld\n", ax);
fprintf(stderr, "\n");
fprintf(stderr, "╔════════════════════════════════════════════════════════════════╗\n");
fprintf(stderr, "║ MEMORY LIMITS ║\n");
fprintf(stderr, "╚════════════════════════════════════════════════════════════════╝\n");
fprintf(stderr, " MEM_SIZE: %d\n", MEM_SIZE);
fprintf(stderr, " VAR_MAX: %d\n", VAR_MAX);
fprintf(stderr, " MAX_TOK: %d\n", MAX_TOK);
fprintf(stderr, "\n");
fprintf(stderr, "╔════════════════════════════════════════════════════════════════╗\n");
fprintf(stderr, "║ MEMORY STATISTICS ║\n");
fprintf(stderr, "╚════════════════════════════════════════════════════════════════╝\n");
fprintf(stderr, " SP High Water Mark: %d\n", mem_stats.sp_high_water);
fprintf(stderr, " LOC_CNT High Water: %d\n", mem_stats.loc_cnt_high_water);
fprintf(stderr, " Current Call Depth: %d\n", mem_stats.call_depth);
fprintf(stderr, " Max Call Depth: %d\n", mem_stats.max_call_depth);
fprintf(stderr, " Total Allocations: %d\n", mem_stats.total_allocations);
fprintf(stderr, " Total Deallocations: %d\n", mem_stats.total_deallocations);
fprintf(stderr, "\n");
if (loc_cnt > 0 && loc_cnt <= VAR_MAX) {
fprintf(stderr, "╔════════════════════════════════════════════════════════════════╗\n");
fprintf(stderr, "║ LOCAL VARIABLES ║\n");
fprintf(stderr, "╚════════════════════════════════════════════════════════════════╝\n");
int show_count = loc_cnt < 20 ? loc_cnt : 20;
for (int i = 0; i < show_count; i++) {
fprintf(stderr, " [%3d] %-20s addr=%5d is_array=%d",
i, locals[i].name, locals[i].addr, locals[i].is_array);
if (locals[i].addr >= 0 && locals[i].addr < MEM_SIZE) {
fprintf(stderr, " value=%ld", memory[locals[i].addr]);
}
fprintf(stderr, "\n");
}
if (loc_cnt > 20) {
fprintf(stderr, " ... and %d more variables\n", loc_cnt - 20);
}
fprintf(stderr, "\n");
}
if (sp > 0 && sp <= MEM_SIZE) {
fprintf(stderr, "╔════════════════════════════════════════════════════════════════╗\n");
fprintf(stderr, "║ STACK CONTENTS ║\n");
fprintf(stderr, "╚════════════════════════════════════════════════════════════════╝\n");
int start = sp > 20 ? sp - 20 : 0;
for (int i = start; i < sp && i < MEM_SIZE; i++) {
fprintf(stderr, " memory[%5d] = %ld", i, memory[i]);
if (i == bp) fprintf(stderr, " <-- bp");
if (i == sp - 1) fprintf(stderr, " <-- sp-1 (top)");
fprintf(stderr, "\n");
}
fprintf(stderr, "\n");
}
exit(1);
}
void mem_init(void) {
mem_stats.sp_high_water = 0;
mem_stats.loc_cnt_high_water = 0;
mem_stats.call_depth = 0;
mem_stats.max_call_depth = 0;
mem_stats.total_allocations = 0;
mem_stats.total_deallocations = 0;
}
void mem_dump_stats(void) {
fprintf(stderr, "\n=== Memory Statistics ===\n");
fprintf(stderr, "SP High Water: %d / %d (%.1f%%)\n",
mem_stats.sp_high_water, MEM_SIZE,
100.0 * mem_stats.sp_high_water / MEM_SIZE);
fprintf(stderr, "LOC_CNT High: %d / %d (%.1f%%)\n",
mem_stats.loc_cnt_high_water, VAR_MAX,
100.0 * mem_stats.loc_cnt_high_water / VAR_MAX);
fprintf(stderr, "Max Call Depth: %d\n", mem_stats.max_call_depth);
fprintf(stderr, "Allocations: %d\n", mem_stats.total_allocations);
fprintf(stderr, "Deallocations: %d\n", mem_stats.total_deallocations);
fprintf(stderr, "=========================\n");
}
int mem_check_sp(int required_sp, const char *context) {
if (required_sp < 0) {
char msg[256];
snprintf(msg, sizeof(msg), "Stack underflow: required sp=%d", required_sp);
mem_error(msg, context);
return 0;
}
if (required_sp >= MEM_SIZE) {
char msg[256];
snprintf(msg, sizeof(msg), "Stack overflow: required sp=%d >= MEM_SIZE=%d",
required_sp, MEM_SIZE);
mem_error(msg, context);
return 0;
}
return 1;
}
int mem_check_addr(int addr, const char *context) {
if (addr < 0) {
char msg[256];
snprintf(msg, sizeof(msg), "Negative memory address: addr=%d", addr);
mem_error(msg, context);
return 0;
}
if (addr >= MEM_SIZE) {
char msg[256];
snprintf(msg, sizeof(msg), "Memory address out of bounds: addr=%d >= MEM_SIZE=%d",
addr, MEM_SIZE);
mem_error(msg, context);
return 0;
}
return 1;
}
int mem_check_loc_cnt(int required_cnt, const char *context) {
if (required_cnt < 0) {
char msg[256];
snprintf(msg, sizeof(msg), "Negative local count: loc_cnt=%d", required_cnt);
mem_error(msg, context);
return 0;
}
if (required_cnt >= VAR_MAX) {
char msg[256];
snprintf(msg, sizeof(msg), "Too many local variables: loc_cnt=%d >= VAR_MAX=%d",
required_cnt, VAR_MAX);
mem_error(msg, context);
return 0;
}
return 1;
}
long mem_read(int addr, const char *context) {
if (!mem_check_addr(addr, context)) {
return 0;
}
return memory[addr];
}
void mem_write(int addr, long value, const char *context) {
if (!mem_check_addr(addr, context)) {
return;
}
memory[addr] = value;
}
int mem_push(long value, const char *context) {
if (!mem_check_sp(sp + 1, context)) {
return 0;
}
memory[sp++] = value;
mem_stats.total_allocations++;
if (sp > mem_stats.sp_high_water) {
mem_stats.sp_high_water = sp;
}
return 1;
}
long mem_pop(const char *context) {
if (sp <= 0) {
mem_error("Stack underflow on pop", context);
return 0;
}
mem_stats.total_deallocations++;
return memory[--sp];
}
void mem_alloc_var(int size, const char *var_name) {
char context[256];
snprintf(context, sizeof(context), "Allocating variable '%s' (size=%d)", var_name, size);
if (!mem_check_sp(sp + size, context)) {
return;
}
if (!mem_check_loc_cnt(loc_cnt + 1, context)) {
return;
}
sp += size;
mem_stats.total_allocations += size;
if (sp > mem_stats.sp_high_water) {
mem_stats.sp_high_water = sp;
}
if (loc_cnt > mem_stats.loc_cnt_high_water) {
mem_stats.loc_cnt_high_water = loc_cnt;
}
}
void mem_free_frame(int old_sp, int old_loc_cnt, const char *context) {
if (old_sp < 0 || old_sp > sp) {
char msg[256];
snprintf(msg, sizeof(msg), "Invalid frame restoration: old_sp=%d, current sp=%d",
old_sp, sp);
mem_error(msg, context);
return;
}
if (old_loc_cnt < 0 || old_loc_cnt > loc_cnt) {
char msg[256];
snprintf(msg, sizeof(msg), "Invalid loc_cnt restoration: old_loc_cnt=%d, current loc_cnt=%d",
old_loc_cnt, loc_cnt);
mem_error(msg, context);
return;
}
mem_stats.total_deallocations += (sp - old_sp);
sp = old_sp;
loc_cnt = old_loc_cnt;
}
void mem_enter_call(const char *func_name) {
mem_stats.call_depth++;
if (mem_stats.call_depth > mem_stats.max_call_depth) {
mem_stats.max_call_depth = mem_stats.call_depth;
}
if (mem_stats.call_depth > MAX_CALL_STACK) {
char msg[256];
snprintf(msg, sizeof(msg), "Call stack overflow entering '%s'", func_name);
mem_error(msg, "mem_enter_call");
}
}
void mem_exit_call(const char *func_name) {
if (mem_stats.call_depth <= 0) {
char msg[256];
snprintf(msg, sizeof(msg), "Call stack underflow exiting '%s'", func_name);
mem_error(msg, "mem_exit_call");
return;
}
mem_stats.call_depth--;
}
void mem_trace_state(const char *label) {
fprintf(stderr, "[TRACE:%s] sp=%d bp=%d loc_cnt=%d call_depth=%d\n",
label, sp, bp, loc_cnt, mem_stats.call_depth);
}
+38
View File
@@ -0,0 +1,38 @@
#ifndef MEMORY_H
#define MEMORY_H
#include "types.h"
typedef struct {
int sp_high_water;
int loc_cnt_high_water;
int call_depth;
int max_call_depth;
int total_allocations;
int total_deallocations;
} MemoryStats;
extern MemoryStats mem_stats;
void mem_init(void);
void mem_dump_stats(void);
int mem_check_sp(int required_sp, const char *context);
int mem_check_addr(int addr, const char *context);
int mem_check_loc_cnt(int required_cnt, const char *context);
long mem_read(int addr, const char *context);
void mem_write(int addr, long value, const char *context);
int mem_push(long value, const char *context);
long mem_pop(const char *context);
void mem_alloc_var(int size, const char *var_name);
void mem_free_frame(int old_sp, int old_loc_cnt, const char *context);
void mem_enter_call(const char *func_name);
void mem_exit_call(const char *func_name);
void mem_trace_state(const char *label);
#endif
+38 -13
View File
@@ -7,6 +7,7 @@
#include "string_utils.h"
#include "error.h"
#include "debug.h"
#include "memory.h"
extern Token tokens[];
extern int pc;
@@ -178,18 +179,24 @@ long factor() {
int ret_pc = pc;
int old_loc_cnt = loc_cnt;
int old_bp = bp;
int old_sp = sp;
if (sp >= MEM_SIZE) return 0;
if (bp < 0 || bp >= MEM_SIZE) return 0;
memory[sp] = bp; bp = sp++;
if (sp >= MEM_SIZE) return 0;
memory[sp++] = ret_pc;
memory[sp++] = old_loc_cnt;
mem_enter_call(funcs[f_idx].name);
char call_ctx[128];
snprintf(call_ctx, sizeof(call_ctx), "call %s: push frame", funcs[f_idx].name);
if (!mem_check_sp(sp + 3 + argc, call_ctx)) return 0;
if (!mem_check_addr(bp, call_ctx)) return 0;
mem_write(sp, bp, call_ctx);
bp = sp++;
mem_write(sp++, ret_pc, call_ctx);
mem_write(sp++, old_loc_cnt, call_ctx);
int param_base = sp;
for(int i=0; i<argc; i++) {
if (sp >= MEM_SIZE) break;
memory[sp++] = args[i];
mem_write(sp++, args[i], call_ctx);
}
int scan_pc = funcs[f_idx].params_start;
@@ -198,7 +205,8 @@ long factor() {
if (tokens[scan_pc].type == Int || tokens[scan_pc].type == Char || tokens[scan_pc].type == Double) {
scan_pc++;
while (scan_pc < MAX_TOK && tokens[scan_pc].type == '*') scan_pc++;
if (scan_pc < MAX_TOK && tokens[scan_pc].type == Id && param_idx < argc && loc_cnt < VAR_MAX) {
if (scan_pc < MAX_TOK && tokens[scan_pc].type == Id && param_idx < argc) {
if (!mem_check_loc_cnt(loc_cnt + 1, call_ctx)) return 0;
Token *param_name = &tokens[scan_pc];
Symbol *sym = &locals[loc_cnt++];
int name_len = param_name->val;
@@ -209,11 +217,18 @@ long factor() {
sym->addr = param_base + param_idx;
sym->is_array = 0;
param_idx++;
if (loc_cnt > mem_stats.loc_cnt_high_water) {
mem_stats.loc_cnt_high_water = loc_cnt;
}
}
}
scan_pc++;
}
if (sp > mem_stats.sp_high_water) {
mem_stats.sp_high_water = sp;
}
const char *func_filename = NULL;
int func_line = 0;
if (funcs[f_idx].entry_point < tk_idx) {
@@ -231,13 +246,23 @@ long factor() {
return_flag = 0;
pop_call_frame();
mem_exit_call(funcs[f_idx].name);
snprintf(call_ctx, sizeof(call_ctx), "return from %s: restore frame", funcs[f_idx].name);
if (old_loc_cnt < 0 || old_loc_cnt > loc_cnt) {
char msg[256];
snprintf(msg, sizeof(msg), "loc_cnt corruption: old=%d, current=%d", old_loc_cnt, loc_cnt);
error(msg);
return 0;
}
loc_cnt = old_loc_cnt;
if (bp < 0 || bp >= MEM_SIZE) return 0;
if (!mem_check_addr(bp, call_ctx)) return 0;
sp = bp;
if (sp < 0 || sp >= MEM_SIZE) return 0;
bp = memory[sp];
if (sp + 1 < MEM_SIZE) ret_pc = memory[sp + 1];
if (!mem_check_addr(sp, call_ctx)) return 0;
bp = mem_read(sp, call_ctx);
ret_pc = mem_read(sp + 1, call_ctx);
pc = ret_pc;
return val;
}
+192
View File
@@ -0,0 +1,192 @@
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <pthread.h>
#include "../../types.h"
#include "benchmark_stdlib.h"
extern void register_native_func(char *name, NativeFunc func);
extern pthread_mutex_t str_pool_mutex;
extern char str_pool[STR_POOL_SIZE];
extern int str_pool_idx;
#define MAX_TIMERS 1000
typedef struct {
struct timespec start_time;
int active;
} BenchTimer;
static BenchTimer timers[MAX_TIMERS];
static pthread_mutex_t timers_mutex = PTHREAD_MUTEX_INITIALIZER;
static int next_timer_id = 0;
long native_bench_start(long *args, int argc) {
pthread_mutex_lock(&timers_mutex);
int timer_id = -1;
for (int i = 0; i < MAX_TIMERS; i++) {
if (!timers[i].active) {
timer_id = i;
break;
}
}
if (timer_id == -1) {
if (next_timer_id < MAX_TIMERS) {
timer_id = next_timer_id++;
} else {
pthread_mutex_unlock(&timers_mutex);
return -1;
}
}
timers[timer_id].active = 1;
clock_gettime(CLOCK_MONOTONIC, &timers[timer_id].start_time);
pthread_mutex_unlock(&timers_mutex);
return timer_id;
}
long native_bench_end(long *args, int argc) {
if (!args || argc < 1) {
return -1;
}
int timer_id = (int)args[0];
if (timer_id < 0 || timer_id >= MAX_TIMERS) {
return -1;
}
struct timespec end_time;
clock_gettime(CLOCK_MONOTONIC, &end_time);
pthread_mutex_lock(&timers_mutex);
if (!timers[timer_id].active) {
pthread_mutex_unlock(&timers_mutex);
return -1;
}
long elapsed_ns = (end_time.tv_sec - timers[timer_id].start_time.tv_sec) * 1000000000L +
(end_time.tv_nsec - timers[timer_id].start_time.tv_nsec);
timers[timer_id].active = 0;
pthread_mutex_unlock(&timers_mutex);
return elapsed_ns;
}
long native_bench_format(long *args, int argc) {
static char empty_str[] = "";
if (!args || argc < 2) {
return (long)empty_str;
}
long nanoseconds = args[0];
int unit = (int)args[1];
pthread_mutex_lock(&str_pool_mutex);
if (str_pool_idx >= STR_POOL_SIZE - 256) {
pthread_mutex_unlock(&str_pool_mutex);
return (long)empty_str;
}
char *result = &str_pool[str_pool_idx];
int len = 0;
switch (unit) {
case 0:
len = snprintf(result, 256, "%ld ns", nanoseconds);
break;
case 1: {
double microseconds = nanoseconds / 1000.0;
len = snprintf(result, 256, "%.3f us", microseconds);
break;
}
case 2: {
double milliseconds = nanoseconds / 1000000.0;
len = snprintf(result, 256, "%.3f ms", milliseconds);
break;
}
case 3: {
double seconds = nanoseconds / 1000000000.0;
len = snprintf(result, 256, "%.6f s", seconds);
break;
}
case 4: {
double minutes = nanoseconds / 60000000000.0;
len = snprintf(result, 256, "%.6f min", minutes);
break;
}
case 5: {
double hours = nanoseconds / 3600000000000.0;
len = snprintf(result, 256, "%.6f h", hours);
break;
}
default:
len = snprintf(result, 256, "%ld ns", nanoseconds);
break;
}
if (len > 0 && len < 256) {
str_pool_idx += len + 1;
}
pthread_mutex_unlock(&str_pool_mutex);
return (long)result;
}
long native_bench_format_auto(long *args, int argc) {
if (!args || argc < 1) {
static char empty_str[] = "";
return (long)empty_str;
}
long nanoseconds = args[0];
int unit = 0;
if (nanoseconds >= 3600000000000L) {
unit = 5;
} else if (nanoseconds >= 60000000000L) {
unit = 4;
} else if (nanoseconds >= 1000000000L) {
unit = 3;
} else if (nanoseconds >= 1000000L) {
unit = 2;
} else if (nanoseconds >= 1000L) {
unit = 1;
} else {
unit = 0;
}
long format_args[2] = {nanoseconds, unit};
return native_bench_format(format_args, 2);
}
long native_bench_reset(long *args, int argc) {
pthread_mutex_lock(&timers_mutex);
for (int i = 0; i < MAX_TIMERS; i++) {
timers[i].active = 0;
}
next_timer_id = 0;
pthread_mutex_unlock(&timers_mutex);
return 0;
}
void register_benchmark_stdlib() {
register_native_func("bench_start", native_bench_start);
register_native_func("bench_end", native_bench_end);
register_native_func("bench_format", native_bench_format);
register_native_func("bench_format_auto", native_bench_format_auto);
register_native_func("bench_reset", native_bench_reset);
}
+6
View File
@@ -0,0 +1,6 @@
#ifndef BENCHMARK_STDLIB_H
#define BENCHMARK_STDLIB_H
void register_benchmark_stdlib();
#endif
+34
View File
@@ -1,6 +1,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include "../../types.h"
#include "math_stdlib.h"
@@ -128,6 +129,35 @@ long native_double_div(long *args, int argc) {
return result.l;
}
long native_rand(long *args, int argc) {
return (long)rand();
}
long native_srand(long *args, int argc) {
if (!args || argc < 1) {
srand(1);
} else {
srand((unsigned int)args[0]);
}
return 0;
}
long native_rand_range(long *args, int argc) {
if (!args || argc < 2) {
return 0;
}
long min = args[0];
long max = args[1];
if (max <= min) {
return min;
}
return min + (rand() % (max - min + 1));
}
long native_time(long *args, int argc) {
return (long)time(NULL);
}
void register_math_stdlib() {
register_native_func("sqrt", native_sqrt);
register_native_func("pow", native_pow);
@@ -143,4 +173,8 @@ void register_math_stdlib() {
register_native_func("double_sub", native_double_sub);
register_native_func("double_mul", native_double_mul);
register_native_func("double_div", native_double_div);
register_native_func("rand", native_rand);
register_native_func("srand", native_srand);
register_native_func("rand_range", native_rand_range);
register_native_func("time", native_time);
}
+2
View File
@@ -6,6 +6,7 @@
#include "async/async_stdlib.h"
#include "constants/constants_stdlib.h"
#include "eval/eval_stdlib.h"
#include "benchmark/benchmark_stdlib.h"
void register_stdlib() {
register_string_stdlib();
@@ -15,4 +16,5 @@ void register_stdlib() {
register_async_stdlib();
register_constants_stdlib();
register_eval_stdlib();
register_benchmark_stdlib();
}