void WriteCodeWL(U8 opw, U8 opl, S32 value) { if(value&0xFFFF8000) { WriteOpcode(opw); WriteCodeW((S16)value); } else { WriteOpcode(opl); WriteCodeL(value); } }
BOOL FASTCALL comProc_IfLoop(U16 flags, S16 *brackCnt) { BOOL BRACK=FALSE,FAR_BRANCH=FALSE,FLIPOP; S32 start,whilestart,offset; BANK *bank; U8 *condPtr,*elsePtr; int index,mode; CheckCurBank(); if((mode=StrInStrint(szTemp,siIffys))!=-1) { if(mode==IFMODE_DOWHILE) { bank = curBank; start = GetBankOffset(); if(STRCMP(GetNextWord(),"while")) { // 'ist der code block! GetCode(flags|CF_BRACEOK, brackCnt); if(STRCMP(GetNextWord(),"while")) error(ERR_WHILEEXP,szTemp); } } if(GetNextWord()[0]!='(') error(ERR_INVCOND,szTemp); else { GetNextWord(); BRACK = TRUE; } USE_DEFS = FALSE; if(!STRCMP(szTemp,"far")) { FAR_BRANCH = TRUE; GetNextWord(); } else if(!STRCMP(szTemp,"near")) { GetNextWord(); } // parse the "is" "is not" "not" "no", etc. FLIPOP = FALSE; while((index=StrInStrint(szTemp,siIsNot))!=-1) { if(!siIsNot[index].index) FLIPOP = !FLIPOP; GetNextWord(); } USE_DEFS = TRUE; if(!PRECOMPILING) { if((index=StrInStrint(szTemp,siConditions))==-1) { error(ERR_INVALIDCOND,szTemp); condPtr = NULL; } else { if(mode==IFMODE_IF || mode==IFMODE_WHILE) FLIPOP = !FLIPOP; index = (FLIPOP)? RelSwapOp(siConditions[index].index): siConditions[index].index; if(mode==IFMODE_WHILE) whilestart = GetBankOffset(); if(FAR_BRANCH) { WriteOpcodeB(RelSwapOp(index),3); WriteOpcode(opJMP_ABS); condPtr = curBank->ptr; WriteCodeW(0); } else { condPtr = curBank->ptr+1; WriteOpcodeB(index,0); } } if(mode!=IFMODE_DOWHILE) { bank = curBank; start = GetBankOffset(); } } if(BRACK && GetNextWord()[0]!=')') { error(ERR_IFCONDCLOSEEXP,szTemp); } if(mode!=IFMODE_DOWHILE) GetCode(flags|CF_BRACEOK|CF_GETNEXTWORD, brackCnt); elsePtr = NULL; if(!STRCMP(PeekNextWord(),"else")) { GetNextWord(); if(mode!=IFMODE_IF) error(ERR_ONLYIFSELSE); else { if(!PRECOMPILING) WriteOpcode(opJMP_ABS); elsePtr = curBank->ptr; if(!PRECOMPILING) WriteCodeW(0); } } if(!PRECOMPILING) { if(bank != curBank) error(ERR_FOREVEROUTOFBANK,bank->label,curBank->label); else if(condPtr) { if(mode==IFMODE_WHILE) { WriteOpcodeW(opJMP_ABS,whilestart); } if(FAR_BRANCH) { if(mode==IFMODE_DOWHILE) { PUTW(condPtr,start); } else { PUTW(condPtr,GetBankOffset()); } } else { offset = mode==IFMODE_DOWHILE? start-GetBankOffset(): GetBankOffset()-start; if((offset<-128 || offset>127)) error(ERR_BRANCHOUTOFRANGE); else PUTB(condPtr,(U8)offset); } } } if(elsePtr) { GetCode(flags|CF_BRACEOK|CF_GETNEXTWORD, brackCnt); if(!PRECOMPILING) PUTW(elsePtr,GetBankOffset()); } } else if(!STRCMP(szTemp,"forever")) { bank = curBank; start = GetBankOffset(); GetCode(flags|CF_BRACEOK|CF_GETNEXTWORD, brackCnt); if(bank != curBank) error(ERR_FOREVEROUTOFBANK,bank->label,curBank->label); else WriteOpcodeW(opJMP_ABS,start); } else return FALSE; return TRUE; }
int FASTCALL CompileVarBody(U16 flags, S16 *brackCnt, VAR *var, int *_elementsSize, int braceCnt, int cast) { int elementsSize, len; S32 num; VAR *childvar; S16 braceCntStart; int elementsStart; elementsSize = *_elementsSize; if(!PRECOMPILING) { elementsStart = elementsSize; } if(comProc_LabelDeclaration(flags, brackCnt)) { // catch the labels if(braceCnt) { if(GetNextWord()[0]=='}') braceCnt--; } } else { if(var->cast == VARCAST_STRUCT) { braceCntStart = braceCnt; if(szTemp[0]!='{') { error(ERR_STRUCTELEMENTBRACE,szTemp); } else { GetNextWord(); braceCnt++; } childvar = FindFirstVariable(var->childVars); while(childvar) { braceCnt = CompileVarBody(flags|CF_VARCHILD,brackCnt, childvar, &elementsSize, braceCnt, childvar->cast); childvar = childvar->next; if(childvar && !braceCnt) return 0; } if(braceCntStart != braceCnt) { error(ERR_CLOSEBRACEEXP,var->label); } if(!PRECOMPILING) var=var; } else if(szTemp[0]=='{' && var->arraySize) { int arsize = var->arraySize; braceCntStart = braceCnt; GetNextWord(); braceCnt++; childvar = CloneVar(var, curVar, 0); childvar->arraySize = 0; do { braceCnt = CompileVarBody(flags|CF_VARCHILD,brackCnt, childvar, &elementsSize, braceCnt, childvar->cast); arsize--; } while(braceCnt && braceCnt > braceCntStart); FreeVars(&childvar); if(braceCntStart != braceCnt) { error(ERR_CLOSEBRACEEXP,var->label); } if(!PRECOMPILING && arsize < 0) { error(ERR_ARRAYTOOLARGE,var->label); } } else if(szTemp[0]=='"') { if(varcasts[cast].size!=VARSIZE_BYTE) error(ERR_STRINGNOTBYTE,var->label); if(!DoString()) return 0; if(!PRECOMPILING) { len = lenSzStr;//(U16)strlen(szString); if(var->arraySize && len > var->arraySize) { len = var->arraySize; szString[len?len-1:0] = '\0'; error(ERR_STRINGTOOLONG,szString); } BankWrite(szString,len); if(var->arraySize) { BankFill(0,var->arraySize-len); elementsSize += var->arraySize; } else { elementsSize += len; } } } else { CompileImmediateInteger(0, &num, -4, 0); if(!PRECOMPILING) { if(strToInt_LabelObject) { // do the fixup AddFixOffs( strToInt_LabelType, (var->flags&VARFLAG_16BIT)?FIXOFFS_WORD:FIXOFFS_BYTE, curBank->ptr, 0, strToInt_LabelObject ); } if(var->flags&VARFLAG_16BIT) { WriteCodeW(num); elementsSize += 2; } else { WriteCodeB(num); elementsSize ++; } } } if(braceCnt) { if(GetNextWord()[0]=='}') { braceCnt--; } else if(szTemp[0]!=',') { error(ERR_ARRAYCOMMAEXP,var->label); } else { if(GetNextWord()[0]=='}') { braceCnt--; } } } } if(!PRECOMPILING && (flags&CF_VARCHILD)) { int amount = (elementsSize-elementsStart); if(var->arraySize && amount < var->arraySize) { BankFill(0,var->arraySize-amount); elementsSize += var->arraySize-amount; } } *_elementsSize = elementsSize; return braceCnt; }
void WriteOpcodeW(U8 code, S32 value) { WriteOpcode(code); WriteCodeW(value); }