00001 #ifndef _NASAL_H 00002 #define _NASAL_H 00003 #ifdef __cplusplus 00004 extern "C" { 00005 #endif 00006 00007 #include "naref.h" 00008 00009 #if __GNUC__ > 2 00010 /* This marks the function as having no side effects and depending on 00011 * nothing but its arguments, which allows the optimizer to avoid 00012 * duplicate calls to naNil(). */ 00013 #define GCC_PURE __attribute__((__pure__)) 00014 #else 00015 #define GCC_PURE 00016 #endif 00017 00018 typedef struct Context* naContext; 00019 00020 // The function signature for an extension function: 00021 typedef naRef (*naCFunction)(naContext ctx, naRef me, int argc, naRef* args); 00022 00023 // All Nasal code runs under the watch of a naContext: 00024 naContext naNewContext(); 00025 void naFreeContext(naContext c); 00026 00027 // Use this when making a call to a new context "underneath" a 00028 // preexisting context on the same stack. It allows stack walking to 00029 // see through the boundary, and eliminates the need to release the 00030 // mod lock (i.e. must be called with the mod lock held!) 00031 naContext naSubContext(naContext super); 00032 00033 // The naContext supports a user data pointer that can be used to 00034 // store data specific to an naCall invocation without exposing it to 00035 // Nasal as a ghost. FIXME: this API is semi-dangerous, there is no 00036 // provision for sharing it, nor for validating the source or type of 00037 // the pointer returned. 00038 void naSetUserData(naContext c, void* p); 00039 void* naGetUserData(naContext c) GCC_PURE; 00040 00041 // "Save" this object in the context, preventing it (and objects 00042 // referenced by it) from being garbage collected. 00043 void naSave(naContext ctx, naRef obj); 00044 00045 // Similar, but the object is automatically released when the 00046 // context next runs native bytecode. Useful for saving off C-space 00047 // temporaries to protect them before passing back into a naCall. 00048 void naTempSave(naContext c, naRef r); 00049 00050 // Parse a buffer in memory into a code object. The srcFile parameter 00051 // is a Nasal string representing the "file" from which the code is 00052 // read. The "first line" is typically 1, but is settable for 00053 // situations where the Nasal code is embedded in another context with 00054 // its own numbering convetions. If an error occurs, returns nil and 00055 // sets the errLine pointer to point to the line at fault. The string 00056 // representation of the error can be retrieved with naGetError() on 00057 // the context. 00058 naRef naParseCode(naContext c, naRef srcFile, int firstLine, 00059 char* buf, int len, int* errLine); 00060 00061 // Binds a bare code object (as returned from naParseCode) with a 00062 // closure object (a hash) to act as the outer scope / namespace. 00063 naRef naBindFunction(naContext ctx, naRef code, naRef closure); 00064 00065 // Similar, but it binds to the current context's closure (i.e. the 00066 // namespace at the top of the current call stack). 00067 naRef naBindToContext(naContext ctx, naRef code); 00068 00069 // Call a code or function object with the specified arguments "on" 00070 // the specified object and using the specified hash for the local 00071 // variables. Passing a null args array skips the parameter variables 00072 // (e.g. "arg") assignments; to get a zero-length arg instead, pass in 00073 // argc==0 and a non-null args vector. The obj or locals parameters 00074 // may be nil. Will attempt to acquire the mod lock, so call 00075 // naModUnlock() first if the lock is already held. 00076 naRef naCall(naContext ctx, naRef func, int argc, naRef* args, 00077 naRef obj, naRef locals); 00078 00079 // As naCall(), but continues execution at the operation after a 00080 // previous die() call or runtime error. Useful to do "yield" 00081 // semantics, leaving the context in a condition where it can be 00082 // restarted from C code. Cannot be used currently to restart a 00083 // failed operation. Will attempt to acquire the mod lock, so call 00084 // naModUnlock() first if the lock is already held. 00085 naRef naContinue(naContext ctx); 00086 00087 // Throw an error from the current call stack. This function makes a 00088 // longjmp call to a handler in naCall() and DOES NOT RETURN. It is 00089 // intended for use in library code that cannot otherwise report an 00090 // error via the return value, and MUST be used carefully. If in 00091 // doubt, return naNil() as your error condition. Works like 00092 // printf(). 00093 void naRuntimeError(naContext c, const char* fmt, ...); 00094 00095 // "Re-throws" a runtime error caught from the subcontext. Acts as a 00096 // naRuntimeError() called on the parent context. Does not return. 00097 void naRethrowError(naContext subc); 00098 00099 // Retrieve the specified member from the object, respecting the 00100 // "parents" array as for "object.field". Returns zero for missing 00101 // fields. 00102 int naMember_get(naRef obj, naRef field, naRef* out); 00103 int naMember_cget(naRef obj, const char* field, naRef* out); 00104 00105 // Returns a hash containing functions from the Nasal standard library 00106 // Useful for passing as a namespace to an initial function call 00107 naRef naInit_std(naContext c); 00108 00109 // Ditto, for other core libraries 00110 naRef naInit_math(naContext c); 00111 naRef naInit_bits(naContext c); 00112 naRef naInit_io(naContext c); 00113 naRef naInit_regex(naContext c); 00114 naRef naInit_unix(naContext c); 00115 naRef naInit_thread(naContext c); 00116 naRef naInit_utf8(naContext c); 00117 naRef naInit_sqlite(naContext c); 00118 naRef naInit_readline(naContext c); 00119 naRef naInit_gtk(naContext ctx); 00120 naRef naInit_cairo(naContext ctx); 00121 00122 // Context stack inspection, frame zero is the "top" 00123 int naStackDepth(naContext ctx); 00124 int naGetLine(naContext ctx, int frame); 00125 naRef naGetSourceFile(naContext ctx, int frame); 00126 char* naGetError(naContext ctx); 00127 00128 // Type predicates 00129 int naIsNil(naRef r) GCC_PURE; 00130 int naIsNum(naRef r) GCC_PURE; 00131 int naIsString(naRef r) GCC_PURE; 00132 int naIsScalar(naRef r) GCC_PURE; 00133 int naIsVector(naRef r) GCC_PURE; 00134 int naIsHash(naRef r) GCC_PURE; 00135 int naIsCode(naRef r) GCC_PURE; 00136 int naIsFunc(naRef r) GCC_PURE; 00137 int naIsCCode(naRef r) GCC_PURE; 00138 00139 // Allocators/generators: 00140 naRef naNil() GCC_PURE; 00141 naRef naNum(double num) GCC_PURE; 00142 naRef naNewString(naContext c); 00143 naRef naNewVector(naContext c); 00144 naRef naNewHash(naContext c); 00145 naRef naNewFunc(naContext c, naRef code); 00146 naRef naNewCCode(naContext c, naCFunction fptr); 00147 00148 // Some useful conversion/comparison routines 00149 int naEqual(naRef a, naRef b) GCC_PURE; 00150 int naStrEqual(naRef a, naRef b) GCC_PURE; 00151 int naTrue(naRef b) GCC_PURE; 00152 naRef naNumValue(naRef n) GCC_PURE; 00153 naRef naStringValue(naContext c, naRef n); 00154 00155 // String utilities: 00156 int naStr_len(naRef s) GCC_PURE; 00157 char* naStr_data(naRef s) GCC_PURE; 00158 naRef naStr_fromdata(naRef dst, const char* data, int len); 00159 naRef naStr_concat(naRef dest, naRef s1, naRef s2); 00160 naRef naStr_substr(naRef dest, naRef str, int start, int len); 00161 naRef naInternSymbol(naRef sym); 00162 00163 // Vector utilities: 00164 int naVec_size(naRef v); 00165 naRef naVec_get(naRef v, int i); 00166 void naVec_set(naRef vec, int i, naRef o); 00167 int naVec_append(naRef vec, naRef o); 00168 naRef naVec_removelast(naRef vec); 00169 void naVec_setsize(naRef vec, int sz); 00170 00171 // Hash utilities: 00172 int naHash_size(naRef h); 00173 int naHash_get(naRef hash, naRef key, naRef* out); 00174 naRef naHash_cget(naRef hash, char* key); 00175 void naHash_set(naRef hash, naRef key, naRef val); 00176 void naHash_cset(naRef hash, char* key, naRef val); 00177 void naHash_delete(naRef hash, naRef key); 00178 void naHash_keys(naRef dst, naRef hash); 00179 00180 // Ghost utilities: 00181 typedef struct naGhostType { 00182 void(*destroy)(void*); 00183 const char* name; 00184 } naGhostType; 00185 naRef naNewGhost(naContext c, naGhostType* t, void* ghost); 00186 naGhostType* naGhost_type(naRef ghost); 00187 void* naGhost_ptr(naRef ghost); 00188 int naIsGhost(naRef r); 00189 00190 // Acquires a "modification lock" on a context, allowing the C code to 00191 // modify Nasal data without fear that such data may be "lost" by the 00192 // garbage collector (nasal data on the C stack is not examined in 00193 // GC!). This disallows garbage collection until the current thread 00194 // can be blocked. The lock should be acquired whenever nasal objects 00195 // are being modified. It need not be acquired when only read access 00196 // is needed, PRESUMING that the Nasal data being read is findable by 00197 // the collector (via naSave, for example) and that another Nasal 00198 // thread cannot or will not delete the reference to the data. It 00199 // MUST NOT be acquired by naCFunction's, as those are called with the 00200 // lock already held; acquiring two locks for the same thread will 00201 // cause a deadlock when the GC is invoked. It should be UNLOCKED by 00202 // naCFunction's when they are about to do any long term non-nasal 00203 // processing and/or blocking I/O. Note that naModLock() may need to 00204 // block to allow garbage collection to occur, and that garbage 00205 // collection by other threads may be blocked until naModUnlock() is 00206 // called. It must also be UNLOCKED by threads that hold a lock 00207 // already before making a naCall() or naContinue() call -- these 00208 // functions will attempt to acquire the lock again. 00209 void naModLock(); 00210 void naModUnlock(); 00211 00212 // Library utilities. Generate namespaces and add symbols. 00213 typedef struct { char* name; naCFunction func; } naCFuncItem; 00214 naRef naGenLib(naContext c, naCFuncItem *funcs); 00215 void naAddSym(naContext c, naRef ns, char *sym, naRef val); 00216 00217 #ifdef __cplusplus 00218 } // extern "C" 00219 #endif 00220 #endif // _NASAL_H