A simple expression parser based on a version I wrote over 20 years ago in Z80 assembly.
It uses one stack for the values and other for the operators.
It is appropriated for the PICs because it doesn't use recursion.
//============================================================================== /* Copyright (c) 2009, Isaac Marino Bavaresco All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ //============================================================================== // isaacbavaresco@yahoo.com.br //============================================================================== // Vers 1.04 2009/05/07 Almost done, lacks parsing of float values. //============================================================================== #include <stdio.h> #include <ctype.h> //============================================================================== #ifndef _PIC14 #define bank1 #define bank2 #else #include <pic.h> #endif //============================================================================== // These are the data types one may chose from // One-byte integer values, from 0 to 255 or from -128 to 127 #define TYPE_CHAR 0 // Two-byte integer values, from 0 to 65535 or from -32768 to 32767 #define TYPE_SHORT 1 // Four-byte integer values, from 0 to 4294967296 or from -2147483648 to 2147483647 #define TYPE_LONG 2 // Three-byte floating point values #define TYPE_FLOAT 3 // Four-byte floating point values #define TYPE_DOUBLE 4 //============================================================================== //============================================================================== //============================================================================== //============================================================================== // Chose the data type you want to use for the calculations #define DATA_TYPE TYPE_SHORT // How many variables you wanto to use #define NUMBER_OF_VARIABLES (10) // Depth of the stack for the calculations. More complicated expressions need more levels #define VAL_STACK_DEPTH (10) #define OPER_STACK_DEPTH (10) // Chose which groups of operators you want to use ( 0 = disabled, 1 = enabled ) // Note: disabling groups will save program memory. // Multiplicative operators: '*', '/', '%' #define INCLUDE_MULT 1 // Aditive operators: '+', '-' #define INCLUDE_ADD 1 // Shift operators: '<<', '>>' #define INCLUDE_SHIFT 1 // Binary boolean operators: '&', '^', '|', '~' #define INCLUDE_BOOLEAN 1 // Relational operators: '<', '<=', '=', '==', '>=', '>', '<>', '!=' #define INCLUDE_RELATIONAL 1 // Logical operators: '&&', '||', '!' #define INCLUDE_LOGICAL 1 //============================================================================== //============================================================================== //============================================================================== //============================================================================== #if DATA_TYPE == TYPE_CHAR #define BASE_TYPE char #define INT_EQUIV_TYPE char #elif DATA_TYPE == TYPE_SHORT #define BASE_TYPE short #define INT_EQUIV_TYPE short #elif DATA_TYPE == TYPE_LONG #define BASE_TYPE long #define INT_EQUIV_TYPE long #elif DATA_TYPE == TYPE_FLOAT #define BASE_TYPE float #define INT_EQUIV_TYPE long #elif DATA_TYPE == TYPE_DOUBLE #define BASE_TYPE double #define INT_EQUIV_TYPE long #else #error "No valid type defined!" #endif //============================================================================== bank1 unsigned short OPStack[OPER_STACK_DEPTH]; bank1 BASE_TYPE VLStack[VAL_STACK_DEPTH]; #if NUMBER_OF_VARIABLES > 0 // Variables from 'a' to 'j' with some arbitrary values for testing purposes... bank2 BASE_TYPE Vars[NUMBER_OF_VARIABLES] = { 10, 15, 30, 50, 100, -1, -2, 1000, 1, 0 }; #endif // NUMBER_OF_VARIABLES > 0 //============================================================================== #define OPCODE(c) ((unsigned char)(c)) #define PRECEDENCE(c) ((unsigned char)((c)>>8)) #define PUSH_VAL(v) (VLStack[VLPtr++]=(v)) #define POP_VAL() (VLStack[--VLPtr]) #define PUSH_OP(v) (OPStack[OPPtr++]=(v)) #define POP_OP() (OPStack[--OPPtr]) #define PEEK_OP() (OPStack[OPPtr-1]) //============================================================================== #define TOKEN_INVALID (0) #define TOKEN_VALUE (1) #define TOKEN_OPER (2) //============================================================================== #define OPER_OPEN (0x0218) /* Open parenthesis */ #define OPER_CLOSE (0x0317) /* Close parenthesis */ #define OPER_CPL (0x0e16) /* Unary boolean complement */ #define OPER_NOT (0x0e15) /* Unary logical complement */ #define OPER_NEG (0x0e14) /* Unary negation (change signal) */ #define OPER_MUL (0x0d01) /* Multiplication */ #define OPER_DIV (0x0d02) /* Division */ #define OPER_MOD (0x0d03) /* Modulus (division remainder) */ #define OPER_ADD (0x0c04) /* Addition */ #define OPER_SUB (0x0c05) /* Subtraction */ #define OPER_LSL (0x0b06) /* Logical shift left */ #define OPER_LSR (0x0b07) /* Logical shift right */ #define OPER_ANDB (0x0a08) /* Boolean AND */ #define OPER_XOR (0x0909) /* Boolean XOR */ #define OPER_ORB (0x080a) /* Boolean OR */ #define OPER_LT (0x070b) /* Less than */ #define OPER_LE (0x070c) /* Less or equal */ #define OPER_GE (0x070d) /* Greater or equal */ #define OPER_GT (0x070e) /* Greater than */ #define OPER_EQ (0x060f) /* Equality */ #define OPER_NE (0x0610) /* Inequality */ #define OPER_ANDL (0x0511) /* Logical AND */ #define OPER_ORL (0x0412) /* Logical OR */ #define OPER_START (0x0113) /* Start of expression */ #define OPER_EOL (0x0000) /* End of expression */ //============================================================================== typedef union { BASE_TYPE val; unsigned short op; } TS_Token; //============================================================================== unsigned char GetToken( const unsigned char **p, TS_Token *v ) { const unsigned char *q; BASE_TYPE val; unsigned char c; unsigned short op; q = *p; while( isspace( c = *q )) q++; if( c == 0 ) { v->op = OPER_EOL; return TOKEN_OPER; } #if NUMBER_OF_VARIABLES > 0 // Not the right place to get the variables values, but makes things easier... else if( isalpha( c )) { c = tolower( c ); if( c >= 'a' && c <= 'a' + NUMBER_OF_VARIABLES - 1 ) { q++; if( isalnum( *q )) return TOKEN_INVALID; v->val = Vars[c-'a']; *p = q; return TOKEN_VALUE; } return TOKEN_INVALID; } #endif // NUMBER_OF_VARIABLES > 0 else if( isdigit( c )) // TODO: Parse float numbers { val = 0; while( isdigit( c = *q )) { val *= 10; val += c - '0'; q++; } v->val = val; *p = q; return TOKEN_VALUE; } switch( c ) { case '(': op = OPER_OPEN; q++; break; case ')': op = OPER_CLOSE; q++; break; #if INCLUDE_MULT == 1 case '*': op = OPER_MUL; q++; break; case '/': op = OPER_DIV; q++; break; case '%': op = OPER_MOD; q++; break; #endif // INCLUDE_MULT == 1 #if INCLUDE_ADD == 1 case '+': op = OPER_ADD; q++; break; case '-': op = OPER_SUB; q++; break; #endif // INCLUDE_ADD == 1 #if INCLUDE_BOOLEAN == 1 || INCLUDE_LOGICAL == 1 case '&': q++; #if INCLUDE_LOGICAL == 1 if( *q == '&' ) { op = OPER_ANDL; q++; } else #endif // INCLUDE_LOGICAL == 1 #if INCLUDE_BOOLEAN == 1 op = OPER_ANDB; #else // INCLUDE_BOOLEAN == 1 return TOKEN_INVALID; #endif // INCLUDE_BOOLEAN == 1 break; case '|': q++; #if INCLUDE_LOGICAL == 1 if( *q == '|' ) { op = OPER_ORL; q++; } else #endif // INCLUDE_LOGICAL == 1 #if INCLUDE_BOOLEAN == 1 op = OPER_ORB; #else // INCLUDE_BOOLEAN == 1 return TOKEN_INVALID; #endif // INCLUDE_BOOLEAN == 1 break; #endif // INCLUDE_BOOLEAN == 1 || INCLUDE_LOGICAL == 1 #if INCLUDE_BOOLEAN == 1 case '~': op = OPER_CPL; q++; break; case '^': op = OPER_XOR; q++; break; #endif // INCLUDE_BOOLEAN == 1 #if INCLUDE_RELATIONAL == 1 || INCLUDE_SHIFT == 1 case '<': q++; #if INCLUDE_RELATIONAL == 1 if( *q == '=' ) { op = OPER_LE; q++; } else if( *q == '>' ) { op = OPER_NE; q++; } else #endif // INCLUDE_RELATIONAL == 1 #if INCLUDE_SHIFT == 1 if( *q == '<' ) { op = OPER_LSL; q++; } else #endif // INCLUDE_SHIFT == 1 #if INCLUDE_RELATIONAL == 1 op = OPER_LT; #else // INCLUDE_RELATIONAL == 1 return TOKEN_INVALID; #endif // INCLUDE_RELATIONAL == 1 break; case '>': q++; #if INCLUDE_RELATIONAL == 1 if( *q == '=' ) { op = OPER_GE; q++; } else #endif // INCLUDE_RELATIONAL == 1 #if INCLUDE_SHIFT == 1 if( *q == '>' ) { op = OPER_LSR; q++; } else #endif // INCLUDE_SHIFT == 1 #if INCLUDE_RELATIONAL == 1 op = OPER_GT; #else // INCLUDE_RELATIONAL == 1 return TOKEN_INVALID; #endif // INCLUDE_RELATIONAL == 1 break; #endif // INCLUDE_RELATIONAL == 1 || INCLUDE_SHIFT == 1 #if INCLUDE_RELATIONAL == 1 case '=': q++; if( *q == '=' ) q++; op = OPER_EQ; break; #endif // INCLUDE_RELATIONAL == 1 #if INCLUDE_RELATIONAL == 1 || INCLUDE_BOOLEAN == 1 case '!': q++; #if INCLUDE_RELATIONAL == 1 if( *q == '=' ) { op = OPER_NE; q++; } else #endif // INCLUDE_RELATIONAL == 1 #if INCLUDE_BOOLEAN == 1 op = OPER_NOT; #else // INCLUDE_BOOLEAN == 1 return TOKEN_INVALID; #endif // INCLUDE_BOOLEAN == 1 break; #endif // INCLUDE_RELATIONAL == 1 || INCLUDE_BOOLEAN == 1 default: return TOKEN_INVALID; } v->op = op; *p = q; return TOKEN_OPER; } //============================================================================== unsigned char Eval( const unsigned char *s, BASE_TYPE *result ) { unsigned char OPPtr = 0; unsigned char VLPtr = 0; BASE_TYPE a, b; unsigned char c, t; #if DATA_TYPE == TYPE_FLOAT INT_EQUIV_TYPE d, e; #elif DATA_TYPE == TYPE_DOUBLE INT_EQUIV_TYPE d; #endif // DATA_TYPE == TYPE_FLOAT TS_Token v; VLPtr = 0; OPPtr = 0; PUSH_OP( OPER_START ); while( 1 ) { do { t = GetToken( &s, &v ); if( t == TOKEN_VALUE ) { // Stack overflow... if( VLPtr >= sizeof VLStack / sizeof VLStack[0] ) return -1; PUSH_VAL( v.val ); } else if( t == TOKEN_OPER ) { // Stack overflow... if( OPPtr >= sizeof OPStack / sizeof OPStack[0] ) return -1; if( v.op == OPER_OPEN ) PUSH_OP( OPER_OPEN ); else #if INCLUDE_ADD == 1 // Unary minus if( v.op == OPER_SUB ) PUSH_OP( OPER_NEG ); // Unary plus else if( v.op == OPER_ADD ) {} // Do nothing else #endif // INCLUDE_ADD == 1 #if INCLUDE_LOGICAL == 1 || INCLUDE_BOOLEAN == 1 #if INCLUDE_LOGICAL != 1 if( v.op == OPER_CPL ) #elif INCLUDE_BOOLEAN != 1 if( v.op == OPER_NOT ) #else // INCLUDE_BOOLEAN != 1 if( v.op == OPER_NOT || v.op == OPER_CPL ) #endif // INCLUDE_LOGICAL != 1 PUSH_OP( v.op ); else #endif // INCLUDE_LOGICAL == 1 || INCLUDE_BOOLEAN == 1 return -1; } else return -1; } while( t != TOKEN_VALUE ); NextOper: if( GetToken( &s, &v ) != TOKEN_OPER ) return -1; while( PRECEDENCE( v.op ) <= PRECEDENCE( PEEK_OP() )) { if( v.op == OPER_EOL && VLPtr == 1 && OPPtr == 1 ) { *result = POP_VAL(); return 0; } // Stack underflow... if( VLPtr < 1 || OPPtr < 2 ) return -1; #if INCLUDE_ADD == 1 if( OPCODE( PEEK_OP() ) == OPCODE( OPER_NEG )) { POP_OP(); b = -POP_VAL(); } else #endif // INCLUDE_ADD == 1 #if INCLUDE_LOGICAL == 1 if( OPCODE( PEEK_OP() ) == OPCODE( OPER_NOT )) { POP_OP(); b = !POP_VAL(); } else #endif // INCLUDE_LOGICAL == 1 #if INCLUDE_BOOLEAN == 1 if( OPCODE( PEEK_OP() ) == OPCODE( OPER_CPL )) { POP_OP(); b = ~(INT_EQUIV_TYPE)POP_VAL(); } else #endif // INCLUDE_BOOLEAN == 1 { // Stack underflow... if( VLPtr < 2 ) return -1; a = POP_VAL(); b = POP_VAL(); switch( OPCODE( POP_OP() )) { #if INCLUDE_MULT == 1 case OPCODE( OPER_MUL ): b *= a; break; case OPCODE( OPER_DIV ): b /= a; break; #endif // INCLUDE_MULT == 1 #if INCLUDE_ADD == 1 case OPCODE( OPER_ADD ): b += a; break; case OPCODE( OPER_SUB ): b -= a; break; #endif // INCLUDE_ADD == 1 #if DATA_TYPE == TYPE_DOUBLE #if INCLUDE_MULT == 1 case OPCODE( OPER_MOD ): d = (INT_EQUIV_TYPE)b % (INT_EQUIV_TYPE)a; b = d; break; #endif // INCLUDE_MULT == 1 #if INCLUDE_SHIFT == 1 case OPCODE( OPER_LSL ): c = (char)a; // Must split this operation or PICC can't generate code b = (INT_EQUIV_TYPE)b << c; break; case OPCODE( OPER_LSR ): c = (char)a; // Must split this operation or PICC can't generate code b = (unsigned INT_EQUIV_TYPE)b >> c; break; #endif // INCLUDE_SHIFT == 1 #if INCLUDE_BOOLEAN == 1 case OPCODE( OPER_ANDB ): b = (INT_EQUIV_TYPE)b & (INT_EQUIV_TYPE)a; break; case OPCODE( OPER_XOR ): b = (INT_EQUIV_TYPE)b ^ (INT_EQUIV_TYPE)a; break; case OPCODE( OPER_ORB ): b = (INT_EQUIV_TYPE)b | (INT_EQUIV_TYPE)a; break; #endif // INCLUDE_BOOLEAN == 1 #elif DATA_TYPE == TYPE_FLOAT #if INCLUDE_MULT == 1 case OPCODE( OPER_MOD ): d = (INT_EQUIV_TYPE)a; d = (INT_EQUIV_TYPE)b & d; b = d; break; #endif // INCLUDE_MULT == 1 #if INCLUDE_SHIFT == 1 case OPCODE( OPER_LSL ): c = (char)a; d = (INT_EQUIV_TYPE)b; // Must split this operation or PICC can't generate code d = d << c; b = d; break; case OPCODE( OPER_LSR ): c = (char)a; d = (unsigned INT_EQUIV_TYPE)b; // Must split this operation or PICC can't generate code b = d >> c; break; #endif // INCLUDE_SHIFT == 1 #if INCLUDE_BOOLEAN == 1 case OPCODE( OPER_ANDB ): d = (INT_EQUIV_TYPE)b; b = d & (INT_EQUIV_TYPE)a; break; case OPCODE( OPER_XOR ): d = (INT_EQUIV_TYPE)b; b = d ^ (INT_EQUIV_TYPE)a; break; case OPCODE( OPER_ORB ): d = (INT_EQUIV_TYPE)b; b = d | (INT_EQUIV_TYPE)a; break; #endif // INCLUDE_BOOLEAN == 1 #else // DATA_TYPE == TYPE_FLOAT #if INCLUDE_MULT == 1 case OPCODE( OPER_MOD ): b = b % a; break; #endif // INCLUDE_MULT == 1 #if INCLUDE_SHIFT == 1 case OPCODE( OPER_LSL ): b = b << a; break; case OPCODE( OPER_LSR ): b = (unsigned INT_EQUIV_TYPE)b >> a; break; #endif // INCLUDE_SHIFT == 1 #if INCLUDE_BOOLEAN == 1 case OPCODE( OPER_ANDB ): b = b & a; break; case OPCODE( OPER_XOR ): b = b ^ a; break; case OPCODE( OPER_ORB ): b = b | a; break; #endif // INCLUDE_BOOLEAN == 1 #endif // DATA_TYPE == TYPE_DOUBLE #if INCLUDE_RELATIONAL == 1 case OPCODE( OPER_LT ): b = b < a; break; case OPCODE( OPER_LE ): b = b <= a; break; case OPCODE( OPER_GE ): b = b >= a; break; case OPCODE( OPER_GT ): b = b > a; break; case OPCODE( OPER_EQ ): b = b == a; break; case OPCODE( OPER_NE ): b = b != a; break; #endif // INCLUDE_RELATIONAL == 1 #if INCLUDE_LOGICAL == 1 case OPCODE( OPER_ANDL ): b = a && b; break; case OPCODE( OPER_ORL ): b = a || b; break; #endif // INCLUDE_LOGICAL == 1 // Something very wrong happened... default: return -1; } } PUSH_VAL( b ); } // We have found a close parenthesis if( OPCODE( v.op ) == OPCODE( OPER_CLOSE )) { if( OPCODE( PEEK_OP() ) == OPCODE( OPER_OPEN )) { POP_OP(); // OK, ugly but the easyest way to handle this. goto NextOper; } else return -1; } else { if( OPPtr >= sizeof OPStack / sizeof OPStack[0] ) return -1; PUSH_OP( v.op ); } } return -1; } //============================================================================== #ifdef _PIC14 // The library functions need a 'putch' to work void putch( char c ) { // Wait until the USART transmits the previous character while( !TXIF ) CLRWDT(); // Send the character TXREG = c; } /*============================================================================*/ unsigned short TMR1U; void interrupt ISR( void ) { if( TMR1IE && TMR1IF ) { TMR1IF = 0; TMR1U++; } else { GIE = 0; } } /*============================================================================*/ void StartTimer( void ) { TMR1ON = 0; TMR1L = 0; TMR1H = 0; /* TMR1U = 0; */ TMR1IF = 0; TMR1IE = 1; TMR1ON = 1; } /*============================================================================*/ unsigned short ReadTimer( void ) { TMR1ON = 0; /* return (unsigned long)TMR1U << 16 | TMR1H << 8 | TMR1L; */ return TMR1H << 8 | TMR1L; } #else // _PIC14 void StartTimer( void ) { } unsigned long ReadTimer( void ) { return 0; } #endif // _PIC14 /*============================================================================*/ #if DATA_TYPE == TYPE_FLOAT || DATA_TYPE == TYPE_DOUBLE #define FORMAT "%20s\t = %12f" #elif DATA_TYPE == TYPE_LONG #define FORMAT "%20s\t = %12ld" #else // DATA_TYPE == TYPE_LONG #define FORMAT "%20s\t = %12d" #endif // DATA_TYPE == TYPE_FLOAT || DATA_TYPE == TYPE_DOUBLE const char * const Expressions[] = { "()", "-(1)", "(-1)", "(((1+2)))", "(", ")", "1(", "(1", ")1", "1)", "(-1)", "((1<<2)+3)*3", "(1<<2+3)*3", "(1+2)*(2+3)", "1", "A", "+1", "-1", "~0", "~-1", "!1", "!0", "3*5", "30/5", "5%3", "3+5", "3-5", "1<<3", "8>>3", "65535&255", "65535^255", "65280|255", "1<2 ", "2<1", "1<=2", "1=2", "1=1", "1==1", "1!=1", "1!=2", "1>=2", "2>=1", "2>1", "2>2", "1!=1", "1!=2", "1<>1", "1<>2", "1<2&&4>3", "1>2&&4>3", "1<2&&4<3", "1>2&&4<3", "1<2||4>3", "1>2||4>3", "1<2||4<3", "1>2||4<3", "100+100/3" }; /* "100 + 100 / c", "100 + 100 / 3", "A * b + C / d", "-A", "b * -c", "1 +* 2", "! 1", "! 0", "~ 0", "~ -1", "X" }; */ void main( void ) { unsigned short t; BASE_TYPE Val; char i, status; // Initialize port pins CMCON = 0x07; PORTB = 0x04; TRISB = 0x02; // Initialize USART SPBRG = 16; TXSTA = 0x24; RCSTA = 0x90; T1CON = 0x00; INTCON = 0xc0; while( 1 ) { CLRWDT(); for( i = 0; i < sizeof Expressions / sizeof Expressions[0]; i++ ) { StartTimer(); status = Eval( Expressions[i], &Val ); t = ReadTimer(); if( status ) { printf( "Error: %20s", Expressions[i] ); printf( "\t(%u tcy)\n", t ); } else { printf( FORMAT, Expressions[i], Val); printf( "\t(%u tcy)\n", t ); } } } } //==============================================================================
Sample output for DATA_TYPE == TYPE_SHORT:
1|356<<2+3/2 = 2849 (4105 tcy) ((((1|356)<<2)+3)/2) = 715 (5685 tcy) Error: " ()" (451 tcy) -(1) = -1 (1204 tcy) (-1) = -1 (1200 tcy) (((1+2))) = 3 (2382 tcy) Error: " (" (367 tcy) Error: " )" (259 tcy) Error: " 1(" (717 tcy) Error: " (1" (735 tcy) Error: " )1" (259 tcy) Error: " 1)" (587 tcy) (-1) = -1 (1200 tcy) ((1<<2)+3)*3 = 21 (3524 tcy) (1<<2+3)*3 = 96 (3150 tcy) (1+2)*(2+3) = 15 (3432 tcy) 1 = 1 (519 tcy) A = 10 (423 tcy) +1 = 1 (726 tcy) -1 = -1 (812 tcy) ~0 = -1 (868 tcy) ~-1 = 0 (1161 tcy) !1 = 0 (840 tcy) !0 = 1 (840 tcy) 3*5 = 15 (1274 tcy) 30/5 = 6 (1722 tcy) 5%3 = 2 (1573 tcy) 3+5 = 8 (1208 tcy) 3-5 = -2 (1209 tcy) 1<<3 = 8 (1320 tcy) 8>>3 = 1 (1306 tcy) 65535&255 = 255 (2084 tcy) 65535^255 = -256 (2085 tcy) 65280|255 = -1 (2114 tcy) 1<2 = 1 (1358 tcy) 2<1 = 0 (1315 tcy) 1<=2 = 1 (1262 tcy) 1=2 = 0 (1254 tcy) 1=1 = 1 (1254 tcy) 1==1 = 1 (1254 tcy) 1!=1 = 0 (1223 tcy) 1!=2 = 1 (1223 tcy) 1>=2 = 0 (1264 tcy) 2>=1 = 1 (1264 tcy) 2>1 = 1 (1290 tcy) 2>2 = 0 (1290 tcy) 1!=1 = 0 (1223 tcy) 1!=2 = 1 (1223 tcy) 1<>1 = 0 (1279 tcy) 1<>2 = 1 (1279 tcy) 1<2&&4>3 = 1 (2800 tcy) 1>2&&4>3 = 0 (2774 tcy) 1<2&&4<3 = 0 (2818 tcy) 1>2&&4<3 = 0 (2793 tcy) 1<2||4>3 = 1 (2825 tcy) 1>2||4>3 = 1 (2800 tcy) 1<2||4<3 = 1 (2853 tcy) 1>2||4<3 = 0 (2827 tcy) 100+100/3 = 133 (2866 tcy)
Sample output for DATA_TYPE == TYPE_DOUBLE:
1|356<<2+3/2 = 2849.000000 (12801 tcy) ((((1|356)<<2)+3)/2) = 715.500000 (14508 tcy) Error: " ()" (453 tcy) -(1) = -1.000000 (2135 tcy) (-1) = -1.000000 (2131 tcy) (((1+2))) = 3.000000 (4351 tcy) Error: " (" (369 tcy) Error: " )" (260 tcy) Error: " 1(" (1598 tcy) Error: " (1" (1617 tcy) Error: " )1" (260 tcy) Error: " 1)" (1467 tcy) (-1) = -1.000000 (2131 tcy) ((1<<2)+3)*3 = 21.000000 (8697 tcy) (1<<2+3)*3 = 96.000000 (8274 tcy) (1+2)*(2+3) = 15.000000 (7977 tcy) 1 = 1.000000 (1415 tcy) A = 10.000000 (467 tcy) +1 = 1.000000 (1623 tcy) -1 = -1.000000 (1741 tcy) ~0 = -1.000000 (1865 tcy) ~-1 = 0.000000 (2391 tcy) !1 = 0.000000 (1810 tcy) !0 = 1.000000 (1802 tcy) 3*5 = 15.000000 (3651 tcy) 30/5 = 6.000000 (4982 tcy) 5%3 = 2.000000 (4950 tcy) 3+5 = 8.000000 (3172 tcy) 3-5 = -2.000000 (3192 tcy) 1<<3 = 8.000000 (3872 tcy) 8>>3 = 1.000000 (3824 tcy) 65535&255 = 255.000000 (10813 tcy) 65535^255 = 65280.000000 (10726 tcy) 65280|255 = 65535.000000 (10297 tcy) 1<2 = 1.000000 (3513 tcy) 2<1 = 0.000000 (3210 tcy) 1<=2 = 1.000000 (3417 tcy) 1=2 = 0.000000 (3119 tcy) 1=1 = 1.000000 (3399 tcy) 1==1 = 1.000000 (3399 tcy) 1!=1 = 0.000000 (3108 tcy) 1!=2 = 1.000000 (3348 tcy) 1>=2 = 0.000000 (3159 tcy) 2>=1 = 1.000000 (3419 tcy) 2>1 = 1.000000 (3445 tcy) 2>2 = 0.000000 (3178 tcy) 1!=1 = 0.000000 (3108 tcy) 1!=2 = 1.000000 (3348 tcy) 1<>1 = 0.000000 (3164 tcy) 1<>2 = 1.000000 (3404 tcy) 1<2&&4>3 = 1.000000 (7439 tcy) 1>2&&4>3 = 0.000000 (6893 tcy) 1<2&&4<3 = 0.000000 (6935 tcy) 1>2&&4<3 = 0.000000 (6650 tcy) 1<2||4>3 = 1.000000 (7462 tcy) 1>2||4>3 = 1.000000 (7177 tcy) 1<2||4<3 = 1.000000 (7232 tcy) 1>2||4<3 = 0.000000 (6686 tcy) 100+100/3 = 133.333328 (9586 tcy)