-
Notifications
You must be signed in to change notification settings - Fork 15
/
tinyscript.h
126 lines (104 loc) · 3.51 KB
/
tinyscript.h
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
#ifndef TINYSCRIPT_H
#define TINYSCRIPT_H
#include <stdint.h>
// language configuration options
// define VERBOSE_ERRORS to get nicer error messages at a small cost in space
// costs about 500 bytes on the Propeller
#define VERBOSE_ERRORS
// define ARRAY_SUPPORT to get support for integer arrays
// costs about 1K on the Propeller
#define ARRAY_SUPPORT
#ifdef __propeller__
// define SMALL_PTRS to use 16 bits for pointers
// useful for machines with <= 64KB of RAM
#define SMALL_PTRS
#endif
// Comment this out if you have provided a function to
// check whether a running script should stop. This
// function should return non-zero when if the script
// should stop, 0 if not.
#define TinyScript_Stop() (0)
// errors
// all the ParseXXX functions return 0 on success, a negative
// error code otherwise
enum {
TS_ERR_OK = 0,
TS_ERR_NOMEM = -1,
TS_ERR_SYNTAX = -2,
TS_ERR_UNKNOWN_SYM = -3,
TS_ERR_BADARGS = -4,
TS_ERR_TOOMANYARGS = -5,
TS_ERR_OUTOFBOUNDS = -6,
TS_ERR_STOPPED = -7,
TS_ERR_OK_ELSE = 1, // special internal condition
};
// we use this a lot
typedef char Byte;
//our target is machines with < 64KB of memory, so 16 bit pointers
//will do
typedef Byte *Ptr;
// strings are represented as (length,ptr) pairs
// this is done so that we can re-use variable names and similar
// substrings directly from the script text, without having
// to insert 0 into them
typedef struct {
#ifdef SMALL_PTRS
uint16_t len_;
uint16_t ptr_;
#else
unsigned len_;
const char *ptr_;
#endif
} String;
// val has to be able to hold a pointer
typedef intptr_t Val;
static inline unsigned StringGetLen(String s) { return (unsigned)s.len_; }
static inline const char *StringGetPtr(String s) { return (const char *)(intptr_t)s.ptr_; }
#ifdef SMALL_PTRS
static inline void StringSetLen(String *s, unsigned len) { s->len_ = (uint16_t)len; }
static inline void StringSetPtr(String *s, const char *ptr) { s->ptr_ = (uint16_t)(intptr_t)ptr; }
#else
static inline void StringSetLen(String *s, unsigned len) { s->len_ = len; }
static inline void StringSetPtr(String *s, const char *ptr) { s->ptr_ = ptr; }
#endif
// symbols can take the following forms:
#define INT 0x0 // integer
#define STRING 0x1 // string
#define OPERATOR 0x2 // operator; precedence in high 8 bits
#define ARG 0x3 // argument; value is offset on stack
#ifdef ARRAY_SUPPORT
#define ARRAY 0x4 // integer array
#endif
#define BUILTIN 'B' // builtin: number of operands in high 8 bits
#define USRFUNC 'f' // user defined a procedure; number of operands in high 8 bits
#define TOK_BINOP 'o'
#define BINOP(x) (((x)<<8)+TOK_BINOP)
#define CFUNC(x) (((x)<<8)+BUILTIN)
typedef struct symbol {
String name;
int type; // symbol type
Val value; // symbol value, or string ptr
} Sym;
#define MAX_BUILTIN_PARAMS 4
typedef Val (*Cfunc)(Val, Val, Val, Val);
typedef Val (*Opfunc)(Val, Val);
// structure to describe a user function
typedef struct ufunc {
String body; // pointer to the body of the function
int nargs; // number of args
// names of arguments
String argName[MAX_BUILTIN_PARAMS];
} UserFunc;
//
// global interface
//
int TinyScript_Init(void *mem, int mem_size);
int TinyScript_Define(const char *name, int toktype, Val value);
int TinyScript_Run(const char *s, int saveStrings, int topLevel);
// provided by our caller
extern void outchar(int c);
// if an external function is provided, comment out the define, and uncomment the declaration
#ifndef TinyScript_Stop
extern int TinyScript_Stop();
#endif
#endif