All pastes #718578 Raw Edit

Unnamed

public text v1 · immutable
#718578 ·published 2007-09-28 15:09 UTC
rendered paste body
// =====================================================================================================================================
// allen_cpu_lib_arithmetics.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 <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 TLIB_ARITH_BSIZE  1024     // Buffer size.

// =====================================================================================================================================
// Possible errors.
// =====================================================================================================================================

#define TLIB_ARITH_EDIV  "arith.*: division parameter is zero."     // Error: Division by zero returns indeterminate results.
#define TLIB_ARITH_EMOD  "arith.*: modulus parameter is zero."      // Error: Modulus by zero returns indeterminate results.
#define TLIB_ARITH_EPAR  "arith.*: unexpected or wrong parameters." // Error: Parameters are not satisfied for the command.
#define TLIB_ARITH_EVAL  "arith.*: variable does not exist."        // Error: Variable does not exist in the interpreter.
#define TLIB_ARITH_EHLP  "arith.*: command not found in library."   // Error: Command not found in arithmetic library.

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

#define TLIB_ARITH_PLS   "+"       // Addition.
#define TLIB_ARITH_DPLS  "++"      // Increment.
#define TLIB_ARITH_MIN   "-"       // Substraction.
#define TLIB_ARITH_DMIN  "--"      // Decrement.
#define TLIB_ARITH_MUL   "*"       // Multiplication.
#define TLIB_ARITH_DMUL  "**"      // Square.
#define TLIB_ARITH_DIV   "/"       // Division.
#define TLIB_ARITH_DDIV  "//"      // Division without floating point.
#define TLIB_ARITH_MOD   "mod"     // Modulus.
#define TLIB_ARITH_POW   "pow"     // Pow.

#define TLIB_ARITH_VPLS  "+:"      // Addition in variable.
#define TLIB_ARITH_VDPLS "++:"     // Increment in variable.
#define TLIB_ARITH_VMIN  "-:"      // Substraction in variable.
#define TLIB_ARITH_VDMIN "--:"     // Decrement in variable.
#define TLIB_ARITH_VMUL  "*:"      // Multiplication in variable.
#define TLIB_ARITH_VDMUL "**:"     // Square in variable.
#define TLIB_ARITH_VDIV  "/:"      // Division in variable.
#define TLIB_ARITH_VDDIV "//:"     // Division without floating point in variable.
#define TLIB_ARITH_VMOD  "mod:"    // Modulus in variable.
#define TLIB_ARITH_VPOW  "pow:"    // Pow in variable.

// =====================================================================================================================================
// Helper Function.
// =====================================================================================================================================

#define TLIB_ARITH_HLP   "arith.?" // Helper function.
#define TLIB_ARITH_NIL   "nil"     // Null value.

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

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

// Index:                              Example:  Result:
// AllenVM_CPU_LIB_ARITH_PLS();   ::  + 2 3 4    9.000000
// AllenVM_CPU_LIB_ARITH_DPLS();  ::  ++ 2       3.000000
// AllenVM_CPU_LIB_ARITH_MIN();   ::  - 2 3 4   -5.000000
// AllenVM_CPU_LIB_ARITH_DMIN();  ::  -- 2       1.000000
// AllenVM_CPU_LIB_ARITH_MUL();   ::  * 2 3 4   24.000000
// AllenVM_CPU_LIB_ARITH_DMUL();  ::  ** 2       4.000000
// AllenVM_CPU_LIB_ARITH_DIV();   ::  / 2 3 4    0.166667
// AllenVM_CPU_LIB_ARITH_DDIV();  ::  // 2 3     0      
// AllenVM_CPU_LIB_ARITH_MOD();   ::  mod 10 3   1.000000
// AllenVM_CPU_LIB_ARITH_POW();   ::  pow 2 4   16.000000

// Index:                              Example:  Result:
// AllenVM_CPU_LIB_ARITH_VPLS();  ::  +: x 10    var.def x [+ $x 10]
// AllenVM_CPU_LIB_ARITH_VDPLS(); ::  ++: x      var.def x [++ $x]
// AllenVM_CPU_LIB_ARITH_VMIN();  ::  -: x 10    var.def x [- $x 10]
// AllenVM_CPU_LIB_ARITH_VDMIN(); ::  --: x      var.def x [-- $x]
// AllenVM_CPU_LIB_ARITH_VMUL();  ::  *: x 10    var.def x [* $x 10]
// AllenVM_CPU_LIB_ARITH_VDMUL(); ::  **: x      var.def x [** $x]
// AllenVM_CPU_LIB_ARITH_VDIV();  ::  /: x 10    var.def x [/ $x 10]
// AllenVM_CPU_LIB_ARITH_VDDIV(); ::  //: x 10   var.def x [// $x 10]
// AllenVM_CPU_LIB_ARITH_VMOD();  ::  mod: x 10  var.def x [mod $x 10]
// AllenVM_CPU_LIB_ARITH_VPOW();  ::  pow: x 10  var.def x [pow $x 10]

// Total: 20.

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

static int AllenVM_CPU_LIB_ARITH_PLS(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc < 2) return AllenVM_CPU_Error(i,TLIB_ARITH_EPAR);                               // Check parameters.
 register int p, op=1; register float c=atof(argv[1]);                                   // Parameters.

 for(p=2; p<argc; ++p) {                                                                 // Loop through parameters.
  if(atof(argv[p])==0) {                                                                 // Check if we want to change operator.
   if(!strcmp(TLIB_ARITH_PLS,argv[p])) { op = 1; continue; }                             // Change operator: Addition.
   if(!strcmp(TLIB_ARITH_MIN,argv[p])) { op = 2; continue; }                             // Change operator: Substraction.
   if(!strcmp(TLIB_ARITH_MUL,argv[p])) { op = 3; continue; }                             // Change operator: Multiplication.
   if(!strcmp(TLIB_ARITH_DIV,argv[p])) { op = 4; continue; }                             // Change operator: Division.
   if(!strcmp(TLIB_ARITH_MOD,argv[p])) { op = 5; continue; }                             // Change operator: Modulus.
   if(!strcmp(TLIB_ARITH_POW,argv[p])) { op = 6; continue; }                             // Change operator: Pow.
  }
  switch(op) {                                                                           // Check current operator.
   case 1: c += atof(argv[p]); break;                                                    // Operate: Addition.
   case 2: c -= atof(argv[p]); break;                                                    // Operate: Substraction.
   case 3: c *= atof(argv[p]); break;                                                    // Operate: Multiplication.
   case 4: c /= atof(argv[p]); break;                                                    // Operate: Division.
   case 5: c = (int) c % atoi(argv[p]); break;                                           // Operate: Modulus.
   case 6: c = pow(c,atof(argv[p])); break;                                              // Operate: Pow.
  }}

 char buf[TLIB_ARITH_BSIZE];                                                             // Create buffer.
 snprintf(buf,TLIB_ARITH_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_ARITH_DPLS();
// Purpose:     Increment.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_ARITH_DPLS(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,TLIB_ARITH_EPAR);                              // Check parameters.
 register float c=atof(argv[1])+1;                                                       // Operate.

 char buf[TLIB_ARITH_BSIZE];                                                             // Create buffer.
 snprintf(buf,TLIB_ARITH_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_ARITH_MIN();
// Purpose:     Substraction.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_ARITH_MIN(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc < 2) return AllenVM_CPU_Error(i,TLIB_ARITH_EPAR);                               // Check parameters.
 register int p, op=2; register float c=atof(argv[1]);                                   // Parameters.

 for(p=2; p<argc; ++p) {                                                                 // Loop through parameters.
  if(atof(argv[p])==0) {                                                                 // Check if we want to change operator.
   if(!strcmp(TLIB_ARITH_PLS,argv[p])) { op = 1; continue; }                             // Change operator: Addition.
   if(!strcmp(TLIB_ARITH_MIN,argv[p])) { op = 2; continue; }                             // Change operator: Substraction.
   if(!strcmp(TLIB_ARITH_MUL,argv[p])) { op = 3; continue; }                             // Change operator: Multiplication.
   if(!strcmp(TLIB_ARITH_DIV,argv[p])) { op = 4; continue; }                             // Change operator: Division.
   if(!strcmp(TLIB_ARITH_MOD,argv[p])) { op = 5; continue; }                             // Change operator: Modulus.
   if(!strcmp(TLIB_ARITH_POW,argv[p])) { op = 6; continue; }                             // Change operator: Pow.
  }
  switch(op) {                                                                           // Check current operator.
   case 1: c += atof(argv[p]); break;                                                    // Operate: Addition.
   case 2: c -= atof(argv[p]); break;                                                    // Operate: Substraction.
   case 3: c *= atof(argv[p]); break;                                                    // Operate: Multiplication.
   case 4: c /= atof(argv[p]); break;                                                    // Operate: Division.
   case 5: c = (int) c % atoi(argv[p]); break;                                           // Operate: Modulus.
   case 6: c = pow(c,atof(argv[p])); break;                                              // Operate: Pow.
  }}

 char buf[TLIB_ARITH_BSIZE];                                                             // Create buffer.
 snprintf(buf,TLIB_ARITH_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_ARITH_DMIN();
// Purpose:     Decrement.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_ARITH_DMIN(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,TLIB_ARITH_EPAR);                              // Check parameters.
 register float c=atof(argv[1])-1;                                                       // Operate.
 
 char buf[TLIB_ARITH_BSIZE];                                                             // Create buffer.
 snprintf(buf,TLIB_ARITH_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_ARITH_MUL();
// Purpose:     Multiplication.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_ARITH_MUL(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc < 2) return AllenVM_CPU_Error(i,TLIB_ARITH_EPAR);                               // Check parameters.
 register int p, op=3; register float c=atof(argv[1]);                                   // Parameters.

 for(p=2; p<argc; ++p) {                                                                 // Loop through parameters.
  if(atof(argv[p])==0) {                                                                 // Check if we want to change operator.
   if(!strcmp(TLIB_ARITH_PLS,argv[p])) { op = 1; continue; }                             // Change operator: Addition.
   if(!strcmp(TLIB_ARITH_MIN,argv[p])) { op = 2; continue; }                             // Change operator: Substraction.
   if(!strcmp(TLIB_ARITH_MUL,argv[p])) { op = 3; continue; }                             // Change operator: Multiplication.
   if(!strcmp(TLIB_ARITH_DIV,argv[p])) { op = 4; continue; }                             // Change operator: Division.
   if(!strcmp(TLIB_ARITH_MOD,argv[p])) { op = 5; continue; }                             // Change operator: Modulus.
   if(!strcmp(TLIB_ARITH_POW,argv[p])) { op = 6; continue; }                             // Change operator: Pow.
  }
  switch(op) {                                                                           // Check current operator.
   case 1: c += atof(argv[p]); break;                                                    // Operate: Addition.
   case 2: c -= atof(argv[p]); break;                                                    // Operate: Substraction.
   case 3: c *= atof(argv[p]); break;                                                    // Operate: Multiplication.
   case 4: c /= atof(argv[p]); break;                                                    // Operate: Division.
   case 5: c = (int) c % atoi(argv[p]); break;                                           // Operate: Modulus.
   case 6: c = pow(c,atof(argv[p])); break;                                              // Operate: Pow.
  }}

 char buf[TLIB_ARITH_BSIZE];                                                             // Create buffer.
 snprintf(buf,TLIB_ARITH_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_ARITH_DMUL();
// Purpose:     Square.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_ARITH_DMUL(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,TLIB_ARITH_EPAR);                              // Check parameters.
 register float c=atof(argv[1])*atof(argv[1]);                                           // Operate.

 char buf[TLIB_ARITH_BSIZE];                                                             // Create buffer.
 snprintf(buf,TLIB_ARITH_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_ARITH_DIV();
// Purpose:     Division.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_ARITH_DIV(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc < 2) return AllenVM_CPU_Error(i,TLIB_ARITH_EPAR);                               // Check parameters.
 register int p, op=4; register float c=atof(argv[1]);                                   // Parameters.

 for(p=2; p<argc; ++p) {                                                                 // Loop through parameters.
  if(atof(argv[p])==0) {                                                                 // Check if we want to change operator.
   if(!strcmp(TLIB_ARITH_PLS,argv[p])) { op = 1; continue; }                             // Change operator: Addition.
   if(!strcmp(TLIB_ARITH_MIN,argv[p])) { op = 2; continue; }                             // Change operator: Substraction.
   if(!strcmp(TLIB_ARITH_MUL,argv[p])) { op = 3; continue; }                             // Change operator: Multiplication.
   if(!strcmp(TLIB_ARITH_DIV,argv[p])) { op = 4; continue; }                             // Change operator: Division.
   if(!strcmp(TLIB_ARITH_MOD,argv[p])) { op = 5; continue; }                             // Change operator: Modulus.
   if(!strcmp(TLIB_ARITH_POW,argv[p])) { op = 6; continue; }                             // Change operator: Pow.
  }
  switch(op) {                                                                           // Check current operator.
   case 1: c += atof(argv[p]); break;                                                    // Operate: Addition.
   case 2: c -= atof(argv[p]); break;                                                    // Operate: Substraction.
   case 3: c *= atof(argv[p]); break;                                                    // Operate: Multiplication.
   case 4: c /= atof(argv[p]); break;                                                    // Operate: Division.
   case 5: c = (int) c % atoi(argv[p]); break;                                           // Operate: Modulus.
   case 6: c = pow(c,atof(argv[p])); break;                                              // Operate: Pow.
  }}

 char buf[TLIB_ARITH_BSIZE];                                                             // Create buffer.
 snprintf(buf,TLIB_ARITH_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_ARITH_DDIV();
// Purpose:     Division without floating point.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_ARITH_DDIV(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc < 2) return AllenVM_CPU_Error(i,TLIB_ARITH_EPAR);                               // Check parameters.
 register int p; register float c=atof(argv[1]);                                         // Parameters.

 for(p=2; p<argc; ++p) {                                                                 // Loop through parameters.
   if(atof(argv[p]) == 0) return AllenVM_CPU_Error(i,TLIB_ARITH_EDIV);                   // Check for errors.
   c /= atof(argv[p]); }                                                                 // Division.
 
 char buf[TLIB_ARITH_BSIZE];                                                             // Create buffer.
 snprintf(buf,TLIB_ARITH_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_LIB_ARITH_MOD();
// Purpose:     Modulus.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_ARITH_MOD(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc < 2) return AllenVM_CPU_Error(i,TLIB_ARITH_EPAR);                               // Check parameters.
 register int p, op=5; register float c=atof(argv[1]);                                   // Parameters.

 for(p=2; p<argc; ++p) {                                                                 // Loop through parameters.
  if(atof(argv[p])==0) {                                                                 // Check if we want to change operator.
   if(!strcmp(TLIB_ARITH_PLS,argv[p])) { op = 1; continue; }                             // Change operator: Addition.
   if(!strcmp(TLIB_ARITH_MIN,argv[p])) { op = 2; continue; }                             // Change operator: Substraction.
   if(!strcmp(TLIB_ARITH_MUL,argv[p])) { op = 3; continue; }                             // Change operator: Multiplication.
   if(!strcmp(TLIB_ARITH_DIV,argv[p])) { op = 4; continue; }                             // Change operator: Division.
   if(!strcmp(TLIB_ARITH_MOD,argv[p])) { op = 5; continue; }                             // Change operator: Modulus.
   if(!strcmp(TLIB_ARITH_POW,argv[p])) { op = 6; continue; }                             // Change operator: Pow.
  }
  switch(op) {                                                                           // Check current operator.
   case 1: c += atof(argv[p]); break;                                                    // Operate: Addition.
   case 2: c -= atof(argv[p]); break;                                                    // Operate: Substraction.
   case 3: c *= atof(argv[p]); break;                                                    // Operate: Multiplication.
   case 4: c /= atof(argv[p]); break;                                                    // Operate: Division.
   case 5: c = (int) c % atoi(argv[p]); break;                                           // Operate: Modulus.
   case 6: c = pow(c,atof(argv[p])); break;                                              // Operate: Pow.
  }}

 char buf[TLIB_ARITH_BSIZE];                                                             // Create buffer.
 snprintf(buf,TLIB_ARITH_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_ARITH_POW();
// Purpose:     Pow.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_ARITH_POW(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc < 2) return AllenVM_CPU_Error(i,TLIB_ARITH_EPAR);                               // Check parameters.
 register int p, op=6; register float c=atof(argv[1]);                                   // Parameters.

 for(p=2; p<argc; ++p) {                                                                 // Loop through parameters.
  if(atof(argv[p])==0) {                                                                 // Check if we want to change operator.
   if(!strcmp(TLIB_ARITH_PLS,argv[p])) { op = 1; continue; }                             // Change operator: Addition.
   if(!strcmp(TLIB_ARITH_MIN,argv[p])) { op = 2; continue; }                             // Change operator: Substraction.
   if(!strcmp(TLIB_ARITH_MUL,argv[p])) { op = 3; continue; }                             // Change operator: Multiplication.
   if(!strcmp(TLIB_ARITH_DIV,argv[p])) { op = 4; continue; }                             // Change operator: Division.
   if(!strcmp(TLIB_ARITH_MOD,argv[p])) { op = 5; continue; }                             // Change operator: Modulus.
   if(!strcmp(TLIB_ARITH_POW,argv[p])) { op = 6; continue; }                             // Change operator: Pow.
  }
  switch(op) {                                                                           // Check current operator.
   case 1: c += atof(argv[p]); break;                                                    // Operate: Addition.
   case 2: c -= atof(argv[p]); break;                                                    // Operate: Substraction.
   case 3: c *= atof(argv[p]); break;                                                    // Operate: Multiplication.
   case 4: c /= atof(argv[p]); break;                                                    // Operate: Division.
   case 5: c = (int) c % atoi(argv[p]); break;                                           // Operate: Modulus.
   case 6: c = pow(c,atof(argv[p])); break;                                              // Operate: Pow.
  }}

 char buf[TLIB_ARITH_BSIZE];                                                             // Create buffer.
 snprintf(buf,TLIB_ARITH_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_ARITH_VPLS();
// Purpose:     Addition in variable.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_ARITH_VPLS(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc < 3) return AllenVM_CPU_Error(i,TLIB_ARITH_EPAR);                               // Check parameters.
 struct AllenVar *v;                                                                     // Variable struct.
 if((v = (void*) AllenVM_InterpGetVar(i,argv[1])) == NULL)                               // Check variable for existence.
  return AllenVM_CPU_Error(i,TLIB_ARITH_EVAL);                                           // Does not exist, error.

 register int p, op=1; register float c=atof(v->c_val);                                  // Parameters.
 for(p=2; p<argc; ++p) {                                                                 // Loop through parameters.
  if(atof(argv[p])==0) {                                                                 // Check if we want to change operator.
   if(!strcmp(TLIB_ARITH_PLS,argv[p])) { op = 1; continue; }                             // Change operator: Addition.
   if(!strcmp(TLIB_ARITH_MIN,argv[p])) { op = 2; continue; }                             // Change operator: Substraction.
   if(!strcmp(TLIB_ARITH_MUL,argv[p])) { op = 3; continue; }                             // Change operator: Multiplication.
   if(!strcmp(TLIB_ARITH_DIV,argv[p])) { op = 4; continue; }                             // Change operator: Division.
   if(!strcmp(TLIB_ARITH_MOD,argv[p])) { op = 5; continue; }                             // Change operator: Modulus.
   if(!strcmp(TLIB_ARITH_POW,argv[p])) { op = 6; continue; }                             // Change operator: Pow.
  }
  switch(op) {                                                                           // Check current operator.
   case 1: c += atof(argv[p]); break;                                                    // Operate: Addition.
   case 2: c -= atof(argv[p]); break;                                                    // Operate: Substraction.
   case 3: c *= atof(argv[p]); break;                                                    // Operate: Multiplication.
   case 4: c /= atof(argv[p]); break;                                                    // Operate: Division.
   case 5: c = (int) c % atoi(argv[p]); break;                                           // Operate: Modulus.
   case 6: c = pow(c,atof(argv[p])); break;                                              // Operate: Pow.
  }}

 char buf[TLIB_ARITH_BSIZE];                                                             // Create buffer.
 snprintf(buf,TLIB_ARITH_BSIZE,"%f",c);                                                  // Copy result to buffer as float.
 if((p=AllenVM_InterpSetVar(i,argv[1],buf,0)) != Allen_VM_OK) return p;                  // Set the new variable value.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_ARITH_VDPLS();
// Purpose:     Increment in variable.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_ARITH_VDPLS(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,TLIB_ARITH_EPAR);                              // Check parameters.
 struct AllenVar *v;                                                                     // Variable struct.
 if((v = (void*) AllenVM_InterpGetVar(i,argv[1])) == NULL)                               // Check variable for existence.
  return AllenVM_CPU_Error(i,TLIB_ARITH_EVAL);                                           // Does not exist, error.

 register float c=atof(v->c_val)+1;                                                      // Operate.
 register int p;                                                                         // Variable assignement result.

 char buf[TLIB_ARITH_BSIZE];                                                             // Create buffer.
 snprintf(buf,TLIB_ARITH_BSIZE,"%f",c);                                                  // Copy result to buffer as float.
 if((p=AllenVM_InterpSetVar(i,argv[1],buf,0)) != Allen_VM_OK) return p;                  // Set the new variable value.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_ARITH_VMIN();
// Purpose:     Substraction in variable.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_ARITH_VMIN(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc < 3) return AllenVM_CPU_Error(i,TLIB_ARITH_EPAR);                               // Check parameters.
 struct AllenVar *v;                                                                     // Variable struct.
 if((v = (void*) AllenVM_InterpGetVar(i,argv[1])) == NULL)                               // Check variable for existence.
  return AllenVM_CPU_Error(i,TLIB_ARITH_EVAL);                                           // Does not exist, error.

 register int p, op=2; register float c=atof(v->c_val);                                  // Parameters.
 for(p=2; p<argc; ++p) {                                                                 // Loop through parameters.
  if(atof(argv[p])==0) {                                                                 // Check if we want to change operator.
   if(!strcmp(TLIB_ARITH_PLS,argv[p])) { op = 1; continue; }                             // Change operator: Addition.
   if(!strcmp(TLIB_ARITH_MIN,argv[p])) { op = 2; continue; }                             // Change operator: Substraction.
   if(!strcmp(TLIB_ARITH_MUL,argv[p])) { op = 3; continue; }                             // Change operator: Multiplication.
   if(!strcmp(TLIB_ARITH_DIV,argv[p])) { op = 4; continue; }                             // Change operator: Division.
   if(!strcmp(TLIB_ARITH_MOD,argv[p])) { op = 5; continue; }                             // Change operator: Modulus.
   if(!strcmp(TLIB_ARITH_POW,argv[p])) { op = 6; continue; }                             // Change operator: Pow.
  }
  switch(op) {                                                                           // Check current operator.
   case 1: c += atof(argv[p]); break;                                                    // Operate: Addition.
   case 2: c -= atof(argv[p]); break;                                                    // Operate: Substraction.
   case 3: c *= atof(argv[p]); break;                                                    // Operate: Multiplication.
   case 4: c /= atof(argv[p]); break;                                                    // Operate: Division.
   case 5: c = (int) c % atoi(argv[p]); break;                                           // Operate: Modulus.
   case 6: c = pow(c,atof(argv[p])); break;                                              // Operate: Pow.
  }}

 char buf[TLIB_ARITH_BSIZE];                                                             // Create buffer.
 snprintf(buf,TLIB_ARITH_BSIZE,"%f",c);                                                  // Copy result to buffer as float.
 if((p=AllenVM_InterpSetVar(i,argv[1],buf,0)) != Allen_VM_OK) return p;                  // Set the new variable value.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_ARITH_VDMIN();
// Purpose:     Decrement in variable.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_ARITH_VDMIN(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,TLIB_ARITH_EPAR);                              // Check parameters.
 struct AllenVar *v;                                                                     // Variable struct.
 if((v = (void*) AllenVM_InterpGetVar(i,argv[1])) == NULL)                               // Check variable for existence.
  return AllenVM_CPU_Error(i,TLIB_ARITH_EVAL);                                           // Does not exist, error.

 register float c=atof(v->c_val)-1;                                                      // Operate.
 register int p;                                                                         // Variable assignement result.

 char buf[TLIB_ARITH_BSIZE];                                                             // Create buffer.
 snprintf(buf,TLIB_ARITH_BSIZE,"%f",c);                                                  // Copy result to buffer as float.
 if((p=AllenVM_InterpSetVar(i,argv[1],buf,0)) != Allen_VM_OK) return p;                  // Set the new variable value.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_ARITH_VMUL();
// Purpose:     Multiplication in variable.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_ARITH_VMUL(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc < 3) return AllenVM_CPU_Error(i,TLIB_ARITH_EPAR);                               // Check parameters.
 struct AllenVar *v;                                                                     // Variable struct.
 if((v = (void*) AllenVM_InterpGetVar(i,argv[1])) == NULL)                               // Check variable for existence.
  return AllenVM_CPU_Error(i,TLIB_ARITH_EVAL);                                           // Does not exist, error.

 register int p, op=3; register float c=atof(v->c_val);                                  // Parameters.
 for(p=2; p<argc; ++p) {                                                                 // Loop through parameters.
  if(atof(argv[p])==0) {                                                                 // Check if we want to change operator.
   if(!strcmp(TLIB_ARITH_PLS,argv[p])) { op = 1; continue; }                             // Change operator: Addition.
   if(!strcmp(TLIB_ARITH_MIN,argv[p])) { op = 2; continue; }                             // Change operator: Substraction.
   if(!strcmp(TLIB_ARITH_MUL,argv[p])) { op = 3; continue; }                             // Change operator: Multiplication.
   if(!strcmp(TLIB_ARITH_DIV,argv[p])) { op = 4; continue; }                             // Change operator: Division.
   if(!strcmp(TLIB_ARITH_MOD,argv[p])) { op = 5; continue; }                             // Change operator: Modulus.
   if(!strcmp(TLIB_ARITH_POW,argv[p])) { op = 6; continue; }                             // Change operator: Pow.
  }
  switch(op) {                                                                           // Check current operator.
   case 1: c += atof(argv[p]); break;                                                    // Operate: Addition.
   case 2: c -= atof(argv[p]); break;                                                    // Operate: Substraction.
   case 3: c *= atof(argv[p]); break;                                                    // Operate: Multiplication.
   case 4: c /= atof(argv[p]); break;                                                    // Operate: Division.
   case 5: c = (int) c % atoi(argv[p]); break;                                           // Operate: Modulus.
   case 6: c = pow(c,atof(argv[p])); break;                                              // Operate: Pow.
  }}

 char buf[TLIB_ARITH_BSIZE];                                                             // Create buffer.
 snprintf(buf,TLIB_ARITH_BSIZE,"%f",c);                                                  // Copy result to buffer as float.
 if((p=AllenVM_InterpSetVar(i,argv[1],buf,0)) != Allen_VM_OK) return p;                  // Set the new variable value.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_ARITH_VDMUL();
// Purpose:     Square in variable.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_ARITH_VDMUL(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc != 2) return AllenVM_CPU_Error(i,TLIB_ARITH_EPAR);                              // Check parameters.
 struct AllenVar *v;                                                                     // Variable struct.
 if((v = (void*) AllenVM_InterpGetVar(i,argv[1])) == NULL)                               // Check variable for existence.
  return AllenVM_CPU_Error(i,TLIB_ARITH_EVAL);                                           // Does not exist, error.

 register float c=atof(v->c_val) * atof(v->c_val);                                       // Operate.
 register int p;                                                                         // Variable assignement result.

 char buf[TLIB_ARITH_BSIZE];                                                             // Create buffer.
 snprintf(buf,TLIB_ARITH_BSIZE,"%f",c);                                                  // Copy result to buffer as float.
 if((p=AllenVM_InterpSetVar(i,argv[1],buf,0)) != Allen_VM_OK) return p;                  // Set the new variable value.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_ARITH_VDIV();
// Purpose:     Division in variable.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_ARITH_VDIV(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc < 3) return AllenVM_CPU_Error(i,TLIB_ARITH_EPAR);                               // Check parameters.
 struct AllenVar *v;                                                                     // Variable struct.
 if((v = (void*) AllenVM_InterpGetVar(i,argv[1])) == NULL)                               // Check variable for existence.
  return AllenVM_CPU_Error(i,TLIB_ARITH_EVAL);                                           // Does not exist, error.

 register int p, op=4; register float c=atof(v->c_val);                                  // Parameters.
 for(p=2; p<argc; ++p) {                                                                 // Loop through parameters.
  if(atof(argv[p])==0) {                                                                 // Check if we want to change operator.
   if(!strcmp(TLIB_ARITH_PLS,argv[p])) { op = 1; continue; }                             // Change operator: Addition.
   if(!strcmp(TLIB_ARITH_MIN,argv[p])) { op = 2; continue; }                             // Change operator: Substraction.
   if(!strcmp(TLIB_ARITH_MUL,argv[p])) { op = 3; continue; }                             // Change operator: Multiplication.
   if(!strcmp(TLIB_ARITH_DIV,argv[p])) { op = 4; continue; }                             // Change operator: Division.
   if(!strcmp(TLIB_ARITH_MOD,argv[p])) { op = 5; continue; }                             // Change operator: Modulus.
   if(!strcmp(TLIB_ARITH_POW,argv[p])) { op = 6; continue; }                             // Change operator: Pow.
  }
  switch(op) {                                                                           // Check current operator.
   case 1: c += atof(argv[p]); break;                                                    // Operate: Addition.
   case 2: c -= atof(argv[p]); break;                                                    // Operate: Substraction.
   case 3: c *= atof(argv[p]); break;                                                    // Operate: Multiplication.
   case 4: c /= atof(argv[p]); break;                                                    // Operate: Division.
   case 5: c = (int) c % atoi(argv[p]); break;                                           // Operate: Modulus.
   case 6: c = pow(c,atof(argv[p])); break;                                              // Operate: Pow.
  }}

 char buf[TLIB_ARITH_BSIZE];                                                             // Create buffer.
 snprintf(buf,TLIB_ARITH_BSIZE,"%f",c);                                                  // Copy result to buffer as float.
 if((p=AllenVM_InterpSetVar(i,argv[1],buf,0)) != Allen_VM_OK) return p;                  // Set the new variable value.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_ARITH_VDDIV();
// Purpose:     Division without floating point in variable.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_ARITH_VDDIV(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc < 3) return AllenVM_CPU_Error(i,TLIB_ARITH_EPAR);                               // Check parameters.
 struct AllenVar *v;                                                                     // Variable struct.
 if((v = (void*) AllenVM_InterpGetVar(i,argv[1])) == NULL)                               // Check variable for existence.
  return AllenVM_CPU_Error(i,TLIB_ARITH_EVAL);                                           // Does not exist, error.

 register int p; register float c=atof(v->c_val);                                        // Parameters.
 for(p=2; p<argc; ++p) c/=atof(argv[p]);                                                 // Operate.

 char buf[TLIB_ARITH_BSIZE];                                                             // Create buffer.
 snprintf(buf,TLIB_ARITH_BSIZE,"%d",(int) c);                                            // Copy result to buffer as integer.
 if((p=AllenVM_InterpSetVar(i,argv[1],buf,0)) != Allen_VM_OK) return p;                  // Set the new variable value.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_ARITH_VMOD();
// Purpose:     Modulus in variable.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_ARITH_VMOD(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc < 3) return AllenVM_CPU_Error(i,TLIB_ARITH_EPAR);                               // Check parameters.
 struct AllenVar *v;                                                                     // Variable struct.
 if((v = (void*) AllenVM_InterpGetVar(i,argv[1])) == NULL)                               // Check variable for existence.
  return AllenVM_CPU_Error(i,TLIB_ARITH_EVAL);                                           // Does not exist, error.

 register int p, op=5; register float c=atof(v->c_val);                                  // Parameters.
 for(p=2; p<argc; ++p) {                                                                 // Loop through parameters.
  if(atof(argv[p])==0) {                                                                 // Check if we want to change operator.
   if(!strcmp(TLIB_ARITH_PLS,argv[p])) { op = 1; continue; }                             // Change operator: Addition.
   if(!strcmp(TLIB_ARITH_MIN,argv[p])) { op = 2; continue; }                             // Change operator: Substraction.
   if(!strcmp(TLIB_ARITH_MUL,argv[p])) { op = 3; continue; }                             // Change operator: Multiplication.
   if(!strcmp(TLIB_ARITH_DIV,argv[p])) { op = 4; continue; }                             // Change operator: Division.
   if(!strcmp(TLIB_ARITH_MOD,argv[p])) { op = 5; continue; }                             // Change operator: Modulus.
   if(!strcmp(TLIB_ARITH_POW,argv[p])) { op = 6; continue; }                             // Change operator: Pow.
  }
  switch(op) {                                                                           // Check current operator.
   case 1: c += atof(argv[p]); break;                                                    // Operate: Addition.
   case 2: c -= atof(argv[p]); break;                                                    // Operate: Substraction.
   case 3: c *= atof(argv[p]); break;                                                    // Operate: Multiplication.
   case 4: c /= atof(argv[p]); break;                                                    // Operate: Division.
   case 5: c = (int) c % atoi(argv[p]); break;                                           // Operate: Modulus.
   case 6: c = pow(c,atof(argv[p])); break;                                              // Operate: Pow.
  }}

 char buf[TLIB_ARITH_BSIZE];                                                             // Create buffer.
 snprintf(buf,TLIB_ARITH_BSIZE,"%f",c);                                                  // Copy result to buffer as float.
 if((p=AllenVM_InterpSetVar(i,argv[1],buf,0)) != Allen_VM_OK) return p;                  // Set the new variable value.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_ARITH_VPOW();
// Purpose:     Pow in variable.
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

static int AllenVM_CPU_LIB_ARITH_VPOW(struct AllenInterp *i, int argc, char **argv, void *pd) {
 if(argc < 3) return AllenVM_CPU_Error(i,TLIB_ARITH_EPAR);                               // Check parameters.
 struct AllenVar *v;                                                                     // Variable struct.
 if((v = (void*) AllenVM_InterpGetVar(i,argv[1])) == NULL)                               // Check variable for existence.
  return AllenVM_CPU_Error(i,TLIB_ARITH_EVAL);                                           // Does not exist, error.

 register int p, op=6; register float c=atof(v->c_val);                                  // Parameters.
 for(p=2; p<argc; ++p) {                                                                 // Loop through parameters.
  if(atof(argv[p])==0) {                                                                 // Check if we want to change operator.
   if(!strcmp(TLIB_ARITH_PLS,argv[p])) { op = 1; continue; }                             // Change operator: Addition.
   if(!strcmp(TLIB_ARITH_MIN,argv[p])) { op = 2; continue; }                             // Change operator: Substraction.
   if(!strcmp(TLIB_ARITH_MUL,argv[p])) { op = 3; continue; }                             // Change operator: Multiplication.
   if(!strcmp(TLIB_ARITH_DIV,argv[p])) { op = 4; continue; }                             // Change operator: Division.
   if(!strcmp(TLIB_ARITH_MOD,argv[p])) { op = 5; continue; }                             // Change operator: Modulus.
   if(!strcmp(TLIB_ARITH_POW,argv[p])) { op = 6; continue; }                             // Change operator: Pow.
  }
  switch(op) {                                                                           // Check current operator.
   case 1: c += atof(argv[p]); break;                                                    // Operate: Addition.
   case 2: c -= atof(argv[p]); break;                                                    // Operate: Substraction.
   case 3: c *= atof(argv[p]); break;                                                    // Operate: Multiplication.
   case 4: c /= atof(argv[p]); break;                                                    // Operate: Division.
   case 5: c = (int) c % atoi(argv[p]); break;                                           // Operate: Modulus.
   case 6: c = pow(c,atof(argv[p])); break;                                              // Operate: Pow.
  }}

 char buf[TLIB_ARITH_BSIZE];                                                             // Create buffer.
 snprintf(buf,TLIB_ARITH_BSIZE,"%f",c);                                                  // Copy result to buffer as float.
 if((p=AllenVM_InterpSetVar(i,argv[1],buf,0)) != Allen_VM_OK) return p;                  // Set the new variable value.
 AllenVM_InterpSetResult(i,buf);                                                         // Set interpreter result.
 return Allen_VM_OK;                                                                     // Everything ok.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_ARITH_HLP();
// Purpose:     Adds help facilities
// Returns:     Expression result.
// -------------------------------------------------------------------------------------------------------------------------------------

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

 if(!strcmp(TLIB_ARITH_PLS,argv[1])) {                                                   // Compare parameters.
  puts("Description: Adds a list of numbers.");                                          // Description.
  puts("Returns: Float number from expression result. ");                                // Returns.
  puts("Sample: + 2 2 3 4 => 11.000000");                                                // Sample function.
  puts("Parameters: min: 1 max: ANY");                                                   // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_ARITH_PLS);                                             // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.
 
 if(!strcmp(TLIB_ARITH_DPLS,argv[1])) {                                                  // Compare parameters.
  puts("Description: Increments it's parameter by one.");                                // Description.
  puts("Returns: Float number from expression result. ");                                // Returns.
  puts("Sample: ++ 5 => 6.000000");                                                      // Sample function.
  puts("Parameters: min: 1 max: 1");                                                     // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_ARITH_DPLS);                                            // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_ARITH_MIN,argv[1])) {                                                   // Compare parameters.
  puts("Description: Substracts a list of numbers.");                                    // Description.
  puts("Returns: Float number from expression result. ");                                // Returns.
  puts("Sample: - 5 10 21 => - 26.000000");                                              // Sample function.
  puts("Parameters: min: 1 max: ANY");                                                   // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_ARITH_MIN);                                             // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_ARITH_DMIN,argv[1])) {                                                  // Compare parameters.
  puts("Description: Decrements it's parameter by one.");                                // Description.
  puts("Returns: Float number from expression result. ");                                // Returns.
  puts("Sample: -- 5 => 4.000000");                                                      // Sample function.
  puts("Parameters: min: 1 max: 1");                                                     // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_ARITH_DMIN);                                            // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_ARITH_MUL,argv[1])) {                                                   // Compare parameters.
  puts("Description: Multiplies a list of numbers.");                                    // Description.
  puts("Returns: Float number from expression result. ");                                // Returns.
  puts("Sample: * 5 4 2 => 40.000000");                                                  // Sample function.
  puts("Parameters: min: 1 max: ANY");                                                   // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_ARITH_MUL);                                             // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_ARITH_DMUL,argv[1])) {                                                  // Compare parameters.
  puts("Description: Calculates the square of a number.");                               // Description.
  puts("Returns: Float number from expression result. ");                                // Returns.
  puts("Sample: ** 10 => 100.000000");                                                   // Sample function.
  puts("Parameters: min: 1 max: 1");                                                     // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_ARITH_DMUL);                                            // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_ARITH_DIV,argv[1])) {                                                   // Compare parameters.
  puts("Description: Divides a list of numbers.");                                       // Description.
  puts("Returns: Float number from expression result. ");                                // Returns.
  puts("Sample: / 5 2 1 => 2.500000");                                                   // Sample function.
  puts("Parameters: min: 1 max: ANY");                                                   // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_ARITH_DIV);                                             // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_ARITH_DDIV,argv[1])) {                                                  // Compare parameters.
  puts("Description: Divides a list of numbers.");                                       // Description.
  puts("Returns: Integer number from expression result. ");                              // Returns.
  puts("Sample: // 5 2 1 => 2.000000");                                                  // Sample function.
  puts("Parameters: min: 1 max: ANY");                                                   // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_ARITH_DDIV);                                            // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_ARITH_MOD,argv[1])) {                                                   // Compare parameters.
  puts("Description: Calculates modulus of a division.");                                // Description.
  puts("Returns: Float number from expression result. ");                                // Returns.
  puts("Sample: mod 10 3 => 1.000000");                                                  // Sample function.
  puts("Parameters: min: 1 max: ANY");                                                   // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_ARITH_MOD);                                             // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.
 
 if(!strcmp(TLIB_ARITH_POW,argv[1])) {                                                   // Compare parameters.
  puts("Description: Calculates the pow of a list of numbers.");                         // Description.
  puts("Returns: Float number from expression result. ");                                // Returns.
  puts("Sample: pow 2 3 => 8.000000");                                                   // Sample function.
  puts("Parameters: min: 1 max: ANY");                                                   // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_ARITH_POW);                                             // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_ARITH_VPLS,argv[1])) {                                                  // Compare parameters.
  puts("Description: Adds a list of numbers to a variable.");                            // Description.
  puts("Returns: Float number from expression result. ");                                // Returns.
  puts("Sample: +: x 10 => var.def x [+ $x 10]");                                        // Sample function.
  puts("Parameters: min: 2 max: ANY");                                                   // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_ARITH_VPLS);                                            // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.
 
 if(!strcmp(TLIB_ARITH_VDPLS,argv[1])) {                                                 // Compare parameters.
  puts("Description: Increments a variable.");                                           // Description.
  puts("Returns: Float number from expression result. ");                                // Returns.
  puts("Sample: ++: x => var.def x [++ $x];");                                           // Sample function.
  puts("Parameters: min: 1 max: 1");                                                     // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_ARITH_VDPLS);                                           // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_ARITH_VMIN,argv[1])) {                                                  // Compare parameters.
  puts("Description: Substracts a list of numbers from a variable.");                    // Description.
  puts("Returns: Float number from expression result. ");                                // Returns.
  puts("Sample: -: x 10 => var.def x [- $x 10]");                                        // Sample function.
  puts("Parameters: min: 2 max: ANY");                                                   // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_ARITH_VMIN);                                            // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_ARITH_VDMIN,argv[1])) {                                                 // Compare parameters.
  puts("Description: Decrements a variable.");                                           // Description.
  puts("Returns: Float number from expression result. ");                                // Returns.
  puts("Sample: --: x => var.def x [-- $x]");                                            // Sample function.
  puts("Parameters: min: 1 max: 1");                                                     // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_ARITH_VDMIN);                                           // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_ARITH_VMUL,argv[1])) {                                                  // Compare parameters.
  puts("Description: Multiplies a variable by a list of numbers.");                      // Description.
  puts("Returns: Float number from expression result. ");                                // Returns.
  puts("Sample: *: x 5 => var.def x [* $x 5]");                                          // Sample function.
  puts("Parameters: min: 2 max: ANY");                                                   // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_ARITH_VMUL);                                            // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_ARITH_VDMUL,argv[1])) {                                                 // Compare parameters.
  puts("Description: Multiplies a variable by self.");                                   // Description.
  puts("Returns: Float number from expression result. ");                                // Returns.
  puts("Sample: **: x => var.def x [** $x]");                                            // Sample function.
  puts("Parameters: min: 1 max: 1");                                                     // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_ARITH_VDMUL);                                           // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_ARITH_VDIV,argv[1])) {                                                  // Compare parameters.
  puts("Description: Divides a variable by a list of numbers.");                         // Description.
  puts("Returns: Float number from expression result. ");                                // Returns.
  puts("Sample: /: x 10 => var.def x [/ $x 10]");                                        // Sample function.
  puts("Parameters: min: 2 max: ANY");                                                   // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_ARITH_VDIV);                                            // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_ARITH_VDDIV,argv[1])) {                                                 // Compare parameters.
  puts("Description: Divides a variable by a list of numbers.");                         // Description.
  puts("Returns: Integer number from expression result. ");                              // Returns.
  puts("Sample: //: x 2 => var.def x [// $x 2]");                                        // Sample function.
  puts("Parameters: min: 1 max: ANY");                                                   // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_ARITH_VDDIV);                                           // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 if(!strcmp(TLIB_ARITH_VMOD,argv[1])) {                                                  // Compare parameters.
  puts("Description: Calculates modulus of a division in a variable.");                  // Description.
  puts("Returns: Float number from expression result. ");                                // Returns.
  puts("Sample: mod: x 3 => var.def x [mod $x 3]");                                      // Sample function.
  puts("Parameters: min: 2 max: ANY");                                                   // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_ARITH_VMOD);                                            // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.
 
 if(!strcmp(TLIB_ARITH_VPOW,argv[1])) {                                                  // Compare parameters.
  puts("Description: Calculates the pow of a variable by a list of numbers.");           // Description.
  puts("Returns: Float number from expression result. ");                                // Returns.
  puts("Sample: pow: x 3 => var.def x [pow $x 3]");                                      // Sample function.
  puts("Parameters: min: 2 max: ANY");                                                   // Parameters needed.
  AllenVM_InterpSetResult(i,TLIB_ARITH_VPOW);                                            // Set interpreter result. 
  return Allen_VM_OK; }                                                                  // Everything ok.

 AllenVM_InterpSetResult(i,TLIB_ARITH_NIL);                                              // Set interpreter result. 
 return AllenVM_CPU_Error(i,TLIB_ARITH_EHLP);                                            // Command not found.
}

// -------------------------------------------------------------------------------------------------------------------------------------
// Function:    AllenVM_CPU_LIB_ARITH_ADD();
// Purpose:     Add instructions to the CPU.
// Returns:     Void (nothing).
// -------------------------------------------------------------------------------------------------------------------------------------

void AllenVM_CPU_LIB_ARITH_ADD(struct AllenInterp *i) {
 AllenVM_InterpSetCommand(i,TLIB_ARITH_PLS,   AllenVM_CPU_LIB_ARITH_PLS,    NULL);       // Addition.
 AllenVM_InterpSetCommand(i,TLIB_ARITH_DPLS,  AllenVM_CPU_LIB_ARITH_DPLS,   NULL);       // Increment.
 AllenVM_InterpSetCommand(i,TLIB_ARITH_MIN,   AllenVM_CPU_LIB_ARITH_MIN,    NULL);       // Substraction.
 AllenVM_InterpSetCommand(i,TLIB_ARITH_DMIN,  AllenVM_CPU_LIB_ARITH_DMIN,   NULL);       // Decrement.
 AllenVM_InterpSetCommand(i,TLIB_ARITH_MUL,   AllenVM_CPU_LIB_ARITH_MUL,    NULL);       // Multiplication.
 AllenVM_InterpSetCommand(i,TLIB_ARITH_DMUL,  AllenVM_CPU_LIB_ARITH_DMUL,   NULL);       // Square.
 AllenVM_InterpSetCommand(i,TLIB_ARITH_DIV,   AllenVM_CPU_LIB_ARITH_DIV,    NULL);       // Division.
 AllenVM_InterpSetCommand(i,TLIB_ARITH_DDIV,  AllenVM_CPU_LIB_ARITH_DDIV,   NULL);       // Division without floating point.
 AllenVM_InterpSetCommand(i,TLIB_ARITH_MOD,   AllenVM_CPU_LIB_ARITH_MOD,    NULL);       // Modulus.
 AllenVM_InterpSetCommand(i,TLIB_ARITH_POW,   AllenVM_CPU_LIB_ARITH_POW,    NULL);       // Pow.
 AllenVM_InterpSetCommand(i,TLIB_ARITH_VPLS,  AllenVM_CPU_LIB_ARITH_VPLS,   NULL);       // Addition in variable.
 AllenVM_InterpSetCommand(i,TLIB_ARITH_VDPLS, AllenVM_CPU_LIB_ARITH_VDPLS,  NULL);       // Increment in variable.
 AllenVM_InterpSetCommand(i,TLIB_ARITH_VMIN,  AllenVM_CPU_LIB_ARITH_VMIN,   NULL);       // Substraction in variable.
 AllenVM_InterpSetCommand(i,TLIB_ARITH_VDMIN, AllenVM_CPU_LIB_ARITH_VDMIN,  NULL);       // Decrement in variable.
 AllenVM_InterpSetCommand(i,TLIB_ARITH_VMUL,  AllenVM_CPU_LIB_ARITH_VMUL,   NULL);       // Multiplication in variable.
 AllenVM_InterpSetCommand(i,TLIB_ARITH_VDMUL, AllenVM_CPU_LIB_ARITH_VDMUL,  NULL);       // Square in variable.
 AllenVM_InterpSetCommand(i,TLIB_ARITH_VDIV,  AllenVM_CPU_LIB_ARITH_VDIV,   NULL);       // Division in variable
 AllenVM_InterpSetCommand(i,TLIB_ARITH_VDDIV, AllenVM_CPU_LIB_ARITH_VDDIV,  NULL);       // Division without fp in variable.
 AllenVM_InterpSetCommand(i,TLIB_ARITH_VMOD,  AllenVM_CPU_LIB_ARITH_VMOD,   NULL);       // Modulus in variable.
 AllenVM_InterpSetCommand(i,TLIB_ARITH_VPOW,  AllenVM_CPU_LIB_ARITH_VPOW,   NULL);       // Pow in variable.
 AllenVM_InterpSetCommand(i,TLIB_ARITH_HLP,   AllenVM_CPU_LIB_ARITH_HLP,    NULL);       // Helper function.
}

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