dect
/
asl
Archived
13
0
Fork 0
This repository has been archived on 2022-02-17. You can view files and clone it, but cannot push or open issues or pull requests.
asl/asmif.c

434 lines
10 KiB
C

/* 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