]> git.mxchange.org Git - simgear.git/blob - simgear/nasal/nasal.h
Nasal String wrapper and allow adding methods to string objects.
[simgear.git] / simgear / nasal / nasal.h
1 #ifndef _NASAL_H
2 #define _NASAL_H
3 #ifdef __cplusplus
4 extern "C" {
5 #endif
6
7 #include "naref.h"
8
9 #if __GNUC__ > 2
10 /* This marks the function as having no side effects and depending on
11  * nothing but its arguments, which allows the optimizer to avoid
12  * duplicate calls to naNil(). */
13 #define GCC_PURE __attribute__((__pure__))
14 #else
15 #define GCC_PURE
16 #endif
17
18 typedef struct Context* naContext;
19     
20 // The function signature for an extension function:
21 typedef naRef (*naCFunction)(naContext ctx, naRef me, int argc, naRef* args);
22
23 // All Nasal code runs under the watch of a naContext:
24 naContext naNewContext();
25 void naFreeContext(naContext c);
26
27 // Use this when making a call to a new context "underneath" a
28 // preexisting context on the same stack.  It allows stack walking to
29 // see through the boundary, and eliminates the need to release the
30 // mod lock (i.e. must be called with the mod lock held!)
31 naContext naSubContext(naContext super);
32
33 // The naContext supports a user data pointer that can be used to
34 // store data specific to an naCall invocation without exposing it to
35 // Nasal as a ghost.  FIXME: this API is semi-dangerous, there is no
36 // provision for sharing it, nor for validating the source or type of
37 // the pointer returned.
38 void naSetUserData(naContext c, void* p);
39 void* naGetUserData(naContext c) GCC_PURE;
40
41 // "Save" this object in the context, preventing it (and objects
42 // referenced by it) from being garbage collected.
43 void naSave(naContext ctx, naRef obj);
44
45 // Similar, but the object is automatically released when the
46 // context next runs native bytecode.  Useful for saving off C-space
47 // temporaries to protect them before passing back into a naCall.
48 void naTempSave(naContext c, naRef r);
49
50 // Parse a buffer in memory into a code object.  The srcFile parameter
51 // is a Nasal string representing the "file" from which the code is
52 // read.  The "first line" is typically 1, but is settable for
53 // situations where the Nasal code is embedded in another context with
54 // its own numbering convetions.  If an error occurs, returns nil and
55 // sets the errLine pointer to point to the line at fault.  The string
56 // representation of the error can be retrieved with naGetError() on
57 // the context.
58 naRef naParseCode(naContext c, naRef srcFile, int firstLine,
59                   char* buf, int len, int* errLine);
60
61 // Binds a bare code object (as returned from naParseCode) with a
62 // closure object (a hash) to act as the outer scope / namespace.
63 naRef naBindFunction(naContext ctx, naRef code, naRef closure);
64
65 // Similar, but it binds to the current context's closure (i.e. the
66 // namespace at the top of the current call stack).
67 naRef naBindToContext(naContext ctx, naRef code);
68
69 // Call a code or function object with the specified arguments "on"
70 // the specified object and using the specified hash for the local
71 // variables.  Passing a null args array skips the parameter variables
72 // (e.g. "arg") assignments; to get a zero-length arg instead, pass in
73 // argc==0 and a non-null args vector.  The obj or locals parameters
74 // may be nil.  Will attempt to acquire the mod lock, so call
75 // naModUnlock() first if the lock is already held.
76 naRef naCall(naContext ctx, naRef func, int argc, naRef* args,
77              naRef obj, naRef locals);
78
79 // As naCall(), but continues execution at the operation after a
80 // previous die() call or runtime error.  Useful to do "yield"
81 // semantics, leaving the context in a condition where it can be
82 // restarted from C code.  Cannot be used currently to restart a
83 // failed operation.  Will attempt to acquire the mod lock, so call
84 // naModUnlock() first if the lock is already held.
85 naRef naContinue(naContext ctx);
86
87 // Throw an error from the current call stack.  This function makes a
88 // longjmp call to a handler in naCall() and DOES NOT RETURN.  It is
89 // intended for use in library code that cannot otherwise report an
90 // error via the return value, and MUST be used carefully.  If in
91 // doubt, return naNil() as your error condition.  Works like
92 // printf().
93 void naRuntimeError(naContext c, const char* fmt, ...);
94
95 // "Re-throws" a runtime error caught from the subcontext.  Acts as a
96 // naRuntimeError() called on the parent context.  Does not return.
97 void naRethrowError(naContext subc);
98
99 // Retrieve the specified member from the object, respecting the
100 // "parents" array as for "object.field".  Returns zero for missing
101 // fields.
102 int naMember_get(naContext c, naRef obj, naRef field, naRef* out);
103 int naMember_cget(naContext c, naRef obj, const char* field, naRef* out);
104
105 // Returns a hash containing functions from the Nasal standard library
106 // Useful for passing as a namespace to an initial function call
107 naRef naInit_std(naContext c);
108
109 // Ditto, for other core libraries
110 naRef naInit_math(naContext c);
111 naRef naInit_bits(naContext c);
112 naRef naInit_io(naContext c);
113 naRef naInit_regex(naContext c);
114 naRef naInit_unix(naContext c);
115 naRef naInit_thread(naContext c);
116 naRef naInit_utf8(naContext c);
117 naRef naInit_sqlite(naContext c);
118 naRef naInit_readline(naContext c);
119 naRef naInit_gtk(naContext ctx);
120 naRef naInit_cairo(naContext ctx);
121
122 // Returns a hash which can be used to add methods callable on strings
123 naRef naInit_string(naContext c);
124
125 // Context stack inspection, frame zero is the "top"
126 int naStackDepth(naContext ctx);
127 int naGetLine(naContext ctx, int frame);
128 naRef naGetSourceFile(naContext ctx, int frame);
129 char* naGetError(naContext ctx);
130
131 // Type predicates
132 int naIsNil(naRef r) GCC_PURE;
133 int naIsNum(naRef r) GCC_PURE;
134 int naIsString(naRef r) GCC_PURE;
135 int naIsScalar(naRef r) GCC_PURE;
136 int naIsVector(naRef r) GCC_PURE;
137 int naIsHash(naRef r) GCC_PURE;
138 int naIsCode(naRef r) GCC_PURE;
139 int naIsFunc(naRef r) GCC_PURE;
140 int naIsCCode(naRef r) GCC_PURE;
141
142 // Allocators/generators:
143 naRef naNil() GCC_PURE;
144 naRef naNum(double num) GCC_PURE;
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);
150
151 // Some useful conversion/comparison routines
152 int naEqual(naRef a, naRef b) GCC_PURE;
153 int naStrEqual(naRef a, naRef b) GCC_PURE;
154 int naTrue(naRef b) GCC_PURE;
155 naRef naNumValue(naRef n) GCC_PURE;
156 naRef naStringValue(naContext c, naRef n);
157
158 // String utilities:
159 int naStr_len(naRef s) GCC_PURE;
160 char* naStr_data(naRef s) GCC_PURE;
161 naRef naStr_fromdata(naRef dst, const 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);
165 naRef getStringMethods(naContext c);
166
167 // Vector utilities:
168 int naVec_size(naRef v);
169 naRef naVec_get(naRef v, int i);
170 void naVec_set(naRef vec, int i, naRef o);
171 int naVec_append(naRef vec, naRef o);
172 naRef naVec_removelast(naRef vec);
173 void naVec_setsize(naContext c, naRef vec, int sz);
174
175 // Hash utilities:
176 int naHash_size(naRef h);
177 int naHash_get(naRef hash, naRef key, naRef* out);
178 naRef naHash_cget(naRef hash, char* key);
179 void naHash_set(naRef hash, naRef key, naRef val);
180 void naHash_cset(naRef hash, char* key, naRef val);
181 void naHash_delete(naRef hash, naRef key);
182 /**
183  * Store the keys in ::hash into the vector at ::dst
184  *
185  * @see ::naNewVector
186  */
187 void naHash_keys(naRef dst, naRef hash);
188
189 // Ghost utilities:
190 typedef struct naGhostType {
191     void(*destroy)(void*);
192     const char* name;
193     const char*(*get_member)(naContext c, void*, naRef key, naRef* out);
194     void(*set_member)(naContext c, void*, naRef key, naRef val);
195 } naGhostType;
196
197 /**
198  * Create a ghost for an object without any attributes. If ::t contains pointers
199  * to get_member or set_member function they will be ignored.
200  */
201 naRef        naNewGhost(naContext c, naGhostType* t, void* ghost);
202 /**
203  * Create a ghost for an object. This version uses the get_member and set_member
204  * function pointers in ::t upon trying to get or set a member respectively from
205  * Nasal.
206  */
207 naRef        naNewGhost2(naContext c, naGhostType* t, void* ghost);
208 naGhostType* naGhost_type(naRef ghost);
209 void*        naGhost_ptr(naRef ghost);
210 int          naIsGhost(naRef r);
211
212 // Acquires a "modification lock" on a context, allowing the C code to
213 // modify Nasal data without fear that such data may be "lost" by the
214 // garbage collector (nasal data on the C stack is not examined in
215 // GC!).  This disallows garbage collection until the current thread
216 // can be blocked.  The lock should be acquired whenever nasal objects
217 // are being modified.  It need not be acquired when only read access
218 // is needed, PRESUMING that the Nasal data being read is findable by
219 // the collector (via naSave, for example) and that another Nasal
220 // thread cannot or will not delete the reference to the data.  It
221 // MUST NOT be acquired by naCFunction's, as those are called with the
222 // lock already held; acquiring two locks for the same thread will
223 // cause a deadlock when the GC is invoked.  It should be UNLOCKED by
224 // naCFunction's when they are about to do any long term non-nasal
225 // processing and/or blocking I/O.  Note that naModLock() may need to
226 // block to allow garbage collection to occur, and that garbage
227 // collection by other threads may be blocked until naModUnlock() is
228 // called.  It must also be UNLOCKED by threads that hold a lock
229 // already before making a naCall() or naContinue() call -- these
230 // functions will attempt to acquire the lock again.
231 void naModLock();
232 void naModUnlock();
233
234 // Library utilities.  Generate namespaces and add symbols.
235 typedef struct { char* name; naCFunction func; } naCFuncItem;
236 naRef naGenLib(naContext c, naCFuncItem *funcs);
237 void naAddSym(naContext c, naRef ns, char *sym, naRef val);
238
239 #ifdef __cplusplus
240 } // extern "C"
241 #endif
242 #endif // _NASAL_H