diff options
author | Patrick McHardy <kaber@trash.net> | 2011-03-03 18:44:02 +0100 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2011-03-03 18:44:02 +0100 |
commit | 1f3e92989e4b9f3e00aaf7729b3dd2f7c044667e (patch) | |
tree | 866b0bbd1d7257634098e05f33781d259614b7b6 /asmpars.c |
Import ASL
Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'asmpars.c')
-rw-r--r-- | asmpars.c | 3822 |
1 files changed, 3822 insertions, 0 deletions
diff --git a/asmpars.c b/asmpars.c new file mode 100644 index 0000000..34b2b9b --- /dev/null +++ b/asmpars.c @@ -0,0 +1,3822 @@ +/* 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 + |