void ring_vm_jumpvarplenum ( VM *pVM ) { List *pVar ; double nNum1,nNum2 ; pVar = (List *) RING_VM_IR_READP ; nNum1 = ring_list_getdouble(pVM->aForStep,ring_list_getsize(pVM->aForStep)); /* Check Data */ if ( ring_list_isstring(pVar,RING_VAR_VALUE) ) { nNum2 = ring_vm_stringtonum(pVM,ring_list_getstring(pVar,RING_VAR_VALUE)); } else if ( ring_list_isnumber(pVar,RING_VAR_VALUE) ) { nNum2 = ring_list_getdouble(pVar,RING_VAR_VALUE) ; } else { ring_vm_error(pVM,RING_VM_ERROR_FORLOOPDATATYPE); return ; } if ( nNum1 < 0 ) { if ( ! (nNum2 >= RING_VM_IR_READDVALUE(2)) ) { /* Jump */ pVM->nPC = RING_VM_IR_READIVALUE(3) ; } } else { if ( ! (nNum2 <= RING_VM_IR_READDVALUE(2)) ) { /* Jump */ pVM->nPC = RING_VM_IR_READIVALUE(3) ; } } }
void ring_vm_inclpjump ( VM *pVM ) { List *pVar ; double nNum1,nNum2 ; /* Check Scope Life Time */ if ( RING_VM_IR_READIVALUE(4) != pVM->nActiveScopeID ) { RING_VM_IR_OPCODE = ICO_INCJUMP ; ring_list_deliteminsidelist_gc(pVM->pRingState,pVM->aNewByteCodeItems,RING_VM_IR_ITEM(3)); ring_list_deliteminsidelist_gc(pVM->pRingState,pVM->aNewByteCodeItems,RING_VM_IR_ITEM(4)); #if RING_SHOWICFINAL RING_VM_IR_PARACOUNT = RING_VM_IR_PARACOUNT - 2 ; ring_list_deleteitem_gc(pVM->pRingState,RING_VM_IR_LIST,ring_list_getsize(RING_VM_IR_LIST)); ring_list_deleteitem_gc(pVM->pRingState,RING_VM_IR_LIST,ring_list_getsize(RING_VM_IR_LIST)); #endif pVM->nPC-- ; return ; } pVar = (List *) RING_VM_IR_READPVALUE(3) ; nNum1 = ring_list_getdouble(pVM->aForStep,ring_list_getsize(pVM->aForStep)); /* Check Data */ if ( ring_list_isstring(pVar,RING_VAR_VALUE) ) { nNum2 = ring_vm_stringtonum(pVM,ring_list_getstring(pVar,RING_VAR_VALUE)); } else if ( ring_list_isnumber(pVar,RING_VAR_VALUE) ) { nNum2 = ring_list_getdouble(pVar,RING_VAR_VALUE) ; } else { ring_vm_error(pVM,RING_VM_ERROR_FORLOOPDATATYPE); return ; } ring_list_setdouble_gc(pVM->pRingState,pVar,RING_VAR_VALUE,nNum2 + nNum1); /* Jump */ pVM->nPC = RING_VM_IR_READIVALUE(2) ; }
void ring_vm_jumpvarlenum ( VM *pVM ) { List *pVar ; double nNum1,nNum2 ; if ( ring_vm_findvar(pVM, RING_VM_IR_READC ) == 0 ) { ring_vm_newvar(pVM, RING_VM_IR_READC); } nNum1 = ring_list_getdouble(pVM->aForStep,ring_list_getsize(pVM->aForStep)); /* Change Instruction for Performance */ if ( pVM->nVarScope == RING_VARSCOPE_GLOBAL ) { /* Replace JumpVarLENum with JumpVarPLENum for better performance */ if ( nNum1 == 1.0 ) { RING_VM_IR_OPCODE = ICO_JUMPVARPLENUMSTEP1 ; } else { RING_VM_IR_OPCODE = ICO_JUMPVARPLENUM ; } ring_item_setpointer_gc(pVM->pRingState,RING_VM_IR_ITEM(1),RING_VM_STACK_READP); } else if ( pVM->nVarScope == RING_VARSCOPE_LOCAL ) { /* Replace JumpVarLENum with JumpVarLPLENum for better performance */ RING_VM_IR_OPCODE = ICO_JUMPVARLPLENUM ; ring_item_setpointer_gc(pVM->pRingState,RING_VM_IR_ITEM(4),RING_VM_STACK_READP); ring_item_setint_gc(pVM->pRingState,RING_VM_IR_ITEM(5),ring_list_getint(pVM->aScopeID,ring_list_getsize(pVM->aScopeID))); #if RING_SHOWICFINAL RING_VM_IR_PARACOUNT = RING_VM_IR_PARACOUNT + 2 ; ring_list_addpointer_gc(pVM->pRingState,RING_VM_IR_LIST,RING_VM_STACK_READP); ring_list_addint_gc(pVM->pRingState,RING_VM_IR_LIST,ring_list_getint(pVM->aScopeID,ring_list_getsize(pVM->aScopeID))); #endif } pVar = (List *) RING_VM_STACK_READP ; RING_VM_STACK_POP ; /* Check Data */ if ( ring_list_isstring(pVar,RING_VAR_VALUE) ) { nNum2 = ring_vm_stringtonum(pVM,ring_list_getstring(pVar,RING_VAR_VALUE)); ring_list_setdouble_gc(pVM->pRingState,pVar,RING_VAR_VALUE,nNum2); } else if ( ring_list_isnumber(pVar,RING_VAR_VALUE) ) { nNum2 = ring_list_getdouble(pVar,RING_VAR_VALUE) ; } else { ring_vm_error(pVM,RING_VM_ERROR_FORLOOPDATATYPE); return ; } if ( nNum1 < 0 ) { if ( ! (nNum2 >= RING_VM_IR_READDVALUE(2)) ) { /* Jump */ pVM->nPC = RING_VM_IR_READIVALUE(3) ; } } else { if ( ! (nNum2 <= RING_VM_IR_READDVALUE(2)) ) { /* Jump */ pVM->nPC = RING_VM_IR_READIVALUE(3) ; } } }
void ring_vm_incpjump ( VM *pVM ) { List *pVar ; double nNum1,nNum2 ; pVar = (List *) RING_VM_IR_READP ; nNum1 = ring_list_getdouble(pVM->aForStep,ring_list_getsize(pVM->aForStep)); /* Check Data */ if ( ring_list_isstring(pVar,RING_VAR_VALUE) ) { nNum2 = ring_vm_stringtonum(pVM,ring_list_getstring(pVar,RING_VAR_VALUE)); } else if ( ring_list_isnumber(pVar,RING_VAR_VALUE) ) { nNum2 = ring_list_getdouble(pVar,RING_VAR_VALUE) ; } else { ring_vm_error(pVM,RING_VM_ERROR_FORLOOPDATATYPE); return ; } ring_list_setdouble_gc(pVM->pRingState,pVar,RING_VAR_VALUE,nNum2 + nNum1); /* Jump */ pVM->nPC = RING_VM_IR_READIVALUE(2) ; }
void ring_vm_incpjumpstep1 ( VM *pVM ) { List *pVar ; double nNum1 ; pVar = (List *) RING_VM_IR_READP ; /* We Don't Check Data Type */ nNum1 = ring_list_getdouble(pVar,RING_VAR_VALUE) ; ring_list_setdouble_gc(pVM->pRingState,pVar,RING_VAR_VALUE,nNum1 + 1); /* Jump */ pVM->nPC = RING_VM_IR_READIVALUE(2) ; }
void ring_vm_incjump ( VM *pVM ) { List *pVar ; double nNum1,nNum2 ; if ( ring_vm_findvar(pVM, RING_VM_IR_READC ) == 0 ) { ring_vm_newvar(pVM, RING_VM_IR_READC); } nNum1 = ring_list_getdouble(pVM->aForStep,ring_list_getsize(pVM->aForStep)); /* Change Instruction for Performance */ if ( pVM->nVarScope == RING_VARSCOPE_GLOBAL ) { /* Replace ICO_INCJUMP with IncPJUMP for better performance */ if ( nNum1 == 1.0 ) { RING_VM_IR_OPCODE = ICO_INCPJUMPSTEP1 ; } else { RING_VM_IR_OPCODE = ICO_INCPJUMP ; } ring_item_setpointer_gc(pVM->pRingState,RING_VM_IR_ITEM(1),RING_VM_STACK_READP); } else if ( pVM->nVarScope == RING_VARSCOPE_LOCAL ) { /* Replace ICO_INCJUMP with IncLPJUMP for better performance */ RING_VM_IR_OPCODE = ICO_INCLPJUMP ; ring_item_setpointer_gc(pVM->pRingState,RING_VM_IR_ITEM(3),RING_VM_STACK_READP); ring_item_setint_gc(pVM->pRingState,RING_VM_IR_ITEM(4),ring_list_getint(pVM->aScopeID,ring_list_getsize(pVM->aScopeID))); } pVar = (List *) RING_VM_STACK_READP ; RING_VM_STACK_POP ; /* Check Data */ if ( ring_list_isstring(pVar,RING_VAR_VALUE) ) { nNum2 = ring_vm_stringtonum(pVM,ring_list_getstring(pVar,RING_VAR_VALUE)); ring_list_setdouble_gc(pVM->pRingState,pVar,RING_VAR_VALUE,nNum2); } else if ( ring_list_isnumber(pVar,RING_VAR_VALUE) ) { nNum2 = ring_list_getdouble(pVar,RING_VAR_VALUE) ; } else { ring_vm_error(pVM,RING_VM_ERROR_FORLOOPDATATYPE); return ; } ring_list_setdouble_gc(pVM->pRingState,pVar,RING_VAR_VALUE,nNum2 +nNum1); /* Jump */ pVM->nPC = RING_VM_IR_READIVALUE(2) ; }
void ring_vm_jumpvarplenumstep1 ( VM *pVM ) { List *pVar ; double nNum1 ; pVar = (List *) RING_VM_IR_READP ; /* We don't Check Data type */ nNum1 = ring_list_getdouble(pVar,RING_VAR_VALUE) ; if ( nNum1 > RING_VM_IR_READDVALUE(2) ) { /* Jump */ pVM->nPC = RING_VM_IR_READIVALUE(3) ; } }
void ring_vm_jumpvarlplenum ( VM *pVM ) { List *pVar ; double nNum1,nNum2 ; /* Check Scope Life Time */ if ( RING_VM_IR_READIVALUE(5) != pVM->nActiveScopeID ) { RING_VM_IR_OPCODE = ICO_JUMPVARLENUM ; #if RING_SHOWICFINAL RING_VM_IR_PARACOUNT = RING_VM_IR_PARACOUNT - 2 ; ring_list_deleteitem_gc(pVM->pRingState,RING_VM_IR_LIST,ring_list_getsize(RING_VM_IR_LIST)); ring_list_deleteitem_gc(pVM->pRingState,RING_VM_IR_LIST,ring_list_getsize(RING_VM_IR_LIST)); #endif pVM->nPC-- ; return ; } pVar = (List *) RING_VM_IR_READPVALUE(4) ; nNum1 = ring_list_getdouble(pVM->aForStep,ring_list_getsize(pVM->aForStep)); /* Check Data */ if ( ring_list_isstring(pVar,RING_VAR_VALUE) ) { nNum2 = ring_vm_stringtonum(pVM,ring_list_getstring(pVar,RING_VAR_VALUE)); } else if ( ring_list_isnumber(pVar,RING_VAR_VALUE) ) { nNum2 = ring_list_getdouble(pVar,RING_VAR_VALUE) ; } else { ring_vm_error(pVM,RING_VM_ERROR_FORLOOPDATATYPE); return ; } if ( nNum1 < 0 ) { if ( ! (nNum2 >= RING_VM_IR_READDVALUE(2)) ) { /* Jump */ pVM->nPC = RING_VM_IR_READIVALUE(3) ; } } else { if ( ! (nNum2 <= RING_VM_IR_READDVALUE(2)) ) { /* Jump */ pVM->nPC = RING_VM_IR_READIVALUE(3) ; } } }
void ring_parser_icg_showoutput ( List *pListGenCode,int nStatus ) { int x,y,nCount,nCount2 ; List *pList ; assert(pListGenCode != NULL); /* Header */ printf( "\n\n" ) ; ring_print_line(); if ( nStatus == 1 ) { puts("Byte Code - Before Execution by the VM"); } else { puts("Byte Code - After Execution by the VM"); } ring_print_line(); nCount = ring_list_getsize(pListGenCode); if ( nCount > 0 ) { printf( "\n %6s %10s %10s\n", "PC","OPCode","Data" ) ; for ( x = 1 ; x <= nCount ; x++ ) { pList = ring_list_getlist(pListGenCode,x); nCount2 = ring_list_getsize(pList); printf( "\n %6d %10s ", x , RING_IC_OP[ring_list_getint(pList,1)] ) ; if ( nCount2 > 1 ) { for ( y = 2 ; y <= nCount2 ; y++ ) { if ( ring_list_isstring(pList,y) ) { printf( " %5s ",ring_list_getstring(pList,y) ) ; } else if ( ring_list_isnumber(pList,y) ) { if ( ring_list_isdouble(pList,y) ) { printf( " %f",ring_list_getdouble(pList,y) ) ; } else { printf( " %5d ",ring_list_getint(pList,y) ) ; } } else { printf( " %5p ",ring_list_getpointer(pList,y) ) ; } } } } printf( "\n" ) ; } /* End */ puts(""); ring_print_line(); puts(""); }
void ring_objfile_writelist ( List *pList,FILE *fObj ) { List *pList2 ; int x,x2 ; char *cString ; char cKey[11] ; strcpy(cKey,"ringstring"); fprintf( fObj , "{\n" ) ; /* Write List Items */ for ( x = 1 ; x <= ring_list_getsize(pList) ; x++ ) { pList2 = ring_list_getlist(pList,x); fprintf( fObj , "[T]\n" ) ; for ( x2 = 1 ; x2 <= ring_list_getsize(pList2) ; x2++ ) { if ( ring_list_isstring(pList2,x2) ) { fprintf( fObj , "[S][%d]" , ring_list_getstringsize(pList2,x2) ) ; /* Encrypt String */ cString = ring_list_getstring(pList2,x2) ; ring_objfile_xorstring(cString,ring_list_getstringsize(pList2,x2),cKey,10); fwrite( ring_list_getstring(pList2,x2) , 1 , ring_list_getstringsize(pList2,x2) , fObj ); /* Decrypt String */ ring_objfile_xorstring(cString,ring_list_getstringsize(pList2,x2),cKey,10); fprintf( fObj , "\n" ) ; } else if ( ring_list_isint(pList2,x2) ) { fprintf( fObj , "[I]%d\n" , ring_list_getint(pList2,x2) ) ; } else if ( ring_list_isdouble(pList2,x2) ) { fprintf( fObj , "[D]%f\n" , ring_list_getdouble(pList2,x2) ) ; } else if ( ring_list_ispointer(pList2,x2) ) { fprintf( fObj , "[P]%p\n" , (void *) ring_list_getpointer(pList2,x2) ) ; } else if ( ring_list_islist(pList2,x2) ) { fprintf( fObj , "[L]\n" ) ; ring_objfile_writelist(ring_list_getlist(pList2,x2) ,fObj); } } fprintf( fObj , "[E]\n" ) ; } fprintf( fObj , "}\n" ) ; }
void ring_vm_restorestack ( VM *pVM,List *pList ) { int x ; List *pList2 ; pVM->nSP = 0 ; if ( ring_list_getsize(pList) == 0 ) { return ; } for ( x = ring_list_getsize(pList) ; x >= 1 ; x-- ) { if ( ring_list_isstring(pList,x) ) { RING_VM_STACK_PUSHCVALUE(ring_list_getstring(pList,x)); } else if ( ring_list_isnumber(pList,x) ) { RING_VM_STACK_PUSHNVALUE(ring_list_getdouble(pList,x)); } else if ( ring_list_islist(pList,x) ) { pList2 = ring_list_getlist(pList,x); RING_VM_STACK_PUSHPVALUE(ring_list_getpointer(pList2,1)); RING_VM_STACK_OBJTYPE = ring_list_getint(pList2,2) ; } } }
void ring_vm_refmeta_getattribute ( void *pPointer ) { List *pList ; char *cStr ; int x ; if ( RING_API_PARACOUNT != 2 ) { RING_API_ERROR(RING_API_BADPARACOUNT); return ; } if ( RING_API_ISLIST(1) && RING_API_ISSTRING(2) ) { pList = RING_API_GETLIST(1) ; if ( ring_vm_oop_isobject(pList) ) { pList = ring_list_getlist(pList,RING_OBJECT_OBJECTDATA); cStr = RING_API_GETSTRING(2) ; ring_string_lower(cStr); for ( x = 1 ; x <= ring_list_getsize(pList) ; x++ ) { if ( strcmp(ring_list_getstring(ring_list_getlist(pList,x),RING_VAR_NAME),cStr) == 0 ) { pList = ring_list_getlist(pList,x) ; if ( ring_list_isnumber(pList,RING_VAR_VALUE) ) { RING_API_RETNUMBER(ring_list_getdouble(pList,RING_VAR_VALUE)); } else if ( ring_list_isstring(pList,RING_VAR_VALUE) ) { RING_API_RETSTRING2(ring_list_getstring(pList,RING_VAR_VALUE),ring_list_getstringsize(pList,RING_VAR_VALUE)); } else if ( ring_list_islist(pList,RING_VAR_VALUE) ) { RING_API_RETLIST(ring_list_getlist(pList,RING_VAR_VALUE)); } return ; } } RING_API_ERROR("Error : Property is not found!"); } else { RING_API_ERROR(RING_API_BADPARATYPE); } } else { RING_API_ERROR(RING_API_BADPARATYPE); } }
void ring_parser_icg_duplicate ( Parser *pParser,int nStart,int nEnd ) { List *pList,*pList2 ; int x ; #if RING_SHOWIC int y,nCount2 ; #endif assert(pParser != NULL); if ( (nStart <= nEnd) && ( nEnd <= ring_parser_icg_instructionscount(pParser) ) ) { for ( x = nStart ; x <= nEnd ; x++ ) { pList = ring_list_newlist(pParser->GenCode); pList2 = ring_list_getlist(pParser->GenCode,x); ring_list_copy(pList,pList2); #if RING_SHOWIC nCount2 = ring_list_getsize(pList); printf( "\n %6d [ %s ] ", ring_list_getsize(pParser->GenCode) , RING_IC_OP[ring_list_getint(pList,1)] ) ; if ( nCount2 > 1 ) { for ( y = 2 ; y <= nCount2 ; y++ ) { if ( ring_list_isstring(pList,y) ) { printf( " Operand : %s ",ring_list_getstring(pList,y) ) ; } else if ( ring_list_isnumber(pList,y) ) { if ( ring_list_isdouble(pList,y) ) { printf( " Operand : %f ",ring_list_getdouble(pList,y) ) ; } else { printf( " Operand : %5d ",ring_list_getint(pList,y) ) ; } } else { printf( " Operand : %5p ",ring_list_getpointer(pList,y) ) ; } } } #endif } } }
int ring_parser_stmt ( Parser *pParser ) { int x,nMark1,nMark2,nMark3,nStart,nEnd,nPerformanceLocations ; String *pString ; List *pMark,*pMark2,*pMark3,*pList2 ; double nNum1 ; char cStr[50] ; nPerformanceLocations = 0 ; char cFileName[200] ; assert(pParser != NULL); /* Statement --> Load Literal */ if ( ring_parser_iskeyword(pParser,K_LOAD) ) { ring_parser_nexttoken(pParser); if ( ring_parser_isliteral(pParser) ) { /* Generate Code */ ring_parser_icg_newoperation(pParser,ICO_FILENAME); ring_parser_icg_newoperand(pParser,pParser->TokenText); ring_parser_icg_newoperation(pParser,ICO_BLOCKFLAG); pMark = ring_parser_icg_getactiveoperation(pParser); #if RING_PARSERTRACE RING_STATE_CHECKPRINTRULES puts("Rule : Statement --> 'Load' Literal"); #endif /* No package at the start of the file */ pParser->ClassesMap = pParser->pRingState->pRingClassesMap ; strcpy(cFileName,pParser->TokenText); if ( ring_fexists(pParser->TokenText) == 0 ) { ring_exefolder(cFileName); strcat(cFileName,pParser->TokenText); if ( ring_fexists(cFileName) == 0 ) { strcpy(cFileName,pParser->TokenText); } } ring_scanner_readfile(cFileName,pParser->pRingState); /* ** Generate Code ** Return NULL */ ring_parser_icg_newoperation(pParser,ICO_RETNULL); nMark1 = ring_parser_icg_newlabel(pParser); ring_parser_icg_addoperandint(pMark,nMark1); /* Set Active File */ ring_parser_icg_newoperation(pParser,ICO_FILENAME); ring_parser_icg_newoperand(pParser,ring_list_getstring(pParser->pRingState->pRingFilesStack,ring_list_getsize(pParser->pRingState->pRingFilesStack))); ring_parser_nexttoken(pParser); return 1 ; } return 0 ; } /* Statement --> See Expr */ if ( ring_parser_iskeyword(pParser,K_SEE) ) { ring_parser_nexttoken(pParser); /* Generate Code */ ring_parser_icg_newoperation(pParser,ICO_FUNCEXE); x = ring_parser_expr(pParser); /* Generate Code */ ring_parser_icg_newoperation(pParser,ICO_PRINT); #if RING_PARSERTRACE RING_STATE_CHECKPRINTRULES puts("Rule : Statement --> 'See' Expr"); #endif return x ; } /* Statement --> Give Identifier */ if ( ring_parser_iskeyword(pParser,K_GIVE) ) { ring_parser_nexttoken(pParser); if ( ring_parser_isidentifier(pParser) ) { /* Generate Code */ ring_parser_icg_newoperation(pParser,ICO_LOADADDRESS); ring_parser_icg_newoperand(pParser,pParser->TokenText); ring_parser_nexttoken(pParser); x = ring_parser_mixer(pParser); if ( x == 0 ) { return 0 ; } /* Generate Code */ ring_parser_icg_newoperation(pParser,ICO_GIVE); #if RING_PARSERTRACE RING_STATE_CHECKPRINTRULES puts("Rule : Statement --> 'Give' Identifier|ListItem|Object.Attribute"); #endif return 1 ; } else { ring_parser_error(pParser,RING_PARSER_ERROR_VARNAME); return 0 ; } } /* Statement --> For Identifier = Expr to Expr {Statement} Next | For Identifier in Expr {Statemen */ if ( ring_parser_iskeyword(pParser,K_FOR) ) { ring_parser_nexttoken(pParser); if ( ring_parser_isidentifier(pParser) ) { pString = ring_string_new(pParser->TokenText); ring_parser_nexttoken(pParser); if ( ring_parser_isoperator(pParser,"=") ) { /* ** Generate Code ** Mark for Exit command to go to outside the loop */ ring_parser_icg_newoperation(pParser,ICO_EXITMARK); pMark3 = ring_parser_icg_getactiveoperation(pParser); ring_parser_icg_newoperation(pParser,ICO_LOADAFIRST); ring_parser_icg_newoperand(pParser,ring_string_get(pString)); ring_parser_nexttoken(pParser); pParser->nAssignmentFlag = 0 ; if ( ring_parser_expr(pParser) ) { /* ** Generate Code ** Before Equal ( = ) not += , -= ,... etc */ ring_parser_icg_newoperation(pParser,ICO_BEFOREEQUAL); ring_parser_icg_newoperandint(pParser,0); ring_parser_icg_newoperation(pParser,ICO_ASSIGNMENT); nMark1 = ring_parser_icg_newlabel(pParser); ring_parser_icg_newoperation(pParser,ICO_LOADAPUSHV); ring_parser_icg_newoperand(pParser,ring_string_get(pString)); if ( ring_parser_iskeyword(pParser,K_TO) ) { ring_parser_nexttoken(pParser); pParser->nAssignmentFlag = 0 ; if ( ring_parser_expr(pParser) ) { pParser->nAssignmentFlag = 1 ; /* Generate Code */ if ( (ring_parser_icg_getlastoperation(pParser) == ICO_PUSHN) && (ring_parser_icg_newlabel(pParser) == (nMark1+2)) ) { /* ** We check nMark2+2 to avoid executing next instructions when we have expr ** for example for x = 1 to 10+5 */ nNum1 = ring_list_getdouble(pParser->ActiveGenCodeList,2) ; ring_parser_icg_deletelastoperation(pParser); ring_parser_icg_setlastoperation(pParser,ICO_JUMPVARLENUM); ring_parser_icg_newoperanddouble(pParser,nNum1); /* Add Locations Needed for Instruction change for performance */ nPerformanceLocations = 1 ; } else { ring_parser_icg_newoperation(pParser,ICO_JUMPFOR); } pMark = ring_parser_icg_getactiveoperation(pParser); /* Step <expr> */ x = ring_parser_step(pParser,&nMark1); if ( x == 0 ) { ring_string_delete(pString); return 0 ; } #if RING_PARSERTRACE RING_STATE_CHECKPRINTRULES puts("Rule : Statement --> 'For' Identifier '=' Expr to Expr ['step' Expr]"); #endif while ( ring_parser_stmt(pParser) ) { if ( pParser->ActiveToken == pParser->TokensCount ) { break ; } } if ( ring_parser_iskeyword(pParser,K_NEXT) ) { /* Generate Code */ nMark3 = ring_parser_icg_newlabel(pParser); /* Increment Jump */ ring_parser_icg_newoperation(pParser,ICO_INCJUMP); ring_parser_icg_newoperand(pParser,ring_string_get(pString)); ring_parser_icg_newoperandint(pParser,nMark1); /* Add Locations needed for instruction change for performance */ ring_parser_icg_newoperandint(pParser,0); ring_parser_icg_newoperandint(pParser,0); nMark2 = ring_parser_icg_newlabel(pParser); ring_parser_icg_addoperandint(pMark,nMark2); /* Performance Locations */ if ( nPerformanceLocations ) { /* Add Locations Needed for Instruction JUMPVARLENUM change for performance */ ring_parser_icg_addoperandint(pMark,0); ring_parser_icg_addoperandint(pMark,0); } /* Set Exit Mark */ ring_parser_icg_addoperandint(pMark3,nMark2); /* Set Loop Mark */ ring_parser_icg_addoperandint(pMark3,nMark3); /* End Loop (Remove Exit Mark) */ ring_parser_icg_newoperation(pParser,ICO_POPEXITMARK); /* POP Step */ ring_parser_icg_newoperation(pParser,ICO_POPSTEP); ring_parser_nexttoken(pParser); #if RING_PARSERTRACE RING_STATE_CHECKPRINTRULES puts("Rule : Next --> 'Next'"); #endif ring_string_delete(pString); return 1 ; } else { ring_parser_error(pParser,RING_PARSER_ERROR_NEXT); } } } } } else if ( ring_parser_iskeyword(pParser,K_IN) ) { /* Generate Code */ sprintf( cStr , "n_sys_var_%d" , ring_parser_icg_instructionscount(pParser) ) ; /* Mark for Exit command to go to outside the loop */ ring_parser_icg_newoperation(pParser,ICO_EXITMARK); pMark3 = ring_parser_icg_getactiveoperation(pParser); ring_parser_icg_newoperation(pParser,ICO_LOADADDRESS); ring_parser_icg_newoperand(pParser,cStr); ring_parser_icg_newoperation(pParser,ICO_PUSHN); ring_parser_icg_newoperanddouble(pParser,1.0); /* Before Equal ( = ) not += , -= ,... etc */ ring_parser_icg_newoperation(pParser,ICO_BEFOREEQUAL); ring_parser_icg_newoperandint(pParser,0); ring_parser_icg_newoperation(pParser,ICO_ASSIGNMENT); /* Generate Code */ nMark1 = ring_parser_icg_newlabel(pParser); ring_parser_icg_newoperation(pParser,ICO_LOADAPUSHV); ring_parser_icg_newoperand(pParser,cStr); ring_parser_icg_newoperation(pParser,ICO_LOADFUNC); ring_parser_icg_newoperand(pParser,"len"); nStart = ring_parser_icg_instructionscount(pParser) + 1 ; ring_parser_nexttoken(pParser); pParser->nAssignmentFlag = 0 ; if ( ring_parser_expr(pParser) ) { pParser->nAssignmentFlag = 1 ; /* Generate Code */ nEnd = ring_parser_icg_instructionscount(pParser) ; /* Note (nEnd-1) , -1 to remove instruction PushV (avoid error with for x in string) */ if ( ring_parser_icg_getlastoperation(pParser) == ICO_PUSHV ) { nEnd-- ; } ring_parser_icg_newoperation(pParser,ICO_CALL); /* Generate 0 For Operator OverLoading */ ring_parser_icg_newoperandint(pParser,0); ring_parser_icg_newoperation(pParser,ICO_JUMPFOR); pMark = ring_parser_icg_getactiveoperation(pParser); ring_parser_icg_newoperation(pParser,ICO_LOADAFIRST); ring_parser_icg_newoperand(pParser,ring_string_get(pString)); ring_parser_icg_duplicate(pParser,nStart,nEnd); ring_parser_icg_newoperation(pParser,ICO_LOADAPUSHV); ring_parser_icg_newoperand(pParser,cStr); ring_parser_icg_newoperation(pParser,ICO_LOADINDEXADDRESS); /* Generate 0 For Operator OverLoading */ ring_parser_icg_newoperandint(pParser,0); /* Item by reference */ ring_parser_icg_newoperation(pParser,ICO_SETREFERENCE); /* Step <expr> */ x = ring_parser_step(pParser,&nMark1); if ( x == 0 ) { ring_string_delete(pString); return 0 ; } #if RING_PARSERTRACE RING_STATE_CHECKPRINTRULES puts("Rule : Statement --> 'For' Identifier 'in' Expr ['step' Expr]"); #endif while ( ring_parser_stmt(pParser) ) { if ( pParser->ActiveToken == pParser->TokensCount ) { break ; } } if ( ring_parser_iskeyword(pParser,K_NEXT) ) { ring_parser_nexttoken(pParser); /* Generate Code */ nMark3 = ring_parser_icg_newlabel(pParser); /* Increment Jump */ ring_parser_icg_newoperation(pParser,ICO_INCJUMP); ring_parser_icg_newoperand(pParser,cStr); ring_parser_icg_newoperandint(pParser,nMark1); /* Add Locations needed for instruction change for performance */ ring_parser_icg_newoperandint(pParser,0); ring_parser_icg_newoperandint(pParser,0); nMark2 = ring_parser_icg_newlabel(pParser); ring_parser_icg_addoperandint(pMark,nMark2); /* Set Exit Mark */ ring_parser_icg_addoperandint(pMark3,nMark2); /* Set Loop Mark */ ring_parser_icg_addoperandint(pMark3,nMark3); /* End Loop (Remove Exit Mark) */ ring_parser_icg_newoperation(pParser,ICO_POPEXITMARK); /* POP Step */ ring_parser_icg_newoperation(pParser,ICO_POPSTEP); /* Remove Reference Value */ ring_parser_icg_newoperation(pParser,ICO_LOADAFIRST); ring_parser_icg_newoperand(pParser,ring_string_get(pString)); ring_parser_icg_newoperation(pParser,ICO_KILLREFERENCE); ring_parser_icg_newoperation(pParser,ICO_PUSHN); ring_parser_icg_newoperanddouble(pParser,1.0); /* Before Equal ( = ) not += , -= ,... etc */ ring_parser_icg_newoperation(pParser,ICO_BEFOREEQUAL); ring_parser_icg_newoperandint(pParser,0); ring_parser_icg_newoperation(pParser,ICO_ASSIGNMENT); #if RING_PARSERTRACE RING_STATE_CHECKPRINTRULES puts("Rule : Next --> 'Next'"); #endif ring_string_delete(pString); return 1 ; } else { ring_parser_error(pParser,RING_PARSER_ERROR_NEXT); } } } ring_string_delete(pString); } return 0 ; } /* Statement --> IF Expr Statements OK */ if ( ring_parser_iskeyword(pParser,K_IF) ) { ring_parser_nexttoken(pParser); pParser->nAssignmentFlag = 0 ; if ( ring_parser_expr(pParser) ) { pParser->nAssignmentFlag = 1 ; /* ** First Condition ** Generate Code */ ring_parser_icg_newoperation(pParser,ICO_JUMPZERO); pMark = ring_parser_icg_getactiveoperation(pParser); #if RING_PARSERTRACE RING_STATE_CHECKPRINTRULES puts("Rule : Statement --> 'If' Expr {Statement} { But } [Else] Ok"); #endif while ( ring_parser_stmt(pParser) ) { if ( pParser->ActiveToken == pParser->TokensCount ) { break ; } } /* Generate Code */ pList2 = ring_list_new(0); ring_parser_icg_newoperation(pParser,ICO_JUMP); ring_list_addpointer(pList2,ring_parser_icg_getactiveoperation(pParser)); /* { 'But' Statements } 'Else' Statements */ while ( ring_parser_iskeyword(pParser,K_BUT) ) { /* Generate Code */ nMark1 = ring_parser_icg_newlabel(pParser); ring_parser_icg_addoperandint(pMark,nMark1); ring_parser_nexttoken(pParser); pParser->nAssignmentFlag = 0 ; if ( ring_parser_expr(pParser) ) { pParser->nAssignmentFlag = 1 ; /* Generate Code */ ring_parser_icg_newoperation(pParser,ICO_JUMPZERO); pMark = ring_parser_icg_getactiveoperation(pParser); #if RING_PARSERTRACE RING_STATE_CHECKPRINTRULES puts("Rule : But --> 'But' Expr {Statement}"); #endif while ( ring_parser_stmt(pParser) ) { if ( pParser->ActiveToken == pParser->TokensCount ) { break ; } } /* Generate Code */ ring_parser_icg_newoperation(pParser,ICO_JUMP); ring_list_addpointer(pList2,ring_parser_icg_getactiveoperation(pParser)); } } if ( ring_parser_iskeyword(pParser,K_ELSE) ) { /* Generate Code */ nMark1 = ring_parser_icg_newlabel(pParser); ring_parser_icg_addoperandint(pMark,nMark1); pMark = NULL ; ring_parser_nexttoken(pParser); #if RING_PARSERTRACE RING_STATE_CHECKPRINTRULES puts("Rule : Else --> 'Else' {Statement} "); #endif while ( ring_parser_stmt(pParser) ) { if ( pParser->ActiveToken == pParser->TokensCount ) { break ; } } } if ( ring_parser_iskeyword(pParser,K_OK) ) { /* Generate Code */ nMark1 = ring_parser_icg_newlabel(pParser); if ( pMark != NULL ) { ring_parser_icg_addoperandint(pMark,nMark1); } if ( ring_list_getsize(pList2) > 0 ) { for ( x = 1 ; x <= ring_list_getsize(pList2) ; x++ ) { ring_parser_icg_addoperandint(((List *) ring_list_getpointer(pList2,x)),nMark1); } } ring_list_delete(pList2); ring_parser_nexttoken(pParser); #if RING_PARSERTRACE RING_STATE_CHECKPRINTRULES puts("Rule : Ok --> 'OK'"); #endif return 1 ; } else { ring_parser_error(pParser,RING_PARSER_ERROR_OK); ring_list_delete(pList2); } } return 0 ; } /* Statement --> WHILE Expr Statements END */ if ( ring_parser_iskeyword(pParser,K_WHILE) ) { /* ** Generate Code ** Mark for Exit command to go to outsize the loop */ ring_parser_icg_newoperation(pParser,ICO_EXITMARK); pMark3 = ring_parser_icg_getactiveoperation(pParser); nMark1 = ring_parser_icg_newlabel(pParser); ring_parser_nexttoken(pParser); pParser->nAssignmentFlag = 0 ; if ( ring_parser_expr(pParser) ) { pParser->nAssignmentFlag = 1 ; /* Generate Code */ ring_parser_icg_newoperation(pParser,ICO_JUMPZERO); pMark = ring_parser_icg_getactiveoperation(pParser); #if RING_PARSERTRACE RING_STATE_CHECKPRINTRULES puts("Rule : Statement --> 'While' Expr {Statement} End"); #endif while ( ring_parser_stmt(pParser) ) { if ( pParser->ActiveToken == pParser->TokensCount ) { break ; } } if ( ring_parser_iskeyword(pParser,K_END) ) { /* Generate Code */ nMark3 = ring_parser_icg_newlabel(pParser); ring_parser_icg_newoperation(pParser,ICO_JUMP); ring_parser_icg_newoperandint(pParser,nMark1); nMark2 = ring_parser_icg_newlabel(pParser); ring_parser_icg_addoperandint(pMark,nMark2); /* Set Exit Mark */ ring_parser_icg_addoperandint(pMark3,nMark2); /* Set Loop Mark */ ring_parser_icg_addoperandint(pMark3,nMark3); /* End Loop (Remove Exit Mark) */ ring_parser_icg_newoperation(pParser,ICO_POPEXITMARK); ring_parser_nexttoken(pParser); #if RING_PARSERTRACE RING_STATE_CHECKPRINTRULES puts("Rule : End --> 'End'"); #endif return 1 ; } else { ring_parser_error(pParser,RING_PARSER_ERROR_END); } } return 0 ; } /* Statement --> DO Statements AGAIN Expr */ if ( ring_parser_iskeyword(pParser,K_DO) ) { /* ** Generate Code ** Mark for Exit command to go to outsize the loop */ ring_parser_icg_newoperation(pParser,ICO_EXITMARK); pMark3 = ring_parser_icg_getactiveoperation(pParser); nMark1 = ring_parser_icg_newlabel(pParser); ring_parser_nexttoken(pParser); #if RING_PARSERTRACE RING_STATE_CHECKPRINTRULES puts("Rule : Statement --> 'Do' {Statement} Again"); #endif while ( ring_parser_stmt(pParser) ) { if ( pParser->ActiveToken == pParser->TokensCount ) { break ; } } if ( ring_parser_iskeyword(pParser,K_AGAIN) ) { /* Generate Code */ ring_parser_nexttoken(pParser); pParser->nAssignmentFlag = 0 ; if ( ring_parser_expr(pParser) ) { /* Generate Code (Test Condition) */ ring_parser_icg_newoperation(pParser,ICO_JUMPZERO); pMark = ring_parser_icg_getactiveoperation(pParser); /* Generate Code */ nMark3 = ring_parser_icg_newlabel(pParser); ring_parser_icg_newoperation(pParser,ICO_JUMP); ring_parser_icg_newoperandint(pParser,nMark1); nMark2 = ring_parser_icg_newlabel(pParser); ring_parser_icg_addoperandint(pMark,nMark2); /* Set Exit Mark */ ring_parser_icg_addoperandint(pMark3,nMark2); /* Set Loop Mark */ ring_parser_icg_addoperandint(pMark3,nMark3); /* End Loop (Remove Exit Mark) */ ring_parser_icg_newoperation(pParser,ICO_POPEXITMARK); pParser->nAssignmentFlag = 1 ; #if RING_PARSERTRACE RING_STATE_CHECKPRINTRULES puts("Rule : Again --> 'Again' Expr"); #endif return 1 ; } } else { ring_parser_error(pParser,RING_PARSER_ERROR_AGAIN); } return 0 ; } /* Statement --> Return Expr */ if ( ring_parser_iskeyword(pParser,K_RETURN) ) { ring_parser_nexttoken(pParser); x = 1 ; if ( ring_parser_isendline(pParser) == 0 ) { /* Generate Code */ ring_parser_icg_newoperation(pParser,ICO_FUNCEXE); pParser->nAssignmentFlag = 0 ; x = ring_parser_expr(pParser); pParser->nAssignmentFlag = 1 ; /* Generate Code */ ring_parser_icg_newoperation(pParser,ICO_ENDFUNCEXE); ring_parser_icg_newoperation(pParser,ICO_RETURN); } else { /* ** Generate Code ** Return NULL */ ring_parser_icg_newoperation(pParser,ICO_RETNULL); } #if RING_PARSERTRACE if ( x == 1 ) { RING_STATE_CHECKPRINTRULES puts("Rule : Statement --> 'Return'"); } #endif return x ; } /* Statement --> Try {Statement} Catch {Statement} Done */ if ( ring_parser_iskeyword(pParser,K_TRY) ) { ring_parser_nexttoken(pParser); /* Generate Code */ ring_parser_icg_newoperation(pParser,ICO_TRY); pMark = ring_parser_icg_getactiveoperation(pParser); #if RING_PARSERTRACE RING_STATE_CHECKPRINTRULES puts("Rule : Statement --> 'Try' {Statement} Catch Done"); #endif while ( ring_parser_stmt(pParser) ) { if ( pParser->ActiveToken == pParser->TokensCount ) { break ; } } if ( ring_parser_iskeyword(pParser,K_CATCH) ) { ring_parser_nexttoken(pParser); /* ** Generate Code ** Jump from end of try block to label after done */ ring_parser_icg_newoperation(pParser,ICO_JUMP); pMark2 = ring_parser_icg_getactiveoperation(pParser); nMark1 = ring_parser_icg_newlabel(pParser); ring_parser_icg_addoperandint(pMark,nMark1); #if RING_PARSERTRACE RING_STATE_CHECKPRINTRULES puts("Rule : Catch --> 'Catch' {Statement}"); #endif while ( ring_parser_stmt(pParser) ) { if ( pParser->ActiveToken == pParser->TokensCount ) { break ; } } if ( ring_parser_iskeyword(pParser,K_DONE) ) { #if RING_PARSERTRACE RING_STATE_CHECKPRINTRULES puts("Rule : Done --> 'Done'"); #endif ring_parser_nexttoken(pParser); /* Generate Code */ ring_parser_icg_newoperation(pParser,ICO_JUMP); pMark3 = ring_parser_icg_getactiveoperation(pParser); nMark2 = ring_parser_icg_newlabel(pParser); ring_parser_icg_addoperandint(pMark2,nMark2); ring_parser_icg_newoperation(pParser,ICO_DONE); nMark3 = ring_parser_icg_newlabel(pParser); ring_parser_icg_addoperandint(pMark3,nMark3); return 1 ; } else { ring_parser_error(pParser,RING_PARSER_ERROR_NODONE); } } else { ring_parser_error(pParser,RING_PARSER_ERROR_NOCATCH); } } /* Statement --> Bye (Close the Program) */ if ( ring_parser_iskeyword(pParser,K_BYE) ) { ring_parser_nexttoken(pParser); #if RING_PARSERTRACE RING_STATE_CHECKPRINTRULES puts("Rule : Statement --> 'Bye' "); #endif /* Generate Code */ ring_parser_icg_newoperation(pParser,ICO_BYE); return 1 ; } /* Statement --> Exit (Go to outside the loop) */ if ( ring_parser_iskeyword(pParser,K_EXIT) ) { ring_parser_nexttoken(pParser); #if RING_PARSERTRACE RING_STATE_CHECKPRINTRULES puts("Rule : Statement --> 'Exit' "); #endif /* Generate Code */ ring_parser_icg_newoperation(pParser,ICO_EXIT); /* Check Number (Exit from more than one loop) */ if ( ring_parser_isnumber(pParser) ) { ring_parser_icg_newoperanddouble(pParser,atof(pParser->TokenText)); ring_parser_nexttoken(pParser); } return 1 ; } /* Statement --> Loop (Continue) */ if ( ring_parser_iskeyword(pParser,K_LOOP) ) { ring_parser_nexttoken(pParser); #if RING_PARSERTRACE RING_STATE_CHECKPRINTRULES puts("Rule : Statement --> 'Loop'"); #endif /* Generate Code */ ring_parser_icg_newoperation(pParser,ICO_LOOP); /* Check Number (Continue from more than one loop) */ if ( ring_parser_isnumber(pParser) ) { ring_parser_icg_newoperanddouble(pParser,atof(pParser->TokenText)); ring_parser_nexttoken(pParser); } return 1 ; } /* Statement --> Switch Expr { ON Expr {Statement} } OFF */ if ( ring_parser_iskeyword(pParser,K_SWITCH) ) { ring_parser_nexttoken(pParser); pParser->nAssignmentFlag = 0 ; if ( ring_parser_expr(pParser) ) { pParser->nAssignmentFlag = 1 ; #if RING_PARSERTRACE RING_STATE_CHECKPRINTRULES puts("Rule : Statement --> 'Switch' Expr {ON} [Other] OFF"); #endif RING_PARSER_IGNORENEWLINE ; /* ON Statements */ pList2 = ring_list_new(0); pMark = NULL ; while ( ring_parser_iskeyword(pParser,K_ON) ) { ring_parser_nexttoken(pParser); /* Generate Code */ nMark1 = ring_parser_icg_newlabel(pParser); if ( pMark != NULL ) { ring_parser_icg_addoperandint(pMark,nMark1); } ring_parser_icg_newoperation(pParser,ICO_DUPLICATE); pParser->nAssignmentFlag = 0 ; if ( ring_parser_expr(pParser) ) { pParser->nAssignmentFlag = 1 ; /* Generate Code */ ring_parser_icg_newoperation(pParser,ICO_EQUAL); ring_parser_icg_newoperation(pParser,ICO_JUMPZERO); pMark = ring_parser_icg_getactiveoperation(pParser); ring_parser_icg_newoperation(pParser,ICO_FREESTACK); #if RING_PARSERTRACE RING_STATE_CHECKPRINTRULES puts("Rule : ON --> 'on' Expr {Statement}"); #endif while ( ring_parser_stmt(pParser) ) { if ( pParser->ActiveToken == pParser->TokensCount ) { break ; } } /* Generate Code */ ring_parser_icg_newoperation(pParser,ICO_JUMP); ring_list_addpointer(pList2,ring_parser_icg_getactiveoperation(pParser)); } } /* Other */ if ( ring_parser_iskeyword(pParser,K_OTHER) ) { ring_parser_nexttoken(pParser); /* Generate Code */ nMark1 = ring_parser_icg_newlabel(pParser); if ( pMark != NULL ) { ring_parser_icg_addoperandint(pMark,nMark1); pMark = NULL ; } ring_parser_icg_newoperation(pParser,ICO_FREESTACK); #if RING_PARSERTRACE RING_STATE_CHECKPRINTRULES puts("Rule : Other --> 'Other' {Statement}"); #endif while ( ring_parser_stmt(pParser) ) { if ( pParser->ActiveToken == pParser->TokensCount ) { break ; } } } /* OFF */ if ( ring_parser_iskeyword(pParser,K_OFF) ) { ring_parser_nexttoken(pParser); /* Generate Code */ nMark1 = ring_parser_icg_newlabel(pParser); if ( pMark != NULL ) { ring_parser_icg_addoperandint(pMark,nMark1); } if ( ring_list_getsize(pList2) > 0 ) { for ( x = 1 ; x <= ring_list_getsize(pList2) ; x++ ) { ring_parser_icg_addoperandint(((List *) ring_list_getpointer(pList2,x)),nMark1); } } ring_list_delete(pList2); ring_parser_icg_newoperation(pParser,ICO_FREESTACK); #if RING_PARSERTRACE RING_STATE_CHECKPRINTRULES puts("Rule : OFF --> 'Off'"); #endif return 1 ; } else { ring_parser_error(pParser,RING_PARSER_ERROR_SWITCHOFF); } } else { ring_parser_error(pParser,RING_PARSER_ERROR_SWITCHEXPR); } } /* Statement --> epslion */ if ( ring_parser_epslion(pParser) ) { return 1 ; } /* Statement --> Expr */ if ( ring_parser_expr(pParser) ) { #if RING_PARSERTRACE RING_STATE_CHECKPRINTRULES puts("Rule : Statement --> Expr "); #endif ring_parser_icg_newoperation(pParser,ICO_FREESTACK); return 1 ; } return 0 ; }
void ring_vm_incp ( VM *pVM ) { List *pVar ; pVar = (List *) RING_VM_IR_READP ; ring_list_setdouble_gc(pVM->pRingState,pVar,RING_VAR_VALUE,ring_list_getdouble(pVar,RING_VAR_VALUE) + 1); }