OpcUaCanOpen
CANopen OPC-UA server
muParserBytecode.cpp
Go to the documentation of this file.
1
/*
2
__________
3
_____ __ __\______ \_____ _______ ______ ____ _______
4
/ \ | | \| ___/\__ \ \_ __ \/ ___/_/ __ \\_ __ \
5
| Y Y \| | /| | / __ \_| | \/\___ \ \ ___/ | | \/
6
|__|_| /|____/ |____| (____ /|__| /____ > \___ >|__|
7
\/ \/ \/ \/
8
Copyright (C) 2011 Ingo Berg
9
10
Permission is hereby granted, free of charge, to any person obtaining a copy of this
11
software and associated documentation files (the "Software"), to deal in the Software
12
without restriction, including without limitation the rights to use, copy, modify,
13
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
14
permit persons to whom the Software is furnished to do so, subject to the following conditions:
15
16
The above copyright notice and this permission notice shall be included in all copies or
17
substantial portions of the Software.
18
19
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
20
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
22
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
*/
25
26
#include "
muParserBytecode.h
"
27
28
#include <algorithm>
29
#include <cassert>
30
#include <string>
31
#include <stack>
32
#include <vector>
33
#include <iostream>
34
35
#include "
muParserDef.h
"
36
#include "
muParserError.h
"
37
#include "
muParserToken.h
"
38
#include "
muParserStack.h
"
39
#include "
muParserTemplateMagic.h
"
40
41
42
namespace
mu
43
{
44
//---------------------------------------------------------------------------
46
ParserByteCode::ParserByteCode
()
47
:m_iStackPos(0)
48
,m_iMaxStackSize(0)
49
,m_vRPN()
50
,m_bEnableOptimizer(true)
51
{
52
m_vRPN
.reserve(50);
53
}
54
55
//---------------------------------------------------------------------------
60
ParserByteCode::ParserByteCode
(
const
ParserByteCode
&a_ByteCode)
61
{
62
Assign
(a_ByteCode);
63
}
64
65
//---------------------------------------------------------------------------
70
ParserByteCode
&
ParserByteCode::operator=
(
const
ParserByteCode
&a_ByteCode)
71
{
72
Assign
(a_ByteCode);
73
return
*
this
;
74
}
75
76
//---------------------------------------------------------------------------
77
void
ParserByteCode::EnableOptimizer
(
bool
bStat)
78
{
79
m_bEnableOptimizer
= bStat;
80
}
81
82
//---------------------------------------------------------------------------
87
void
ParserByteCode::Assign
(
const
ParserByteCode
&a_ByteCode)
88
{
89
if
(
this
==&a_ByteCode)
90
return
;
91
92
m_iStackPos
= a_ByteCode.
m_iStackPos
;
93
m_vRPN
= a_ByteCode.
m_vRPN
;
94
m_iMaxStackSize
= a_ByteCode.
m_iMaxStackSize
;
95
m_bEnableOptimizer
= a_ByteCode.
m_bEnableOptimizer
;
96
}
97
98
//---------------------------------------------------------------------------
103
void
ParserByteCode::AddVar
(
value_type
*
a_pVar
)
104
{
105
++
m_iStackPos
;
106
m_iMaxStackSize
=
std::max
(
m_iMaxStackSize
, (
size_t
)
m_iStackPos
);
107
108
// optimization does not apply
109
SToken
tok;
110
tok.
Cmd
=
cmVAR
;
111
tok.
Val
.ptr =
a_pVar
;
112
tok.
Val
.data = 1;
113
tok.
Val
.data2 = 0;
114
m_vRPN
.push_back(tok);
115
}
116
117
//---------------------------------------------------------------------------
130
void
ParserByteCode::AddVal
(
value_type
a_fVal
)
131
{
132
++
m_iStackPos
;
133
m_iMaxStackSize
=
std::max
(
m_iMaxStackSize
, (
size_t
)
m_iStackPos
);
134
135
// If optimization does not apply
136
SToken
tok;
137
tok.
Cmd
=
cmVAL
;
138
tok.
Val
.ptr = NULL;
139
tok.
Val
.data = 0;
140
tok.
Val
.data2 =
a_fVal
;
141
m_vRPN
.push_back(tok);
142
}
143
144
//---------------------------------------------------------------------------
145
void
ParserByteCode::ConstantFolding
(
ECmdCode
a_Oprt)
146
{
147
std::size_t sz =
m_vRPN
.size();
148
value_type
&
x
=
m_vRPN
[sz-2].Val.data2,
149
&y =
m_vRPN
[sz-1].Val.data2;
150
switch
(a_Oprt)
151
{
152
case
cmLAND
:
x
= (int)
x
&& (
int
)y;
m_vRPN
.pop_back();
break
;
153
case
cmLOR
:
x
= (int)
x
|| (
int
)y;
m_vRPN
.pop_back();
break
;
154
case
cmLT
:
x
=
x
< y;
m_vRPN
.pop_back();
break
;
155
case
cmGT
:
x
=
x
> y;
m_vRPN
.pop_back();
break
;
156
case
cmLE
:
x
=
x
<= y;
m_vRPN
.pop_back();
break
;
157
case
cmGE
:
x
=
x
>= y;
m_vRPN
.pop_back();
break
;
158
case
cmNEQ
:
x
=
x
!= y;
m_vRPN
.pop_back();
break
;
159
case
cmEQ
:
x
=
x
== y;
m_vRPN
.pop_back();
break
;
160
case
cmADD
:
x
=
x
+ y;
m_vRPN
.pop_back();
break
;
161
case
cmSUB
:
x
=
x
- y;
m_vRPN
.pop_back();
break
;
162
case
cmMUL
:
x
=
x
* y;
m_vRPN
.pop_back();
break
;
163
case
cmDIV
:
164
165
#if defined(MUP_MATH_EXCEPTIONS)
166
if
(y==0)
167
throw
ParserError
(
ecDIV_BY_ZERO
,
_T
(
"0"
));
168
#endif
169
170
x
=
x
/ y;
171
m_vRPN
.pop_back();
172
break
;
173
174
case
cmPOW
:
x
=
MathImpl<value_type>::Pow
(
x
, y);
175
m_vRPN
.pop_back();
176
break
;
177
178
default
:
179
break
;
180
}
// switch opcode
181
}
182
183
//---------------------------------------------------------------------------
194
void
ParserByteCode::AddOp
(
ECmdCode
a_Oprt)
195
{
196
bool
bOptimized =
false
;
197
198
if
(
m_bEnableOptimizer
)
199
{
200
std::size_t sz =
m_vRPN
.size();
201
202
// Check for foldable constants like:
203
// cmVAL cmVAL cmADD
204
// where cmADD can stand fopr any binary operator applied to
205
// two constant values.
206
if
(sz>=2 &&
m_vRPN
[sz-2].Cmd ==
cmVAL
&&
m_vRPN
[sz-1].Cmd ==
cmVAL
)
207
{
208
ConstantFolding
(a_Oprt);
209
bOptimized =
true
;
210
}
211
else
212
{
213
switch
(a_Oprt)
214
{
215
case
cmPOW
:
216
// Optimization for polynomials of low order
217
if
(
m_vRPN
[sz-2].Cmd ==
cmVAR
&&
m_vRPN
[sz-1].Cmd ==
cmVAL
)
218
{
219
if
(
m_vRPN
[sz-1].Val.data2==2)
220
m_vRPN
[sz-2].Cmd =
cmVARPOW2
;
221
else
if
(
m_vRPN
[sz-1].Val.data2==3)
222
m_vRPN
[sz-2].Cmd =
cmVARPOW3
;
223
else
if
(
m_vRPN
[sz-1].Val.data2==4)
224
m_vRPN
[sz-2].Cmd =
cmVARPOW4
;
225
else
226
break
;
227
228
m_vRPN
.pop_back();
229
bOptimized =
true
;
230
}
231
break
;
232
233
case
cmSUB
:
234
case
cmADD
:
235
// Simple optimization based on pattern recognition for a shitload of different
236
// bytecode combinations of addition/subtraction
237
if
( (
m_vRPN
[sz-1].Cmd ==
cmVAR
&&
m_vRPN
[sz-2].Cmd ==
cmVAL
) ||
238
(
m_vRPN
[sz-1].Cmd ==
cmVAL
&&
m_vRPN
[sz-2].Cmd ==
cmVAR
) ||
239
(
m_vRPN
[sz-1].Cmd ==
cmVAL
&&
m_vRPN
[sz-2].Cmd ==
cmVARMUL
) ||
240
(
m_vRPN
[sz-1].Cmd ==
cmVARMUL
&&
m_vRPN
[sz-2].Cmd ==
cmVAL
) ||
241
(
m_vRPN
[sz-1].Cmd ==
cmVAR
&&
m_vRPN
[sz-2].Cmd ==
cmVAR
&&
m_vRPN
[sz-2].Val.ptr ==
m_vRPN
[sz-1].Val.ptr) ||
242
(
m_vRPN
[sz-1].Cmd ==
cmVAR
&&
m_vRPN
[sz-2].Cmd ==
cmVARMUL
&&
m_vRPN
[sz-2].Val.ptr ==
m_vRPN
[sz-1].Val.ptr) ||
243
(
m_vRPN
[sz-1].Cmd ==
cmVARMUL
&&
m_vRPN
[sz-2].Cmd ==
cmVAR
&&
m_vRPN
[sz-2].Val.ptr ==
m_vRPN
[sz-1].Val.ptr) ||
244
(
m_vRPN
[sz-1].Cmd ==
cmVARMUL
&&
m_vRPN
[sz-2].Cmd ==
cmVARMUL
&&
m_vRPN
[sz-2].Val.ptr ==
m_vRPN
[sz-1].Val.ptr) )
245
{
246
assert( (
m_vRPN
[sz-2].Val.ptr==NULL &&
m_vRPN
[sz-1].Val.ptr!=NULL) ||
247
(
m_vRPN
[sz-2].Val.ptr!=NULL &&
m_vRPN
[sz-1].Val.ptr==NULL) ||
248
(
m_vRPN
[sz-2].Val.ptr ==
m_vRPN
[sz-1].Val.ptr) );
249
250
m_vRPN
[sz-2].Cmd =
cmVARMUL
;
251
m_vRPN
[sz-2].Val.ptr = (
value_type
*)((
long
long
)(
m_vRPN
[sz-2].Val.ptr) | (
long
long
)(
m_vRPN
[sz-1].Val.ptr));
// variable
252
m_vRPN
[sz-2].Val.data2 += ((a_Oprt==
cmSUB
) ? -1 : 1) *
m_vRPN
[sz-1].Val.data2;
// offset
253
m_vRPN
[sz-2].Val.data += ((a_Oprt==
cmSUB
) ? -1 : 1) *
m_vRPN
[sz-1].Val.data;
// multiplicand
254
m_vRPN
.pop_back();
255
bOptimized =
true
;
256
}
257
break
;
258
259
case
cmMUL
:
260
if
( (
m_vRPN
[sz-1].Cmd ==
cmVAR
&&
m_vRPN
[sz-2].Cmd ==
cmVAL
) ||
261
(
m_vRPN
[sz-1].Cmd ==
cmVAL
&&
m_vRPN
[sz-2].Cmd ==
cmVAR
) )
262
{
263
m_vRPN
[sz-2].Cmd =
cmVARMUL
;
264
m_vRPN
[sz-2].Val.ptr = (
value_type
*)((
long
long
)(
m_vRPN
[sz-2].Val.ptr) | (
long
long
)(
m_vRPN
[sz-1].Val.ptr));
265
m_vRPN
[sz-2].Val.data =
m_vRPN
[sz-2].Val.data2 +
m_vRPN
[sz-1].Val.data2;
266
m_vRPN
[sz-2].Val.data2 = 0;
267
m_vRPN
.pop_back();
268
bOptimized =
true
;
269
}
270
else
if
( (
m_vRPN
[sz-1].Cmd ==
cmVAL
&&
m_vRPN
[sz-2].Cmd ==
cmVARMUL
) ||
271
(
m_vRPN
[sz-1].Cmd ==
cmVARMUL
&&
m_vRPN
[sz-2].Cmd ==
cmVAL
) )
272
{
273
// Optimization: 2*(3*b+1) or (3*b+1)*2 -> 6*b+2
274
m_vRPN
[sz-2].Cmd =
cmVARMUL
;
275
m_vRPN
[sz-2].Val.ptr = (
value_type
*)((
long
long
)(
m_vRPN
[sz-2].Val.ptr) | (
long
long
)(
m_vRPN
[sz-1].Val.ptr));
276
if
(
m_vRPN
[sz-1].Cmd ==
cmVAL
)
277
{
278
m_vRPN
[sz-2].Val.data *=
m_vRPN
[sz-1].Val.data2;
279
m_vRPN
[sz-2].Val.data2 *=
m_vRPN
[sz-1].Val.data2;
280
}
281
else
282
{
283
m_vRPN
[sz-2].Val.data =
m_vRPN
[sz-1].Val.data *
m_vRPN
[sz-2].Val.data2;
284
m_vRPN
[sz-2].Val.data2 =
m_vRPN
[sz-1].Val.data2 *
m_vRPN
[sz-2].Val.data2;
285
}
286
m_vRPN
.pop_back();
287
bOptimized =
true
;
288
}
289
else
if
(
m_vRPN
[sz-1].Cmd ==
cmVAR
&&
m_vRPN
[sz-2].Cmd ==
cmVAR
&&
290
m_vRPN
[sz-1].Val.ptr ==
m_vRPN
[sz-2].Val.ptr)
291
{
292
// Optimization: a*a -> a^2
293
m_vRPN
[sz-2].Cmd =
cmVARPOW2
;
294
m_vRPN
.pop_back();
295
bOptimized =
true
;
296
}
297
break
;
298
299
case
cmDIV
:
300
if
(
m_vRPN
[sz-1].Cmd ==
cmVAL
&&
m_vRPN
[sz-2].Cmd ==
cmVARMUL
&&
m_vRPN
[sz-1].Val.data2!=0)
301
{
302
// Optimization: 4*a/2 -> 2*a
303
m_vRPN
[sz-2].Val.data /=
m_vRPN
[sz-1].Val.data2;
304
m_vRPN
[sz-2].Val.data2 /=
m_vRPN
[sz-1].Val.data2;
305
m_vRPN
.pop_back();
306
bOptimized =
true
;
307
}
308
break
;
309
default
:
310
// no optimization for other opcodes
311
break
;
312
}
// switch a_Oprt
313
}
314
}
315
316
// If optimization can't be applied just write the value
317
if
(!bOptimized)
318
{
319
--
m_iStackPos
;
320
SToken
tok;
321
tok.
Cmd
= a_Oprt;
322
m_vRPN
.push_back(tok);
323
}
324
}
325
326
//---------------------------------------------------------------------------
327
void
ParserByteCode::AddIfElse
(
ECmdCode
a_Oprt)
328
{
329
SToken
tok;
330
tok.
Cmd
= a_Oprt;
331
m_vRPN
.push_back(tok);
332
}
333
334
//---------------------------------------------------------------------------
345
void
ParserByteCode::AddAssignOp
(
value_type
*
a_pVar
)
346
{
347
--
m_iStackPos
;
348
349
SToken
tok;
350
tok.
Cmd
=
cmASSIGN
;
351
tok.
Oprt
.ptr =
a_pVar
;
352
m_vRPN
.push_back(tok);
353
}
354
355
//---------------------------------------------------------------------------
361
void
ParserByteCode::AddFun
(
generic_fun_type
a_pFun
,
int
a_iArgc)
362
{
363
if
(a_iArgc>=0)
364
{
365
m_iStackPos
=
m_iStackPos
- a_iArgc + 1;
366
}
367
else
368
{
369
// function with unlimited number of arguments
370
m_iStackPos
=
m_iStackPos
+ a_iArgc + 1;
371
}
372
m_iMaxStackSize
=
std::max
(
m_iMaxStackSize
, (
size_t
)
m_iStackPos
);
373
374
SToken
tok;
375
tok.
Cmd
=
cmFUNC
;
376
tok.
Fun
.argc = a_iArgc;
377
tok.
Fun
.ptr =
a_pFun
;
378
m_vRPN
.push_back(tok);
379
}
380
381
//---------------------------------------------------------------------------
387
void
ParserByteCode::AddBulkFun
(
generic_fun_type
a_pFun
,
int
a_iArgc)
388
{
389
m_iStackPos
=
m_iStackPos
- a_iArgc + 1;
390
m_iMaxStackSize
=
std::max
(
m_iMaxStackSize
, (
size_t
)
m_iStackPos
);
391
392
SToken
tok;
393
tok.
Cmd
=
cmFUNC_BULK
;
394
tok.
Fun
.argc = a_iArgc;
395
tok.
Fun
.ptr =
a_pFun
;
396
m_vRPN
.push_back(tok);
397
}
398
399
//---------------------------------------------------------------------------
407
void
ParserByteCode::AddStrFun
(
generic_fun_type
a_pFun
,
int
a_iArgc,
int
a_iIdx)
408
{
409
m_iStackPos
=
m_iStackPos
- a_iArgc + 1;
410
411
SToken
tok;
412
tok.
Cmd
=
cmFUNC_STR
;
413
tok.
Fun
.argc = a_iArgc;
414
tok.
Fun
.idx = a_iIdx;
415
tok.
Fun
.ptr =
a_pFun
;
416
m_vRPN
.push_back(tok);
417
418
m_iMaxStackSize
=
std::max
(
m_iMaxStackSize
, (
size_t
)
m_iStackPos
);
419
}
420
421
//---------------------------------------------------------------------------
426
void
ParserByteCode::Finalize
()
427
{
428
SToken
tok;
429
tok.
Cmd
=
cmEND
;
430
m_vRPN
.push_back(tok);
431
rpn_type
(
m_vRPN
).swap(
m_vRPN
);
// shrink bytecode vector to fit
432
433
// Determine the if-then-else jump offsets
434
ParserStack<int>
stIf, stElse;
435
int
idx;
436
for
(
int
i=0; i<(int)
m_vRPN
.size(); ++i)
437
{
438
switch
(
m_vRPN
[i].Cmd)
439
{
440
case
cmIF
:
441
stIf.
push
(i);
442
break
;
443
444
case
cmELSE
:
445
stElse.
push
(i);
446
idx = stIf.
pop
();
447
m_vRPN
[idx].Oprt.offset = i - idx;
448
break
;
449
450
case
cmENDIF
:
451
idx = stElse.
pop
();
452
m_vRPN
[idx].Oprt.offset = i - idx;
453
break
;
454
455
default
:
456
break
;
457
}
458
}
459
}
460
461
//---------------------------------------------------------------------------
462
const
SToken
*
ParserByteCode::GetBase
()
const
463
{
464
if
(
m_vRPN
.size()==0)
465
throw
ParserError
(
ecINTERNAL_ERROR
);
466
else
467
return
&
m_vRPN
[0];
468
}
469
470
//---------------------------------------------------------------------------
471
std::size_t
ParserByteCode::GetMaxStackSize
()
const
472
{
473
return
m_iMaxStackSize
+1;
474
}
475
476
//---------------------------------------------------------------------------
478
std::size_t
ParserByteCode::GetSize
()
const
479
{
480
return
m_vRPN
.size();
481
}
482
483
//---------------------------------------------------------------------------
492
void
ParserByteCode::clear
()
493
{
494
m_vRPN
.clear();
495
m_iStackPos
= 0;
496
m_iMaxStackSize
= 0;
497
}
498
499
//---------------------------------------------------------------------------
501
void
ParserByteCode::AsciiDump
()
502
{
503
if
(!
m_vRPN
.size())
504
{
505
mu::console
() <<
_T
(
"No bytecode available\n"
);
506
return
;
507
}
508
509
mu::console
() <<
_T
(
"Number of RPN tokens:"
) << (int)
m_vRPN
.size() <<
_T
(
"\n"
);
510
for
(std::size_t i=0; i<
m_vRPN
.size() &&
m_vRPN
[i].Cmd!=
cmEND
; ++i)
511
{
512
mu::console
() << std::dec << i <<
_T
(
" : \t"
);
513
switch
(
m_vRPN
[i].Cmd)
514
{
515
case
cmVAL
:
mu::console
() <<
_T
(
"VAL \t"
);
516
mu::console
() <<
_T
(
"["
) <<
m_vRPN
[i].Val.data2 <<
_T
(
"]\n"
);
517
break
;
518
519
case
cmVAR
:
mu::console
() <<
_T
(
"VAR \t"
);
520
mu::console
() <<
_T
(
"[ADDR: 0x"
) << std::hex <<
m_vRPN
[i].Val.ptr <<
_T
(
"]\n"
);
521
break
;
522
523
case
cmVARPOW2
:
mu::console
() <<
_T
(
"VARPOW2 \t"
);
524
mu::console
() <<
_T
(
"[ADDR: 0x"
) << std::hex <<
m_vRPN
[i].Val.ptr <<
_T
(
"]\n"
);
525
break
;
526
527
case
cmVARPOW3
:
mu::console
() <<
_T
(
"VARPOW3 \t"
);
528
mu::console
() <<
_T
(
"[ADDR: 0x"
) << std::hex <<
m_vRPN
[i].Val.ptr <<
_T
(
"]\n"
);
529
break
;
530
531
case
cmVARPOW4
:
mu::console
() <<
_T
(
"VARPOW4 \t"
);
532
mu::console
() <<
_T
(
"[ADDR: 0x"
) << std::hex <<
m_vRPN
[i].Val.ptr <<
_T
(
"]\n"
);
533
break
;
534
535
case
cmVARMUL
:
mu::console
() <<
_T
(
"VARMUL \t"
);
536
mu::console
() <<
_T
(
"[ADDR: 0x"
) << std::hex <<
m_vRPN
[i].Val.ptr <<
_T
(
"]"
);
537
mu::console
() <<
_T
(
" * ["
) <<
m_vRPN
[i].Val.data <<
_T
(
"]"
);
538
mu::console
() <<
_T
(
" + ["
) <<
m_vRPN
[i].Val.data2 <<
_T
(
"]\n"
);
539
break
;
540
541
case
cmFUNC
:
mu::console
() <<
_T
(
"CALL\t"
);
542
mu::console
() <<
_T
(
"[ARG:"
) << std::dec <<
m_vRPN
[i].Fun.argc <<
_T
(
"]"
);
543
mu::console
() <<
_T
(
"[ADDR: 0x"
) << std::hex <<
m_vRPN
[i].Fun.ptr <<
_T
(
"]"
);
544
mu::console
() <<
_T
(
"\n"
);
545
break
;
546
547
case
cmFUNC_STR
:
548
mu::console
() <<
_T
(
"CALL STRFUNC\t"
);
549
mu::console
() <<
_T
(
"[ARG:"
) << std::dec <<
m_vRPN
[i].Fun.argc <<
_T
(
"]"
);
550
mu::console
() <<
_T
(
"[IDX:"
) << std::dec <<
m_vRPN
[i].Fun.idx <<
_T
(
"]"
);
551
mu::console
() <<
_T
(
"[ADDR: 0x"
) <<
m_vRPN
[i].Fun.ptr <<
_T
(
"]\n"
);
552
break
;
553
554
case
cmLT
:
mu::console
() <<
_T
(
"LT\n"
);
break
;
555
case
cmGT
:
mu::console
() <<
_T
(
"GT\n"
);
break
;
556
case
cmLE
:
mu::console
() <<
_T
(
"LE\n"
);
break
;
557
case
cmGE
:
mu::console
() <<
_T
(
"GE\n"
);
break
;
558
case
cmEQ
:
mu::console
() <<
_T
(
"EQ\n"
);
break
;
559
case
cmNEQ
:
mu::console
() <<
_T
(
"NEQ\n"
);
break
;
560
case
cmADD
:
mu::console
() <<
_T
(
"ADD\n"
);
break
;
561
case
cmLAND
:
mu::console
() <<
_T
(
"&&\n"
);
break
;
562
case
cmLOR
:
mu::console
() <<
_T
(
"||\n"
);
break
;
563
case
cmSUB
:
mu::console
() <<
_T
(
"SUB\n"
);
break
;
564
case
cmMUL
:
mu::console
() <<
_T
(
"MUL\n"
);
break
;
565
case
cmDIV
:
mu::console
() <<
_T
(
"DIV\n"
);
break
;
566
case
cmPOW
:
mu::console
() <<
_T
(
"POW\n"
);
break
;
567
568
case
cmIF
:
mu::console
() <<
_T
(
"IF\t"
);
569
mu::console
() <<
_T
(
"[OFFSET:"
) << std::dec <<
m_vRPN
[i].Oprt.offset <<
_T
(
"]\n"
);
570
break
;
571
572
case
cmELSE
:
mu::console
() <<
_T
(
"ELSE\t"
);
573
mu::console
() <<
_T
(
"[OFFSET:"
) << std::dec <<
m_vRPN
[i].Oprt.offset <<
_T
(
"]\n"
);
574
break
;
575
576
case
cmENDIF
:
mu::console
() <<
_T
(
"ENDIF\n"
);
break
;
577
578
case
cmASSIGN
:
579
mu::console
() <<
_T
(
"ASSIGN\t"
);
580
mu::console
() <<
_T
(
"[ADDR: 0x"
) <<
m_vRPN
[i].Oprt.ptr <<
_T
(
"]\n"
);
581
break
;
582
583
default
:
mu::console
() <<
_T
(
"(unknown code: "
) <<
m_vRPN
[i].Cmd <<
_T
(
")\n"
);
584
break
;
585
}
// switch cmdCode
586
}
// while bytecode
587
588
mu::console
() <<
_T
(
"END"
) << std::endl;
589
}
590
}
// namespace mu
muparser
src
muParserBytecode.cpp
Generated on Fri Sep 11 2020 14:30:14 for OpcUaCanOpen by
1.8.14