User | Revision | Line number | New contents of line |
okini3939 |
0:684b6fdf080c
|
1
|
/** @file
|
okini3939 |
0:684b6fdf080c
|
2
|
* @brief Instruction List interpreter
|
okini3939 |
0:684b6fdf080c
|
3
|
*/
|
okini3939 |
0:684b6fdf080c
|
4
|
|
okini3939 |
0:684b6fdf080c
|
5
|
#include "mbed.h"
|
okini3939 |
0:684b6fdf080c
|
6
|
#include "ILinterpreter.h"
|
okini3939 |
0:684b6fdf080c
|
7
|
|
okini3939 |
0:684b6fdf080c
|
8
|
#undef DEBUG
|
okini3939 |
0:684b6fdf080c
|
9
|
|
okini3939 |
0:684b6fdf080c
|
10
|
struct MNE_str {
|
okini3939 |
0:684b6fdf080c
|
11
|
eMNEMONIC mne;
|
okini3939 |
0:684b6fdf080c
|
12
|
char str[5];
|
okini3939 |
0:684b6fdf080c
|
13
|
};
|
okini3939 |
0:684b6fdf080c
|
14
|
|
okini3939 |
0:684b6fdf080c
|
15
|
#define IL_MNE_NUM 22
|
okini3939 |
1:f8c5afc27878
|
16
|
static const struct MNE_str mne_str[IL_MNE_NUM] = {
|
okini3939 |
0:684b6fdf080c
|
17
|
{MNE_DEF, "DEF"},
|
okini3939 |
0:684b6fdf080c
|
18
|
{MNE_LD, "LD"}, {MNE_LDI, "LDI"}, {MNE_LDP, "LDP"}, {MNE_LDF, "LDF"},
|
okini3939 |
0:684b6fdf080c
|
19
|
{MNE_OR, "OR"}, {MNE_ORI, "ORI"}, {MNE_ORP, "ORP"}, {MNE_ORF, "ORF"},
|
okini3939 |
0:684b6fdf080c
|
20
|
{MNE_AND, "AND"}, {MNE_ANI, "ANI"}, {MNE_ANDP, "ANDP"}, {MNE_ANDF, "ANDF"},
|
okini3939 |
0:684b6fdf080c
|
21
|
{MNE_ORB, "ORB"}, {MNE_ANB, "ANB"}, {MNE_INV, "INV"},
|
okini3939 |
0:684b6fdf080c
|
22
|
{MNE_MPS, "MPS"}, {MNE_MRD, "MRD"}, {MNE_MPP, "MPP"},
|
okini3939 |
0:684b6fdf080c
|
23
|
{MNE_OUT, "OUT"}, {MNE_SET, "SET"}, {MNE_RST, "RST"},
|
okini3939 |
0:684b6fdf080c
|
24
|
};
|
okini3939 |
0:684b6fdf080c
|
25
|
|
okini3939 |
0:684b6fdf080c
|
26
|
struct EXP_str {
|
okini3939 |
0:684b6fdf080c
|
27
|
eEXPRESSION exp;
|
okini3939 |
0:684b6fdf080c
|
28
|
char str[3];
|
okini3939 |
0:684b6fdf080c
|
29
|
};
|
okini3939 |
0:684b6fdf080c
|
30
|
|
okini3939 |
0:684b6fdf080c
|
31
|
#define IL_EXP_NUM 10
|
okini3939 |
1:f8c5afc27878
|
32
|
static const struct EXP_str exp_str[IL_EXP_NUM] = {
|
okini3939 |
0:684b6fdf080c
|
33
|
{EXP_EQ, "=="}, {EXP_EQ, "="}, {EXP_NE, "!="}, {EXP_NE, "<>"},
|
okini3939 |
0:684b6fdf080c
|
34
|
{EXP_LT, "<="}, {EXP_LE, "<"}, {EXP_GT, ">"}, {EXP_GE, ">="},
|
okini3939 |
0:684b6fdf080c
|
35
|
{EXP_MOD, "%"}, {EXP_NMOD, "!%"},
|
okini3939 |
0:684b6fdf080c
|
36
|
};
|
okini3939 |
0:684b6fdf080c
|
37
|
|
okini3939 |
0:684b6fdf080c
|
38
|
|
okini3939 |
1:f8c5afc27878
|
39
|
ILinterpreter::ILinterpreter () {
|
okini3939 |
0:684b6fdf080c
|
40
|
il_count = 0;
|
okini3939 |
0:684b6fdf080c
|
41
|
memset(&inout, 0, sizeof(inout));
|
okini3939 |
0:684b6fdf080c
|
42
|
inout.sec = time(NULL) + (60 * 60 * 9);
|
okini3939 |
0:684b6fdf080c
|
43
|
inout_old = inout;
|
okini3939 |
0:684b6fdf080c
|
44
|
cb_input = NULL;
|
okini3939 |
0:684b6fdf080c
|
45
|
cb_output = NULL;
|
okini3939 |
0:684b6fdf080c
|
46
|
}
|
okini3939 |
0:684b6fdf080c
|
47
|
|
okini3939 |
0:684b6fdf080c
|
48
|
// input relay, expression
|
okini3939 |
0:684b6fdf080c
|
49
|
int ILinterpreter::input (tInOut *io, int i, int old) {
|
okini3939 |
0:684b6fdf080c
|
50
|
int keynum;
|
okini3939 |
0:684b6fdf080c
|
51
|
float value, check;
|
okini3939 |
0:684b6fdf080c
|
52
|
struct tm *tim;
|
okini3939 |
0:684b6fdf080c
|
53
|
|
okini3939 |
0:684b6fdf080c
|
54
|
tim = localtime(&io->sec);
|
okini3939 |
0:684b6fdf080c
|
55
|
keynum = il[i].keynum;
|
okini3939 |
0:684b6fdf080c
|
56
|
// right value
|
okini3939 |
0:684b6fdf080c
|
57
|
check = il[i].value;
|
okini3939 |
0:684b6fdf080c
|
58
|
|
okini3939 |
0:684b6fdf080c
|
59
|
// left value
|
okini3939 |
0:684b6fdf080c
|
60
|
value = 0;
|
okini3939 |
0:684b6fdf080c
|
61
|
switch (il[i].key) {
|
okini3939 |
0:684b6fdf080c
|
62
|
|
okini3939 |
0:684b6fdf080c
|
63
|
case 'y':
|
okini3939 |
0:684b6fdf080c
|
64
|
value = tim->tm_year + 1900;
|
okini3939 |
0:684b6fdf080c
|
65
|
break;
|
okini3939 |
0:684b6fdf080c
|
66
|
case 'm':
|
okini3939 |
0:684b6fdf080c
|
67
|
value = tim->tm_mon;
|
okini3939 |
0:684b6fdf080c
|
68
|
break;
|
okini3939 |
0:684b6fdf080c
|
69
|
case 'd':
|
okini3939 |
0:684b6fdf080c
|
70
|
value = tim->tm_mday;
|
okini3939 |
0:684b6fdf080c
|
71
|
break;
|
okini3939 |
0:684b6fdf080c
|
72
|
case 'h':
|
okini3939 |
0:684b6fdf080c
|
73
|
value = tim->tm_hour;
|
okini3939 |
0:684b6fdf080c
|
74
|
break;
|
okini3939 |
0:684b6fdf080c
|
75
|
case 'i':
|
okini3939 |
0:684b6fdf080c
|
76
|
value = tim->tm_min;
|
okini3939 |
0:684b6fdf080c
|
77
|
break;
|
okini3939 |
0:684b6fdf080c
|
78
|
case 's':
|
okini3939 |
0:684b6fdf080c
|
79
|
value = tim->tm_sec;
|
okini3939 |
0:684b6fdf080c
|
80
|
break;
|
okini3939 |
0:684b6fdf080c
|
81
|
|
okini3939 |
0:684b6fdf080c
|
82
|
case '0':
|
okini3939 |
0:684b6fdf080c
|
83
|
value = 0;
|
okini3939 |
0:684b6fdf080c
|
84
|
break;
|
okini3939 |
0:684b6fdf080c
|
85
|
case '1':
|
okini3939 |
0:684b6fdf080c
|
86
|
value = 1;
|
okini3939 |
0:684b6fdf080c
|
87
|
break;
|
okini3939 |
0:684b6fdf080c
|
88
|
|
okini3939 |
0:684b6fdf080c
|
89
|
case 'M': // RELAY
|
okini3939 |
0:684b6fdf080c
|
90
|
if (keynum >= IL_RELAY_NUM) break;
|
okini3939 |
0:684b6fdf080c
|
91
|
value = io->relay[keynum];
|
okini3939 |
0:684b6fdf080c
|
92
|
break;
|
okini3939 |
0:684b6fdf080c
|
93
|
|
okini3939 |
0:684b6fdf080c
|
94
|
case 'T': // Timer
|
okini3939 |
0:684b6fdf080c
|
95
|
if (keynum >= IL_TIMER_NUM) break;
|
okini3939 |
0:684b6fdf080c
|
96
|
if (il[i].expression == EXP_NULL) {
|
okini3939 |
0:684b6fdf080c
|
97
|
value = io->timer_flg[keynum] && io->timer_cnt[keynum] >= io->timer_set[keynum];
|
okini3939 |
0:684b6fdf080c
|
98
|
} else {
|
okini3939 |
0:684b6fdf080c
|
99
|
value = io->timer_cnt[keynum];
|
okini3939 |
0:684b6fdf080c
|
100
|
}
|
okini3939 |
0:684b6fdf080c
|
101
|
break;
|
okini3939 |
0:684b6fdf080c
|
102
|
|
okini3939 |
0:684b6fdf080c
|
103
|
case 'C': // Counter
|
okini3939 |
0:684b6fdf080c
|
104
|
if (keynum >= IL_COUNTER_NUM) break;
|
okini3939 |
0:684b6fdf080c
|
105
|
if (il[i].expression == EXP_NULL) {
|
okini3939 |
0:684b6fdf080c
|
106
|
value = io->count_cnt[keynum] >= io->count_set[keynum];
|
okini3939 |
0:684b6fdf080c
|
107
|
} else {
|
okini3939 |
0:684b6fdf080c
|
108
|
value = io->count_cnt[keynum];
|
okini3939 |
0:684b6fdf080c
|
109
|
}
|
okini3939 |
0:684b6fdf080c
|
110
|
break;
|
okini3939 |
0:684b6fdf080c
|
111
|
|
okini3939 |
0:684b6fdf080c
|
112
|
default: // order input
|
okini3939 |
0:684b6fdf080c
|
113
|
if (cb_input) {
|
okini3939 |
0:684b6fdf080c
|
114
|
value = (*cb_input)(il[i].key, keynum, il[i].expression, old);
|
okini3939 |
0:684b6fdf080c
|
115
|
}
|
okini3939 |
0:684b6fdf080c
|
116
|
break;
|
okini3939 |
0:684b6fdf080c
|
117
|
}
|
okini3939 |
0:684b6fdf080c
|
118
|
|
okini3939 |
0:684b6fdf080c
|
119
|
// expression
|
okini3939 |
0:684b6fdf080c
|
120
|
switch (il[i].expression) {
|
okini3939 |
0:684b6fdf080c
|
121
|
case EXP_EQ:
|
okini3939 |
0:684b6fdf080c
|
122
|
return value == check;
|
okini3939 |
0:684b6fdf080c
|
123
|
case EXP_NE:
|
okini3939 |
0:684b6fdf080c
|
124
|
return value != check;
|
okini3939 |
0:684b6fdf080c
|
125
|
case EXP_LE:
|
okini3939 |
0:684b6fdf080c
|
126
|
return value <= check;
|
okini3939 |
0:684b6fdf080c
|
127
|
case EXP_LT:
|
okini3939 |
0:684b6fdf080c
|
128
|
return value < check;
|
okini3939 |
0:684b6fdf080c
|
129
|
case EXP_GE:
|
okini3939 |
0:684b6fdf080c
|
130
|
return value >= check;
|
okini3939 |
0:684b6fdf080c
|
131
|
case EXP_GT:
|
okini3939 |
0:684b6fdf080c
|
132
|
return value > check;
|
okini3939 |
0:684b6fdf080c
|
133
|
case EXP_MOD:
|
okini3939 |
0:684b6fdf080c
|
134
|
return (int)value % (int)check;
|
okini3939 |
0:684b6fdf080c
|
135
|
case EXP_NMOD:
|
okini3939 |
0:684b6fdf080c
|
136
|
return ! ((int)value % (int)check);
|
okini3939 |
0:684b6fdf080c
|
137
|
}
|
okini3939 |
0:684b6fdf080c
|
138
|
|
okini3939 |
0:684b6fdf080c
|
139
|
return value != 0;
|
okini3939 |
0:684b6fdf080c
|
140
|
}
|
okini3939 |
0:684b6fdf080c
|
141
|
|
okini3939 |
0:684b6fdf080c
|
142
|
// output relay
|
okini3939 |
0:684b6fdf080c
|
143
|
void ILinterpreter::output (int i, int reg, eMNEMONIC mne) {
|
okini3939 |
0:684b6fdf080c
|
144
|
int keynum;
|
okini3939 |
0:684b6fdf080c
|
145
|
|
okini3939 |
0:684b6fdf080c
|
146
|
keynum = il[i].keynum;
|
okini3939 |
0:684b6fdf080c
|
147
|
#ifdef DEBUG
|
okini3939 |
0:684b6fdf080c
|
148
|
printf("output [%c%d] reg=%d sr=%d\r\n", il[i].key, keynum, reg, mne);
|
okini3939 |
0:684b6fdf080c
|
149
|
#endif
|
okini3939 |
0:684b6fdf080c
|
150
|
|
okini3939 |
0:684b6fdf080c
|
151
|
switch (il[i].key) {
|
okini3939 |
0:684b6fdf080c
|
152
|
case 'M': // relay
|
okini3939 |
0:684b6fdf080c
|
153
|
if (keynum >= IL_RELAY_NUM) break;
|
okini3939 |
0:684b6fdf080c
|
154
|
if (mne == MNE_OUT) {
|
okini3939 |
0:684b6fdf080c
|
155
|
inout.relay[keynum] = reg;
|
okini3939 |
0:684b6fdf080c
|
156
|
} else
|
okini3939 |
0:684b6fdf080c
|
157
|
if (mne == MNE_SET && reg) {
|
okini3939 |
0:684b6fdf080c
|
158
|
inout.relay[keynum] = 1;
|
okini3939 |
0:684b6fdf080c
|
159
|
} else
|
okini3939 |
0:684b6fdf080c
|
160
|
if (mne == MNE_RST && reg) {
|
okini3939 |
0:684b6fdf080c
|
161
|
inout.relay[keynum] = 0;
|
okini3939 |
0:684b6fdf080c
|
162
|
}
|
okini3939 |
0:684b6fdf080c
|
163
|
break;
|
okini3939 |
0:684b6fdf080c
|
164
|
|
okini3939 |
0:684b6fdf080c
|
165
|
case 'T': // Timer
|
okini3939 |
0:684b6fdf080c
|
166
|
if (keynum >= IL_TIMER_NUM) break;
|
okini3939 |
0:684b6fdf080c
|
167
|
if (mne == MNE_OUT) {
|
okini3939 |
0:684b6fdf080c
|
168
|
if (! inout.timer_flg[keynum]) {
|
okini3939 |
0:684b6fdf080c
|
169
|
// set timer
|
okini3939 |
0:684b6fdf080c
|
170
|
inout.timer_cnt[keynum] = 0;
|
okini3939 |
0:684b6fdf080c
|
171
|
}
|
okini3939 |
0:684b6fdf080c
|
172
|
inout.timer_flg[keynum] = reg;
|
okini3939 |
0:684b6fdf080c
|
173
|
} else
|
okini3939 |
0:684b6fdf080c
|
174
|
if (mne == MNE_RST && reg) {
|
okini3939 |
0:684b6fdf080c
|
175
|
inout.timer_cnt[keynum] = 0;
|
okini3939 |
0:684b6fdf080c
|
176
|
}
|
okini3939 |
0:684b6fdf080c
|
177
|
break;
|
okini3939 |
0:684b6fdf080c
|
178
|
|
okini3939 |
0:684b6fdf080c
|
179
|
case 'C': // Counter
|
okini3939 |
0:684b6fdf080c
|
180
|
if (keynum >= IL_COUNTER_NUM) break;
|
okini3939 |
0:684b6fdf080c
|
181
|
if (mne == MNE_OUT && reg) {
|
okini3939 |
0:684b6fdf080c
|
182
|
if (inout.count_rev[keynum]) {
|
okini3939 |
0:684b6fdf080c
|
183
|
inout.count_cnt[keynum] --;
|
okini3939 |
0:684b6fdf080c
|
184
|
} else {
|
okini3939 |
0:684b6fdf080c
|
185
|
inout.count_cnt[keynum] ++;
|
okini3939 |
0:684b6fdf080c
|
186
|
}
|
okini3939 |
0:684b6fdf080c
|
187
|
} else
|
okini3939 |
0:684b6fdf080c
|
188
|
if (mne == MNE_RST && reg) {
|
okini3939 |
0:684b6fdf080c
|
189
|
inout.count_cnt[keynum] = 0;
|
okini3939 |
0:684b6fdf080c
|
190
|
}
|
okini3939 |
0:684b6fdf080c
|
191
|
case 'R': // Counter (reverse)
|
okini3939 |
0:684b6fdf080c
|
192
|
if (keynum >= IL_COUNTER_NUM) break;
|
okini3939 |
0:684b6fdf080c
|
193
|
if (mne == MNE_OUT) {
|
okini3939 |
0:684b6fdf080c
|
194
|
inout.count_rev[keynum] = reg;
|
okini3939 |
0:684b6fdf080c
|
195
|
}
|
okini3939 |
0:684b6fdf080c
|
196
|
break;
|
okini3939 |
0:684b6fdf080c
|
197
|
|
okini3939 |
0:684b6fdf080c
|
198
|
default: // order output
|
okini3939 |
0:684b6fdf080c
|
199
|
if (cb_output) {
|
okini3939 |
0:684b6fdf080c
|
200
|
(*cb_output)(il[i].key, keynum, reg, mne);
|
okini3939 |
0:684b6fdf080c
|
201
|
}
|
okini3939 |
0:684b6fdf080c
|
202
|
break;
|
okini3939 |
0:684b6fdf080c
|
203
|
}
|
okini3939 |
0:684b6fdf080c
|
204
|
}
|
okini3939 |
0:684b6fdf080c
|
205
|
|
okini3939 |
0:684b6fdf080c
|
206
|
// execute IL
|
okini3939 |
0:684b6fdf080c
|
207
|
int ILinterpreter::exec () {
|
okini3939 |
0:684b6fdf080c
|
208
|
int i, j, reg = -1;
|
okini3939 |
0:684b6fdf080c
|
209
|
tInOut inout_tmp;
|
okini3939 |
0:684b6fdf080c
|
210
|
|
okini3939 |
0:684b6fdf080c
|
211
|
if (! il_count) return 0;
|
okini3939 |
0:684b6fdf080c
|
212
|
|
okini3939 |
1:f8c5afc27878
|
213
|
addr = 0;
|
okini3939 |
0:684b6fdf080c
|
214
|
inout.sec = time(NULL);
|
okini3939 |
0:684b6fdf080c
|
215
|
inout_tmp = inout;
|
okini3939 |
0:684b6fdf080c
|
216
|
|
okini3939 |
0:684b6fdf080c
|
217
|
// mnemonic decode
|
okini3939 |
0:684b6fdf080c
|
218
|
for(i = 0; i < il_count; i ++) {
|
okini3939 |
0:684b6fdf080c
|
219
|
switch (il[i].mnemonic) {
|
okini3939 |
0:684b6fdf080c
|
220
|
case MNE_LD:
|
okini3939 |
1:f8c5afc27878
|
221
|
push(reg);
|
okini3939 |
0:684b6fdf080c
|
222
|
reg = input(&inout, i);
|
okini3939 |
0:684b6fdf080c
|
223
|
break;
|
okini3939 |
0:684b6fdf080c
|
224
|
case MNE_LDI:
|
okini3939 |
1:f8c5afc27878
|
225
|
push(reg);
|
okini3939 |
0:684b6fdf080c
|
226
|
reg = ! input(&inout, i);
|
okini3939 |
0:684b6fdf080c
|
227
|
break;
|
okini3939 |
0:684b6fdf080c
|
228
|
case MNE_LDP:
|
okini3939 |
1:f8c5afc27878
|
229
|
push(reg);
|
okini3939 |
0:684b6fdf080c
|
230
|
reg = input(&inout, i) && ! input(&inout_old, i, 1);
|
okini3939 |
0:684b6fdf080c
|
231
|
break;
|
okini3939 |
0:684b6fdf080c
|
232
|
case MNE_LDF:
|
okini3939 |
1:f8c5afc27878
|
233
|
push(reg);
|
okini3939 |
0:684b6fdf080c
|
234
|
reg = ! input(&inout, i) && input(&inout_old, i, 1);
|
okini3939 |
0:684b6fdf080c
|
235
|
break;
|
okini3939 |
0:684b6fdf080c
|
236
|
|
okini3939 |
0:684b6fdf080c
|
237
|
case MNE_AND:
|
okini3939 |
0:684b6fdf080c
|
238
|
reg = reg && input(&inout, i);
|
okini3939 |
0:684b6fdf080c
|
239
|
break;
|
okini3939 |
0:684b6fdf080c
|
240
|
case MNE_ANI:
|
okini3939 |
0:684b6fdf080c
|
241
|
reg = reg && ! input(&inout, i);
|
okini3939 |
0:684b6fdf080c
|
242
|
break;
|
okini3939 |
0:684b6fdf080c
|
243
|
case MNE_ANDP:
|
okini3939 |
2:64bc38078592
|
244
|
reg = reg && (input(&inout, i) && ! input(&inout_old, i, 1));
|
okini3939 |
0:684b6fdf080c
|
245
|
break;
|
okini3939 |
0:684b6fdf080c
|
246
|
case MNE_ANDF:
|
okini3939 |
2:64bc38078592
|
247
|
reg = reg && (! input(&inout, i) && input(&inout_old, i, 1));
|
okini3939 |
0:684b6fdf080c
|
248
|
break;
|
okini3939 |
0:684b6fdf080c
|
249
|
|
okini3939 |
0:684b6fdf080c
|
250
|
case MNE_OR:
|
okini3939 |
0:684b6fdf080c
|
251
|
reg = reg || input(&inout, i);
|
okini3939 |
0:684b6fdf080c
|
252
|
break;
|
okini3939 |
0:684b6fdf080c
|
253
|
case MNE_ORI:
|
okini3939 |
0:684b6fdf080c
|
254
|
reg = reg || ! input(&inout, i);
|
okini3939 |
0:684b6fdf080c
|
255
|
break;
|
okini3939 |
0:684b6fdf080c
|
256
|
case MNE_ORP:
|
okini3939 |
2:64bc38078592
|
257
|
reg = reg || (input(&inout, i) && ! input(&inout_old, i, 1));
|
okini3939 |
0:684b6fdf080c
|
258
|
break;
|
okini3939 |
0:684b6fdf080c
|
259
|
case MNE_ORF:
|
okini3939 |
2:64bc38078592
|
260
|
reg = reg || (! input(&inout, i) && input(&inout_old, i, 1));
|
okini3939 |
0:684b6fdf080c
|
261
|
break;
|
okini3939 |
0:684b6fdf080c
|
262
|
|
okini3939 |
0:684b6fdf080c
|
263
|
case MNE_ANB:
|
okini3939 |
1:f8c5afc27878
|
264
|
if (pop(&j) || j == -1) return -1;
|
okini3939 |
0:684b6fdf080c
|
265
|
reg = reg && j;
|
okini3939 |
0:684b6fdf080c
|
266
|
break;
|
okini3939 |
0:684b6fdf080c
|
267
|
case MNE_ORB:
|
okini3939 |
1:f8c5afc27878
|
268
|
if (pop(&j) || j == -1) return -1;
|
okini3939 |
0:684b6fdf080c
|
269
|
reg = reg || j;
|
okini3939 |
0:684b6fdf080c
|
270
|
break;
|
okini3939 |
0:684b6fdf080c
|
271
|
|
okini3939 |
0:684b6fdf080c
|
272
|
case MNE_INV:
|
okini3939 |
0:684b6fdf080c
|
273
|
reg = ! reg;
|
okini3939 |
0:684b6fdf080c
|
274
|
break;
|
okini3939 |
0:684b6fdf080c
|
275
|
|
okini3939 |
0:684b6fdf080c
|
276
|
case MNE_MPS:
|
okini3939 |
1:f8c5afc27878
|
277
|
if (push(reg)) return -1;
|
okini3939 |
0:684b6fdf080c
|
278
|
break;
|
okini3939 |
0:684b6fdf080c
|
279
|
case MNE_MRD:
|
okini3939 |
1:f8c5afc27878
|
280
|
if (read(®) || reg == -1) return -1;
|
okini3939 |
0:684b6fdf080c
|
281
|
break;
|
okini3939 |
0:684b6fdf080c
|
282
|
case MNE_MPP:
|
okini3939 |
1:f8c5afc27878
|
283
|
if (pop(®) || reg == -1) return -1;
|
okini3939 |
0:684b6fdf080c
|
284
|
break;
|
okini3939 |
0:684b6fdf080c
|
285
|
|
okini3939 |
0:684b6fdf080c
|
286
|
case MNE_OUT:
|
okini3939 |
0:684b6fdf080c
|
287
|
case MNE_SET:
|
okini3939 |
0:684b6fdf080c
|
288
|
case MNE_RST:
|
okini3939 |
0:684b6fdf080c
|
289
|
output(i, reg, il[i].mnemonic);
|
okini3939 |
0:684b6fdf080c
|
290
|
break;
|
okini3939 |
0:684b6fdf080c
|
291
|
}
|
okini3939 |
0:684b6fdf080c
|
292
|
}
|
okini3939 |
0:684b6fdf080c
|
293
|
|
okini3939 |
0:684b6fdf080c
|
294
|
inout_old = inout_tmp;
|
okini3939 |
0:684b6fdf080c
|
295
|
|
okini3939 |
0:684b6fdf080c
|
296
|
#ifdef DEBUG
|
okini3939 |
0:684b6fdf080c
|
297
|
printf("timer0=%d(%d) timer1=%d(%d)\r\n", inout.timer_cnt[0], inout.timer_set[0], inout.timer_cnt[1], inout.timer_set[1]);
|
okini3939 |
0:684b6fdf080c
|
298
|
#endif
|
okini3939 |
0:684b6fdf080c
|
299
|
return 0;
|
okini3939 |
0:684b6fdf080c
|
300
|
}
|
okini3939 |
0:684b6fdf080c
|
301
|
|
okini3939 |
0:684b6fdf080c
|
302
|
// set callback function
|
okini3939 |
1:f8c5afc27878
|
303
|
struct tInOut* ILinterpreter::attach (float (*pf_i)(char, int, eEXPRESSION, int), void (*pf_o)(char, int, int, eMNEMONIC)) {
|
okini3939 |
0:684b6fdf080c
|
304
|
cb_input = pf_i;
|
okini3939 |
0:684b6fdf080c
|
305
|
cb_output = pf_o;
|
okini3939 |
1:f8c5afc27878
|
306
|
return &inout;
|
okini3939 |
0:684b6fdf080c
|
307
|
}
|
okini3939 |
0:684b6fdf080c
|
308
|
|
okini3939 |
0:684b6fdf080c
|
309
|
// timer 10Hz
|
okini3939 |
0:684b6fdf080c
|
310
|
void ILinterpreter::pool () {
|
okini3939 |
0:684b6fdf080c
|
311
|
int i;
|
okini3939 |
0:684b6fdf080c
|
312
|
|
okini3939 |
0:684b6fdf080c
|
313
|
if (! il_count) return;
|
okini3939 |
0:684b6fdf080c
|
314
|
|
okini3939 |
0:684b6fdf080c
|
315
|
// timer
|
okini3939 |
0:684b6fdf080c
|
316
|
for (i = 0; i < IL_TIMER_NUM; i ++) {
|
okini3939 |
0:684b6fdf080c
|
317
|
if (inout.timer_flg[i] && inout.timer_cnt[i] < inout.timer_set[i]) {
|
okini3939 |
0:684b6fdf080c
|
318
|
inout.timer_cnt[i] ++;
|
okini3939 |
0:684b6fdf080c
|
319
|
}
|
okini3939 |
0:684b6fdf080c
|
320
|
}
|
okini3939 |
0:684b6fdf080c
|
321
|
}
|
okini3939 |
0:684b6fdf080c
|
322
|
|
okini3939 |
0:684b6fdf080c
|
323
|
// load sub
|
okini3939 |
0:684b6fdf080c
|
324
|
void ILinterpreter::load_exp (int i, char *buf) {
|
okini3939 |
0:684b6fdf080c
|
325
|
int j, len;
|
okini3939 |
0:684b6fdf080c
|
326
|
char *tmp;
|
okini3939 |
0:684b6fdf080c
|
327
|
|
okini3939 |
0:684b6fdf080c
|
328
|
// MNEMONIC "KEY""num"==value
|
okini3939 |
0:684b6fdf080c
|
329
|
il[i].key = buf[0];
|
okini3939 |
0:684b6fdf080c
|
330
|
il[i].keynum = strtol(&buf[1], &tmp, 10);
|
okini3939 |
0:684b6fdf080c
|
331
|
il[i].expression = EXP_NULL;
|
okini3939 |
0:684b6fdf080c
|
332
|
il[i].value = 0;
|
okini3939 |
0:684b6fdf080c
|
333
|
|
okini3939 |
0:684b6fdf080c
|
334
|
if (tmp) {
|
okini3939 |
0:684b6fdf080c
|
335
|
// expression
|
okini3939 |
0:684b6fdf080c
|
336
|
for (j = 0; j < IL_EXP_NUM; j ++) {
|
okini3939 |
0:684b6fdf080c
|
337
|
len = strlen(exp_str[j].str);
|
okini3939 |
0:684b6fdf080c
|
338
|
if (strncmp(tmp, exp_str[j].str, len) == 0 && tmp[len] >= '0' && tmp[len] <= '9') {
|
okini3939 |
0:684b6fdf080c
|
339
|
// MNEMONIC KEYnum"==""value"
|
okini3939 |
0:684b6fdf080c
|
340
|
il[i].expression = exp_str[j].exp;
|
okini3939 |
0:684b6fdf080c
|
341
|
il[i].value = atof(&tmp[len]);
|
okini3939 |
0:684b6fdf080c
|
342
|
break;
|
okini3939 |
0:684b6fdf080c
|
343
|
}
|
okini3939 |
0:684b6fdf080c
|
344
|
}
|
okini3939 |
0:684b6fdf080c
|
345
|
}
|
okini3939 |
0:684b6fdf080c
|
346
|
}
|
okini3939 |
0:684b6fdf080c
|
347
|
|
okini3939 |
0:684b6fdf080c
|
348
|
// load IL file
|
okini3939 |
0:684b6fdf080c
|
349
|
int ILinterpreter::load (char *file) {
|
okini3939 |
0:684b6fdf080c
|
350
|
FILE *fp;
|
okini3939 |
0:684b6fdf080c
|
351
|
char c;
|
okini3939 |
0:684b6fdf080c
|
352
|
int i, j, len;
|
okini3939 |
0:684b6fdf080c
|
353
|
char buf[20];
|
okini3939 |
0:684b6fdf080c
|
354
|
|
okini3939 |
0:684b6fdf080c
|
355
|
il_count = 0;
|
okini3939 |
0:684b6fdf080c
|
356
|
|
okini3939 |
0:684b6fdf080c
|
357
|
fp = fopen(file, "r");
|
okini3939 |
0:684b6fdf080c
|
358
|
if (fp == NULL) return -1;
|
okini3939 |
0:684b6fdf080c
|
359
|
|
okini3939 |
0:684b6fdf080c
|
360
|
i = 0;
|
okini3939 |
0:684b6fdf080c
|
361
|
for (;;) {
|
okini3939 |
0:684b6fdf080c
|
362
|
if (il_count >= IL_NUM) break;
|
okini3939 |
0:684b6fdf080c
|
363
|
c = fgetc(fp);
|
okini3939 |
0:684b6fdf080c
|
364
|
if (feof(fp)) break;
|
okini3939 |
0:684b6fdf080c
|
365
|
|
okini3939 |
0:684b6fdf080c
|
366
|
if (c != '\r' && c != '\n' && i < 40 - 1) {
|
okini3939 |
0:684b6fdf080c
|
367
|
// load
|
okini3939 |
0:684b6fdf080c
|
368
|
buf[i] = c;
|
okini3939 |
0:684b6fdf080c
|
369
|
i ++;
|
okini3939 |
0:684b6fdf080c
|
370
|
continue;
|
okini3939 |
0:684b6fdf080c
|
371
|
}
|
okini3939 |
0:684b6fdf080c
|
372
|
buf[i] = 0;
|
okini3939 |
0:684b6fdf080c
|
373
|
|
okini3939 |
0:684b6fdf080c
|
374
|
if (i == 0 || buf[0] == '#' || buf[0] == ';') {
|
okini3939 |
0:684b6fdf080c
|
375
|
// comment
|
okini3939 |
0:684b6fdf080c
|
376
|
i = 0;
|
okini3939 |
0:684b6fdf080c
|
377
|
continue;
|
okini3939 |
0:684b6fdf080c
|
378
|
}
|
okini3939 |
0:684b6fdf080c
|
379
|
|
okini3939 |
0:684b6fdf080c
|
380
|
// mnemonic
|
okini3939 |
0:684b6fdf080c
|
381
|
for (j = 0; j < IL_MNE_NUM; j ++) {
|
okini3939 |
0:684b6fdf080c
|
382
|
len = strlen(mne_str[j].str);
|
okini3939 |
0:684b6fdf080c
|
383
|
if (strncmp(buf, mne_str[j].str, len) == 0 && (buf[len] == ' ' || buf[len] == 0)) {
|
okini3939 |
0:684b6fdf080c
|
384
|
// "MNEMONIC" KEYnum==value
|
okini3939 |
0:684b6fdf080c
|
385
|
il[il_count].mnemonic = mne_str[j].mne;
|
okini3939 |
0:684b6fdf080c
|
386
|
load_exp(il_count, &buf[len + 1]);
|
okini3939 |
2:64bc38078592
|
387
|
#ifdef DEBUG
|
okini3939 |
2:64bc38078592
|
388
|
printf("%d: M=%d [%c%d] E=%d V=%f\r\n", il_count, il[il_count].mnemonic, il[il_count].key, il[il_count].keynum, il[il_count].expression, il[il_count].value);
|
okini3939 |
2:64bc38078592
|
389
|
#endif
|
okini3939 |
0:684b6fdf080c
|
390
|
il_count ++;
|
okini3939 |
0:684b6fdf080c
|
391
|
break;
|
okini3939 |
0:684b6fdf080c
|
392
|
}
|
okini3939 |
0:684b6fdf080c
|
393
|
}
|
okini3939 |
0:684b6fdf080c
|
394
|
if (strncmp(buf, "END", 3) == 0) break;
|
okini3939 |
0:684b6fdf080c
|
395
|
if (j == IL_MNE_NUM) return -1;
|
okini3939 |
0:684b6fdf080c
|
396
|
|
okini3939 |
0:684b6fdf080c
|
397
|
i = 0;
|
okini3939 |
0:684b6fdf080c
|
398
|
}
|
okini3939 |
0:684b6fdf080c
|
399
|
|
okini3939 |
0:684b6fdf080c
|
400
|
// init
|
okini3939 |
0:684b6fdf080c
|
401
|
for (i = 0; i < il_count; i ++) {
|
okini3939 |
0:684b6fdf080c
|
402
|
if (il[i].mnemonic == MNE_DEF) {
|
okini3939 |
0:684b6fdf080c
|
403
|
switch (il[i].key) {
|
okini3939 |
0:684b6fdf080c
|
404
|
case 't': // Timer
|
okini3939 |
0:684b6fdf080c
|
405
|
inout.timer_set[il[i].keynum] = (int)il[i].value * 10;
|
okini3939 |
0:684b6fdf080c
|
406
|
break;
|
okini3939 |
0:684b6fdf080c
|
407
|
|
okini3939 |
0:684b6fdf080c
|
408
|
case 'c': // Counter
|
okini3939 |
0:684b6fdf080c
|
409
|
inout.count_set[il[i].keynum] = (int)il[i].value;
|
okini3939 |
0:684b6fdf080c
|
410
|
break;
|
okini3939 |
0:684b6fdf080c
|
411
|
}
|
okini3939 |
0:684b6fdf080c
|
412
|
}
|
okini3939 |
0:684b6fdf080c
|
413
|
}
|
okini3939 |
0:684b6fdf080c
|
414
|
|
okini3939 |
0:684b6fdf080c
|
415
|
fclose(fp);
|
okini3939 |
0:684b6fdf080c
|
416
|
|
okini3939 |
0:684b6fdf080c
|
417
|
return 0;
|
okini3939 |
0:684b6fdf080c
|
418
|
}
|
okini3939 |
1:f8c5afc27878
|
419
|
|
okini3939 |
1:f8c5afc27878
|
420
|
int ILinterpreter::push (int dat) {
|
okini3939 |
1:f8c5afc27878
|
421
|
|
okini3939 |
1:f8c5afc27878
|
422
|
if (addr >= IL_STACK) {
|
okini3939 |
1:f8c5afc27878
|
423
|
return -1;
|
okini3939 |
1:f8c5afc27878
|
424
|
}
|
okini3939 |
1:f8c5afc27878
|
425
|
stack[addr] = dat;
|
okini3939 |
1:f8c5afc27878
|
426
|
addr ++;
|
okini3939 |
1:f8c5afc27878
|
427
|
return dat;
|
okini3939 |
1:f8c5afc27878
|
428
|
}
|
okini3939 |
1:f8c5afc27878
|
429
|
|
okini3939 |
1:f8c5afc27878
|
430
|
int ILinterpreter::pop (int *dat) {
|
okini3939 |
1:f8c5afc27878
|
431
|
|
okini3939 |
1:f8c5afc27878
|
432
|
if (addr == 0) {
|
okini3939 |
1:f8c5afc27878
|
433
|
return -1;
|
okini3939 |
1:f8c5afc27878
|
434
|
}
|
okini3939 |
1:f8c5afc27878
|
435
|
addr --;
|
okini3939 |
1:f8c5afc27878
|
436
|
*dat = stack[addr];
|
okini3939 |
1:f8c5afc27878
|
437
|
return 0;
|
okini3939 |
1:f8c5afc27878
|
438
|
}
|
okini3939 |
1:f8c5afc27878
|
439
|
|
okini3939 |
1:f8c5afc27878
|
440
|
int ILinterpreter::read (int *dat) {
|
okini3939 |
1:f8c5afc27878
|
441
|
|
okini3939 |
1:f8c5afc27878
|
442
|
if (addr == 0) {
|
okini3939 |
1:f8c5afc27878
|
443
|
return -1;
|
okini3939 |
1:f8c5afc27878
|
444
|
}
|
okini3939 |
1:f8c5afc27878
|
445
|
*dat = stack[addr];
|
okini3939 |
1:f8c5afc27878
|
446
|
return 0;
|
okini3939 |
1:f8c5afc27878
|
447
|
} |