All pastes #571810 Raw Edit

Mine

public text v1 · immutable
·published 2007-06-17 10:21 UTC
rendered paste body
// =====================================================================================================================================
// allen_cpu_base.c - Wed 13 jun 2007 00:09 CEST - Allen version 2.0
// ===================================================================================================================================== 
// Copyright (c) 2007, Archville, Licencia BSD. 
// Initally based on Salvatore <antirez> Sanfilippo within Picol 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.

// =====================================================================================================================================
// Changelog. (As of 17/06/07)
// =====================================================================================================================================
// 
// * Added try/catch exceptions and errors management.
// * Added possibility to break/continue of returning values.
// * Moved break, continue from loop.*
// * Translated into english.
// * ++p instead of p++, it's faster.
// * strtol/strtod could be used instead of atof() or atoi() 
//   but atof() and atoi() are faster.

// =====================================================================================================================================
// 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.

#include "allen_cpu_base.h"          // Headers.

// =====================================================================================================================================
// Basic arithmetic operators.
// =====================================================================================================================================

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

// Index:                        Example:  Result:
// AllenVM_CPU_BASE_PLS();  ::  + 2 3 4    9
// AllenVM_CPU_BASE_DPLS(); ::  ++ 2       3
// AllenVM_CPU_BASE_MIN();  ::  - 2 3 4   -5
// AllenVM_CPU_BASE_DMIN(); ::  -- 2       1
// AllenVM_CPU_BASE_MUL();  ::  * 2 3 4   24
// AllenVM_CPU_BASE_DMUL(); ::  ** 2       4
// AllenVM_CPU_BASE_DIV();  ::  / 2 3 4    0.166667
// AllenVM_CPU_BASE_DDIV(); ::  // 2 3     0      
// AllenVM_CPU_BASE_MOD();  ::  % 10 3     1
// AllenVM_CPU_BASE_POW();  ::  ^ 2 4     16

// Total: 10.

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_BASE_PLS();
// Purpose:     Addition.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_PLS(struct AllenInterp *i, int argc, char **argv, void *pd) {
 char buf[TBASE_BSIZE]; register int p; register float c=0;                              // Buffer and parameters.
 if(argc>=2) c=atof(argv[1]);                                                            // Conversion.
 for(p=2; p<argc; ++p) c += atof(argv[p]);                                               // Addition.

 snprintf(buf,TBASE_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_DPLS();
// Purpose:     Increment.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_DPLS(struct AllenInterp *i, int argc, char **argv, void *pd) {
 char buf[TBASE_BSIZE]; register float c=0;                                              // Buffer and parameters.
 if(argc>=2) c=atof(argv[1])+1;                                                          // Increment.

 snprintf(buf,TBASE_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_MIN();
// Purpose:     Substraction.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_MIN(struct AllenInterp *i, int argc, char **argv, void *pd) {
 char buf[TBASE_BSIZE]; register int p; register float c=0;                              // Buffer and parameters.
 if(argc>=2) c=atof(argv[1]);                                                            // Conversion.
 for(p=2; p<argc; ++p) c -= atof(argv[p]);                                               // Substraction. 

 snprintf(buf,TBASE_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_DMIN();
// Purpose:     Decrement.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_DMIN(struct AllenInterp *i, int argc, char **argv, void *pd) {
 char buf[TBASE_BSIZE]; register float c=0;                                              // Buffer and parameters.
 if(argc>=2) c=atof(argv[1])-1;                                                          // Decrement.
 
 snprintf(buf,TBASE_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_MUL();
// Purpose:     Multiplication.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_MUL(struct AllenInterp *i, int argc, char **argv, void *pd) {
 char buf[TBASE_BSIZE]; register int p; register float c=0;                              // Buffer and parameters.
 if(argc>=2) c=atof(argv[1]);                                                            // Conversion.
 for(p=2; p<argc; ++p) c *= atof(argv[p]);                                               // Multiplication.

 snprintf(buf,TBASE_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_DMUL();
// Purpose:     Square.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_DMUL(struct AllenInterp *i, int argc, char **argv, void *pd) {
 char buf[TBASE_BSIZE]; register float c=0;                                              // Buffer and parameters.
 if(argc>=2) c=atof(argv[1])*atof(argv[1]);                                              // Square.

 snprintf(buf,TBASE_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_DIV();
// Purpose:     Division.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_DIV(struct AllenInterp *i, int argc, char **argv, void *pd) {
 char buf[TBASE_BSIZE]; register int p; register float c=0;                              // Buffer and parameters.
 if(argc>=2) c=atof(argv[1]);                                                            // Conversion.
 for(p=2; p<argc; ++p) {
   if(atof(argv[p]) == 0) return AllenVM_CPU_Error(i,TBASE_EDIV);                        // Look for errors.
   c /= atof(argv[p]);                                                                   // Division.
 }

 snprintf(buf,TBASE_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_DDIV();
// Purpose:     Division without floating point.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_DDIV(struct AllenInterp *i, int argc, char **argv, void *pd) {
 char buf[TBASE_BSIZE]; register int p; register float c=0;                              // Buffer and parameters.
 if(argc>=2) c=atof(argv[1]);                                                            // Conversion.
 for(p=2; p<argc; ++p) {
   if(atof(argv[p]) == 0) return AllenVM_CPU_Error(i,TBASE_EDIV);                        // Look for errors.
   c /= atof(argv[p]);                                                                   // Division.
 } 
 
 snprintf(buf,TBASE_BSIZE,"%d",(int) c);                                                 // Copy result to buffer as integer.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_BASE_MOD();
// Purpose:     Modulus.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_MOD(struct AllenInterp *i, int argc, char **argv, void *pd) {
 char buf[TBASE_BSIZE]; register int p; register float c=0;                              // Buffer and parameters.
 if(argc>=2) c=atof(argv[1]);                                                            // Conversion.
 for(p=2; p<argc; ++p) { 
   if(atof(argv[p]) == 0) return AllenVM_CPU_Error(i,TBASE_EMOD);                        // Look for errors.
   c = (int) c % atoi(argv[p]);                                                          // Modulus.
 }                                      

 snprintf(buf,TBASE_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_POW();
// Purpose:     Pow.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_POW(struct AllenInterp *i, int argc, char **argv, void *pd) {
 char buf[TBASE_BSIZE]; register int p; register float c=0;                              // Buffer and parameters.
 if(argc>=2) c=atof(argv[1]);                                                            // Conversion.
 for(p=2; p<argc; ++p) c = pow(c,atof(argv[p]));                                         // Pow.

 snprintf(buf,TBASE_BSIZE,"%f",c);                                                       // Copy result to buffer as float.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// =====================================================================================================================================
// Basic logic operators.
// =====================================================================================================================================

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

// Index:                        Example:  Result:
// AllenVM_CPU_BASE_OR();   ::  || 1 0     1.000000
// AllenVM_CPU_BASE_AND();  ::  && 0 1     0.000000
// AllenVM_CPU_BASE_XOR();  ::  <> 1 1     0.000000
// AllenVM_CPU_BASE_NOT();  ::  >< 0 0     1.000000

// Total: 4.

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_BASE_OR();
// Purpose:     Logic OR.
// Returns:     0/1 wether false/true.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_OR(struct AllenInterp *i, int argc, char **argv, void *pd) {
 char buf[TBASE_BSIZE]; register int p; register float c=0;                              // Buffer and parameters.
 if(argc>=2) c=atof(argv[1]);                                                            // Conversion.
 for(p=2; p<argc; ++p) c = c || atof(argv[p]);                                           // Or.

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

static int AllenVM_CPU_BASE_AND(struct AllenInterp *i, int argc, char **argv, void *pd) {
 char buf[TBASE_BSIZE]; register int p; register float c=0;                              // Buffer and parameters.
 if(argc>=2) c=atof(argv[1]);                                                            // Conversion.
 for(p=2; p<argc; ++p) c = c && atof(argv[p]);                                           // And.

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

static int AllenVM_CPU_BASE_XOR(struct AllenInterp *i, int argc, char **argv, void *pd) {
 char buf[TBASE_BSIZE]; register int p; register float c=0;                              // Buffer and parameters.
 if(argc>=2) c=atof(argv[1]);                                                            // Conversion.
 for(p=2; p<argc; ++p) c = (int) c ^ atoi(argv[p]);                                      // Xor.

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

static int AllenVM_CPU_BASE_NOT(struct AllenInterp *i, int argc, char **argv, void *pd) {
 char buf[TBASE_BSIZE]; register int p; register float c=0;                              // Buffer and parameters.
 if(argc>=2) c=atof(argv[1]);                                                            // Conversion.
 for(p=2; p<argc; ++p) c = c || atoi(argv[p]); c=!c;                                     // Not.

 snprintf(buf,TBASE_BSIZE,"%f",c);                                                       // Copy result to buffer as float.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// =====================================================================================================================================
// 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_GT();    ::   > 10 2     1.000000
// AllenVM_CPU_BASE_GTLT();  ::   -> 1 2 3   0.000000
// AllenVM_CPU_BASE_LT();    ::   < 20 1     0.000000
// AllenVM_CPU_BASE_LTGT();  ::   <- 1 2 3   1.000000
// AllenVM_CPU_BASE_EQ();    ::   = 4 4      1.000000
// AllenVM_CPU_BASE_NQ();    ::   ! 2 3      1.000000
// AllenVM_CPU_BASE_GEQ();   ::   => 10 1    1.000000
// AllenVM_CPU_BASE_LEQ();   ::   <= 2 2     1.000000

// Total: 8.

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

static int AllenVM_CPU_BASE_GT(struct AllenInterp *i, int argc, char **argv, void *pd) {
 char buf[TBASE_BSIZE]; register int p; register float c=1;                              // Buffer and parameters.
 for(p=1; p<argc-1; ++p) { if(atof(argv[1]) <= atof(argv[p+1])) { c=0; break; }}         // Greater than.

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

static int AllenVM_CPU_BASE_GTLT(struct AllenInterp *i, int argc, char **argv, void *pd) {
 char buf[TBASE_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.

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

static int AllenVM_CPU_BASE_LT(struct AllenInterp *i, int argc, char **argv, void *pd) {
 char buf[TBASE_BSIZE]; register int p; register float c=1;                              // Buffer and parameters.
 for(p=1; p<argc-1; ++p) { if(atof(argv[1]) >= atof(argv[p+1])) { c=0; break; }}         // Less than.

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

static int AllenVM_CPU_BASE_LTGT(struct AllenInterp *i, int argc, char **argv, void *pd) {
 char buf[TBASE_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_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_EQ();
// Purpose:     Equal.
// Returns:     0/1 wether false/true.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_EQ(struct AllenInterp *i, int argc, char **argv, void *pd) {
 char buf[TBASE_BSIZE]; register int p; register float c=1;                              // Buffer and parameters.
 for(p=1; p<argc-1; ++p) { if(atof(argv[1]) != atof(argv[p+1])) { c=0; break; }}         // Equal.
 
 snprintf(buf,TBASE_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_NQ();
// Purpose:     Not equal.
// Returns:     0/1 wether false/true.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_NQ(struct AllenInterp *i, int argc, char **argv, void *pd) {
 char buf[TBASE_BSIZE]; register int p; register float c=1;                              // Buffer and parameters.
 for(p=1; p<argc-1; ++p) { if(atof(argv[1]) == atof(argv[p+1])) { c=0; break; }}         // Not equal.
 
 snprintf(buf,TBASE_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_GEQ();
// Purpose:     Greater or equal than.
// Returns:     0/1 wether false/true.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_GEQ(struct AllenInterp *i, int argc, char **argv, void *pd) {
 char buf[TBASE_BSIZE]; register int p; register float c=1;                              // Buffer and parameters.
 for(p=1; p<argc-1; ++p) { if(atof(argv[1]) < atof(argv[p+1])) { c=0; break; }}          // Greater or equal than.

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

static int AllenVM_CPU_BASE_LEQ(struct AllenInterp *i, int argc, char **argv, void *pd) {
 char buf[TBASE_BSIZE]; register int p; register float c=1;                              // Buffer and parameters.
 for(p=1; p<argc-1; ++p) { if(atof(argv[1]) > atof(argv[p+1])) { c=0; break; }}          // Less or equal than.
 
 snprintf(buf,TBASE_BSIZE,"%f",c);                                                       // Copy result to buffer as float.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// =====================================================================================================================================
// Basic bits operations.
// =====================================================================================================================================

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

// Index:                        Example: Result:
// AllenVM_CPU_BASE_SHL();  ::  << 2 8    512
// AllenVM_CPU_BASE_SHR();  ::  >> 2 8    0

// Total: 2. 

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_BASE_SHL();
// Purpose:     Shift left.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_SHL(struct AllenInterp *i, int argc, char **argv, void *pd) {
 char buf[TBASE_BSIZE]; register int p=0; register unsigned int c=0;                     // Buffer and parameters.
 if(argc>=2) c=atoi(argv[1]);                                                            // Conversion.
 for(p=2; p<argc; ++p) c = c << (unsigned int) atoi(argv[p]);                            // Shift left.

 snprintf(buf,TBASE_BSIZE,"%d",c);                                                       // Copy result to buffer.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_BASE_SHR();
// Purpose:     Shift right.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_SHR(struct AllenInterp *i, int argc, char **argv, void *pd) {
 char buf[TBASE_BSIZE]; register int p=0; register unsigned int c=0;                     // Buffer and parameters.
 if(argc>=2) c=atoi(argv[1]);                                                            // Conversion.
 for(p=2; p<argc; ++p) c = c >> (unsigned int) atoi(argv[p]);                            // Shift right.

 snprintf(buf,TBASE_BSIZE,"%d",c);                                                       // Copy result to buffer.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// =====================================================================================================================================
// Basic conversion operators.
// =====================================================================================================================================

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

// Index:                       Example:   Result:
// AllenVM_CPU_BASE_INT();  :: int 10      10
// AllenVM_CPU_BASE_FLT();  :: float 20    20.000000
// AllenVM_CPU_BASE_LNG();  :: long 90     90.000000
// AllenVM_CPU_BASE_STR();  :: string A    A
// AllenVM_CPU_BASE_BIN();  :: bin 10      1010
// AllenVM_CPU_BASE_DEC();  :: dec 21      21
// AllenVM_CPU_BASE_HEX();  :: hex 15      FF
// AllenVM_CPU_BASE_OCT();  :: oct 10      12

// Total: 8.

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_BASE_INT();
// Purpose:     Integer conversion.
// Returns:     Expression result (as integer).
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_INT(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,argv[0]);                                      // Check parameters.
 char buf[TBASE_BSIZE];                                                                  // Buffer for results.

 snprintf(buf,TBASE_BSIZE,"%d",atoi(argv[1]));                                           // Integer conversion.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_BASE_FLT();
// Purpose:     Float conversion.
// Returns:     Expression result (as float).
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_FLT(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,argv[0]);                                      // Check parameters.
 char buf[TBASE_BSIZE];                                                                  // Buffer for results.

 snprintf(buf,TBASE_BSIZE,"%f",atof(argv[1]));                                           // Float conversion.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_BASE_LNG();
// Purpose:     Long conversion.
// Returns:     Expression result (as long).
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_LNG(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,argv[0]);                                      // Check parameters.
 char buf[TBASE_BSIZE];                                                                  // Buffer for results.

 snprintf(buf,TBASE_BSIZE,"%u",atol(argv[1]));                                           // Long conversion.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_BASE_STR();
// Purpose:     String conversion.
// Returns:     Expression result (as string).
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_STR(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,argv[0]);                                      // Check parameters.

 AllenVM_InterpSetResult(i,argv[1]);                                                     // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_BASE_BIN();
// Purpose:     Binary conversion.
// Returns:     Expresion result (as binary).
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_BIN(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,argv[0]);                                      // Check parameters.
 char buf[TBASE_BSIZE];                                                                  // Buffer and parameters.
 char base_digits[2] =  {'0', '1'};                                                      // Possible base values.
                                                 
 int index = 0;                                                                          // Zero index.
 int result[TBASE_BSIZE];                                                                // Store result..
 int number = abs(atoi(argv[1]));                                                        // Save value as absolute integer.
 
 while (number != 0) {                                                                   // While not zero......
  result[index] = number % 2;                                                            // Apply modulus,
  number = number / 2;                                                                   // Divide.
  ++index;                                                                               // Next index.
 }

 buf[index]='\0'; int c = 0;                                                             // Add \0 to the string..
 for(--index; index>=0; index--,c++)                                                     // Through index values...
   buf[c] = base_digits[result[index]];                                                  // Copy current character.

 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_BASE_DEC();
// Purpose:     Decimal conversion.
// Returns:     Expresion result (as decimal).
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_DEC(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,argv[0]);                                      // Check parameters.
 char buf[TBASE_BSIZE];                                                                  // Buffer and parameters.
 char base_digits[10] =  {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };            // Possible base values.
           
 int index = 0;                                                                          // Zero index.
 int result[TBASE_BSIZE];                                                                // Store result..
 int number = abs(atoi(argv[1]));                                                        // Save value as absolute integer.
 
 while (number != 0) {                                                                   // While not zero......
  result[index] = number % 10;                                                           // Apply modulus,
  number = number / 10;                                                                  // Divide.
  ++index;                                                                               // Next index.
 }

 buf[index]='\0'; int c = 0;                                                             // Add \0 to the string..
 for(--index; index>=0; index--,c++)                                                     // Through index values...
   buf[c] = base_digits[result[index]];                                                  // Copy current character.

 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_BASE_HEX();
// Purpose:     Hexadecimal conversion.
// Returns:     Expresion result (as hexadecimal).
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_HEX(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,argv[0]);                                      // Check parameters.
 char buf[TBASE_BSIZE];                                                                  // Buffer and parameters.
 char base_digits[16] =  {'0', '1', '2', '3', '4', '5', '6', '7',                        // Possible base values.
                          '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};                       
 int index = 0;                                                                          // Zero index.
 int result[TBASE_BSIZE];                                                                // Store result.
 int number = abs(atoi(argv[1]));                                                        // Save value as absolute integer.
 
 while (number != 0) {                                                                   // While not zero......
  result[index] = number % 16;                                                           // Apply modulus,
  number = number / 16;                                                                  // Divide.
  ++index;                                                                               // Next index.
 }

 buf[index]='\0'; int c = 0;                                                             // Add \0 to the string..
 for(--index; index>=0; index--,c++)                                                     // Through index values...
   buf[c] = base_digits[result[index]];                                                  // Copy current character.

 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_BASE_OCT();
// Purpose:     Octal conversion.
// Returns:     Expresion result (as octal).
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_OCT(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,argv[0]);                                      // Check parameters.
 char buf[TBASE_BSIZE];                                                                  // Buffer and parameters.
 char base_digits[8] =  {'0', '1', '2', '3', '4', '5', '6', '7' };                       // Possible base values.
                      
 int index = 0;                                                                          // Zero index.
 int result[TBASE_BSIZE];                                                                // Store result..
 int number = abs(atoi(argv[1]));                                                        // Save value as absolute integer.
 
 while (number != 0) {                                                                   // While not zero......
  result[index] = number % 8;                                                            // Apply modulus,
  number = number / 8;                                                                   // Divide.
  ++index;                                                                               // Next index.
 }

 buf[index]='\0'; int c = 0;                                                             // Add \0 to the string..
 for(--index; index>=0; index--,c++)                                                     // Through index values...
   buf[c] = base_digits[result[index]];                                                  // Copy current character.

 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// =====================================================================================================================================
// Macro operators.
// =====================================================================================================================================

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

// Index:                       Example:        Result:
// AllenVM_CPU_BASE_BRK(); ::  break TRUE       TRUE
// AllenVM_CPU_BASE_CON(); ::  continue         NULL
// AllenVM_CPU_BASE_EVL(); ::  eval { + 1 1 }   2.000000
// AllenVM_CPU_BASE_TRY(); ::  try  { / 1 0 }   0.000000

// Total: 4.

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:     AllenVM_CPU_BASE_BRK();
// Purpose:      Break from a block.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_BRK(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc == 2) AllenVM_InterpSetResult(i,argv[1]);                                       // Set interpreter result.
 return Allen_VM_BRK;                                                                    // Breaks current block of sentences.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Funcion:     AllenVM_CPU_BASE_CON();
// Proposito:   Continue to the next iteration of a block.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_CON(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc == 2) AllenVM_InterpSetResult(i,argv[1]);                                       // Set interpreter result.
 return Allen_VM_CON;                                                                    // Continues to the next iteration.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_BASE_EVL();
// Purpose:     Evaluate a given expression.
// Returns:     Last evaluated expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_EVL(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,argv[0]);                                      // Check parameters.
 register int c;                                                                         // Declare vars.
 if((c = AllenVM_InterpEval(i,argv[1])) != Allen_VM_OK) return c;                        // Evaluate the expression.
 return Allen_VM_OK;                                                                     // Everything ok.   
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_BASE_TRY();
// Purpose:     Try a given expression.
// Returns:     0/1 wether the expression is factible.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_BASE_TRY(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2 && argc != 4)                 return AllenVM_CPU_Error(i,argv[0]);         // Check parameters.
 if(argc == 4 && strcmp(argv[2],TBASE_CTH)) return AllenVM_CPU_Error(i,argv[0]);         // Check if there is catch.
 
 char buf[TBASE_BSIZE]; register int c;                                                  // Buffer and parameters.
 if((c = AllenVM_InterpEval(i,argv[1])) != Allen_VM_OK)                                  // Evaluate the expression.
  if(argc==4) c = AllenVM_InterpEval(i,argv[3]);                                         // Look for exceptions.
                                                   
 snprintf(buf,TBASE_BSIZE,"%f",(float) c);                                               // Copy result to buffer as float.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.   
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_BASE_ADD();
// Purpose:     Add instructions to the CPU.
// -------------------------------------------------------------------------------------------------------------------------------------
// Descripcion: Register VM instructions for the interpreter.
// -------------------------------------------------------------------------------------------------------------------------------------

void AllenVM_CPU_BASE_ADD(struct AllenInterp *i) {
 AllenVM_InterpSetCommand(i,TBASE_PLS,   AllenVM_CPU_BASE_PLS,    NULL);                 // Addition.
 AllenVM_InterpSetCommand(i,TBASE_DPLS,  AllenVM_CPU_BASE_DPLS,   NULL);                 // Increment.
 AllenVM_InterpSetCommand(i,TBASE_MIN,   AllenVM_CPU_BASE_MIN,    NULL);                 // Substraction.
 AllenVM_InterpSetCommand(i,TBASE_DMIN,  AllenVM_CPU_BASE_DMIN,   NULL);                 // Decrement.
 AllenVM_InterpSetCommand(i,TBASE_MUL,   AllenVM_CPU_BASE_MUL,    NULL);                 // Multiplication.
 AllenVM_InterpSetCommand(i,TBASE_DMUL,  AllenVM_CPU_BASE_DMUL,   NULL);                 // Square.
 AllenVM_InterpSetCommand(i,TBASE_DIV,   AllenVM_CPU_BASE_DIV,    NULL);                 // Division.
 AllenVM_InterpSetCommand(i,TBASE_DDIV,  AllenVM_CPU_BASE_DDIV,   NULL);                 // Division without floating point.
 AllenVM_InterpSetCommand(i,TBASE_MOD,   AllenVM_CPU_BASE_MOD,    NULL);                 // Modulus.
 AllenVM_InterpSetCommand(i,TBASE_POW,   AllenVM_CPU_BASE_POW,    NULL);                 // Pow.
 AllenVM_InterpSetCommand(i,TBASE_OR,    AllenVM_CPU_BASE_OR,     NULL);                 // Logic OR.
 AllenVM_InterpSetCommand(i,TBASE_AND,   AllenVM_CPU_BASE_AND,    NULL);                 // Logic AND.
 AllenVM_InterpSetCommand(i,TBASE_XOR,   AllenVM_CPU_BASE_XOR,    NULL);                 // Logic XOR.
 AllenVM_InterpSetCommand(i,TBASE_NOT,   AllenVM_CPU_BASE_NOT,    NULL);                 // Logic NOT.
 AllenVM_InterpSetCommand(i,TBASE_GT,    AllenVM_CPU_BASE_GT,     NULL);                 // Greater.
 AllenVM_InterpSetCommand(i,TBASE_GTLT,  AllenVM_CPU_BASE_GTLT,   NULL);                 // Ordered mayor/minor.
 AllenVM_InterpSetCommand(i,TBASE_LT,    AllenVM_CPU_BASE_LT,     NULL);                 // Lesser.
 AllenVM_InterpSetCommand(i,TBASE_LTGT,  AllenVM_CPU_BASE_LTGT,   NULL);                 // Ordered minor/major.
 AllenVM_InterpSetCommand(i,TBASE_EQ,    AllenVM_CPU_BASE_EQ,     NULL);                 // Equal.
 AllenVM_InterpSetCommand(i,TBASE_NQ,    AllenVM_CPU_BASE_NQ,     NULL);                 // Not equal.
 AllenVM_InterpSetCommand(i,TBASE_GEQ,   AllenVM_CPU_BASE_GEQ,    NULL);                 // Greater or equal.
 AllenVM_InterpSetCommand(i,TBASE_LEQ,   AllenVM_CPU_BASE_LEQ,    NULL);                 // Less or equal.
 AllenVM_InterpSetCommand(i,TBASE_SHL,   AllenVM_CPU_BASE_SHL,    NULL);                 // Shift left.
 AllenVM_InterpSetCommand(i,TBASE_SHR,   AllenVM_CPU_BASE_SHR,    NULL);                 // Shift right.
 AllenVM_InterpSetCommand(i,TBASE_INT,   AllenVM_CPU_BASE_INT,    NULL);                 // Integer conversion.
 AllenVM_InterpSetCommand(i,TBASE_FLT,   AllenVM_CPU_BASE_FLT,    NULL);                 // Float conversion.
 AllenVM_InterpSetCommand(i,TBASE_LNG,   AllenVM_CPU_BASE_LNG,    NULL);                 // Long conversion.
 AllenVM_InterpSetCommand(i,TBASE_STR,   AllenVM_CPU_BASE_STR,    NULL);                 // String conversion.
 AllenVM_InterpSetCommand(i,TBASE_BIN,   AllenVM_CPU_BASE_BIN,    NULL);                 // Binary conversion.
 AllenVM_InterpSetCommand(i,TBASE_DEC,   AllenVM_CPU_BASE_DEC,    NULL);                 // Decimal conversion.
 AllenVM_InterpSetCommand(i,TBASE_HEX,   AllenVM_CPU_BASE_HEX,    NULL);                 // Hexadecimal conversion.
 AllenVM_InterpSetCommand(i,TBASE_OCT,   AllenVM_CPU_BASE_OCT,    NULL);                 // Octal conversion.
 AllenVM_InterpSetCommand(i,TBASE_BRK,   AllenVM_CPU_BASE_BRK,    NULL);                 // Break from a block.
 AllenVM_InterpSetCommand(i,TBASE_CON,   AllenVM_CPU_BASE_CON,    NULL);                 // Continue to the next iteration.
 AllenVM_InterpSetCommand(i,TBASE_EVL,   AllenVM_CPU_BASE_EVL,    NULL);                 // Evaluate expression.
 AllenVM_InterpSetCommand(i,TBASE_TRY,   AllenVM_CPU_BASE_TRY,    NULL);                 // Try expression.
}

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