ALib C++ Library
Library Version: 2412 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
strings.hpp
Go to the documentation of this file.
1//==================================================================================================
2/// \file
3/// This header file is part of module \alib_expressions of the \aliblong.
4///
5/// \emoji :copyright: 2013-2024 A-Worx GmbH, Germany.
6/// Published under \ref mainpage_license "Boost Software License".
7//==================================================================================================
8#ifndef HPP_ALIB_EXPRESSIONS_PLUGINS_STRINGS
9#define HPP_ALIB_EXPRESSIONS_PLUGINS_STRINGS
10#pragma once
12
13namespace alib { namespace expressions { namespace plugins {
14
15
16//==================================================================================================
17/// This built-in \alib{expressions;CompilerPlugin} of \alib_expressions_nl
18/// compiles identifiers, functions and operators with character string-type operands or return
19/// types.
20///
21/// By default, this plug-in is \alib{expressions;Compiler::CfgBuiltInPlugins;automatically created}
22/// and inserted into each instance of class \alib{expressions;Compiler} with the invocation of
23/// \alib{expressions::Compiler;SetupDefaults}.
24///
25/// <b>Constants:</b><br>
26///
27/// Type | Name | Min. Abbreviation | Description
28/// --------|-------------|-------------------|--------------
29/// String |\b NewLine | nl | System dependent new line character combination ( <c>"\n"</c> or <c>"\r\n"</c>).
30/// String |\b Tabulator | tab | String with single tabulator character (<c>"\t"</c>).
31///
32/// <br>
33/// <b>Functions:</b><br>
34///
35/// Note: All identifier and function names are defined case insensitive.
36///
37/// Return Type | Name | Min. Abbreviation| Signature | Description
38/// ---------------|-----------|------------------|-----------|-------------
39/// String | \b String | str | ... | Creates and returns a string representation of the arguments, concatenated from left to right.
40/// String | \b ToUpper | tu | String | Converts all appropriate characters of a string to upper case letters. This function is aliased by unary operator <c>'+'</c>.
41/// String | \b ToLower | tl | String | Converts all appropriate characters of a string to lower case letters. This function is aliased by unary operator <c>'-'</c>.
42/// Boolean | \b Compare | comp | String, String | Returns \c 0 if strings are equal, a negative value if the first string is "smaller" than the second and a positive otherwise.
43/// Boolean | \b Compare | comp | String, String, Boolean | Same as Compare(String,String) if third parameter is \c false. If it is \c true letter case is ignored.
44/// Boolean | \b StartsWith | sw | String, String | Tests if the first given string starts with the second. Comparison is case-sensitive.
45/// Boolean | \b StartsWith | sw | String, String, Boolean | Tests if the first given string starts with the second. The third parameter is \c true, letter case is ignored.
46/// Boolean | \b EndsWith | ew | String, String | Tests if the first given string ends with the second. Comparison is case-sensitive.
47/// Boolean | \b EndsWith | ew | String, String, Boolean | Tests if the first given string ends with the second. The third parameter is \c true, letter case is ignored.
48/// String | \b Substring | subs | String, Integer | Returns the substring, starting at given position (2nd argument) to the end of the string..
49/// String | \b Substring | subs | String, Integer, Integer| Returns the substring, starting at given position (2nd argument) with the given length (3rd argument).
50/// Integer | \b IndexOf | indo | String, String | Searches the first occurrence of the second string in the first. Returns the position if found, otherwise \c -1.
51/// Integer | \b Count | count | String, String | Counts the number of occurrences of the second string in the first.
52/// String | \b Replace | repl | String, String, String | Returns a copy of the 1st argument, with occurrences of 2nd argument replaced by 3rd argument.
53/// String | \b Repeat | repeat | String, Integer | Returns 1st argument concatenated \e N times (2nd argument).
54/// String | \b Token | tok | String, String, Integer | Parses tokens separated by character (2nd argument) in string (1st argument) an returns the n-th (3rd argument).
55/// String | \b Trim | trim | String | Trims the string at both sides by removing the following whitespace characters: <c>' '</c>, <c>'\\n'</c>, <c>'\\r'</c> and <c>'\\t'</c>.
56/// String | \b Trim | trim | String, String | Trims the string at both sides by removing the whitespace characters listed in the second string.
57/// String | \b TrimStart | trims | String | Trims the string at the start by removing the following whitespace characters: <c>' '</c>, <c>'\\n'</c>, <c>'\\r'</c> and <c>'\\t'</c>.
58/// String | \b TrimStart | trims | String, String | Trims the string at the start by removing the whitespace characters listed in the second string.
59/// String | \b TrimEnd | trime | String | Trims the string at the end by removing the following whitespace characters: <c>' '</c>, <c>'\\n'</c>, <c>'\\r'</c> and <c>'\\t'</c>.
60/// String | \b TrimEnd | trime | String, String | Trims the string at the end by removing the whitespace characters listed in the second string.
61/// Integer | \b Integer | int | String | Parses an integral value from the string. Allows decimal, hexadecimal, octal and binary formats. Literal prefixes default to <c>'0x'</c>, <c>'0o'</c> and <c>'0b'</c>, which can be changed by configuring object \alib{lang::format::Formatter;DefaultNumberFormat} of field \doxlinkproblem{structalib_1_1expressions_1_1Scope.html;aebf2cd4ff8a2611de06368fccfd3ef5b;Scope::Formatter;expressions::Scope::Formatter}.
62/// Float | \b Float | float | String | Parses a floating point value from the string. Allows scientific format and change of decimal point character by configuring object \alib{lang::format::Formatter;DefaultNumberFormat} of field \doxlinkproblem{structalib_1_1expressions_1_1Scope.html;aebf2cd4ff8a2611de06368fccfd3ef5b;Scope::Formatter;expressions::Scope::Formatter}.
63/// String | \b Hexadecimal | hex | Integer | Converts an integral value to a hexadecimal string representation. Format options are available with object \alib{lang::format::Formatter;DefaultNumberFormat} of field \doxlinkproblem{structalib_1_1expressions_1_1Scope.html;aebf2cd4ff8a2611de06368fccfd3ef5b;Scope::Formatter;expressions::Scope::Formatter}. The literal prefix (e.g., \c "0x") is not written.
64/// String | \b Hexadecimal | hex | Integer, Integer | Converts an integral value to a hexadecimal string representation of the given output width (2nd argument). Format options are available with object \alib{lang::format::Formatter;DefaultNumberFormat} of field \doxlinkproblem{structalib_1_1expressions_1_1Scope.html;aebf2cd4ff8a2611de06368fccfd3ef5b;Scope::Formatter;expressions::Scope::Formatter}. The literal prefix (e.g., \c "0x") is not written.
65/// String | \b Octal | oct | Integer | Converts an integral value to a binary string representation. Format options are available with object \alib{lang::format::Formatter;DefaultNumberFormat} of field \doxlinkproblem{structalib_1_1expressions_1_1Scope.html;aebf2cd4ff8a2611de06368fccfd3ef5b;Scope::Formatter;expressions::Scope::Formatter}. The literal prefix (e.g., \c "0x") is not written.
66/// String | \b Octal | oct | Integer, Integer | Converts an integral value to a binary string representation of the given output width (2nd argument). Format options are available with object \alib{lang::format::Formatter;DefaultNumberFormat} of field \doxlinkproblem{structalib_1_1expressions_1_1Scope.html;aebf2cd4ff8a2611de06368fccfd3ef5b;Scope::Formatter;expressions::Scope::Formatter}. The literal prefix (e.g., \c "0x") is not written.
67/// String | \b Binary | bin | Integer | Converts an integral value to an octal string representation. Format options are available with object \alib{lang::format::Formatter;DefaultNumberFormat} of field \doxlinkproblem{structalib_1_1expressions_1_1Scope.html;aebf2cd4ff8a2611de06368fccfd3ef5b;Scope::Formatter;expressions::Scope::Formatter}. The literal prefix (e.g., \c "0x") is not written.
68/// String | \b Binary | bin | Integer, Integer | Converts an integral value to an octal string representation of the given output width (2nd argument). Format options are available with object \alib{lang::format::Formatter;DefaultNumberFormat} of field \doxlinkproblem{structalib_1_1expressions_1_1Scope.html;aebf2cd4ff8a2611de06368fccfd3ef5b;Scope::Formatter;expressions::Scope::Formatter}. The literal prefix (e.g., \c "0x") is not written.
69/// String | \b Format | format | String, ... | Formats the given variadic parameters according to the given format string. See notes below, for further information.
70/// Boolean | \b WildCardMatch | wcm | String, String | Matches a string against a wildcard pattern. See notes below, for further information.
71/// Boolean | \b RegExMatch | rem | String, String | Matches a string against a regex pattern. See notes below, for further information.
72///
73/// <br>
74/// <b>Unary Operators:</b><br>
75///
76/// | Return Type | Operator| Argument Type | Description|
77/// |-------------|---------|---------------|---------------------
78/// | String |<b>+</b> | String | Alias to function \b %ToUpper.
79/// | String |<b>-</b> | String | Alias to function \b %ToLower.
80/// | Boolean |<b>!</b> | String | Tests a string for emptiness. See notes below.
81///
82/// <br>
83/// <b>Binary Operators:</b><br>
84///
85/// | Return Type | Lhs Type | Operator | Rhs Type | Description
86/// |-------------|----------|------------|----------|--------------------
87/// |String | String |<b>+</b> | Integer | Concatenates an integral value to a string. The number conversion is performed using object \alib{lang::format::Formatter;DefaultNumberFormat} of field \doxlinkproblem{structalib_1_1expressions_1_1Scope.html;aebf2cd4ff8a2611de06368fccfd3ef5b;Scope::Formatter;expressions::Scope::Formatter}.
88/// |String | String |<b>+</b> | Float | Concatenates a floating point value to a string. The number conversion is performed using object \alib{lang::format::Formatter;DefaultNumberFormat} of field \doxlinkproblem{structalib_1_1expressions_1_1Scope.html;aebf2cd4ff8a2611de06368fccfd3ef5b;Scope::Formatter;expressions::Scope::Formatter}.
89/// |String | String |<b>+</b> | <any> | Converts a boxed value of an arbitrary type to a string and appends the result to another string. The conversion of the boxed value is performed by invoking box-function \alib{boxing;FAppend}.
90/// |String | Integer |<b>+</b> | String | Converts an integral value to a string and concatenates another string. The number conversion is performed using object \alib{lang::format::Formatter;DefaultNumberFormat} of field \doxlinkproblem{structalib_1_1expressions_1_1Scope.html;aebf2cd4ff8a2611de06368fccfd3ef5b;Scope::Formatter;expressions::Scope::Formatter}.
91/// |String | Float |<b>+</b> | String | Converts a floating point value to a string and concatenates another string. The number conversion is performed using object \alib{lang::format::Formatter;DefaultNumberFormat} of field \doxlinkproblem{structalib_1_1expressions_1_1Scope.html;aebf2cd4ff8a2611de06368fccfd3ef5b;Scope::Formatter;expressions::Scope::Formatter}.
92/// |String | <any> |<b>+</b> | String | Converts a boxed value of an arbitrary type to a string and appends another string. The conversion of the boxed value is performed by invoking box-function \alib{boxing;FAppend}.
93/// |String | String |<b>+</b> | String | Concatenates two strings.
94/// |Boolean | String |<b><</b> | String | Compares two strings using method \alib{strings;TString::CompareTo;String::CompareTo}.
95/// |Boolean | String |<b><=</b> | String | Compares two strings using method \alib{strings;TString::CompareTo;String::CompareTo}.
96/// |Boolean | String |<b>></b> | String | Compares two strings using method \alib{strings;TString::CompareTo;String::CompareTo}.
97/// |Boolean | String |<b>>=</b> | String | Compares two strings using method \alib{strings;TString::CompareTo;String::CompareTo}.
98/// |Boolean | String |<b>==</b> | String | Compares two strings using method \alib{strings;TString::Equals;String::Equals}.
99/// |Boolean | String |<b>!=</b> | String | Compares two strings using method \alib{strings;TString::Equals;String::Equals}.
100/// |Boolean | String |<b>*</b> | String | Alias to expression function \b %WildCardMatch. See notes below, for further information.
101/// |Boolean | String |<b>\%</b> | String | Alias to expression function \b %RegexMatch. See notes below, for further information.
102/// |Boolean | String |<b>[]</b> | Integer | Returns the substring of length \c 1 at index \e rhs in string \e lhs.
103///
104///
105///\I{##############################################################################################}
106/// # Notes And Hints #
107///
108/// \par Compile-Time Invokable:
109/// All callback functions are defined compile-time invokable. This means that redundancies in
110/// string expressions emerging from operations on constant strings are optimized (pruned) by the
111/// compiler.
112///
113/// \par Underlying %String %Types:
114/// While all string manipulation is based on \alib classes \alib{strings;TString;String},
115/// \alib{strings;TAString;AString} and \alib{strings;TSubstring;Substring}, due to the
116/// "harmonizing" way that string classes become boxed, none of these types appears as an expression
117/// result type. This means that custom expression functions can unbox strings that have been created
118/// by callback functions of this plug-in to their own custom string-type (e.g., \c std::string,
119/// \c QString, or whatever), and, the other way round, results of custom callback functions that
120/// returned custom strings objects, can seamlessly be used by functions and operators defined here.
121///
122/// \par
123/// Details of this are explained in chapters
124/// \ref alib_boxing_bijective "3. Non-Bijective Type Relationships" and
125/// \ref alib_boxing_strings "10. Boxing Character Strings" of the
126/// \ref alib_mod_boxing "Programmer's Manual" of module \alib_boxing_nl.
127///
128///
129/// \par Determine A String's Length
130/// The length of the string can be determined with function \b %Length, which is defined with
131/// compiler plugin \alib{expressions::plugins;Arithmetics} (because it works on all arrays).
132///
133/// \par Test For Empty %Strings:
134/// Unary operator \alib{expressions::DefaultUnaryOperators;BoolNot} (<c>'!'</c>) may be used to check if a
135/// string is not empty. The operator returns \c true if the string is empty and \c false otherwise.
136///
137/// \par
138/// Consequently, to test for non-empty strings, <c>'!!'</c> may be written. The outer
139/// <em>not-</em>operator is then a <em>not-</em>operator on the boolean result of the inner.<br>
140/// Alternatively, binary operators (see below) against an emtpy string can be used:
141///
142/// myIndentifier == ""
143/// myIndentifier != ""
144///
145/// \par
146/// As a result, this expressions is a tautology:
147///
148/// !myIdentifier == (myIndentifier == "")
149///
150/// \par
151/// Finally with strings, the built-in implementation of the
152/// \alib{expressions;plugins::ElvisOperator;elvis operator} is quite useful to avoid empty
153/// strings. The expression:
154///
155/// myIdentifier ?: "Default"
156///
157/// \par
158/// returns "Default" if \e myIdentifier evaluates to an empty string.
159///
160///
161/// \par Case conversion:
162/// Unary operators \alib{expressions::DefaultUnaryOperators;Positive} <c>'+'</c> and
163/// \alib{expressions::DefaultUnaryOperators;Negative} <c>'-'</c> are alias to functions \b %ToUpper and
164/// \b %ToLower.
165/// Hence, the expressions
166///
167/// ToUpper( "Hello " ) + ToLower( "World" )
168/// +"Hello " + -"World"
169/// are equivalent.
170///
171///
172/// \par Concatenation:
173/// Binary operator <c>'+'</c> is compiled by this plug-in if one of the arguments (or both) is of
174/// string-type. If one argument is not of string-type, it becomes converted. For the conversion,
175/// the following rules apply:
176///
177/// - Types \alib{expressions::Types;Integer} and \alib{expressions::Types;Float} are converted
178/// to string-types using object \alib{lang::format::Formatter;DefaultNumberFormat} of
179/// field \doxlinkproblem{structalib_1_1expressions_1_1Scope.html;aebf2cd4ff8a2611de06368fccfd3ef5b;Scope::Formatter;expressions::Scope::Formatter}.
180/// With this, detailed options for the number output format is available.
181/// Even more options are available when using expression function \b %Format instead of
182/// the <c>'+'</c> operator.
183///
184/// <p>
185/// - Any other type is converted to a string representation by using box-function
186/// \alib{boxing;FAppend}. For information on how to implement this for custom
187/// types, consult the documentation of module \alib_boxing.
188/// The following provides a quick sample snippet, taken from the unit tests:
189///
190/// 1. The custom type:
191/// \snippet "ut_expr.cpp" DOX_EXPRESSIONS_STRINGOPS_IAPPEND_1
192///
193/// 2. Definition of functor \alib{strings;T_Append} type <b>MyType</b>.
194/// Because the type will be boxed as a pointer, we also define the functor for the pointer type:
195/// \snippet "ut_expr.cpp" DOX_EXPRESSIONS_STRINGOPS_IAPPEND_2
196///
197/// 3. In the bootstrap section of an application, an implementation of the templated interface
198/// function has be registered with \alib_boxing_nl:
199/// \snippet "ut_expr.cpp" DOX_EXPRESSIONS_STRINGOPS_IAPPEND_3
200///
201/// With this short setup code, objects of type \e MyType, which might be returned by custom
202/// identifiers, can be added to strings in expressions!
203///
204/// <p>
205/// - With type \alib{expressions::Types;Boolean}, the \alib{lang::resources;ResourcePool;resourced}
206/// string values generally used with box-function \alib{boxing;FAppend} defined for
207/// C++ type \c bool are used.
208/// These string resources default to \b "true" and \b "false". While resources can be customized,
209/// such customization has process-wide effect.<br>
210/// To express other values, \ref alib_expressions_builtin_ternary "conditional operator"
211/// (<c>Q ? T : F</c>) can be used by the end-user:
212///
213/// "Is true: " + {boolean expression} // Uses the global resourced strings
214/// "Is true: " + ( {boolean expression} ? "Yes" : "No" ) // Custom conversion per expression.
215///
216/// \par Comparison:
217/// Operators <c>'=='</c>, <c>'!='</c>, <c>'<'</c>, <c>'<='</c>, <c>'>'</c> and <c>'>='</c>
218/// perform comparisons between two string operands.
219/// Internally, to perform the comparison, methods \alib{strings;TString::Equals;String::Equals} and
220/// \alib{strings;TString::CompareTo;String::CompareTo} are used.
221///
222/// Case insensitive comparison can be performed by converting the operand(s) to upper case
223/// using expression function \b %ToUpper or its "alias operator", unary <c>'+'</c>.
224/// A more effective way is to use overloaded function \b %Compare that accepts an optional
225/// third operator of type \b %Boolean, which if \c true is given performs a case insensitive
226/// search without performing string conversions.
227///
228/// \anchor alib_expressions_Strings_Formatting
229/// \par Formatting:
230/// Function <b>Format(String, ...)</b> offers full featured string formatting in expressions.
231/// Being based on classes of underlying module \alib_basecamp, there is a choice between
232/// \alib{lang::format;FormatterPythonStyle;python style} or
233/// \alib{lang::format;FormatterJavaStyle;Java/printf style} format strings. It is even possible
234/// to allow both formats, of course not within the same string, but within different
235/// evaluations of the same expression!
236///
237/// \par
238/// Please consult the documentation of classes
239/// - \alib{lang::format;Formatter},
240/// - \alib{lang::format;FormatterPythonStyle;FormatterPythonStyle} and
241/// - \alib{lang::format;FormatterJavaStyle;FormatterJavaStyle} for details.
242///
243/// \par Wildcard Match:
244/// Wildcard match is implemented with expression function \b %WildcardMatch, respectively its "alias
245/// operator" <c>'*'</c>.
246/// The first (left-hand side) argument is the
247/// string that is searched, the second (right-hand side) argument is the pattern string to be
248/// matched.
249///
250/// \par
251/// Wildcards characters are (<c>'*'</c>) and (<c>'?'</c>). For example, expressions
252///
253/// WildcardMatch("This is ALib Expressions", "*A?ib*")
254/// "This is ALib Expressions" * "*A?ib*"
255///
256/// are equivalent and return boolean \c true.
257///
258/// \par
259/// For case insensitive search, the both strings are to be converted to upper case, as in
260/// expression:
261///
262/// +filename * "*.JPG"
263///
264/// \note
265/// A more performant alternative for the latest sample expression is:
266///
267/// EndsWith( filename, ".jpg", true )
268///
269/// \par Regular %Expression Match:
270/// Regular expression match is implemented with expression function \b %RegexMatch, respectively its
271/// "alias operator" <c>'\%'</c>.
272/// The first (left-hand side) argument is the
273/// string that is searched, the second (right-hand side) argument is the pattern string to be matched.
274///
275/// \par
276/// The regular expression syntax is compatible with
277/// \https{Perl Regular Expressions,perldoc.perl.org/perlretut.html}.
278/// The feature is implemented with using \https{boost::regex library,www.boost.org}.
279///
280/// \attention
281/// The regular expression features of \alib and therefore of this compiler plug-in, are only
282/// available with the definition of compiler symbol \ref ALIB_FEAT_BOOST_REGEX
283/// and if either \ref ALIB_CHARACTERS_WIDE is \c false or \ref ALIB_CHARACTERS_NATIVE_WCHAR
284/// equals \c true.
285///
286///\I{##############################################################################################}
287/// # Reference Documentation #
288//==================================================================================================
290{
291 //==============================================================================================
292 /// Constructor. Creates the hash map.
293 /// @param compiler The compiler we will get attached to.
294 //==============================================================================================
296
297 //==============================================================================================
298 /// Virtual destructor
299 //==============================================================================================
300 virtual ~Strings() override
301 {}
302
303 //==============================================================================================
304 /// Overwrites the implementation of class \b %Calculus. While this is usually not needed,
305 /// this class uses this for wildcard and regular expression matching functions.
306 /// These functions implement a special behavior in respect to allocate "matcher" classes
307 /// at compile-time in the case that the pattern string is constant (which usually is).
308 /// Parent helper-class \alib{expressions::plugins;Calculus} does provide mechanics for such
309 /// rather complicated special actions.
310 ///
311 /// Of course, the original method is called alternatively.
312 ///
313 /// @param[in,out] ciFunction The compilation info struct.
314 /// @return \c true if compilation information was given, \c false otherwise.
315 //==============================================================================================
317 virtual bool TryCompilation( CIFunction& ciFunction) override;
318
319 //==============================================================================================
320 /// Overwrites the implementation of class \b %Calculus. While this is usually not needed,
321 /// this class uses this to fetch arbitrary boxed types for certain operations because
322 /// the interface mechanics of module \alib_boxing allows us to convert any custom type
323 /// to a string.
324 ///
325 /// Of course, the original method is called alternatively.
326 ///
327 /// @param[in,out] ciBinaryOp The compilation info struct.
328 /// @return \c true if compilation information was given, \c false otherwise.
329 //==============================================================================================
331 virtual bool TryCompilation( CIBinaryOp& ciBinaryOp ) override;
332
333};
334
335//==================================================================================================
336/// This is the callback method for string function <b>%String(...)</b>, which converts an arbitrary
337/// number of arguments of arbitrary types to a concatenated string.
338///
339/// The function is compile-time invokable.
340///
341/// \note
342/// As an exception to the rule, this function is not defined in an anonymous namespace, but
343/// exposed through the C++ header file of this struct. The rationale for this
344/// is that the function is also used for auto-casting custom types to strings, which is performed
345/// with compiler plug-in \alib{expressions;plugins::AutoCast}.
346///
347/// @param scope The scope.
348/// @param args The single argument.
349/// @return The boxed result string, allocated inside the scope's mono allocator.
350//==================================================================================================
353
354//==================================================================================================
355/// This is the callback method for string function <b>%Format(...)</b>, which formats an arbitrary
356/// number of arguments according to a given format string.
357///
358/// The function is compile-time invokable.
359///
360/// \note
361/// As an exception to the rule, this function is not defined in an anonymous namespace, but
362/// exposed through the C++ header file of this struct. The rationale for this
363/// is that the function this way can be called by other plug-ins as well.
364///
365/// @param scope The scope.
366/// @param args The single argument.
367/// @return The boxed result string, allocated inside the scope's mono allocator.
368//==================================================================================================
371
372}}} // namespace [alib::expressions::plugins]
373
374#endif // HPP_ALIB_EXPRESSIONS_PLUGINS_STRINGS
375
#define ALIB_API
Definition alib.hpp:639
ALIB_API Box CBFormat(Scope &scope, ArgIterator args, ArgIterator)
ALIB_API Box CBToString(Scope &scope, ArgIterator args, ArgIterator)
StdVectorMono< Box >::iterator ArgIterator
Definition alib.cpp:69
virtual ALIB_API bool TryCompilation(CIFunction &ciFunction) override
virtual ~Strings() override
Virtual destructor.
Definition strings.hpp:300
virtual ALIB_API bool TryCompilation(CIBinaryOp &ciBinaryOp) override
ALIB_API Strings(Compiler &compiler)