plxvm/src/var.h

76 lines
1.9 KiB
C

#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