3823 lines
107 KiB
C
3823 lines
107 KiB
C
/* asmpars.c */
|
|
/*****************************************************************************/
|
|
/* AS-Portierung */
|
|
/* */
|
|
/* Verwaltung von Symbolen und das ganze Drumherum... */
|
|
/* */
|
|
/* Historie: 5. 5.1996 Grundsteinlegung */
|
|
/* 4. 1.1997 Umstellung wg. case-sensitiv */
|
|
/* 24. 9.1997 Registersymbole */
|
|
/* 26. 6.1998 Codepages */
|
|
/* 7. 7.1998 Fix Zugriffe auf CharTransTable wg. signed chars */
|
|
/* 17. 7.1998 Korrektur Maskentabellen */
|
|
/* 16. 8.1998 NoICE-Symbolausgabe */
|
|
/* 18. 8.1998 Benutzung RadixBase */
|
|
/* 19. 8.1998 == als Alias fuer = - Operator */
|
|
/* 1. 9.1998 RefList nicht initialisiert bei Symbolen */
|
|
/* ACOT korrigiert */
|
|
/* 6.12.1998 UInt14 */
|
|
/* 30. 1.1999 Formate maschinenunabhaengig gemacht */
|
|
/* 12. 2.1999 Compilerwarnungen beseitigt */
|
|
/* 17. 4.1999 Abfrage auf PCSymbol gegen Nullzeigerzugriff ge- */
|
|
/* schuetzt. */
|
|
/* 30. 5.1999 OutRadixBase beruecksichtigt */
|
|
/* 12. 7.1999 angefangen mit externen Symbolen */
|
|
/* 14. 7.1999 Relocs im Parser beruecksichtigt */
|
|
/* 1. 8.1999 Relocs im Formelparser durch */
|
|
/* 8. 8.1999 Relocs in EvalIntExpression beruecksichtigt */
|
|
/* */
|
|
/*****************************************************************************/
|
|
|
|
#include "stdinc.h"
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
|
|
#include "endian.h"
|
|
#include "bpemu.h"
|
|
#include "nls.h"
|
|
#include "nlmessages.h"
|
|
#include "as.rsc"
|
|
#include "strutil.h"
|
|
|
|
#include "asmdef.h"
|
|
#include "asmsub.h"
|
|
#include "asmfnums.h"
|
|
#include "asmrelocs.h"
|
|
#include "chunks.h"
|
|
|
|
#include "asmpars.h"
|
|
|
|
LargeWord IntMasks[IntTypeCnt]=
|
|
{0x00000001l, /* UInt1 */
|
|
0x00000003l, /* UInt2 */
|
|
0x00000007l, /* UInt3 */
|
|
0x00000007l,0x0000000fl,0x0000000fl, /* SInt4 UInt4 Int4 */
|
|
0x0000000fl,0x0000001fl,0x0000001fl, /* SInt5 UInt5 Int5 */
|
|
0x0000003fl, /* UInt6 */
|
|
0x0000003fl,0x0000007fl, /* SInt7 UInt7 */
|
|
0x0000007fl,0x000000ffl,0x000000ffl, /* SInt8 UInt8 Int8 */
|
|
0x000001ffl, /* UInt9 */
|
|
0x000003ffl,0x000003ffl, /* UInt10 Int10 */
|
|
0x000007ffl, /* UInt11 */
|
|
0x00000fffl,0x00000fffl, /* UInt12 Int12 */
|
|
0x00001fffl, /* UInt13 */
|
|
0x00003fffl, /* UInt14 */
|
|
0x00007fffl, /* UInt15 */
|
|
0x00007fffl,0x0000ffffl,0x0000ffffl, /* SInt16 UInt16 Int16 */
|
|
0x0003ffffl, /* UInt18 */
|
|
0x0007ffffl,0x000fffffl,0x000fffffl, /* SInt20 UInt20 Int20 */
|
|
0x003fffffl, /* UInt22 */
|
|
0x007fffffl,0x00ffffffl,0x00ffffffl, /* SInt24 UInt24 Int24 */
|
|
0xffffffffl,0xffffffffl,0xffffffffl /* SInt32 UInt32 Int32 */
|
|
#ifdef HAS64
|
|
,0xffffffffffffffffllu /* Int64 */
|
|
#endif
|
|
};
|
|
|
|
LargeInt IntMins[IntTypeCnt]=
|
|
{ 0l, /* UInt1 */
|
|
0l, /* UInt2 */
|
|
0l, /* UInt3 */
|
|
-8l, 0l, -8l, /* SInt4 UInt4 Int4 */
|
|
-16l, 0l, -16l, /* SInt5 UInt5 Int5 */
|
|
0l, /* UInt6 */
|
|
-64, 0l, /* SInt7 UInt7 */
|
|
-128l, 0l, -128l, /* SInt8 UInt8 Int8 */
|
|
0l, /* UInt9 */
|
|
0l, -512l, /* UInt10 Int10 */
|
|
0l, /* UInt11 */
|
|
0l, -2047l, /* UInt12 Int12 */
|
|
0l, /* UInt13 */
|
|
0l, /* UInt14 */
|
|
0l, /* UInt15 */
|
|
-32768l, 0l, -32768l, /* SInt16 UInt16 Int16 */
|
|
0l, /* UInt18 */
|
|
-524288l, 0l, -524288l, /* SInt20 UInt20 Int20 */
|
|
0l, /* UInt22 */
|
|
-8388608l, 0l, -8388608l, /* SInt24 UInt24 Int24 */
|
|
-2147483647l, 0l,-2147483647l /* SInt32 UInt32 Int32 */
|
|
#ifdef HAS64
|
|
,-9223372036854775807ll /* Int64 */
|
|
#endif
|
|
};
|
|
|
|
LargeInt IntMaxs[IntTypeCnt]=
|
|
{ 1l, /* UInt1 */
|
|
3l, /* UInt2 */
|
|
7l, /* UInt3 */
|
|
7l, 15l, 15l, /* SInt4 UInt4 Int4 */
|
|
15l, 31l, 31l, /* SInt5 UInt5 Int5 */
|
|
63l, /* UInt6 */
|
|
63l, 127l, /* SInt7 UInt7 */
|
|
127l, 255l, 255l, /* SInt8 UInt8 Int8 */
|
|
511l, /* UInt9 */
|
|
1023l, 1023l, /* UInt10 Int10 */
|
|
2047l, /* UInt11 */
|
|
4095l, 4095l, /* UInt12 Int12 */
|
|
8191l, /* UInt13 */
|
|
16383l, /* UInt14 */
|
|
32767l, /* UInt15 */
|
|
32767l, 65535l, 65535l, /* SInt16 UInt16 Int16 */
|
|
262143l, /* UInt18 */
|
|
524287l, /* SInt20 */
|
|
1048575l, 1048575l, /* UInt20 Int20 */
|
|
4194303l, /* UInt22 */
|
|
#ifdef __STDC__
|
|
8388607l, 16777215l, 16777215l, /* SInt24 UInt24 Int24 */
|
|
2147483647l, 4294967295ul,4294967295ul /* SInt32 UInt32 Int32 */
|
|
#else
|
|
8388607l, 16777215l, 16777215l, /* SInt24 UInt24 Int24 */
|
|
2147483647l, 4294967295l, 4294967295l /* SInt32 UInt32 Int32 */
|
|
#endif
|
|
#ifdef HAS64
|
|
, 9223372036854775807ll /* Int64 */
|
|
#endif
|
|
};
|
|
|
|
|
|
Boolean FirstPassUnknown; /* Hinweisflag: evtl. im ersten Pass unbe-
|
|
kanntes Symbol, Ausdruck nicht ausgewertet */
|
|
Boolean SymbolQuestionable; /* Hinweisflag: Dadurch, dass Phasenfehler
|
|
aufgetreten sind, ist dieser Symbolwert evtl.
|
|
nicht mehr aktuell */
|
|
Boolean UsesForwards; /* Hinweisflag: benutzt Vorwaertsdefinitionen */
|
|
LongInt MomLocHandle; /* Merker, den lokale Symbole erhalten */
|
|
|
|
LongInt LocHandleCnt; /* mom. verwendeter lokaler Handle */
|
|
|
|
Boolean BalanceTree; /* Symbolbaum ausbalancieren */
|
|
|
|
|
|
static char BaseIds[3]={'%','@','$'};
|
|
static char BaseLetters[3]={'B','O','H'};
|
|
static Byte BaseVals[3]={2,8,16};
|
|
|
|
typedef struct _TSymbolStackEntry
|
|
{
|
|
struct _TSymbolStackEntry *Next;
|
|
SymbolVal Contents;
|
|
} TSymbolStackEntry,*PSymbolStackEntry;
|
|
|
|
typedef struct _TSymbolStack
|
|
{
|
|
struct _TSymbolStack *Next;
|
|
char *Name;
|
|
PSymbolStackEntry Contents;
|
|
} TSymbolStack,*PSymbolStack;
|
|
|
|
typedef struct _TDefSymbol
|
|
{
|
|
struct _TDefSymbol *Next;
|
|
char *SymName;
|
|
TempResult Wert;
|
|
} TDefSymbol,*PDefSymbol;
|
|
|
|
typedef struct _TCToken
|
|
{
|
|
struct _TCToken *Next;
|
|
char *Name;
|
|
LongInt Parent;
|
|
ChunkList Usage;
|
|
} TCToken,*PCToken;
|
|
|
|
typedef struct Operator
|
|
{
|
|
char *Id;
|
|
int IdLen;
|
|
Boolean Dyadic;
|
|
Byte Priority;
|
|
Boolean MayInt;
|
|
Boolean MayFloat;
|
|
Boolean MayString;
|
|
Boolean Present;
|
|
} Operator;
|
|
|
|
typedef struct _TLocHeap
|
|
{
|
|
struct _TLocHeap *Next;
|
|
LongInt Cont;
|
|
} TLocHeap,*PLocHandle;
|
|
|
|
typedef struct _TRegDefList
|
|
{
|
|
struct _TRegDefList *Next;
|
|
LongInt Section;
|
|
char *Value;
|
|
Boolean Used;
|
|
} TRegDefList,*PRegDefList;
|
|
|
|
typedef struct _TRegDef
|
|
{
|
|
struct _TRegDef *Left,*Right;
|
|
char *Orig;
|
|
PRegDefList Defs,DoneDefs;
|
|
} TRegDef,*PRegDef;
|
|
|
|
static SymbolPtr FirstSymbol,FirstLocSymbol;
|
|
static PDefSymbol FirstDefSymbol;
|
|
/*static*/ PCToken FirstSection;
|
|
static PRegDef FirstRegDef;
|
|
static Boolean DoRefs; /* Querverweise protokollieren */
|
|
static PLocHandle FirstLocHandle;
|
|
static PSymbolStack FirstStack;
|
|
static PCToken MomSection;
|
|
|
|
void AsmParsInit(void)
|
|
BEGIN
|
|
FirstSymbol=Nil;
|
|
|
|
FirstLocSymbol = Nil; MomLocHandle = (-1); SetMomSection(-1);
|
|
FirstSection = Nil;
|
|
FirstLocHandle = Nil;
|
|
FirstStack = Nil;
|
|
FirstRegDef = Nil;
|
|
DoRefs = True;
|
|
RadixBase = 10;
|
|
OutRadixBase = 16;
|
|
END
|
|
|
|
|
|
Boolean RangeCheck(LargeInt Wert, IntType Typ)
|
|
BEGIN
|
|
#ifndef HAS64
|
|
if (((int)Typ)>=((int)SInt32)) return True;
|
|
#else
|
|
if (((int)Typ)>=((int)Int64)) return True;
|
|
#endif
|
|
else return ((Wert>=IntMins[(int)Typ]) AND (Wert<=IntMaxs[(int)Typ]));
|
|
END
|
|
|
|
Boolean FloatRangeCheck(Double Wert, FloatType Typ)
|
|
BEGIN
|
|
switch (Typ)
|
|
BEGIN
|
|
case Float32 : return (fabs(Wert)<=3.4e38);
|
|
case Float64 : return (fabs(Wert)<=1.7e308);
|
|
/** case FloatCo : FloatRangeCheck:=Abs(Wert)<=9.22e18;
|
|
case Float80 : FloatRangeCheck:=True;
|
|
case FloatDec : FloatRangeCheck:=True;**/
|
|
default: return False;
|
|
END
|
|
/** IF (Typ=FloatDec) AND (Abs(Wert)>1e1000) THEN WrError(40);**/
|
|
END
|
|
|
|
|
|
Boolean SingleBit(LargeInt Inp, LargeInt *Erg)
|
|
BEGIN
|
|
*Erg=0;
|
|
do
|
|
BEGIN
|
|
if (NOT Odd(Inp)) (*Erg)++;
|
|
if (NOT Odd(Inp)) Inp=Inp>>1;
|
|
END
|
|
while ((*Erg!=LARGEBITS) AND (NOT Odd(Inp)));
|
|
return (*Erg!=LARGEBITS) AND (Inp==1);
|
|
END
|
|
|
|
|
|
static Boolean ProcessBk(char **Start, char *Erg)
|
|
BEGIN
|
|
LongInt System=0,Acc=0,Digit=0;
|
|
char ch;
|
|
int cnt;
|
|
Boolean Finish;
|
|
|
|
switch (toupper(**Start))
|
|
BEGIN
|
|
case '\'': case '\\': case '"':
|
|
*Erg=**Start; (*Start)++; return True;
|
|
case 'H':
|
|
*Erg='\''; (*Start)++; return True;
|
|
case 'I':
|
|
*Erg='"'; (*Start)++; return True;
|
|
case 'B':
|
|
*Erg=Char_BS; (*Start)++; return True;
|
|
case 'A':
|
|
*Erg=Char_BEL; (*Start)++; return True;
|
|
case 'E':
|
|
*Erg=Char_ESC; (*Start)++; return True;
|
|
case 'T':
|
|
*Erg=Char_HT; (*Start)++; return True;
|
|
case 'N':
|
|
*Erg=Char_LF; (*Start)++; return True;
|
|
case 'R':
|
|
*Erg=Char_CR; (*Start)++; return True;
|
|
case 'X':
|
|
System=16; (*Start)++;
|
|
case '0': case '1': case '2': case '3': case '4':
|
|
case '5': case '6': case '7': case '8': case '9':
|
|
if (System==0) System=(**Start=='0')?8:10;
|
|
cnt=(System==16) ? 1 : ((System==10) ? 0 : -1);
|
|
do
|
|
BEGIN
|
|
ch=toupper(**Start); Finish=False;
|
|
if ((ch>='0') AND (ch<='9')) Digit=ch-'0';
|
|
else if ((System==16) AND (ch>='A') AND (ch<='F')) Digit=(ch-'A')+10;
|
|
else Finish=True;
|
|
if (NOT Finish)
|
|
BEGIN
|
|
(*Start)++; cnt++;
|
|
if (Digit>=System)
|
|
BEGIN
|
|
WrError(1320); return False;
|
|
END
|
|
Acc=(Acc*System)+Digit;
|
|
END
|
|
END
|
|
while ((NOT Finish) AND (cnt<3));
|
|
if (NOT ChkRange(Acc,0,255)) return False;
|
|
*Erg=Acc; return True;
|
|
default:
|
|
WrError(1135); return False;
|
|
END
|
|
END
|
|
|
|
static void ReplaceBkSlashes(char *s)
|
|
BEGIN
|
|
char *p,*n;
|
|
char ErgChar;
|
|
|
|
p=strchr(s,'\\');
|
|
while (p!=Nil)
|
|
BEGIN
|
|
n=p+1; if (ProcessBk(&n,&ErgChar)) *p=ErgChar;
|
|
strcpy(p+1,n);
|
|
p=strchr(p+1,'\\');
|
|
END
|
|
END
|
|
|
|
|
|
Boolean ExpandSymbol(char *Name)
|
|
BEGIN
|
|
char *p1,*p2;
|
|
String h;
|
|
Boolean OK;
|
|
|
|
do
|
|
BEGIN
|
|
if ((p1=strchr(Name,'{'))==Nil) return True;
|
|
strmaxcpy(h,p1+1,255);
|
|
if ((p2=QuotPos(h,'}'))==Nil)
|
|
BEGIN
|
|
WrXError(1020,Name);
|
|
return False;
|
|
END
|
|
strcpy(p1,p2+1); *p2='\0';
|
|
FirstPassUnknown=False;
|
|
EvalStringExpression(h,&OK,h);
|
|
if (FirstPassUnknown)
|
|
BEGIN
|
|
WrError(1820); return False;
|
|
END
|
|
if (NOT CaseSensitive) UpString(h);
|
|
strmaxins(Name,h,p1-Name,255);
|
|
END
|
|
while (p1!=Nil);
|
|
return True;
|
|
END
|
|
|
|
Boolean IdentifySection(char *Name, LongInt *Erg)
|
|
BEGIN
|
|
PSaveSection SLauf;
|
|
sint Depth;
|
|
|
|
if (NOT ExpandSymbol(Name)) return False;
|
|
if (NOT CaseSensitive) NLS_UpString(Name);
|
|
|
|
if (*Name=='\0')
|
|
BEGIN
|
|
*Erg=(-1); return True;
|
|
END
|
|
else if (((strlen(Name)==6) OR (strlen(Name)==7))
|
|
AND (strncasecmp(Name,"PARENT",6)==0)
|
|
AND ((strlen(Name)==6) OR ((Name[6]>='0') AND (Name[6]<='9'))))
|
|
BEGIN
|
|
if (strlen(Name)==6) Depth=1; else Depth=Name[6]-AscOfs;
|
|
SLauf=SectionStack; *Erg=MomSectionHandle;
|
|
while ((Depth>0) AND (*Erg!=(-2)))
|
|
BEGIN
|
|
if (SLauf==Nil) *Erg=(-2);
|
|
else
|
|
BEGIN
|
|
*Erg=SLauf->Handle;
|
|
SLauf=SLauf->Next;
|
|
END
|
|
Depth--;
|
|
END
|
|
if (*Erg==(-2))
|
|
BEGIN
|
|
WrError(1484); return False;
|
|
END
|
|
else return True;
|
|
END
|
|
else if (strcmp(Name,GetSectionName(MomSectionHandle))==0)
|
|
BEGIN
|
|
*Erg=MomSectionHandle; return True;
|
|
END
|
|
else
|
|
BEGIN
|
|
SLauf=SectionStack;
|
|
while ((SLauf!=Nil) AND (strcmp(GetSectionName(SLauf->Handle),Name)!=0))
|
|
SLauf=SLauf->Next;
|
|
if (SLauf==Nil)
|
|
BEGIN
|
|
WrError(1484); return False;
|
|
END
|
|
else
|
|
BEGIN
|
|
*Erg=SLauf->Handle; return True;
|
|
END
|
|
END
|
|
END
|
|
|
|
static Boolean GetSymSection(char *Name, LongInt *Erg)
|
|
BEGIN
|
|
String Part;
|
|
char *q;
|
|
int l=strlen(Name);
|
|
|
|
if (Name[l-1]!=']')
|
|
BEGIN
|
|
*Erg=(-2); return True;
|
|
END
|
|
|
|
Name[l-1]='\0';
|
|
q=RQuotPos(Name,'[');
|
|
Name[l-1]=']';
|
|
if (Name+strlen(Name)-q<=2)
|
|
BEGIN
|
|
WrXError(1020,Name); return False;
|
|
END
|
|
|
|
Name[strlen(Name)-1]='\0';
|
|
strmaxcpy(Part,q+1,255);
|
|
*q='\0';
|
|
|
|
return IdentifySection(Part,Erg);
|
|
END
|
|
|
|
int DigitVal(char ch, int Base)
|
|
BEGIN
|
|
static char *DigitVals="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
char *pos=strchr(DigitVals,ch);
|
|
int erg;
|
|
|
|
if (pos==Nil) return -1;
|
|
else if ((erg=pos-DigitVals)>=Base) return -1;
|
|
return erg;
|
|
END
|
|
|
|
LargeInt ConstIntVal(char *Asc_O, IntType Typ, Boolean *Ok)
|
|
BEGIN
|
|
String Asc;
|
|
int Search;
|
|
Byte Base,Digit;
|
|
LargeInt Wert;
|
|
Boolean NegFlag;
|
|
TConstMode ActMode=ConstModeC;
|
|
Boolean Found;
|
|
char *z,ch;
|
|
int l;
|
|
|
|
*Ok=False; Wert=0; strmaxcpy(Asc,Asc_O,255);
|
|
if (Asc[0]=='\0')
|
|
BEGIN
|
|
*Ok=True; return 0;
|
|
END
|
|
|
|
/* ASCII herausfiltern */
|
|
|
|
else if (*Asc=='\'')
|
|
BEGIN
|
|
if (Asc[strlen(Asc)-1]!='\'') return -1;
|
|
strcpy(Asc,Asc+1); Asc[strlen(Asc)-1]='\0'; ReplaceBkSlashes(Asc);
|
|
for (Search=0; Search<strlen(Asc); Search++)
|
|
BEGIN
|
|
Digit=(usint) Asc[Search];
|
|
Wert=(Wert<<8)+CharTransTable[Digit&0xff];
|
|
END
|
|
NegFlag=False;
|
|
END
|
|
|
|
/* Zahlenkonstante */
|
|
|
|
else
|
|
BEGIN
|
|
/* Vorzeichen */
|
|
|
|
if (*Asc=='+') strcpy(Asc,Asc+1);
|
|
NegFlag=(*Asc=='-');
|
|
if (NegFlag) strcpy(Asc,Asc+1);
|
|
|
|
/* automatische Syntaxermittlung */
|
|
|
|
if (RelaxedMode)
|
|
BEGIN
|
|
Found=False;
|
|
if ((strlen(Asc)>=2) AND (*Asc=='0') AND (toupper(Asc[1])=='X'))
|
|
BEGIN
|
|
ActMode=ConstModeC; Found=True;
|
|
END
|
|
if ((NOT Found) AND (strlen(Asc)>=2))
|
|
BEGIN
|
|
for (Search=0; Search<3; Search++)
|
|
if (Asc[0]==BaseIds[Search])
|
|
BEGIN
|
|
ActMode=ConstModeMoto; Found=True; break;
|
|
END
|
|
END
|
|
if ((NOT Found) AND (strlen(Asc)>=2) AND (*Asc>='0') AND (*Asc<='9'))
|
|
BEGIN
|
|
ch=toupper(Asc[strlen(Asc)-1]);
|
|
if (DigitVal(ch,RadixBase)==-1)
|
|
for (Search=0; Search<3; Search++)
|
|
if (ch==BaseLetters[Search])
|
|
BEGIN
|
|
ActMode=ConstModeIntel; Found=True; break;
|
|
END
|
|
END
|
|
if (NOT Found) ActMode=ConstModeC;
|
|
END
|
|
else ActMode=ConstMode;
|
|
|
|
/* Zahlensystem ermitteln/pruefen */
|
|
|
|
Base=RadixBase;
|
|
switch (ActMode)
|
|
BEGIN
|
|
case ConstModeIntel:
|
|
l=strlen(Asc); ch=toupper(Asc[l-1]);
|
|
if (DigitVal(ch,RadixBase)==-1)
|
|
for (Search=0; Search<3; Search++)
|
|
if (ch==BaseLetters[Search])
|
|
BEGIN
|
|
Base=BaseVals[Search]; Asc[l-1]='\0'; break;
|
|
END
|
|
break;
|
|
case ConstModeMoto:
|
|
for (Search=0; Search<3; Search++)
|
|
if (Asc[0]==BaseIds[Search])
|
|
BEGIN
|
|
Base=BaseVals[Search]; strcpy(Asc,Asc+1); break;
|
|
END
|
|
break;
|
|
case ConstModeC:
|
|
if (strcmp(Asc,"0")==0)
|
|
BEGIN
|
|
*Ok=True; return 0;
|
|
END
|
|
else if (*Asc!='0') Base=RadixBase;
|
|
else if (strlen(Asc)<2) return -1;
|
|
else
|
|
BEGIN
|
|
strcpy(Asc,Asc+1);
|
|
ch=toupper(*Asc);
|
|
if ((RadixBase!=10) && (DigitVal(ch,RadixBase)!=-1)) Base=RadixBase;
|
|
else switch (toupper(*Asc))
|
|
BEGIN
|
|
case 'X': strcpy(Asc,Asc+1); Base=16; break;
|
|
case 'B': strcpy(Asc,Asc+1); Base=2; break;
|
|
default: Base=8; break;
|
|
END
|
|
if (Asc[0]=='\0') return -1;
|
|
END
|
|
END
|
|
|
|
if (Asc[0]=='\0') return -1;
|
|
|
|
if (ActMode==ConstModeIntel)
|
|
if ((Asc[0]<'0') OR (Asc[0]>'9')) return -1;
|
|
|
|
for (z=Asc; *z!='\0'; z++)
|
|
BEGIN
|
|
Search=DigitVal(toupper(*z),Base); if (Search==-1) return -1;
|
|
Wert=Wert*Base+Search;
|
|
END
|
|
END
|
|
|
|
if (NegFlag) Wert=(-Wert);
|
|
|
|
*Ok=RangeCheck(Wert,Typ);
|
|
if (Ok) return Wert;
|
|
else if (HardRanges)
|
|
BEGIN
|
|
WrError(1320);
|
|
return -1;
|
|
END
|
|
else
|
|
BEGIN
|
|
*Ok=True; WrError(260); return Wert&IntMasks[(int)Typ];
|
|
END
|
|
END
|
|
|
|
Double ConstFloatVal(char *Asc_O, FloatType Typ, Boolean *Ok)
|
|
BEGIN
|
|
Double Erg;
|
|
char *end;
|
|
|
|
if (*Asc_O)
|
|
BEGIN
|
|
Erg=strtod(Asc_O,&end);
|
|
*Ok=(*end=='\0');
|
|
END
|
|
else
|
|
BEGIN
|
|
Erg=0.0;
|
|
*Ok=True;
|
|
END
|
|
return Erg;
|
|
END
|
|
|
|
void ConstStringVal(char *Asc_O, char *Erg, Boolean *OK)
|
|
BEGIN
|
|
String Asc,tmp,Part;
|
|
char *z,Save;
|
|
int l;
|
|
Boolean OK2;
|
|
TempResult t;
|
|
|
|
*OK=False;
|
|
|
|
if ((strlen(Asc_O)<2) OR (*Asc_O!='"') OR (Asc_O[strlen(Asc_O)-1]!='"')) return;
|
|
|
|
strmaxcpy(Asc,Asc_O+1,255); Asc[strlen(Asc)-1]='\0'; *tmp='\0';
|
|
|
|
while (*Asc!='\0')
|
|
BEGIN
|
|
z=strchr(Asc,'\\'); if (z==Nil) z=Asc+strlen(Asc);
|
|
Save=(*z); *z='\0'; if (strchr(Asc,'"')!=Nil) return;
|
|
strmaxcat(tmp,Asc,255); *z=Save; strcpy(Asc,z);
|
|
if (*Asc=='\\')
|
|
BEGIN
|
|
if (Asc[1]=='{')
|
|
BEGIN
|
|
z=QuotPos(Asc,'}'); if (z==Nil) return;
|
|
FirstPassUnknown=False;
|
|
*(z++)='\0'; strmaxcpy(Part,Asc+2,255); KillBlanks(Part);
|
|
EvalExpression(Part,&t);
|
|
if (FirstPassUnknown)
|
|
BEGIN
|
|
WrXError(1820,Part); return;
|
|
END
|
|
else if (t.Relocs != Nil)
|
|
BEGIN
|
|
WrError(1150); FreeRelocs(&t.Relocs); return;
|
|
END
|
|
else switch(t.Typ)
|
|
BEGIN
|
|
case TempInt: strmaxcat(tmp,SysString(t.Contents.Int,OutRadixBase,0),255); break;
|
|
case TempFloat: strmaxcat(tmp,FloatString(t.Contents.Float),255); break;
|
|
case TempString: strmaxcat(tmp,t.Contents.Ascii,255); break;
|
|
default: return;
|
|
END
|
|
END
|
|
else
|
|
BEGIN
|
|
z=Asc+1; OK2=ProcessBk(&z,&Save);
|
|
if (NOT OK2) return;
|
|
l=strlen(tmp); tmp[l++]=Save; tmp[l++]='\0';
|
|
END
|
|
strcpy(Asc,z);
|
|
END
|
|
END
|
|
|
|
*OK=True; strmaxcpy(Erg,tmp,255);
|
|
END
|
|
|
|
|
|
static SymbolPtr FindLocNode(
|
|
#ifdef __PROTOS__
|
|
char *Name, TempType SearchType
|
|
#endif
|
|
);
|
|
|
|
static SymbolPtr FindNode(
|
|
#ifdef __PROTOS__
|
|
char *Name, TempType SearchType
|
|
#endif
|
|
);
|
|
|
|
|
|
static void EvalExpression_ChgFloat(TempResult *T)
|
|
BEGIN
|
|
if (T->Typ!=TempInt) return;
|
|
T->Typ=TempFloat; T->Contents.Float=T->Contents.Int;
|
|
END
|
|
|
|
#define LEAVE goto func_exit
|
|
|
|
void EvalExpression(char *Asc_O, TempResult *Erg)
|
|
BEGIN
|
|
#define OpCnt 24
|
|
static Operator Operators[OpCnt+1]=
|
|
/* Dummynulloperator */
|
|
{{" " ,1 , False, 0, False, False, False, False},
|
|
/* Einerkomplement */
|
|
{"~" ,1 , False, 1, True , False, False, False},
|
|
/* Linksschieben */
|
|
{"<<",2 , True , 3, True , False, False, False},
|
|
/* Rechtsschieben */
|
|
{">>",2 , True , 3, True , False, False, False},
|
|
/* Bitspiegelung */
|
|
{"><",2 , True , 4, True , False, False, False},
|
|
/* binaeres AND */
|
|
{"&" ,1 , True , 5, True , False, False, False},
|
|
/* binaeres OR */
|
|
{"|" ,1 , True , 6, True , False, False, False},
|
|
/* binaeres EXOR */
|
|
{"!" ,1 , True , 7, True , False, False, False},
|
|
/* allg. Potenz */
|
|
{"^" ,1 , True , 8, True , True , False, False},
|
|
/* Produkt */
|
|
{"*" ,1 , True , 11, True , True , False, False},
|
|
/* Quotient */
|
|
{"/" ,1 , True , 11, True , True , False, False},
|
|
/* Modulodivision */
|
|
{"#" ,1 , True , 11, True , False, False, False},
|
|
/* Summe */
|
|
{"+" ,1 , True , 13, True , True , True , False},
|
|
/* Differenz */
|
|
{"-" ,1 , True , 13, True , True , False, False},
|
|
/* logisches NOT */
|
|
{"~~",2 , False, 2, True , False, False, False},
|
|
/* logisches AND */
|
|
{"&&",2 , True , 15, True , False, False, False},
|
|
/* logisches OR */
|
|
{"||",2 , True , 16, True , False, False, False},
|
|
/* logisches EXOR */
|
|
{"!!",2 , True , 17, True , False, False, False},
|
|
/* Gleichheit */
|
|
{"=" ,1 , True , 23, True , True , True , False},
|
|
{"==",2 , True , 23, True , True , True , False},
|
|
/* Groesser als */
|
|
{">" ,1 , True , 23, True , True , True , False},
|
|
/* Kleiner als */
|
|
{"<" ,1 , True , 23, True , True , True , False},
|
|
/* Kleiner oder gleich */
|
|
{"<=",2 , True , 23, True , True , True , False},
|
|
/* Groesser oder gleich */
|
|
{">=",2 , True , 23, True , True , True , False},
|
|
/* Ungleichheit */
|
|
{"<>",2 , True , 23, True , True , True , False}};
|
|
static Operator *OpEnd=Operators+OpCnt;
|
|
Operator *FOps[OpCnt+1];
|
|
LongInt FOpCnt=0;
|
|
|
|
Boolean OK,FFound;
|
|
TempResult LVal,RVal,MVal;
|
|
int z1,cnt;
|
|
Operator *Op;
|
|
char Save='\0';
|
|
sint LKlamm,RKlamm,WKlamm,zop;
|
|
sint OpMax,LocOpMax,OpPos=(-1),OpLen;
|
|
Boolean OpFnd,InHyp,InQuot;
|
|
LargeInt HVal;
|
|
Double FVal;
|
|
SymbolPtr Ptr;
|
|
PFunction ValFunc;
|
|
String Asc,stemp,ftemp;
|
|
char *KlPos,*zp,*DummyPtr;
|
|
PRelocEntry TReloc;
|
|
|
|
memset(&LVal, 0, sizeof(LVal));
|
|
memset(&RVal, 0, sizeof(RVal));
|
|
|
|
ChkStack();
|
|
|
|
strmaxcpy(Asc, Asc_O, 255);
|
|
strmaxcpy(stemp, Asc, 255); KillBlanks(Asc);
|
|
if (MakeDebug) fprintf(Debug, "Parse %s", Asc);
|
|
|
|
/* Annahme Fehler */
|
|
|
|
Erg->Typ = TempNone;
|
|
Erg->Relocs = Nil;
|
|
|
|
/* Programmzaehler ? */
|
|
|
|
if ((PCSymbol != NULL) AND (strcasecmp(Asc,PCSymbol) == 0))
|
|
BEGIN
|
|
Erg->Typ = TempInt;
|
|
Erg->Contents.Int = EProgCounter();
|
|
Erg->Relocs = Nil;
|
|
LEAVE;
|
|
END
|
|
|
|
/* Konstanten ? */
|
|
|
|
Erg->Contents.Int = ConstIntVal(Asc, (IntType) (IntTypeCnt-1), &OK);
|
|
if (OK)
|
|
BEGIN
|
|
Erg->Typ = TempInt;
|
|
Erg->Relocs = Nil;
|
|
LEAVE;
|
|
END
|
|
|
|
Erg->Contents.Float = ConstFloatVal(Asc, Float80, &OK);
|
|
if (OK)
|
|
BEGIN
|
|
Erg->Typ = TempFloat;
|
|
Erg->Relocs = Nil;
|
|
LEAVE;
|
|
END
|
|
|
|
ConstStringVal(Asc,Erg->Contents.Ascii,&OK);
|
|
if (OK)
|
|
BEGIN
|
|
Erg->Typ = TempString;
|
|
Erg->Relocs = Nil;
|
|
LEAVE;
|
|
END
|
|
|
|
/* durch Codegenerator gegebene Konstanten ? */
|
|
|
|
Erg->Relocs = Nil;
|
|
InternSymbol(Asc, Erg);
|
|
if (Erg->Typ != TempNone) LEAVE;
|
|
|
|
/* Zaehler initialisieren */
|
|
|
|
LocOpMax = 0; OpMax = 0; LKlamm = 0; RKlamm = 0; WKlamm = 0;
|
|
InHyp = False; InQuot = False;
|
|
for (Op=Operators+1; Op<=OpEnd; Op++)
|
|
if (((Op->IdLen==1)?(strchr(Asc,*Op->Id)):(strstr(Asc,Op->Id)))!=Nil) FOps[FOpCnt++]=Op;
|
|
/* if (strstr(Asc,Op->Id)!=Nil) FOps[FOpCnt++]=Op;*/
|
|
|
|
/* nach Operator hoechster Rangstufe ausserhalb Klammern suchen */
|
|
|
|
for (zp=Asc; *zp!='\0'; zp++)
|
|
BEGIN
|
|
switch (*zp)
|
|
BEGIN
|
|
case '(': if (NOT (InHyp OR InQuot)) LKlamm++; break;
|
|
case ')': if (NOT (InHyp OR InQuot)) RKlamm++; break;
|
|
case '{': if (NOT (InHyp OR InQuot)) WKlamm++; break;
|
|
case '}': if (NOT (InHyp OR InQuot)) WKlamm--; break;
|
|
case '"': if (NOT InHyp) InQuot=NOT InQuot; break;
|
|
case '\'':if (NOT InQuot) InHyp=NOT InHyp; break;
|
|
default:
|
|
if ((LKlamm==RKlamm) AND (WKlamm==0) AND (NOT InHyp) AND (NOT InQuot))
|
|
BEGIN
|
|
OpFnd=False; OpLen=0; LocOpMax=0;
|
|
for (zop=0; zop<FOpCnt; zop++)
|
|
if (strncmp(zp,FOps[zop]->Id,FOps[zop]->IdLen)==0)
|
|
if (FOps[zop]->IdLen>=OpLen)
|
|
BEGIN
|
|
OpFnd=True; OpLen=FOps[zop]->IdLen; LocOpMax=FOps[zop]-Operators;
|
|
if (Operators[LocOpMax].Priority>=Operators[OpMax].Priority)
|
|
BEGIN
|
|
OpMax=LocOpMax; OpPos=zp-Asc;
|
|
END
|
|
END
|
|
if (OpFnd) zp+=strlen(Operators[LocOpMax].Id)-1;
|
|
END
|
|
END
|
|
END
|
|
|
|
/* Klammerfehler ? */
|
|
|
|
if (LKlamm != RKlamm)
|
|
BEGIN
|
|
WrXError(1300, Asc); LEAVE;
|
|
END
|
|
|
|
/* Operator gefunden ? */
|
|
|
|
if (OpMax!=0)
|
|
BEGIN
|
|
Op=Operators + OpMax;
|
|
|
|
/* Minuszeichen sowohl mit einem als auch 2 Operanden */
|
|
|
|
if (strcmp(Op->Id, "-") == 0) Op->Dyadic = (OpPos>0);
|
|
|
|
/* Operandenzahl pruefen */
|
|
|
|
if (((Op->Dyadic) AND (OpPos == 0)) OR ((NOT Op->Dyadic) AND (OpPos != 0)) OR (OpPos == strlen(Asc)-1))
|
|
BEGIN
|
|
WrError(1110); LEAVE;
|
|
END
|
|
|
|
/* Teilausdruecke rekursiv auswerten */
|
|
|
|
Save = Asc[OpPos]; Asc[OpPos] = '\0';
|
|
if (Op->Dyadic) EvalExpression(Asc, &LVal);
|
|
else
|
|
BEGIN
|
|
LVal.Typ = TempInt; LVal.Contents.Int = 0; LVal.Relocs = Nil;
|
|
END
|
|
EvalExpression(Asc + OpPos + strlen(Op->Id), &RVal);
|
|
Asc[OpPos] = Save;
|
|
|
|
/* Abbruch, falls dabei Fehler */
|
|
|
|
if ((LVal.Typ == TempNone) OR (RVal.Typ == TempNone)) LEAVE;
|
|
|
|
/* relokatible Symbole nur fuer + und - erlaubt */
|
|
|
|
if ((OpMax != 12) AND (OpMax != 13) AND ((LVal.Relocs != Nil) OR (RVal.Relocs != Nil)))
|
|
BEGIN
|
|
WrError(1150);
|
|
LEAVE;
|
|
END
|
|
|
|
/* Typueberpruefung */
|
|
|
|
if ((Op->Dyadic) AND (LVal.Typ != RVal.Typ))
|
|
BEGIN
|
|
if ((LVal.Typ == TempString) OR (RVal.Typ == TempString))
|
|
BEGIN
|
|
WrError(1135); LEAVE;
|
|
END
|
|
if (LVal.Typ == TempInt) EvalExpression_ChgFloat(&LVal);
|
|
if (RVal.Typ == TempInt) EvalExpression_ChgFloat(&RVal);
|
|
END
|
|
|
|
switch (RVal.Typ)
|
|
BEGIN
|
|
case TempInt:
|
|
if (NOT Op->MayInt)
|
|
BEGIN
|
|
if (NOT Op->MayFloat)
|
|
BEGIN
|
|
WrError(1135); LEAVE;
|
|
END
|
|
else
|
|
BEGIN
|
|
EvalExpression_ChgFloat(&RVal);
|
|
if (Op->Dyadic) EvalExpression_ChgFloat(&LVal);
|
|
END
|
|
END
|
|
break;
|
|
case TempFloat:
|
|
if (NOT Op->MayFloat)
|
|
BEGIN
|
|
WrError(1135); LEAVE;
|
|
END
|
|
break;
|
|
case TempString:
|
|
if (NOT Op->MayString)
|
|
BEGIN
|
|
WrError(1135); LEAVE;
|
|
END;
|
|
break;
|
|
default:
|
|
break;
|
|
END
|
|
|
|
/* Operanden abarbeiten */
|
|
|
|
switch (OpMax)
|
|
BEGIN
|
|
case 1: /* ~ */
|
|
Erg->Typ = TempInt;
|
|
Erg->Contents.Int = ~RVal.Contents.Int;
|
|
break;
|
|
case 2: /* << */
|
|
Erg->Typ = TempInt;
|
|
Erg->Contents.Int = LVal.Contents.Int << RVal.Contents.Int;
|
|
break;
|
|
case 3: /* >> */
|
|
Erg->Typ = TempInt;
|
|
Erg->Contents.Int = LVal.Contents.Int >> RVal.Contents.Int;
|
|
break;
|
|
case 4: /* >< */
|
|
Erg->Typ = TempInt;
|
|
if ((RVal.Contents.Int < 1) OR (RVal.Contents.Int > 32)) WrError(1320);
|
|
else
|
|
BEGIN
|
|
Erg->Contents.Int = (LVal.Contents.Int >> RVal.Contents.Int) << RVal.Contents.Int;
|
|
RVal.Contents.Int--;
|
|
for (z1 = 0; z1 <= RVal.Contents.Int; z1++)
|
|
BEGIN
|
|
if ((LVal.Contents.Int & (1 << (RVal.Contents.Int - z1))) != 0)
|
|
Erg->Contents.Int += (1 << z1);
|
|
END
|
|
END
|
|
break;
|
|
case 5: /* & */
|
|
Erg->Typ = TempInt;
|
|
Erg->Contents.Int = LVal.Contents.Int & RVal.Contents.Int;
|
|
break;
|
|
case 6: /* | */
|
|
Erg->Typ = TempInt;
|
|
Erg->Contents.Int = LVal.Contents.Int | RVal.Contents.Int;
|
|
break;
|
|
case 7: /* ! */
|
|
Erg->Typ = TempInt;
|
|
Erg->Contents.Int = LVal.Contents.Int ^ RVal.Contents.Int;
|
|
break;
|
|
case 8: /* ^ */
|
|
switch (Erg->Typ = LVal.Typ)
|
|
BEGIN
|
|
case TempInt:
|
|
if (RVal.Contents.Int < 0) Erg->Contents.Int = 0;
|
|
else
|
|
BEGIN
|
|
Erg->Contents.Int = 1;
|
|
while (RVal.Contents.Int > 0)
|
|
BEGIN
|
|
if ((RVal.Contents.Int&1) == 1) Erg->Contents.Int *= LVal.Contents.Int;
|
|
RVal.Contents.Int >>= 1;
|
|
if (RVal.Contents.Int != 0) LVal.Contents.Int *= LVal.Contents.Int;
|
|
END
|
|
END
|
|
break;
|
|
case TempFloat:
|
|
if (RVal.Contents.Float == 0.0) Erg->Contents.Float = 1.0;
|
|
else if (LVal.Contents.Float == 0.0) Erg->Contents.Float = 0.0;
|
|
else if (LVal.Contents.Float > 0) Erg->Contents.Float = pow(LVal.Contents.Float, RVal.Contents.Float);
|
|
else if ((abs(RVal.Contents.Float) <= ((double)MaxLongInt)) AND (floor(RVal.Contents.Float) == RVal.Contents.Float))
|
|
BEGIN
|
|
HVal = (LongInt) floor(RVal.Contents.Float+0.5);
|
|
if (HVal < 0)
|
|
BEGIN
|
|
LVal.Contents.Float = 1 / LVal.Contents.Float; HVal = (-HVal);
|
|
END
|
|
Erg->Contents.Float = 1.0;
|
|
while (HVal > 0)
|
|
BEGIN
|
|
if ((HVal & 1) == 1) Erg->Contents.Float *= LVal.Contents.Float;
|
|
LVal.Contents.Float *= LVal.Contents.Float; HVal >>= 1;
|
|
END
|
|
END
|
|
else
|
|
BEGIN
|
|
WrError(1890); Erg->Typ = TempNone;
|
|
END
|
|
break;
|
|
default:
|
|
break;
|
|
END
|
|
break;
|
|
case 9: /* * */
|
|
switch (Erg->Typ = LVal.Typ)
|
|
BEGIN
|
|
case TempInt:
|
|
Erg->Contents.Int = LVal.Contents.Int * RVal.Contents.Int; break;
|
|
case TempFloat:
|
|
Erg->Contents.Float = LVal.Contents.Float * RVal.Contents.Float; break;
|
|
default:
|
|
break;
|
|
END
|
|
break;
|
|
case 10: /* / */
|
|
switch (LVal.Typ)
|
|
BEGIN
|
|
case TempInt:
|
|
if (RVal.Contents.Int == 0) WrError(1310);
|
|
else
|
|
BEGIN
|
|
Erg->Typ = TempInt;
|
|
Erg->Contents.Int = LVal.Contents.Int / RVal.Contents.Int;
|
|
END
|
|
break;
|
|
case TempFloat:
|
|
if (RVal.Contents.Float == 0.0) WrError(1310);
|
|
else
|
|
BEGIN
|
|
Erg->Typ = TempFloat;
|
|
Erg->Contents.Float = LVal.Contents.Float / RVal.Contents.Float;
|
|
END
|
|
default:
|
|
break;
|
|
END
|
|
break;
|
|
case 11: /* # */
|
|
if (RVal.Contents.Int == 0) WrError(1310);
|
|
else
|
|
BEGIN
|
|
Erg->Typ = TempInt;
|
|
Erg->Contents.Int = LVal.Contents.Int % RVal.Contents.Int;
|
|
END
|
|
break;
|
|
case 12: /* + */
|
|
switch (Erg->Typ = LVal.Typ)
|
|
BEGIN
|
|
case TempInt :
|
|
Erg->Contents.Int = LVal.Contents.Int + RVal.Contents.Int;
|
|
Erg->Relocs = MergeRelocs(&(LVal.Relocs), &(RVal.Relocs), TRUE);
|
|
break;
|
|
case TempFloat :
|
|
Erg->Contents.Float = LVal.Contents.Float + RVal.Contents.Float;
|
|
break;
|
|
case TempString:
|
|
strmaxcpy(Erg->Contents.Ascii, LVal.Contents.Ascii, 255);
|
|
strmaxcat(Erg->Contents.Ascii, RVal.Contents.Ascii, 255);
|
|
break;
|
|
default:
|
|
break;
|
|
END
|
|
break;
|
|
case 13: /* - */
|
|
if (Op->Dyadic)
|
|
switch (Erg->Typ = LVal.Typ)
|
|
BEGIN
|
|
case TempInt:
|
|
Erg->Contents.Int = LVal.Contents.Int-RVal.Contents.Int;
|
|
Erg->Relocs = MergeRelocs(&(LVal.Relocs), &(RVal.Relocs), FALSE);
|
|
break;
|
|
case TempFloat:
|
|
Erg->Contents.Float = LVal.Contents.Float - RVal.Contents.Float;
|
|
break;
|
|
default:
|
|
break;
|
|
END
|
|
else
|
|
switch (Erg->Typ = RVal.Typ)
|
|
BEGIN
|
|
case TempInt:
|
|
Erg->Contents.Int = (-RVal.Contents.Int);
|
|
InvertRelocs(&(Erg->Relocs), &(RVal.Relocs));
|
|
break;
|
|
case TempFloat:
|
|
Erg->Contents.Float = (-RVal.Contents.Float);
|
|
break;
|
|
default:
|
|
break;
|
|
END
|
|
break;
|
|
case 14: /* ~~ */
|
|
Erg->Typ = TempInt;
|
|
Erg->Contents.Int = (RVal.Contents.Int == 0) ? 1 : 0;
|
|
break;
|
|
case 15: /* && */
|
|
Erg->Typ = TempInt;
|
|
Erg->Contents.Int = ((LVal.Contents.Int != 0) AND (RVal.Contents.Int != 0)) ? 1 : 0;
|
|
break;
|
|
case 16: /* || */
|
|
Erg->Typ = TempInt;
|
|
Erg->Contents.Int = ((LVal.Contents.Int != 0) OR (RVal.Contents.Int != 0)) ? 1 : 0;
|
|
break;
|
|
case 17: /* !! */
|
|
Erg->Typ = TempInt;
|
|
if ((LVal.Contents.Int != 0) AND (RVal.Contents.Int == 0))
|
|
Erg->Contents.Int = 1;
|
|
else if ((LVal.Contents.Int == 0) AND (RVal.Contents.Int != 0))
|
|
Erg->Contents.Int = 1;
|
|
else Erg->Contents.Int = 0;
|
|
break;
|
|
case 18: /* = */
|
|
case 19: /* == */
|
|
Erg->Typ = TempInt;
|
|
switch (LVal.Typ)
|
|
BEGIN
|
|
case TempInt:
|
|
Erg->Contents.Int = (LVal.Contents.Int == RVal.Contents.Int) ? 1 : 0;
|
|
break;
|
|
case TempFloat:
|
|
Erg->Contents.Int = (LVal.Contents.Float == RVal.Contents.Float) ? 1 : 0;
|
|
break;
|
|
case TempString:
|
|
Erg->Contents.Int = (strcmp(LVal.Contents.Ascii, RVal.Contents.Ascii) == 0) ? 1 : 0;
|
|
break;
|
|
default:
|
|
break;
|
|
END
|
|
break;
|
|
case 20: /* > */
|
|
Erg->Typ = TempInt;
|
|
switch (LVal.Typ)
|
|
BEGIN
|
|
case TempInt:
|
|
Erg->Contents.Int = (LVal.Contents.Int > RVal.Contents.Int) ? 1 : 0;
|
|
break;
|
|
case TempFloat:
|
|
Erg->Contents.Int = (LVal.Contents.Float > RVal.Contents.Float) ? 1 : 0;
|
|
break;
|
|
case TempString:
|
|
Erg->Contents.Int = (strcmp(LVal.Contents.Ascii, RVal.Contents.Ascii) > 0) ? 1 : 0;
|
|
break;
|
|
default:
|
|
break;
|
|
END
|
|
break;
|
|
case 21: /* < */
|
|
Erg->Typ = TempInt;
|
|
switch (LVal.Typ)
|
|
BEGIN
|
|
case TempInt:
|
|
Erg->Contents.Int = (LVal.Contents.Int < RVal.Contents.Int) ? 1 : 0;
|
|
break;
|
|
case TempFloat:
|
|
Erg->Contents.Int = (LVal.Contents.Float < RVal.Contents.Float) ? 1 : 0;
|
|
break;
|
|
case TempString:
|
|
Erg->Contents.Int = (strcmp(LVal.Contents.Ascii, RVal.Contents.Ascii) < 0) ? 1 : 0;
|
|
break;
|
|
default:
|
|
break;
|
|
END
|
|
break;
|
|
case 22: /* <= */
|
|
Erg->Typ = TempInt;
|
|
switch (LVal.Typ)
|
|
BEGIN
|
|
case TempInt:
|
|
Erg->Contents.Int = (LVal.Contents.Int <= RVal.Contents.Int) ? 1 : 0;
|
|
break;
|
|
case TempFloat:
|
|
Erg->Contents.Int = (LVal.Contents.Float <= RVal.Contents.Float) ? 1 : 0;
|
|
break;
|
|
case TempString:
|
|
Erg->Contents.Int = (strcmp(LVal.Contents.Ascii, RVal.Contents.Ascii) <= 0) ? 1 : 0; break;
|
|
default:
|
|
break;
|
|
END
|
|
break;
|
|
case 23: /* >= */
|
|
Erg->Typ=TempInt;
|
|
switch (LVal.Typ)
|
|
BEGIN
|
|
case TempInt:
|
|
Erg->Contents.Int=(LVal.Contents.Int>=RVal.Contents.Int)?1:0; break;
|
|
case TempFloat:
|
|
Erg->Contents.Int=(LVal.Contents.Float>=RVal.Contents.Float)?1:0; break;
|
|
case TempString:
|
|
Erg->Contents.Int=(strcmp(LVal.Contents.Ascii,RVal.Contents.Ascii)>=0)?1:0; break;
|
|
default:
|
|
break;
|
|
END
|
|
break;
|
|
case 24: /* <> */
|
|
Erg->Typ=TempInt;
|
|
switch (LVal.Typ)
|
|
BEGIN
|
|
case TempInt:
|
|
Erg->Contents.Int=(LVal.Contents.Int!=RVal.Contents.Int)?1:0; break;
|
|
case TempFloat:
|
|
Erg->Contents.Int=(LVal.Contents.Float!=RVal.Contents.Float)?1:0; break;
|
|
case TempString:
|
|
Erg->Contents.Int=(strcmp(LVal.Contents.Ascii,RVal.Contents.Ascii)!=0)?1:0; break;
|
|
default:
|
|
break;
|
|
END
|
|
break;
|
|
END
|
|
LEAVE;
|
|
END
|
|
|
|
/* kein Operator gefunden: Klammerausdruck ? */
|
|
|
|
if (LKlamm!=0)
|
|
BEGIN
|
|
|
|
/* erste Klammer suchen, Funktionsnamen abtrennen */
|
|
|
|
KlPos=strchr(Asc,'(');
|
|
|
|
/* Funktionsnamen abschneiden */
|
|
|
|
*KlPos='\0'; strmaxcpy(ftemp,Asc,255);
|
|
strcpy(Asc,KlPos+1); Asc[strlen(Asc)-1]='\0';
|
|
|
|
/* Nullfunktion: nur Argument */
|
|
|
|
if (ftemp[0]=='\0')
|
|
BEGIN
|
|
EvalExpression(Asc,&LVal);
|
|
*Erg=LVal; LEAVE;
|
|
END
|
|
|
|
/* selbstdefinierte Funktion ? */
|
|
|
|
if ((ValFunc=FindFunction(ftemp))!=Nil)
|
|
BEGIN
|
|
strmaxcpy(ftemp,ValFunc->Definition,255);
|
|
for (z1=1; z1<=ValFunc->ArguCnt; z1++)
|
|
BEGIN
|
|
if (Asc[0]=='\0')
|
|
BEGIN
|
|
WrError(1490); LEAVE;
|
|
END;
|
|
KlPos=QuotPos(Asc,','); if (KlPos!=Nil) *KlPos='\0';
|
|
EvalExpression(Asc,&LVal);
|
|
if (LVal.Relocs != Nil)
|
|
BEGIN
|
|
WrError(1150); FreeRelocs(&LVal.Relocs); return;
|
|
END
|
|
if (KlPos==Nil) Asc[0]='\0'; else strcpy(Asc,KlPos+1);
|
|
switch (LVal.Typ)
|
|
BEGIN
|
|
case TempInt:
|
|
sprintf(stemp,"%s",LargeString(LVal.Contents.Int));
|
|
break;
|
|
case TempFloat:
|
|
sprintf(stemp,"%0.16e",LVal.Contents.Float);
|
|
KillBlanks(stemp);
|
|
break;
|
|
case TempString:
|
|
strcpy(stemp,"\"");
|
|
strmaxcat(stemp,LVal.Contents.Ascii,255);
|
|
strmaxcat(stemp,"\"",255);
|
|
break;
|
|
default:
|
|
LEAVE;
|
|
END
|
|
memmove(stemp+1,stemp,strlen(stemp)+1);
|
|
stemp[0]='('; strmaxcat(stemp,")",255);
|
|
ExpandLine(stemp,z1,ftemp);
|
|
END
|
|
if (Asc[0]!='\0')
|
|
BEGIN
|
|
WrError(1490); LEAVE;
|
|
END
|
|
EvalExpression(ftemp,Erg);
|
|
LEAVE;
|
|
END
|
|
|
|
/* hier einmal umwandeln ist effizienter */
|
|
|
|
NLS_UpString(ftemp);
|
|
|
|
/* symbolbezogene Funktionen */
|
|
|
|
if (strcmp(ftemp,"SYMTYPE")==0)
|
|
BEGIN
|
|
Erg->Typ=TempInt;
|
|
if (FindRegDef(Asc,&DummyPtr)) Erg->Contents.Int=0x80;
|
|
else Erg->Contents.Int=GetSymbolType(Asc);
|
|
LEAVE;
|
|
END
|
|
|
|
/* Unterausdruck auswerten (interne Funktionen maxmimal mit drei Argumenten) */
|
|
|
|
z1 = 0; KlPos = Asc;
|
|
do
|
|
BEGIN
|
|
zp = QuotPos(KlPos, ',');
|
|
if (zp != Nil) *zp = '\0';
|
|
switch (z1)
|
|
BEGIN
|
|
case 0:
|
|
EvalExpression(KlPos, &LVal);
|
|
if (LVal.Typ == TempNone) LEAVE;
|
|
TReloc = LVal.Relocs;
|
|
break;
|
|
case 1:
|
|
EvalExpression(KlPos, &MVal);
|
|
if (MVal.Typ == TempNone) LEAVE;
|
|
TReloc = MVal.Relocs;
|
|
break;
|
|
case 2:
|
|
EvalExpression(KlPos, &RVal);
|
|
if (RVal.Typ == TempNone) LEAVE;
|
|
TReloc = RVal.Relocs;
|
|
break;
|
|
default:
|
|
WrError(1490); LEAVE;
|
|
END
|
|
if (TReloc != Nil)
|
|
BEGIN
|
|
WrError(1150); FreeRelocs(&TReloc); LEAVE;
|
|
END
|
|
if (zp != Nil) KlPos = zp + 1;
|
|
z1++;
|
|
END
|
|
while (zp!=Nil);
|
|
|
|
/* ein paar Funktionen mit zwei,drei Argumenten */
|
|
|
|
if (z1==3)
|
|
BEGIN
|
|
if (strcmp(ftemp,"SUBSTR")==0)
|
|
BEGIN
|
|
if ((LVal.Typ!=TempString) OR (MVal.Typ!=TempInt) OR (RVal.Typ!=TempInt)) WrError(1135);
|
|
else
|
|
BEGIN
|
|
cnt=strlen(LVal.Contents.Ascii)-MVal.Contents.Int;
|
|
if ((RVal.Contents.Int!=0) AND (RVal.Contents.Int<cnt)) cnt=RVal.Contents.Int;
|
|
if (cnt<0) cnt=0;
|
|
memcpy(Erg->Contents.Ascii,LVal.Contents.Ascii+MVal.Contents.Int,cnt);
|
|
Erg->Contents.Ascii[cnt]='\0';
|
|
Erg->Typ=TempString;
|
|
END
|
|
END
|
|
else WrXError(1860,ftemp);
|
|
LEAVE;
|
|
END
|
|
else if (z1==2)
|
|
BEGIN
|
|
if (strcmp(ftemp,"STRSTR")==0)
|
|
BEGIN
|
|
if ((LVal.Typ!=TempString) OR (MVal.Typ!=TempString)) WrError(1135);
|
|
else
|
|
BEGIN
|
|
zp=strstr(LVal.Contents.Ascii,MVal.Contents.Ascii);
|
|
Erg->Typ=TempInt;
|
|
Erg->Contents.Int=(zp==Nil) ? -1 : (zp-LVal.Contents.Ascii);
|
|
END
|
|
END
|
|
else WrXError(1860,ftemp);
|
|
LEAVE;
|
|
END
|
|
|
|
/* Funktionen fuer Stringargumente */
|
|
|
|
if (LVal.Typ==TempString)
|
|
BEGIN
|
|
/* in Grossbuchstaben wandeln ? */
|
|
|
|
if (strcmp(ftemp,"UPSTRING")==0)
|
|
BEGIN
|
|
Erg->Typ=TempString; strmaxcpy(Erg->Contents.Ascii,LVal.Contents.Ascii,255);
|
|
for (KlPos=Erg->Contents.Ascii; *KlPos!='\0'; KlPos++)
|
|
*KlPos=toupper(*KlPos);
|
|
END
|
|
|
|
/* in Kleinbuchstaben wandeln ? */
|
|
|
|
else if (strcmp(ftemp,"LOWSTRING")==0)
|
|
BEGIN
|
|
Erg->Typ=TempString; strmaxcpy(Erg->Contents.Ascii,LVal.Contents.Ascii,255);
|
|
for (KlPos=Erg->Contents.Ascii; *KlPos!='\0'; KlPos++)
|
|
*KlPos=tolower(*KlPos);
|
|
END
|
|
|
|
/* Laenge ermitteln ? */
|
|
|
|
else if (strcmp(ftemp,"STRLEN")==0)
|
|
BEGIN
|
|
Erg->Typ=TempInt; Erg->Contents.Int=strlen(LVal.Contents.Ascii);
|
|
END
|
|
|
|
/* Parser aufrufen ? */
|
|
|
|
else if (strcmp(ftemp,"VAL")==0)
|
|
BEGIN
|
|
EvalExpression(LVal.Contents.Ascii,Erg);
|
|
END
|
|
|
|
/* nix gefunden ? */
|
|
|
|
else
|
|
BEGIN
|
|
WrXError(1860,ftemp); Erg->Typ=TempNone;
|
|
END
|
|
END
|
|
|
|
/* Funktionen fuer Zahlenargumente */
|
|
|
|
else
|
|
BEGIN
|
|
FFound=False; Erg->Typ=TempNone;
|
|
|
|
/* reine Integerfunktionen */
|
|
|
|
if (strcmp(ftemp,"TOUPPER")==0)
|
|
BEGIN
|
|
if (LVal.Typ!=TempInt) WrError(1135);
|
|
else if ((LVal.Contents.Int<0) OR (LVal.Contents.Int>255)) WrError(1320);
|
|
else
|
|
BEGIN
|
|
Erg->Typ=TempInt;
|
|
Erg->Contents.Int=toupper(LVal.Contents.Int);
|
|
END
|
|
FFound=True;
|
|
END
|
|
|
|
else if (strcmp(ftemp,"TOLOWER")==0)
|
|
BEGIN
|
|
if (LVal.Typ!=TempInt) WrError(1135);
|
|
else if ((LVal.Contents.Int<0) OR (LVal.Contents.Int>255)) WrError(1320);
|
|
else
|
|
BEGIN
|
|
Erg->Typ=TempInt;
|
|
Erg->Contents.Int=tolower(LVal.Contents.Int);
|
|
END
|
|
FFound=True;
|
|
END
|
|
|
|
else if (strcmp(ftemp,"BITCNT")==0)
|
|
BEGIN
|
|
if (LVal.Typ!=TempInt) WrError(1135);
|
|
else
|
|
BEGIN
|
|
Erg->Typ=TempInt;
|
|
Erg->Contents.Int=0;
|
|
for (z1=0; z1<LARGEBITS; z1++)
|
|
BEGIN
|
|
Erg->Contents.Int+=(LVal.Contents.Int & 1);
|
|
LVal.Contents.Int=LVal.Contents.Int >> 1;
|
|
END
|
|
END
|
|
FFound=True;
|
|
END
|
|
|
|
else if (strcmp(ftemp,"FIRSTBIT")==0)
|
|
BEGIN
|
|
if (LVal.Typ!=TempInt) WrError(1135);
|
|
else
|
|
BEGIN
|
|
Erg->Typ=TempInt;
|
|
Erg->Contents.Int=0;
|
|
do
|
|
BEGIN
|
|
if (NOT Odd(LVal.Contents.Int)) Erg->Contents.Int++;
|
|
LVal.Contents.Int=LVal.Contents.Int >> 1;
|
|
END
|
|
while ((Erg->Contents.Int<LARGEBITS) AND (NOT Odd(LVal.Contents.Int)));
|
|
if (Erg->Contents.Int>=LARGEBITS) Erg->Contents.Int=(-1);
|
|
END
|
|
FFound=True;
|
|
END
|
|
|
|
else if (strcmp(ftemp,"LASTBIT")==0)
|
|
BEGIN
|
|
if (LVal.Typ!=TempInt) WrError(1135);
|
|
else
|
|
BEGIN
|
|
Erg->Typ=TempInt;
|
|
Erg->Contents.Int=(-1);
|
|
for (z1=0; z1<LARGEBITS; z1++)
|
|
BEGIN
|
|
if (Odd(LVal.Contents.Int)) Erg->Contents.Int=z1;
|
|
LVal.Contents.Int=LVal.Contents.Int >> 1;
|
|
END
|
|
END
|
|
FFound=True;
|
|
END
|
|
|
|
else if (strcmp(ftemp,"BITPOS")==0)
|
|
BEGIN
|
|
if (LVal.Typ!=TempInt) WrError(1135);
|
|
else
|
|
BEGIN
|
|
Erg->Typ=TempInt;
|
|
if (NOT SingleBit(LVal.Contents.Int,&Erg->Contents.Int))
|
|
BEGIN
|
|
Erg->Contents.Int=(-1); WrError(1540);
|
|
END
|
|
END
|
|
FFound=True;
|
|
END
|
|
|
|
/* variable Integer/Float-Funktionen */
|
|
|
|
else if (strcmp(ftemp,"ABS")==0)
|
|
BEGIN
|
|
switch (Erg->Typ=LVal.Typ)
|
|
BEGIN
|
|
case TempInt: Erg->Contents.Int=abs(LVal.Contents.Int); break;
|
|
case TempFloat: Erg->Contents.Float=fabs(LVal.Contents.Float);break;
|
|
default: break;
|
|
END
|
|
FFound=True;
|
|
END
|
|
|
|
else if (strcmp(ftemp,"SGN")==0)
|
|
BEGIN
|
|
Erg->Typ=TempInt;
|
|
switch (LVal.Typ)
|
|
BEGIN
|
|
case TempInt:
|
|
if (LVal.Contents.Int<0) Erg->Contents.Int=(-1);
|
|
else if (LVal.Contents.Int>0) Erg->Contents.Int=1;
|
|
else Erg->Contents.Int=0;
|
|
break;
|
|
case TempFloat:
|
|
if (LVal.Contents.Float<0) Erg->Contents.Int=(-1);
|
|
else if (LVal.Contents.Float>0) Erg->Contents.Int=1;
|
|
else Erg->Contents.Int=0;
|
|
break;
|
|
default:
|
|
break;
|
|
END
|
|
FFound=True;
|
|
END
|
|
|
|
/* Funktionen Float und damit auch Int */
|
|
|
|
if (NOT FFound)
|
|
BEGIN
|
|
/* Typkonvertierung */
|
|
|
|
EvalExpression_ChgFloat(&LVal);
|
|
Erg->Typ=TempFloat;
|
|
|
|
/* Integerwandlung */
|
|
|
|
if (strcmp(ftemp,"INT")==0)
|
|
BEGIN
|
|
if (fabs(LVal.Contents.Float)>MaxLargeInt)
|
|
BEGIN
|
|
Erg->Typ=TempNone; WrError(1320);
|
|
END
|
|
else
|
|
BEGIN
|
|
Erg->Typ=TempInt; Erg->Contents.Int=(LargeInt) floor(LVal.Contents.Float);
|
|
END
|
|
END
|
|
|
|
/* Quadratwurzel */
|
|
|
|
else if (strcmp(ftemp,"SQRT")==0)
|
|
BEGIN
|
|
if (LVal.Contents.Float<0)
|
|
BEGIN
|
|
Erg->Typ=TempNone; WrError(1870);
|
|
END
|
|
else Erg->Contents.Float=sqrt(LVal.Contents.Float);
|
|
END
|
|
|
|
/* trigonometrische Funktionen */
|
|
|
|
else if (strcmp(ftemp,"SIN")==0) Erg->Contents.Float=sin(LVal.Contents.Float);
|
|
else if (strcmp(ftemp,"COS")==0) Erg->Contents.Float=cos(LVal.Contents.Float);
|
|
else if (strcmp(ftemp,"TAN")==0)
|
|
BEGIN
|
|
if (cos(LVal.Contents.Float)==0.0)
|
|
BEGIN
|
|
Erg->Typ=TempNone; WrError(1870);
|
|
END
|
|
else Erg->Contents.Float=tan(LVal.Contents.Float);
|
|
END
|
|
else if (strcmp(ftemp,"COT")==0)
|
|
BEGIN
|
|
if ((FVal=sin(LVal.Contents.Float))==0.0)
|
|
BEGIN
|
|
Erg->Typ=TempNone; WrError(1870);
|
|
END
|
|
else Erg->Contents.Float=cos(LVal.Contents.Float)/FVal;
|
|
END
|
|
|
|
/* inverse trigonometrische Funktionen */
|
|
|
|
else if (strcmp(ftemp,"ASIN")==0)
|
|
BEGIN
|
|
if (fabs(LVal.Contents.Float)>1)
|
|
BEGIN
|
|
Erg->Typ=TempNone; WrError(1870);
|
|
END
|
|
else Erg->Contents.Float=asin(LVal.Contents.Float);
|
|
END
|
|
else if (strcmp(ftemp,"ACOS")==0)
|
|
BEGIN
|
|
if (fabs(LVal.Contents.Float)>1)
|
|
BEGIN
|
|
Erg->Typ=TempNone; WrError(1870);
|
|
END
|
|
else Erg->Contents.Float=acos(LVal.Contents.Float);
|
|
END
|
|
else if (strcmp(ftemp,"ATAN")==0) Erg->Contents.Float=atan(LVal.Contents.Float);
|
|
else if (strcmp(ftemp,"ACOT")==0) Erg->Contents.Float=M_PI/2-atan(LVal.Contents.Float);
|
|
|
|
/* exponentielle & hyperbolische Funktionen */
|
|
|
|
else if (strcmp(ftemp,"EXP")==0)
|
|
BEGIN
|
|
if (LVal.Contents.Float>709)
|
|
BEGIN
|
|
Erg->Typ=TempNone; WrError(1880);
|
|
END
|
|
else Erg->Contents.Float=exp(LVal.Contents.Float);
|
|
END
|
|
else if (strcmp(ftemp,"ALOG")==0)
|
|
BEGIN
|
|
if (LVal.Contents.Float>308)
|
|
BEGIN
|
|
Erg->Typ=TempNone; WrError(1880);
|
|
END
|
|
else Erg->Contents.Float=exp(LVal.Contents.Float*log(10.0));
|
|
END
|
|
else if (strcmp(ftemp,"ALD")==0)
|
|
BEGIN
|
|
if (LVal.Contents.Float>1022)
|
|
BEGIN
|
|
Erg->Typ=TempNone; WrError(1880);
|
|
END
|
|
else Erg->Contents.Float=exp(LVal.Contents.Float*log(2.0));
|
|
END
|
|
else if (strcmp(ftemp,"SINH")==0)
|
|
BEGIN
|
|
if (LVal.Contents.Float>709)
|
|
BEGIN
|
|
Erg->Typ=TempNone; WrError(1880);
|
|
END
|
|
else Erg->Contents.Float=sinh(LVal.Contents.Float);
|
|
END
|
|
else if (strcmp(ftemp,"COSH")==0)
|
|
BEGIN
|
|
if (LVal.Contents.Float>709)
|
|
BEGIN
|
|
Erg->Typ=TempNone; WrError(1880);
|
|
END
|
|
else Erg->Contents.Float=cosh(LVal.Contents.Float);
|
|
END
|
|
else if (strcmp(ftemp,"TANH")==0)
|
|
BEGIN
|
|
if (LVal.Contents.Float>709)
|
|
BEGIN
|
|
Erg->Typ=TempNone; WrError(1880);
|
|
END
|
|
else Erg->Contents.Float=tanh(LVal.Contents.Float);
|
|
END
|
|
else if (strcmp(ftemp,"COTH")==0)
|
|
BEGIN
|
|
if (LVal.Contents.Float>709)
|
|
BEGIN
|
|
Erg->Typ=TempNone; WrError(1880);
|
|
END
|
|
else if ((FVal=tanh(LVal.Contents.Float))==0.0)
|
|
BEGIN
|
|
Erg->Typ=TempNone; WrError(1870);
|
|
END
|
|
else Erg->Contents.Float=1.0/FVal;
|
|
END
|
|
|
|
/* logarithmische & inverse hyperbolische Funktionen */
|
|
|
|
else if (strcmp(ftemp,"LN")==0)
|
|
BEGIN
|
|
if (LVal.Contents.Float<=0)
|
|
BEGIN
|
|
Erg->Typ=TempNone; WrError(1870);
|
|
END
|
|
else Erg->Contents.Float=log(LVal.Contents.Float);
|
|
END
|
|
else if (strcmp(ftemp,"LOG")==0)
|
|
BEGIN
|
|
if (LVal.Contents.Float<=0)
|
|
BEGIN
|
|
Erg->Typ=TempNone; WrError(1870);
|
|
END
|
|
else Erg->Contents.Float=log10(LVal.Contents.Float);
|
|
END
|
|
else if (strcmp(ftemp,"LD")==0)
|
|
BEGIN
|
|
if (LVal.Contents.Float<=0)
|
|
BEGIN
|
|
Erg->Typ=TempNone; WrError(1870);
|
|
END
|
|
else Erg->Contents.Float=log(LVal.Contents.Float)/log(2.0);
|
|
END
|
|
else if (strcmp(ftemp,"ASINH")==0)
|
|
Erg->Contents.Float=log(LVal.Contents.Float+sqrt(LVal.Contents.Float*LVal.Contents.Float+1));
|
|
else if (strcmp(ftemp,"ACOSH")==0)
|
|
BEGIN
|
|
if (LVal.Contents.Float<1)
|
|
BEGIN
|
|
Erg->Typ=TempNone; WrError(1880);
|
|
END
|
|
else Erg->Contents.Float=log(LVal.Contents.Float+sqrt(LVal.Contents.Float*LVal.Contents.Float-1));
|
|
END
|
|
else if (strcmp(ftemp,"ATANH")==0)
|
|
BEGIN
|
|
if (fabs(LVal.Contents.Float)>=1)
|
|
BEGIN
|
|
Erg->Typ=TempNone; WrError(1880);
|
|
END
|
|
else Erg->Contents.Float=0.5*log((1+LVal.Contents.Float)/(1-LVal.Contents.Float));
|
|
END
|
|
else if (strcmp(ftemp,"ACOTH")==0)
|
|
BEGIN
|
|
if (fabs(LVal.Contents.Float)<=1)
|
|
BEGIN
|
|
Erg->Typ=TempNone; WrError(1880);
|
|
END
|
|
else Erg->Contents.Float=0.5*log((LVal.Contents.Float+1)/(LVal.Contents.Float-1));
|
|
END
|
|
|
|
/* nix gefunden ? */
|
|
|
|
else
|
|
BEGIN
|
|
WrXError(1860,ftemp); Erg->Typ=TempNone;
|
|
END
|
|
END
|
|
END
|
|
LEAVE;
|
|
END
|
|
|
|
/* nichts dergleichen, dann einfaches Symbol: */
|
|
|
|
/* interne Symbole ? */
|
|
|
|
strmaxcpy(Asc,stemp,255); KillPrefBlanks(Asc); KillPostBlanks(Asc);
|
|
|
|
if (strcasecmp(Asc,"MOMFILE")==0)
|
|
BEGIN
|
|
Erg->Typ=TempString;
|
|
strmaxcpy(Erg->Contents.Ascii,CurrFileName,255);
|
|
LEAVE;
|
|
END;
|
|
|
|
if (strcasecmp(Asc,"MOMLINE")==0)
|
|
BEGIN
|
|
Erg->Typ=TempInt;
|
|
Erg->Contents.Int=CurrLine;
|
|
LEAVE;
|
|
END
|
|
|
|
if (strcasecmp(Asc,"MOMPASS")==0)
|
|
BEGIN
|
|
Erg->Typ=TempInt;
|
|
Erg->Contents.Int=PassNo;
|
|
LEAVE;
|
|
END
|
|
|
|
if (strcasecmp(Asc,"MOMSECTION")==0)
|
|
BEGIN
|
|
Erg->Typ=TempString;
|
|
strmaxcpy(Erg->Contents.Ascii,GetSectionName(MomSectionHandle),255);
|
|
LEAVE;
|
|
END
|
|
|
|
if (strcasecmp(Asc,"MOMSEGMENT")==0)
|
|
BEGIN
|
|
Erg->Typ=TempString;
|
|
strmaxcpy(Erg->Contents.Ascii,SegNames[ActPC],255);
|
|
LEAVE;
|
|
END
|
|
|
|
if (NOT ExpandSymbol(Asc)) LEAVE;
|
|
|
|
KlPos=strchr(Asc,'[');
|
|
if (KlPos!=Nil)
|
|
BEGIN
|
|
Save=(*KlPos); *KlPos='\0';
|
|
END
|
|
OK=ChkSymbName(Asc);
|
|
if (KlPos!=Nil) *KlPos=Save;
|
|
if (NOT OK)
|
|
BEGIN
|
|
WrXError(1020,Asc); LEAVE;
|
|
END;
|
|
|
|
Ptr = FindLocNode(Asc, TempNone);
|
|
if (Ptr == Nil) Ptr=FindNode(Asc, TempNone);
|
|
if (Ptr != Nil)
|
|
BEGIN
|
|
switch (Erg->Typ = Ptr->SymWert.Typ)
|
|
BEGIN
|
|
case TempInt: Erg->Contents.Int=Ptr->SymWert.Contents.IWert; break;
|
|
case TempFloat: Erg->Contents.Float=Ptr->SymWert.Contents.FWert; break;
|
|
case TempString: strmaxcpy(Erg->Contents.Ascii,Ptr->SymWert.Contents.SWert,255);
|
|
default: break;
|
|
END
|
|
if (Erg->Typ != TempNone) Erg->Relocs = DupRelocs(Ptr->Relocs);
|
|
if (Ptr->SymType != 0) TypeFlag |= (1 << Ptr->SymType);
|
|
if ((Ptr->SymSize != (-1)) AND (SizeFlag == (-1))) SizeFlag = Ptr->SymSize;
|
|
if (NOT Ptr->Defined)
|
|
BEGIN
|
|
if (Repass) SymbolQuestionable = True;
|
|
UsesForwards = True;
|
|
END
|
|
Ptr->Used = True;
|
|
LEAVE;
|
|
END
|
|
|
|
/* Symbol evtl. im ersten Pass unbekannt */
|
|
|
|
if (PassNo<=MaxSymPass)
|
|
BEGIN
|
|
Erg->Typ=TempInt; Erg->Contents.Int=EProgCounter();
|
|
Repass=True;
|
|
if ((MsgIfRepass) AND (PassNo>=PassNoForMessage)) WrXError(170,Asc);
|
|
FirstPassUnknown=True;
|
|
END
|
|
|
|
/* alles war nix, Fehler */
|
|
|
|
else WrXError(1010,Asc);
|
|
|
|
func_exit:
|
|
if (LVal.Relocs != NULL) FreeRelocs(&LVal.Relocs);
|
|
if (RVal.Relocs != NULL) FreeRelocs(&RVal.Relocs);
|
|
END
|
|
|
|
|
|
LargeInt EvalIntExpression(char *Asc, IntType Typ, Boolean *OK)
|
|
BEGIN
|
|
TempResult t;
|
|
|
|
*OK = False;
|
|
TypeFlag = 0; SizeFlag = (-1);
|
|
UsesForwards = False;
|
|
SymbolQuestionable = False;
|
|
FirstPassUnknown = False;
|
|
|
|
EvalExpression(Asc, &t);
|
|
SetRelocs(t.Relocs);
|
|
if (t.Typ != TempInt)
|
|
BEGIN
|
|
if (t.Typ != TempNone) WrError(1135);
|
|
FreeRelocs(&LastRelocs);
|
|
return -1;
|
|
END
|
|
|
|
if (FirstPassUnknown) t.Contents.Int &= IntMasks[(int)Typ];
|
|
|
|
if (NOT RangeCheck(t.Contents.Int,Typ))
|
|
if (HardRanges)
|
|
BEGIN
|
|
FreeRelocs(&LastRelocs);
|
|
WrError(1320); return -1;
|
|
END
|
|
else
|
|
BEGIN
|
|
WrError(260); *OK = True; return t.Contents.Int&IntMasks[(int)Typ];
|
|
END
|
|
else
|
|
BEGIN
|
|
*OK = True; return t.Contents.Int;
|
|
END
|
|
END
|
|
|
|
Double EvalFloatExpression(char *Asc, FloatType Typ, Boolean *OK)
|
|
BEGIN
|
|
TempResult t;
|
|
|
|
*OK=False;
|
|
TypeFlag=0; SizeFlag=(-1);
|
|
UsesForwards=False;
|
|
SymbolQuestionable=False;
|
|
FirstPassUnknown=False;
|
|
|
|
EvalExpression(Asc,&t);
|
|
switch (t.Typ)
|
|
BEGIN
|
|
case TempNone:
|
|
return -1;
|
|
case TempInt:
|
|
t.Contents.Float=t.Contents.Int;
|
|
break;
|
|
case TempString:
|
|
WrError(1135); return -1;
|
|
default:
|
|
break;
|
|
END
|
|
|
|
if (NOT FloatRangeCheck(t.Contents.Float,Typ))
|
|
BEGIN
|
|
WrError(1320); return -1;
|
|
END
|
|
|
|
*OK=True; return t.Contents.Float;
|
|
END
|
|
|
|
void EvalStringExpression(char *Asc, Boolean *OK, char *Result)
|
|
BEGIN
|
|
TempResult t;
|
|
|
|
*OK=False;
|
|
TypeFlag=0; SizeFlag=(-1);
|
|
UsesForwards=False;
|
|
SymbolQuestionable=False;
|
|
FirstPassUnknown=False;
|
|
|
|
EvalExpression(Asc,&t);
|
|
if (t.Typ!=TempString)
|
|
BEGIN
|
|
*Result='\0';
|
|
if (t.Typ!=TempNone) WrError(1135);
|
|
return;
|
|
END
|
|
|
|
strmaxcpy(Result,t.Contents.Ascii,255); *OK=True;
|
|
END
|
|
|
|
|
|
static void FreeSymbol(SymbolPtr *Node)
|
|
BEGIN
|
|
PCrossRef Lauf;
|
|
|
|
free((*Node)->SymName);
|
|
|
|
if ((*Node)->SymWert.Typ == TempString)
|
|
free((*Node)->SymWert.Contents.SWert);
|
|
|
|
while ((*Node)->RefList != Nil)
|
|
BEGIN
|
|
Lauf = (*Node)->RefList->Next;
|
|
free((*Node)->RefList);
|
|
(*Node)->RefList = Lauf;
|
|
END
|
|
|
|
FreeRelocs(&((*Node)->Relocs));
|
|
|
|
free(*Node); *Node = Nil;
|
|
END
|
|
|
|
static String serr,snum;
|
|
|
|
Boolean EnterTreeNode(SymbolPtr *Node, SymbolPtr Neu, Boolean MayChange, Boolean DoCross)
|
|
BEGIN
|
|
SymbolPtr Hilf,p1,p2;
|
|
Boolean Grown,Result;
|
|
ShortInt CompErg;
|
|
|
|
/* Stapelueberlauf pruefen, noch nichts eingefuegt */
|
|
|
|
ChkStack(); Result = False;
|
|
|
|
/* an einem Blatt angelangt--> einfach anfuegen */
|
|
|
|
if (*Node == Nil)
|
|
BEGIN
|
|
(*Node) = Neu;
|
|
(*Node)->Balance = 0; (*Node)->Left = Nil; (*Node)->Right = Nil;
|
|
(*Node)->Defined = True; (*Node)->Used = False;
|
|
(*Node)->Changeable = MayChange; (*Node)->RefList = Nil;
|
|
if (DoCross)
|
|
BEGIN
|
|
(*Node)->FileNum = GetFileNum(CurrFileName);
|
|
(*Node)->LineNum = CurrLine;
|
|
END
|
|
return True;
|
|
END
|
|
|
|
CompErg = StrCmp(Neu->SymName, (*Node)->SymName, Neu->Attribute,
|
|
(*Node)->Attribute);
|
|
|
|
if (CompErg > 0)
|
|
BEGIN
|
|
Grown = EnterTreeNode(&((*Node)->Right), Neu, MayChange, DoCross);
|
|
if ((BalanceTree) AND (Grown))
|
|
switch ((*Node)->Balance)
|
|
BEGIN
|
|
case -1:
|
|
(*Node)->Balance = 0; break;
|
|
case 0:
|
|
(*Node)->Balance = 1; Result = True; break;
|
|
case 1:
|
|
p1 = (*Node)->Right;
|
|
if (p1->Balance == 1)
|
|
BEGIN
|
|
(*Node)->Right = p1->Left; p1->Left = (*Node);
|
|
(*Node)->Balance = 0; *Node = p1;
|
|
END
|
|
else
|
|
BEGIN
|
|
p2 = p1->Left;
|
|
p1->Left = p2->Right; p2->Right = p1;
|
|
(*Node)->Right = p2->Left; p2->Left = (*Node);
|
|
if (p2->Balance == 1) (*Node)->Balance = (-1); else (*Node)->Balance = 0;
|
|
if (p2->Balance == -1) p1 ->Balance = 1; else p1 ->Balance = 0;
|
|
*Node = p2;
|
|
END
|
|
(*Node)->Balance = 0;
|
|
break;
|
|
END
|
|
END
|
|
else if (CompErg < 0)
|
|
BEGIN
|
|
Grown = EnterTreeNode(&((*Node)->Left), Neu, MayChange, DoCross);
|
|
if ((BalanceTree) AND (Grown))
|
|
switch ((*Node)->Balance)
|
|
BEGIN
|
|
case 1:
|
|
(*Node)->Balance = 0; break;
|
|
case 0:
|
|
(*Node)->Balance = (-1); Result = True; break;
|
|
case -1:
|
|
p1 = (*Node)->Left;
|
|
if (p1->Balance == (-1))
|
|
BEGIN
|
|
(*Node)->Left = p1->Right; p1->Right = (*Node);
|
|
(*Node)->Balance = 0; (*Node) = p1;
|
|
END
|
|
else
|
|
BEGIN
|
|
p2 = p1->Right;
|
|
p1->Right = p2->Left; p2->Left = p1;
|
|
(*Node)->Left = p2->Right; p2->Right = (*Node);
|
|
if (p2->Balance == (-1)) (*Node)->Balance = 1; else (*Node)->Balance = 0;
|
|
if (p2->Balance == 1) p1 ->Balance = (-1); else p1 ->Balance = 0;
|
|
*Node = p2;
|
|
END
|
|
(*Node)->Balance = 0;
|
|
break;
|
|
END
|
|
END
|
|
else
|
|
BEGIN
|
|
if (((*Node)->Defined) AND (NOT MayChange))
|
|
BEGIN
|
|
strmaxcpy(serr, (*Node)->SymName, 255);
|
|
if (DoCross)
|
|
BEGIN
|
|
sprintf(snum, ",%s %s:%ld", getmessage(Num_PrevDefMsg),
|
|
GetFileName((*Node)->FileNum), (long)((*Node)->LineNum));
|
|
strmaxcat(serr, snum, 255);
|
|
END
|
|
WrXError(1000, serr);
|
|
FreeSymbol(&Neu);
|
|
END
|
|
else
|
|
BEGIN
|
|
if (NOT MayChange)
|
|
BEGIN
|
|
if ((Neu->SymWert.Typ != (*Node)->SymWert.Typ)
|
|
OR ((Neu->SymWert.Typ == TempString) AND (strcmp(Neu->SymWert.Contents.SWert, (*Node)->SymWert.Contents.SWert) != 0))
|
|
OR ((Neu->SymWert.Typ == TempFloat ) AND (Neu->SymWert.Contents.FWert != (*Node)->SymWert.Contents.FWert))
|
|
OR ((Neu->SymWert.Typ == TempInt ) AND (Neu->SymWert.Contents.IWert != (*Node)->SymWert.Contents.IWert)))
|
|
BEGIN
|
|
if ((NOT Repass) AND (JmpErrors>0))
|
|
BEGIN
|
|
if (ThrowErrors) ErrorCount -= JmpErrors;
|
|
JmpErrors = 0;
|
|
END
|
|
Repass = True;
|
|
if ((MsgIfRepass) AND (PassNo >= PassNoForMessage))
|
|
BEGIN
|
|
strmaxcpy(serr, Neu->SymName, 255);
|
|
if (Neu->Attribute != (-1))
|
|
BEGIN
|
|
strmaxcat(serr, "[", 255);
|
|
strmaxcat(serr, GetSectionName(Neu->Attribute), 255);
|
|
strmaxcat(serr, "]", 255);
|
|
END
|
|
WrXError(80, serr);
|
|
END
|
|
END
|
|
END
|
|
Neu->Left = (*Node)->Left; Neu->Right = (*Node)->Right;
|
|
Neu->Balance = (*Node)->Balance;
|
|
if (DoCross)
|
|
BEGIN
|
|
Neu->LineNum = (*Node)->LineNum; Neu->FileNum = (*Node)->FileNum;
|
|
END
|
|
Neu->RefList = (*Node)->RefList; (*Node)->RefList = Nil;
|
|
Neu->Defined = True; Neu->Used = (*Node)->Used; Neu->Changeable = MayChange;
|
|
Hilf = (*Node); *Node = Neu;
|
|
FreeSymbol(&Hilf);
|
|
END
|
|
END
|
|
|
|
return Result;
|
|
END
|
|
|
|
static void EnterLocSymbol(SymbolPtr Neu)
|
|
BEGIN
|
|
Neu->Attribute=MomLocHandle;
|
|
if (NOT CaseSensitive) NLS_UpString(Neu->SymName);
|
|
EnterTreeNode(&FirstLocSymbol,Neu,False,False);
|
|
END
|
|
|
|
static void EnterSymbol_Search(PForwardSymbol *Lauf, PForwardSymbol *Prev,
|
|
PForwardSymbol **RRoot, SymbolPtr Neu,
|
|
PForwardSymbol *Root, Byte ResCode, Byte *SearchErg)
|
|
BEGIN
|
|
*Lauf=(*Root); *Prev=Nil; *RRoot=Root;
|
|
while ((*Lauf!=Nil) AND (strcmp((*Lauf)->Name,Neu->SymName)!=0))
|
|
BEGIN
|
|
*Prev=(*Lauf); *Lauf=(*Lauf)->Next;
|
|
END
|
|
if (*Lauf!=Nil) *SearchErg=ResCode;
|
|
END
|
|
|
|
static void EnterSymbol(SymbolPtr Neu, Boolean MayChange, LongInt ResHandle)
|
|
BEGIN
|
|
PForwardSymbol Lauf,Prev;
|
|
PForwardSymbol *RRoot;
|
|
Byte SearchErg;
|
|
String CombName;
|
|
PSaveSection RunSect;
|
|
LongInt MSect;
|
|
SymbolPtr Copy;
|
|
|
|
/* Neu^.Attribute:=MomSectionHandle;
|
|
IF SectionStack<>Nil THEN
|
|
BEGIN
|
|
Search(SectionStack^.GlobSyms);
|
|
IF Lauf<>Nil THEN Neu^.Attribute:=Lauf^.DestSection
|
|
ELSE Search(SectionStack^.LocSyms);
|
|
IF Lauf<>Nil THEN
|
|
BEGIN
|
|
FreeMem(Lauf^.Name,Length(Lauf^.Name^)+1);
|
|
IF Prev=Nil THEN RRoot^:=Lauf^.Next
|
|
ELSE Prev^.Next:=Lauf^.Next;
|
|
Dispose(Lauf);
|
|
END;
|
|
END;
|
|
IF EnterTreeNode(FirstSymbol,Neu,MayChange,MakeCrossList) THEN;*/
|
|
|
|
if (NOT CaseSensitive) NLS_UpString(Neu->SymName);
|
|
|
|
SearchErg = 0;
|
|
Neu->Attribute = (ResHandle == (-2)) ? (MomSectionHandle) : (ResHandle);
|
|
if ((SectionStack != Nil) AND (Neu->Attribute == MomSectionHandle))
|
|
BEGIN
|
|
EnterSymbol_Search(&Lauf, &Prev, &RRoot, Neu, &(SectionStack->LocSyms),
|
|
1, &SearchErg);
|
|
if (Lauf == Nil)
|
|
EnterSymbol_Search(&Lauf, &Prev, &RRoot, Neu,
|
|
&(SectionStack->GlobSyms), 2, &SearchErg);
|
|
if (Lauf == Nil)
|
|
EnterSymbol_Search(&Lauf, &Prev, &RRoot, Neu,
|
|
&(SectionStack->ExportSyms), 3, &SearchErg);
|
|
if (SearchErg == 2) Neu->Attribute = Lauf->DestSection;
|
|
if (SearchErg == 3)
|
|
BEGIN
|
|
strmaxcpy(CombName, Neu->SymName, 255);
|
|
RunSect = SectionStack; MSect = MomSectionHandle;
|
|
while ((MSect != Lauf->DestSection) AND (RunSect != Nil))
|
|
BEGIN
|
|
strmaxprep(CombName, "_", 255);
|
|
strmaxprep(CombName, GetSectionName(MSect), 255);
|
|
MSect = RunSect->Handle; RunSect = RunSect->Next;
|
|
END
|
|
Copy = (SymbolPtr) malloc(sizeof(SymbolEntry)); *Copy = (*Neu);
|
|
Copy->SymName = strdup(CombName);
|
|
Copy->Attribute = Lauf->DestSection;
|
|
Copy->Relocs = DupRelocs(Neu->Relocs);
|
|
if (Copy->SymWert.Typ == TempString)
|
|
Copy->SymWert.Contents.SWert = strdup(Neu->SymWert.Contents.SWert);
|
|
EnterTreeNode(&FirstSymbol, Copy, MayChange, MakeCrossList);
|
|
END
|
|
if (Lauf != Nil)
|
|
BEGIN
|
|
free(Lauf->Name);
|
|
if (Prev == Nil) *RRoot = Lauf->Next;
|
|
else Prev->Next = Lauf->Next;
|
|
free(Lauf);
|
|
END
|
|
END
|
|
EnterTreeNode(&FirstSymbol, Neu, MayChange, MakeCrossList);
|
|
END
|
|
|
|
void PrintSymTree(char *Name)
|
|
BEGIN
|
|
fprintf(Debug,"---------------------\n");
|
|
fprintf(Debug,"Enter Symbol %s\n\n",Name);
|
|
PrintSymbolTree(); PrintSymbolDepth();
|
|
END
|
|
|
|
void EnterIntSymbol(char *Name_O, LargeInt Wert, Byte Typ, Boolean MayChange)
|
|
BEGIN
|
|
SymbolPtr Neu;
|
|
LongInt DestHandle;
|
|
String Name;
|
|
|
|
strmaxcpy(Name, Name_O, 255);
|
|
if (NOT ExpandSymbol(Name)) return;
|
|
if (NOT GetSymSection(Name, &DestHandle)) return;
|
|
if (NOT ChkSymbName(Name))
|
|
BEGIN
|
|
WrXError(1020, Name); return;
|
|
END
|
|
|
|
Neu=(SymbolPtr) malloc(sizeof(SymbolEntry));
|
|
Neu->SymName = strdup(Name);
|
|
Neu->SymWert.Typ = TempInt;
|
|
Neu->SymWert.Contents.IWert = Wert;
|
|
Neu->SymType = Typ;
|
|
Neu->SymSize = (-1);
|
|
Neu->RefList = Nil;
|
|
Neu->Relocs = Nil;
|
|
|
|
if ((MomLocHandle == (-1)) OR (DestHandle != (-2)))
|
|
BEGIN
|
|
EnterSymbol(Neu, MayChange, DestHandle);
|
|
if (MakeDebug) PrintSymTree(Name);
|
|
END
|
|
else EnterLocSymbol(Neu);
|
|
END
|
|
|
|
void EnterExtSymbol(char *Name_O, LargeInt Wert, Byte Typ, Boolean MayChange)
|
|
BEGIN
|
|
SymbolPtr Neu;
|
|
LongInt DestHandle;
|
|
String Name;
|
|
|
|
strmaxcpy(Name, Name_O, 255);
|
|
if (NOT ExpandSymbol(Name)) return;
|
|
if (NOT GetSymSection(Name, &DestHandle)) return;
|
|
if (NOT ChkSymbName(Name))
|
|
BEGIN
|
|
WrXError(1020, Name); return;
|
|
END
|
|
|
|
Neu=(SymbolPtr) malloc(sizeof(SymbolEntry));
|
|
Neu->SymName = strdup(Name);
|
|
Neu->SymWert.Typ = TempInt;
|
|
Neu->SymWert.Contents.IWert = Wert;
|
|
Neu->SymType = Typ;
|
|
Neu->SymSize = (-1);
|
|
Neu->RefList = Nil;
|
|
Neu->Relocs = (PRelocEntry) malloc(sizeof(TRelocEntry));
|
|
Neu->Relocs->Next = Nil;
|
|
Neu->Relocs->Ref = strdup(Name);
|
|
Neu->Relocs->Add = True;
|
|
|
|
if ((MomLocHandle == (-1)) OR (DestHandle != (-2)))
|
|
BEGIN
|
|
EnterSymbol(Neu, MayChange, DestHandle);
|
|
if (MakeDebug) PrintSymTree(Name);
|
|
END
|
|
else EnterLocSymbol(Neu);
|
|
END
|
|
|
|
void EnterFloatSymbol(char *Name_O, Double Wert, Boolean MayChange)
|
|
BEGIN
|
|
SymbolPtr Neu;
|
|
LongInt DestHandle;
|
|
String Name;
|
|
|
|
strmaxcpy(Name, Name_O,255);
|
|
if (NOT ExpandSymbol(Name)) return;
|
|
if (NOT GetSymSection(Name,&DestHandle)) return;
|
|
if (NOT ChkSymbName(Name))
|
|
BEGIN
|
|
WrXError(1020, Name); return;
|
|
END
|
|
Neu=(SymbolPtr) malloc(sizeof(SymbolEntry));
|
|
Neu->SymName=strdup(Name);
|
|
Neu->SymWert.Typ = TempFloat;
|
|
Neu->SymWert.Contents.FWert = Wert;
|
|
Neu->SymType = 0;
|
|
Neu->SymSize = (-1);
|
|
Neu->RefList = Nil;
|
|
Neu->Relocs = Nil;
|
|
|
|
if ((MomLocHandle == (-1)) OR (DestHandle != (-2)))
|
|
BEGIN
|
|
EnterSymbol(Neu, MayChange, DestHandle);
|
|
if (MakeDebug) PrintSymTree(Name);
|
|
END
|
|
else EnterLocSymbol(Neu);
|
|
END
|
|
|
|
void EnterStringSymbol(char *Name_O, char *Wert, Boolean MayChange)
|
|
BEGIN
|
|
SymbolPtr Neu;
|
|
LongInt DestHandle;
|
|
String Name;
|
|
|
|
strmaxcpy(Name, Name_O, 255);
|
|
if (NOT ExpandSymbol(Name)) return;
|
|
if (NOT GetSymSection(Name,&DestHandle)) return;
|
|
if (NOT ChkSymbName(Name))
|
|
BEGIN
|
|
WrXError(1020, Name); return;
|
|
END
|
|
Neu=(SymbolPtr) malloc(sizeof(SymbolEntry));
|
|
Neu->SymName = strdup(Name);
|
|
Neu->SymWert.Contents.SWert = strdup(Wert);
|
|
Neu->SymWert.Typ = TempString;
|
|
Neu->SymType = 0;
|
|
Neu->SymSize = (-1);
|
|
Neu->RefList = Nil;
|
|
Neu->Relocs = Nil;
|
|
|
|
if ((MomLocHandle == (-1)) OR (DestHandle != (-2)))
|
|
BEGIN
|
|
EnterSymbol(Neu, MayChange, DestHandle);
|
|
if (MakeDebug) PrintSymTree(Name);
|
|
END
|
|
else EnterLocSymbol(Neu);
|
|
END
|
|
|
|
static void AddReference(SymbolPtr Node)
|
|
BEGIN
|
|
PCrossRef Lauf,Neu;
|
|
|
|
/* Speicher belegen */
|
|
|
|
Neu=(PCrossRef) malloc(sizeof(TCrossRef));
|
|
Neu->LineNum=CurrLine; Neu->OccNum=1; Neu->Next=Nil;
|
|
|
|
/* passende Datei heraussuchen */
|
|
|
|
Neu->FileNum=GetFileNum(CurrFileName);
|
|
|
|
/* suchen, ob Eintrag schon existiert */
|
|
|
|
Lauf=Node->RefList;
|
|
while ((Lauf!=Nil)
|
|
AND ((Lauf->FileNum!=Neu->FileNum) OR (Lauf->LineNum!=Neu->LineNum)))
|
|
Lauf=Lauf->Next;
|
|
|
|
/* schon einmal in dieser Datei in dieser Zeile aufgetaucht: nur Zaehler
|
|
rauf: */
|
|
|
|
if (Lauf!=Nil)
|
|
BEGIN
|
|
Lauf->OccNum++; free(Neu);
|
|
END
|
|
|
|
/* ansonsten an Kettenende anhaengen */
|
|
|
|
else if (Node->RefList==Nil) Node->RefList=Neu;
|
|
|
|
else
|
|
BEGIN
|
|
Lauf=Node->RefList;
|
|
while (Lauf->Next!=Nil) Lauf=Lauf->Next;
|
|
Lauf->Next=Neu;
|
|
END
|
|
END
|
|
|
|
static Boolean FindNode_FNode(char *Name, TempType SearchType,
|
|
SymbolPtr *FindNode_Result, LongInt Handle)
|
|
BEGIN
|
|
SymbolPtr Lauf=FirstSymbol;
|
|
ShortInt SErg=(-1);
|
|
Boolean Result=False;
|
|
|
|
while ((Lauf!=Nil) AND (SErg!=0))
|
|
BEGIN
|
|
SErg=StrCmp(Name,Lauf->SymName,Handle,Lauf->Attribute);
|
|
if (SErg<0) Lauf=Lauf->Left;
|
|
else if (SErg>0) Lauf=Lauf->Right;
|
|
END
|
|
if (Lauf!=Nil)
|
|
if ((SearchType==TempNone) OR (Lauf->SymWert.Typ==SearchType))
|
|
BEGIN
|
|
*FindNode_Result=Lauf; Result=True;
|
|
if (MakeCrossList AND DoRefs) AddReference(Lauf);
|
|
END
|
|
|
|
return Result;
|
|
END
|
|
|
|
static Boolean FindNode_FSpec(char *Name, PForwardSymbol Root)
|
|
BEGIN
|
|
while ((Root!=Nil) AND (strcmp(Root->Name,Name)!=0)) Root=Root->Next;
|
|
return (Root!=Nil);
|
|
END
|
|
|
|
static SymbolPtr FindNode(char *Name_O, TempType SearchType)
|
|
BEGIN
|
|
PSaveSection Lauf;
|
|
LongInt DestSection;
|
|
SymbolPtr FindNode_Result;
|
|
String Name;
|
|
|
|
strmaxcpy(Name,Name_O,255);
|
|
FindNode_Result=Nil;
|
|
if (NOT GetSymSection(Name,&DestSection)) return FindNode_Result;
|
|
if (NOT CaseSensitive) NLS_UpString(Name);
|
|
if (SectionStack!=Nil)
|
|
if (PassNo<=MaxSymPass)
|
|
if (FindNode_FSpec(Name,SectionStack->LocSyms)) DestSection=MomSectionHandle;
|
|
/* if (FSpec(SectionStack->GlobSyms)) return; */
|
|
if (DestSection==(-2))
|
|
BEGIN
|
|
if (FindNode_FNode(Name,SearchType,&FindNode_Result,MomSectionHandle)) return FindNode_Result;
|
|
Lauf=SectionStack;
|
|
while (Lauf!=Nil)
|
|
BEGIN
|
|
if (FindNode_FNode(Name,SearchType,&FindNode_Result,Lauf->Handle)) return FindNode_Result;
|
|
Lauf=Lauf->Next;
|
|
END
|
|
END
|
|
else FindNode_FNode(Name,SearchType,&FindNode_Result,DestSection);
|
|
|
|
return FindNode_Result;
|
|
END
|
|
|
|
static Boolean FindLocNode_FNode(char *Name, TempType SearchType,
|
|
SymbolPtr *FindLocNode_Result, LongInt Handle)
|
|
BEGIN
|
|
SymbolPtr Lauf=FirstLocSymbol;
|
|
ShortInt SErg=(-1);
|
|
Boolean Result=False;
|
|
|
|
while ((Lauf!=Nil) AND (SErg!=0))
|
|
BEGIN
|
|
SErg=StrCmp(Name,Lauf->SymName,Handle,Lauf->Attribute);
|
|
if (SErg<0) Lauf=Lauf->Left;
|
|
else if (SErg>0) Lauf=Lauf->Right;
|
|
END
|
|
|
|
if (Lauf!=Nil)
|
|
if ((SearchType==TempNone) OR (Lauf->SymWert.Typ==SearchType))
|
|
BEGIN
|
|
*FindLocNode_Result=Lauf; Result=True;
|
|
END
|
|
|
|
return Result;
|
|
END
|
|
|
|
static SymbolPtr FindLocNode(char *Name_O, TempType SearchType)
|
|
BEGIN
|
|
PLocHandle RunLocHandle;
|
|
SymbolPtr FindLocNode_Result;
|
|
String Name;
|
|
|
|
FindLocNode_Result=Nil;
|
|
|
|
strmaxcpy(Name,Name_O,255); if (NOT CaseSensitive) NLS_UpString(Name);
|
|
|
|
if (MomLocHandle==(-1)) return FindLocNode_Result;
|
|
|
|
if (FindLocNode_FNode(Name,SearchType,&FindLocNode_Result,MomLocHandle))
|
|
return FindLocNode_Result;
|
|
|
|
RunLocHandle=FirstLocHandle;
|
|
while ((RunLocHandle!=Nil) AND (RunLocHandle->Cont!=(-1)))
|
|
BEGIN
|
|
if (FindLocNode_FNode(Name,SearchType,&FindLocNode_Result,RunLocHandle->Cont))
|
|
return FindLocNode_Result;
|
|
RunLocHandle=RunLocHandle->Next;
|
|
END
|
|
|
|
return FindLocNode_Result;
|
|
END
|
|
/**
|
|
void SetSymbolType(char *Name, Byte NTyp)
|
|
BEGIN
|
|
Lauf:SymbolPtr;
|
|
HRef:Boolean;
|
|
|
|
IF NOT ExpandSymbol(Name) THEN Exit;
|
|
HRef:=DoRefs; DoRefs:=False;
|
|
Lauf:=FindLocNode(Name,TempInt);
|
|
IF Lauf=Nil THEN Lauf:=FindNode(Name,TempInt);
|
|
IF Lauf<>Nil THEN Lauf^.SymType:=NTyp;
|
|
DoRefs:=HRef;
|
|
END
|
|
**/
|
|
|
|
Boolean GetIntSymbol(char *Name, LargeInt *Wert)
|
|
BEGIN
|
|
SymbolPtr Lauf;
|
|
String NName;
|
|
|
|
strmaxcpy(NName,Name,255);
|
|
if (NOT ExpandSymbol(NName)) return False;
|
|
Lauf=FindLocNode(NName,TempInt);
|
|
if (Lauf==Nil) Lauf=FindNode(NName,TempInt);
|
|
if (Lauf!=Nil)
|
|
BEGIN
|
|
*Wert=Lauf->SymWert.Contents.IWert;
|
|
if (Lauf->SymType!=0) TypeFlag|=(1<<Lauf->SymType);
|
|
if ((Lauf->SymSize!=(-1)) AND (SizeFlag!=(-1))) SizeFlag=Lauf->SymSize;
|
|
Lauf->Used=True;
|
|
END
|
|
else
|
|
BEGIN
|
|
if (PassNo>MaxSymPass) WrXError(1010,Name);
|
|
*Wert=EProgCounter();
|
|
END
|
|
return (Lauf!=Nil);
|
|
END
|
|
|
|
Boolean GetFloatSymbol(char *Name, Double *Wert)
|
|
BEGIN
|
|
SymbolPtr Lauf;
|
|
String NName;
|
|
|
|
strmaxcpy(NName,Name,255);
|
|
if (NOT ExpandSymbol(NName)) return False;
|
|
Lauf=FindLocNode(Name,TempFloat);
|
|
if (Lauf==Nil) Lauf=FindNode(NName,TempFloat);
|
|
if (Lauf!=Nil)
|
|
BEGIN
|
|
*Wert=Lauf->SymWert.Contents.FWert;
|
|
Lauf->Used=True;
|
|
END
|
|
else
|
|
BEGIN
|
|
if (PassNo>MaxSymPass) WrXError(1010,Name);
|
|
*Wert=0;
|
|
END
|
|
return (Lauf!=Nil);
|
|
END
|
|
|
|
Boolean GetStringSymbol(char *Name, char *Wert)
|
|
BEGIN
|
|
SymbolPtr Lauf;
|
|
String NName;
|
|
|
|
strmaxcpy(NName,Name,255);
|
|
if (NOT ExpandSymbol(NName)) return False;
|
|
Lauf=FindLocNode(NName,TempString);
|
|
if (Lauf==Nil) Lauf=FindNode(NName,TempString);
|
|
if (Lauf!=Nil)
|
|
BEGIN
|
|
strcpy(Wert,Lauf->SymWert.Contents.SWert);
|
|
Lauf->Used=True;
|
|
END
|
|
else
|
|
BEGIN
|
|
if (PassNo>MaxSymPass) WrXError(1010,Name);
|
|
*Wert='\0';
|
|
END
|
|
return (Lauf!=Nil);
|
|
END
|
|
|
|
void SetSymbolSize(char *Name, ShortInt Size)
|
|
BEGIN
|
|
SymbolPtr Lauf;
|
|
Boolean HRef;
|
|
String NName;
|
|
|
|
strmaxcpy(NName,Name,255);
|
|
if (NOT ExpandSymbol(NName)) return;
|
|
HRef=DoRefs; DoRefs=False;
|
|
Lauf=FindLocNode(NName,TempInt);
|
|
if (Lauf==Nil) Lauf=FindNode(Name,TempInt);
|
|
if (Lauf!=Nil) Lauf->SymSize=Size;
|
|
DoRefs=HRef;
|
|
END
|
|
|
|
ShortInt GetSymbolSize(char *Name)
|
|
BEGIN
|
|
SymbolPtr Lauf;
|
|
String NName;
|
|
|
|
strmaxcpy(NName,Name,255);
|
|
if (NOT ExpandSymbol(NName)) return -1;
|
|
Lauf=FindLocNode(NName,TempInt);
|
|
if (Lauf==Nil) Lauf=FindNode(NName,TempInt);
|
|
return ((Lauf!=Nil) ? Lauf->SymSize : -1);
|
|
END
|
|
|
|
Boolean IsSymbolFloat(char *Name)
|
|
BEGIN
|
|
SymbolPtr Lauf;
|
|
String NName;
|
|
|
|
strmaxcpy(NName,Name,255);
|
|
if (NOT ExpandSymbol(NName)) return False;
|
|
|
|
Lauf=FindLocNode(NName,TempFloat);
|
|
if (Lauf==Nil) Lauf=FindNode(NName,TempFloat);
|
|
return ((Lauf!=Nil) AND (Lauf->SymWert.Typ==TempFloat));
|
|
END
|
|
|
|
Boolean IsSymbolString(char *Name)
|
|
BEGIN
|
|
SymbolPtr Lauf;
|
|
String NName;
|
|
|
|
strmaxcpy(NName,Name,255);
|
|
if (NOT ExpandSymbol(NName)) return False;
|
|
|
|
Lauf=FindLocNode(NName,TempString);
|
|
if (Lauf==Nil) Lauf=FindNode(NName,TempString);
|
|
return ((Lauf!=Nil) AND (Lauf->SymWert.Typ==TempString));
|
|
END
|
|
|
|
Boolean IsSymbolDefined(char *Name)
|
|
BEGIN
|
|
SymbolPtr Lauf;
|
|
String NName;
|
|
|
|
strmaxcpy(NName,Name,255);
|
|
if (NOT ExpandSymbol(NName)) return False;
|
|
|
|
Lauf=FindLocNode(NName,TempInt);
|
|
if (Lauf==Nil) Lauf=FindLocNode(NName,TempFloat);
|
|
if (Lauf==Nil) Lauf=FindLocNode(NName,TempString);
|
|
if (Lauf==Nil) Lauf=FindNode(NName,TempInt);
|
|
if (Lauf==Nil) Lauf=FindNode(NName,TempFloat);
|
|
if (Lauf==Nil) Lauf=FindNode(NName,TempString);
|
|
return ((Lauf!=Nil) AND (Lauf->Defined));
|
|
END
|
|
|
|
Boolean IsSymbolUsed(char *Name)
|
|
BEGIN
|
|
SymbolPtr Lauf;
|
|
String NName;
|
|
|
|
strmaxcpy(NName,Name,255);
|
|
if (NOT ExpandSymbol(NName)) return False;
|
|
|
|
Lauf=FindLocNode(NName,TempInt);
|
|
if (Lauf==Nil) Lauf=FindLocNode(NName,TempFloat);
|
|
if (Lauf==Nil) Lauf=FindLocNode(NName,TempString);
|
|
if (Lauf==Nil) Lauf=FindNode(NName,TempInt);
|
|
if (Lauf==Nil) Lauf=FindNode(NName,TempFloat);
|
|
if (Lauf==Nil) Lauf=FindNode(NName,TempString);
|
|
return ((Lauf!=Nil) AND (Lauf->Used));
|
|
END
|
|
|
|
Boolean IsSymbolChangeable(char *Name)
|
|
BEGIN
|
|
SymbolPtr Lauf;
|
|
String NName;
|
|
|
|
strmaxcpy(NName,Name,255);
|
|
if (NOT ExpandSymbol(NName)) return False;
|
|
|
|
Lauf=FindLocNode(NName,TempInt);
|
|
if (Lauf==Nil) Lauf=FindLocNode(NName,TempFloat);
|
|
if (Lauf==Nil) Lauf=FindLocNode(NName,TempString);
|
|
if (Lauf==Nil) Lauf=FindNode(NName,TempInt);
|
|
if (Lauf==Nil) Lauf=FindNode(NName,TempFloat);
|
|
if (Lauf==Nil) Lauf=FindNode(NName,TempString);
|
|
return ((Lauf!=Nil) AND (Lauf->Changeable));
|
|
END
|
|
|
|
Integer GetSymbolType(char *Name)
|
|
BEGIN
|
|
SymbolPtr Lauf;
|
|
String NName;
|
|
|
|
strmaxcpy(NName,Name,255);
|
|
if (NOT ExpandSymbol(NName)) return -1;
|
|
|
|
Lauf=FindLocNode(Name,TempInt);
|
|
if (Lauf==Nil) Lauf=FindLocNode(Name,TempFloat);
|
|
if (Lauf==Nil) Lauf=FindLocNode(Name,TempString);
|
|
if (Lauf==Nil) Lauf=FindNode(Name,TempInt);
|
|
if (Lauf==Nil) Lauf=FindNode(Name,TempFloat);
|
|
if (Lauf==Nil) Lauf=FindNode(Name,TempString);
|
|
return (Lauf==Nil) ? -1 : Lauf->SymType;
|
|
END
|
|
|
|
static void ConvertSymbolVal(SymbolVal *Inp, TempResult *Outp)
|
|
BEGIN
|
|
switch (Outp->Typ=Inp->Typ)
|
|
BEGIN
|
|
case TempInt :Outp->Contents.Int =Inp->Contents.IWert; break;
|
|
case TempFloat :Outp->Contents.Float=Inp->Contents.FWert; break;
|
|
case TempString:strmaxcpy(Outp->Contents.Ascii,Inp->Contents.SWert,255); break;
|
|
default: break;
|
|
END
|
|
END
|
|
|
|
static int ActPageWidth,cwidth;
|
|
|
|
static void PrintSymbolList_AddOut(char *s, char *Zeilenrest, int Width)
|
|
BEGIN
|
|
if (strlen(s)+strlen(Zeilenrest)>Width)
|
|
BEGIN
|
|
Zeilenrest[strlen(Zeilenrest)-1]='\0';
|
|
WrLstLine(Zeilenrest); strmaxcpy(Zeilenrest,s,255);
|
|
END
|
|
else strmaxcat(Zeilenrest,s,255);
|
|
END
|
|
|
|
static void PrintSymbolList_PNode(SymbolPtr Node, int Width,
|
|
LongInt *Sum, LongInt *USum,
|
|
char *Zeilenrest)
|
|
BEGIN
|
|
String s1,sh;
|
|
int l1;
|
|
TempResult t;
|
|
|
|
ConvertSymbolVal(&(Node->SymWert),&t); StrSym(&t,False,s1);
|
|
|
|
strmaxcpy(sh,Node->SymName,255);
|
|
if (Node->Attribute!=(-1))
|
|
BEGIN
|
|
strmaxcat(sh," [",255);
|
|
strmaxcat(sh,GetSectionName(Node->Attribute),255);
|
|
strmaxcat(sh,"]",255);
|
|
END
|
|
strmaxprep(sh,(Node->Used)?" ":"*",255);
|
|
l1=(strlen(s1)+strlen(sh)+6)%(cwidth);
|
|
if (l1<cwidth-2) strmaxprep(s1,Blanks(cwidth-2-l1),255);
|
|
strmaxprep(s1," : ",255);
|
|
strmaxprep(s1,sh,255);
|
|
strmaxcat(s1," ",255);
|
|
s1[l1=strlen(s1)]=SegShorts[Node->SymType]; s1[l1+1]='\0';
|
|
strmaxcat(s1," | ",255);
|
|
PrintSymbolList_AddOut(s1,Zeilenrest,Width); (*Sum)++;
|
|
if (NOT Node->Used) (*USum)++;
|
|
END
|
|
|
|
static void PrintSymbolList_PrintNode(SymbolPtr Node, int Width,
|
|
LongInt *Sum, LongInt *USum,
|
|
char *Zeilenrest)
|
|
BEGIN
|
|
ChkStack();
|
|
|
|
if (Node==Nil) return;
|
|
|
|
PrintSymbolList_PrintNode(Node->Left,Width,Sum,USum,Zeilenrest);
|
|
PrintSymbolList_PNode(Node,Width,Sum,USum,Zeilenrest);
|
|
PrintSymbolList_PrintNode(Node->Right,Width,Sum,USum,Zeilenrest);
|
|
END
|
|
|
|
void PrintSymbolList(void)
|
|
BEGIN
|
|
int Width;
|
|
String Zeilenrest;
|
|
LongInt Sum,USum;
|
|
|
|
Width=(PageWidth==0)?80:PageWidth;
|
|
NewPage(ChapDepth,True);
|
|
WrLstLine(getmessage(Num_ListSymListHead1));
|
|
WrLstLine(getmessage(Num_ListSymListHead2));
|
|
WrLstLine("");
|
|
|
|
Zeilenrest[0]='\0'; Sum=0; USum=0;
|
|
ActPageWidth=(PageWidth==0) ? 80 : PageWidth; cwidth=ActPageWidth>>1;
|
|
PrintSymbolList_PrintNode(FirstSymbol,Width,&Sum,&USum,Zeilenrest);
|
|
if (Zeilenrest[0]!='\0')
|
|
BEGIN
|
|
Zeilenrest[strlen(Zeilenrest)-1]='\0';
|
|
WrLstLine(Zeilenrest);
|
|
END
|
|
WrLstLine("");
|
|
sprintf(Zeilenrest,"%7d",Sum);
|
|
strmaxcat(Zeilenrest,getmessage((Sum==1)?Num_ListSymSumMsg:Num_ListSymSumsMsg),255);
|
|
WrLstLine(Zeilenrest);
|
|
sprintf(Zeilenrest,"%7d",USum);
|
|
strmaxcat(Zeilenrest,getmessage((USum==1)?Num_ListUSymSumMsg:Num_ListUSymSumsMsg),255);
|
|
WrLstLine(Zeilenrest);
|
|
WrLstLine("");
|
|
END
|
|
|
|
static Boolean HWritten;
|
|
static int Space;
|
|
|
|
static void PrintDebSymbols_PNode(FILE *f, SymbolPtr Node)
|
|
BEGIN
|
|
char *p;
|
|
int l1;
|
|
TempResult t;
|
|
String s;
|
|
|
|
if (NOT HWritten)
|
|
BEGIN
|
|
fprintf(f,"\n"); ChkIO(10004);
|
|
fprintf(f,"Symbols in Segment %s\n",SegNames[Space]); ChkIO(10004);
|
|
HWritten=True;
|
|
END
|
|
|
|
fprintf(f,"%s",Node->SymName); ChkIO(10004); l1=strlen(Node->SymName);
|
|
if (Node->Attribute!=(-1))
|
|
BEGIN
|
|
sprintf(s,"[%d]", (int)Node->Attribute);
|
|
fprintf(f,"%s",s); ChkIO(10004);
|
|
l1+=strlen(s);
|
|
END
|
|
fprintf(f,"%s ",Blanks(37-l1)); ChkIO(10004);
|
|
switch (Node->SymWert.Typ)
|
|
BEGIN
|
|
case TempInt: fprintf(f,"Int "); break;
|
|
case TempFloat: fprintf(f,"Float "); break;
|
|
case TempString: fprintf(f,"String "); break;
|
|
default: break;
|
|
END
|
|
ChkIO(10004);
|
|
if (Node->SymWert.Typ==TempString)
|
|
BEGIN
|
|
l1=0;
|
|
for (p=Node->SymWert.Contents.SWert; *p!='\0'; p++)
|
|
BEGIN
|
|
if ((*p=='\\') OR (*p<=' '))
|
|
BEGIN
|
|
fprintf(f,"\\%03d",*p); l1+=4;
|
|
END
|
|
else
|
|
BEGIN
|
|
fputc(*p,f); ChkIO(10004); l1++;
|
|
END
|
|
END
|
|
END
|
|
else
|
|
BEGIN
|
|
ConvertSymbolVal(&(Node->SymWert),&t); StrSym(&t,False,s);
|
|
l1=strlen(s);
|
|
fprintf(f,"%s",s); ChkIO(10004);
|
|
END
|
|
fprintf(f,"%s %-3d %d\n",Blanks(25-l1),Node->SymSize,(int)Node->Used);
|
|
ChkIO(10004);
|
|
END
|
|
|
|
static void PrintDebSymbols_PrintNode(FILE *f, SymbolPtr Node)
|
|
BEGIN
|
|
ChkStack();
|
|
|
|
if (Node==Nil) return;
|
|
|
|
PrintDebSymbols_PrintNode(f,Node->Left);
|
|
|
|
if (Node->SymType==Space) PrintDebSymbols_PNode(f,Node);
|
|
|
|
PrintDebSymbols_PrintNode(f,Node->Right);
|
|
END
|
|
|
|
void PrintDebSymbols(FILE *f)
|
|
BEGIN
|
|
for (Space=0; Space<PCMax; Space++)
|
|
BEGIN
|
|
HWritten=False;
|
|
PrintDebSymbols_PrintNode(f,FirstSymbol);
|
|
END
|
|
END
|
|
|
|
static void PrNoISection(FILE *f, SymbolPtr Node, LongInt Handle)
|
|
BEGIN
|
|
if (Node->Left!=Nil) PrNoISection(f,Node->Left,Handle);
|
|
if ((Node->SymType==SegCode) AND (Node->Attribute==Handle) AND (Node->SymWert.Typ==TempInt))
|
|
BEGIN
|
|
errno=0; fprintf(f,"DEFINE %s ",Node->SymName); ChkIO(10004);
|
|
errno=0; fprintf(f,LargeIntFormat,Node->SymWert.Contents.IWert); ChkIO(10004);
|
|
errno=0; fprintf(f,"\n"); ChkIO(10004);
|
|
END
|
|
if (Node->Right!=Nil) PrNoISection(f,Node->Right,Handle);
|
|
END
|
|
|
|
void PrintNoISymbols(FILE *f)
|
|
BEGIN
|
|
PCToken CurrSection;
|
|
LongInt z;
|
|
|
|
PrNoISection(f,FirstSymbol,-1); z=0;
|
|
for (CurrSection=FirstSection; CurrSection!=Nil; CurrSection=CurrSection->Next)
|
|
if (ChunkSum(&CurrSection->Usage)>0)
|
|
BEGIN
|
|
fprintf(f,"FUNCTION %s ",CurrSection->Name); ChkIO(10004);
|
|
fprintf(f,LargeIntFormat,ChunkMin(&CurrSection->Usage)); ChkIO(10004);
|
|
fprintf(f,"\n"); ChkIO(10004);
|
|
PrNoISection(f,FirstSymbol,z++);
|
|
fprintf(f,"ENDFUNC "); ChkIO(10004);
|
|
fprintf(f,LargeIntFormat,ChunkMax(&CurrSection->Usage)); ChkIO(10004);
|
|
fprintf(f,"\n"); ChkIO(10004);
|
|
END
|
|
END
|
|
|
|
static void PrintSymbolTree_PrintNode(SymbolPtr Node, int Shift)
|
|
BEGIN
|
|
Byte z;
|
|
|
|
if (Node==Nil) return;
|
|
|
|
PrintSymbolTree_PrintNode(Node->Left,Shift+1);
|
|
|
|
for (z=1; z<=Shift; z++) fprintf(Debug,"%6s","");
|
|
fprintf(Debug,"%s\n",Node->SymName);
|
|
|
|
PrintSymbolTree_PrintNode(Node->Right,Shift+1);
|
|
END
|
|
|
|
void PrintSymbolTree(void)
|
|
BEGIN
|
|
PrintSymbolTree_PrintNode(FirstSymbol,0);
|
|
END
|
|
|
|
static void ClearSymbolList_ClearNode(SymbolPtr *Node)
|
|
BEGIN
|
|
if ((*Node)->Left!=Nil) ClearSymbolList_ClearNode(&((*Node)->Left));
|
|
if ((*Node)->Right!=Nil) ClearSymbolList_ClearNode(&((*Node)->Right));
|
|
FreeSymbol(Node);
|
|
END
|
|
|
|
void ClearSymbolList(void)
|
|
BEGIN
|
|
|
|
if (FirstSymbol!=Nil) ClearSymbolList_ClearNode(&FirstSymbol);
|
|
|
|
if (FirstLocSymbol!=Nil) ClearSymbolList_ClearNode(&FirstLocSymbol);
|
|
END
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
/* Stack-Verwaltung */
|
|
|
|
Boolean PushSymbol(char *SymName_O, char *StackName_O)
|
|
BEGIN
|
|
SymbolPtr Src;
|
|
PSymbolStack LStack,NStack,PStack;
|
|
PSymbolStackEntry Elem;
|
|
String SymName,StackName;
|
|
|
|
strmaxcpy(SymName,SymName_O,255);
|
|
if (NOT ExpandSymbol(SymName)) return False;
|
|
|
|
Src=FindNode(SymName,TempInt);
|
|
if (Src==Nil) Src=FindNode(SymName,TempFloat);
|
|
if (Src==Nil) Src=FindNode(SymName,TempString);
|
|
if (Src==Nil)
|
|
BEGIN
|
|
WrXError(1010,SymName); return False;
|
|
END
|
|
|
|
strmaxcpy(StackName,(*StackName_O=='\0')?DefStackName:StackName_O,255);
|
|
if (NOT ExpandSymbol(StackName)) return False;
|
|
if (NOT ChkSymbName(StackName))
|
|
BEGIN
|
|
WrXError(1020,StackName); return False;
|
|
END
|
|
|
|
LStack=FirstStack; PStack=Nil;
|
|
while ((LStack!=Nil) AND (strcmp(LStack->Name,StackName)<0))
|
|
BEGIN
|
|
PStack=LStack;
|
|
LStack=LStack->Next;
|
|
END
|
|
|
|
if ((LStack==Nil) OR (strcmp(LStack->Name,StackName)>0))
|
|
BEGIN
|
|
NStack=(PSymbolStack) malloc(sizeof(TSymbolStack));
|
|
NStack->Name=strdup(StackName);
|
|
NStack->Contents=Nil;
|
|
NStack->Next=LStack;
|
|
if (PStack==Nil) FirstStack=NStack; else PStack->Next=NStack;
|
|
LStack=NStack;
|
|
END
|
|
|
|
Elem=(PSymbolStackEntry) malloc(sizeof(TSymbolStackEntry));
|
|
Elem->Next=LStack->Contents;
|
|
Elem->Contents=Src->SymWert;
|
|
LStack->Contents=Elem;
|
|
|
|
return True;
|
|
END
|
|
|
|
Boolean PopSymbol(char *SymName_O, char *StackName_O)
|
|
BEGIN
|
|
SymbolPtr Dest;
|
|
PSymbolStack LStack,PStack;
|
|
PSymbolStackEntry Elem;
|
|
String SymName,StackName;
|
|
|
|
strmaxcpy(SymName,SymName_O,255);
|
|
if (NOT ExpandSymbol(SymName)) return False;
|
|
|
|
Dest=FindNode(SymName,TempInt);
|
|
if (Dest==Nil) Dest=FindNode(SymName,TempFloat);
|
|
if (Dest==Nil) Dest=FindNode(SymName,TempString);
|
|
if (Dest==Nil)
|
|
BEGIN
|
|
WrXError(1010,SymName); return False;
|
|
END
|
|
|
|
strmaxcpy(StackName,(*StackName_O=='\0')?DefStackName:StackName_O,255);
|
|
if (NOT ExpandSymbol(StackName)) return False;
|
|
if (NOT ChkSymbName(StackName))
|
|
BEGIN
|
|
WrXError(1020,StackName); return False;
|
|
END
|
|
|
|
LStack=FirstStack; PStack=Nil;
|
|
while ((LStack!=Nil) AND (strcmp(LStack->Name,StackName)<0))
|
|
BEGIN
|
|
PStack=LStack;
|
|
LStack=LStack->Next;
|
|
END
|
|
|
|
if ((LStack==Nil) OR (strcmp(LStack->Name,StackName)>0))
|
|
BEGIN
|
|
WrXError(1530,StackName); return False;
|
|
END
|
|
|
|
Elem=LStack->Contents;
|
|
Dest->SymWert=Elem->Contents;
|
|
if ((LStack->Contents=Elem->Next)==Nil)
|
|
BEGIN
|
|
if (PStack==Nil) FirstStack=LStack->Next; else PStack->Next=LStack->Next;
|
|
free(LStack->Name);
|
|
free(LStack);
|
|
END
|
|
free(Elem);
|
|
|
|
return True;
|
|
END
|
|
|
|
void ClearStacks(void)
|
|
BEGIN
|
|
PSymbolStack Act;
|
|
PSymbolStackEntry Elem;
|
|
int z;
|
|
String s;
|
|
|
|
while (FirstStack!=Nil)
|
|
BEGIN
|
|
z=0; Act=FirstStack;
|
|
while (Act->Contents!=Nil)
|
|
BEGIN
|
|
Elem=Act->Contents; Act->Contents=Elem->Next;
|
|
free(Elem); z++;
|
|
END
|
|
sprintf(s,"%s(%d)", Act->Name, z);
|
|
WrXError(230,s);
|
|
free(Act->Name);
|
|
FirstStack=Act->Next; free(Act);
|
|
END
|
|
END
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
/* Funktionsverwaltung */
|
|
|
|
void EnterFunction(char *FName, char *FDefinition, Byte NewCnt)
|
|
BEGIN
|
|
PFunction Neu;
|
|
String FName_N;
|
|
|
|
if (NOT CaseSensitive)
|
|
BEGIN
|
|
strmaxcpy(FName_N,FName,255); NLS_UpString(FName_N); FName=FName_N;
|
|
END
|
|
|
|
if (NOT ChkSymbName(FName))
|
|
BEGIN
|
|
WrXError(1020,FName); return;
|
|
END
|
|
|
|
if (FindFunction(FName)!=Nil)
|
|
BEGIN
|
|
if (PassNo==1) WrXError(1000,FName); return;
|
|
END
|
|
|
|
Neu=(PFunction) malloc(sizeof(TFunction));
|
|
Neu->Next=FirstFunction; Neu->ArguCnt=NewCnt;
|
|
Neu->Name=strdup(FName);
|
|
Neu->Definition=strdup(FDefinition);
|
|
FirstFunction=Neu;
|
|
END
|
|
|
|
PFunction FindFunction(char *Name)
|
|
BEGIN
|
|
PFunction Lauf=FirstFunction;
|
|
String Name_N;
|
|
|
|
if (NOT CaseSensitive)
|
|
BEGIN
|
|
strmaxcpy(Name_N,Name,255); NLS_UpString(Name_N); Name=Name_N;
|
|
END
|
|
|
|
while ((Lauf!=Nil) AND (strcmp(Lauf->Name,Name)!=0)) Lauf=Lauf->Next;
|
|
return Lauf;
|
|
END
|
|
|
|
void PrintFunctionList(void)
|
|
BEGIN
|
|
PFunction Lauf;
|
|
String OneS;
|
|
Boolean cnt;
|
|
|
|
if (FirstFunction==Nil) return;
|
|
|
|
NewPage(ChapDepth,True);
|
|
WrLstLine(getmessage(Num_ListFuncListHead1));
|
|
WrLstLine(getmessage(Num_ListFuncListHead2));
|
|
WrLstLine("");
|
|
|
|
OneS[0]='\0'; Lauf=FirstFunction; cnt=False;
|
|
while (Lauf!=Nil)
|
|
BEGIN
|
|
strmaxcat(OneS,Lauf->Name,255);
|
|
if (strlen(Lauf->Name)<37) strmaxcat(OneS,Blanks(37-strlen(Lauf->Name)),255);
|
|
if (NOT cnt) strmaxcat(OneS," | ",255);
|
|
else
|
|
BEGIN
|
|
WrLstLine(OneS); OneS[0]='\0';
|
|
END
|
|
cnt=NOT cnt;
|
|
Lauf=Lauf->Next;
|
|
END
|
|
if (cnt)
|
|
BEGIN
|
|
OneS[strlen(OneS)-1]='\0';
|
|
WrLstLine(OneS);
|
|
END
|
|
WrLstLine("");
|
|
END
|
|
|
|
void ClearFunctionList(void)
|
|
BEGIN
|
|
PFunction Lauf;
|
|
|
|
while (FirstFunction!=Nil)
|
|
BEGIN
|
|
Lauf=FirstFunction->Next;
|
|
free(FirstFunction->Name);
|
|
free(FirstFunction->Definition);
|
|
free(FirstFunction);
|
|
FirstFunction=Lauf;
|
|
END
|
|
END
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
static void ResetSymbolDefines_ResetNode(SymbolPtr Node)
|
|
BEGIN
|
|
if (Node->Left !=Nil) ResetSymbolDefines_ResetNode(Node->Left);
|
|
if (Node->Right!=Nil) ResetSymbolDefines_ResetNode(Node->Right);
|
|
Node->Defined=False; Node->Used=False;
|
|
END
|
|
|
|
void ResetSymbolDefines(void)
|
|
BEGIN
|
|
|
|
if (FirstSymbol!=Nil) ResetSymbolDefines_ResetNode(FirstSymbol);
|
|
|
|
if (FirstLocSymbol!=Nil) ResetSymbolDefines_ResetNode(FirstLocSymbol);
|
|
END
|
|
|
|
void SetFlag(Boolean *Flag, char *Name, Boolean Wert)
|
|
BEGIN
|
|
*Flag=Wert; EnterIntSymbol(Name,(*Flag)?1:0,0,True);
|
|
END
|
|
|
|
void AddDefSymbol(char *Name, TempResult *Value)
|
|
BEGIN
|
|
PDefSymbol Neu;
|
|
|
|
Neu=FirstDefSymbol;
|
|
while (Neu!=Nil)
|
|
BEGIN
|
|
if (strcmp(Neu->SymName,Name)==0) return;
|
|
Neu=Neu->Next;
|
|
END
|
|
|
|
Neu=(PDefSymbol) malloc(sizeof(TDefSymbol));
|
|
Neu->Next=FirstDefSymbol;
|
|
Neu->SymName=strdup(Name);
|
|
Neu->Wert=(*Value);
|
|
FirstDefSymbol=Neu;
|
|
END
|
|
|
|
void RemoveDefSymbol(char *Name)
|
|
BEGIN
|
|
PDefSymbol Save,Lauf;
|
|
|
|
if (FirstDefSymbol==Nil) return;
|
|
|
|
if (strcmp(FirstDefSymbol->SymName,Name)==0)
|
|
BEGIN
|
|
Save=FirstDefSymbol; FirstDefSymbol=FirstDefSymbol->Next;
|
|
END
|
|
else
|
|
BEGIN
|
|
Lauf=FirstDefSymbol;
|
|
while ((Lauf->Next!=Nil) AND (strcmp(Lauf->Next->SymName,Name)!=0)) Lauf=Lauf->Next;
|
|
if (Lauf->Next==Nil) return;
|
|
Save=Lauf->Next; Lauf->Next=Lauf->Next->Next;
|
|
END
|
|
free(Save->SymName); free(Save);
|
|
END
|
|
|
|
void CopyDefSymbols(void)
|
|
BEGIN
|
|
PDefSymbol Lauf;
|
|
|
|
Lauf=FirstDefSymbol;
|
|
while (Lauf!=Nil)
|
|
BEGIN
|
|
switch (Lauf->Wert.Typ)
|
|
BEGIN
|
|
case TempInt: EnterIntSymbol(Lauf->SymName,Lauf->Wert.Contents.Int,0,True); break;
|
|
case TempFloat: EnterFloatSymbol(Lauf->SymName,Lauf->Wert.Contents.Float,True); break;
|
|
case TempString: EnterStringSymbol(Lauf->SymName,Lauf->Wert.Contents.Ascii,True); break;
|
|
default: break;
|
|
END
|
|
Lauf=Lauf->Next;
|
|
END
|
|
END
|
|
|
|
static void PrintSymbolDepth_SearchTree(SymbolPtr Lauf, LongInt SoFar,
|
|
LongInt *TreeMin, LongInt *TreeMax)
|
|
BEGIN
|
|
if (Lauf==Nil)
|
|
BEGIN
|
|
if (SoFar>*TreeMax) *TreeMax=SoFar;
|
|
if (SoFar<*TreeMin) *TreeMin=SoFar;
|
|
END
|
|
else
|
|
BEGIN
|
|
PrintSymbolDepth_SearchTree(Lauf->Right,SoFar+1,TreeMin,TreeMax);
|
|
PrintSymbolDepth_SearchTree(Lauf->Left,SoFar+1,TreeMin,TreeMax);
|
|
END
|
|
END
|
|
|
|
void PrintSymbolDepth(void)
|
|
BEGIN
|
|
LongInt TreeMin,TreeMax;
|
|
|
|
TreeMin=MaxLongInt; TreeMax=0;
|
|
PrintSymbolDepth_SearchTree(FirstSymbol,0,&TreeMin,&TreeMax);
|
|
fprintf(Debug," MinTree %ld\n", (long)TreeMin);
|
|
fprintf(Debug," MaxTree %ld\n", (long)TreeMax);
|
|
END
|
|
|
|
LongInt GetSectionHandle(char *SName_O, Boolean AddEmpt, LongInt Parent)
|
|
BEGIN
|
|
PCToken Lauf,Prev;
|
|
LongInt z;
|
|
String SName;
|
|
|
|
strmaxcpy(SName,SName_O,255); if (NOT CaseSensitive) NLS_UpString(SName);
|
|
|
|
Lauf=FirstSection; Prev=Nil; z=0;
|
|
while ((Lauf!=Nil) AND ((strcmp(Lauf->Name,SName)!=0) OR (Lauf->Parent!=Parent)))
|
|
BEGIN
|
|
z++; Prev=Lauf; Lauf=Lauf->Next;
|
|
END
|
|
|
|
if (Lauf==Nil)
|
|
if (AddEmpt)
|
|
BEGIN
|
|
Lauf=(PCToken) malloc(sizeof(TCToken));
|
|
Lauf->Parent=MomSectionHandle;
|
|
Lauf->Name=strdup(SName);
|
|
Lauf->Next=Nil;
|
|
InitChunk(&(Lauf->Usage));
|
|
if (Prev==Nil) FirstSection=Lauf; else Prev->Next=Lauf;
|
|
END
|
|
else z=(-2);
|
|
return z;
|
|
END
|
|
|
|
char *GetSectionName(LongInt Handle)
|
|
BEGIN
|
|
PCToken Lauf=FirstSection;
|
|
static char *Dummy="";
|
|
|
|
if (Handle==(-1)) return Dummy;
|
|
while ((Handle>0) AND (Lauf!=Nil))
|
|
BEGIN
|
|
Lauf=Lauf->Next; Handle--;
|
|
END
|
|
return (Lauf==Nil)?Dummy:Lauf->Name;
|
|
END
|
|
|
|
void SetMomSection(LongInt Handle)
|
|
BEGIN
|
|
LongInt z;
|
|
|
|
MomSectionHandle=Handle;
|
|
if (Handle<0) MomSection=Nil;
|
|
else
|
|
BEGIN
|
|
MomSection=FirstSection;
|
|
for (z=1; z<=Handle; z++)
|
|
if (MomSection!=Nil) MomSection=MomSection->Next;
|
|
END
|
|
END
|
|
|
|
void AddSectionUsage(LongInt Start,LongInt Length)
|
|
BEGIN
|
|
if ((ActPC!=SegCode) OR (MomSection==Nil)) return;
|
|
AddChunk(&(MomSection->Usage),Start,Length,False);
|
|
END
|
|
|
|
static void PrintSectionList_PSection(LongInt Handle, int Indent)
|
|
BEGIN
|
|
PCToken Lauf;
|
|
LongInt Cnt;
|
|
String h;
|
|
|
|
ChkStack();
|
|
if (Handle!=(-1))
|
|
BEGIN
|
|
strmaxcpy(h,Blanks(Indent<<1),255);
|
|
strmaxcat(h,GetSectionName(Handle),255);
|
|
WrLstLine(h);
|
|
END
|
|
Lauf=FirstSection; Cnt=0;
|
|
while (Lauf!=Nil)
|
|
BEGIN
|
|
if (Lauf->Parent==Handle) PrintSectionList_PSection(Cnt,Indent+1);
|
|
Lauf=Lauf->Next; Cnt++;
|
|
END
|
|
END
|
|
|
|
void PrintSectionList(void)
|
|
BEGIN
|
|
if (FirstSection==Nil) return;
|
|
|
|
NewPage(ChapDepth,True);
|
|
WrLstLine(getmessage(Num_ListSectionListHead1));
|
|
WrLstLine(getmessage(Num_ListSectionListHead2));
|
|
WrLstLine("");
|
|
PrintSectionList_PSection(-1,0);
|
|
END
|
|
|
|
void PrintDebSections(FILE *f)
|
|
BEGIN
|
|
PCToken Lauf;
|
|
LongInt Cnt,z,l,s;
|
|
|
|
Lauf=FirstSection; Cnt=0;
|
|
while (Lauf!=Nil)
|
|
BEGIN
|
|
fputs("\nInfo for Section ", f); ChkIO(10004);
|
|
fprintf(f, LongIntFormat, Cnt); ChkIO(10004);
|
|
fputc(' ', f); ChkIO(10004);
|
|
fputs(GetSectionName(Cnt), f); ChkIO(10004);
|
|
fputc(' ', f); ChkIO(10004);
|
|
fprintf(f, LongIntFormat, Lauf->Parent); ChkIO(10004);
|
|
fputc('\n', f); ChkIO(10004);
|
|
for (z=0; z<Lauf->Usage.RealLen; z++)
|
|
BEGIN
|
|
l=Lauf->Usage.Chunks[z].Length;
|
|
s=Lauf->Usage.Chunks[z].Start;
|
|
fprintf(f,"%s",HexString(s,0)); ChkIO(10004);
|
|
if (l==1) fprintf(f,"\n"); else fprintf(f,"-%s\n",HexString(s+l-1,0)); ChkIO(10004);
|
|
END
|
|
Lauf=Lauf->Next;
|
|
Cnt++;
|
|
END
|
|
END
|
|
|
|
void ClearSectionList(void)
|
|
BEGIN
|
|
PCToken Tmp;
|
|
|
|
while (FirstSection!=Nil)
|
|
BEGIN
|
|
Tmp=FirstSection;
|
|
free(Tmp->Name);
|
|
ClearChunk(&(Tmp->Usage));
|
|
FirstSection=Tmp->Next; free(Tmp);
|
|
END
|
|
END
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
|
|
static void PrintCrossList_PNode(SymbolPtr Node)
|
|
BEGIN
|
|
int FileZ;
|
|
PCrossRef Lauf;
|
|
String LinePart,LineAcc;
|
|
String h,h2;
|
|
TempResult t;
|
|
|
|
if (Node->RefList==Nil) return;
|
|
|
|
ConvertSymbolVal(&(Node->SymWert),&t);
|
|
strcpy(h," (=");
|
|
StrSym(&t,False,h2); strmaxcat(h,h2,255);
|
|
strmaxcat(h,",",255);
|
|
strmaxcat(h,GetFileName(Node->FileNum),255);
|
|
strmaxcat(h,":",255);
|
|
sprintf(h2, LongIntFormat, Node->LineNum); strmaxcat(h,h2,255);
|
|
strmaxcat(h,"):",255);
|
|
if (Node->Attribute!=(-1))
|
|
BEGIN
|
|
strmaxprep(h,"] ",255);
|
|
strmaxprep(h,GetSectionName(Node->Attribute),255);
|
|
strmaxprep(h," [",255);
|
|
END
|
|
|
|
strmaxprep(h,Node->SymName,255);
|
|
strmaxprep(h,getmessage(Num_ListCrossSymName),255);
|
|
WrLstLine(h);
|
|
|
|
for (FileZ=0; FileZ<GetFileCount(); FileZ++)
|
|
BEGIN
|
|
Lauf=Node->RefList;
|
|
|
|
while ((Lauf!=Nil) AND (Lauf->FileNum!=FileZ)) Lauf=Lauf->Next;
|
|
|
|
if (Lauf!=Nil)
|
|
BEGIN
|
|
strcpy(h," ");
|
|
strmaxcat(h,getmessage(Num_ListCrossFileName),255);
|
|
strmaxcat(h,GetFileName(FileZ),255);
|
|
strmaxcat(h," :",255);
|
|
WrLstLine(h);
|
|
strcpy(LineAcc," ");
|
|
while (Lauf!=Nil)
|
|
BEGIN
|
|
sprintf(LinePart,"%5ld", (long)Lauf->LineNum);
|
|
strmaxcat(LineAcc,LinePart,255);
|
|
if (Lauf->OccNum!=1)
|
|
BEGIN
|
|
sprintf(LinePart,"(%2ld)", (long)Lauf->OccNum);
|
|
strmaxcat(LineAcc,LinePart,255);
|
|
END
|
|
else strmaxcat(LineAcc," ",255);
|
|
if (strlen(LineAcc)>=72)
|
|
BEGIN
|
|
WrLstLine(LineAcc); strcpy(LineAcc," ");
|
|
END
|
|
Lauf=Lauf->Next;
|
|
END
|
|
if (strcmp(LineAcc," ")!=0) WrLstLine(LineAcc);
|
|
END
|
|
END
|
|
WrLstLine("");
|
|
END
|
|
|
|
static void PrintCrossList_PrintNode(SymbolPtr Node)
|
|
BEGIN
|
|
if (Node==Nil) return;
|
|
|
|
PrintCrossList_PrintNode(Node->Left);
|
|
|
|
PrintCrossList_PNode(Node);
|
|
|
|
PrintCrossList_PrintNode(Node->Right);
|
|
END
|
|
|
|
void PrintCrossList(void)
|
|
BEGIN
|
|
|
|
WrLstLine("");
|
|
WrLstLine(getmessage(Num_ListCrossListHead1));
|
|
WrLstLine(getmessage(Num_ListCrossListHead2));
|
|
WrLstLine("");
|
|
PrintCrossList_PrintNode(FirstSymbol);
|
|
WrLstLine("");
|
|
END
|
|
|
|
static void ClearCrossList_CNode(SymbolPtr Node)
|
|
BEGIN
|
|
PCrossRef Lauf;
|
|
|
|
if (Node->Left!=Nil) ClearCrossList_CNode(Node->Left);
|
|
|
|
if (Node!=Nil)
|
|
while (Node->RefList!=Nil)
|
|
BEGIN
|
|
Lauf=Node->RefList->Next;
|
|
free(Node->RefList);
|
|
Node->RefList=Lauf;
|
|
END
|
|
|
|
if (Node->Right!=Nil) ClearCrossList_CNode(Node->Right);
|
|
END
|
|
|
|
void ClearCrossList(void)
|
|
BEGIN
|
|
ClearCrossList_CNode(FirstSymbol);
|
|
END
|
|
|
|
LongInt GetLocHandle(void)
|
|
BEGIN
|
|
return LocHandleCnt++;
|
|
END
|
|
|
|
void PushLocHandle(LongInt NewLoc)
|
|
BEGIN
|
|
PLocHandle NewLocHandle;
|
|
|
|
NewLocHandle=(PLocHandle) malloc(sizeof(TLocHeap));
|
|
NewLocHandle->Cont=MomLocHandle;
|
|
NewLocHandle->Next=FirstLocHandle;
|
|
FirstLocHandle=NewLocHandle; MomLocHandle=NewLoc;
|
|
END
|
|
|
|
void PopLocHandle(void)
|
|
BEGIN
|
|
PLocHandle OldLocHandle;
|
|
|
|
OldLocHandle=FirstLocHandle;
|
|
if (OldLocHandle==Nil) return;
|
|
MomLocHandle=OldLocHandle->Cont;
|
|
FirstLocHandle=OldLocHandle->Next;
|
|
free(OldLocHandle);
|
|
END
|
|
|
|
void ClearLocStack()
|
|
BEGIN
|
|
while (MomLocHandle!=(-1)) PopLocHandle();
|
|
END
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
static PRegDef LookupReg(char *Name, Boolean CreateNew)
|
|
BEGIN
|
|
PRegDef Run,Neu,Prev;
|
|
int cmperg=0;
|
|
|
|
Prev=Nil; Run=FirstRegDef;
|
|
while ((Run!=Nil) AND ((cmperg=strcmp(Run->Orig,Name))!=0))
|
|
BEGIN
|
|
Prev=Run; Run=(cmperg<0) ? Run->Left : Run->Right;
|
|
END
|
|
if ((Run==Nil) AND (CreateNew))
|
|
BEGIN
|
|
Neu=(PRegDef) malloc(sizeof(TRegDef));
|
|
Neu->Orig=strdup(Name);
|
|
Neu->Left=Neu->Right=Nil;
|
|
Neu->Defs=Nil;
|
|
Neu->DoneDefs=Nil;
|
|
if (Prev==Nil) FirstRegDef=Neu;
|
|
else if (cmperg<0) Prev->Left=Neu; else Prev->Right=Neu;
|
|
return Neu;
|
|
END
|
|
else return Run;
|
|
END
|
|
|
|
void AddRegDef(char *Orig_N, char *Repl_N)
|
|
BEGIN
|
|
PRegDef Node;
|
|
PRegDefList Neu;
|
|
String Orig,Repl;
|
|
|
|
strmaxcpy(Orig,Orig_N,255); strmaxcpy(Repl,Repl_N,255);
|
|
if (NOT CaseSensitive)
|
|
BEGIN
|
|
NLS_UpString(Orig); NLS_UpString(Repl);
|
|
END
|
|
if (NOT ChkSymbName(Orig))
|
|
BEGIN
|
|
WrXError(1020,Orig); return;
|
|
END
|
|
if (NOT ChkSymbName(Repl))
|
|
BEGIN
|
|
WrXError(1020,Repl); return;
|
|
END
|
|
Node=LookupReg(Orig,True);
|
|
if ((Node->Defs!=Nil) AND (Node->Defs->Section==MomSectionHandle))
|
|
WrXError(1000,Orig);
|
|
else
|
|
BEGIN
|
|
Neu=(PRegDefList) malloc(sizeof(TRegDefList));
|
|
Neu->Next=Node->Defs; Neu->Section=MomSectionHandle;
|
|
Neu->Value=strdup(Repl);
|
|
Neu->Used=False;
|
|
Node->Defs=Neu;
|
|
END
|
|
END
|
|
|
|
Boolean FindRegDef(char *Name_N, char **Erg)
|
|
BEGIN
|
|
LongInt Sect;
|
|
PRegDef Node;
|
|
PRegDefList Def;
|
|
String Name;
|
|
|
|
if (*Name_N=='[') return FALSE;
|
|
|
|
strmaxcpy(Name,Name_N,255);
|
|
|
|
if (NOT GetSymSection(Name,&Sect)) return False;
|
|
if (NOT CaseSensitive) NLS_UpString(Name);
|
|
Node=LookupReg(Name,False);
|
|
if (Node==Nil) return False;
|
|
Def=Node->Defs;
|
|
if (Sect!=-2)
|
|
while ((Def!=Nil) AND (Def->Section!=Sect)) Def=Def->Next;
|
|
if (Def==Nil) return False;
|
|
else
|
|
BEGIN
|
|
*Erg=Def->Value; Def->Used=True; return True;
|
|
END
|
|
END
|
|
|
|
static void TossRegDefs_TossSingle(PRegDef Node, LongInt Sect)
|
|
BEGIN
|
|
PRegDefList Tmp;
|
|
|
|
if (Node==Nil) return; ChkStack();
|
|
|
|
if ((Node->Defs!=Nil) AND (Node->Defs->Section==Sect))
|
|
BEGIN
|
|
Tmp=Node->Defs; Node->Defs=Node->Defs->Next;
|
|
Tmp->Next=Node->DoneDefs; Node->DoneDefs=Tmp;
|
|
END
|
|
|
|
TossRegDefs_TossSingle(Node->Left,Sect);
|
|
TossRegDefs_TossSingle(Node->Right,Sect);
|
|
END
|
|
|
|
void TossRegDefs(LongInt Sect)
|
|
BEGIN
|
|
TossRegDefs_TossSingle(FirstRegDef,Sect);
|
|
END
|
|
|
|
static void ClearRegDefList(PRegDefList Start)
|
|
BEGIN
|
|
PRegDefList Tmp;
|
|
|
|
while (Start!=Nil)
|
|
BEGIN
|
|
Tmp=Start; Start=Start->Next;
|
|
free(Tmp->Value);
|
|
free(Tmp);
|
|
END
|
|
END
|
|
|
|
static void CleanupRegDefs_CleanupNode(PRegDef Node)
|
|
BEGIN
|
|
if (Node==Nil) return; ChkStack();
|
|
ClearRegDefList(Node->DoneDefs); Node->DoneDefs=Nil;
|
|
CleanupRegDefs_CleanupNode(Node->Left);
|
|
CleanupRegDefs_CleanupNode(Node->Right);
|
|
END
|
|
|
|
void CleanupRegDefs(void)
|
|
BEGIN
|
|
CleanupRegDefs_CleanupNode(FirstRegDef);
|
|
END
|
|
|
|
static void ClearRegDefs_ClearNode(PRegDef Node)
|
|
BEGIN
|
|
if (Node==Nil) return; ChkStack();
|
|
ClearRegDefList(Node->Defs); Node->Defs=Nil;
|
|
ClearRegDefList(Node->DoneDefs); Node->DoneDefs=Nil;
|
|
ClearRegDefs_ClearNode(Node->Left); ClearRegDefs_ClearNode(Node->Right);
|
|
free(Node->Orig);
|
|
free(Node);
|
|
END
|
|
|
|
void ClearRegDefs(void)
|
|
BEGIN
|
|
ClearRegDefs_ClearNode(FirstRegDef);
|
|
END
|
|
|
|
static void PrintRegDefs_PNode(PRegDef Node, char *buf, LongInt *Sum, LongInt *USum)
|
|
BEGIN
|
|
PRegDefList Lauf;
|
|
String tmp,tmp2;
|
|
|
|
for (Lauf=Node->DoneDefs; Lauf!=Nil; Lauf=Lauf->Next)
|
|
BEGIN
|
|
if (Lauf->Section!=-1)
|
|
sprintf(tmp2,"[%s]",GetSectionName(Lauf->Section));
|
|
else
|
|
*tmp2='\0';
|
|
sprintf(tmp,"%c%s%s --> %s",(Lauf->Used) ? ' ' : '*',Node->Orig,tmp2,Lauf->Value);
|
|
if (strlen(tmp)>cwidth-3)
|
|
BEGIN
|
|
if (*buf!='\0') WrLstLine(buf); *buf='\0'; WrLstLine(tmp);
|
|
END
|
|
else
|
|
BEGIN
|
|
strmaxcat(tmp,Blanks(cwidth-3-strlen(tmp)),255);
|
|
if (*buf=='\0') strcpy(buf,tmp);
|
|
else
|
|
BEGIN
|
|
strcat(buf," | "); strcat(buf,tmp);
|
|
WrLstLine(buf); *buf='\0';
|
|
END
|
|
END
|
|
(*Sum)++; if (NOT Lauf->Used) (*USum)++;
|
|
END
|
|
END
|
|
|
|
static void PrintRegDefs_PrintSingle(PRegDef Node, char *buf, LongInt *Sum, LongInt *USum)
|
|
BEGIN
|
|
if (Node==Nil) return; ChkStack();
|
|
|
|
PrintRegDefs_PrintSingle(Node->Left,buf,Sum,USum);
|
|
PrintRegDefs_PNode(Node,buf,Sum,USum);
|
|
PrintRegDefs_PrintSingle(Node->Right,buf,Sum,USum);
|
|
END
|
|
|
|
void PrintRegDefs(void)
|
|
BEGIN
|
|
String buf;
|
|
LongInt Sum,USum;
|
|
|
|
if (FirstRegDef==Nil) return;
|
|
|
|
NewPage(ChapDepth,True);
|
|
WrLstLine(getmessage(Num_ListRegDefListHead1));
|
|
WrLstLine(getmessage(Num_ListRegDefListHead2));
|
|
WrLstLine("");
|
|
|
|
*buf='\0'; Sum=0; USum=0;
|
|
ActPageWidth=(PageWidth==0) ? 80 : PageWidth;
|
|
cwidth=ActPageWidth>>1;
|
|
PrintRegDefs_PrintSingle(FirstRegDef,buf,&Sum,&USum);
|
|
|
|
if (*buf!='\0') WrLstLine(buf);
|
|
WrLstLine("");
|
|
sprintf(buf,"%7ld%s",
|
|
(long) Sum,
|
|
getmessage((Sum==1)?Num_ListRegDefSumMsg:Num_ListRegDefSumsMsg));
|
|
WrLstLine(buf);
|
|
sprintf(buf,"%7ld%s",
|
|
(long)USum,
|
|
getmessage((USum==1)?Num_ListRegDefUSumMsg:Num_ListRegDefUSumsMsg));
|
|
WrLstLine("");
|
|
END
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
void ClearCodepages(void)
|
|
BEGIN
|
|
PTransTable Old;
|
|
|
|
while (TransTables!=Nil)
|
|
BEGIN
|
|
Old=TransTables; TransTables=Old->Next;
|
|
free(Old->Name); free(Old->Table); free(Old);
|
|
END
|
|
END
|
|
|
|
void PrintCodepages(void)
|
|
BEGIN
|
|
char buf[500];
|
|
PTransTable Table;
|
|
int z,cnt,cnt2;
|
|
|
|
NewPage(ChapDepth,True);
|
|
WrLstLine(getmessage(Num_ListCodepageListHead1));
|
|
WrLstLine(getmessage(Num_ListCodepageListHead2));
|
|
WrLstLine("");
|
|
|
|
cnt2=0;
|
|
for (Table=TransTables; Table!=Nil; Table=Table->Next)
|
|
BEGIN
|
|
for (z=cnt=0; z<256; z++)
|
|
if (Table->Table[z]!=z) cnt++;
|
|
sprintf(buf,"%s (%d%s)",Table->Name,cnt,
|
|
getmessage((cnt==1) ? Num_ListCodepageChange : Num_ListCodepagePChange));
|
|
WrLstLine(buf);
|
|
cnt2++;
|
|
END
|
|
WrLstLine("");
|
|
sprintf(buf,"%d%s",cnt2,
|
|
getmessage((cnt2==1) ? Num_ListCodepageSumMsg : Num_ListCodepageSumsMsg));
|
|
END
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
void asmpars_init(void)
|
|
BEGIN
|
|
FirstDefSymbol=Nil;
|
|
FirstFunction=Nil;
|
|
BalanceTree=False;
|
|
IntMins[(int)Int32]--;
|
|
IntMins[(int)SInt32]--;
|
|
#ifdef HAS64
|
|
IntMins[(int)Int64]--;
|
|
#endif
|
|
END
|
|
|