All pastes #609262 Raw Edit

Unnamed

public text v1 · immutable
·published 2007-07-08 19:53 UTC
rendered paste body
// =====================================================================================================================================
// allen_cpu_base_comparison.c - Wed 13 jun 2007 00:09 CEST - Allen version 2.0
// ===================================================================================================================================== 

// Copyright (c) 2007, Archville, BSD License.
// A copy can be found here: http://www.opensource.org/licenses/bsd-license.php
// Initally based on Salvatore <antirez> 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 <stdio.h>                   // Standard input/output.
#include <stdlib.h>                  // Standard C libraries.
#include <string.h>                  // String libraries.
#include <math.h>                    // Math libraries.
#include <ctype.h>                   // Types and conversion libraries.

#include "allen_interpreter.h"       // Main interpreter library.
#include "allen_parser.h"            // Main parser library.

// =====================================================================================================================================
// Parameters.
// =====================================================================================================================================

#define TBASE_CMP_BSIZE  1024        // Buffer size.

// =====================================================================================================================================
// Tokens.
// =====================================================================================================================================

#define TBASE_CMP_GT     ">"         // Greater.
#define TBASE_CMP_GTLT   "->"        // Ordered mayor/minor. (restrictive)
#define TBASE_CMP_GTEQLT "+>"        // Ordered mayor/minor. (non restrictive)
#define TBASE_CMP_LT     "<"         // Lesser.
#define TBASE_CMP_LTGT   "<-"        // Ordered minor/major. (restrictive)
#define TBASE_CMP_LTEQGT "<+"        // Ordered minor/major. (non restrictive)
#define TBASE_CMP_EQ     "="         // Equal.
#define TBASE_CMP_NQ     "!"         // Not equal.
#define TBASE_CMP_GEQ    "=>"        // Greater or equal.
#define TBASE_CMP_LEQ    "<="        // Less or equal.
#define TBASE_CMP_SEP    ":"         // Separator for parameters.

// =====================================================================================================================================
// Basic comparison operators.
// =====================================================================================================================================

// Allows to perform regular comparison operations on value lists
// and return results based on their expresions.

// Index:                              Example:       Result:
// AllenVM_CPU_BASE_CMP_GT();      ::   > 10 2 1      1.000000
// AllenVM_CPU_BASE_CMP_GTLT();    ::   -> 1 2 3      0.000000
// AllenVM_CPU_BASE_CMP_GTEQLT();  ::   +> 3 2 2      1.000000
// AllenVM_CPU_BASE_CMP_LT();      ::   < 20 : 1      0.000000
// AllenVM_CPU_BASE_CMP_LTGT();    ::   <- 1 2 3      1.000000
// AllenVM_CPU_BASE_CMP_LTEQGT();  ::   <+ 2 2 3      1.000000
// AllenVM_CPU_BASE_CMP_EQ();      ::   = 4 : 4       1.000000
// AllenVM_CPU_BASE_CMP_NQ();      ::   ! 2 : 3 1     1.000000
// AllenVM_CPU_BASE_CMP_GEQ();     ::   => 10 : 1     1.000000
// AllenVM_CPU_BASE_CMP_LEQ();     ::   <= 2 : 2      1.000000

// Total: 10.

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_BASE_CMP_GT();
// Purpose:     Greater than.
// Returns:     0/1 wether false/true.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_CMP_GT(struct AllenInterp *i, int argc, char **argv, void *pd) {
 char buf[TBASE_CMP_BSIZE]; register int p,x,y; register float c=1;                      // Buffer and parameters.
 for(p=1; p<argc; ++p) { if (!strcmp(argv[p],TBASE_CMP_SEP)) break; }                    // Get parameters. 

 if(p!=argc) {                                                                           // Lists comparison.
  for(x=1; x<p; ++x) for(y=p+1; y<argc; ++y)                                             //  - Loop through parameters.
  if(atof(argv[x]) <= atof(argv[y])) { c=0; break; }}                                    //  - Make comparison.

 else {                                                                                  // Forward comparison.
  for(x=2; x<p; ++x)                                                                     //  - Loop through parameters.
  if(atof(argv[1]) <= atof(argv[x])) { c=0; break; }}                                    //  - Make comparison.

 snprintf(buf,TBASE_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_BASE_CMP_GTLT();
// Purpose:     Ordered from mayor to minor. (restrictive)
// Returns:     0/1 wether false/true.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_CMP_GTLT(struct AllenInterp *i, int argc, char **argv, void *pd) {
 char buf[TBASE_CMP_BSIZE]; register int p; register float c=1;                          // Buffer and parameters.
 for(p=1; p<argc-1; ++p) { if(atof(argv[p]) <= atof(argv[p+1])) { c=0; break; }}         // Ordered from mayor to minor. (rest)

 snprintf(buf,TBASE_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_BASE_CMP_GTEQLT();
// Purpose:     Ordered from mayor to minor. (not restrictive)
// Returns:     0/1 wether false/true.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_CMP_GTEQLT(struct AllenInterp *i, int argc, char **argv, void *pd) {
 char buf[TBASE_CMP_BSIZE]; register int p; register float c=1;                          // Buffer and parameters.
 for(p=1; p<argc-1; ++p) { if(atof(argv[p]) < atof(argv[p+1])) { c=0; break; }}          // Ordered from mayor to minor. (not rest)

 snprintf(buf,TBASE_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_BASE_CMP_LT();
// Purpose:     Less than.
// Returns:     0/1 wether false/true.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_CMP_LT(struct AllenInterp *i, int argc, char **argv, void *pd) {
 char buf[TBASE_CMP_BSIZE]; register int p,x,y; register float c=1;                      // Buffer and parameters.
 for(p=1; p<argc; ++p) { if (!strcmp(argv[p],TBASE_CMP_SEP)) break; }                    // Get parameters. 

 if(p!=argc) {                                                                           // Lists comparison.
  for(x=1; x<p; ++x) for(y=p+1; y<argc; ++y)                                             //  - Loop through parameters.
  if(atof(argv[x]) >= atof(argv[y])) { c=0; break; }}                                    //  - Make comparison.

 else {                                                                                  // Forward comparison.
  for(x=2; x<p; ++x)                                                                     //  - Loop through parameters.
  if(atof(argv[1]) >= atof(argv[x])) { c=0; break; }}                                    //  - Make comparison.

 snprintf(buf,TBASE_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_BASE_CMP_LTGT();
// Purpose:     Ordered from minor to major (restrictive).
// Returns:     0/1 wether false/true.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_CMP_LTGT(struct AllenInterp *i, int argc, char **argv, void *pd) {
 char buf[TBASE_CMP_BSIZE]; register int p; register float c=1;                          // Buffer and parameters.
 for(p=1; p<argc-1; ++p) { if(atof(argv[p]) >= atof(argv[p+1])) { c=0; break; }}         // Ordered from minor to mayor.

 snprintf(buf,TBASE_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_BASE_CMP_LTEQGT();
// Purpose:     Ordered from minor to major (non restrictive).
// Returns:     0/1 wether false/true.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_CMP_LTEQGT(struct AllenInterp *i, int argc, char **argv, void *pd) {
 char buf[TBASE_CMP_BSIZE]; register int p; register float c=1;                          // Buffer and parameters.
 for(p=1; p<argc-1; ++p) { if(atof(argv[p]) > atof(argv[p+1])) { c=0; break; }}          // Ordered from minor to mayor. (not rest)

 snprintf(buf,TBASE_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_BASE_CMP_EQ();
// Purpose:     Equal.
// Returns:     0/1 wether false/true.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_CMP_EQ(struct AllenInterp *i, int argc, char **argv, void *pd) {
 char buf[TBASE_CMP_BSIZE]; register int p,x,y; register float c=1;                      // Buffer and parameters.
 for(p=1; p<argc; ++p) { if (!strcmp(argv[p],TBASE_CMP_SEP)) break; }                    // Get parameters. 

 if(p!=argc) {                                                                           // Lists comparison.
  for(x=1; x<p; ++x) for(y=p+1; y<argc; ++y)                                             //  - Loop through parameters.
  if(atof(argv[x]) != atof(argv[y])) { c=0; break; }}                                    //  - Make comparison.

 else {                                                                                  // Forward comparison.
  for(x=2; x<p; ++x)                                                                     //  - Loop through parameters.
  if(atof(argv[1]) != atof(argv[x])) { c=0; break; }}                                    //  - Make comparison.

 snprintf(buf,TBASE_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_BASE_CMP_NQ();
// Purpose:     Not equal.
// Returns:     0/1 wether false/true.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_CMP_NQ(struct AllenInterp *i, int argc, char **argv, void *pd) {
 char buf[TBASE_CMP_BSIZE]; register int p,x,y; register float c=1;                      // Buffer and parameters.
 for(p=1; p<argc; ++p) { if (!strcmp(argv[p],TBASE_CMP_SEP)) break; }                    // Get parameters. 

 if(p!=argc) {                                                                           // Lists comparison.
  for(x=1; x<p; ++x) for(y=p+1; y<argc; ++y)                                             //  - Loop through parameters.
  if(atof(argv[x]) == atof(argv[y])) { c=0; break; }}                                    //  - Make comparison.

 else {                                                                                  // Forward comparison.
  for(x=2; x<p; ++x)                                                                     //  - Loop through parameters.
  if(atof(argv[1]) == atof(argv[x])) { c=0; break; }}                                    //  - Make comparison.

 snprintf(buf,TBASE_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_BASE_CMP_GEQ();
// Purpose:     Greater or equal than.
// Returns:     0/1 wether false/true.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_CMP_GEQ(struct AllenInterp *i, int argc, char **argv, void *pd) {
 char buf[TBASE_CMP_BSIZE]; register int p,x,y; register float c=1;                      // Buffer and parameters.
 for(p=1; p<argc; ++p) { if (!strcmp(argv[p],TBASE_CMP_SEP)) break; }                    // Get parameters. 

 if(p!=argc) {                                                                           // Lists comparison.
  for(x=1; x<p; ++x) for(y=p+1; y<argc; ++y)                                             //  - Loop through parameters.
  if(atof(argv[x]) < atof(argv[y])) { c=0; break; }}                                     //  - Make comparison.

 else {                                                                                  // Forward comparison.
  for(x=2; x<p; ++x)                                                                     //  - Loop through parameters.
  if(atof(argv[1]) < atof(argv[x])) { c=0; break; }}                                     //  - Make comparison.

 snprintf(buf,TBASE_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_BASE_CMP_LEQ();
// Purpose:     Less or equal than.
// Returns:     0/1 wether false/true.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_CMP_LEQ(struct AllenInterp *i, int argc, char **argv, void *pd) {
 char buf[TBASE_CMP_BSIZE]; register int p,x,y; register float c=1;                      // Buffer and parameters.
 for(p=1; p<argc; ++p) { if (!strcmp(argv[p],TBASE_CMP_SEP)) break; }                    // Get parameters. 

 if(p!=argc) {                                                                           // Lists comparison.
  for(x=1; x<p; ++x) for(y=p+1; y<argc; ++y)                                             //  - Loop through parameters.
  if(atof(argv[x]) > atof(argv[y])) { c=0; break; }}                                     //  - Make comparison.

 else {                                                                                  // Forward comparison.
  for(x=2; x<p; ++x)                                                                     //  - Loop through parameters.
  if(atof(argv[1]) > atof(argv[x])) { c=0; break; }}                                     //  - Make comparison.

 snprintf(buf,TBASE_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_BASE_CMP_ADD();
// Purpose:     Add instructions to the CPU.
// -------------------------------------------------------------------------------------------------------------------------------------
// Description: Register VM instructions for the interpreter.
// -------------------------------------------------------------------------------------------------------------------------------------

void AllenVM_CPU_BASE_CMP_ADD(struct AllenInterp *i) {
 AllenVM_InterpSetCommand(i,TBASE_CMP_GT,    AllenVM_CPU_BASE_CMP_GT,     NULL);         // Greater.
 AllenVM_InterpSetCommand(i,TBASE_CMP_GTLT,  AllenVM_CPU_BASE_CMP_GTLT,   NULL);         // Ordered mayor/minor (restrictive).
 AllenVM_InterpSetCommand(i,TBASE_CMP_GTEQLT,AllenVM_CPU_BASE_CMP_GTEQLT, NULL);         // Ordered mayor/minor (non restrictive).
 AllenVM_InterpSetCommand(i,TBASE_CMP_LT,    AllenVM_CPU_BASE_CMP_LT,     NULL);         // Lesser.
 AllenVM_InterpSetCommand(i,TBASE_CMP_LTGT,  AllenVM_CPU_BASE_CMP_LTGT,   NULL);         // Ordered minor/major (restrictive).
 AllenVM_InterpSetCommand(i,TBASE_CMP_LTEQGT,AllenVM_CPU_BASE_CMP_LTEQGT, NULL);         // Ordered minor/major (non restrictive).
 AllenVM_InterpSetCommand(i,TBASE_CMP_EQ,    AllenVM_CPU_BASE_CMP_EQ,     NULL);         // Equal.
 AllenVM_InterpSetCommand(i,TBASE_CMP_NQ,    AllenVM_CPU_BASE_CMP_NQ,     NULL);         // Not equal.
 AllenVM_InterpSetCommand(i,TBASE_CMP_GEQ,   AllenVM_CPU_BASE_CMP_GEQ,    NULL);         // Greater or equal.
 AllenVM_InterpSetCommand(i,TBASE_CMP_LEQ,   AllenVM_CPU_BASE_CMP_LEQ,    NULL);         // Less or equal.
}

// =====================================================================================================================================
// EOF
// =====================================================================================================================================
// Compiler parameters: Gcc -O2 -lm
// Recommended editor: Scite/Gedit/Vim.