Added support for list in symbolics - work in progress

This commit is contained in:
claudiol 2018-07-20 19:08:41 -04:00
parent bf28df6528
commit 216a8b6770
3 changed files with 179 additions and 25 deletions

View file

@ -563,17 +563,19 @@ WORDPTR rplCompile(BYTEPTR string,BINT length, BINT addwrapper)
if(!previous_tokeninfo || (TI_TYPE(previous_tokeninfo)>TITYPE_OPERATORS)) {
// THIS IS A PARENTHESIS FOLLOWING AN OPERATOR
// PUSH THE NEW OPERATOR
if(RStkSize<=(InfixOpTop+1-(WORDPTR)RStk)) growRStk(InfixOpTop-(WORDPTR)RStk+RSTKSLACK);
if(RStkSize<=(InfixOpTop+3-(WORDPTR)RStk)) growRStk(InfixOpTop-(WORDPTR)RStk+RSTKSLACK);
if(Exceptions) { LAMTop=LAMTopSaved; return 0; }
InfixOpTop[0]=CompileEnd-TempObEnd; // SAVE POSITION TO START COUNTING ARGUMENTS
InfixOpTop[1]=probe_tokeninfo;
InfixOpTop+=2;
InfixOpTop[2]=Opcode; // SAVE OPCODE TO DISTINGUISH BRACKET TYPES
InfixOpTop[3]=probe_tokeninfo;
InfixOpTop+=4;
} else
{
// THIS IS EITHER MATRIX/VECTOR INDEXING OR A USER FUNCTION CALL
// PUSH OPERATOR FUNCEVAL FIRST
if(RStkSize<=(InfixOpTop+3-(WORDPTR)RStk)) growRStk(InfixOpTop-(WORDPTR)RStk+RSTKSLACK);
if(RStkSize<=(InfixOpTop+5-(WORDPTR)RStk)) growRStk(InfixOpTop-(WORDPTR)RStk+RSTKSLACK);
if(Exceptions) { LAMTop=LAMTopSaved; return 0; }
InfixOpTop[0]=(CMD_OVR_FUNCEVAL); // SAVE POSITION TO START COUNTING ARGUMENTS
InfixOpTop[1]=MKTOKENINFO(TI_LENGTH(previous_tokeninfo),TITYPE_FUNCTION,0xf,2);
@ -582,7 +584,9 @@ WORDPTR rplCompile(BYTEPTR string,BINT length, BINT addwrapper)
// THEN THE OPENING BRACKET
InfixOpTop[0]=CompileEnd-TempObEnd; // SAVE POSITION TO START COUNTING ARGUMENTS
InfixOpTop[1]=probe_tokeninfo;
InfixOpTop+=2;
InfixOpTop[2]=Opcode; // SAVE OPCODE TO DISTINGUISH BRACKET TYPES
InfixOpTop[3]=probe_tokeninfo;
InfixOpTop+=4;
}
@ -593,7 +597,16 @@ WORDPTR rplCompile(BYTEPTR string,BINT length, BINT addwrapper)
// POP ALL OPERATORS OFF THE STACK UNTIL THE OPENING BRACKET IS FOUND
while(InfixOpTop>(WORDPTR)ValidateTop){
if((TI_TYPE(*(InfixOpTop-1))==TITYPE_OPENBRACKET)) break;
if((TI_TYPE(*(InfixOpTop-1))==TITYPE_OPENBRACKET)) {
// CHECK IF THE BRACKET IS THE RIGHT TYPE OF BRACKET
if((TI_TYPE(probe_tokeninfo)==TITYPE_CLOSEBRACKET) &&(*(InfixOpTop-2)!=Opcode)) {
// MISMATCHED BRACKET TYPE
rplError(ERR_MISSINGBRACKET);
LAMTop=LAMTopSaved;
return 0;
}
break;
}
// POP OPERATORS OFF THE STACK AND APPLY TO OBJECTS
InfixOpTop-=2;
if(!rplInfixApply(InfixOpTop[0],TI_NARGS(InfixOpTop[1])))
@ -614,9 +627,10 @@ WORDPTR rplCompile(BYTEPTR string,BINT length, BINT addwrapper)
if(TI_TYPE(probe_tokeninfo)==TITYPE_CLOSEBRACKET) {
// COUNT THE NUMBER OF ARGUMENTS WE HAVE
// REMOVE THE OPENING BRACKET
InfixOpTop-=2;
InfixOpTop-=4;
BINT nargs=0;
WORD brackettype=InfixOpTop[2]; // OPCODE WITH BRACKET TYPE TO DISTINGUISH BRACKETS
WORDPTR list=TempObEnd+InfixOpTop[0];
WORDPTR ptr=CompileEnd;
@ -625,8 +639,7 @@ WORDPTR rplCompile(BYTEPTR string,BINT length, BINT addwrapper)
// CHECK IF THE TOP OF STACK IS A FUNCTION
if(InfixOpTop>(WORDPTR)ValidateTop) {
if(TI_TYPE(*(InfixOpTop-1))==TITYPE_FUNCTION) {
if((InfixOpTop>(WORDPTR)ValidateTop)&&(TI_TYPE(*(InfixOpTop-1))==TITYPE_FUNCTION)) {
BINT needargs=(BINT)TI_NARGS(*(InfixOpTop-1));
if((needargs!=0xf) && (nargs!=needargs)) {
rplError(ERR_BADARGCOUNT);
@ -652,7 +665,23 @@ WORDPTR rplCompile(BYTEPTR string,BINT length, BINT addwrapper)
}
}
else {
// THERE'S NO FUNCTION ON THE STACK, USE THE BRACKET THE MAIN OPERATOR
if((brackettype!=CMD_OPENBRACKET)||(nargs>1)) {
if(!rplInfixApply(brackettype,nargs))
{
LAMTop=LAMTopSaved;
return 0;
}
}
}
} else {
// THE PARAMETER IS A COMMA
// DO NOTHING FOR NOW
@ -1433,6 +1462,31 @@ end_of_expression:
}
case TITYPE_OPENBRACKET:
{
// DECOMPILE THE OPERATOR NOW, THEN ADD PARENTHESIS FOR THE LIST
CurOpcode=MKOPCODE(LIBNUM(*DecompileObject),(flags&DECOMP_EDIT)? OPCODE_DECOMPEDIT:OPCODE_DECOMPILE);
DecompMode=infixmode|(flags<<16);
RetNum=-1;
if(handler) {
// PROTECT OPERATOR'S STACK FROM BEING OVERWRITTEN
WORDPTR *tmpRSTop=RSTop;
RSTop=(WORDPTR *)InfixOpTop;
(*handler)();
RSTop=tmpRSTop;
}
// IGNORE THE RESULT OF DECOMPILATION
if(RetNum!=OK_CONTINUE) {
rplDecompAppendString((BYTEPTR)"##INVALID##");
}
++DecompileObject;
infixmode=INFIX_FUNCARGUMENT;
break;
}
case TITYPE_FUNCTION:
default:
// DECOMPILE THE OPERATOR NOW, THEN ADD PARENTHESIS FOR THE LIST
@ -1801,11 +1855,41 @@ end_of_expression:
WORDPTR EndofExpression = rplSkipOb(*(signed int *)(InfixOpTop-4)+EndOfObject);
if(DecompileObject==EndofExpression) {
rplDecompAppendChar(')');
LIBHANDLER handler;
// ADD THE OPERATOR AFTER THE OPERAND
WORD functype=*(InfixOpTop-1);
if(TI_TYPE(functype)==TITYPE_OPENBRACKET) {
BINT libnum=LIBNUM(*(InfixOpTop-2));
WORD closebracket;
closebracket=*(InfixOpTop-2)+1;
DecompileObject=&closebracket;
CurOpcode=MKOPCODE(libnum,(flags&DECOMP_EDIT)? OPCODE_DECOMPEDIT:OPCODE_DECOMPILE);
DecompMode=infixmode|(flags<<16);
handler=rplGetLibHandler(libnum);
RetNum=-1;
if(handler) {
// PROTECT OPERATOR'S STACK FROM BEING OVERWRITTEN
WORDPTR *tmpRSTop=RSTop;
RSTop=(WORDPTR *)InfixOpTop;
(*handler)();
RSTop=tmpRSTop;
}
// IGNORE THE RESULT OF DECOMPILATION
if(RetNum!=OK_CONTINUE) {
rplDecompAppendString((BYTEPTR)"##INVALID##");
}
}
else rplDecompAppendChar(')');
// END OF THIS EXPRESSION
// POP EXPRESSION FROM THE STACK
InfixOpTop-=4;
// RESTORE PREVIOUS EXPRESSION STATE
infixmode=InfixOpTop[1];
DecompileObject=rplSkipOb(*(signed int *)InfixOpTop+EndOfObject);
if(!infixmode) rplDecompAppendChar('\'');

View file

@ -30,7 +30,7 @@
#define COMMAND_LIST \
ECMD(RULESEPARATOR,":→",MKTOKENINFO(2,TITYPE_BINARYOP_LEFT,2,14)), \
ECMD(OPENBRACKET,"(",MKTOKENINFO(1,TITYPE_OPENBRACKET,0,31)), \
ECMD(OPENBRACKET,"(",MKTOKENINFO(1,TITYPE_OPENBRACKET,0,1)), \
ECMD(CLOSEBRACKET,")",MKTOKENINFO(1,TITYPE_CLOSEBRACKET,0,31)), \
ECMD(COMMA,"",MKTOKENINFO(1,TITYPE_COMMA,0,31)), \
ECMD(SYMBEVALPRE,"",MKTOKENINFO(0,TITYPE_NOTALLOWED,1,2)), \
@ -46,8 +46,10 @@
CMD(RULEMATCH,MKTOKENINFO(9,TITYPE_NOTALLOWED,1,2)), \
CMD(RULEAPPLY,MKTOKENINFO(9,TITYPE_NOTALLOWED,1,2)), \
ECMD(TOFRACTION,"→Q",MKTOKENINFO(2,TITYPE_FUNCTION,1,2)), \
ECMD(SYMBEVAL1CHK,"",MKTOKENINFO(0,TITYPE_NOTALLOWED,1,2))
ECMD(SYMBEVAL1CHK,"",MKTOKENINFO(0,TITYPE_NOTALLOWED,1,2)), \
ECMD(EQUATIONOPERATOR,"=",MKTOKENINFO(1,TITYPE_BINARYOP_LEFT,2,15)), \
ECMD(LISTOPENBRACKET,"{",MKTOKENINFO(1,TITYPE_OPENBRACKET,0,1)), \
ECMD(LISTCLOSEBRACKET,"}",MKTOKENINFO(1,TITYPE_CLOSEBRACKET,0,31))
// CMD(TEST,MKTOKENINFO(4,TITYPE_NOTALLOWED,1,2))
@ -895,6 +897,13 @@ void LIB_HANDLER()
rplSetExceptionHandler(IPtr+5); // SET THE EXCEPTION HANDLER TO THE SYMBEVAL1ERR WORD
if((Opcode==CMD_OPENBRACKET) || (Opcode==CMD_LISTOPENBRACKET)) {
// SPECIAL CASE, THESE COMMANDS NEED THE NUMBER OF ARGUMENTS PUSHED ON THE STACK
rplNewBINTPush(newdepth,DECBINT);
}
if((Opcode==CMD_OVR_MUL)||(Opcode==CMD_OVR_ADD)) {
// CHECK FOR FLATTENED LIST, APPLY MORE THAN ONCE IF MORE THAN 2 ARGUMENTS
if(newdepth<=2) rplPutLAMn(1,(WORDPTR)zero_bint); // SIGNAL OPCODE IS DONE
@ -1494,11 +1503,57 @@ void LIB_HANDLER()
case RULESEPARATOR:
//@SHORT_DESC=@HIDE
return;
case OPENBRACKET:
//@SHORT_DESC=@HIDE
{
// OPERATOR USED IN SYMBOLIC NUMBERS, SHOULD CREATE SOME KIND OF SET OF NUMBERS, A LIST FOR NOW
if(rplDepthData()<2) {
rplError(ERR_BADARGCOUNT);
return;
}
rplCreateList();
return;
}
case CLOSEBRACKET:
//@SHORT_DESC=@HIDE
return;
return;
case LISTOPENBRACKET:
//@SHORT_DESC=@HIDE
if(rplDepthData()<1) {
rplError(ERR_BADARGCOUNT);
return;
}
rplCreateList();
return;
case LISTCLOSEBRACKET:
//@SHORT_DESC=@HIDE
case EQUATIONOPERATOR:
//@SHORT_DESC=@HIDE
{
if(rplDepthData()<2) {
rplError(ERR_BADARGCOUNT);
return;
}
WORDPTR arg1=rplPeekData(2);
WORDPTR arg2=rplPeekData(1);
// ALLOW LIST PROCESSING AND MATRIX PROCESSING FIRST
if(ISLIST(*arg1) || ISLIST(*arg2)){
rplListBinaryDoCmd(arg1,arg2);
return;
}
// MAKE SURE WE KEEP THE EQUALITY WHEN EVAL'd
rplSymbApplyOperator(CurOpcode,2);
return;
}
// STANDARIZED OPCODES:
// --------------------
@ -1534,7 +1589,7 @@ void LIB_HANDLER()
if(*tok==')') {
if((TokenLen==1) && (CurrentConstruct==MKPROLOG(DOSYMB,0))) {
rplCompileAppend(MKOPCODE(LIBRARY_NUMBER,CLOSEBRACKET));
rplCompileAppend(MKOPCODE(LIBRARY_NUMBER,OPENBRACKET)); // INDICATE THE OPENING BRACKET TO MATCH
RetNum=OK_CONTINUE;
}
else RetNum=ERR_NOTMINE;
@ -1549,6 +1604,27 @@ void LIB_HANDLER()
return;
}
if(*tok=='{') {
if((TokenLen==1)&&(CurrentConstruct==MKPROLOG(DOSYMB,0))) {
rplCompileAppend(MKOPCODE(LIBRARY_NUMBER,LISTOPENBRACKET));
RetNum=OK_CONTINUE;
}
else RetNum=ERR_NOTMINE;
return;
}
if(*tok=='}') {
if((TokenLen==1)&&(CurrentConstruct==MKPROLOG(DOSYMB,0))) {
// ISSUE A BUILDLIST OPERATOR
rplCompileAppend(MKOPCODE(LIBRARY_NUMBER,LISTOPENBRACKET));
RetNum=OK_CONTINUE;
}
else RetNum=ERR_NOTMINE;
return;
}
if( (TokenLen==2) && !utf8ncmp2((char *)tok,(char *)BlankStart,":→",2)) {
if(CurrentConstruct==MKPROLOG(DOSYMB,0)) {
rplCompileAppend(MKOPCODE(LIBRARY_NUMBER,RULESEPARATOR));
@ -1635,17 +1711,7 @@ void LIB_HANDLER()
RetNum= OK_ENDCONSTRUCT_INFIX;
return;
}
/*
if(*((char *)TokenStart)=='(') {
RetNum= OK_TOKENINFO | MKTOKENINFO(1,TITYPE_OPENBRACKET,0,31);
return;
}
if(*((char *)TokenStart)==')') {
RetNum= OK_TOKENINFO | MKTOKENINFO(1,TITYPE_CLOSEBRACKET,0,31);
return;
}
*/
if((WORD)utf82cp((char *)TokenStart,(char *)BlankStart)==ARG_SEP(Locale)) {
RetNum= OK_TOKENINFO | MKTOKENINFO(1,TITYPE_COMMA,0,31);
return;

View file

@ -2967,8 +2967,12 @@ void LIB_HANDLER()
// RetNum = OK_TOKENINFO | MKTOKENINFO(...) WITH THE INFORMATION ABOUT THE CURRENT TOKEN
// OR RetNum = ERR_NOTMINE IF NO TOKEN WAS FOUND
{
if(*((char *)TokenStart)=='}') {
// FOUND END OF LIST WITHIN A SYMBOLIC COMPILATION. JUST IGNORE AND LET THE SYMBOLIC LIBRARY HANDLE IT
RetNum=ERR_NOTMINE;
return;
}
libProbeCmds((char **)LIB_NAMES,(BINT *)LIB_TOKENINFO,LIB_NUMBEROFCMDS);
return;
}