// ===================================================================================================================================== // allen_cpu_lib_comparisons.c - Allen version 2.0 // ===================================================================================================================================== // // This file is part of the Allen Library. // Last modified: Saturday July 14, 2007. // // Copyright (c) 2007, Archville, BSD License. // A copy can be found here: http://www.opensource.org/licenses/bsd-license.php // Initally based on Salvatore Sanfilippo within Picol 0.1.0 // // 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. // * Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // * Neither the name of the Garabatos de licor 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 copyright holders and contributors // "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 copyright owner or // contributors 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. // ===================================================================================================================================== // Include libraries. // ===================================================================================================================================== #include // Standard input/output. #include // Standard C libraries. #include // String libraries. #include // Math libraries. #include // Types and conversion libraries. #include "allen_interpreter.h" // Main interpreter library. #include "allen_parser.h" // Main parser library. // ===================================================================================================================================== // Parameters. // ===================================================================================================================================== #define TLIB_CMP_BSIZE 1024 // Buffer size. // ===================================================================================================================================== // Possible errors. // ===================================================================================================================================== #define TLIB_CMP_EHLP "cmp.?: command not found in library" // Error: Command not found in comparisons library. // ===================================================================================================================================== // Tokens. // ===================================================================================================================================== #define TLIB_CMP_GT ">" // Greater. #define TLIB_CMP_GTLT "->" // Ordered mayor/minor. (restrictive) #define TLIB_CMP_GTEQLT "+>" // Ordered mayor/minor. (non restrictive) #define TLIB_CMP_LT "<" // Lesser. #define TLIB_CMP_LTGT "<-" // Ordered minor/major. (restrictive) #define TLIB_CMP_LTEQGT "<+" // Ordered minor/major. (non restrictive) #define TLIB_CMP_EQ "=" // Equal. #define TLIB_CMP_NQ "!" // Not equal. #define TLIB_CMP_GEQ "=>" // Greater or equal. #define TLIB_CMP_LEQ "<=" // Less or equal. // ===================================================================================================================================== // Helper Function. // ===================================================================================================================================== #define TLIB_CMP_HLP "cmp.?" // Helper function. #define TLIB_CMP_NIL "nil" // Null value. // ===================================================================================================================================== // Basic comparison operators. // ===================================================================================================================================== // Allows to perform regular comparison operations on value lists // and return results based on their expresions. // Index: Example: Result: // AllenVM_CPU_LIB_CMP_GT(); :: > 10 2 1.000000 // AllenVM_CPU_LIB_CMP_GTLT(); :: -> 1 2 3 0.000000 // AllenVM_CPU_LIB_CMP_GTEQLT(); :: +> 3 2 2 1.000000 // AllenVM_CPU_LIB_CMP_LT(); :: < 20 1 0.000000 // AllenVM_CPU_LIB_CMP_LTGT(); :: <- 1 2 3 1.000000 // AllenVM_CPU_LIB_CMP_LTEQGT(); :: <+ 2 2 3 1.000000 // AllenVM_CPU_LIB_CMP_EQ(); :: = 4 4 1.000000 // AllenVM_CPU_LIB_CMP_NQ(); :: ! 2 3 1.000000 // AllenVM_CPU_LIB_CMP_GEQ(); :: => 10 1 1.000000 // AllenVM_CPU_LIB_CMP_LEQ(); :: <= 2 2 1.000000 // Total: 10. // ------------------------------------------------------------------------------------------------------------------------------------- // Function: AllenVM_CPU_LIB_CMP_GT(); // Purpose: Greater than. // Returns: 0/1 wether false/true. // ------------------------------------------------------------------------------------------------------------------------------------- static int AllenVM_CPU_LIB_CMP_GT(struct AllenInterp *i, int argc, char **argv, void *pd) { if(argc < 3) return AllenVM_CPU_Error(i,argv[0]); // Check parameters. register int p,op=1; register float c=1; // Parameters. for(p=2; p= atof(argv[p])) c=0; break; // Operate: Less than. case 3: if(atof(argv[1]) != atof(argv[p])) c=0; break; // Operate: Equal to. case 4: if(atof(argv[1]) == atof(argv[p])) c=0; break; // Operate: Not equal. case 5: if(atof(argv[1]) < atof(argv[p])) c=0; break; // Operate: Greater or equal. case 6: if(atof(argv[1]) > atof(argv[p])) c=0; break; // Operate: Less or equal. }} char buf[TLIB_CMP_BSIZE]; // Create buffer. snprintf(buf,TLIB_CMP_BSIZE,"%f",c); // Copy result to buffer as float. AllenVM_InterpSetResult(i,buf); // Set interpreter result. return Allen_VM_OK; // Everything ok. } // ------------------------------------------------------------------------------------------------------------------------------------- // Function: AllenVM_CPU_LIB_CMP_GTLT(); // Purpose: Ordered from mayor to minor. (restrictive) // Returns: 0/1 wether false/true. // ------------------------------------------------------------------------------------------------------------------------------------- static int AllenVM_CPU_LIB_CMP_GTLT(struct AllenInterp *i, int argc, char **argv, void *pd) { if(argc < 3) return AllenVM_CPU_Error(i,argv[0]); // Check parameters. register int p; register float c=1; // Parameters. for(p=2; p= atof(argv[p])) c=0; break; // Operate: Less than. case 3: if(atof(argv[1]) != atof(argv[p])) c=0; break; // Operate: Equal to. case 4: if(atof(argv[1]) == atof(argv[p])) c=0; break; // Operate: Not equal. case 5: if(atof(argv[1]) < atof(argv[p])) c=0; break; // Operate: Greater or equal. case 6: if(atof(argv[1]) > atof(argv[p])) c=0; break; // Operate: Less or equal. }} char buf[TLIB_CMP_BSIZE]; // Create buffer. snprintf(buf,TLIB_CMP_BSIZE,"%f",c); // Copy result to buffer as float. AllenVM_InterpSetResult(i,buf); // Set interpreter result. return Allen_VM_OK; // Everything ok. } // ------------------------------------------------------------------------------------------------------------------------------------- // Function: AllenVM_CPU_LIB_CMP_LTGT(); // Purpose: Ordered from minor to major (restrictive). // Returns: 0/1 wether false/true. // ------------------------------------------------------------------------------------------------------------------------------------- static int AllenVM_CPU_LIB_CMP_LTGT(struct AllenInterp *i, int argc, char **argv, void *pd) { if(argc < 3) return AllenVM_CPU_Error(i,argv[0]); // Check parameters. register int p; register float c=1; // Parameters. for(p=2; p= atof(argv[p+1])) { c=0; break; } // Ordered from minor to mayor. char buf[TLIB_CMP_BSIZE]; // Create buffer. snprintf(buf,TLIB_CMP_BSIZE,"%f",c); // Copy result to buffer as float. AllenVM_InterpSetResult(i,buf); // Set interpreter result. return Allen_VM_OK; // Everything ok. } // ------------------------------------------------------------------------------------------------------------------------------------- // Function: AllenVM_CPU_LIB_CMP_LTEQGT(); // Purpose: Ordered from minor to major (non restrictive). // Returns: 0/1 wether false/true. // ------------------------------------------------------------------------------------------------------------------------------------- static int AllenVM_CPU_LIB_CMP_LTEQGT(struct AllenInterp *i, int argc, char **argv, void *pd) { if(argc < 3) return AllenVM_CPU_Error(i,argv[0]); // Check parameters. register int p; register float c=1; // Parameters. for(p=2; p atof(argv[p+1])) { c=0; break; } // Ordered from minor to mayor. (not rest) char buf[TLIB_CMP_BSIZE]; // Create buffer. snprintf(buf,TLIB_CMP_BSIZE,"%f",c); // Copy result to buffer as float. AllenVM_InterpSetResult(i,buf); // Set interpreter result. return Allen_VM_OK; // Everything ok. } // ------------------------------------------------------------------------------------------------------------------------------------- // Function: AllenVM_CPU_LIB_CMP_EQ(); // Purpose: Equal. // Returns: 0/1 wether false/true. // ------------------------------------------------------------------------------------------------------------------------------------- static int AllenVM_CPU_LIB_CMP_EQ(struct AllenInterp *i, int argc, char **argv, void *pd) { if(argc < 3) return AllenVM_CPU_Error(i,argv[0]); // Check parameters. register int p,op=3; register float c=1; // Parameters. for(p=2; p= atof(argv[p])) c=0; break; // Operate: Less than. case 3: if(atof(argv[1]) != atof(argv[p])) c=0; break; // Operate: Equal to. case 4: if(atof(argv[1]) == atof(argv[p])) c=0; break; // Operate: Not equal. case 5: if(atof(argv[1]) < atof(argv[p])) c=0; break; // Operate: Greater or equal. case 6: if(atof(argv[1]) > atof(argv[p])) c=0; break; // Operate: Less or equal. }} char buf[TLIB_CMP_BSIZE]; // Create buffer. snprintf(buf,TLIB_CMP_BSIZE,"%f",c); // Copy result to buffer as float. AllenVM_InterpSetResult(i,buf); // Set interpreter result. return Allen_VM_OK; // Everything ok. } // ------------------------------------------------------------------------------------------------------------------------------------- // Function: AllenVM_CPU_LIB_CMP_NQ(); // Purpose: Not equal. // Returns: 0/1 wether false/true. // ------------------------------------------------------------------------------------------------------------------------------------- static int AllenVM_CPU_LIB_CMP_NQ(struct AllenInterp *i, int argc, char **argv, void *pd) { if(argc < 3) return AllenVM_CPU_Error(i,argv[0]); // Check parameters. register int p,op=4; register float c=1; // Parameters. for(p=2; p= atof(argv[p])) c=0; break; // Operate: Less than. case 3: if(atof(argv[1]) != atof(argv[p])) c=0; break; // Operate: Equal to. case 4: if(atof(argv[1]) == atof(argv[p])) c=0; break; // Operate: Not equal. case 5: if(atof(argv[1]) < atof(argv[p])) c=0; break; // Operate: Greater or equal. case 6: if(atof(argv[1]) > atof(argv[p])) c=0; break; // Operate: Less or equal. }} char buf[TLIB_CMP_BSIZE]; // Create buffer. snprintf(buf,TLIB_CMP_BSIZE,"%f",c); // Copy result to buffer as float. AllenVM_InterpSetResult(i,buf); // Set interpreter result. return Allen_VM_OK; // Everything ok. } // ------------------------------------------------------------------------------------------------------------------------------------- // Function: AllenVM_CPU_LIB_CMP_GEQ(); // Purpose: Greater or equal than. // Returns: 0/1 wether false/true. // ------------------------------------------------------------------------------------------------------------------------------------- static int AllenVM_CPU_LIB_CMP_GEQ(struct AllenInterp *i, int argc, char **argv, void *pd) { if(argc < 3) return AllenVM_CPU_Error(i,argv[0]); // Check parameters. register int p,op=5; register float c=1; // Parameters. for(p=2; p= atof(argv[p])) c=0; break; // Operate: Less than. case 3: if(atof(argv[1]) != atof(argv[p])) c=0; break; // Operate: Equal to. case 4: if(atof(argv[1]) == atof(argv[p])) c=0; break; // Operate: Not equal. case 5: if(atof(argv[1]) < atof(argv[p])) c=0; break; // Operate: Greater or equal. case 6: if(atof(argv[1]) > atof(argv[p])) c=0; break; // Operate: Less or equal. }} char buf[TLIB_CMP_BSIZE]; // Create buffer. snprintf(buf,TLIB_CMP_BSIZE,"%f",c); // Copy result to buffer as float. AllenVM_InterpSetResult(i,buf); // Set interpreter result. return Allen_VM_OK; // Everything ok. } // ------------------------------------------------------------------------------------------------------------------------------------- // Function: AllenVM_CPU_LIB_CMP_LEQ(); // Purpose: Less or equal than. // Returns: 0/1 wether false/true. // ------------------------------------------------------------------------------------------------------------------------------------- static int AllenVM_CPU_LIB_CMP_LEQ(struct AllenInterp *i, int argc, char **argv, void *pd) { if(argc < 3) return AllenVM_CPU_Error(i,argv[0]); // Check parameters. register int p,op=6; register float c=1; // Parameters. for(p=2; p= atof(argv[p])) c=0; break; // Operate: Less than. case 3: if(atof(argv[1]) != atof(argv[p])) c=0; break; // Operate: Equal to. case 4: if(atof(argv[1]) == atof(argv[p])) c=0; break; // Operate: Not equal. case 5: if(atof(argv[1]) < atof(argv[p])) c=0; break; // Operate: Greater or equal. case 6: if(atof(argv[1]) > atof(argv[p])) c=0; break; // Operate: Less or equal. }} char buf[TLIB_CMP_BSIZE]; // Create buffer. snprintf(buf,TLIB_CMP_BSIZE,"%f",c); // Copy result to buffer as float. AllenVM_InterpSetResult(i,buf); // Set interpreter result. return Allen_VM_OK; // Everything ok. } // ------------------------------------------------------------------------------------------------------------------------------------- // Function: AllenVM_CPU_LIB_CMP_HLP(); // Purpose: Adds help facilities // Returns: Expression result. // ------------------------------------------------------------------------------------------------------------------------------------- static int AllenVM_CPU_LIB_CMP_HLP(struct AllenInterp *i, int argc, char **argv, void *pd) { if(argc != 2) return AllenVM_CPU_Error(i,argv[0]); // Check parameters. if(!strcmp(TLIB_CMP_GT,argv[1])) { // Compare parameters. puts("Description: Greater than expression."); // Description. puts("Returns: Float 1/0 wether the expression is true/false."); // Returns. puts("Sample: > 2 10 => 0.000000"); // Sample function. puts("Parameters: min: 2 max: ANY"); // Parameters needed. AllenVM_InterpSetResult(i,TLIB_CMP_GT); // Set interpreter result. return Allen_VM_OK; } // Everything ok. if(!strcmp(TLIB_CMP_GTLT,argv[1])) { // Compare parameters. puts("Description: Ordered mayor/minor (restrictive)."); // Description. puts("Returns: Float 1/0 wether the expression is true/false."); // Returns. puts("Sample: -> 10 2 => 1.000000"); // Sample function. puts("Parameters: min: 2 max: ANY"); // Parameters needed. AllenVM_InterpSetResult(i,TLIB_CMP_GTLT); // Set interpreter result. return Allen_VM_OK; } // Everything ok. if(!strcmp(TLIB_CMP_GTEQLT,argv[1])) { // Compare parameters. puts("Description: Ordered mayor/minor (non restrictive)."); // Description. puts("Returns: Float 1/0 wether the expression is true/false."); // Returns. puts("Sample: +> 10 10 2 => 1.000000"); // Sample function. puts("Parameters: min: 2 max: ANY"); // Parameters needed. AllenVM_InterpSetResult(i,TLIB_CMP_GTEQLT); // Set interpreter result. return Allen_VM_OK; } // Everything ok. if(!strcmp(TLIB_CMP_LT,argv[1])) { // Compare parameters. puts("Description: Less than expression."); // Description. puts("Returns: Float 1/0 wether the expression is true/false."); // Returns. puts("Sample: < 10 2 => 0.000000"); // Sample function. puts("Parameters: min: 2 max: ANY"); // Parameters needed. AllenVM_InterpSetResult(i,TLIB_CMP_LT); // Set interpreter result. return Allen_VM_OK; } // Everything ok. if(!strcmp(TLIB_CMP_LTGT,argv[1])) { // Compare parameters. puts("Description: Ordered minor/major (restrictive)."); // Description. puts("Returns: Float 1/0 wether the expression is true/false."); // Returns. puts("Sample: <- 8 9 10 => 1.000000"); // Sample function. puts("Parameters: min: 2 max: ANY"); // Parameters needed. AllenVM_InterpSetResult(i,TLIB_CMP_LTGT); // Set interpreter result. return Allen_VM_OK; } // Everything ok. if(!strcmp(TLIB_CMP_LTEQGT,argv[1])) { // Compare parameters. puts("Description: Ordered minor/major (non restrictive."); // Description. puts("Returns: Float 1/0 wether the expression is true/false."); // Returns. puts("Sample: <+ 8 8 9 9 10 => 1.000000"); // Sample function. puts("Parameters: min: 2 max: ANY"); // Parameters needed. AllenVM_InterpSetResult(i,TLIB_CMP_LTEQGT); // Set interpreter result. return Allen_VM_OK; } // Everything ok. if(!strcmp(TLIB_CMP_EQ,argv[1])) { // Compare parameters. puts("Description: Equal to expression."); // Description. puts("Returns: Float 1/0 wether the expression is true/false."); // Returns. puts("Sample: = 2 10 => 0.000000"); // Sample function. puts("Parameters: min: 2 max: ANY"); // Parameters needed. AllenVM_InterpSetResult(i,TLIB_CMP_EQ); // Set interpreter result. return Allen_VM_OK; } // Everything ok. if(!strcmp(TLIB_CMP_NQ,argv[1])) { // Compare parameters. puts("Description: Not equal to expression."); // Description. puts("Returns: Float 1/0 wether the expression is true/false."); // Returns. puts("Sample: ! 2 10 => 1.000000"); // Sample function. puts("Parameters: min: 2 max: ANY"); // Parameters needed. AllenVM_InterpSetResult(i,TLIB_CMP_NQ); // Set interpreter result. return Allen_VM_OK; } // Everything ok. if(!strcmp(TLIB_CMP_GEQ,argv[1])) { // Compare parameters. puts("Description: Greater or equal expression."); // Description. puts("Returns: Float 1/0 wether the expression is true/false."); // Returns. puts("Sample: => 5 4 => 1.000000"); // Sample function. puts("Parameters: min: 2 max: ANY"); // Parameters needed. AllenVM_InterpSetResult(i,TLIB_CMP_GEQ); // Set interpreter result. return Allen_VM_OK; } // Everything ok. if(!strcmp(TLIB_CMP_LEQ,argv[1])) { // Compare parameters. puts("Description: Less or equal expression."); // Description. puts("Returns: Float 1/0 wether the expression is true/false."); // Returns. puts("Sample: <= 21 22 => 1.000000"); // Sample function. puts("Parameters: min: 2 max: ANY"); // Parameters needed. AllenVM_InterpSetResult(i,TLIB_CMP_LEQ); // Set interpreter result. return Allen_VM_OK; } // Everything ok. AllenVM_InterpSetResult(i,TLIB_CMP_NIL); // Set interpreter result. return AllenVM_CPU_Error(i,TLIB_CMP_EHLP); // Command not found. } // ------------------------------------------------------------------------------------------------------------------------------------- // Function: AllenVM_CPU_LIB_CMP_ADD(); // Purpose: Add instructions to the CPU. // Returns: Void (nothing). // ------------------------------------------------------------------------------------------------------------------------------------- void AllenVM_CPU_LIB_CMP_ADD(struct AllenInterp *i) { AllenVM_InterpSetCommand(i,TLIB_CMP_GT, AllenVM_CPU_LIB_CMP_GT, NULL); // Greater. AllenVM_InterpSetCommand(i,TLIB_CMP_GTLT, AllenVM_CPU_LIB_CMP_GTLT, NULL); // Ordered mayor/minor (restrictive). AllenVM_InterpSetCommand(i,TLIB_CMP_GTEQLT,AllenVM_CPU_LIB_CMP_GTEQLT, NULL); // Ordered mayor/minor (non restrictive). AllenVM_InterpSetCommand(i,TLIB_CMP_LT, AllenVM_CPU_LIB_CMP_LT, NULL); // Lesser. AllenVM_InterpSetCommand(i,TLIB_CMP_LTGT, AllenVM_CPU_LIB_CMP_LTGT, NULL); // Ordered minor/major (restrictive). AllenVM_InterpSetCommand(i,TLIB_CMP_LTEQGT,AllenVM_CPU_LIB_CMP_LTEQGT, NULL); // Ordered minor/major (non restrictive). AllenVM_InterpSetCommand(i,TLIB_CMP_EQ, AllenVM_CPU_LIB_CMP_EQ, NULL); // Equal. AllenVM_InterpSetCommand(i,TLIB_CMP_NQ, AllenVM_CPU_LIB_CMP_NQ, NULL); // Not equal. AllenVM_InterpSetCommand(i,TLIB_CMP_GEQ, AllenVM_CPU_LIB_CMP_GEQ, NULL); // Greater or equal. AllenVM_InterpSetCommand(i,TLIB_CMP_LEQ, AllenVM_CPU_LIB_CMP_LEQ, NULL); // Less or equal. AllenVM_InterpSetCommand(i,TLIB_CMP_HLP, AllenVM_CPU_LIB_CMP_HLP, NULL); // Helper function. } // ===================================================================================================================================== // EOF // ===================================================================================================================================== // Compiler parameters: Gcc -O2 -lm // Recommended editor: Scite/Gedit/Vim.