]> git.mxchange.org Git - simgear.git/blob - simgear/nasal/nasal.h
57b0372de295c78fa401df1ac1360f7a8eba6551
[simgear.git] / simgear / nasal / nasal.h
1 #ifndef _NASAL_H
2 #define _NASAL_H
3 #ifdef __cplusplus
4 extern "C" {
5 #endif
6
7 // This is a nasal "reference".  They are always copied by value, and
8 // contain either a pointer to a garbage-collectable nasal object
9 // (string, vector, hash) or a floating point number.  Keeping the
10 // number here is an optimization to prevent the generation of
11 // zillions of tiny "number" object that have to be collected.  Note
12 // sneaky hack: on little endian systems, placing reftag after ptr and
13 // putting 1's in the top 13 (except the sign bit) bits makes the
14 // double value a NaN, and thus unmistakable (no actual number can
15 // appear as a reference, and vice versa).  Swap the structure order
16 // on 32 bit big-endian systems.  On 64 bit sytems of either
17 // endianness, reftag and the double won't be coincident anyway.
18 #define NASAL_REFTAG 0x7ff56789 // == 2,146,789,257 decimal
19 typedef union {
20     double num;
21     struct {
22 #ifdef NASAL_BIG_ENDIAN_32_BIT
23         int reftag; // Big-endian systems need this here!
24 #endif
25         union {
26             struct naObj* obj;
27             struct naStr* str;
28             struct naVec* vec;
29             struct naHash* hash;
30             struct naCode* code;
31             struct naFunc* func;
32             struct naClosure* closure;
33             struct naCCode* ccode;
34             struct naGhost* ghost;
35         } ptr;
36 #ifndef NASAL_BIG_ENDIAN_32_BIT
37         int reftag; // Little-endian and 64 bit systems need this here!
38 #endif
39     } ref;
40 } naRef;
41
42 typedef struct Context* naContext;
43     
44 // The function signature for an extension function:
45 typedef naRef (*naCFunction)(naContext ctx, naRef args);
46
47 // All Nasal code runs under the watch of a naContext:
48 naContext naNewContext();
49
50 // Save this object in the context, preventing it (and objects
51 // referenced by it) from being garbage collected.
52 void naSave(naContext ctx, naRef obj);
53
54 // Parse a buffer in memory into a code object.
55 naRef naParseCode(naContext c, naRef srcFile, int firstLine,
56                   char* buf, int len, int* errLine);
57
58 // Binds a bare code object (as returned from naParseCode) with a
59 // closure object (a hash) to act as the outer scope / namespace.
60 // FIXME: this API is weak.  It should expose the recursive nature of
61 // closures, and allow for extracting the closure and namespace
62 // information from function objects.
63 naRef naBindFunction(naContext ctx, naRef code, naRef closure);
64
65 // Call a code or function object with the specifed arguments "on" the
66 // specified object and using the specified hash for the local
67 // variables.  Any of args, obj or locals may be nil.
68 naRef naCall(naContext ctx, naRef func, naRef args, naRef obj, naRef locals);
69
70 // Throw an error from the current call stack.  This function makes a
71 // longjmp call to a handler in naCall() and DOES NOT RETURN.  It is
72 // intended for use in library code that cannot otherwise report an
73 // error via the return value, and MUST be used carefully.  If in
74 // doubt, return naNil() as your error condition.
75 void naRuntimeError(naContext ctx, char* msg);
76
77 // Call a method on an object (NOTE: func is a function binding, *not*
78 // a code object as returned from naParseCode).
79 naRef naMethod(naContext ctx, naRef func, naRef object);
80
81 // Returns a hash containing functions from the Nasal standard library
82 // Useful for passing as a namespace to an initial function call
83 naRef naStdLib(naContext c);
84
85 // Ditto, with math functions
86 naRef naMathLib(naContext c);
87
88 // Current line number & error message
89 int naStackDepth(naContext ctx);
90 int naGetLine(naContext ctx, int frame);
91 naRef naGetSourceFile(naContext ctx, int frame);
92 char* naGetError(naContext ctx);
93
94 // Type predicates
95 int naIsNil(naRef r);
96 int naIsNum(naRef r);
97 int naIsString(naRef r);
98 int naIsScalar(naRef r);
99 int naIsVector(naRef r);
100 int naIsHash(naRef r);
101 int naIsCode(naRef r);
102 int naIsFunc(naRef r);
103 int naIsCCode(naRef r);
104
105 // Allocators/generators:
106 naRef naNil();
107 naRef naNum(double num);
108 naRef naNewString(naContext c);
109 naRef naNewVector(naContext c);
110 naRef naNewHash(naContext c);
111 naRef naNewFunc(naContext c, naRef code);
112 naRef naNewCCode(naContext c, naCFunction fptr);
113
114 // Some useful conversion/comparison routines
115 int naEqual(naRef a, naRef b);
116 int naTrue(naRef b);
117 naRef naNumValue(naRef n);
118 naRef naStringValue(naContext c, naRef n);
119
120 // String utilities:
121 int naStr_len(naRef s);
122 char* naStr_data(naRef s);
123 naRef naStr_fromdata(naRef dst, char* data, int len);
124 naRef naStr_concat(naRef dest, naRef s1, naRef s2);
125 naRef naStr_substr(naRef dest, naRef str, int start, int len);
126
127 // Vector utilities:
128 int naVec_size(naRef v);
129 naRef naVec_get(naRef v, int i);
130 void naVec_set(naRef vec, int i, naRef o);
131 int naVec_append(naRef vec, naRef o);
132 naRef naVec_removelast(naRef vec);
133
134 // Hash utilities:
135 int naHash_size(naRef h);
136 int naHash_get(naRef hash, naRef key, naRef* out);
137 naRef naHash_cget(naRef hash, char* key);
138 void naHash_set(naRef hash, naRef key, naRef val);
139 void naHash_cset(naRef hash, char* key, naRef val);
140 void naHash_delete(naRef hash, naRef key);
141 void naHash_keys(naRef dst, naRef hash);
142
143 // Ghost utilities:
144 typedef struct naGhostType {
145     void (*destroy)(void* ghost);
146 } naGhostType;
147 naRef        naNewGhost(naContext c, naGhostType* t, void* ghost);
148 naGhostType* naGhost_type(naRef ghost);
149 void*        naGhost_ptr(naRef ghost);
150 int          naIsGhost(naRef r);
151
152 #ifdef __cplusplus
153 } // extern "C"
154 #endif
155 #endif // _NASAL_H