Added handling of unary plus and minus.

This commit is contained in:
claudio 2014-07-20 21:16:50 -04:00
parent 316a291878
commit b22c27e1e6
4 changed files with 80 additions and 6 deletions

View file

@ -94,7 +94,7 @@ WORDPTR rplCompile(BYTEPTR string,BINT length, BINT addwrapper)
// START COMPILATION LOOP
BINT force_libnum,splittoken,validate,infixmode;
BINT probe_libnum,probe_tokeninfo;
BINT probe_libnum,probe_tokeninfo,previous_tokeninfo;
LIBHANDLER handler,ValidateHandler;
BINT libcnt,libnum;
WORDPTR InfixOpTop;
@ -107,6 +107,7 @@ WORDPTR rplCompile(BYTEPTR string,BINT length, BINT addwrapper)
force_libnum=-1;
splittoken=0;
infixmode=0;
previous_tokeninfo=0;
if(addwrapper) {
rplCompileAppend(MKPROLOG(DOCOL,0));
@ -385,6 +386,47 @@ WORDPTR rplCompile(BYTEPTR string,BINT length, BINT addwrapper)
// REMOVE THE OPERATOR FROM THE OUTPUT STREAM
CompileEnd=LastCompiledObject;
// SPECIAL CALSE THAT CAN ONLY BE HANDLED BY THE COMPILER:
// AMBIGUITY BETWEEN UNARY MINUS AND SUBSTRACTION
if(Opcode==MKOPCODE(LIB_OVERLOADABLE,OVR_SUB))
{
switch(TI_TYPE(previous_tokeninfo))
{
case 0:
case TITYPE_BINARYOP_LEFT:
case TITYPE_BINARYOP_RIGHT:
case TITYPE_OPENBRACKET:
case TITYPE_PREFIXOP:
// IT'S A UNARY MINUS
Opcode=MKOPCODE(LIB_OVERLOADABLE,OVR_UMINUS);
probe_tokeninfo=MKTOKENINFO(1,TITYPE_PREFIXOP,1,4);
break;
default:
break;
}
}
// AMBIGUITY BETWEEN UNARY PLUS AND ADDITION
if(Opcode==MKOPCODE(LIB_OVERLOADABLE,OVR_ADD))
{
switch(TI_TYPE(previous_tokeninfo))
{
case 0:
case TITYPE_BINARYOP_LEFT:
case TITYPE_BINARYOP_RIGHT:
case TITYPE_OPENBRACKET:
case TITYPE_PREFIXOP:
// IT'S A UNARY PLUS
Opcode=MKOPCODE(LIB_OVERLOADABLE,OVR_UPLUS);
probe_tokeninfo=MKTOKENINFO(1,TITYPE_PREFIXOP,1,4);
break;
default:
break;
}
}
if(TI_TYPE(probe_tokeninfo)==TITYPE_OPENBRACKET) {
// PUSH THE NEW OPERATOR
if(RStkSize<=(InfixOpTop-(WORDPTR)RStk)) growRStk(InfixOpTop-(WORDPTR)RStk+RSTKSLACK);
@ -507,7 +549,7 @@ WORDPTR rplCompile(BYTEPTR string,BINT length, BINT addwrapper)
}
previous_tokeninfo=probe_tokeninfo;
}

View file

@ -27,7 +27,7 @@
// GET LIST OF OVERLOADABLE OPERATORS AS DEFINED IN <libraries.h>
#define OP_LIST \
OP(INV,MKTOKENINFO(3,TITYPE_FUNCTION,1,2)), \
OP(NEG,MKTOKENINFO(3,TITYPE_FUNCTION,1,2)), \
OP(NEG,MKTOKENINFO(1,TITYPE_FUNCTION,1,4)), \
OP(EVAL,MKTOKENINFO(4,TITYPE_FUNCTION,1,2)), \
OP(XEQ,MKTOKENINFO(3,TITYPE_FUNCTION,1,2)), \
OP(ABS,MKTOKENINFO(3,TITYPE_FUNCTION,1,2)), \
@ -48,7 +48,7 @@
OP(SUB,MKTOKENINFO(1,TITYPE_BINARYOP_LEFT,2,6)), \
OP(MUL,MKTOKENINFO(1,TITYPE_BINARYOP_LEFT,2,5)), \
OP(DIV,MKTOKENINFO(1,TITYPE_BINARYOP_LEFT,2,5)), \
OP(POW,MKTOKENINFO(1,TITYPE_BINARYOP_RIGHT,2,4))
OP(POW,MKTOKENINFO(1,TITYPE_BINARYOP_RIGHT,2,3))
// ADD MORE OPERATORS HERE
@ -144,6 +144,12 @@ void LIB_HANDLER()
return;
case OPCODE_DECOMPILE:
// MANUALLY DECOMPILE UNARY PLUS AND UNARY MINUS IN SYMBOLICS
if(OPCODE(*DecompileObject)==OVR_UMINUS) { rplDecompAppendChar('-'); RetNum=OK_CONTINUE; return; }
if(OPCODE(*DecompileObject)==OVR_UPLUS) { rplDecompAppendChar('+'); RetNum=OK_CONTINUE; return; }
libDecompileCmds(LIB_NAMES,LIB_OPCODES,LIB_NUMCMDS);
return;
case OPCODE_VALIDATE:
@ -165,6 +171,11 @@ void LIB_HANDLER()
libProbeCmds(LIBRARY_NUMBER,LIB_NAMES,LIB_TOKENINFO,LIB_NUMCMDS);
return;
case OPCODE_GETINFO:
// MANUALLY RETURN INFO FOR UNARY PLUS AND MINUS
if(OPCODE(*DecompileObject)==OVR_UMINUS) { RetNum=OK_TOKENINFO | MKTOKENINFO(1,TITYPE_PREFIXOP,1,4); return; }
if(OPCODE(*DecompileObject)==OVR_UPLUS) { RetNum=OK_TOKENINFO | MKTOKENINFO(1,TITYPE_PREFIXOP,1,4); return; }
libGetInfo(*DecompileObject,LIB_NAMES,LIB_OPCODES,LIB_TOKENINFO,LIB_NUMCMDS);
return;

View file

@ -191,6 +191,13 @@ extern void libGetInfo(WORD opcode,char *libnames[],WORD libopcodes[],BINT token
#define OVRT_NOT "NOT"
#define OVR_NOT OVR_OPERATORS+OVR_UNARY+7
//UNARY PLUS IN SYMBOLICS
#define OVRT_UPLUS "+"
#define OVR_UPLUS OVR_OPERATORS+OVR_UNARY+8
// OPCODE FOR UNARY MINUS IN SYMBOLICS ONLY
#define OVRT_UMINUS "-"
#define OVR_UMINUS OVR_OPERATORS+OVR_UNARY+9

View file

@ -50,9 +50,10 @@
5= OVR_MUL,OVR_DIV,OVR_INV
4= OVR_ABS,OVR_POW
4= OVR_NEG, OVR_ISTRUE, OVR_NOT
3= OVR_ABS,OVR_POW
3= OVR_NEG, OVR_ISTRUE, OVR_NOT
2 = ALL OTHER FUNCTIONS AND COMMANDS
@ -113,6 +114,7 @@ BINT rplIsAllowedInSymb(WORDPTR object)
return 0;
}
// TAKE 'nargs' ITEMS FROM THE STACK AND APPLY THE OPERATOR OPCODE
// LEAVE THE NEW SYMBOLIC OBJECT IN THE STACK
// NO ARGUMENT CHECKS!
@ -168,3 +170,15 @@ void rplSymbApplyOperator(WORD Opcode,BINT nargs)
rplDropData(nargs-1);
rplOverwriteData(1,newobject);
}
// CHANGE THE SYMBOLIC TO CANONICAL FORM.
// CANONICAL FORM APPLIES THE FOLLOWING RULES:
// SUBTRACTION AND DIVISION ARE FOLDED INTO ADDITION AND MULTIPLICATION WITH NEG() AND INV()
// SUCCESSIVE ADDITION AND MULTIPLICATION LISTS ARE FLATTENED
void rplSymbCanonicalForm(WORDPTR object)
{
}