1 /*
2 * Copyright (c) 2020 Calvin Rose
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to
6 * deal in the Software without restriction, including without limitation the
7 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 * sell copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20 * IN THE SOFTWARE.
21 */
22 
23 module janet.c;
24 
25 import core.stdc.stdarg;
26 import core.stdc.stddef;
27 import core.stdc.stdint;
28 import core.stdc.stdio;
29 
30 extern (C):
31 
32 /* Variable length arrays are ok */
33 
34 /***** START SECTION CONFIG *****/
35 
36 enum JANET_BUILD = "local";
37 
38 /*
39  * Detect OS and endianess.
40  * From webkit source. There is likely some extreneous
41  * detection for unsupported platforms
42  */
43 
44 /* Check for any flavor of BSD (except apple) */
45 
46 /* Check for Mac */
47 
48 /* Check for Linux */
49 
50 /* Check Unix */
51 
52 /* Darwin */
53 
54 /* GNU/Hurd */
55 
56 /* Solaris */
57 
58 enum JANET_WINDOWS = 1;
59 
60 /* Check 64-bit vs 32-bit */ /* Windows 64 bit */
61 /* Itanium in LP64 mode */
62 /* DEC Alpha */
63 /* BE */
64 /* S390 64-bit (BE) */
65 
66 /* ARM 64-bit */
67 enum JANET_64 = 1;
68 
69 /* Check big endian */
70 /* If we know the target is LE, always use that - e.g. ppc64 little endian
71  * defines the __LITTLE_ENDIAN__ macro in the ABI spec, so we can rely
72  * on that and if that's not defined, fall back to big endian assumption
73  */
74 enum JANET_LITTLE_ENDIAN = 1;
75 /* MIPS 32-bit */
76 /* CPU(PPC) - PowerPC 32-bit */
77 
78 /* PowerPC 64-bit */
79 /* Sparc 32bit */
80 /* Sparc 64-bit */
81 /* S390 64-bit */
82 /* S390 32-bit */
83 /* ARM big endian */
84 /* ARM RealView compiler */
85 
86 /* Check emscripten */
87 
88 /* Check sun */
89 
90 /* Add some windows flags */
91 
92 /* Define how global janet state is declared */
93 
94 /* Enable or disable dynamic module loading. Enabled by default. */
95 
96 /* Enable or disable the assembler. Enabled by default. */
97 
98 /* Enable or disable the peg module */
99 
100 /* Enable or disable the typedarray module */
101 
102 /* Enable or disable networking */
103 
104 /* Enable or disable large int types (for now 64 bit, maybe 128 / 256 bit integer types) */
105 
106 /* How to export symbols */
107 
108 /* Tell complier some functions don't return */
109 
110 /* Prevent some recursive functions from recursing too deeply
111  * ands crashing (the parser). Instead, error out. */
112 enum JANET_RECURSION_GUARD = 1024;
113 
114 /* Maximum depth to follow table prototypes before giving up and returning nil. */
115 enum JANET_MAX_PROTO_DEPTH = 200;
116 
117 /* Maximum depth to follow table prototypes before giving up and returning nil. */
118 enum JANET_MAX_MACRO_EXPAND = 200;
119 
120 /* Define default max stack size for stacks before raising a stack overflow error.
121  * This can also be set on a per fiber basis. */
122 
123 enum JANET_STACK_MAX = 0x7fffffff;
124 
125 /* Use nanboxed values - uses 8 bytes per value instead of 12 or 16.
126  * To turn of nanboxing, for debugging purposes or for certain
127  * architectures (Nanboxing only tested on x86 and x64), comment out
128  * the JANET_NANBOX define.*/
129 
130 /* We will only enable nanboxing by default on 64 bit systems
131  * on x86. This is mainly because the approach is tied to the
132  * implicit 47 bit address space. */
133 
134 /* Runtime config constants */
135 enum JANET_NANBOX_BIT = 0;
136 
137 enum JANET_SINGLE_THREADED_BIT = 0;
138 
139 enum JANET_CURRENT_CONFIG_BITS = JANET_SINGLE_THREADED_BIT | JANET_NANBOX_BIT;
140 
141 /* Represents the settings used to compile Janet, as well as the version */
142 struct JanetBuildConfig
143 {
144     uint major;
145     uint minor;
146     uint patch;
147     uint bits;
148 }
149 
150 /* Get config of current compilation unit. */
151 
152 /***** END SECTION CONFIG *****/
153 
154 /***** START SECTION TYPES *****/
155 
156 // Must be defined before including stdlib.h
157 
158 /* Names of all of the types */
159 extern __gshared const(char*)[16] janet_type_names;
160 extern __gshared const(char*)[14] janet_signal_names;
161 extern __gshared const(char*)[16] janet_status_names;
162 
163 /* Fiber signals */
164 enum JanetSignal
165 {
166     JANET_SIGNAL_OK = 0,
167     JANET_SIGNAL_ERROR = 1,
168     JANET_SIGNAL_DEBUG = 2,
169     JANET_SIGNAL_YIELD = 3,
170     JANET_SIGNAL_USER0 = 4,
171     JANET_SIGNAL_USER1 = 5,
172     JANET_SIGNAL_USER2 = 6,
173     JANET_SIGNAL_USER3 = 7,
174     JANET_SIGNAL_USER4 = 8,
175     JANET_SIGNAL_USER5 = 9,
176     JANET_SIGNAL_USER6 = 10,
177     JANET_SIGNAL_USER7 = 11,
178     JANET_SIGNAL_USER8 = 12,
179     JANET_SIGNAL_USER9 = 13
180 }
181 
182 enum JANET_SIGNAL_EVENT = JanetSignal.JANET_SIGNAL_USER9;
183 
184 /* Fiber statuses - mostly corresponds to signals. */
185 enum JanetFiberStatus
186 {
187     JANET_STATUS_DEAD = 0,
188     JANET_STATUS_ERROR = 1,
189     JANET_STATUS_DEBUG = 2,
190     JANET_STATUS_PENDING = 3,
191     JANET_STATUS_USER0 = 4,
192     JANET_STATUS_USER1 = 5,
193     JANET_STATUS_USER2 = 6,
194     JANET_STATUS_USER3 = 7,
195     JANET_STATUS_USER4 = 8,
196     JANET_STATUS_USER5 = 9,
197     JANET_STATUS_USER6 = 10,
198     JANET_STATUS_USER7 = 11,
199     JANET_STATUS_USER8 = 12,
200     JANET_STATUS_USER9 = 13,
201     JANET_STATUS_NEW = 14,
202     JANET_STATUS_ALIVE = 15
203 }
204 
205 /* Use type punning for GC objects */
206 
207 /* All of the primary Janet GCed types */
208 
209 /* Prefixed Janet types */
210 
211 /* Other structs */
212 
213 /* Basic types for all Janet Values */
214 enum JanetType
215 {
216     JANET_NUMBER = 0,
217     JANET_NIL = 1,
218     JANET_BOOLEAN = 2,
219     JANET_FIBER = 3,
220     JANET_STRING = 4,
221     JANET_SYMBOL = 5,
222     JANET_KEYWORD = 6,
223     JANET_ARRAY = 7,
224     JANET_TUPLE = 8,
225     JANET_TABLE = 9,
226     JANET_STRUCT = 10,
227     JANET_BUFFER = 11,
228     JANET_FUNCTION = 12,
229     JANET_CFUNCTION = 13,
230     JANET_ABSTRACT = 14,
231     JANET_POINTER = 15
232 }
233 
234 /* Recursive type (Janet) */
235 
236 struct Janet
237 {
238     union _Anonymous_0
239     {
240         ulong u64;
241         double number;
242         int integer;
243         void* pointer;
244         const(void)* cpointer;
245     }
246 
247     _Anonymous_0 as_c;
248     JanetType type;
249 }
250 
251 /* C functions */
252 alias JanetCFunction = Janet function (int argc, Janet* argv);
253 
254 @nogc:
255 
256 /* String and other aliased pointer types */
257 alias JanetString = const(ubyte)*;
258 alias JanetSymbol = const(ubyte)*;
259 alias JanetKeyword = const(ubyte)*;
260 alias JanetTuple = const(Janet)*;
261 alias JanetStruct = const(JanetKV)*;
262 alias JanetAbstract = void*;
263 
264 enum JANET_COUNT_TYPES = JanetType.JANET_POINTER + 1;
265 
266 /* Type flags */
267 enum JANET_TFLAG_NIL = 1 << JanetType.JANET_NIL;
268 enum JANET_TFLAG_BOOLEAN = 1 << JanetType.JANET_BOOLEAN;
269 enum JANET_TFLAG_FIBER = 1 << JanetType.JANET_FIBER;
270 enum JANET_TFLAG_NUMBER = 1 << JanetType.JANET_NUMBER;
271 enum JANET_TFLAG_STRING = 1 << JanetType.JANET_STRING;
272 enum JANET_TFLAG_SYMBOL = 1 << JanetType.JANET_SYMBOL;
273 enum JANET_TFLAG_KEYWORD = 1 << JanetType.JANET_KEYWORD;
274 enum JANET_TFLAG_ARRAY = 1 << JanetType.JANET_ARRAY;
275 enum JANET_TFLAG_TUPLE = 1 << JanetType.JANET_TUPLE;
276 enum JANET_TFLAG_TABLE = 1 << JanetType.JANET_TABLE;
277 enum JANET_TFLAG_STRUCT = 1 << JanetType.JANET_STRUCT;
278 enum JANET_TFLAG_BUFFER = 1 << JanetType.JANET_BUFFER;
279 enum JANET_TFLAG_FUNCTION = 1 << JanetType.JANET_FUNCTION;
280 enum JANET_TFLAG_CFUNCTION = 1 << JanetType.JANET_CFUNCTION;
281 enum JANET_TFLAG_ABSTRACT = 1 << JanetType.JANET_ABSTRACT;
282 enum JANET_TFLAG_POINTER = 1 << JanetType.JANET_POINTER;
283 
284 enum JANET_TFLAG_BYTES = JANET_TFLAG_STRING | JANET_TFLAG_SYMBOL | JANET_TFLAG_BUFFER | JANET_TFLAG_KEYWORD;
285 enum JANET_TFLAG_INDEXED = JANET_TFLAG_ARRAY | JANET_TFLAG_TUPLE;
286 enum JANET_TFLAG_DICTIONARY = JANET_TFLAG_TABLE | JANET_TFLAG_STRUCT;
287 enum JANET_TFLAG_LENGTHABLE = JANET_TFLAG_BYTES | JANET_TFLAG_INDEXED | JANET_TFLAG_DICTIONARY;
288 enum JANET_TFLAG_CALLABLE = JANET_TFLAG_FUNCTION | JANET_TFLAG_CFUNCTION | JANET_TFLAG_LENGTHABLE | JANET_TFLAG_ABSTRACT;
289 
290 /* We provide three possible implementations of Janets. The preferred
291  * nanboxing approach, for 32 or 64 bits, and the standard C version. Code in the rest of the
292  * application must interact through exposed interface. */
293 
294 /* Required interface for Janet */
295 /* wrap and unwrap for all types */
296 /* Get type quickly */
297 /* Check against type quickly */
298 /* Small footprint */
299 /* 32 bit integer support */
300 
301 /* janet_type(x)
302  * janet_checktype(x, t)
303  * janet_wrap_##TYPE(x)
304  * janet_unwrap_##TYPE(x)
305  * janet_truthy(x)
306  * janet_memclear(p, n) - clear memory for hash tables to nils
307  * janet_u64(x) - get 64 bits of payload for hashing
308  */
309 
310 /***** START SECTION NON-C API *****/
311 
312 /* Some janet types use offset tricks to make operations easier in C. For
313  * external bindings, we should prefer using the Head structs directly, and
314  * use the host language to add sugar around the manipulation of the Janet types. */
315 
316 pure JanetStructHead* janet_struct_head (const(JanetKV)* st);
317 pure JanetAbstractHead* janet_abstract_head (const(void)* abstract_);
318 pure JanetStringHead* janet_string_head (const(ubyte)* s);
319 pure JanetTupleHead* janet_tuple_head (const(Janet)* tuple);
320 
321 /* Some language bindings won't have access to the macro versions. */
322 
323 pure JanetType janet_type (Janet x);
324 pure int janet_checktype (Janet x, JanetType type);
325 pure int janet_checktypes (Janet x, int typeflags);
326 pure int janet_truthy (Janet x);
327 
328 pure const(JanetKV)* janet_unwrap_struct (Janet x);
329 pure const(Janet)* janet_unwrap_tuple (Janet x);
330 pure JanetFiber* janet_unwrap_fiber (Janet x);
331 pure JanetArray* janet_unwrap_array (Janet x);
332 pure JanetTable* janet_unwrap_table (Janet x);
333 pure JanetBuffer* janet_unwrap_buffer (Janet x);
334 pure const(ubyte)* janet_unwrap_string (Janet x);
335 pure const(ubyte)* janet_unwrap_symbol (Janet x);
336 pure const(ubyte)* janet_unwrap_keyword (Janet x);
337 pure void* janet_unwrap_abstract (Janet x);
338 pure void* janet_unwrap_pointer (Janet x);
339 pure JanetFunction* janet_unwrap_function (Janet x);
340 pure JanetCFunction janet_unwrap_cfunction (Janet x);
341 pure int janet_unwrap_boolean (Janet x);
342 pure double janet_unwrap_number (Janet x);
343 pure int janet_unwrap_integer (Janet x);
344 
345 @safe Janet janet_wrap_nil ();
346 Janet janet_wrap_number (double x);
347 Janet janet_wrap_true ();
348 Janet janet_wrap_false ();
349 Janet janet_wrap_boolean (int x);
350 Janet janet_wrap_string (const(ubyte)* x);
351 Janet janet_wrap_symbol (const(ubyte)* x);
352 Janet janet_wrap_keyword (const(ubyte)* x);
353 Janet janet_wrap_array (JanetArray* x);
354 Janet janet_wrap_tuple (const(Janet)* x);
355 Janet janet_wrap_struct (const(JanetKV)* x);
356 Janet janet_wrap_fiber (JanetFiber* x);
357 Janet janet_wrap_buffer (JanetBuffer* x);
358 Janet janet_wrap_function (JanetFunction* x);
359 Janet janet_wrap_cfunction (JanetCFunction x);
360 Janet janet_wrap_table (JanetTable* x);
361 Janet janet_wrap_abstract (void* x);
362 Janet janet_wrap_pointer (void* x);
363 Janet janet_wrap_integer (int x);
364 
365 /***** END SECTION NON-C API *****/
366 
367 /* Wrap the simple types */
368 
369 /* Unwrap the simple types */
370 
371 /* Wrap the pointer types */
372 
373 /* Unwrap the pointer types */
374 
375 /* Wrap the pointer types */
376 
377 pure @safe extern (D) auto janet_u64(T)(auto ref T x)
378 {
379     return x.as.u64;
380 }
381 
382 pure @safe extern (D) auto janet_type(T)(auto ref T x)
383 {
384     return x.type;
385 }
386 
387 pure @safe extern (D) auto janet_checktype(T0, T1)(auto ref T0 x, auto ref T1 t)
388 {
389     return x.type == t;
390 }
391 
392 pure @safe extern (D) auto janet_truthy(T)(auto ref T x)
393 {
394     return x.type != JanetType.JANET_NIL && (x.type != JanetType.JANET_BOOLEAN || (x.as.u64 & 0x1));
395 }
396 
397 pure extern (D) auto janet_unwrap_struct(T)(auto ref T x)
398 {
399     return cast(const(JanetKV)*) x.as.pointer;
400 }
401 
402 pure extern (D) auto janet_unwrap_tuple(T)(auto ref T x)
403 {
404     return cast(const(Janet)*) x.as.pointer;
405 }
406 
407 pure extern (D) auto janet_unwrap_fiber(T)(auto ref T x)
408 {
409     return cast(JanetFiber*) x.as.pointer;
410 }
411 
412 pure extern (D) auto janet_unwrap_array(T)(auto ref T x)
413 {
414     return cast(JanetArray*) x.as.pointer;
415 }
416 
417 pure extern (D) auto janet_unwrap_table(T)(auto ref T x)
418 {
419     return cast(JanetTable*) x.as.pointer;
420 }
421 
422 pure extern (D) auto janet_unwrap_buffer(T)(auto ref T x)
423 {
424     return cast(JanetBuffer*) x.as.pointer;
425 }
426 
427 pure extern (D) auto janet_unwrap_string(T)(auto ref T x)
428 {
429     return cast(const(ubyte)*) x.as.pointer;
430 }
431 
432 pure extern (D) auto janet_unwrap_symbol(T)(auto ref T x)
433 {
434     return cast(const(ubyte)*) x.as.pointer;
435 }
436 
437 pure extern (D) auto janet_unwrap_keyword(T)(auto ref T x)
438 {
439     return cast(const(ubyte)*) x.as.pointer;
440 }
441 
442 pure extern (D) auto janet_unwrap_abstract(T)(auto ref T x)
443 {
444     return x.as.pointer;
445 }
446 
447 pure extern (D) auto janet_unwrap_pointer(T)(auto ref T x)
448 {
449     return x.as.pointer;
450 }
451 
452 pure extern (D) auto janet_unwrap_function(T)(auto ref T x)
453 {
454     return cast(JanetFunction*) x.as.pointer;
455 }
456 
457 pure extern (D) auto janet_unwrap_cfunction(T)(auto ref T x)
458 {
459     return cast(JanetCFunction) x.as.pointer;
460 }
461 
462 pure @safe extern (D) auto janet_unwrap_boolean(T)(auto ref T x)
463 {
464     return x.as.u64 & 0x1;
465 }
466 
467 pure @safe extern (D) auto janet_unwrap_number(T)(auto ref T x)
468 {
469     return x.as.number;
470 }
471 
472 /* End of tagged union implementation */
473 
474 pure int janet_checkint (Janet x);
475 pure int janet_checkint64 (Janet x);
476 pure int janet_checksize (Janet x);
477 JanetAbstract janet_checkabstract (Janet x, const(JanetAbstractType)* at);
478 
479 pure @safe extern (D) auto janet_checkintrange(T)(auto ref T x)
480 {
481     return x >= INT32_MIN && x <= INT32_MAX && x == cast(int) x;
482 }
483 
484 pure @safe extern (D) auto janet_checkint64range(T)(auto ref T x)
485 {
486     return x >= INT64_MIN && x <= INT64_MAX && x == cast(long) x;
487 }
488 
489 pure @safe extern (D) auto janet_unwrap_integer(T)(auto ref T x)
490 {
491     return cast(int) janet_unwrap_number(x);
492 }
493 
494 pure @safe extern (D) auto janet_wrap_integer(T)(auto ref T x)
495 {
496     return janet_wrap_number(cast(int) x);
497 }
498 
499 pure @safe extern (D) auto janet_checktypes(T0, T1)(auto ref T0 x, auto ref T1 tps)
500 {
501     return (1 << janet_type(x)) & tps;
502 }
503 
504 /* GC Object type pun. The lower 16 bits of flags are reserved for the garbage collector,
505  * but the upper 16 can be used per type for custom flags. The current collector is a linked
506  * list of blocks, which is naive but works. */
507 struct JanetGCObject
508 {
509     int flags;
510     JanetGCObject* next;
511 }
512 
513 /* A lightweight green thread in janet. Does not correspond to
514  * operating system threads. */
515 struct JanetFiber
516 {
517     JanetGCObject gc; /* GC Object stuff */
518     int flags; /* More flags */
519     int frame; /* Index of the stack frame */
520     int stackstart; /* Beginning of next args */
521     int stacktop; /* Top of stack. Where values are pushed and popped from. */
522     int capacity;
523     int maxstack; /* Arbitrary defined limit for stack overflow */
524     JanetTable* env; /* Dynamic bindings table (usually current environment). */
525     Janet* data;
526     JanetFiber* child; /* Keep linked list of fibers for restarting pending fibers */
527 }
528 
529 /* Mark if a stack frame is a tail call for debugging */
530 enum JANET_STACKFRAME_TAILCALL = 1;
531 
532 /* Mark if a stack frame is an entrance frame */
533 enum JANET_STACKFRAME_ENTRANCE = 2;
534 
535 /* A stack frame on the fiber. Is stored along with the stack values. */
536 struct JanetStackFrame
537 {
538     JanetFunction* func;
539     uint* pc;
540     JanetFuncEnv* env;
541     int prevframe;
542     int flags;
543 }
544 
545 /* Number of Janets a frame takes up in the stack
546  * Should be constant across architectures */
547 enum JANET_FRAME_SIZE = 4;
548 
549 /* A dynamic array type. */
550 struct JanetArray
551 {
552     JanetGCObject gc;
553     int count;
554     int capacity;
555     Janet* data;
556 }
557 
558 /* A byte buffer type. Used as a mutable string or string builder. */
559 struct JanetBuffer
560 {
561     JanetGCObject gc;
562     int count;
563     int capacity;
564     ubyte* data;
565 }
566 
567 /* A mutable associative data type. Backed by a hashtable. */
568 struct JanetTable
569 {
570     JanetGCObject gc;
571     int count;
572     int capacity;
573     int deleted;
574     JanetKV* data;
575     JanetTable* proto;
576 }
577 
578 /* A key value pair in a struct or table */
579 struct JanetKV
580 {
581     Janet key;
582     Janet value;
583 }
584 
585 /* Prefix for a tuple */
586 struct JanetTupleHead
587 {
588     JanetGCObject gc;
589     int length;
590     int hash;
591     int sm_line;
592     int sm_column;
593     const(Janet)[] data;
594 }
595 
596 /* Prefix for a struct */
597 struct JanetStructHead
598 {
599     JanetGCObject gc;
600     int length;
601     int hash;
602     int capacity;
603     const(JanetKV)[] data;
604 }
605 
606 /* Prefix for a string */
607 struct JanetStringHead
608 {
609     JanetGCObject gc;
610     int length;
611     int hash;
612     const(ubyte)[] data;
613 }
614 
615 /* Prefix for an abstract value */
616 struct JanetAbstractHead
617 {
618     JanetGCObject gc;
619     const(JanetAbstractType)* type;
620     size_t size;
621     long[] data; /* Use long long to ensure most general alignment */
622 }
623 
624 /* Some function definition flags */
625 enum JANET_FUNCDEF_FLAG_VARARG = 0x10000;
626 enum JANET_FUNCDEF_FLAG_NEEDSENV = 0x20000;
627 enum JANET_FUNCDEF_FLAG_HASNAME = 0x80000;
628 enum JANET_FUNCDEF_FLAG_HASSOURCE = 0x100000;
629 enum JANET_FUNCDEF_FLAG_HASDEFS = 0x200000;
630 enum JANET_FUNCDEF_FLAG_HASENVS = 0x400000;
631 enum JANET_FUNCDEF_FLAG_HASSOURCEMAP = 0x800000;
632 enum JANET_FUNCDEF_FLAG_STRUCTARG = 0x1000000;
633 enum JANET_FUNCDEF_FLAG_HASCLOBITSET = 0x2000000;
634 enum JANET_FUNCDEF_FLAG_TAG = 0xFFFF;
635 
636 /* Source mapping structure for a bytecode instruction */
637 struct JanetSourceMapping
638 {
639     int line;
640     int column;
641 }
642 
643 /* A function definition. Contains information needed to instantiate closures. */
644 struct JanetFuncDef
645 {
646     JanetGCObject gc;
647     int* environments; /* Which environments to capture from parent. */
648     Janet* constants;
649     JanetFuncDef** defs;
650     uint* bytecode;
651     uint* closure_bitset; /* Bit set indicating which slots can be referenced by closures. */
652 
653     /* Various debug information */
654     JanetSourceMapping* sourcemap;
655     JanetString source;
656     JanetString name;
657 
658     int flags;
659     int slotcount; /* The amount of stack space required for the function */
660     int arity; /* Not including varargs */
661     int min_arity; /* Including varargs */
662     int max_arity; /* Including varargs */
663     int constants_length;
664     int bytecode_length;
665     int environments_length;
666     int defs_length;
667 }
668 
669 /* A function environment */
670 struct JanetFuncEnv
671 {
672     JanetGCObject gc;
673 
674     union _Anonymous_1
675     {
676         JanetFiber* fiber;
677         Janet* values;
678     }
679 
680     _Anonymous_1 as;
681     int length; /* Size of environment */
682     int offset; /* Stack offset when values still on stack. If offset is <= 0, then
683     environment is no longer on the stack. */
684 }
685 
686 enum JANET_FUNCFLAG_TRACE = 1 << 16;
687 
688 /* A function */
689 struct JanetFunction
690 {
691     JanetGCObject gc;
692     JanetFuncDef* def;
693     JanetFuncEnv*[] envs;
694 }
695 
696 struct JanetParseState;
697 
698 enum JanetParserStatus
699 {
700     JANET_PARSE_ROOT = 0,
701     JANET_PARSE_ERROR = 1,
702     JANET_PARSE_PENDING = 2,
703     JANET_PARSE_DEAD = 3
704 }
705 
706 /* A janet parser */
707 struct JanetParser
708 {
709     Janet* args;
710     const(char)* error;
711     JanetParseState* states;
712     ubyte* buf;
713     size_t argcount;
714     size_t argcap;
715     size_t statecount;
716     size_t statecap;
717     size_t bufcount;
718     size_t bufcap;
719     size_t line;
720     size_t column;
721     size_t pending;
722     int lookback;
723     int flag;
724 }
725 
726 /* A context for marshaling and unmarshaling abstract types */
727 struct JanetMarshalContext
728 {
729     void* m_state;
730     void* u_state;
731     int flags;
732     const(ubyte)* data;
733     const(JanetAbstractType)* at;
734 }
735 
736 /* Defines an abstract type */
737 struct JanetAbstractType
738 {
739     const(char)* name;
740     int function (void* data, size_t len) gc;
741     int function (void* data, size_t len) gcmark;
742     int function (void* data, Janet key, Janet* out_) get;
743     void function (void* data, Janet key, Janet value) put;
744     void function (void* p, JanetMarshalContext* ctx) marshal;
745     void* function (JanetMarshalContext* ctx) unmarshal;
746     void function (void* p, JanetBuffer* buffer) tostring;
747     int function (void* lhs, void* rhs) compare;
748     int function (void* p, size_t len) hash;
749     Janet function (void* p, Janet key) next;
750     Janet function (void* p, int argc, Janet* argv) call;
751 }
752 
753 /* Some macros to let us add extra types to JanetAbstract types without
754  * needing to changing native modules that declare them as static const
755  * structures. If more fields are added, these macros are modified to include
756  * default values (usually NULL). This silences missing field warnings. */
757 
758 struct JanetReg
759 {
760     const(char)* name;
761     JanetCFunction cfun;
762     const(char)* documentation;
763 }
764 
765 struct JanetMethod
766 {
767     const(char)* name;
768     JanetCFunction cfun;
769 }
770 
771 struct JanetView
772 {
773     const(Janet)* items;
774     int len;
775 }
776 
777 struct JanetByteView
778 {
779     const(ubyte)* bytes;
780     int len;
781 }
782 
783 struct JanetDictView
784 {
785     const(JanetKV)* kvs;
786     int len;
787     int cap;
788 }
789 
790 struct JanetRange
791 {
792     int start;
793     int end;
794 }
795 
796 struct JanetRNG
797 {
798     uint a;
799     uint b;
800     uint c;
801     uint d;
802     uint counter;
803 }
804 
805 struct JanetFile
806 {
807     FILE* file;
808     int flags;
809 }
810 
811 /* Thread types */
812 struct JanetMailbox;
813 
814 struct JanetThread
815 {
816     JanetMailbox* mailbox;
817     JanetTable* encode;
818 }
819 
820 /***** END SECTION TYPES *****/
821 
822 /***** START SECTION OPCODES *****/
823 
824 /* Bytecode op argument types */
825 enum JanetOpArgType
826 {
827     JANET_OAT_SLOT = 0,
828     JANET_OAT_ENVIRONMENT = 1,
829     JANET_OAT_CONSTANT = 2,
830     JANET_OAT_INTEGER = 3,
831     JANET_OAT_TYPE = 4,
832     JANET_OAT_SIMPLETYPE = 5,
833     JANET_OAT_LABEL = 6,
834     JANET_OAT_FUNCDEF = 7
835 }
836 
837 /* Various types of instructions */
838 enum JanetInstructionType
839 {
840     JINT_0 = 0, /* No args */
841     JINT_S = 1, /* Slot(3) */
842     JINT_L = 2, /* Label(3) */
843     JINT_SS = 3, /* Slot(1), Slot(2) */
844     JINT_SL = 4, /* Slot(1), Label(2) */
845     JINT_ST = 5, /* Slot(1), Slot(2) */
846     JINT_SI = 6, /* Slot(1), Immediate(2) */
847     JINT_SD = 7, /* Slot(1), Closure(2) */
848     JINT_SU = 8, /* Slot(1), Unsigned Immediate(2) */
849     JINT_SSS = 9, /* Slot(1), Slot(1), Slot(1) */
850     JINT_SSI = 10, /* Slot(1), Slot(1), Immediate(1) */
851     JINT_SSU = 11, /* Slot(1), Slot(1), Unsigned Immediate(1) */
852     JINT_SES = 12, /* Slot(1), Environment(1), Far Slot(1) */
853     JINT_SC = 13 /* Slot(1), Constant(2) */
854 }
855 
856 /* All opcodes for the bytecode interpreter. */
857 enum JanetOpCode
858 {
859     JOP_NOOP = 0,
860     JOP_ERROR = 1,
861     JOP_TYPECHECK = 2,
862     JOP_RETURN = 3,
863     JOP_RETURN_NIL = 4,
864     JOP_ADD_IMMEDIATE = 5,
865     JOP_ADD = 6,
866     JOP_SUBTRACT = 7,
867     JOP_MULTIPLY_IMMEDIATE = 8,
868     JOP_MULTIPLY = 9,
869     JOP_DIVIDE_IMMEDIATE = 10,
870     JOP_DIVIDE = 11,
871     JOP_MODULO = 12,
872     JOP_REMAINDER = 13,
873     JOP_BAND = 14,
874     JOP_BOR = 15,
875     JOP_BXOR = 16,
876     JOP_BNOT = 17,
877     JOP_SHIFT_LEFT = 18,
878     JOP_SHIFT_LEFT_IMMEDIATE = 19,
879     JOP_SHIFT_RIGHT = 20,
880     JOP_SHIFT_RIGHT_IMMEDIATE = 21,
881     JOP_SHIFT_RIGHT_UNSIGNED = 22,
882     JOP_SHIFT_RIGHT_UNSIGNED_IMMEDIATE = 23,
883     JOP_MOVE_FAR = 24,
884     JOP_MOVE_NEAR = 25,
885     JOP_JUMP = 26,
886     JOP_JUMP_IF = 27,
887     JOP_JUMP_IF_NOT = 28,
888     JOP_JUMP_IF_NIL = 29,
889     JOP_JUMP_IF_NOT_NIL = 30,
890     JOP_GREATER_THAN = 31,
891     JOP_GREATER_THAN_IMMEDIATE = 32,
892     JOP_LESS_THAN = 33,
893     JOP_LESS_THAN_IMMEDIATE = 34,
894     JOP_EQUALS = 35,
895     JOP_EQUALS_IMMEDIATE = 36,
896     JOP_COMPARE = 37,
897     JOP_LOAD_NIL = 38,
898     JOP_LOAD_TRUE = 39,
899     JOP_LOAD_FALSE = 40,
900     JOP_LOAD_INTEGER = 41,
901     JOP_LOAD_CONSTANT = 42,
902     JOP_LOAD_UPVALUE = 43,
903     JOP_LOAD_SELF = 44,
904     JOP_SET_UPVALUE = 45,
905     JOP_CLOSURE = 46,
906     JOP_PUSH = 47,
907     JOP_PUSH_2 = 48,
908     JOP_PUSH_3 = 49,
909     JOP_PUSH_ARRAY = 50,
910     JOP_CALL = 51,
911     JOP_TAILCALL = 52,
912     JOP_RESUME = 53,
913     JOP_SIGNAL = 54,
914     JOP_PROPAGATE = 55,
915     JOP_IN = 56,
916     JOP_GET = 57,
917     JOP_PUT = 58,
918     JOP_GET_INDEX = 59,
919     JOP_PUT_INDEX = 60,
920     JOP_LENGTH = 61,
921     JOP_MAKE_ARRAY = 62,
922     JOP_MAKE_BUFFER = 63,
923     JOP_MAKE_STRING = 64,
924     JOP_MAKE_STRUCT = 65,
925     JOP_MAKE_TABLE = 66,
926     JOP_MAKE_TUPLE = 67,
927     JOP_MAKE_BRACKET_TUPLE = 68,
928     JOP_GREATER_THAN_EQUAL = 69,
929     JOP_LESS_THAN_EQUAL = 70,
930     JOP_NEXT = 71,
931     JOP_INSTRUCTION_COUNT = 72
932 }
933 
934 /* Info about all instructions */
935 extern __gshared JanetInstructionType[JanetOpCode.JOP_INSTRUCTION_COUNT] janet_instructions;
936 
937 /***** END SECTION OPCODES *****/
938 
939 /***** START SECTION MAIN *****/
940 
941 /* Event Loop */
942 void janet_loop ();
943 
944 /* Parsing */
945 extern __gshared const JanetAbstractType janet_parser_type;
946 pure void janet_parser_init (JanetParser* parser);
947 pure void janet_parser_deinit (JanetParser* parser);
948 pure void janet_parser_consume (JanetParser* parser, ubyte c);
949 pure JanetParserStatus janet_parser_status (JanetParser* parser);
950 pure Janet janet_parser_produce (JanetParser* parser);
951 pure const(char)* janet_parser_error (JanetParser* parser);
952 pure void janet_parser_flush (JanetParser* parser);
953 pure void janet_parser_eof (JanetParser* parser);
954 pure int janet_parser_has_more (JanetParser* parser);
955 
956 /* Assembly */
957 enum JanetAssembleStatus
958 {
959     JANET_ASSEMBLE_OK = 0,
960     JANET_ASSEMBLE_ERROR = 1
961 }
962 
963 struct JanetAssembleResult
964 {
965     JanetFuncDef* funcdef;
966     JanetString error;
967     JanetAssembleStatus status;
968 }
969 
970 JanetAssembleResult janet_asm (Janet source, int flags);
971 Janet janet_disasm (JanetFuncDef* def);
972 Janet janet_asm_decode_instruction (uint instr);
973 
974 /* Compilation */
975 enum JanetCompileStatus
976 {
977     JANET_COMPILE_OK = 0,
978     JANET_COMPILE_ERROR = 1
979 }
980 
981 struct JanetCompileResult
982 {
983     JanetFuncDef* funcdef;
984     JanetString error;
985     JanetFiber* macrofiber;
986     JanetSourceMapping error_mapping;
987     JanetCompileStatus status;
988 }
989 
990 JanetCompileResult janet_compile (Janet source, JanetTable* env, JanetString where);
991 
992 /* Get the default environment for janet */
993 JanetTable* janet_core_env (JanetTable* replacements);
994 
995 int janet_dobytes (JanetTable* env, const(ubyte)* bytes, int len, const(char)* sourcePath, Janet* out_);
996 int janet_dostring (JanetTable* env, const(char)* str, const(char)* sourcePath, Janet* out_);
997 
998 /* Number scanning */
999 int janet_scan_number (const(ubyte)* str, int len, double* out_);
1000 int janet_scan_int64 (const(ubyte)* str, int len, long* out_);
1001 int janet_scan_uint64 (const(ubyte)* str, int len, ulong* out_);
1002 
1003 /* Debugging */
1004 void janet_debug_break (JanetFuncDef* def, int pc);
1005 void janet_debug_unbreak (JanetFuncDef* def, int pc);
1006 void janet_debug_find (
1007     JanetFuncDef** def_out,
1008     int* pc_out,
1009     JanetString source,
1010     int line,
1011     int column);
1012 
1013 /* RNG */
1014 extern __gshared const JanetAbstractType janet_rng_type;
1015 JanetRNG* janet_default_rng ();
1016 pure void janet_rng_seed (JanetRNG* rng, uint seed);
1017 pure void janet_rng_longseed (JanetRNG* rng, const(ubyte)* bytes, int len);
1018 pure uint janet_rng_u32 (JanetRNG* rng);
1019 
1020 /* Array functions */
1021 JanetArray* janet_array (int capacity);
1022 JanetArray* janet_array_n (const(Janet)* elements, int n);
1023 void janet_array_ensure (JanetArray* array, int capacity, int growth);
1024 void janet_array_setcount (JanetArray* array, int count);
1025 void janet_array_push (JanetArray* array, Janet x);
1026 Janet janet_array_pop (JanetArray* array);
1027 Janet janet_array_peek (JanetArray* array);
1028 
1029 /* Buffer functions */
1030 JanetBuffer* janet_buffer (int capacity);
1031 JanetBuffer* janet_buffer_init (JanetBuffer* buffer, int capacity);
1032 void janet_buffer_deinit (JanetBuffer* buffer);
1033 void janet_buffer_ensure (JanetBuffer* buffer, int capacity, int growth);
1034 void janet_buffer_setcount (JanetBuffer* buffer, int count);
1035 void janet_buffer_extra (JanetBuffer* buffer, int n);
1036 void janet_buffer_push_bytes (JanetBuffer* buffer, const(ubyte)* string, int len);
1037 void janet_buffer_push_string (JanetBuffer* buffer, JanetString string);
1038 void janet_buffer_push_cstring (JanetBuffer* buffer, const(char)* cstring);
1039 void janet_buffer_push_u8 (JanetBuffer* buffer, ubyte x);
1040 void janet_buffer_push_u16 (JanetBuffer* buffer, ushort x);
1041 void janet_buffer_push_u32 (JanetBuffer* buffer, uint x);
1042 void janet_buffer_push_u64 (JanetBuffer* buffer, ulong x);
1043 
1044 /* Tuple */
1045 
1046 enum JANET_TUPLE_FLAG_BRACKETCTOR = 0x10000;
1047 
1048 pure extern (D) auto janet_tuple_head(T)(auto ref T t)
1049 {
1050     return cast(JanetTupleHead*) cast(char*) t - offsetof(JanetTupleHead, data);
1051 }
1052 
1053 pure extern (D) auto janet_tuple_from_head(T)(auto ref T gcobject)
1054 {
1055     return cast(const(Janet)*) cast(char*) gcobject + offsetof(JanetTupleHead, data);
1056 }
1057 
1058 pure extern (D) auto janet_tuple_length(T)(auto ref T t)
1059 {
1060     return janet_tuple_head(t).length;
1061 }
1062 
1063 pure extern (D) auto janet_tuple_hash(T)(auto ref T t)
1064 {
1065     return janet_tuple_head(t).hash;
1066 }
1067 
1068 pure extern (D) auto janet_tuple_sm_line(T)(auto ref T t)
1069 {
1070     return janet_tuple_head(t).sm_line;
1071 }
1072 
1073 pure extern (D) auto janet_tuple_sm_column(T)(auto ref T t)
1074 {
1075     return janet_tuple_head(t).sm_column;
1076 }
1077 
1078 pure extern (D) auto janet_tuple_flag(T)(auto ref T t)
1079 {
1080     return janet_tuple_head(t).gc.flags;
1081 }
1082 
1083 Janet* janet_tuple_begin (int length);
1084 JanetTuple janet_tuple_end (Janet* tuple);
1085 JanetTuple janet_tuple_n (const(Janet)* values, int n);
1086 
1087 /* String/Symbol functions */
1088 extern (D) auto janet_string_head(T)(auto ref T s)
1089 {
1090     return cast(JanetStringHead*) cast(char*) s - offsetof(JanetStringHead, data);
1091 }
1092 
1093 extern (D) auto janet_string_length(T)(auto ref T s)
1094 {
1095     return janet_string_head(s).length;
1096 }
1097 
1098 extern (D) auto janet_string_hash(T)(auto ref T s)
1099 {
1100     return janet_string_head(s).hash;
1101 }
1102 
1103 ubyte* janet_string_begin (int length);
1104 JanetString janet_string_end (ubyte* str);
1105 JanetString janet_string (const(ubyte)* buf, int len);
1106 JanetString janet_cstring (const(char)* cstring);
1107 int janet_string_compare (JanetString lhs, JanetString rhs);
1108 int janet_string_equal (JanetString lhs, JanetString rhs);
1109 int janet_string_equalconst (JanetString lhs, const(ubyte)* rhs, int rlen, int rhash);
1110 JanetString janet_description (Janet x);
1111 JanetString janet_to_string (Janet x);
1112 void janet_to_string_b (JanetBuffer* buffer, Janet x);
1113 void janet_description_b (JanetBuffer* buffer, Janet x);
1114 
1115 extern (D) auto janet_cstringv(T)(auto ref T cstr)
1116 {
1117     return janet_wrap_string(janet_cstring(cstr));
1118 }
1119 
1120 extern (D) auto janet_stringv(T0, T1)(auto ref T0 str, auto ref T1 len)
1121 {
1122     return janet_wrap_string(janet_string(str, len));
1123 }
1124 
1125 JanetString janet_formatc (const(char)* format, ...);
1126 JanetBuffer* janet_formatb (JanetBuffer* bufp, const(char)* format, ...);
1127 void janet_formatbv (JanetBuffer* bufp, const(char)* format, va_list args);
1128 
1129 /* Symbol functions */
1130 JanetSymbol janet_symbol (const(ubyte)* str, int len);
1131 JanetSymbol janet_csymbol (const(char)* str);
1132 JanetSymbol janet_symbol_gen ();
1133 
1134 extern (D) auto janet_symbolv(T0, T1)(auto ref T0 str, auto ref T1 len)
1135 {
1136     return janet_wrap_symbol(janet_symbol(str, len));
1137 }
1138 
1139 extern (D) auto janet_csymbolv(T)(auto ref T cstr)
1140 {
1141     return janet_wrap_symbol(janet_csymbol(cstr));
1142 }
1143 
1144 /* Keyword functions */
1145 JanetKeyword janet_keyword (const(ubyte)* str, int len);
1146 JanetKeyword janet_ckeyword (const(char)* str);
1147 
1148 extern (D) auto janet_keywordv(T0, T1)(auto ref T0 str, auto ref T1 len)
1149 {
1150     return janet_wrap_keyword(janet_keyword());
1151 }
1152 
1153 extern (D) auto janet_ckeywordv(T)(auto ref T cstr)
1154 {
1155     return janet_wrap_keyword(janet_ckeyword());
1156 }
1157 
1158 /* Structs */
1159 extern (D) auto janet_struct_head(T)(auto ref T t)
1160 {
1161     return cast(JanetStructHead*) cast(char*) t - offsetof(JanetStructHead, data);
1162 }
1163 
1164 extern (D) auto janet_struct_from_head(T)(auto ref T t)
1165 {
1166     return cast(const(JanetKV)*) cast(char*) gcobject + offsetof(JanetStructHead, data);
1167 }
1168 
1169 extern (D) auto janet_struct_length(T)(auto ref T t)
1170 {
1171     return janet_struct_head(t).length;
1172 }
1173 
1174 extern (D) auto janet_struct_capacity(T)(auto ref T t)
1175 {
1176     return janet_struct_head(t).capacity;
1177 }
1178 
1179 extern (D) auto janet_struct_hash(T)(auto ref T t)
1180 {
1181     return janet_struct_head(t).hash;
1182 }
1183 
1184 JanetKV* janet_struct_begin (int count);
1185 void janet_struct_put (JanetKV* st, Janet key, Janet value);
1186 const(JanetKV)* janet_struct_end (JanetKV* st);
1187 pure Janet janet_struct_get (const(JanetKV)* st, Janet key);
1188 JanetTable* janet_struct_to_table (const(JanetKV)* st);
1189 pure int janet_struct_equal (const(JanetKV)* lhs, const(JanetKV)* rhs);
1190 pure int janet_struct_compare (const(JanetKV)* lhs, const(JanetKV)* rhs);
1191 const(JanetKV)* janet_struct_find (const(JanetKV)* st, Janet key);
1192 
1193 /* Table functions */
1194 JanetTable* janet_table (int capacity);
1195 JanetTable* janet_table_init (JanetTable* table, int capacity);
1196 void janet_table_deinit (JanetTable* table);
1197 pure Janet janet_table_get (JanetTable* t, Janet key);
1198 Janet janet_table_get_ex (JanetTable* t, Janet key, JanetTable** which);
1199 Janet janet_table_rawget (JanetTable* t, Janet key);
1200 Janet janet_table_remove (JanetTable* t, Janet key);
1201 void janet_table_put (JanetTable* t, Janet key, Janet value);
1202 JanetStruct janet_table_to_struct (JanetTable* t);
1203 void janet_table_merge_table (JanetTable* table, JanetTable* other);
1204 void janet_table_merge_struct (JanetTable* table, JanetStruct other);
1205 JanetKV* janet_table_find (JanetTable* t, Janet key);
1206 JanetTable* janet_table_clone (JanetTable* table);
1207 
1208 /* Fiber */
1209 JanetFiber* janet_fiber (JanetFunction* callee, int capacity, int argc, const(Janet)* argv);
1210 JanetFiber* janet_fiber_reset (JanetFiber* fiber, JanetFunction* callee, int argc, const(Janet)* argv);
1211 JanetFiberStatus janet_fiber_status (JanetFiber* fiber);
1212 JanetFiber* janet_current_fiber ();
1213 JanetFiber* janet_root_fiber ();
1214 
1215 /* Treat similar types through uniform interfaces for iteration */
1216 int janet_indexed_view (Janet seq, const(Janet*)* data, int* len);
1217 int janet_bytes_view (Janet str, const(ubyte*)* data, int* len);
1218 int janet_dictionary_view (Janet tab, const(JanetKV*)* data, int* len, int* cap);
1219 Janet janet_dictionary_get (const(JanetKV)* data, int cap, Janet key);
1220 const(JanetKV)* janet_dictionary_next (const(JanetKV)* kvs, int cap, const(JanetKV)* kv);
1221 
1222 /* Abstract */
1223 pure extern (D) auto janet_abstract_head(T)(auto ref T u)
1224 {
1225     return cast(JanetAbstractHead*) cast(char*) u - offsetof(JanetAbstractHead, data);
1226 }
1227 
1228 pure extern (D) auto janet_abstract_from_head(T)(auto ref T gcobject)
1229 {
1230     return cast(JanetAbstract) cast(char*) gcobject + offsetof(JanetAbstractHead, data);
1231 }
1232 
1233 pure extern (D) auto janet_abstract_type(T)(auto ref T u)
1234 {
1235     return janet_abstract_head(u).type;
1236 }
1237 
1238 pure extern (D) auto janet_abstract_size(T)(auto ref T u)
1239 {
1240     return janet_abstract_head(u).size;
1241 }
1242 
1243 void* janet_abstract_begin (const(JanetAbstractType)* type, size_t size);
1244 JanetAbstract janet_abstract_end (void* abstractTemplate);
1245 JanetAbstract janet_abstract (const(JanetAbstractType)* type, size_t size); /* begin and end in one call */
1246 
1247 /* Native */
1248 alias JanetModule = void function (JanetTable*);
1249 alias JanetModconf = JanetBuildConfig function ();
1250 JanetModule janet_native (const(char)* name, JanetString* error);
1251 
1252 /* Marshaling */
1253 enum JANET_MARSHAL_UNSAFE = 0x20000;
1254 
1255 void janet_marshal (JanetBuffer* buf, Janet x, JanetTable* rreg, int flags);
1256 Janet janet_unmarshal (
1257     const(ubyte)* bytes,
1258     size_t len,
1259     int flags,
1260     JanetTable* reg,
1261     const(ubyte*)* next);
1262 JanetTable* janet_env_lookup (JanetTable* env);
1263 void janet_env_lookup_into (JanetTable* renv, JanetTable* env, const(char)* prefix, int recurse);
1264 
1265 /* GC */
1266 void janet_mark (Janet x);
1267 void janet_sweep ();
1268 void janet_collect ();
1269 void janet_clear_memory ();
1270 void janet_gcroot (Janet root);
1271 int janet_gcunroot (Janet root);
1272 int janet_gcunrootall (Janet root);
1273 int janet_gclock ();
1274 void janet_gcunlock (int handle);
1275 void janet_gcpressure (size_t s);
1276 
1277 /* Functions */
1278 JanetFuncDef* janet_funcdef_alloc ();
1279 JanetFunction* janet_thunk (JanetFuncDef* def);
1280 int janet_verify (JanetFuncDef* def);
1281 
1282 /* Pretty printing */
1283 enum JANET_PRETTY_COLOR = 1;
1284 enum JANET_PRETTY_ONELINE = 2;
1285 enum JANET_PRETTY_NOTRUNC = 4;
1286 JanetBuffer* janet_pretty (JanetBuffer* buffer, int depth, int flags, Janet x);
1287 
1288 /* Misc */
1289 
1290 enum JANET_HASH_KEY_SIZE = 16;
1291 void janet_init_hash_key (ref ubyte[JANET_HASH_KEY_SIZE] key);
1292 
1293 pure int janet_equals (Janet x, Janet y);
1294 pure int janet_hash (Janet x);
1295 pure int janet_compare (Janet x, Janet y);
1296 pure int janet_cstrcmp (JanetString str, const(char)* other);
1297 pure Janet janet_in (Janet ds, Janet key);
1298 pure Janet janet_get (Janet ds, Janet key);
1299 pure Janet janet_next (Janet ds, Janet key);
1300 pure Janet janet_getindex (Janet ds, int index);
1301 pure int janet_length (Janet x);
1302 pure Janet janet_lengthv (Janet x);
1303 void janet_put (Janet ds, Janet key, Janet value);
1304 void janet_putindex (Janet ds, int index, Janet value);
1305 
1306 pure extern (D) auto janet_flag_at(T0, T1)(auto ref T0 F, auto ref T1 I)
1307 {
1308     return F & ((1) << I);
1309 }
1310 
1311 Janet janet_wrap_number_safe (double x) @trusted;
1312 pure int janet_keyeq (Janet x, const(char)* cstring);
1313 pure int janet_streq (Janet x, const(char)* cstring);
1314 pure int janet_symeq (Janet x, const(char)* cstring);
1315 
1316 /* VM functions */
1317 int janet_init ();
1318 void janet_deinit ();
1319 JanetSignal janet_continue (JanetFiber* fiber, Janet in_, Janet* out_);
1320 JanetSignal janet_pcall (JanetFunction* fun, int argn, const(Janet)* argv, Janet* out_, JanetFiber** f);
1321 JanetSignal janet_step (JanetFiber* fiber, Janet in_, Janet* out_);
1322 Janet janet_call (JanetFunction* fun, int argc, const(Janet)* argv);
1323 Janet janet_mcall (const(char)* name, int argc, Janet* argv);
1324 void janet_stacktrace (JanetFiber* fiber, Janet err);
1325 
1326 /* Scratch Memory API */
1327 alias JanetScratchFinalizer = void function (void*);
1328 
1329 void* janet_smalloc (size_t size);
1330 void* janet_srealloc (void* mem, size_t size);
1331 void* janet_scalloc (size_t nmemb, size_t size);
1332 void janet_sfinalizer (void* mem, JanetScratchFinalizer finalizer);
1333 void janet_sfree (void* mem);
1334 
1335 /* C Library helpers */
1336 enum JanetBindingType
1337 {
1338     JANET_BINDING_NONE = 0,
1339     JANET_BINDING_DEF = 1,
1340     JANET_BINDING_VAR = 2,
1341     JANET_BINDING_MACRO = 3
1342 }
1343 
1344 void janet_def (JanetTable* env, const(char)* name, Janet val, const(char)* documentation);
1345 void janet_var (JanetTable* env, const(char)* name, Janet val, const(char)* documentation);
1346 void janet_cfuns (JanetTable* env, const(char)* regprefix, const(JanetReg)* cfuns);
1347 JanetBindingType janet_resolve (JanetTable* env, JanetSymbol sym, Janet* out_);
1348 void janet_register (const(char)* name, JanetCFunction cfun);
1349 
1350 /* Get values from the core environment. */
1351 Janet janet_resolve_core (const(char)* name);
1352 
1353 /* New C API */
1354 
1355 /* Allow setting entry name for static libraries */
1356 
1357 void janet_signalv (JanetSignal signal, Janet message);
1358 void janet_panicv (Janet message);
1359 void janet_panic (const(char)* message);
1360 void janet_panics (JanetString message);
1361 void janet_panicf (const(char)* format, ...);
1362 void janet_dynprintf (const(char)* name, FILE* dflt_file, const(char)* format, ...);
1363 void janet_panic_type (Janet x, int n, int expected);
1364 void janet_panic_abstract (Janet x, int n, const(JanetAbstractType)* at);
1365 void janet_arity (int arity, int min, int max);
1366 void janet_fixarity (int arity, int fix);
1367 
1368 pure @trusted Janet janet_getmethod (const(ubyte)* method, const(JanetMethod)* methods);
1369 
1370 pure @trusted double janet_getnumber (const(Janet)* argv, int n);
1371 pure @trusted JanetArray* janet_getarray (const(Janet)* argv, int n);
1372 pure @trusted JanetTuple janet_gettuple (const(Janet)* argv, int n);
1373 pure @trusted JanetTable* janet_gettable (const(Janet)* argv, int n);
1374 pure @trusted JanetStruct janet_getstruct (const(Janet)* argv, int n);
1375 pure @trusted JanetString janet_getstring (const(Janet)* argv, int n);
1376 pure const(char)* janet_getcstring (const(Janet)* argv, int n); // can't be @trusted -- pointer arithmetic in the C func
1377 pure @trusted JanetSymbol janet_getsymbol (const(Janet)* argv, int n);
1378 pure @trusted JanetKeyword janet_getkeyword (const(Janet)* argv, int n);
1379 pure @trusted JanetBuffer* janet_getbuffer (const(Janet)* argv, int n);
1380 pure @trusted JanetFiber* janet_getfiber (const(Janet)* argv, int n);
1381 pure @trusted JanetFunction* janet_getfunction (const(Janet)* argv, int n);
1382 pure @trusted JanetCFunction janet_getcfunction (const(Janet)* argv, int n);
1383 pure @trusted int janet_getboolean (const(Janet)* argv, int n);
1384 pure @trusted void* janet_getpointer (const(Janet)* argv, int n);
1385 
1386 pure @trusted int janet_getnat (const(Janet)* argv, int n);
1387 pure @trusted int janet_getinteger (const(Janet)* argv, int n);
1388 pure @trusted long janet_getinteger64 (const(Janet)* argv, int n);
1389 pure @trusted size_t janet_getsize (const(Janet)* argv, int n);
1390 pure @trusted JanetView janet_getindexed (const(Janet)* argv, int n);
1391 pure @trusted JanetByteView janet_getbytes (const(Janet)* argv, int n);
1392 pure @trusted JanetDictView janet_getdictionary (const(Janet)* argv, int n);
1393 pure @trusted void* janet_getabstract (const(Janet)* argv, int n, const(JanetAbstractType)* at);
1394 pure @trusted JanetRange janet_getslice (int argc, const(Janet)* argv);
1395 pure @trusted int janet_gethalfrange (const(Janet)* argv, int n, int length, const(char)* which);
1396 pure @trusted int janet_getargindex (const(Janet)* argv, int n, int length, const(char)* which);
1397 pure @trusted ulong janet_getflags (const(Janet)* argv, int n, const(char)* flags);
1398 
1399 /* Optionals */
1400 double janet_optnumber (const(Janet)* argv, int argc, int n, double dflt);
1401 JanetTuple janet_opttuple (const(Janet)* argv, int argc, int n, JanetTuple dflt);
1402 JanetStruct janet_optstruct (const(Janet)* argv, int argc, int n, JanetStruct dflt);
1403 JanetString janet_optstring (const(Janet)* argv, int argc, int n, JanetString dflt);
1404 const(char)* janet_optcstring (const(Janet)* argv, int argc, int n, const(char)* dflt);
1405 JanetSymbol janet_optsymbol (const(Janet)* argv, int argc, int n, JanetString dflt);
1406 JanetKeyword janet_optkeyword (const(Janet)* argv, int argc, int n, JanetString dflt);
1407 JanetFiber* janet_optfiber (const(Janet)* argv, int argc, int n, JanetFiber* dflt);
1408 JanetFunction* janet_optfunction (const(Janet)* argv, int argc, int n, JanetFunction* dflt);
1409 JanetCFunction janet_optcfunction (const(Janet)* argv, int argc, int n, JanetCFunction dflt);
1410 int janet_optboolean (const(Janet)* argv, int argc, int n, int dflt);
1411 void* janet_optpointer (const(Janet)* argv, int argc, int n, void* dflt);
1412 int janet_optnat (const(Janet)* argv, int argc, int n, int dflt);
1413 int janet_optinteger (const(Janet)* argv, int argc, int n, int dflt);
1414 long janet_optinteger64 (const(Janet)* argv, int argc, int n, long dflt);
1415 size_t janet_optsize (const(Janet)* argv, int argc, int n, size_t dflt);
1416 JanetAbstract janet_optabstract (const(Janet)* argv, int argc, int n, const(JanetAbstractType)* at, JanetAbstract dflt);
1417 
1418 /* Mutable optional types specify a size default, and construct a new value if none is provided */
1419 JanetBuffer* janet_optbuffer (const(Janet)* argv, int argc, int n, int dflt_len);
1420 JanetTable* janet_opttable (const(Janet)* argv, int argc, int n, int dflt_len);
1421 JanetArray* janet_optarray (const(Janet)* argv, int argc, int n, int dflt_len);
1422 
1423 Janet janet_dyn (const(char)* name);
1424 void janet_setdyn (const(char)* name, Janet value);
1425 
1426 extern __gshared const JanetAbstractType janet_file_type;
1427 
1428 enum JANET_FILE_WRITE = 1;
1429 enum JANET_FILE_READ = 2;
1430 enum JANET_FILE_APPEND = 4;
1431 enum JANET_FILE_UPDATE = 8;
1432 enum JANET_FILE_NOT_CLOSEABLE = 16;
1433 enum JANET_FILE_CLOSED = 32;
1434 enum JANET_FILE_BINARY = 64;
1435 enum JANET_FILE_SERIALIZABLE = 128;
1436 enum JANET_FILE_PIPED = 256;
1437 
1438 Janet janet_makefile (FILE* f, int flags);
1439 FILE* janet_getfile (const(Janet)* argv, int n, int* flags);
1440 FILE* janet_dynfile (const(char)* name, FILE* def);
1441 JanetAbstract janet_checkfile (Janet j);
1442 FILE* janet_unwrapfile (Janet j, int* flags);
1443 
1444 /* Marshal API */
1445 void janet_marshal_size (JanetMarshalContext* ctx, size_t value);
1446 void janet_marshal_int (JanetMarshalContext* ctx, int value);
1447 void janet_marshal_int64 (JanetMarshalContext* ctx, long value);
1448 void janet_marshal_byte (JanetMarshalContext* ctx, ubyte value);
1449 void janet_marshal_bytes (JanetMarshalContext* ctx, const(ubyte)* bytes, size_t len);
1450 void janet_marshal_janet (JanetMarshalContext* ctx, Janet x);
1451 void janet_marshal_abstract (JanetMarshalContext* ctx, JanetAbstract abstract_);
1452 
1453 void janet_unmarshal_ensure (JanetMarshalContext* ctx, size_t size);
1454 size_t janet_unmarshal_size (JanetMarshalContext* ctx);
1455 int janet_unmarshal_int (JanetMarshalContext* ctx);
1456 long janet_unmarshal_int64 (JanetMarshalContext* ctx);
1457 ubyte janet_unmarshal_byte (JanetMarshalContext* ctx);
1458 void janet_unmarshal_bytes (JanetMarshalContext* ctx, ubyte* dest, size_t len);
1459 Janet janet_unmarshal_janet (JanetMarshalContext* ctx);
1460 JanetAbstract janet_unmarshal_abstract (JanetMarshalContext* ctx, size_t size);
1461 
1462 void janet_register_abstract_type (const(JanetAbstractType)* at);
1463 const(JanetAbstractType)* janet_get_abstract_type (Janet key);
1464 
1465 extern __gshared const JanetAbstractType janet_peg_type;
1466 
1467 /* opcodes for peg vm */
1468 enum JanetPegOpcode
1469 {
1470     RULE_LITERAL = 0, /* [len, bytes...] */
1471     RULE_NCHAR = 1, /* [n] */
1472     RULE_NOTNCHAR = 2, /* [n] */
1473     RULE_RANGE = 3, /* [lo | hi << 16 (1 word)] */
1474     RULE_SET = 4, /* [bitmap (8 words)] */
1475     RULE_LOOK = 5, /* [offset, rule] */
1476     RULE_CHOICE = 6, /* [len, rules...] */
1477     RULE_SEQUENCE = 7, /* [len, rules...] */
1478     RULE_IF = 8, /* [rule_a, rule_b (b if a)] */
1479     RULE_IFNOT = 9, /* [rule_a, rule_b (b if not a)] */
1480     RULE_NOT = 10, /* [rule] */
1481     RULE_BETWEEN = 11, /* [lo, hi, rule] */
1482     RULE_GETTAG = 12, /* [searchtag, tag] */
1483     RULE_CAPTURE = 13, /* [rule, tag] */
1484     RULE_POSITION = 14, /* [tag] */
1485     RULE_ARGUMENT = 15, /* [argument-index, tag] */
1486     RULE_CONSTANT = 16, /* [constant, tag] */
1487     RULE_ACCUMULATE = 17, /* [rule, tag] */
1488     RULE_GROUP = 18, /* [rule, tag] */
1489     RULE_REPLACE = 19, /* [rule, constant, tag] */
1490     RULE_MATCHTIME = 20, /* [rule, constant, tag] */
1491     RULE_ERROR = 21, /* [rule] */
1492     RULE_DROP = 22, /* [rule] */
1493     RULE_BACKMATCH = 23, /* [tag] */
1494     RULE_LENPREFIX = 24 /* [rule_a, rule_b (repeat rule_b rule_a times)] */
1495 }
1496 
1497 struct JanetPeg
1498 {
1499     uint* bytecode;
1500     Janet* constants;
1501     size_t bytecode_len;
1502     uint num_constants;
1503 }
1504 
1505 extern __gshared const JanetAbstractType janet_ta_view_type;
1506 extern __gshared const JanetAbstractType janet_ta_buffer_type;
1507 
1508 enum JanetTArrayType
1509 {
1510     JANET_TARRAY_TYPE_U8 = 0,
1511     JANET_TARRAY_TYPE_S8 = 1,
1512     JANET_TARRAY_TYPE_U16 = 2,
1513     JANET_TARRAY_TYPE_S16 = 3,
1514     JANET_TARRAY_TYPE_U32 = 4,
1515     JANET_TARRAY_TYPE_S32 = 5,
1516     JANET_TARRAY_TYPE_U64 = 6,
1517     JANET_TARRAY_TYPE_S64 = 7,
1518     JANET_TARRAY_TYPE_F32 = 8,
1519     JANET_TARRAY_TYPE_F64 = 9
1520 }
1521 
1522 struct JanetTArrayBuffer
1523 {
1524     ubyte* data;
1525     size_t size;
1526     int flags;
1527 }
1528 
1529 struct JanetTArrayView
1530 {
1531     union _Anonymous_2
1532     {
1533         void* pointer;
1534         ubyte* u8;
1535         byte* s8;
1536         ushort* u16;
1537         short* s16;
1538         uint* u32;
1539         int* s32;
1540         ulong* u64;
1541         long* s64;
1542         float* f32;
1543         double* f64;
1544     }
1545 
1546     _Anonymous_2 as;
1547     JanetTArrayBuffer* buffer;
1548     size_t size;
1549     size_t stride;
1550     JanetTArrayType type;
1551 }
1552 
1553 JanetTArrayBuffer* janet_tarray_buffer (size_t size);
1554 JanetTArrayView* janet_tarray_view (JanetTArrayType type, size_t size, size_t stride, size_t offset, JanetTArrayBuffer* buffer);
1555 int janet_is_tarray_view (Janet x, JanetTArrayType type);
1556 JanetTArrayBuffer* janet_gettarray_buffer (const(Janet)* argv, int n);
1557 JanetTArrayView* janet_gettarray_view (const(Janet)* argv, int n, JanetTArrayType type);
1558 JanetTArrayView* janet_gettarray_any (const(Janet)* argv, int n);
1559 
1560 extern __gshared const JanetAbstractType janet_s64_type;
1561 extern __gshared const JanetAbstractType janet_u64_type;
1562 
1563 enum JanetIntType
1564 {
1565     JANET_INT_NONE = 0,
1566     JANET_INT_S64 = 1,
1567     JANET_INT_U64 = 2
1568 }
1569 
1570 JanetIntType janet_is_int (Janet x);
1571 Janet janet_wrap_s64 (long x);
1572 Janet janet_wrap_u64 (ulong x);
1573 long janet_unwrap_s64 (Janet x);
1574 ulong janet_unwrap_u64 (Janet x);
1575 int janet_scan_int64 (const(ubyte)* str, int len, long* out_);
1576 int janet_scan_uint64 (const(ubyte)* str, int len, ulong* out_);
1577 
1578 extern __gshared const JanetAbstractType janet_thread_type;
1579 
1580 int janet_thread_receive (Janet* msg_out, double timeout);
1581 int janet_thread_send (JanetThread* thread, Janet msg, double timeout);
1582 
1583 /***** END SECTION MAIN *****/
1584 
1585 /* Re-enable popped variable length array warnings */
1586 
1587 /* JANET_H_defined */