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.