@hsusulist/luc 0.2.5 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/luc.h ADDED
@@ -0,0 +1,303 @@
1
+ /* shared header: core/libs contract */
2
+ /* cleanup 2026-09-01 */
3
+ #ifndef LUC_H
4
+ #define LUC_H
5
+
6
+ #define _POSIX_C_SOURCE 200809L
7
+ #include <stdio.h>
8
+ #include <stdlib.h>
9
+ #include <string.h>
10
+ #include <stdarg.h>
11
+ #include <math.h>
12
+ #include <ctype.h>
13
+ #include <setjmp.h>
14
+ #include <time.h>
15
+ #include <errno.h>
16
+ #include <limits.h>
17
+ #include <stdint.h>
18
+ #include <stddef.h>
19
+
20
+ #define LUC_VERSION "LUC 0.2.0-beta-1"
21
+ #define LUC_MAXREG 200
22
+ #define LUC_MAXUPVAL 60
23
+ #define LUC_MAXCI 220
24
+ #define LUC_MAXSTACK 1000000
25
+ #define LUC_YIELDCODE (-1)
26
+
27
+ /* 1. values & objects */
28
+
29
+ typedef struct Obj Obj;
30
+ typedef struct Str Str;
31
+ typedef struct Table Table;
32
+ typedef struct Proto Proto;
33
+ typedef struct Closure Closure;
34
+ typedef struct CFunc CFunc;
35
+ typedef struct Buffer Buffer;
36
+ typedef struct FileH FileH;
37
+ typedef struct Socket Socket;
38
+ typedef struct Upval Upval;
39
+ typedef struct LucState LucState;
40
+
41
+ enum {
42
+ LT_NIL=0, LT_BOOL, LT_NUM, LT_STR, LT_TABLE, LT_LIST, LT_FUNC,
43
+ LT_CFUNC, LT_BUFFER, LT_CORO, LT_FILE, LT_PROTO, LT_UPVAL, LT_SOCKET
44
+ };
45
+
46
+ typedef struct {
47
+ int t;
48
+ union { double n; int b; Obj *o; } u;
49
+ } Value;
50
+
51
+ struct Obj { unsigned char type, marked; Obj *next; };
52
+
53
+ struct Str { Obj o; Str *snext; int len; unsigned hash; char s[1]; };
54
+
55
+ typedef struct { Value k, v; } Entry;
56
+ struct Table {
57
+ Obj o;
58
+ Value *arr; int alen, acap; /* array part: 1..alen */
59
+ Entry *ents; int ecap, ecount; /* hash part: open addressing */
60
+ unsigned tid, ver; /* inline cache id + version */
61
+ struct Table *meta; /* metatable: __index/__call/... */
62
+ };
63
+
64
+ typedef struct { unsigned char instack; unsigned char idx; } UpvalDesc;
65
+ struct Proto {
66
+ Obj o;
67
+ uint32_t *code; int ncode, ccap;
68
+ int *lines;
69
+ Value *k; int nk, kcap;
70
+ Proto **p; int np, pcap;
71
+ UpvalDesc upvals[LUC_MAXUPVAL];
72
+ int nparams, isvararg, maxstack, nup;
73
+ Str *name, *source;
74
+ int uses_karatsuba; /* !karatsuba: exact big-int * here */
75
+ int uses_strict; /* !strict: no implicit globals, quoted dict keys */
76
+ };
77
+
78
+ struct Upval {
79
+ Obj o; LucState *L; int idx; int isclosed; Value closed; Upval *next;
80
+ };
81
+ #define UPVAL_PTR(u) ((u)->isclosed ? &(u)->closed : &(u)->L->stack[(u)->idx])
82
+
83
+ struct Closure { Obj o; Proto *p; int nup; Upval **up; };
84
+
85
+ typedef int (*CFn)(LucState *L,int base,int nargs,CFunc *self);
86
+ struct CFunc { Obj o; CFn fn; const char *name; int nup; Value *up; };
87
+
88
+ struct Buffer { Obj o; int len; unsigned char *b; };
89
+ struct FileH { Obj o; FILE *f; int closed, isstd, ispipe; };
90
+ struct Socket { Obj o; intptr_t fd; int closed; unsigned char isserver; void *tlsctx;
91
+ unsigned char isws; char *rbuf, *frag; size_t rlen, rcap, fraglen, fragcap; };
92
+
93
+ typedef struct CallInfo {
94
+ Closure *cl;
95
+ int func, base, nresults;
96
+ uint32_t *savedpc;
97
+ } CallInfo;
98
+
99
+ enum { CO_START=0, CO_SUSPENDED, CO_RUNNING, CO_NORMAL, CO_DEAD };
100
+
101
+ struct LucState {
102
+ Obj o;
103
+ Value *stack; int stacksize, top;
104
+ CallInfo *ci; int nci, cicap;
105
+ Upval *openupv;
106
+ int status;
107
+ LucState *resumer;
108
+ int yield_A, yield_C; /* resume value slots */
109
+ int yieldbase, nyield; /* yielded values slot */
110
+ int npending; /* pre-pushed first-resume args */
111
+ double waketime; int scheduled;
112
+ Str *cursource; int curline;
113
+ };
114
+
115
+ extern Value NIL;
116
+
117
+ #define AS_STR(v) ((Str*)(v).u.o)
118
+ #define AS_TAB(v) ((Table*)(v).u.o)
119
+ #define AS_CL(v) ((Closure*)(v).u.o)
120
+ #define AS_CF(v) ((CFunc*)(v).u.o)
121
+ #define AS_BUF(v) ((Buffer*)(v).u.o)
122
+ #define AS_CO(v) ((LucState*)(v).u.o)
123
+ #define AS_FILE(v) ((FileH*)(v).u.o)
124
+ #define AS_SOCK(v) ((Socket*)(v).u.o)
125
+
126
+ /* 1b. opcodes + codecs (core/trans shared) */
127
+ enum {
128
+ OP_MOVE, OP_LOADK, OP_LOADNIL, OP_LOADBOOL,
129
+ OP_GETGLOBAL, OP_SETGLOBAL, OP_GETUPVAL, OP_SETUPVAL,
130
+ OP_GETTABLE, OP_SETTABLE, OP_NEWTABLE, OP_SETLIST, OP_SELF,
131
+ OP_ADD, OP_SUB, OP_MUL, OP_DIV, OP_MOD, OP_POW,
132
+ OP_UNM, OP_NOT, OP_LEN, OP_CONCAT,
133
+ OP_EQ, OP_NE, OP_LT, OP_LE, OP_GT, OP_GE, OP_IN,
134
+ OP_JMP, OP_JMPIF, OP_JMPIFNOT,
135
+ OP_CALL, OP_RETURN, OP_CLOSURE, OP_VARARG, OP_CLOSE,
136
+ OP_FORPREP, OP_FORLOOP, OP_TFORLOOP, OP_SLICE, OP_NEXT,
137
+ OP_APPEND, OP_ADDEQ, OP_SUBEQ, OP_MULEQ, OP_DIVEQ,
138
+ OP_COUNT
139
+ };
140
+
141
+ #define I_ABC(o,a,b,c) (((uint32_t)(o)<<24)|(((uint32_t)(a)&0xFFu)<<16)|(((uint32_t)(b)&0xFFu)<<8)|((uint32_t)(c)&0xFFu))
142
+ #define I_ABx(o,a,bx) (((uint32_t)(o)<<24)|(((uint32_t)(a)&0xFFu)<<16)|((uint32_t)(bx)&0xFFFFu))
143
+ #define I_AsBx(o,a,s) I_ABx(o,a,(int)(s)+32767)
144
+
145
+ #define GET_OP(i) ((int)((i)>>24))
146
+ #define GET_A(i) ((int)(((i)>>16)&0xFFu))
147
+ #define GET_B(i) ((int)(((i)>>8)&0xFFu))
148
+ #define GET_C(i) ((int)((i)&0xFFu))
149
+ #define GET_Bx(i) ((int)((i)&0xFFFFu))
150
+ #define GET_sBx(i) (GET_Bx(i)-32767)
151
+
152
+ /* 2. global VM state (core) */
153
+
154
+ typedef struct ErrJmp { jmp_buf jb; struct ErrJmp *prev; } ErrJmp;
155
+
156
+ typedef struct { LucState *co; double wake; } SchedEntry;
157
+
158
+ typedef struct LucV {
159
+ Obj *objects;
160
+ Str **strtab; int strcap, nstr;
161
+ size_t nalloc, gcthresh;
162
+ int gcoff;
163
+
164
+ Table *globals;
165
+ Table *stringlib, *listmeta, *bufferlib, *filelib;
166
+ Table *listcore; /* list core methods (shadow listmeta) */
167
+ Table *tabmeta; /* dict methods via dot access */
168
+ Table *socklib; /* socket methods (import net) */
169
+
170
+ LucState *mainco, *cur;
171
+
172
+ ErrJmp *errjmp;
173
+ Value errval;
174
+
175
+ SchedEntry *sched; int nsched, schedcap;
176
+ Table *loaded; /* module cache for require() */
177
+ unsigned tidcounter; /* inline cache id */
178
+ } LucV;
179
+
180
+ extern LucV V;
181
+
182
+ /* yield machinery (core, for coro/task) */
183
+ typedef struct YieldPt { jmp_buf jb; struct YieldPt *prev; LucState *co; int cdepth; } YieldPt;
184
+ extern YieldPt *g_yp;
185
+
186
+ /* core funcs for libs */
187
+
188
+ /* platform (core) */
189
+ double luc_now(void);
190
+ void luc_sleep(double s);
191
+ void *lmalloc(size_t n);
192
+ void *lrealloc(void *p,size_t n);
193
+ void *lcalloc(size_t n);
194
+
195
+ /* values (inline helpers below) */
196
+ int truthy(Value v);
197
+ const char *type_name(Value v);
198
+
199
+ /* errors */
200
+ void luc_error(const char *fmt,...);
201
+ void luc_throw(Value err);
202
+
203
+ /* strings */
204
+ Str *str_new(const char *s,int len);
205
+ void num2str(double n,char *buf,size_t sz);
206
+ int str2num(const char *s,int len,double *out);
207
+ Str *tostr(Value v);
208
+ extern const char *const HEXD; /* hex digits (string+buffer) */
209
+ int hexval(int c); /* hex digit to value */
210
+
211
+ static inline Value mknum(double d){ Value v; v.t=LT_NUM; v.u.n=d; return v; }
212
+ static inline Value mkbool(int b){ Value v; v.t=LT_BOOL; v.u.b=(b!=0); return v; }
213
+ static inline Value mkobj(int t,void*o){ Value v; v.t=t; v.u.o=(Obj*)o; return v; }
214
+ static inline Str *str_fromc(const char *s){ return str_new(s,(int)strlen(s)); }
215
+ static inline Value strv(const char *s,int n){ return mkobj(LT_STR,str_new(s,n)); }
216
+ static inline Value cstrv(const char *s){ return mkobj(LT_STR,str_fromc(s)); }
217
+
218
+ /* tables & lists */
219
+ Table *tab_new(int islist);
220
+ Value tab_get(Table *t,Value k);
221
+ void tab_set(Table *t,Value k,Value v);
222
+ int tab_len(Table *t);
223
+ int tab_next(Table *t,Value key,Value *ok,Value *ov);
224
+ void list_push(Table *t,Value v);
225
+ void list_insert(Table *t,int pos,Value v);
226
+ Value list_removeat(Table *t,int pos);
227
+ int val_rawequal(Value a,Value b);
228
+
229
+ /* object constructors */
230
+ Buffer *buf_new(int n);
231
+ CFunc *cfunc_new(CFn fn,const char *name,int nup);
232
+ FileH *file_new(FILE *f,int isstd);
233
+ Socket *sock_new(intptr_t fd,int isserver);
234
+ LucState *state_new(int stacksize);
235
+ void ensure_stack(LucState *L,int need);
236
+
237
+ /* GC */
238
+ void gc_collect(void);
239
+
240
+ /* VM internals for libs */
241
+ int vm_call(LucState *L,int func,int nargs,int nres);
242
+ int vm_len(Value v);
243
+ int vm_lessthan(Value a,Value b,int orequal);
244
+ int vm_in(Value x,Value c);
245
+ void close_upvals(LucState *L,int level);
246
+ int co_resume(LucState *co,Value *args,int nargs,Value *res,int *nres);
247
+ void sched_add(LucState *co,double wake);
248
+ void sched_remove(int i);
249
+ void sched_run(void);
250
+ void sched_poll(void); /* run due tasks now, no sleep */
251
+
252
+ /* compiler + modules (require/import) */
253
+ Closure *luc_compile(const char *src,int len,const char *chunkname);
254
+ char *find_module(const char *name,int *len,char *found,size_t fcap);
255
+ char *find_system_module(const char *name,int *len,char *found,size_t fcap);
256
+ const char *luc_scriptdir(void);
257
+ int part_make_name(const char *path,char *out,size_t cap);
258
+ char *find_pack(const char *name,int *len,char *found,size_t fcap);
259
+
260
+ /* lib registration helpers (core) */
261
+ void reg(Table *t,const char *name,CFn fn);
262
+ Table *newlib(const char *name);
263
+
264
+ /* arg-check helpers (core) */
265
+ double checknum (LucState *L,int base,int nargs,int i,const char *fn);
266
+ int checkint (LucState *L,int base,int nargs,int i,const char *fn);
267
+ Str *checkstr (LucState *L,int base,int nargs,int i,const char *fn);
268
+ Table *checktab (LucState *L,int base,int nargs,int i,const char *fn);
269
+ Buffer *checkbuf (LucState *L,int base,int nargs,int i,const char *fn);
270
+ uint32_t checku32 (LucState *L,int base,int nargs,int i,const char *fn);
271
+
272
+ /* lib-side helpers */
273
+ int luc_try_bigmul(Value x,Value y,int force,Value *out);
274
+
275
+ #define LFN(name) static int name(LucState *L,int base,int nargs,CFunc *self)
276
+ #define UNUSED_SELF (void)self
277
+
278
+ static inline Value argv_(LucState *L,int base,int nargs,int i){
279
+ return i<nargs? L->stack[base+i] : NIL;
280
+ }
281
+ #define AR(i) argv_(L,base,nargs,(i))
282
+ #define RET(i,v) do{ ensure_stack(L,base+(i)+2); L->stack[base+(i)]=(v); }while(0)
283
+
284
+ /* shared base<->table helper (base) */
285
+ int f_unpack(LucState *L,int base,int nargs,CFunc *self);
286
+
287
+ /* module entry points (one per lib) */
288
+
289
+ void lucL_open_base(void); /* luc_lib_base.c */
290
+ void lucL_open_string(void); /* luc_lib_string.c */
291
+ void lucL_open_list(void); /* luc_lib_list.c */
292
+ void lucL_open_math(void); /* luc_lib_math.c */
293
+ void lucL_open_os(void); /* luc_lib_os.c */
294
+ void lucL_open_io(void); /* luc_lib_io.c */
295
+ void lucL_open_buffer(void); /* luc_lib_buffer.c */
296
+ void lucL_open_coro(void); /* luc_lib_coro.c */
297
+ void lucL_open_net(void); /* luc_lib_net.c */
298
+ Value lucL_json_module(void); /* luc_lib_json.c (require) */
299
+ Value lucL_window_module(void); /* luc_lib_window.c (require) */
300
+ Value lucL_net_module(LucState *L); /* luc_lib_net.c (import) */
301
+ void net_socket_close_fd(Socket *s); /* luc_lib_net.c (GC fd cleanup) */
302
+
303
+ #endif /* LUC_H */