newrpl/lib-64-precision.c
2014-04-27 18:53:11 -04:00

220 lines
5.6 KiB
C

#include "newrpl.h"
#include "libraries.h"
#include "hal.h"
// LIB 64 PROVIDES COMMANDS THAT DEAL WITH ROUNDING AND PRECISION
// MAIN LIBRARY NUMBER, CHANGE THIS FOR EACH LIBRARY
#define LIBRARY_NUMBER 64
#define LIB_ENUM lib64_enum
#define LIB_NAMES lib64_names
#define LIB_HANDLER lib64_handler
#define LIB_NUMBEROFCMDS LIB64_NUMBEROFCMDS
// LIST OF COMMANDS EXPORTED, CHANGE FOR EACH LIBRARY
#define CMD_LIST \
CMD(SETPREC), \
CMD(FLOOR), \
CMD(CEIL), \
CMD(IP), \
CMD(FP)
// ADD MORE OPCODES HERE
// EXTRA LIST FOR COMMANDS WITH SYMBOLS THAT ARE DISALLOWED IN AN ENUM
// THE NAMES AND ENUM SYMBOLS ARE GIVEN SEPARATELY
/*#define CMD_EXTRANAME \
"VOID",
#define CMD_EXTRAENUM \
VOID
*/
// INTERNAL DECLARATIONS
// CREATE AN ENUM WITH THE OPCODE NAMES FOR THE DISPATCHER
#define CMD(a) a
enum LIB_ENUM { CMD_LIST /*, CMD_EXTRAENUM */, LIB_NUMBEROFCMDS };
#undef CMD
// AND A LIST OF STRINGS WITH THE NAMES FOR THE COMPILER
#define CMD(a) #a
char *LIB_NAMES[]= { CMD_LIST /*, CMD_EXTRANAME*/ };
#undef CMD
void LIB_HANDLER()
{
if(ISPROLOG(CurOpcode)) {
// THIS LIBRARY DOES NOT DEFINE ANY OBJECTS
Exceptions=EX_BADOPCODE;
ExceptionPointer=IPtr;
return;
}
switch(OPCODE(CurOpcode))
{
case SETPREC:
{
// TAKE AN INTEGER NUMBER FROM THE STACK
if(rplDepthData()<1) {
Exceptions|=EX_BADARGCOUNT;
ExceptionPointer=IPtr;
return;
}
BINT64 number=rplReadNumberAsBINT(rplPeekData(1));
if(Exceptions) return;
if(number<9) number=9;
if(number>REAL_PRECISION_MAX) number=REAL_PRECISION_MAX;
mpd_qsetprec(&Context,number);
rplDropData(1);
return;
}
case FLOOR:
{
if(rplDepthData()<1) {
Exceptions|=EX_BADARGCOUNT;
ExceptionPointer=IPtr;
return;
}
WORDPTR arg=rplPeekData(1);
mpd_t rnum;
if(ISBINT(*arg)) return;
rplReadNumberAsReal(rplPeekData(1),&rnum);
if(Exceptions) return;
mpd_floor(&RReg[1],&rnum,&Context);
if(Exceptions) return;
rplDropData(1);
rplRRegToRealPush(1);
return;
}
case CEIL:
{
if(rplDepthData()<1) {
Exceptions|=EX_BADARGCOUNT;
ExceptionPointer=IPtr;
return;
}
WORDPTR arg=rplPeekData(1);
if(ISBINT(*arg)) return;
mpd_t rnum;
rplReadNumberAsReal(rplPeekData(1),&rnum);
if(Exceptions) return;
mpd_ceil(&RReg[1],&rnum,&Context);
if(Exceptions) return;
rplDropData(1);
rplRRegToRealPush(1);
return;
}
case IP:
{
if(rplDepthData()<1) {
Exceptions|=EX_BADARGCOUNT;
ExceptionPointer=IPtr;
return;
}
WORDPTR arg=rplPeekData(1);
if(ISBINT(*arg)) return;
mpd_t rnum;
rplReadNumberAsReal(arg,&rnum);
if(Exceptions) return;
mpd_trunc(&RReg[1],&rnum,&Context);
if(Exceptions) return;
rplDropData(1);
rplRRegToRealPush(1);
return;
}
case FP:
{
if(rplDepthData()<1) {
Exceptions|=EX_BADARGCOUNT;
ExceptionPointer=IPtr;
return;
}
WORDPTR arg=rplPeekData(1);
if(ISBINT(*arg)) {
rplDropData(1);
rplNewSINTPush(0,DECBINT);
return;
}
mpd_t rnum;
rplReadNumberAsReal(arg,&rnum);
if(Exceptions) return;
mpd_trunc(&RReg[1],&rnum,&Context);
if(Exceptions) return;
mpd_sub(&RReg[2],&rnum,&RReg[1],&Context);
if(Exceptions) return;
rplDropData(1);
rplRRegToRealPush(2);
return;
}
// ADD MORE OPCODES HERE
// STANDARIZED OPCODES:
// --------------------
// LIBRARIES ARE FORCED TO ALWAYS HANDLE THE STANDARD OPCODES
case OPCODE_COMPILE:
// COMPILE RECEIVES:
// TokenStart = token string
// TokenLen = token length
// BlankStart = token blanks afterwards
// BlanksLen = blanks length
// CurrentConstruct = Opcode of current construct/WORD of current composite
// COMPILE RETURNS:
// RetNum = enum CompileErrors
// THIS STANDARD FUNCTION WILL TAKE CARE OF COMPILATION OF STANDARD COMMANDS GIVEN IN THE LIST
// NO NEED TO CHANGE THIS UNLESS CUSTOM OPCODES
libCompileCmds(LIBRARY_NUMBER,LIB_NAMES,NULL,LIB_NUMBEROFCMDS);
return;
case OPCODE_DECOMPILE:
// DECOMPILE RECEIVES:
// DecompileObject = Ptr to WORD of object to decompile
// DecompStringEnd = Ptr to the end of decompile string
//DECOMPILE RETURNS
// RetNum = enum DecompileErrors
// THIS STANDARD FUNCTION WILL TAKE CARE OF DECOMPILING STANDARD COMMANDS GIVEN IN THE LIST
// NO NEED TO CHANGE THIS UNLESS THERE ARE CUSTOM OPCODES
libDecompileCmds(LIB_NAMES,NULL,LIB_NUMBEROFCMDS);
return;
case OPCODE_VALIDATE:
// VALIDATE RECEIVES OPCODES COMPILED BY OTHER LIBRARIES, TO BE INCLUDED WITHIN A COMPOSITE OWNED BY
// THIS LIBRARY. EVERY COMPOSITE HAS TO EVALUATE IF THE OBJECT BEING COMPILED IS ALLOWED INSIDE THIS
// COMPOSITE OR NOT. FOR EXAMPLE, A REAL MATRIX SHOULD ONLY ALLOW REAL NUMBERS INSIDE, ANY OTHER
// OPCODES SHOULD BE REJECTED AND AN ERROR THROWN.
// TokenStart = token string
// TokenLen = token length
// ArgNum2 = Opcode/WORD of object
// VALIDATE RETURNS:
// RetNum = enum CompileErrors
return;
}
// BY DEFAULT, ISSUE A BAD OPCODE ERROR
Exceptions|=EX_BADOPCODE;
ExceptionPointer=IPtr;
return;
}