Following is a list of recent and significant changes to the compiler. The gaps in the numeric sequence indicate edits that were minor enhancements or bug fixes. Note that the descriptions below are just summaries; for full details, refer to the appropriate topic(s) elsewhere in this document or to the A-Shell Development Notes. For compiler changes prior to the release of A-Shell 6.1 and compiler edit 600, refer to the A-Shell 6.0 Development Notes.
Also note that there is a second listing of compiler edits following this one; it is called "Compiler Edit History II." It differs from this version in that it lists every edit, including bug fixes, has no links, is in table form, and has not been as thoroughly edited.
2022 February, A-Shell 6.5.1711, edit 967: LSX file ++include indicators now show a <##_#> suffix indicating the sequential file # and the nesting level.
2021 October, A-Shell 6.5.1708, edit 957: DEFALIAS now updates the effective type (string or numeric) of the function, making it possible to alias a numeric function call to a string function or vice versa.
2021 October, A-Shell 1707, edit 952: provides for more comprehensive MX_DYNSTRUCT support. The default amount of work area memory allocated when defining (compiling) a dynamic structure has been increased from 128K to 2M.
2021 September, A-Shell 1706, edit 949: provides support for auto-mapped %var$ variables in loop counters.
2021 June, A-Shell 1704, edit 947: all standard string functions now support the optional $ suffix on the name—e.g. STR(x) or STR$(x).
2021 June, A-Shell 1704, edit 946: Introduce auto-mapped for/next loop variables. You may now create a new variable on the fly to act as the loop counter in a for/next loop by preceding the variable name with a %. See FOR … NEXT Control Structures.
2021 January, A-Shell 6.5.1695, edit 939: Add support for Implicit Function Return Value Capture.
2020 October, A-Shell 6.5.1689, edit 938: Add support for a ++ifdef ... ++endif statement on a single source line, e.g.: ++ifdef TEST_MODE : ? "Running in test mode" : ++endif
2020 September, A-Shell 6.5.1689, edit 937: Arrays/collections may now be passed to DYNFUNC(), as they can in normal function references. Previously only array elements were supported.
2020 July, A-Shell 6.5.1686, edit 934: Add new Shortcut Operators #+= and $+=.
2020 July, A-Shell 6.5.1685, edit 933: Add several new Dot Variables.
2020 June, A-Shell 6.5.1683, edit 928: Language enhancements: (1) new statement to set the record number of a file: set'recnovar #channel, expr; (2) new Dot Functions to access the fstatvar and recnovar attributes associated with an ISAM-A file; (3) new XOPEN statement for ISAM-A.
2019 December, A-Shell 6.5.1672, edit 924: Revise edit 923 so that all ++ conditional compilation directives within functions and procedures are included in the LSX, even if within a function that has been shaken out by the /PX switch. Such conditionals may still be be relevant to how the rest of the file is compiled, and this resolves problems with conditionals that span the start or end of a routine.
2019 December, A-Shell 6.5.1671, edit 922: Attempting to use the .ISNULL() function with a non-string argument now generates an illegal expression error.
2019 October, A-Shell 6.5.1670, edit 920: The minimum run version stored in the program header—see compiler edit 896 in 6.5.1657.0—now distinguishes between two variations of the .CLEAR statement:
.CLEAR $MAP() ! (collections) minimum version is 1354
.CLEAR MAP() ! (mapped or DIMX array) minimum version is 1624
Previously it was setting the minimum version in both cases to 1624. The point is largely moot since the minimum version for running any program containing the new header type is 1657, but it was creating confusion as to whether such a program could be run if the header was removed (using the /F1 switch).
2019 September, A-Shell 6.5.1668, edit 918: The shortcut operators += and -= now work with collections. Adding/subtracting collections was implemented in 6.5.1650, but the compiler was recognizing only the long form of the assignment, e.g. $map1() = $map1() + $map(2).
2019 August, A-Shell 6.5.1664, edit 914: Add comment marker (!) to "{shaken out by /PX}" notations in the LSX file for ease of recompiling from the LSX.
2019 May, A-Shell 6.5.1661, edit 905: Add language enhancement / functional directive .EXTERN(expr).
2019 May, A-Shell 6.5.1661, edit 903: .SIZEOF() now supports DEFTYPE names, e.g. .SIZEOF(BOOLEAN).
2019 April, A-Shell 6.5.1660, edit 898: MX_DYNSTRUCT now allows DEFTYPE aliases for implicitly sized X variables. There were previously allowed, but the DEFTYPE name was lost during the runtime compilation.
2019 March, A-Shell 6.5.1657, edit 896: The compiler now embeds into the object header an indication of the minimum acceptable A-Shell runtime version, when certain newer language features are present. Runtime versions prior to 6.5.1657 will not recognize the new header signature and will treat the RUN as invalid—i.e. will refuse to run it. From this version on, the runtime system will recognize the minimum version header and will give a more precise error: "Program requires minimum A-Shell level ####."
2019 February, A-Shell 6.5.1654, edit 892: The LSX header now includes more details.
2019 February, A-Shell 6.5.1654, edit 892: Add explicit / unambiguous comparison operators.
2019 February, A-Shell 6.5.1654, edit 891: Add new operators and casting functions NUMEXPR, STREXPR, #+, $+ to eliminate the ambiguity in the Plus operator.
2019 February, A-Shell 6.5.1654, edit 890: Add new ++PRAGMA AUTO_LARGE_CONSTANTS
2018 December, A-Shell 6.5.1651, edit 889: Unmapped struct.member errors now display the full struct.member name. Previously it was only noting the structure name.
2018 November, A-Shell 6.5.1650, edit 888: Language extension: high level operations to Copy, Add, Subtract Collections (i.e. ORDMAP, ORDMAPM and MLIST structures) to/from each other.
2018 November, A-Shell 6.5.1650, edit 887, compil.exe (Windows standalone) enhancement: -z and -zt command line switches are now supported to stifle the creation/destruction of the main window during compilation. Note that these have no effect in the APN environment, which already hides the compiler window, but might provide some aesthetic relief when calling the compiler from some other environments.
2018 September, A-Shell build 1647, edit 882: The dynfunc mechanism now allows for retrieval of function return type information; see MX_DYNFUNC. TRACE.PRINT statements with the (level) and/or (level,tags) option were throwing bogus syntax errors for variations that weren't errors.
2018 September, A-Shell build 1647, edit 881: Support .fn (case INsensitive) within a function as an alias for the function name variable. For example...
Function Fn'Foo(a as b2) as f6
.fn = a**2 ! equivalent to Fn'Foo = a**2
EndFunction
Note that the $ suffix is not used here; the .FN alias applies to both string and numeric functions.
2018 September, A-Shell build 1647, edit 880:
2018 September, A-Shell build 1647, edit 879: Various:
• Revise compilation of ds.field(x) and ds.@fname$(x) to allow for better runtime error detection and handling. Incorrect use of ds.@fname$(x) in place of ds.@fname$(x)(y) can now be trapped at runtime with error 71, undefined dynstruct member. Any programs using DYNSTRUCT must be recompiled!
• Improve robustness of file-based MX_DYNSTRUCT DYNOP_DEF
• Disable the auto-tracing—activated by ++PRAGMA TRACE_BEGIN—of MAP statements with initializers, as this was leading to spurious errors.
• Fix spurious compiler error on IF <expr> RESUME <label>.
• Fix problem with ++PRAGMA TRACE_BEGIN appearing to have no effect after a previous ++PRAGMA TRACE_BEGIN at the same nesting level.
2018 September, A-Shell build 1646, edit 877: Language refinement: change syntax for indirect deferred dynstruct references from ".." to ".@" :
ds.@fname ! fname contains name of member (was ds..fname)
ds.fname ! fname is name of member (same as before)
Samples and related support files in SOSLIB and EXLIB updated accordingly.
2018 August, A-Shell build 1645, edit 873: Add dynamic structures (Dynstruct).
2018 August, A-Shell build 1641, edit 868: Language enhancement: PRIVATE variables and ++PRAGMA PRIVATE_BEGIN / _END blocks may now be used in the main source module to limit the scope of those variables to just that source file. Note that this enhancement entirely handled by the compiler; there is no issue with backwards or forwards runtime compatibility, even under AMOS.
2018 July, A-Shell build 1639, edit 865: Add private functions to the tags file for the benefit of APN and the Go To Definition script.
2018 July, A-Shell build 1639, edit 862: Add support for /NOTRC option.
2018 May, A-Shell build 1636, edit 859: The starting key in a FOREACH statement may now be any kind of expression.
2018 February, A-Shell build 1629, edit 854: INPUT CSV Into Array
2018 February, A-Shell build 1628, edit 852: Increase maximum length of a single line of source code, including continuations, from 3K to 16K. Also increase the limit on the number of subroutine / function / procedure parameters from 128 to 1024.
2018 January, A-Shell build 1624, edit 846: .CLEAR ARY() now supported for all types of arrays; previously it only applied to collections.
2018 January, A-Shell build 1624, edit 845: STRSIZ-related enhancements
2017 December, A-Shell build 1623, edit 844: Collections can now be passed by reference in a subroutine to an SBX
2017 November, A-Shell build 1555, edit 834: Support .ARGTYP(@arg) and .ARGSIZ(@arg). Concept is similar to that used for XPUTARG @arg—i.e. @arg is treated essentiall as a macro for the argument number corresponding to the argument arg as defined in the function/procedure definition or as retrieved in an SBX using XGETARG(S). No change to the runtime system required.
2017 July, A-Shell build 1552, edit 830: Errors related to improperly terminated functions and procedures (such as a missing or mismatched ENDFUNCTION statement, or a prior missing ENDIF, ENDSWITCH, LOOP or NEXT statement) are now reporting in a somewhat more helpful way than before, hopefully making it easier to understand and locate the real problem.
2017 May, A-Shell 6.5.1603, edit 821: DEFSTRUCT may now include a MAP1 statement as the first member of the structure
A-Shell 6.3/6.4 below here, A-Shell 6.5/6.6 above
2017 March, A-Shell 6.4.1547, edit 803: The line marking the end of a ++INCLUDE now also indicates the module that we are returning to.
2017 March, A-Shell 6.4.1546, edit 797: Maximum nesting levels for ++INCLUDE and ++IF conditions increased from 20 to 40. Improve messaging/recovery for the overflow condition.
2016 November, A-Shell 6.3.1538, edit 792: Add new Dot Functions .LINENO and .LOCATION.
2016 October, A-Shell 6.3.1534, edit 790: Use of .ARGCNT within a PRIVATE_BEGIN / PRIVATE_END block now generates a compile error. Although the expression wouldn't technically be illegal, because the PRIVATE block is essentially called for initialization by whatever function or procedure in the module gets called first, there's really no good way to predict in advance what the .ARGCNT value will represent, and thus it is almost certain to create a discrepancy between the expected and actual behavior.
2016 September, A-Shell 6.3.1528, edit 779: Add pragma ++pragma INCLUDE_GLOBAL_ONCE_ONLY <boolean> . When enabled, ++INCLUDE is treated as ++INCLUDE'ONCE, except when it occurs inside a function or procedure. In such cases, it is likely that you are intentionally including an extra copy of some map statements.
2016 September, A-Shell 6.3.1528, edit 778: Add auto-defined macros ABC_CURRENT_ROUTINE$ and ABC_CURRENT_MODULE$. These equate to the current function/procedure name (or "" if none), and the current module filename (file.ext). Both may be useful in standardized error reporting.
2016 September, A-Shell 6.3.1528, edit 777: Add three pragmas: +PRAGMA ASHELL_EXTENSIONS <boolean>, ++PRAGMA PRE_PROCESS <boolean>, and ++PRAGMA EXTENDED_PRE_PROCESS <boolean>
2016 September, A-Shell 6.3.1528, edit 776: Add indirect function calls.
2016 September, A-Shell 6.3.1527, edit 774: Add .INSTRR function
2016 September, A-Shell 6.3.1526, edit 773: Add IFELSE functions
2016 August, A-Shell 6.3.1523, edit 770: Add Private Attribute for Functions and Procedures
2016 July, A-Shell 6.3.1517, edit 764: Enhancement to recognize the new random generator functions RND() and SRND() in /X:2 mode.
2016 April, A-Shell 6.3.1508, edit 761: Optimization of PRIVATE_BEGIN/END logic so that the initialization is effectively "lazy", i.e. delayed until code within the module is executed. This eliminates unnecessary initializations that would otherwise occur if the ++INCLUDE for the module is placed near the top of the parent program.
A-Shell 6.1/6.2 below here, A-Shell 6.3/6.4 above
2015 October, A-Shell 6.1.1420, edit 756 & 758: Compiler/APN change/refinement (edits 756 & 758): ++IF, ++IFDEF and ++IFNDEF directives are now being "obeyed". Previously, all of the ++IFxxx directives were being ignored, resulting in both the True and False sections being included in the tags. This was harmless in some cases, but in others it was resulting in duplicate tags, which interferes with the ^ALT+G command. Note however, that since neither MAPs nor labels are "compiled" by the tagger, ++IFMAP, ++IFNMAP, ++IFLBL and ++IFNLBL directives continue to be ignored—i.e. no source code is excluded by them or their associated ++ELSE and ++ELIF directives. Also, SIZEOF(var) will evaluate to zero. Hopefully this represents the sweet spot on the compromise between file loading/tagging speed and accuracy.
2015 September, A-Shell 6.1.1418, edit 751: Compiler now generates the tag output used by APN, eliminating the need to call the external tagger and speeding up file loads substantially. Note that this only applies to the standalone compil.exe and APN.
2015 August, A-Shell 6.1.1416, edit 748: MAP2+ statements are now flagged as illegal if not preceded by a finalized MAP1 statement.
2015 August, A-Shell 6.1.1416, edit 747: Compiler bug fix ***SERIOUS***: Referencing a variable in a MAP statement initializer was causing the side-effect of finalizing the parent MAP1 definition, which was then causing it be encoded in the RUN file with the wrong size.
2015 August, A-Shell 6.1.1414, edit 744: Attempting to define a local dimx byref array without the required initial subscript value of -1 is now flagged as an error. Previously, no error was generate but the pass-by-reference mechanism would not have worked correctly.
2015 August, A-Shell 6.1.1414, edit 743: MAP statements with initial values, when part of a DEFSTRUCT, were generating improper assignments in the RUN file. Typically these were benign, but in some cases they were causing the program to abort with a nonsensical error code during the initialization.
2015 August, A-Shell 6.1.1414, edit 742: Add new Dot Function .ISNULL for use with ordered maps to test for the .NULL condition.
2015 February, A-Shell 6.1.1401, edit 740: DEFXCALL now allows all named parameters to be optional, i.e. to be enclosed in braces, e.g.: DEFXCALL MYSBR {,one=1, two=2, three$="3"}. Previously there had to be at least one mandatory parameter prior to the "{" marking the start of the optional parameters.
2014 November, A-Shell 6.1.1398, edit 734: When passing an entire ordmap to a subroutine, you can now use the more natural syntax with a pair of empty (), rather than having to specify a null string, e.g. (""). For example, in the CGIUTL opcode CGIOP_GETPARARY (see edit 1394 below), you can now specify the ordmap using () as in this example: xcall CGIUTL, CGIOP_GETPARARY, status, $req() {,stdin$} The old syntax is still supported, but is now deprecated and any existing programs using it should probably be changed after updating to this version.
2014 October, A-Shell 6.1.1396, edit 730: LSM files (/LSM compiler switch) no longer limited to Windows.
2014 October, A-Shell 6.1.1392, edit 718: You may now optionally use procedure-style syntax with the subroutine statement. In other words, instead of: XCALL NAME,ARG1,...ARGN, you can instead use XCALL NAME(ARG1,...ARGN). The advantage of the alternate syntax is perhaps mainly aesthetic, but will seem more natural to programmers coming from other language backgrounds. Another potential advantage is that it would allow APN call tips to be set up for common subroutines, since the feature is triggered by typing the "(" which normally signals the start of a procedure parameter list.
2014 October, A-Shell 6.1.1392, edit 717: Add pragmas GLOBAL_BEGIN and _END.
2014 October, A-Shell 6.1.1391, edit 714: ++MESSAGE and ++ERROR output is now captured when executing in background mode—i.e. from within APN.
2014 October, A-Shell 6.1.1391, edit 713: ++INCLUDE files without a line terminator on the last line should no longer generate syntax errors.
2014 October, A-Shell 6.1.1391, edit 711: New auto-defined COMPILER_VERSION macro equates to the compiler edit.
2014 October, A-Shell 6.1.1391a, edit 710: New .TRUE and .FALSE may be used as self-documenting replacements for -1 and 0.
2014 October, A-Shell 6.1.1391b, edit 710: New statement DEFTYPE may be used to define an alias for a data type.
2014 October, A-Shell 6.1.1391, edit 708: It is no longer required that function names start with fn'.
2014 July, A-Shell 6.1.1387, edit 685: LSX file now shows offsets for members within instances of structures.
2014 July, A-Shell 6.1.1387, edit 679: ++PRAGMA ERROR_IF_NOT_MAPPED "FALSE" may now be used to override /M or a previous "TRUE". Previously it was only possible to enable the /M switch, not disable it. Note that you can now turn the option on and off multiple times within a program, allowing you to get the benefit of the for new sections of code without being forced to clean up the unmapped variables in all of your code—i.e. in all of your include modules.
2014 July, A-Shell 6.1.1387, edit 678: Improve error reporting on missing ++endif; now lists all of the unmatched ++if statements in the stack.
2014 July, A-Shell 6.1.1387, edit 675: On first $COPY, attempt to also include <prog>.VER if it exists.
2014 July, A-Shell 6.1.1387, edit 672, 674: Support Madics $COPY directive. Similar to ++INCLUDE but with default extension .cpy and different search paths.
2014 July, A-Shell 6.1.1387, edit 673: Compiler now allows a locally defined structure variable with same name as a module or global variable provided they are same type of structure.
2014 July, A-Shell 6.1.1387, edit 669-671: APN-related internal adjustments.
2014 June, A-Shell 6.1.1387, edit 668: Compiler now flags as an error an attempt to define a local structure whose name matches an auto-externed global or private (module) structure. Although this would be technically legal, it invites confusion likely to lead to difficult-to-detect bugs, especially when the local and module/global structures aren't even the same layout.
2014 June, A-Shell 6.1.1387, edit 668: Added support for -so switch to output errors to stdout rather than to a file or window. This makes it easier to interface with certain editors and IDEs.
2014 March, A-Shell 6.1.1381, edit 663: When using /P and /L, the LSX file now contains a list of all the procedures and functions, along with an indicator of how many times they were called.
2014 March, A-Shell 6.1.1381, edit 655: New statements ++IFLBL label, ++IFNLBL label and ++ELIFLBL label areanalogous to the existing ++IFDEF, ++IFNDEF, and ++ELIFDEF statements, as well as ++IFMAP, ++IFNMAP and ++ELIFMAP, except that instead of referring to defined symbols or mapped variables, they refer to labels—used by GOTO and GOSUB—as well as procedure and function names. Note however that when the specified label is meant to refer to a function or procedure name, it must be terminated by an empty pair of parentheses.
2014 March, A-Shell 6.1.1380, edit 654: The new UNDEF statement causes the specified symbol to be undefined, allowing it to be redefined or to fail a ++IFDEF symbol test.
2014 February, A-Shell 6.1.1373, edit 651: Two new Dot Functions, .ARGTYP(argno) and .ARGSIZ(argno), return the type and size of the specified argument passed to the current SBX, function, or procedure. If the specified argno is invalid, the return value will be -1.
2014 February, A-Shell 6.1.1373, edit 652/653: Subroutines, both internal and SBX, may now use named parameters for functions and procedures. Parameter passing to subroutines is nearly identical to that for procedures and functions, so the implementation details are nearly the same. The main difference is that since subroutines do not have definition statements like functions and procedures, a new statement had been introduced to allow you to define their parameter names and default values: DEFXCALL xcallname{+|,}pname{|alias}{=defval},pname{|alias}{=defval}...
2013 October, A-Shell 6.1.1363, edit 647: When a function or procedure definition occurs (illegally) within an extended IF or FOR statement, the compiler now reports the location of the unterminated IF or FOR statement. Otherwise, it may have occured countless lines or even modules previously, since there otherwise no limit to the size of the body of a FOR or IF statement, making it very difficult to find the problem.
2013 August, A-Shell 6.1.1358, edit 642: New variations of ++INCLUDE: ++INCLUDE'IF'EXISTS <filespec> and ++INCLUDE'ONCE'IF'EXISTS <filespec>. As the name implies, these operate just like ++INCLUDE and ++INCLUDE'ONCE except that if the file is not found in the normal search path, it is just skipped.
2013 April, A-Shell 6.1.1350, edit 633: New compile-time function .OFFSIZ$(struct.member) is a variation of the .OFFSET() function which returns the combination of the specified structure member's offset and size, as a string formatted as "offset~size". While the combination of the two values in a string may seem unusual, since the offset and size are often used together, the combined format eliminates the need to specify the struct.member name twice, which invites discrepancy, and lends itself to use in runtime functions that may parse out the two values and combine them with other information.
Also: SIZEOF(VAR) now handles a much wider variety of VAR arguments, including structure names, DIMX structure variables, etc. Also, for symmetry with .OFFSET(), .SIZEOF() may be used interchangeablywith SIZEOF()—i.e. with or without the leading dot.
2013 April, A-Shell 6.1.1350, edit 632: The new compile-time function .OFFSET(struct.member) is similar to SIZEOF(var) except that it returns the offset to the specified member variable within the specified structure, starting from 1, rather than the size of the variable, and it only works on fields within structures. Also, in the case of arrays, .OFFSET only returns the offset to the base of the array, and doesn't actually allow the use of subscripts. The specified structure name can either be a defined structure name, or a MAP'd or DIMX'd instance of it.
2013 March, A-Shell 6.1.1346, edit 627: Add new conditional compilation statements ++ELIFDEF <symbol> and ++ELIFMAP <var>. ++ELIFDEF is to ++IFDEF, and ++ELIFMAP is to ++IFMAP, as ++ELIF is to ++IF.
2013 March, A-Shell 6.1.1339, edit 624: The new pragmas PRIVATE_BEGIN ... PRIVATE_END may be used within ++INCLUDE files to ensure that the module's private variables (MAP and DIMX) are initialized once and only once before they are used, regardless of the position of the ++INCLUDE in the main program.