3 * Iter Vehemens ad Necem (IVAN)
4 * Copyright (C) Timo Kiviluoto
5 * Released under the GNU General
8 * See LICENSING which should be included
9 * along with this file for more details
12 #ifndef __FELIB_PARSE_H__
13 #define __FELIB_PARSE_H__
22 // ////////////////////////////////////////////////////////////////////////// //
26 struct InputFileSaved
;
29 using valuemap
= std::map
<festring
, sLong
>;
30 using InputFileGetVarFn
= festring (*) (TextInput
*fl
, cfestring
&name
);
33 // ////////////////////////////////////////////////////////////////////////// //
36 TextInput (const valuemap
*aValueMap
=0);
38 void setup (const valuemap
*aValueMap
);
41 virtual ~TextInput ();
43 virtual cfestring
&GetFileName () const = 0;
44 virtual truth
IsOpen () = 0;
46 virtual void Close (); // for dtor
49 void UngetChar (int ch
);
51 festring
ReadWord (truth abortOnEOF
=true);
52 truth
ReadWord (festring
&str
, truth abortOnEOF
=true); // returns `false` on EOF
53 char ReadLetter (truth abortOnEOF
=true);
54 sLong
ReadNumber (int CallLevel
=HIGHEST
, truth PreserveTerminator
=false, truth
*wasCloseBrc
=0);
55 festring
ReadStringOrNumber (sLong
*num
, truth
*isString
, truth PreserveTerminator
=false, truth
*wasCloseBrc
=0);
56 sLong
ReadNumberKeepStr (int CallLevel
=HIGHEST
, truth PreserveTerminator
=false, truth
*wasCloseBrc
=0);
57 festring
ReadStringOrNumberKeepStr (sLong
*num
, truth
*isString
, truth PreserveTerminator
=false, truth
*wasCloseBrc
=0);
62 festring
getVar (cfestring
&name
);
63 void setVar (cfestring
&name
, cfestring
&value
);
64 truth
delVar (cfestring
&name
);
66 void setGetVarCB (InputFileGetVarFn cb
) { mGetVar
= cb
; }
68 void die (cfestring
&msg
);
70 void skipBlanks (); // comments too
72 int countArrayItems (char echar
);
74 inline int TokenLine () const { return mTokenLine
; }
75 inline int CurrentLine () const { return mCurrentLine
; }
77 // when reading a number, and `mCollectingNumStr` flag is set, this will be filled
78 inline cfestring
& numStr () const { return mNumStr
; }
80 int gotCharSkipComment (int ch
, truth allowSingleLineComments
=true); // just read `ch`, skip possible comment; returns `ch` or -1
83 template<typename numtype
> festring
ReadNumberIntr (int CallLevel
, numtype
*num
, truth
*isString
, truth allowStr
, truth PreserveTerminator
, truth
*wasCloseBrc
, truth allowFloats
);
85 festring
findVar (cfestring
&name
, truth
*found
) const;
86 truth
readWordIntr (festring
&String
, truth abortOnEOF
); // returns `false` on EOF
88 festring
readCondition (festring
&token
, int prio
, truth skipIt
);
91 virtual int realGetChar () = 0;
92 virtual truth
isRealEof () = 0;
94 // used to save/restore parsing positions
95 virtual sLong
realGetPos () = 0;
96 virtual void realSetPos (sLong apos
) = 0;
99 enum { MaxUngetChars
= 4 };
100 typedef std::map
<festring
, festring
> VarMap
;
103 const valuemap
*ValueMap
;
105 truth lastWordWasString
;
107 InputFileGetVarFn mGetVar
;
108 std::stack
<int> mIfStack
;
109 int mCharBuf
[MaxUngetChars
];
113 festring mNumStr
; // when reading a number, and `mCollectingNumStr` flag is set, this will be filled
114 truth mCollectingNumStr
;
115 truth mAllowFloatNums
;
117 friend InputFileSaved
;
121 // ////////////////////////////////////////////////////////////////////////// //
122 class TextInputFile
: public TextInput
{
124 TextInputFile (cfestring
&FileName
, const valuemap
*aValueMap
=0, truth AbortOnErr
=true);
125 virtual ~TextInputFile ();
127 virtual cfestring
&GetFileName () const override
;
128 virtual truth
IsOpen () override
;
129 virtual void Close () override
;
132 virtual int realGetChar () override
;
133 virtual truth
isRealEof () override
;
135 virtual sLong
realGetPos () override
;
136 virtual void realSetPos (sLong apos
) override
;
143 // ////////////////////////////////////////////////////////////////////////// //
144 class MemTextFile
: public TextInput
{
146 MemTextFile (cfestring
&afname
, cfestring
&str
, const valuemap
*aValueMap
=0);
147 MemTextFile (cfestring
&afname
, int stline
, cfestring
&str
, const valuemap
*aValueMap
=0);
148 virtual ~MemTextFile ();
150 virtual cfestring
&GetFileName () const override
;
151 virtual truth
IsOpen () override
;
152 virtual void Close () override
;
155 virtual int realGetChar () override
;
156 virtual truth
isRealEof () override
;
158 virtual sLong
realGetPos () override
;
159 virtual void realSetPos (sLong apos
) override
;
169 // ////////////////////////////////////////////////////////////////////////// //
170 // `rand()` returns `add+RAND_N(rnd)`
171 // `inRange()` returns `true` if `rand()` is in [rmin..rmax] (inclusive!)
173 // RCField = { add: num; rnd: num; rmin: num; rmax: num; }
174 // any field may absent
177 struct RandomChance
{
180 sLong rmin
= 0, rmax
= 0;
182 inline void clear () { add
= rnd
= rmin
= rmax
= 0; }
183 inline sLong
rand () const { return add
+RAND_N(rnd
); }
184 // if `rnd` is zero, assume "no chances"
185 inline truth
inRange () const { if (rnd
> 0) { auto v
= rand(); return (v
>= rmin
&& v
<= rmax
); } return false; }
189 inline void ReadData (char &Type
, TextInput
&infile
) { Type
= infile
.ReadNumber(); }
190 inline void ReadData (uChar
&Type
, TextInput
&infile
) { Type
= infile
.ReadNumber(); }
191 inline void ReadData (short &Type
, TextInput
&infile
) { Type
= infile
.ReadNumber(); }
192 inline void ReadData (uShort
&Type
, TextInput
&infile
) { Type
= infile
.ReadNumber(); }
193 //inline void ReadData (sLong &Type, inputfile &SaveFile) { Type = SaveFile.ReadNumber(); } //k8:64
194 inline void ReadData (feuLong
&Type
, TextInput
&infile
) { Type
= infile
.ReadNumber(); }
195 inline void ReadData (int &Type
, TextInput
&infile
) { Type
= infile
.ReadNumber(); }
196 inline void ReadData (packv2
&Type
, TextInput
&infile
) { Type
= infile
.ReadVector2d(); }
197 inline void ReadData (v2
&Type
, TextInput
&infile
) { Type
= infile
.ReadVector2d(); }
198 inline void ReadData (rect
&Type
, TextInput
&infile
) { Type
= infile
.ReadRect(); }
199 inline void ReadData (float &Type
, TextInput
&infile
) { Type
= infile
.ReadFloat(); }
201 void ReadData (festring
&, TextInput
&);
202 void ReadData (fearray
<sLong
> &, TextInput
&);
203 void ReadData (fearray
<festring
> &, TextInput
&);
204 void ReadData (RandomChance
&rc
, TextInput
&fl
);
206 template <class type
> void ReadData (fearray
<type
> &Array
, TextInput
&infile
) {
209 infile
.ReadWord(Word
);
213 ReadData(Array
.Data
[0], infile
);
216 // more than one element
217 typedef typename fearray
<type
>::sizetype sizetype
;
219 // unknown number of elements?
221 infile
.ReadWord(Word
);
222 if (Word
!= "{") ABORT("Array syntax error \"%s\" found in file %s, line %d!", Word
.CStr(), infile
.GetFileName().CStr(), infile
.TokenLine());
223 //fprintf(stderr, "counting array items; file: '%s'; line: %u\n", SaveFile.GetFileName().CStr(), SaveFile.TokenLine());
224 int count
= infile
.countArrayItems('}');
226 if (count
< 1) ABORT("Array count error found in file %s, line %d!", infile
.GetFileName().CStr(), infile
.TokenLine());
228 //fprintf(stderr, "counted %u array items; file: '%s'; line: %u\n", Size, SaveFile.GetFileName().CStr(), SaveFile.TokenLine());
230 if (Word
!= "=") ABORT("Array syntax error: '=', '==' or ':=' expected in file %s, line %u!", infile
.GetFileName().CStr(), infile
.TokenLine());
231 infile
.ReadWord(Word
);
232 if (Word
!= "{") ABORT("Array syntax error \"%s\" found in file %s, line %u!", Word
.CStr(), infile
.GetFileName().CStr(), infile
.TokenLine());
233 Size
= infile
.ReadNumber();
234 int count
= infile
.countArrayItems('}');
235 if (count
< 1) ABORT("Array count error found in file %s, line %d!", infile
.GetFileName().CStr(), infile
.TokenLine());
236 //HACK: 2 for vectors, 4 for rects
237 //if ((sizetype)count != Size && (sizetype)count/2 != Size && (sizetype)count/4 != Size) ABORT("Array count error (%u != %d) found in file %s, line %d!", Size, count, SaveFile.GetFileName().CStr(), SaveFile.TokenLine());
238 if ((sizetype
)count
!= Size
) ABORT("Array count error (%u != %d) found in file %s, line %d!", Size
, count
, infile
.GetFileName().CStr(), infile
.TokenLine());
240 Array
.Allocate(Size
);
241 for (sizetype c
= 0; c
< Size
; ++c
) ReadData(Array
.Data
[c
], infile
);
242 if (infile
.ReadWord() != "}") ABORT("Illegal array terminator \"%s\" encountered in file %s, line %u!", Word
.CStr(), infile
.GetFileName().CStr(), infile
.TokenLine());
246 // ////////////////////////////////////////////////////////////////////////// //
247 struct EventHandlerSource
{
255 struct EventHandlerMap
{
257 //EventHandlerMap (const EventHandlerMap &); // disable copying
261 virtual ~EventHandlerMap ();
265 // "on" skipped, expecting type
266 void collectSource (std::stack
<TextInput
*> &infStack
, TextInput
**iff
);
268 // "on" skipped, expecting type
269 void collectSource (TextInput
&iff
);
271 // can return `nullptr`
272 TextInput
*openHandler (cfestring
&atype
, const valuemap
*aValueMap
=0) const;
275 std::map
<festring
, EventHandlerSource
> mMap
;
279 festring
collectSourceCode (std::stack
<TextInput
*> &infStack
, TextInput
**iff
);
280 EventHandlerSource
collectEventHandlerSource (std::stack
<TextInput
*> &infStack
, TextInput
**iff
);