#ifndef _VAR_H #define _VAR_H #include "reg.h" #include "mem.h" /* Variables (or function/procedure) including symbol information are store in the heap The heap segment is a symbol table, too. The heap is the upper region of the data memory. */ /* +----------+ size -1 | data+n | | .. | | data | <- addr | length | | name[] | <- top ... +----------+ 0 */ typedef enum { MVAR = 'V', // numeric variable or array on the heap var x,y,z #if HAS_FUNC > 0 MVARLOC = 'v', // numeric variable or array on the stack var* x,y,z : func (a,b,c) { } #endif MCONST = 'C', // constant value MFUNC = 'F', // user defined function reference MPROC = 'P', // user defined procedure reference MSTRING = 'S', // string variable MEVENT = 'E', // user defined events, duplicate, but needed because events table need name string stolen from here! MANY = '*' // any pattern for heap look-up } var_type; #ifndef VARPADDING #define VARPADDING 1 #endif typedef struct __attribute__((packed)) { char name[MAXNAMELEN+1+HAS_LOCK+VARPADDING]; var_type type; index_t length; // data length, for proc length is code size, scalar=1, array > 1 number_t data; } var_t; #define var_s sizeof(var_t) // data as an array #define VARDATA(v,index) ((number_t*)&v->data)[index] #if HAS_LOCK>0 /* variable lock is stored at the end of the name field */ #define LOCKDATA(v) v->name[MAXNAMELEN+1] #endif #if HAS_FUNC > 0 #define VARLOCLEVEL(x) ((index_t)x&1) #define VARLOCINDEX(x) ((index_t)x>>1) // encode variable address: addr>=0 is heap, addr < -1 is stack #define VARADDRESS(var,addr) var->type==MVARLOC?-(VARLOCINDEX(var->data))-2:addr #endif /* Dual use: Allocates variable on heap or resolves address if exists already (and type and length is conforming) */ address_t Allocate(mem_t *M, reg_t *R, char *name, var_type type, index_t length, var_t **v); void HeapInit(); #endif