42 #define POTION_SIG "p\07\10n"
43 #define POTION_VMID 0x79
55 # include <sys/stat.h>
56 # define DLLEXPORT __declspec(dllexport)
61 #define _XSTR(s) _STR(s)
65 # define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS __attribute__((no_address_safety_analysis))
67 # define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS
78 typedef unsigned long _PN;
101 # define __WORDSIZE 64
103 # define __WORDSIZE 32
107 #define PN_TNIL 0x250000
108 #define PN_TNUMBER (1+PN_TNIL)
109 #define PN_TBOOLEAN (2+PN_TNIL)
110 #define PN_TDOUBLE (3+PN_TNIL) //is a Number, no arbitrary prec. yet
111 #define PN_TINTEGER (4+PN_TNIL) //is a Number
112 #define PN_TSTRING (5+PN_TNIL)
113 #define PN_TWEAK (6+PN_TNIL)
114 #define PN_TCLOSURE (7+PN_TNIL)
115 #define PN_TTUPLE (8+PN_TNIL)
116 #define PN_TSTATE (9+PN_TNIL)
117 #define PN_TFILE (10+PN_TNIL) //0a
118 #define PN_TOBJECT (11+PN_TNIL) //0b
119 #define PN_TVTABLE (12+PN_TNIL) //0c
120 #define PN_TSOURCE (13+PN_TNIL) //0d
121 #define PN_TBYTES (14+PN_TNIL) //0e
122 #define PN_TPROTO (15+PN_TNIL) //0f
123 #define PN_TLOBBY (16+PN_TNIL) //10
124 #define PN_TTABLE (17+PN_TNIL) //11
125 #define PN_TLICK (18+PN_TNIL) //12
126 #define PN_TFLEX (19+PN_TNIL) //13
127 #define PN_TSTRINGS (20+PN_TNIL) //14
128 #define PN_TERROR (21+PN_TNIL) //15
129 #define PN_TCONT (22+PN_TNIL) //16
130 #define PN_TUSER (23+PN_TNIL) //17
132 #define vPN(t) struct PN##t * volatile
133 #define PN_TYPE(x) potion_type((PN)(x))
134 #define PN_VTYPE(x) (((struct PNObject *)(x))->vt)
135 #define PN_TYPE_ID(t) ((t)-PN_TNIL)
136 #define PN_VTABLE(t) (PN_FLEX_AT(P->vts, PN_TYPE_ID(t)))
137 #define PN_TYPECHECK(t) (PN_TYPE_ID(t) >= 0 && PN_TYPE_ID(t) < PN_FLEX_SIZE(P->vts))
139 #define PN_NIL ((PN)0)
140 #define PN_ZERO ((PN)1) //i.e. PN_NUM(0)
141 #define PN_FALSE ((PN)2)
142 #define PN_TRUE ((PN)6)
143 #define PN_PRIMITIVE 7
144 #define PN_REF_MASK ~7
145 #define PN_NONE ((PN_SIZE)-1)
146 #define POTION_FWD 0xFFFFFFFE
147 #define POTION_COPIED 0xFFFFFFFF
149 #define NIL_NAME "nil" // "undef" in p2
150 #define NILKIND_NAME "NilKind"
152 #define PN_FINTEGER 1
153 #define PN_FBOOLEAN 2
157 #define PN_TEST(v) ((PN)(v) != PN_FALSE && (PN)(v) != PN_NIL)
158 #define PN_TEST1(v) ((PN)(v) != PN_FALSE && (PN)(v) != PN_NIL \
159 && (PN)(v) != PN_ZERO && (PN)(v) != PN_STR0 \
160 && (!PN_IS_TUPLE(v) || PN_IS_EMPTY(v)))
162 #define PN_TEST(v) ((PN)(v) != PN_FALSE && (PN)(v) != PN_NIL)
163 #define PN_TEST1(v) ((PN)(v) != PN_FALSE && (PN)(v) != PN_NIL)
165 #define PN_BOOL(v) (PN_TEST(v) ? PN_TRUE : PN_FALSE)
168 #define PN_IS_PTR(v) (!PN_IS_INT(v) && ((PN)(v) & PN_REF_MASK))
169 #define PN_IS_NIL(v) ((PN)(v) == PN_NIL)
170 #define PN_IS_BOOL(v) ((PN)(v) & PN_FBOOLEAN)
171 #define PN_IS_INT(v) ((PN)(v) & PN_FINTEGER)
172 #define PN_IS_DBL(v) (PN_IS_PTR(v) && ({PNType _t = potion_qptr_type((PN)v); _t == PN_TNUMBER || _t == PN_TDOUBLE;}))
173 #define PN_IS_NUM(v) (PN_IS_INT(v) || PN_IS_DBL(v))
174 #define PN_IS_TUPLE(v) (PN_IS_PTR(v) && (potion_ptr_type((PN)v) == PN_TTUPLE))
175 #define PN_IS_STR(v) (PN_IS_PTR(v) && (potion_ptr_type((PN)v) == PN_TSTRING))
176 #define PN_IS_TABLE(v) (PN_IS_PTR(v) && (potion_ptr_type((PN)v) == PN_TTABLE))
177 #define PN_IS_CLOSURE(v) (PN_IS_PTR(v) && (potion_ptr_type((PN)v) == PN_TCLOSURE))
178 #define PN_IS_PROTO(v) (PN_IS_PTR(v) && (potion_ptr_type((PN)v) == PN_TPROTO))
179 #define PN_IS_REF(v) (PN_IS_PTR(v) && (potion_ptr_type((PN)v) == PN_TWEAK))
180 #define PN_IS_METACLASS(v) (((struct PNVtable *)v)->meta == PN_NIL)
181 #define PN_IS_FFIPTR(p) ((PN_IS_PTR(p) && !(p >= (_PN)P->mem && p <= (_PN)P->mem->birth_hi)) \
182 || (!PN_IS_PTR(p) && p > (_PN)P->mem->birth_hi))
184 #define PN_CHECK_STR(obj) if (!PN_IS_STR(obj)) return potion_type_error_want(P, ""#obj, (PN)obj, "String")
185 #define PN_CHECK_STRB(obj) if (!PN_IS_STR(obj) || (PN_TYPE(obj) != PN_TBYTES)) return potion_type_error_want(P, ""#obj, (PN)obj, "String or Bytes")
186 #define PN_CHECK_NUM(obj) if (!PN_IS_NUM(obj)) return potion_type_error_want(P, ""#obj, (PN)obj, "Number")
187 #define PN_CHECK_INT(obj) if (!PN_IS_INT(obj)) return potion_type_error_want(P, ""#obj, (PN)obj, "Integer")
188 #define PN_CHECK_DBL(obj) if (!PN_IS_DBL(obj)) return potion_type_error_want(P, ""#obj, (PN)obj, "Double")
189 #define PN_CHECK_BOOL(obj) if (!PN_IS_BOOL(obj)) return potion_type_error_want(P, ""#obj, (PN)obj, "Bool")
190 #define PN_CHECK_TUPLE(obj) if (!PN_IS_TUPLE(obj)) return potion_type_error_want(P, ""#obj, (PN)obj, "Tuple")
191 #define PN_CHECK_CLOSURE(obj) if (!PN_IS_CLOSURE(obj)) return potion_type_error_want(P, ""#obj, (PN)obj, "Closure")
193 #define PN_CHECK_TYPE(obj,type) if (type != PN_TYPE(obj)) return potion_type_error(P, (PN)obj)
195 #define DBG_CHECK_TYPE(obj,type) PN_CHECK_TYPE(obj,type)
196 #define DBG_CHECK_NUM(obj) PN_CHECK_NUM(obj)
197 #define DBG_CHECK_INT(obj) PN_CHECK_INT(obj)
198 #define DBG_CHECK_DBL(obj) PN_CHECK_DBL(obj)
199 #define DBG_CHECK_TUPLE(obj) PN_CHECK_TUPLE(obj)
201 #define DBG_CHECK_TYPE(obj,type)
202 #define DBG_CHECK_NUM(obj)
203 #define DBG_CHECK_INT(obj)
204 #define DBG_CHECK_DBL(obj)
205 #define DBG_CHECK_TUPLE(obj)
213 #define PN_NUM(i) ((PN)((((long)(i))<<1) + PN_FINTEGER))
214 #define PN_INT(x) ((long)((long)(x))>>1)
215 #define PN_DBL(num) (PN_IS_INT(num) ? (double)PN_INT(num) : ((struct PNDouble *)num)->value)
218 #define PN_RAND() PN_NUM(potion_rand_int())
219 #define PN_STR(x) potion_str(P, x)
220 #define PN_STRN(x, l) potion_str2(P, x, l)
221 #define PN_STRCAT(a, b) potion_strcat(P, (a), (b))
222 #define PN_STR_PTR(x) potion_str_ptr(x)
223 #define PN_STR_LEN(x) ((struct PNString *)(x))->len
224 #define PN_STR_B(x) potion_bytes_string(P, PN_NIL, x)
225 #define PN_CLOSURE(x) ((struct PNClosure *)(x))
226 #define PN_CLOSURE_F(x) ((struct PNClosure *)(x))->method
227 #define PN_PROTO(x) ((struct PNProto *)(x))
228 #define PN_FUNC(f, s) potion_closure_new(P, (PN_F)f, potion_sig(P, s), 0)
229 #define PN_DEREF(x) ((struct PNWeakRef *)(x))->data
230 #define PN_DATA(x) ((struct PNData *)(x))->data
231 #define PN_TOUCH(x) potion_gc_update(P, (PN)(x))
232 #define PN_ALIGN(o, x) (((((o) - 1) / (x)) + 1) * (x))
234 #define PN_OBJECT_HEADER \
238 #define PN_FLEX(N, T) typedef struct { PN_OBJECT_HEADER; PN_SIZE len; PN_SIZE siz; T ptr[]; } N
239 #define PN_FLEX_AT(N, I) ((PNFlex *)(N))->ptr[I]
240 #define PN_FLEX_SIZE(N) ((PNFlex *)(N))->len
243 #define PN_NUMHASH(x) x
245 #define PN_NUMHASH(x) (PNUniq)((x)>>33^(x)^(x)<<11)
247 #define PN_UNIQ(x) (PN_IS_PTR(x) ? ((struct PNObject *)(x))->uniq : PN_NUMHASH(x))
249 #define AS_STR(x) PN_STR_PTR(potion_send(x, PN_string))
252 if (P->flags & DEBUG_TRACE) fprintf(stderr, __VA_ARGS__)
254 if (P->flags & DEBUG_VERBOSE) fprintf(stderr, __VA_ARGS__)
255 #define DBG_vt(...) \
256 if (P->flags & DEBUG_VERBOSE && P->flags & DEBUG_TRACE) fprintf(stderr, __VA_ARGS__)
257 #define DBG_vi(...) \
258 if (P->flags & DEBUG_VERBOSE && P->flags & DEBUG_INSPECT) fprintf(stderr, __VA_ARGS__)
260 if (P->flags & DEBUG_COMPILE) fprintf(stderr, __VA_ARGS__)
269 #define PN_IS_EMPTY(T) (PN_TUPLE_LEN(T) == 0)
270 #define PN_TUP0() potion_tuple_empty(P)
271 #define PN_TUP(X) potion_tuple_new(P, X)
272 #define PN_PUSH(T, X) potion_tuple_push(P, T, (PN)X)
273 #define PN_SHIFT(T) potion_tuple_shift(P, 0, T)
274 #define PN_GET(T, X) potion_tuple_find(P, T, X)
275 #define PN_PUT(T, X) potion_tuple_push_unless(P, T, X)
276 #define PN_GET_TUPLE(t) ((struct PNTuple *)potion_fwd((PN)t))
277 #define PN_TUPLE_LEN(t) PN_GET_TUPLE(t)->len
278 #define PN_TUPLE_AT(t, n) PN_GET_TUPLE(t)->set[n]
279 #define PN_TUPLE_COUNT(T, I, B) ({ \
281 struct PNTuple * volatile __t##I = PN_GET_TUPLE(T); \
282 if (__t##I->len != 0) { \
284 for (I = 0; I < __t##I->len; I++) B \
287 #define PN_TUPLE_EACH(T, I, V, B) ({ \
289 struct PNTuple * volatile __t##V = PN_GET_TUPLE(T); \
290 if (__t##V->len != 0) { \
292 for (I = 0; I < __t##V->len; I++) { \
293 PN V = __t##V->set[I]; \
355 #define PN_MANTISSA(d, n) d->real[1 + n]
558 #define PN_QUICK_FWD(t, obj) \
559 if (((struct PNFwd *)obj)->fwd == POTION_FWD) \
560 obj = (t)(((struct PNFwd *)obj)->ptr);
566 return ((
struct PNObject *)obj)->vt;
572 obj = ((
struct PNFwd *)obj)->ptr;
579 return ((
struct PNString *)s)->chars;
581 return ((
struct PNBytes *)s)->chars;
591 #define OP_MAX 50 // OP_DEBUG+1 was 64, statically allocated in Potion interpreter
599 void (*registers)(
Potion *,
struct PNProto *
volatile, PNAsm *
volatile *, long);
600 void (*local) (
Potion *,
struct PNProto *
volatile, PNAsm *
volatile *, long, long);
602 void (*jmpedit) (
Potion *,
struct PNProto *
volatile, PNAsm *
volatile *,
unsigned char *, int);
692 #define POTION_INIT_STACK(x) \
693 PN __##x = 0x571FF; void *x = (void *)&__##x
703 if (siz <
sizeof(
struct PNFwd))
704 siz =
sizeof(
struct PNFwd);
752 memcpy(dst, (
void *)obj, oldsz);
754 ((
struct PNFwd *)obj)->siz = oldsz;
755 ((
struct PNFwd *)obj)->ptr = (
PN)dst;
775 #define POTION_NO_MEM 8910
781 #define potion_send(RCV, MSG, ARGS...) ({ \
783 PN c = potion_bind(P, r, (MSG)); \
784 if (PN_IS_CLOSURE(c)) \
785 c = ((struct PNClosure *)c)->method(P, c, r, ##ARGS); \
789 #define potion_method(RCV, MSG, FN, SIG) \
790 potion_send(RCV, PN_def, potion_str(P, MSG), PN_FUNC(FN, SIG))
791 #define potion_class_method(RCV, MSG, FN, SIG) \
792 potion_send(((struct PNVtable *)(RCV))->meta, PN_def, potion_str(P, MSG), PN_FUNC(FN, SIG))
808 : type ==
'S' ? PN_STR0
824 __attribute__ ((format (printf, 3, 4)));
832 __attribute__ ((format (printf, 2, 3)));
838 __attribute__ ((format (printf, 3, 4)));
936 #if defined(STATIC) || defined(SANDBOX)
953 PN
potion_vm(Potion *, PN, PN, PN, PN_SIZE, PN *
volatile);
volatile void * old_lo
the old region (TODO: consider making the old region common to all threads)
void potion_allocation_error(void)
void potion_fatal(char *)
PN potion_obj_bitn(Potion *, PN)
void potion_define_global(Potion *, PN, PN)
PN potion_vm(Potion *, PN, PN, PN, PN_SIZE, PN *volatile)
the bytecode run-loop
void potion_syntax_error(Potion *, struct PNSource *, const char *,...) __attribute__((format(printf
PN asmb
assembled instructions
PN potion_bytes(Potion *, size_t)
PN potion_tuple_ins_sort(Potion *P, PN cl, PN self, PN cmp)
PN potion_sig_string(Potion *, PN, PN)
PN upvals
variables in upper scopes
PN potion_num_string(Potion *, PN, PN)
forwarding pointer (in case of reallocation)
bytecode (switch or cgoto)
PN_AST
An AST fragment, non-volatile.
PN values
numbers, strings, etc.
PN potion_rand(Potion *P, PN cl, PN self)
PN line
PNString of src line.
void potion_object_init(Potion *)
PN potion_str(Potion *, const char *)
byte strings are raw character data, volatile, may be appended/changed.
void Potion_Init_readline(Potion *P)
PN potion_load(Potion *, PN, PN, PN)
void potion_table_init(Potion *)
PN_OBJECT_HEADER
PNType vt; PNUniq uniq.
PN_F potion_jit_proto(Potion *, PN)
double potion_rand_double()
generates a random number on [0,1) with 53-bit resolution
PN unclosed
used by parser for named block endings
exec_mode_t
the interpreter (one per thread, houses its own garbage collector)
a tuple is an array of PNs.
PN potion_str_add(Potion *P, PN cl, PN self, PN x)
PN potion_table_set(Potion *, PN, PN, PN)
helper function for potion_table_put:"put", accepts tuple or table
PN potion_filename_push(Potion *, PN)
PN_OBJECT_HEADER
PNType vt; PNUniq uniq.
PN_OBJECT_HEADER
PNType vt; PNUniq uniq.
static PNType potion_qptr_type(PN obj)
if obj is guaranteed to be a PTR fwd only once, no loop.
void potion_compiler_init(Potion *)
PN potion_type_new(Potion *, PNType, PN)
create a non-user type, derived from self
Potion_Flags flags
vm flags: execution model and debug flags
a closure is an anonymous function, without closed values,
the central vtable, see io http://www.piumarta.com/pepsi/objmodel.pdf
void potion_p(Potion *, PN)
PN_SIZE void potion_bytes_obj_string(Potion *, PN, PN)
void potion_file_init(Potion *)
set Env global
PN_OBJECT_HEADER
PNType vt; PNUniq uniq.
struct to wrap arbitrary data that we may want to allocate from Potion.
int potion_sig_find(Potion *, PN, PN)
PN potion_closure_new(Potion *, PN_F, PN, PN_SIZE)
PN potion_run(Potion *, PN, int)
PN potion_table_put(Potion *P, PN cl, PN self, PN key, PN value)
PN PN potion_byte_str(Potion *, const char *)
static PN potion_type_default(char type)
zero values per type
PN potion_sig_name_at(Potion *, PN, int)
PN potion_tuple_at(Potion *P, PN cl, PN self, PN index)
PN potion_source_dumpbc(Potion *P, PN cl, PN proto, PN options)
void potion_error_init(Potion *)
PN potion_closure_arity(Potion *P, PN cl, PN self)
PN potion_obj_mult(Potion *, PN, PN)
void(* OP_F)(Potion *P, struct PNProto *, PNAsm *volatile *,...)
PN potion_bytes_append(Potion *P, PN cl, PN self, PN str)
PN line
currently parsed line (for debug)
PN potion_any_is_nil(Potion *, PN, PN)
PN potion_ref(Potion *P, PN data)
PN potion_byte_str2(Potion *, const char *, size_t len)
static struct PNData * potion_data_alloc(Potion *P, int siz)
static PN potion_fwd(PN)
the potion type is the 't' in the vtable tuple (m,t)
int arity
cached number of declared args, including optional
void potion_num_init(Potion *)
static void potion_gc_update(Potion *P, PN x)
PN potion_eval(Potion *, PN)
static void * potion_gc_alloc(Potion *P, PNType vt, int siz)
quick inline allocation
Potion * potion_gc_boot(void *)
struct PNMemory * mem
allocator/gc
a file is wrapper around a file descriptor, non-volatile but mutable.
PN_SIZE extra
0 or 1 if has code attached at data
PN potion_ivars(Potion *, PN, PN, PN)
PN potion_source_load(Potion *P, PN cl, PN buf)
PN potion_call(Potion *, PN, PN_SIZE, PN *volatile)
void potion_destroy(Potion *)
PN_SIZE fileno
currently parsed file
PN_F jit
jit function pointer
PN potion_source_compile(Potion *P, PN cl, PN self, PN source, PN sig)
void potion_release(Potion *, PN)
void potion_lick_init(Potion *)
a weak ref is used for upvals, it acts as a memory slot, non-volatile but mutable.
definition of the jit targets: x86, ppc, arm
volatile void * birth_lo
the birth region
PN potion_source_dump(Potion *P, PN cl, PN self, PN backend, PN options)
void * cstack
machine stack start
PN potion_num_pow(Potion *, PN, PN, PN)
PNAsm *volatile pbuf
parser buffer
void potion_primitive_init(Potion *)
PN potion_filename_find(Potion *, PN)
standard objects act like C structs the fields are defined by the type and it's a fixed size...
void * protect
end of protected memory
int arity
cached sig arity (number of args)
void potion_lobby_init(Potion *)
enum PN_AST part
AST type, avoid -Wswitch (aligned access: 4+4+8+4+24)
static PNType potion_ptr_type(PN obj)
if obj is guaranteed to be a PTR
a continuation saves the stack and all stack pointers.
PN potion_tuple_shift(Potion *P, PN cl, PN self)
char * potion_find_file(Potion *, char *str, PN_SIZE str_len)
PN potion_table_empty(Potion *P)
PN_OBJECT_HEADER
PNType vt; PNUniq uniq.
PN potion_type_error_want(Potion *, const char *, PN, const char *)
PN potion_num_rand(Potion *P, PN cl, PN self)
void potion_garbagecollect(Potion *, int, int)
a lick is a unit of generic tree data.
PN inner
"licks" PNTuple or "text" PNString member
PN potion_obj_get(Potion *, PN, PN, PN)
implements OP_GETPATH
int potion_sig_arity(Potion *, PN)
number of args of sig tuple, implements the potion_closure_arity method.
DLLEXPORT void Potion_Init_buffile(Potion *P)
unsigned long potion_rand_int()
generates a random number on [0,0xffffffff]-interval
the table class, based on khash
PN potion_tuple_new(Potion *, PN)
PN paths
paths (instance variables)
PN potion_message(Potion *, PN, PN)
PN potion_parse(Potion *, PN, char *)
PN potion_type_error(Potion *, PN)
PN_OBJECT_HEADER
PNType vt; PNUniq uniq.
PN potion_obj_div(Potion *, PN, PN)
PN PN_allocate
common method names in GC protected area
PN potion_io_error(Potion *, const char *)
char potion_type_char(PNType)
valid signature types syntax.y: arg-type = ('s' | 'S' | 'n' | 'N' | 'b' | 'B' | 'k' | 't' | 'o' | 'O'...
volatile void ** birth_storeptr
PN potion_any_cmp(Potion *P, PN cl, PN self, PN value)
Potion * potion_create(void *)
the potion API
PN potion_tuple_bsearch(Potion *P, PN cl, PN self, PN x)
PN potion_class(Potion *, PN, PN, PN)
create a user-class (ie type)
strings are immutable UTF-8, the ID is incremental and they may be garbage collected.
PN potion_bytes_string(Potion *P, PN cl, PN self)
PN potion_vm_proto(Potion *, PN, PN,...)
entrypoint for all bytecode methods from the C api.
void potion_source_init(Potion *)
PN callset
generic call and setter
PN potion_bind(Potion *, PN, PN)
find method for given receiver and message (method lookup)
PN potion_class_find(Potion *, PN)
find class by name. At first only system metaclasses (types), no user classes yet.
PN_OBJECT_HEADER
PNType vt; PNUniq uniq.
PN_SIZE potion_type_size(Potion *, const struct PNObject *)
PN potion_obj_set(Potion *, PN, PN, PN, PN)
implements OP_SETPATH
PN potion_lookup(Potion *, PN, PN, PN)
used in bind and def_method
PN potion_error(Potion *, PN, long, long, PN)
PN potion_tuple_push(Potion *, PN, PN)
JIT if detected at config-time (x86, ppc)
-c stop after compilation
a prototype is compiled source code, a closure block (lambda) non-volatile.
PN potion_table_at(Potion *P, PN cl, PN self, PN key)
PN potion_obj_add(Potion *, PN, PN)
PNFlex *volatile vts
built in types
PN potion_obj_bitl(Potion *, PN, PN)
an error, including a description, file location, a brief excerpt.
ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS PN potion_callcc(Potion *P, PN cl, PN self)
PN potion_str_format(Potion *, const char *,...) __attribute__((format(printf
PN source
parser input and output (AST)
DLLEXPORT void Potion_Init_aio(Potion *P)
static char * potion_str_ptr(PN s)
quick access to either PNString or PNByte pointer
static void * potion_gc_calloc(Potion *P, PNType vt, int siz)
PN_OBJECT_HEADER
PNType vt; PNUniq uniq.
PN potion_vm_class(Potion *, PN, PN)
implements the class op creates a class (or type) from a closure and parent class with obj ivars ...
PN potion_closure_minargs(Potion *P, PN cl, PN self)
sanity-check (possible stack overwrites by callcc)
PN potion_gc_fixed(Potion *, PN, PN)
PN potion_delegated(Potion *, PN, PN)
PN_OBJECT_HEADER
PNType vt; PNUniq uniq.
PN_OBJECT_HEADER
PNType vt; PNUniq uniq.
-d: instrumented bytecode (line stepping) or just slow runloop?
volatile void * birth_cur
int potion_sig_minargs(Potion *, PN)
number of mandatory args, without any optional arguments
int minargs
cached number of mandatory args, without optional
PN potion_greg_parse(Potion *, PN)
PN_SIZE potion_tuple_find(Potion *, PN, PN)
Return index of found value or PN_NONE.
the global interpreter state P. currently singleton (not threads yet)
PN_SIZE pn_printf(Potion *, PN, const char *,...) __attribute__((format(printf
PN potion_def_method(Potion *P, PN, PN, PN, PN)
define a method for a class
PN potion_strtod(Potion *, char *, int)
Convert string to double.
PN potion_strcat(Potion *P, char *str, char *str2)
PN potion_tuple_empty(Potion *)
PN potion_obj_bitr(Potion *, PN, PN)
PN potion_srand(Potion *P, PN cl, PN self, PN seed)
void potion_str_init(Potion *)
PN_SIZE potion_tuple_push_unless(Potion *, PN, PN)
void potion_type_callset_is(PN, PN)
set default writer
void potion_str_hash_init(Potion *)
static PNType potion_type(PN obj)
either immediate (NUM,BOOL,NIL) or a fwd
#define PN_QUICK_FWD(t, obj)
PN_QUICK_FWD - doing a single fwd check after a possible realloc.
struct PNSource *volatile a[3]
PNTuple of 1-3 kids,.
void potion_type_constructor_is(PN, PN)
set default constructor
0x10 16 plain potion syntax
_PN(* PN_F)(Potion *, PN, PN,...)
PN_OBJECT_HEADER
PNType vt; PNUniq uniq.
PN stack
size of the stack
PNType potion_class_type(Potion *, PN)
PN potion_str2(Potion *, char *, size_t)
doubles are floating point numbers stored as binary data.
PN potion_gc_actual(Potion *, PN, PN)
PN potion_double(Potion *, double)
new PNDouble (double)
PN potion_sig_at(Potion *, PN, int)
PN potion_obj_rem(Potion *, PN, PN)
PN_SIZE alloc
overallocate a bit
PN_OBJECT_HEADER
PNType vt; PNUniq uniq.
void potion_cont_init(Potion *)
PN_OBJECT_HEADER
PNType vt; PNUniq uniq.
PN tree
abstract syntax tree
int yypos
parser buffer position
PN_OBJECT_HEADER
PNType vt; PNUniq uniq.
PN potion_obj_get_call(Potion *, PN)
get the default accessor (usually "at")
PN_OBJECT_HEADER
PNType vt; PNUniq uniq.
static void * potion_gc_realloc(Potion *P, PNType vt, struct PNObject *volatile obj, PN_SIZE sz)
PN source
program name or enclosing scope
struct PNTable * strings
table of all strings
PN potion_gc_reserved(Potion *, PN, PN)
void PNType potion_kind_of(PN)
PN potion_obj_get_callset(Potion *, PN)
get default writer
struct PNSource::@1 loc
bitfield of fileno and lineno
void potion_loader_add(Potion *, PN path)
PN potion_sig(Potion *, char *)
void potion_vm_init(Potion *)
PN potion_type_new2(Potion *, PNType, PN, PN)
create a named type
void potion_dump_stack(Potion *)
PN ivars
PNTuple of all our or the parents inherited vars.
PN potion_obj_sub(Potion *, PN, PN)
void potion_loader_init(Potion *)
PN potion_lick(Potion *, PN, PN, PN)
void potion_type_call_is(PN, PN)
sets the default call method of the PNVtable
PN potion_object_new(Potion *P, PN cl, PN self)
PN potion_tuple_with_size(Potion *, unsigned long)