added gracefull shutdown
[mTask.git] / client / interpret.c
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 #include "mTaskSymbols.h"
5 #include "interpret.h"
6 #include "interface.h"
7 #include "task.h"
8 #include "sds.h"
9
10 #ifdef STM
11 #define trace(op, ...) {};
12 #else
13 #define trace(op, ...) {};
14 //#define trace(op, ...) printf("pc: %d, sp: %d, op: " op "\n", pc, sp, ##__VA_ARGS__);
15 #endif
16
17 #define f16(p) program[pc]*265+program[pc+1]
18
19 uint16_t stack[STACKSIZE] = {0};
20
21 void run_task(struct task *t)
22 {
23 uint8_t *program = t->bc;
24 int plen = t->tasklength;
25 int pc = 0;
26 int sp = 0;
27 debug("Running task with length: %d", plen);
28 while(pc < plen){
29 switch(program[pc++]){
30 case BCNOP: trace("nop");
31 break;
32 case BCLAB: trace("label: 0x%02x!!!!!!", program[pc]);
33 pc++;
34 break;
35 case BCPUSH: trace("push %d", program[pc]*265+program[pc+1]);
36 switch(program[pc++]){
37 //Long
38 case 'l':
39 //Int
40 case 'i':
41 stack[sp++] = f16(pc);
42 pc+=2;
43 break;
44 case 'b': //Bool
45 case 'c': //Character
46 case 'B': //Button
47 case 'L': //UserLED
48 stack[sp++] = program[pc++];
49 break;
50 }
51 break;
52 case BCPOP: trace("pop");
53 sp--;
54 break;
55 case BCSDSSTORE: trace("sds store: %d", f16(pc));
56 sds_store(f16(pc), stack[--sp]);
57 pc+=2;
58 break;
59 case BCSDSFETCH: trace("sds fetch: %d", f16(pc));
60 stack[sp++] = sds_fetch(f16(pc));
61 pc+=2;
62 break;
63 case BCSDSPUBLISH: trace("sds publish %d", f16(pc));
64 sds_publish(f16(pc));
65 pc+=2;
66 break;
67 case BCNOT: trace("not");
68 stack[sp] = stack[sp] > 0 ? 0 : 1;
69 break;
70 case BCADD: trace("add");
71 stack[sp-2] = stack[sp-2] + stack[sp-1];
72 sp -= 1;
73 break;
74 case BCSUB: trace("sub");
75 stack[sp-2] = stack[sp-2] - stack[sp-1];
76 sp -= 1;
77 break;
78 case BCMUL: trace("mul");
79 stack[sp-2] = stack[sp-2] * stack[sp-1];
80 sp -= 1;
81 break;
82 case BCDIV: trace("div");
83 stack[sp-2] = stack[sp-2] / stack[sp-1];
84 sp -= 1;
85 break;
86 case BCAND: trace("and");
87 stack[sp-2] = stack[sp-2] && stack[sp-1];
88 sp -= 1;
89 break;
90 case BCOR: trace("or");
91 stack[sp-2] = stack[sp-2] || stack[sp-1];
92 sp -= 1;
93 break;
94 case BCEQ: trace("eq");
95 stack[sp-2] = stack[sp-2] == stack[sp-1];
96 sp -= 1;
97 break;
98 case BCNEQ: trace("neq");
99 stack[sp-2] = stack[sp-2] != stack[sp-1];
100 sp -= 1;
101 break;
102 case BCLES: trace("les");
103 stack[sp-2] = stack[sp-2] < stack[sp-1];
104 sp -= 1;
105 break;
106 case BCGRE: trace("gre");
107 stack[sp-2] = stack[sp-2] > stack[sp-1];
108 sp -= 1;
109 break;
110 case BCLEQ: trace("leq");
111 stack[sp-2] = stack[sp-2] <= stack[sp-1];
112 sp -= 1;
113 break;
114 case BCGEQ: trace("geq");
115 stack[sp-2] = stack[sp-2] >= stack[sp-1];
116 sp -= 1;
117 break;
118 case BCJMP: trace("jmp to %d", program[pc]);
119 pc = program[pc]-1;
120 break;
121 case BCJMPT: trace("jmpt to %d", program[pc]);
122 pc = stack[--sp] ? program[pc]-1 : pc+1;
123 break;
124 case BCJMPF: trace("jmpf(%d) to %d", stack[sp-1], program[pc]);
125 pc = stack[--sp] ? pc+1 : program[pc]-1;
126 break;
127 case BCSERIALAVAIL: trace("SerialAvailable()");
128 break;
129 case BCSERIALPRINT: trace("SerialPrint()");
130 break;
131 case BCSERIALPRINTLN: trace("SerialPrintln()");
132 break;
133 case BCSERIALREAD: trace("SerialRead()");
134 break;
135 case BCSERIALPARSEINT: trace("SerialParseInt()");
136 break;
137 #if HAVEAIO == 1
138 case BCANALOGREAD: trace("AnalogRead(%d)", program[pc]);
139 stack[sp++] = read_apin(program[pc++]);
140 break;
141 case BCANALOGWRITE: trace("AnalogWrite(%d)", program[pc]);
142 write_apin(program[pc++], stack[sp-1]);
143 sp--;
144 break;
145 #endif
146 #if HAVEDIO == 1
147 case BCDIGITALREAD: trace("DigitalRead(%d)", program[pc]);
148 stack[sp++] = read_dpin(program[pc++]);
149 break;
150 case BCDIGITALWRITE: trace("DigitalWrite(%d)", program[pc]);
151 write_dpin(program[pc++], stack[sp-1]);
152 sp--;
153 break;
154 #endif
155 #if HAVELED == 1
156 case BCLEDON: trace("LedOn(%d)", program[pc]);
157 led_on(stack[sp-1]);
158 sp--;
159 break;
160 case BCLEDOFF: trace("LedOn(%d)", program[pc]);
161 led_off(stack[sp-1]);
162 sp--;
163 break;
164 #endif
165 case BCRETURN: trace("Return");
166 debug("Task returned");
167 task_delete(t->taskid);
168 return;
169 default:
170 trace("unrecognized");
171 die("Unrecognized command: %d", program[pc-1]);
172 }
173 }
174 debug("Task terminated");
175 }