Add a line to KNOWN_BUGS about `let' inconsistently forcing values.
[proto.git] / src / kernel / proto.h
blob6a48ab17894652f64418245f3986bbcb299f9032
1 /* ProtoKernel virtual machine
2 Copyright (C) 2005-2008, Jonathan Bachrach, Jacob Beal, and contributors
3 listed in the AUTHORS file in the MIT Proto distribution's top directory.
5 This file is part of MIT Proto, and is distributed under the terms of
6 the GNU General Public License, with a linking exception, as described
7 in the file LICENSE in the MIT Proto distribution's top directory. */
9 // Note: to maintain compatibility with embedded devices, functions of
10 // no arguments must be declared function(void), not function()
12 #ifndef __PROTO__
13 #define __PROTO__
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
19 #ifndef MIN
20 #define MIN(x,y) (((x)<(y))?(x):(y))
21 #define MAX(x,y) (((x)>(y))?(x):(y))
22 #endif
24 #include <string.h>
25 #include <math.h>
26 #include <stdint.h>
28 #ifndef INFINITY
29 #define INFINITY HUGE_VAL
30 #endif
33 //Using math.h will give us a proper platform dependent definition of infinity
34 //anyway. If it doesn't, it should be dealt in platform.h file.
36 #ifndef INFINITY
37 #ifdef WIN32
38 #define INFINITY (infinityf())
39 #else
40 // this is probably frowned upon
41 #define INFINITY HUGE_VAL
42 #endif
43 #endif
46 #ifndef FLODEF
47 #define FLODEF
48 typedef float flo;
49 #endif
51 typedef int BOOL;
52 typedef float FLO;
54 // typedef uint8_t int;
56 typedef FLO TICKS;
57 typedef double TIME;
58 typedef int32_t MSECS;
59 typedef struct data_rec DATA;
60 typedef struct vec_val_rec VEC_VAL;
61 // typedef struct tup_val_rec TUP_VAL; // not used
62 typedef FLO NUM_VAL;
63 typedef uint16_t FUN_VAL;
64 typedef uint32_t BIN_VAL;
66 #define TRUE 1
67 #define FALSE 0
69 #include "proto_opcodes.h"
70 #include "proto_platform.h"
72 typedef enum {
73 NUM_TAG,
74 VEC_TAG,
75 FUN_TAG,
76 } TAG;
78 typedef union {
79 NUM_VAL n;
80 VEC_VAL *v;
81 FUN_VAL f;
82 BIN_VAL b;
83 } DATA_VAL;
85 struct data_rec {
86 uint8_t is_dead;
87 uint8_t tag;
88 DATA_VAL val;
91 #ifdef IS_COMPRESSED_COM_DATA
92 #ifndef __BIG_ENDIAN__ // normally, little endian
93 typedef struct {
94 uint8_t is_dead:1, tag:2, extra:5;
95 union {
96 uint16_t n __attribute__ ((__packed__));
97 } val;
98 } COM_DATA;
99 #else
100 typedef struct {
101 uint8_t extra:5, tag:2, is_dead:1;
102 union {
103 uint16_t n __attribute__ ((__packed__));
104 } val;
105 } COM_DATA;
106 #endif
107 #else
108 typedef struct data_rec COM_DATA;
109 #endif
111 struct vec_val_rec {
112 int n;
113 int cap;
114 DATA elts[];
117 #define R_LED 0
118 #define G_LED 1
119 #define B_LED 2
120 #define ACT_ANGLE 3
122 #define N_ACTUATORS 4
124 #define LIGHT 0
125 #define SOUND 1
126 #define TEMPERATURE 2
127 #define USER3 3 // -> Conductivity is out:
128 #define SEN_ANGLE 4 // (No ADC, no buffer needed).
130 #define N_SENSORS 5
132 #define N_FOLDS 8
134 #define RADIO_EXPORT 0
136 #define BAD_VERSION 255
138 typedef struct {
139 uint16_t id;
140 uint8_t timeout;
141 flo x, y, z;
142 TICKS stamp;
143 TIME time;
144 DATA *imports;
145 } NBR;
147 typedef struct {
148 uint8_t is_exec;
149 uint8_t is_open;
150 DATA data;
151 } STATE;
153 typedef struct {
154 uint8_t version;
155 uint8_t is_complete;
156 uint8_t bytes[MAX_SCRIPT_LEN];
157 uint16_t len;
158 } SCRIPT;
160 typedef struct MACHINE {
161 int16_t id;
162 uint8_t timeout;
163 uint8_t cur_script;
164 uint8_t *script;
165 SCRIPT scripts[MAX_SCRIPTS];
166 uint8_t pkt_tracker[MAX_SCRIPT_LEN / MAX_SCRIPT_PKT + 1];
167 uint8_t pkt_listner[MAX_SCRIPT_LEN / MAX_SCRIPT_PKT + 1];
168 BOOL is_digest;
169 uint8_t radio_range;
170 uint8_t radio_range_sqr;
171 NUM_VAL x;
172 NUM_VAL y;
173 NUM_VAL z;
174 NUM_VAL nbr_x;
175 NUM_VAL nbr_y;
176 NUM_VAL nbr_z;
177 NUM_VAL nbr_lag;
178 NUM_VAL actuators[N_ACTUATORS];
179 NUM_VAL sensors[N_SENSORS];
180 BOOL is_folding[N_FOLDS];
181 int n_hood_vals; // number of neighborhood values
182 uint16_t n_hood; // number of neighbors
183 COM_DATA *buf;
184 COM_DATA *next_buf;
185 NBR hood_data[MAX_HOOD];
186 NBR *hood[MAX_HOOD];
187 DATA *hood_exports;
188 TIME last_time;
189 TIME time;
190 TIME period;
191 TIME desired_period;
192 TICKS ticks;
193 TICKS send_ticks;
194 // EVAL MACHINERY
195 DATA res;
196 uint16_t n_state;
197 uint16_t n_globals;
198 uint16_t max_globals;
199 FUN_VAL exec;
200 STATE *state;
201 DATA *globals;
202 uint16_t n_stack;
203 DATA *stack;
204 uint16_t n_env;
205 DATA *env;
206 uint16_t pc;
207 DATA *sp;
208 DATA *ep;
209 uint8_t *membuf;
210 uint16_t buflen;
211 uint16_t memlen;
212 uint16_t memptr;
213 uint16_t saved_memptr;
214 } MACHINE;
216 extern MACHINE *new_machine
217 (MACHINE *m, int id, int16_t x, int16_t y, int16_t z,
218 TIME desired_period, uint8_t *script, uint16_t script_len);
220 extern void open_machine (VOID);
221 extern void close_machine (VOID);
222 extern void export_machine (VOID);
223 extern void export_script (VOID);
224 extern void radio_receive_export
225 (uint16_t src_id, uint8_t version, uint8_t timeout, flo x, flo y, flo z, uint8_t n, COM_DATA *buf);
226 extern int radio_send_export (uint8_t version, uint8_t timeout, uint8_t n, uint8_t len, COM_DATA *buf);
227 extern void radio_receive_script_pkt (uint8_t version, uint16_t n, uint8_t pkt_num, uint8_t *script);
228 extern int radio_send_script_pkt (uint8_t version, uint16_t n, uint8_t pkt_num, uint8_t *script);
229 extern void script_pkt_callback(uint8_t pkt_num);
230 extern int serial_send_debug (uint8_t version, int len, uint8_t msgval);
231 extern void radio_receive_digest(uint8_t version, uint16_t script_len, uint8_t *digest);
232 extern int radio_send_digest (uint8_t version, uint16_t script_len, uint8_t *digest);
233 extern int script_export_needed(VOID);
234 extern uint16_t machine_mem_size (MACHINE *m);
236 extern MACHINE *machine;
238 // extern void post(char* string, ...);
240 extern void reinitHardware(void); // required for protobo
242 extern void mov (VEC_VAL *val);
243 extern void flex (NUM_VAL val);
244 extern void set_probe (DATA*, uint8_t);
245 extern void set_dt(NUM_VAL val);
247 extern NUM_VAL read_radio_range (VOID);
248 extern NUM_VAL read_bearing (VOID);
249 extern NUM_VAL read_speed (VOID);
251 extern void platform_operation(uint8_t op);
253 extern int is_throttling;
254 extern int depth;
256 // #define IS_TRACE
258 static inline DATA* init_num (DATA* x, NUM_VAL n) {
259 x->tag = NUM_TAG;
260 x->is_dead = FALSE;
261 x->val.n = n;
262 return x;
265 static inline NUM_VAL NUM_VAL_GET(DATA_VAL *x) { return x->n; }
266 static inline NUM_VAL NUM_VAL_SET(DATA_VAL *x, NUM_VAL n) { return x->n = n; }
267 static inline VEC_VAL *VEC_VAL_GET(DATA_VAL *x) { return x->v; }
268 static inline VEC_VAL *VEC_VAL_SET(DATA_VAL *x, VEC_VAL *v) { return x->v = v; }
269 static inline NUM_VAL NUM_GET(DATA *x) { return x->val.n; }
270 static inline NUM_VAL NUM_SET(DATA *x, NUM_VAL n) { x->is_dead = 0; x->tag = NUM_TAG; return x->val.n = n; }
271 static inline FUN_VAL FUN_GET(DATA *x) { return x->val.f; }
272 static inline FUN_VAL FUN_SET(DATA *x, FUN_VAL f) { x->is_dead = 0; x->tag = FUN_TAG; return x->val.f = f; }
273 static inline VEC_VAL *VEC_GET(DATA *x) { return x->val.v; }
274 static inline VEC_VAL *VEC_SET(DATA *x, VEC_VAL *v) { x->is_dead = 0; x->tag = VEC_TAG; return x->val.v = v; }
275 static inline DATA* DATA_SET(DATA *d, DATA *s) {
276 memcpy(d, s, sizeof(DATA));
277 return d;
280 extern DATA *new_tup(int n, DATA *f);
282 extern void exec_machine (TICKS ticks, TIME time);
284 #define Null ((void*)0)
286 extern void uerror(char* dstring, ...);
287 extern void POST(char* string, ...);
288 extern void post_data_to (char *str, DATA *d);
289 extern void post_data (DATA *d);
291 extern void MEM_GROW (MACHINE *m);
293 #define PROTO_VERSION 402
295 #ifdef __cplusplus
297 #endif
299 #endif