10 # include <machine/endian.h>
11 # elif defined(__CYGWIN__) || defined(__MINGW32__)
12 # include <sys/param.h>
16 # ifndef LITTLE_ENDIAN
17 # define LITTLE_ENDIAN 1234 /* LSB first: i386, vax */
20 # define BIG_ENDIAN 4321 /* MSB first: 68000, ibm, net */
23 # if defined(ultrix) || defined(__alpha__) || defined(__alpha) || \
24 defined(__i386__) || defined(__i486__) || defined(_X86_) || \
26 # define BYTE_ORDER LITTLE_ENDIAN
28 # define BYTE_ORDER BIG_ENDIAN
31 #endif /* BYTE_ORDER */
33 #if BYTE_ORDER == BIG_ENDIAN
35 # if (LONG_MAX == 2147483647)
36 # define NASAL_BIG_ENDIAN_32_BIT 1
40 // This is a nasal "reference". They are always copied by value, and
41 // contain either a pointer to a garbage-collectable nasal object
42 // (string, vector, hash) or a floating point number. Keeping the
43 // number here is an optimization to prevent the generation of
44 // zillions of tiny "number" object that have to be collected. Note
45 // sneaky hack: on little endian systems, placing reftag after ptr and
46 // putting 1's in the top 13 (except the sign bit) bits makes the
47 // double value a NaN, and thus unmistakable (no actual number can
48 // appear as a reference, and vice versa). Swap the structure order
49 // on 32 bit big-endian systems. On 64 bit sytems of either
50 // endianness, reftag and the double won't be coincident anyway.
51 #define NASAL_REFTAG 0x7ff56789 // == 2,146,789,257 decimal
55 #ifdef NASAL_BIG_ENDIAN_32_BIT
56 int reftag; // Big-endian systems need this here!
65 struct naCCode* ccode;
66 struct naGhost* ghost;
68 #ifndef NASAL_BIG_ENDIAN_32_BIT
69 int reftag; // Little-endian and 64 bit systems need this here!
74 typedef struct Context* naContext;
76 // The function signature for an extension function:
77 typedef naRef (*naCFunction)(naContext ctx, naRef me, int argc, naRef* args);
79 // All Nasal code runs under the watch of a naContext:
80 naContext naNewContext();
81 void naFreeContext(naContext c);
83 // Save this object in the context, preventing it (and objects
84 // referenced by it) from being garbage collected.
85 void naSave(naContext ctx, naRef obj);
87 // Parse a buffer in memory into a code object.
88 naRef naParseCode(naContext c, naRef srcFile, int firstLine,
89 char* buf, int len, int* errLine);
91 // Binds a bare code object (as returned from naParseCode) with a
92 // closure object (a hash) to act as the outer scope / namespace.
93 // FIXME: this API is weak. It should expose the recursive nature of
94 // closures, and allow for extracting the closure and namespace
95 // information from function objects.
96 naRef naBindFunction(naContext ctx, naRef code, naRef closure);
98 // Similar, but it binds to the current context's closure (i.e. the
99 // namespace at the top of the current call stack).
100 naRef naBindToContext(naContext ctx, naRef code);
102 // Call a code or function object with the specifed arguments "on" the
103 // specified object and using the specified hash for the local
104 // variables. Any of args, obj or locals may be nil.
105 naRef naCall(naContext ctx, naRef func, naRef args, naRef obj, naRef locals);
107 // Throw an error from the current call stack. This function makes a
108 // longjmp call to a handler in naCall() and DOES NOT RETURN. It is
109 // intended for use in library code that cannot otherwise report an
110 // error via the return value, and MUST be used carefully. If in
111 // doubt, return naNil() as your error condition.
112 void naRuntimeError(naContext ctx, char* msg);
114 // Call a method on an object (NOTE: func is a function binding, *not*
115 // a code object as returned from naParseCode).
116 naRef naMethod(naContext ctx, naRef func, naRef object);
118 // Returns a hash containing functions from the Nasal standard library
119 // Useful for passing as a namespace to an initial function call
120 naRef naStdLib(naContext c);
122 // Ditto, with math functions
123 naRef naMathLib(naContext c);
125 // Current line number & error message
126 int naStackDepth(naContext ctx);
127 int naGetLine(naContext ctx, int frame);
128 naRef naGetSourceFile(naContext ctx, int frame);
129 char* naGetError(naContext ctx);
132 int naIsNil(naRef r);
133 int naIsNum(naRef r);
134 int naIsString(naRef r);
135 int naIsScalar(naRef r);
136 int naIsVector(naRef r);
137 int naIsHash(naRef r);
138 int naIsCode(naRef r);
139 int naIsFunc(naRef r);
140 int naIsCCode(naRef r);
142 // Allocators/generators:
144 naRef naNum(double num);
145 naRef naNewString(naContext c);
146 naRef naNewVector(naContext c);
147 naRef naNewHash(naContext c);
148 naRef naNewFunc(naContext c, naRef code);
149 naRef naNewCCode(naContext c, naCFunction fptr);
151 // Some useful conversion/comparison routines
152 int naEqual(naRef a, naRef b);
153 int naStrEqual(naRef a, naRef b);
155 naRef naNumValue(naRef n);
156 naRef naStringValue(naContext c, naRef n);
159 int naStr_len(naRef s);
160 char* naStr_data(naRef s);
161 naRef naStr_fromdata(naRef dst, char* data, int len);
162 naRef naStr_concat(naRef dest, naRef s1, naRef s2);
163 naRef naStr_substr(naRef dest, naRef str, int start, int len);
164 naRef naInternSymbol(naRef sym);
167 int naVec_size(naRef v);
168 naRef naVec_get(naRef v, int i);
169 void naVec_set(naRef vec, int i, naRef o);
170 int naVec_append(naRef vec, naRef o);
171 naRef naVec_removelast(naRef vec);
172 void naVec_setsize(naRef vec, int sz);
175 int naHash_size(naRef h);
176 int naHash_get(naRef hash, naRef key, naRef* out);
177 naRef naHash_cget(naRef hash, char* key);
178 void naHash_set(naRef hash, naRef key, naRef val);
179 void naHash_cset(naRef hash, char* key, naRef val);
180 void naHash_delete(naRef hash, naRef key);
181 void naHash_keys(naRef dst, naRef hash);
184 typedef struct naGhostType {
185 void (*destroy)(void* ghost);
187 naRef naNewGhost(naContext c, naGhostType* t, void* ghost);
188 naGhostType* naGhost_type(naRef ghost);
189 void* naGhost_ptr(naRef ghost);
190 int naIsGhost(naRef r);
192 // Acquires a "modification lock" on a context, allowing the C code to
193 // modify Nasal data without fear that such data may be "lost" by the
194 // garbage collector (the C stack is not examined in GC!). This
195 // disallows garbage collection until the current thread can be
196 // blocked. The lock should be acquired whenever modifications to
197 // Nasal objects are made. It need not be acquired when only read
198 // access is needed. It MUST NOT be acquired by naCFunction's, as
199 // those are called with the lock already held; acquiring two locks
200 // for the same thread will cause a deadlock when the GC is invoked.
201 // It should be UNLOCKED by naCFunction's when they are about to do
202 // any long term non-nasal processing and/or blocking I/O.