-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathvar.h
More file actions
517 lines (445 loc) · 9.68 KB
/
var.h
File metadata and controls
517 lines (445 loc) · 9.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
// This file is part of SmallBASIC
//
// SmallBASIC variant type
//
// This program is distributed under the terms of the GPL v2.0 or later
// Download the GNU Public License (GPL) from www.gnu.org
//
// Copyright(C) 2018 Chris Warren-Smith
#if !defined(_INC_VAR_T_H)
#define _INC_VAR_T_H
#include <stdint.h>
// https://en.wikipedia.org/wiki/Dependency_inversion_principle
typedef double var_num_t;
typedef long long int var_int_t;
#define MAXDIM 6
#define OS_INTSZ sizeof(var_int_t)
#define OS_REALSZ sizeof(var_num_t)
#ifdef V_INT
#undef V_INT
#endif
#ifdef V_ARRAY
#undef V_ARRAY
#endif
/*
* Variable - types
*/
#define V_INT 0 /**< variable type, 64bit integer @ingroup var */
#define V_NUM 1 /**< variable type, 64bit float (same as V_NUM) @ingroup var */
#define V_STR 2 /**< variable type, string @ingroup var */
#define V_ARRAY 3 /**< variable type, array of variables @ingroup var */
#define V_PTR 4 /**< variable type, pointer to UDF or label @ingroup var */
#define V_MAP 5 /**< variable type, associative array @ingroup var */
#define V_REF 6 /**< variable type, reference another var @ingroup var */
#define V_FUNC 7 /**< variable type, object method @ingroup var */
#define V_NIL 8 /**< variable type, null value @ingroup var */
#if defined(__cplusplus)
extern "C" {
#endif
struct var_s;
typedef struct {
// the parameter
struct var_s *var_p;
// whether the parameter can be used by reference
uint8_t byref;
} slib_par_t;
// signature for module callback/virtual functions
typedef int (*callback) (struct var_s *self, int param_count, slib_par_t *params, struct var_s *retval);
// signature for internal v_funcs
typedef void (*method) (struct var_s *self, struct var_s *retval);
typedef struct var_s {
union {
// numeric
var_num_t n;
// integer
var_int_t i;
// pointer to sub/func variable
struct {
// address pointer
uint32_t p;
// return var ID
uint32_t v;
} ap;
// associative array/map
struct {
// pointer to the map structure
void *map;
uint32_t count;
uint32_t size;
uint32_t id;
uint32_t lib_id;
uint32_t cls_id;
} m;
// reference variable
struct var_s *ref;
// object method
struct {
method cb;
callback mcb;
uint32_t id;
} fn;
// generic ptr (string)
struct {
char *ptr;
uint32_t length;
uint8_t owner;
} p;
// array
struct {
struct var_s *data;
// the number of elements
uint32_t size;
// the number of available element slots
uint32_t capacity;
// upper and lower bounds
int32_t ubound[MAXDIM];
int32_t lbound[MAXDIM];
} a;
// next item in the free-list
struct var_s *pool_next;
} v;
// number of dimensions
uint8_t maxdim;
// variables type
uint8_t type;
// non-zero if constant
uint8_t const_flag;
// whether held in pooled memory
uint8_t pooled;
} var_t;
typedef var_t *var_p_t;
/**
* @ingroup var
*
* creates a new variable
*
* @return a newly created var_t object
*/
var_t *v_new(void);
/**
* @ingroup var
*
* creates a new variable array
*
* @return a newly created var_t array of the given size
*/
void v_new_array(var_t *var, uint32_t size);
/**
* @ingroup var
*
* frees memory associated with the given array
*/
void v_array_free(var_t *var);
/**
* @ingroup var
*
* initialise the variable as a string of the given length
*/
void v_init_str(var_t *var, int length);
/**
* @ingroup var
*
* takes ownership of the given allocated string
*/
void v_move_str(var_t *var, char *str);
/**
* @ingroup var
*
* returns true if the value is not 0/NULL
*
* @param v the variable
* @return true if the value is not 0/NULL
*/
int v_is_nonzero(var_t *v);
/**
* @ingroup var
*
* compares two variables
*
* @param a the left-side variable
* @param b the right-side variable
* @return 0 if a = b, <0 if a < b, >0 if a > b
*/
int v_compare(var_t *a, var_t *b);
/**
* @ingroup var
*
* calculates the result type of the addition of two variables
*
* @param a the left-side variable
* @param b the right-side variable
* @return the type of the new variable
*/
int v_addtype(var_t *a, var_t *b);
/**
* @ingroup var
*
* adds two variables
*
* @param result the result
* @param a the left-side variable
* @param b the right-side variable
*/
void v_add(var_t *result, var_t *a, var_t *b);
/**
* @ingroup var
*
* assigning: dest = src
*
* @param dest the destination-var
* @param src the source-var
*/
void v_set(var_t *dest, const var_t *src);
/**
* @ingroup var
*
* assigning: dest = src
*
* @param dest the destination-var
* @param src the source-var
*/
void v_move(var_t *dest, const var_t *src);
/**
* @ingroup var
*
* increase the value of variable a by b
* (similar to v_add())
*
* @param a is the variable
* @param b is the increment
*/
void v_inc(var_t *a, var_t *b);
/**
* @ingroup var
*
* returns the sign of a variable
*
* @param x the variable
* @return the sign
*/
int v_sign(var_t *x);
/**
* @ingroup var
*
* create a string variable (with value str)
*
* @param v is the variable
* @param src is the string
*/
void v_createstr(var_t *v, const char *src);
/**
* @ingroup var
*
* print variable as string
*
* @param arg is the variable
*/
char *v_str(var_t *arg);
/**
* @ingroup var
*
* convert variable to string
*
* @param arg is the variable
*/
void v_tostr(var_t *arg);
/**
* @ingroup var
*
* creates a new variable which is a clone of 'source'.
*
* @param source is the source
* @return a newly created var_t object, clone of 'source'
*/
var_t *v_clone(const var_t *source);
/**
* @ingroup var
*
* resizes an array-variable to 1-dimension array of 'size' elements
*
* @param v the variable
* @param size the number of the elements
*/
void v_resize_array(var_t *v, uint32_t size);
/**
* @ingroup var
*
* convert variable v to a RxC matrix
*
* @param v the variable
* @param r the number of the rows
* @param c the number of the columns
*/
void v_tomatrix(var_t *v, int r, int c);
/**
* @ingroup var
*
* converts the variable v to an array of R elements.
* R can be zero for zero-length arrays
*
* @param v the variable
* @param r the number of the elements
*/
void v_toarray1(var_t *v, uint32_t r);
/**
* @ingroup var
*
* returns true if the 'v' is empty (see EMPTY())
*
* @param v the variable
* @return non-zero if v is not 'empty'
*/
int v_isempty(var_t *v);
/**
* @ingroup var
*
* returns the length of the variable (see LEN())
*
* @param v the variable
* @return the length of the variable
*/
int v_length(var_t *v);
/**
* @ingroup var
*
* sets a string value to variable 'var'
*
* @param var is the variable
* @param string is the string
*/
void v_setstr(var_t *var, const char *string);
/**
* @ingroup var
*
* sets a string value to variable 'var' to the given length
*
* @param var is the variable
* @param string is the string
*/
void v_setstrn(var_t *var, const char *string, int len);
/**
* @ingroup var
*
* concate string to variable 'var'
*
* @param var is the variable
* @param string is the string
*/
void v_strcat(var_t *var, const char *string);
/**
* @ingroup var
*
* sets a real-number value to variable 'var'
*
* @param var is the variable
* @param number is the number
*/
void v_setreal(var_t *var, var_num_t number);
/**
* @ingroup var
*
* sets an integer value to variable 'var'
*
* @param var is the variable
* @param integer is the integer
*/
void v_setint(var_t *var, var_int_t integer);
/**
* @ingroup var
*
* makes 'var' an empty string variable
*
* @param var is the variable
*/
void v_zerostr(var_t *var);
/**
* @ingroup var
*
* assign value 'str' to var. the final type of the var will be decided
* on that function (numeric if the str is a numeric-constant string or string)
*
* @note used by INPUT to convert the variables
*
* @param str is the string
* @param var is the variable
*/
void v_input2var(const char *str, var_t *var);
/**
*< returns the var_t pointer of the element i
* on the array x. i is a zero-based, one dim, index.
* @ingroup var
*/
#define v_elem(var, i) &((var)->v.a.data[i])
/**
* < the number of the elements of the array (x)
* @ingroup var
*/
#define v_asize(x) ((x)->v.a.size)
/**
* < the number of array dimensions (x)
* @ingroup var
*/
#define v_maxdim(x) ((x)->maxdim)
/**
* < the array lower bound of the given dimension (x)
* @ingroup var
*/
#define v_lbound(x, i) ((x)->v.a.lbound[i])
/**
* < the array upper bound of the given dimension (x)
* @ingroup var
*/
#define v_ubound(x, i) ((x)->v.a.ubound[i])
/**
* < the array data
* @ingroup var
*/
#define v_data(x) ((x)->v.a.data)
/**
* < the array capacity
* @ingroup var
*/
#define v_capacity(x) ((x)->v.a.capacity)
/**
* @ingroup var
*
* returns the string-pointer of variable v
*
* @param v is the variable
* @return the pointer of the string
*/
char *v_getstr(var_t *v);
/**
* @ingroup var
*
* returns the length of the var string
*
* @param v is the variable
* @return the string length
*/
int v_strlen(const var_t *v);
/**
* @ingroup var
*
* returns whether the variable is of the given type
*
* @param v is the variable
* @return whether the variable is of the given type
*/
#define v_is_type(v, t) (v != NULL && v->type == t)
/**
* @ingroup var
*
* setup a method on the map using the given name
*/
void v_create_func(var_p_t map, const char *name, method cb);
/**
* @ingroup var
*
* creates a callback method
*/
void v_create_callback(var_p_t map, const char *name, callback cb);
#if defined(__cplusplus)
}
#endif
#endif