From b22c27e1e6f8713675b288cf5c58ea43c8518c10 Mon Sep 17 00:00:00 2001 From: claudio Date: Sun, 20 Jul 2014 21:16:50 -0400 Subject: [PATCH] Added handling of unary plus and minus. --- compiler.c | 46 +++++++++++++++++++++++++++++++++++++++++-- lib-4090-overloaded.c | 15 ++++++++++++-- libraries.h | 7 +++++++ symbolic.c | 18 +++++++++++++++-- 4 files changed, 80 insertions(+), 6 deletions(-) diff --git a/compiler.c b/compiler.c index c869911..0825d0f 100644 --- a/compiler.c +++ b/compiler.c @@ -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; } diff --git a/lib-4090-overloaded.c b/lib-4090-overloaded.c index f303a4e..75a48bc 100644 --- a/lib-4090-overloaded.c +++ b/lib-4090-overloaded.c @@ -27,7 +27,7 @@ // GET LIST OF OVERLOADABLE OPERATORS AS DEFINED IN #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; diff --git a/libraries.h b/libraries.h index 4bf2d8c..45f9bbc 100644 --- a/libraries.h +++ b/libraries.h @@ -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 + diff --git a/symbolic.c b/symbolic.c index dbf56b6..44ea23f 100644 --- a/symbolic.c +++ b/symbolic.c @@ -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) +{ + +}