root/trunk/orca/ovalue.h

Revision 154, 15.3 kB (checked in by krobillard, 2 years ago)

Orca - Replaced atom variables with fixed atom defines.

Line 
1 #ifndef OVALUE_H
2 #define OVALUE_H
3 /*============================================================================
4     ORCA Interpreter
5     Copyright (C) 2005-2006  Karl Robillard
6
7     This library is free software; you can redistribute it and/or
8     modify it under the terms of the GNU Lesser General Public
9     License as published by the Free Software Foundation; either
10     version 2.1 of the License, or (at your option) any later version.
11
12     This library is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15     Lesser General Public License for more details.
16
17     You should have received a copy of the GNU Lesser General Public
18     License along with this library; if not, write to the Free Software
19     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 ===========================================================================*/
21
22
23 #include <stdint.h>
24
25
26 /*
27    The following namespaces are used:
28
29    OT_*  Value type defines
30    OR_*  Constants
31    O*    Structures and types
32    or*   Functions, variables, macros
33 */
34
35
36 #define OR_VERSION_STR  "0.0.24"
37 #define OR_VERSION      0x000024
38
39
40 // Simple datatypes
41
42 #define OT_UNSET        0
43 #define OT_NONE         1
44 #define OT_WORD         2
45 #define OT_LITWORD      3
46 #define OT_SETWORD      4
47 #define OT_GETWORD      5
48 #define OT_REFINEMENT   6
49 #define OT_OP           7
50 #define OT_NATIVE       8
51 #define OT_NUMBER       9
52 #define OT_INTEGER      10
53 #define OT_DECIMAL      11
54 #define OT_PAIR         12
55 #define OT_TUPLE        13
56 #define OT_CHAR         14
57 #define OT_LOGIC        15
58 #define OT_DATATYPE     16
59 #define OT_TIME         17
60 #define OT_DATE         18
61 #define OT_ACTION       19
62
63 // Complex datatypes
64
65 #define OT_COMPLEX      20
66 #define OT_BLOCK        20
67 #define OT_PAREN        21
68 #define OT_PATH         22
69 #define OT_LITPATH      23
70 #define OT_SETPATH      24
71 #define OT_STRING       25
72 #define OT_UNICODE      26
73 #define OT_ISSUE        27
74 #define OT_TAG          28
75 #define OT_FILE         29
76 #define OT_BINARY       30
77 #define OT_LIST         31
78 #define OT_HASH         32
79 #define OT_DEC_ARRAY    33
80 #define OT_INT_ARRAY    34
81 #define OT_SERIES       35
82
83 #define OT_OBJECT       36
84 #define OT_FUNCTION     37
85 #define OT_BITSET       38
86 #define OT_ERROR        39
87 #define OT_PORT         40
88 #define OT_STRUCT       41
89
90 #define OT_CORE         42
91
92 // Graphics datatypes
93
94 #define OT_IMAGE        42
95 #define OT_SOUND        43
96 #define OT_WIDGET       44
97 #define OT_VEC2         45
98 #define OT_VEC3         46
99 #define OT_MATRIX       47
100 #define OT_RESOURCE     48
101
102 #define OT_COUNT        49
103
104
105 #define OR_TMP_SIZE     512
106
107 #define OR_FALSE        0
108 #define OR_TRUE         1
109
110 #define OR_TUPLE_MAX    10
111
112 // orLookupPath() terminator.
113 #define OR_LPATH_END    -1
114
115 #define OR_INVALID_HOLD -1
116 #define OR_MAX_QHOLDS   256
117
118
119 // OValue flags
120
121 #define OR_FLAG_EOL         0x01
122 #define OR_FLAG_BEOL        0x02    // block! only
123 #define OR_FLAG_HEADER      0x04    // block! only
124 #define OR_FLAG_HEX         0x02    // integer! only
125 #define OR_FLAG_RECURSION   0x02    // object! only
126 //#define OR_FLAG_CLOSURE     0x04    // object! only
127 #define OR_FLAG_CATCH       0x08
128 #define OR_FLAG_THROW       0x10
129
130 // OWord flags
131
132 #define OR_WORD_PROT    0x01
133
134
135 typedef int32_t     OIndex;
136 typedef int16_t     OAtom;
137
138
139 typedef struct
140 {
141     OIndex      wblkN;
142     OIndex      vblkN;
143 }
144 OContext;
145
146
147 typedef struct
148 {
149     OIndex      wordBlk;
150     OIndex      context;
151     uint16_t    index;
152     uint16_t    atom;
153 }
154 OWordRef;
155
156
157 // NOTE: Must keep order of first 5 OR_ERROR_ in sync with errorText[].
158
159 #define OR_ERROR_SYNTAX     0
160 #define OR_ERROR_SCRIPT     1
161 #define OR_ERROR_MATH       2
162 #define OR_ERROR_ACCESS     3
163 #define OR_ERROR_INTERNAL   4
164 #define OR_ERROR_RETURN     5
165 #define OR_ERROR_BREAK      6
166 #define OR_ERROR_QUIT       7
167 #define OR_ERROR_HALT       8
168 #define OR_ERROR_THROW      9
169
170
171 typedef void (*ONativeFunc)(void*);
172
173
174 #ifdef __GNUC__
175 #define OVALUE_PACK  __attribute__ ((__packed__))
176 #endif
177 #ifdef _MSC_VER
178 #pragma pack(push)
179 #pragma pack(4)
180 #define OVALUE_PACK
181 #endif
182
183 typedef struct
184 {
185     uint8_t     type;
186     uint8_t     flags;
187     uint8_t     argc;               /* Sub-type for error! */
188     uint8_t     refc;
189
190     union
191     {
192         OIndex      index;
193         int32_t     integer;
194         uint8_t     tuple[OR_TUPLE_MAX];
195         int32_t     pair[2];
196         OWordRef    word;
197         OContext    ctx;
198         struct {
199             OIndex      n;
200             OIndex      it;
201         } series;
202         struct {
203             int32_t pad;
204             double  decimal;
205         } OVALUE_PACK num;
206         struct {
207             OIndex      specBlk;
208             OIndex      bodyBlk;
209             OIndex      context;
210         } func;
211         struct {
212             OIndex      specBlk;
213             ONativeFunc addr;       /* On 8 byte boundary (64-bit systems) */
214         } OVALUE_PACK native;
215         struct {
216             OIndex      msg;        /* Name atom for OR_ERROR_THROW, a string
217                                        index for most other types */
218             OIndex      block;
219             uint16_t    nearVal;    /* LIMIT: block length; should be OIndex */
220             uint16_t    funcName;
221         } error;
222         struct {
223             float x;
224             float y;
225             float z;
226         } vec3;
227     } OVALUE_PACK;
228 }
229 OValue;
230
231 #ifdef _MSC_VER
232 #pragma pack(pop)
233 #endif
234
235
236 typedef struct
237 {
238     uint16_t    flags;
239     OAtom       atom;
240     OIndex      str;
241 }
242 OWord;
243
244
245 typedef struct
246 {
247     uint16_t    refCount;
248     uint16_t    dataType;
249     OIndex      which;
250 }
251 OHold;
252
253
254 typedef struct
255 {
256     int32_t     avail;
257     int32_t     used;
258     union
259     {
260         void*       buf;
261         OValue*     values;
262         OWord*      words;
263         OIndex*     indices;
264         char*       charArray;
265         uint8_t*    byteArray;
266         uint16_t*   unicodeArray;
267         int32_t*    integers;
268         double*     decimals;
269         float*      floats;
270     };
271 }
272 OArray;
273
274
275 typedef OArray      OBlock;     // Array of OValue
276 typedef OArray      OBinary;    // Array of uint8_t
277 typedef OArray      OString;    // Array of char
278 typedef OArray      OProto;     // Array of OWord
279
280
281 typedef struct
282 {
283     uint32_t    count;
284     OIndex      sweepStart;
285     OIndex      freeList;
286 }
287 OArrayGC;
288
289
290 typedef struct
291 {
292     int (*open)( OValue* spec, OContext* ctx );
293     void (*close)( OContext* );
294     void (*read)( OContext*, OValue* a1 );
295     void (*write)( OContext*, OValue* a1 );
296 }
297 OPortDevice;
298
299
300 typedef struct
301 {
302     OArray      blocks;
303     OArray      strings;
304     OArray      holds;
305
306     OArray      atoms;
307     OBlock      dataStack;
308     OArray      callStack;
309
310     OValue*     error;
311
312     OIndex      sweepStartAtom;
313
314     uint16_t    gcEnabled;
315     uint16_t    secure;
316
317     OArrayGC    freeBlocks;
318     OArrayGC    freeStrings;
319     OArrayGC    freeHolds;
320
321     OHold*      quickHolds;
322     int         quickHoldsUsed;
323
324 #ifdef OR_CONFIG_NUMBER_ARRAYS
325     OArray      decArr;
326     OArray      intArr;
327     OArrayGC    freeDecArr;
328     OArrayGC    freeIntArr;
329 #endif
330
331     OArray      loaders;
332     OArray      devices;
333 }
334 OEnv;
335
336
337 #ifdef __cplusplus
338 extern "C" {
339 #endif
340
341 extern OEnv* orEnv;
342
343 extern uint8_t charset_white[32];
344 extern char    orTmp[OR_TMP_SIZE];
345
346 void    orInitEnv( OEnv*, int dataStackSize, int callStackSize );
347 void    orFreeEnv( OEnv* );
348 void    orResetEnv( OEnv* );
349 void    orAtomStr( OAtom, OString* );
350 OAtom   orInternAtom( const char* str, int len );
351 OIndex  orInternA( OBlock* wordBlk, OAtom );
352 OValue* orIntern( OContext*, const char* str, int len, OValue* wordV );
353 int     orLookup( const OContext*, int atom );
354 OValue* orLookupPath( int first_tag, ... );
355 const char* orDatatypeName( int type );
356 void    orNative( void* func, const char* name );
357 void    orMakeOp( void* func, const char* name );
358 void    orDumpBlock( OBlock*, int depth );
359 void    orBind( OBlock*, OContext* ctx );
360 void    orEvalBlock( OBlock*, int seriesIndex );
361 void    orEvalCStr( const char* txt, int len );
362 void    orDoNative( OValue* );
363 void    orLockGarbageCollector();
364 void    orCollectGarbage();
365 void    orFreeBlock( OIndex );
366 void    orRegisterPortDevice( OPortDevice* );
367 void    orRegisterFileLoader( int (*func)( const char*, uint8_t*, int ) );
368 int     orEqual( const OValue*, const OValue* );
369 void    orForm( OString* out, const OValue* val );
370 void    orMold( OString* out, const OValue* val );
371 void    orProbe( OValue* );
372 void    orPrintNative( OValue* );
373 void    orError( const char* fmt, ... );
374 void    orErrorT( int type, const char* fmt, ... );
375 void    orSetError( OValue*, int type );
376 void    orSetErrorLoc( int blkN, int vi );
377
378 int       orMakeChar( const char* txt, int len );
379 OIndex    orMakeCString( const char* txt, int len );
380 OIndex    orMakeCStringS( const char* txt, int len );
381 OIndex    orMakeBinaryStr( const char* txt, int len );
382 OBlock*   orMakeBlock( int size );
383 OString*  orMakeString( int size );
384 void      orMakeContext( OContext*, int size );
385 int       orMakeObject( OBlock*, int index, OContext* );
386 OBinary*  orMakeCharset( const OString*, int index );
387
388 #ifdef OR_CONFIG_NUMBER_ARRAYS
389 OArray*  orMakeDecArray( int size );
390 OArray*  orMakeIntArray( int size );
391 void     orDecArrayAppend( OArray*, double );
392 void     orIntArrayAppend( OArray*, int32_t );
393 #endif
394
395 OBlock*  orCopyBlock( OIndex, int skip, int deep );
396 OString* orCopyString( OIndex, int skip );
397 void     orCopy( OValue*, int part, int deep );
398 void     orCloneObject( const OContext* orig, OContext* clone );
399 int      orPick( const OValue* ser, int n, OValue* result );
400
401 int     orStringToInt( const char* start, const char* end, const char** it );
402 double  orStringToDec( const char* start, const char* end, const char** it );
403
404 OValue* orAppendValue( OBlock*, int type, int ind );
405 OValue* orAppendNone( OBlock* );
406 OValue* orAppendWord( OBlock* blk, int type, const char* name, int len );
407 OValue* orAppendPath( OBlock*, int type, OIndex blkN );
408 OValue* orAppendDecimal( OBlock*, double );
409 OValue* orAppendTuple( OBlock*, const uint8_t* bytes, int len );
410
411 void orArrayInit( OArray*, int elemSize, int elemCount );
412 void orArrayFree( OArray* );
413 void orArrayReserve( OArray*, int elemSize, int elemCount );
414 void orArrayErase( OArray*, int elemSize, int index, int count );
415
416 #ifdef OR_CONFIG_BYTECODE
417 void orCompileByteCodes( OBinary*, const OValue* );
418 OIndex orByteCodeBlock( const uint8_t** codep, OIndex* lenp );
419 const uint8_t* orRevaluateByteCodes( const uint8_t*, int valueCount, OBlock* );
420 #endif
421
422 OIndex orHold( int type, OIndex which );
423 OIndex orHoldIndex( OIndex );
424 void   orRelease( OIndex );
425
426 #ifdef __cplusplus
427 }
428 #endif
429
430
431 #define orSTRINGS       ((OString*) orEnv->strings.buf)
432 #define orBLOCKS        ((OBlock*) orEnv->blocks.buf)
433 #define orTOS           (orEnv->dataStack.values + orEnv->dataStack.used)
434
435 #define orSTRING(val)   (orSTRINGS + (val)->index)
436 #define orBLOCK(val)    (orBLOCKS + (val)->index)
437
438 #ifdef OR_CONFIG_NUMBER_ARRAYS
439 #define orDEC_ARRAYS        ((OArray*) orEnv->decArr.buf)
440 #define orINT_ARRAYS        ((OArray*) orEnv->intArr.buf)
441
442 #define orDEC_ARRAY(val)    (orDEC_ARRAYS + (val)->index)
443 #define orINT_ARRAY(val)    (orINT_ARRAYS + (val)->index)
444 #endif
445
446 #define orBlockN(ptr)   (ptr - orBLOCKS)
447 #define orStringN(ptr)  (ptr - orSTRINGS)
448 #define orBinaryN(ptr)  (ptr - orSTRINGS)
449
450 #define orBlockPtr(n)   (orBLOCKS + n)
451 #define orStringPtr(n)  (orSTRINGS + n)
452
453 #define orIs(val,t)     ((val)->type == t)
454
455 #define orType(val)     (val)->type
456 #define orAtom(val)     (val)->word.atom
457 #define orDatatype(val) (val)->index
458 #define orInt(val)      (val)->integer
459 #define orLogic(val)    (val)->integer
460 #define orDecimal(val)  (val)->num.decimal
461 #define orSeconds(val)  (val)->num.decimal
462 #define orTupleLen(val) (val)->argc
463
464 #define orIsWord(t)     ((t >= OT_WORD) && (t < OT_REFINEMENT))
465 #define orIsSeries(t)   ((t >= OT_COMPLEX) && (t < OT_SERIES))
466 #define orIsString(t)   ((t >= OT_STRING) && (t < OT_BINARY))
467 #define orIsBlock(t)    ((t >= OT_BLOCK) && (t < OT_SETPATH))
468 #define orIsNumber(t)   ((t == OT_INTEGER) || (t == OT_DECIMAL))
469
470 #define orIfTrue(val) \
471     ((orType(val) != OT_NONE) && \
472      ((orType(val) != OT_LOGIC) || (orLogic(val) != 0)))
473
474 #define orIfFalse(val) \
475     (orIs(val, OT_NONE) || (orIs(val, OT_LOGIC) && (orLogic(val) == 0)))
476
477 #define orRefAvail(n) \
478     (((OR_MAX_QHOLDS - 1) - orEnv->quickHoldsUsed) > n)
479
480 #define orRefAvailErr(n) \
481     if( ! orRefAvail(n) ) { \
482         orErrorT(OR_ERROR_INTERNAL, "Hold stack overflow"); \
483         return; }
484
485 #define orRefPush(type,index) \
486     orEnv->quickHolds[ orEnv->quickHoldsUsed ].dataType = type; \
487     orEnv->quickHolds[ orEnv->quickHoldsUsed ].which = index; \
488     ++orEnv->quickHoldsUsed
489
490 #define orRefPop(count)         orEnv->quickHoldsUsed -= count
491
492 #define orWordVal(wv,blk,val) \
493     blk = orBLOCKS + wv->word.context; \
494     val = blk->values + wv->word.index
495
496 #define orMakePath(n)           orMakeBlock(n)
497 #define orMakeBinary(n)         ((OBinary*) orMakeString(n))
498
499 #define orAppendInteger(b,v)    orAppendValue(b,OT_INTEGER,v)
500 #define orAppendLogic(b,v)      orAppendValue(b,OT_LOGIC,v)
501 #define orAppendChar(b,v)       orAppendValue(b,OT_CHAR,v)
502 #define orAppendString(b,v)     orAppendValue(b,OT_STRING,v)
503 #define orAppendFile(b,v)       orAppendValue(b,OT_FILE,v)
504 #define orAppendTag(b,v)        orAppendValue(b,OT_TAG,v)
505 #define orAppendBlock(b,v)      orAppendValue(b,OT_BLOCK,v)
506
507 #define orBitIsSet(array,n) (array[(n)>>3] & 1<<((n)&7))
508 #define orSetBit(array,n)   (array[(n)>>3] |= 1<<((n)&7))
509 #define orClrBit(array,n)   (array[(n)>>3] &= ~(1<<((n)&7)))
510
511 #ifdef __BIG_ENDIAN__
512 #define orSetTF(val,t)      *((uint32_t*) &(val)->type) = t << 24
513 #else
514 #define orSetTF(val,t)      *((uint32_t*) &(val)->type) = t
515 #endif
516
517 #define orSetSeries(val,w,idx) \
518     val->series.n  = w; \
519     val->series.it = idx
520
521 #define orSetWord(val,wb,vb,wrd,atm) \
522     val->word.wordBlk = wb; \
523     val->word.context = vb; \
524     val->word.index   = wrd; \
525     val->word.atom    = atm
526
527 #define orStrChars(str,val)     (str->charArray + val->series.it)
528 #define orSeriesLen(ser,val)    (ser->used - val->series.it)
529
530 #define orRefineSet(val)    ((val)->type == OT_LOGIC)
531
532 #define orCopyV(val,t)      *(val) = t
533
534 #define orNumberToInt(v) \
535     ((v->type == OT_DECIMAL) ? (int) v->num.decimal : v->integer)
536
537 #define orResult(t,v) \
538     orSetTF(a1, t); \
539     a1->index = v;
540
541 #define orResultCopy(v)     orCopyV(a1,v)
542
543 #define orResultSeries(t,w,idx) \
544     orSetTF(a1, t); \
545     orSetSeries(a1,w,idx)
546
547 #define orResultSTRING(i)   orResultSeries(OT_STRING,i,0)
548 #define orResultFILE(i)     orResultSeries(OT_FILE,i,0)
549 #define orResultBLOCK(i)    orResultSeries(OT_BLOCK,i,0)
550 #define orResultBINARY(i)   orResultSeries(OT_BINARY,i,0)
551 #define orResultNONE        orResult(OT_NONE,0)
552 #define orResultUNSET       orResult(OT_UNSET,0)
553 #define orResultTRUE        orResult(OT_LOGIC,OR_TRUE)
554 #define orResultFALSE       orResult(OT_LOGIC,OR_FALSE)
555
556 #define orResultDECIMAL(v) \
557     orSetTF(a1, OT_DECIMAL); \
558     a1->num.decimal = v
559
560 #define OR_NATIVE(func)     static void func( OValue* a1 )
561 #define OR_NATIVE_PUB(func) void func( OValue* a1 )
562
563 #define OR_CTERM_LEN        1
564
565 #define orTermCStr(s) \
566     if(s->used == s->avail) \
567         orArrayReserve(s,sizeof(char),s->used+1); \
568     s->charArray[s->used] = '\0'
569
570 #define orErrorThrown       orEnv->error
571 #define orErrorClear        orEnv->error = 0
572 #define orErrorType(ev)     (ev)->argc
573 #define orErrorIsType(t)    (orEnv->error->argc == t)
574
575 #define orHoldIsValid(h)    ((h) > OR_INVALID_HOLD)
576
577 #define orToByteRange(v)    ((v) < 0 ? 0 : (v) > 255 ? 255 : (v))
578
579 #endif  /* OVALUE_H */
Note: See TracBrowser for help on using the browser.