aboutsummaryrefslogtreecommitdiffstats
path: root/asmif.c
diff options
context:
space:
mode:
Diffstat (limited to 'asmif.c')
-rw-r--r--asmif.c433
1 files changed, 433 insertions, 0 deletions
diff --git a/asmif.c b/asmif.c
new file mode 100644
index 0000000..18a616e
--- /dev/null
+++ b/asmif.c
@@ -0,0 +1,433 @@
+/* asmif.c */
+/*****************************************************************************/
+/* AS-Portierung */
+/* */
+/* Befehle zur bedingten Assemblierung */
+/* */
+/* Historie: 15. 5.1996 Grundsteinlegung */
+/* */
+/*****************************************************************************/
+
+#include "stdinc.h"
+#include <string.h>
+#include <ctype.h>
+
+#include "bpemu.h"
+#include "chunks.h"
+#include "strutil.h"
+#include "asmdef.h"
+#include "asmsub.h"
+#include "asmpars.h"
+
+#include "asmif.h"
+
+
+PIfSave FirstIfSave;
+Boolean IfAsm; /* FALSE: in einer neg. IF-Sequenz-->kein Code */
+
+static Boolean ActiveIF;
+
+ static LongInt GetIfVal(char *Cond)
+BEGIN
+ Boolean IfOK;
+ LongInt Tmp;
+
+ FirstPassUnknown=False;
+ Tmp=EvalIntExpression(Cond,Int32,&IfOK);
+ if ((FirstPassUnknown) OR (NOT IfOK))
+ BEGIN
+ Tmp=1;
+ if (FirstPassUnknown) WrError(1820);
+ else if (NOT IfOK) WrError(1135);
+ END
+
+ return Tmp;
+END
+
+
+ static void AddBoolFlag(Boolean Flag)
+BEGIN
+ strmaxcpy(ListLine,Flag?"=>TRUE":"=>FALSE",255);
+END
+
+
+ static void PushIF(LongInt IfExpr)
+BEGIN
+ PIfSave NewSave;
+
+ NewSave=(PIfSave) malloc(sizeof(TIfSave));
+ NewSave->NestLevel=SaveIFs()+1;
+ NewSave->Next=FirstIfSave; NewSave->SaveIfAsm=IfAsm;
+ NewSave->State=IfState_IFIF; NewSave->CaseFound=(IfExpr!=0);
+ FirstIfSave=NewSave;
+ IfAsm=(IfAsm AND (IfExpr!=0));
+END
+
+
+ static void CodeIF(void)
+BEGIN
+ LongInt IfExpr;
+
+ ActiveIF=IfAsm;
+
+ if (NOT IfAsm) IfExpr=1;
+ else if (ArgCnt!=1)
+ BEGIN
+ WrError(1110); IfExpr=1;
+ END
+ else IfExpr=GetIfVal(ArgStr[1]);
+ if (IfAsm) AddBoolFlag(IfExpr!=0);
+ PushIF(IfExpr);
+END
+
+
+ static void CodeIFDEF(void)
+BEGIN
+ LongInt IfExpr;
+ Boolean Defined;
+
+ ActiveIF=IfAsm;
+
+ if (NOT IfAsm) IfExpr=1;
+ else if (ArgCnt!=1)
+ BEGIN
+ WrError(1110); IfExpr=1;
+ END
+ else
+ BEGIN
+ Defined=IsSymbolDefined(ArgStr[1]);
+ if (IfAsm)
+ strmaxcpy(ListLine,(Defined)?"=>DEFINED":"=>UNDEFINED",255);
+ if (Memo("IFDEF")) IfExpr=(Defined)?1:0;
+ else IfExpr=(Defined)?0:1;
+ END
+ PushIF(IfExpr);
+END
+
+
+ static void CodeIFUSED(void)
+BEGIN
+ LongInt IfExpr;
+ Boolean Used;
+
+ ActiveIF=IfAsm;
+
+ if (NOT IfAsm) IfExpr=1;
+ else if (ArgCnt!=1)
+ BEGIN
+ WrError(1110); IfExpr=1;
+ END
+ else
+ BEGIN
+ Used=IsSymbolUsed(ArgStr[1]);
+ if (IfAsm)
+ strmaxcpy(ListLine,(Used)?"=>USED":"=>UNUSED",255);
+ if (Memo("IFUSED")) IfExpr=(Used)?1:0;
+ else IfExpr=(Used)?0:1;
+ END
+ PushIF(IfExpr);
+END
+
+
+ void CodeIFEXIST(void)
+BEGIN
+ LongInt IfExpr;
+ Boolean Found;
+ String NPath;
+
+ ActiveIF=IfAsm;
+
+ if (NOT IfAsm) IfExpr=1;
+ else if (ArgCnt!=1)
+ BEGIN
+ WrError(1110); IfExpr=1;
+ END
+ else
+ BEGIN
+ strmaxcpy(ArgPart,ArgStr[1],255);
+ if (*ArgPart=='"') strcpy(ArgPart,ArgPart+1);
+ if (ArgPart[strlen(ArgPart)-1]=='"') ArgPart[strlen(ArgPart)-1]='\0';
+ AddSuffix(ArgPart,IncSuffix);
+ strmaxcpy(NPath,IncludeList,255); strmaxprep(NPath,".:",255);
+ Found=(*(FSearch(ArgPart,NPath))!='\0');
+ if (IfAsm)
+ strmaxcpy(ListLine,(Found)?"=>FOUND":"=>NOT FOUND",255);
+ if (Memo("IFEXIST")) IfExpr=(Found)?1:0;
+ else IfExpr=(Found)?0:1;
+ END
+ PushIF(IfExpr);
+END
+
+
+ static void CodeIFB(void)
+BEGIN
+ Boolean Blank=True;
+ LongInt IfExpr;
+ int z;
+
+ ActiveIF=IfAsm;
+
+ if (NOT IfAsm) IfExpr=1;
+ else
+ BEGIN
+ for (z=1; z<=ArgCnt; z++) if (strlen(ArgStr[z++])>0) Blank=False;
+ if (IfAsm)
+ strmaxcpy(ListLine,(Blank)?"=>BLANK":"=>NOT BLANK",255);
+ if (Memo("IFB")) IfExpr=(Blank)?1:0;
+ else IfExpr=(Blank)?0:1;
+ END
+ PushIF(IfExpr);
+END
+
+
+ static void CodeELSEIF(void)
+BEGIN
+ LongInt IfExpr;
+
+ if (FirstIfSave==Nil) WrError(1840);
+ else if (ArgCnt==0)
+ BEGIN
+ if (FirstIfSave->State!=IfState_IFIF) WrError(1480);
+ else if (FirstIfSave->SaveIfAsm) AddBoolFlag(IfAsm=(NOT FirstIfSave->CaseFound));
+ FirstIfSave->State=IfState_IFELSE;
+ END
+ else if (ArgCnt==1)
+ BEGIN
+ if (FirstIfSave->State!=IfState_IFIF) WrError(1480);
+ else
+ BEGIN
+ if (NOT FirstIfSave->SaveIfAsm) IfExpr=1;
+ else if (FirstIfSave->CaseFound) IfExpr=0;
+ else IfExpr=GetIfVal(ArgStr[1]);
+ IfAsm=((FirstIfSave->SaveIfAsm) AND (IfExpr!=0) AND (NOT FirstIfSave->CaseFound));
+ if (FirstIfSave->SaveIfAsm) AddBoolFlag(IfExpr!=0);
+ if (IfExpr!=0) FirstIfSave->CaseFound=True;
+ END
+ END
+ else WrError(1110);
+
+ ActiveIF=(FirstIfSave==Nil) OR (FirstIfSave->SaveIfAsm);
+END
+
+
+ static void CodeENDIF(void)
+BEGIN
+ PIfSave NewSave;
+
+ if (ArgCnt!=0) WrError(1110);
+ if (FirstIfSave==Nil) WrError(1840);
+ else
+ BEGIN
+ if ((FirstIfSave->State!=IfState_IFIF) AND (FirstIfSave->State!=IfState_IFELSE)) WrError(1480);
+ else
+ BEGIN
+ IfAsm=FirstIfSave->SaveIfAsm;
+ NewSave=FirstIfSave; FirstIfSave=NewSave->Next;
+ free(NewSave);
+ END
+ END
+
+ ActiveIF=IfAsm;
+END
+
+
+ static void EvalIfExpression(char *Cond, TempResult *erg)
+BEGIN
+ FirstPassUnknown=False;
+ EvalExpression(Cond,erg);
+ if ((erg->Typ==TempNone) OR (FirstPassUnknown))
+ BEGIN
+ erg->Typ=TempInt; erg->Contents.Int=1;
+ if (FirstPassUnknown) WrError(1820);
+ END
+END
+
+
+ static void CodeSWITCH(void)
+BEGIN
+ PIfSave NewSave;
+
+ ActiveIF=IfAsm;
+
+ NewSave=(PIfSave) malloc(sizeof(TIfSave));
+ NewSave->NestLevel=SaveIFs()+1;
+ NewSave->Next=FirstIfSave; NewSave->SaveIfAsm=IfAsm;
+ NewSave->CaseFound=False; NewSave->State=IfState_CASESWITCH;
+ if (ArgCnt!=1)
+ BEGIN
+ NewSave->SaveExpr.Typ=TempInt;
+ NewSave->SaveExpr.Contents.Int=1;
+ if (IfAsm) WrError(1110);
+ END
+ else
+ BEGIN
+ EvalIfExpression(ArgStr[1],&(NewSave->SaveExpr));
+ SetListLineVal(&(NewSave->SaveExpr));
+ END
+ FirstIfSave=NewSave;
+END
+
+
+ static void CodeCASE(void)
+BEGIN
+ Boolean eq;
+ int z;
+ TempResult t;
+
+ if (FirstIfSave==Nil) WrError(1840);
+ else if (ArgCnt==0) WrError(1110);
+ else
+ BEGIN
+ if ((FirstIfSave->State!=IfState_CASESWITCH) AND (FirstIfSave->State!=IfState_CASECASE)) WrError(1480);
+ else
+ BEGIN
+ if (NOT FirstIfSave->SaveIfAsm) eq=True;
+ else if (FirstIfSave->CaseFound) eq=False;
+ else
+ BEGIN
+ eq=False; z=1;
+ do
+ BEGIN
+ EvalIfExpression(ArgStr[z],&t);
+ eq=(FirstIfSave->SaveExpr.Typ==t.Typ);
+ if (eq)
+ switch (t.Typ)
+ BEGIN
+ case TempInt: eq=(t.Contents.Int==FirstIfSave->SaveExpr.Contents.Int); break;
+ case TempFloat: eq=(t.Contents.Float==FirstIfSave->SaveExpr.Contents.Float); break;
+ case TempString: eq=(strcmp(t.Contents.Ascii,FirstIfSave->SaveExpr.Contents.Ascii)==0); break;
+ case TempNone: eq=False; break;
+ END
+ z++;
+ END
+ while ((NOT eq) AND (z<=ArgCnt));
+ END;
+ IfAsm=((FirstIfSave->SaveIfAsm) AND (eq) AND (NOT FirstIfSave->CaseFound));
+ if (FirstIfSave->SaveIfAsm) AddBoolFlag(eq AND (NOT FirstIfSave->CaseFound));
+ if (eq) FirstIfSave->CaseFound=True;
+ FirstIfSave->State=IfState_CASECASE;
+ END
+ END
+
+ ActiveIF=(FirstIfSave==Nil) OR (FirstIfSave->SaveIfAsm);
+END
+
+
+ static void CodeELSECASE(void)
+BEGIN
+ if (ArgCnt!=0) WrError(1110);
+ else
+ BEGIN
+ if ((FirstIfSave->State!=IfState_CASESWITCH) AND (FirstIfSave->State!=IfState_CASECASE)) WrError(1480);
+ else IfAsm=(FirstIfSave->SaveIfAsm AND (NOT FirstIfSave->CaseFound));
+ if (FirstIfSave->SaveIfAsm) AddBoolFlag(NOT FirstIfSave->CaseFound);
+ FirstIfSave->CaseFound=True;
+ FirstIfSave->State=IfState_CASEELSE;
+ END
+
+ ActiveIF=(FirstIfSave==Nil) OR (FirstIfSave->SaveIfAsm);
+END
+
+
+ static void CodeENDCASE(void)
+BEGIN
+ PIfSave NewSave;
+
+ if (ArgCnt!=0) WrError(1110);
+ if (FirstIfSave==Nil) WrError(1840);
+ else
+ BEGIN
+ if ((FirstIfSave->State!=IfState_CASESWITCH)
+ AND (FirstIfSave->State!=IfState_CASECASE)
+ AND (FirstIfSave->State!=IfState_CASEELSE)) WrError(1480);
+ else
+ BEGIN
+ IfAsm=FirstIfSave->SaveIfAsm;
+ if (NOT FirstIfSave->CaseFound) WrError(100);
+ NewSave=FirstIfSave; FirstIfSave=NewSave->Next;
+ free(NewSave);
+ END
+ END
+
+ ActiveIF=IfAsm;
+END
+
+
+ Boolean CodeIFs(void)
+BEGIN
+ Boolean Result=True;
+
+ ActiveIF=False;
+
+ switch (toupper(*OpPart))
+ BEGIN
+ case 'I':
+ if (Memo("IF")) CodeIF();
+ else if ((Memo("IFDEF")) OR (Memo("IFNDEF"))) CodeIFDEF();
+ else if ((Memo("IFUSED")) OR (Memo("IFNUSED"))) CodeIFUSED();
+ else if ((Memo("IFEXIST")) OR (Memo("IFNEXIST"))) CodeIFEXIST();
+ else if ((Memo("IFB")) OR (Memo("IFNB"))) CodeIFB();
+ else Result=False;
+ break;
+ case 'E':
+ if ((Memo("ELSE")) OR (Memo("ELSEIF"))) CodeELSEIF();
+ else if (Memo("ENDIF")) CodeENDIF();
+ else if (Memo("ELSECASE")) CodeELSECASE();
+ else if (Memo("ENDCASE")) CodeENDCASE();
+ else Result=False;
+ break;
+ case 'S':
+ if (Memo("SWITCH")) CodeSWITCH();
+ else Result=False;
+ break;
+ case 'C':
+ if (Memo("CASE")) CodeCASE();
+ else Result=False;
+ break;
+ default:
+ Result=False;
+ END
+
+ return Result;
+END
+
+ Integer SaveIFs(void)
+BEGIN
+ return (FirstIfSave==Nil) ? 0 : FirstIfSave->NestLevel;
+END
+
+ void RestoreIFs(Integer Level)
+BEGIN
+ PIfSave OldSave;
+
+ while ((FirstIfSave!=Nil) AND (FirstIfSave->NestLevel!=Level))
+ BEGIN
+ OldSave=FirstIfSave; FirstIfSave=OldSave->Next;
+ IfAsm=OldSave->SaveIfAsm;
+ free(OldSave);
+ END
+END
+
+
+ Boolean IFListMask(void)
+BEGIN
+ switch (ListOn)
+ BEGIN
+ case 0: return True;
+ case 1: return False;
+ case 2: return ((NOT ActiveIF) AND (NOT IfAsm));
+ case 3: return (ActiveIF OR (NOT IfAsm));
+ END
+ return True;
+END
+
+
+ void AsmIFInit(void)
+BEGIN
+ IfAsm=True;
+END
+
+
+ void asmif_init(void)
+BEGIN
+END