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; }
BOOL FASTCALL comProc_VarDeclare(U16 flags, S16 *brackCnt) { int cast,arraySize,elementsSize,braceCnt; S32 offset=-1,elementsEnd; S32 num; U16 varflags = 0; char *label=NULL; VAR *castvar=NULL; VAR *var=NULL,*pvar; BOOL VARSET, SEEKED = FALSE; if(!STRCMP(szTemp,"typedef")) { varflags |= VARFLAG_TYPECAST; GetNextWord(); } if(!STRCMP(szTemp,"shared")) { varflags |= VARFLAG_SHARED; GetNextWord(); } if((cast=IsVarCast(szTemp,&castvar))==VARCAST_NULL) { if(varflags&VARFLAG_TYPECAST) { error(ERR_NOTTYPECAST,szTemp); return TRUE; } return FALSE; } if(curVar&&(curVar->flags&VARFLAG_TYPECAST)) varflags |= VARFLAG_TYPECAST; for(;;) { if(!IsStringLabel(GetNextWord())) { error(ERR_BADLABEL,szTemp); sprintf(szTemp, "invlabel_%04X", invlabel++); } else { if(PRECOMPILING && IsLabelUsed(szTemp,curVar?curVar->childVars:vars)) sprintf(szTemp, "invlabel_%04X", invlabel++); } label = strdup(szTemp); if(PeekNextWord()[0]==':') { GetNextWord(); if(IsStrNum(GetNextWord())) { offset = ConfirmWord(StrToInt(szTemp)); varflags |= VARFLAG_FIXED; } else error(ERR_INTEXP); VARSET = TRUE; } else { if(varflags&VARFLAG_TYPECAST) VARSET = TRUE; else if(!curBank) fatal(FTL_VARNOTROMBANK); if(cast == VARCAST_STRUCT && !(varflags & VARFLAG_TYPECAST) && !PRECOMPILING) { offset = GetBankOffset(); VARSET = TRUE; } else VARSET = FALSE; } if(PRECOMPILING) { var = AddVariable(label, cast, castvar, varflags, offset); if(varflags&VARFLAG_TYPECAST) { if(curVar) { var->offset = VarSize(curVar); } } } else { var = FindVariable(curVar?curVar->childVars:(varflags&VARFLAG_TYPECAST)?typedefs:vars, label); if(!(var->flags&VARFLAG_TYPECAST) && (!(var->flags&VARFLAG_DEFCASTED) || cast!=VARCAST_STRUCT) && (var->offset==-1)) SetVarOffsets(var,GetBankOffset(),FALSE); } if(castvar) { var->size = castvar->size; } arraySize = 0; if(PeekNextWord()[0]=='[') { GetNextWord(); if(PeekNextWord()[0]==']') { arraySize=-1;//autosize GetNextWord(); } else { /* if(IsStrNum(szTemp)) { if(((var->flags&VARFLAG_TYPECAST) && PRECOMPILING) || (!(var->flags&VARFLAG_TYPECAST))) { arraySize = ConfirmWord(StrToInt(szTemp)); var->arraySize = arraySize; } } else error(ERR_INTEXP); */ CompileImmediateInteger(0, &num, -1, 0); if(((var->flags&VARFLAG_TYPECAST) && PRECOMPILING) || (!(var->flags&VARFLAG_TYPECAST))) { arraySize = ConfirmWord(num); var->arraySize = arraySize; } if(GetNextWord()[0]!=']') error(ERR_ARRAYENDEXP,szTemp); } } if(!(var->flags&VARFLAG_DEFCASTED) && (cast==VARCAST_STRUCT)) { SetCurVar(var); GetCode(flags|CF_BRACEOK|CF_GETNEXTWORD, brackCnt); ReleaseCurVar(); } else { if(PeekNextWord()[0]=='=') { GetNextWord(); if(var->flags&VARFLAG_TYPECAST) { error(ERR_VARCASTASSIGN,label); SeekPastBraceBlock(); } else if(curBank->type==BANKTYPE_RAM) { error(ERR_VARDECLAREINRAM); SeekPastBraceBlock(); } else { elementsSize = 0; elementsEnd = (GetBankOffset()-curBank->org) + ((arraySize==-1)? var->size:var->size*arraySize); if(GetNextWord()[0]=='{') { if(!arraySize) { error(ERR_NOTARRAY,var->label); } braceCnt = 1; GetNextWord(); } else braceCnt = 0; do { braceCnt = CompileVarBody(flags,brackCnt, var, &elementsSize, braceCnt, cast); } while(braceCnt); if(!PRECOMPILING) { if(arraySize==-1) { arraySize=elementsSize/VarSize(var); SEEKED = TRUE; } else { if(elementsSize>VarSize(var)) error(ERR_ELEMENTSTOOLARGE,var->label,elementsSize-VarSize(var)); BankSeek(elementsEnd); SEEKED = TRUE; } var->arraySize = arraySize; } } } else { if(((var->flags&VARFLAG_TYPECAST) && PRECOMPILING) || (!(var->flags&VARFLAG_TYPECAST) && !PRECOMPILING && !VARSET)) { if(arraySize==-1) arraySize = 1; if(arraySize!=0) var->arraySize = arraySize; if(!PRECOMPILING) { BankSeekFwd(VarSize(var)); SEEKED = TRUE; } } } if(((var->flags&VARFLAG_TYPECAST) && PRECOMPILING) || (!(var->flags&VARFLAG_TYPECAST) && !PRECOMPILING)) { // adjust all the var sizes for structs arraySize = VarSize(var); pvar = var->parent; while(pvar) { pvar->size += arraySize; pvar = pvar->parent; } } } if(!(var->flags&VARFLAG_TYPECAST) && (cast==VARCAST_STRUCT)) SetVarOffsets(var,offset,FALSE); // removed 2004-05-22, if problems occurs, check if(!SEEKED && (var->flags&(VARFLAG_TYPECAST|VARFLAG_DEFCASTED))==VARFLAG_DEFCASTED && (cast==VARCAST_STRUCT)) { CheckCurBank(); if((var->flags&VARFLAG_TYPECAST) || !PRECOMPILING) BankSeekFwd(VarSize(var)); } ssFree(label); if(PeekNextWord()[0]!=',') break; GetNextWord(); } return TRUE; }