diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..176a458 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto diff --git a/history.txt b/history.txt index ab73bda..8e43395 100644 --- a/history.txt +++ b/history.txt @@ -1,2112 +1,2112 @@ -Version 3.2, build 3664 ------------------------ - -* BUG fix: using user-defined operators with the compiler option -O2 (for using - macro instructions) could produce code that the abstract machine finds - "invalid". Actually, the code is good, but the abstract machine sees a - combination of instructions that it does not expect. - -* The Linux autopackage now uses autopackage version 1.2. This should make the - Linux setup more robust. - -* BUG fix: The function libcall() in the amxProcess extension module pushed the - parameters in the wrong order under Microsoft Windows (when the module was - built with Borland C++ and perhaps with other C/C++ compilers too). - -* BUG fix: when the conditional operator is used in combination with functions - returning arrays, the heap was restored twice (once too often). In particular - the expression - a ? test1() : test2() - where test1() and test2() are both functions that return an array, had the - effect that both the "true branch" and the "false branch" allocate space for - the return value on the heap, and the heap is restored for the total of - test1() and test2() at the end of the expression. However, only one of the - branches is taken, so the heap is incremented for either test1() or test2(), - but restored for both. - - This bug was reported by Bailopan on the Pawn forum. - -* BUG fix: the heap checking (overrun and underrun) was incorrect in the JITs. - This made heap underflows go by mostly undetected. This bug was found by - Bailopan, when he investigated the bug with the conditional operator. - -* The expression "++a" in a statement like "return ++a" was optimized - incorrectly by the peephole optimizer, because it considered the expression - result as "unused". This also occurred in the statements "sleep" and "exit". - This bug was reported by Bailopan on the Pawn forum. - -* BUG fix: "nametable" field in the AMX header was swapped twice on Big Endian - architectures. This bug was reported by Pekka Nikander on the Pawn forum. - -* There is a new build macro to remove the default implementation of - amx_Callback(). A patch from Markus Schaber, on the Pawn forum. - -* The Abstract Machine core that uses computed gotos ("labels as values") is - now also used for the Intel C/C++ compiler (ICC). The Intel compiler supports - the GNU GCC extension. This change was suggested by Markus Schaber on the Pawn - forum. - -* The AMX API functions amx_PushArray() and amx_PushString() now accept NULL for - the "amx_addr" parameter. This is convenient, because amx_Release() can free - heap memory for multiple allocations at once. - -* The compiler now adds a warning for the expression - showval (a > 0) ? 1 : 2 - because this is interpreted as calling showval() with the parameter "a > 0", - like in: - (showval(a > 0)) ? 1 : 2 - What was intended is: - showval((a > 0) ? 1 : 2) - -* On Microsoft Windows, there is a second pre-compiled debugger that splits the - debugger output from the script output. This debugger is intended to be used - from an IDE like Quincy. - -* The definition of native functions has changed so that "params" is now a - "const" parameter. This gives some protection against inadvertedly changing - the stack in the abstract machine. - -* Improved support for running scripts in ROM. In this configuration, the P-code - of the script resides in ROM and the data/stack/heap is in RAM. The abstract - machine must be configured specifically for running scripts in ROM, because - various optimizations (such as relocating jump addresses) no longer work. - -* Various minor improvements to the Pawn debugger and the Quincy IDE. - -* Various minor optimizations and minor fixes. Some related to Macintosh - support, others to the Linux Autopackage. A few error/warning messages in the - compiler were made more precise/accurate too. - - -Version 3.2, build 3636 ------------------------ - -* Performance of the compiler has improved, due to a faster "memory file" - interface. The new interface was donated by the AMX Mod X team - (http://www.amxmodx.org). - -* BUG fix: for "optimize level" 2 and when using GCC or the assembler core, the - SYSREQ.N instructions were not replaced correctly by SYSREQ.ND. Mostly, it - failed to replace the instruction; when it did replace the instruction, it - did so at the wrong position, leading to a crash. This problem did not occur - with the ANSI C version of the abstract machine. - -* amxProcess now loads libffi dynamically, so that it works with both version - 1.20 and version 2.00-beta. Version 1.20 is the only release that can still be - downloaded separately, and which is needed for GCC versions before 3.4; - see http://sources.redhat.com/libffi/. - libffi is only used for the Linux version of amxProcess; the Microsoft Windows - version uses its own code. - -* Better checks for unreachable code, including a test for code following an - infinite loop. - -* If no AMXLIB environment variable is set, pawnrun and pawndbg now look for - the add-in modules in the same path as where they reside themselves. This - change makes it easier to run Pawn "out of the box" on Linux machines. - -* When making an array without specifiying the dimensions, but where the element - count at the lowest dimension is the same for all, the compiler now "counts" - this size, rather than setting the lowest dimension as "variable length". - - An example for this situation is the declaration: - new my_array[][] = { {1,0}, {2,1}, {3,1} } - No dimensions are given, but the new compiler determines that the minor - dimension is 2 (and the major dimension is 3). Previous compilers set the - minor dimension to 0 --meaning "variable". - -* BUG fix: #elseif handling did not work. Bug reported and patched by "rain" at - the Pawn forum. - -* A minor compiler bug (which surfaced when you would change the file output - stage) was reported by Bailopan on the Pawn forum, including a suggested fix. - - -Version 3.2, build 3599 ------------------------ - -* Constants (fields) in an enumeration may now be redeclared in other - enumerations, provided that all enumerations have a tag. When arrays are - declared with these enumeration tags for the index, the same constant - name may refer to different elements in different arrays. - -* The directive "#pragma depricated" now allows for a comment on the directive - line. This comment is appended to the warning message (warning 234). This - feature was requested on the Pawn forum by "Greenberet" and Felix Kollmann. - -* New extension module amxProcess, bringing process control and a "foreign - function interface" (meaning that you can call functions from dynamically - loaded DLLs in Microsoft Windows or shared libraries in Unix/Linux). There - is an example script, gtkcalc, that uses the amxProcess module to create a - simple GUI via gtk-server (see http://www.gtk-server.org/). - -* Pawn now uses autopackage 1.0.10, which fixes a problem with the zsh shell - (Linux/Unix). - -* BUG fix in handling the "precision" (i.e. the maximum width) of string - parameters in printf() and strformat() (from the amxCons and amxString - modules respectively). - -* BUG fix in using a state function before its definition, when this usage - occurs from a fall-back state. - -* BUG fix: the "@" character was not allowed in macro definitions (while the - documentation stated that they were). They are now allowed. - -* BUG fix: the retail binaries crashed when an extension module invoked a - public function on an event, and that extension module was in a DLL. The - cause was that the DLL contained its own copy of amx_Exec(), but possibly - one that was compiled differently from the amx_Exec() in the main program. - The fix is to let the main host program pass in a pointer to the correct - amx_Exec() to use. This bug was reported by Loo on the Pawn forum. - -* BUG fix: when compiling with -O2, an invalid assembler instruction - occasionally popped up. Reported by Brad Benjamin. - -* BUG fix: the OP_SYSREQ_N was not handled correctly in the assembly-optimized - version of the AMX. This opcode is only generated when the optimization level - (of the Pawn compiler) is set to 2. - -* BUG fix in amxCons in relation with amxString: when strformat() forwards to - amx_printstring() and the format string contains a %s, amx_printstring() is - re-entered, but the redirected output functions were not passed through. - - -Version 3.1, build 3541 ------------------------ - -* The debugger now allows for a "split-screen" build, meaning that the debugger - output goes to a simple console window/terminal (or "DOS box") and the - console output produced by the script goes through a second emulated terminal - (termwin for Microsoft Windows, or term_ga for GraphApp). - -* Minor improvements in the termwin pseudo-terminal, mostly concerning lay-out. - -* For warning 203 (symbol is never used), the reported line number is now the - line of the declaration of the symbol. For warning 204 (symbol is assigned a - value that is never used), the line number is the one at which the latest - assignment appears. - -* When the "sleep" instruction is used, the compiler now flags this in its stack - usage report. The stack usage may not be accurate in such case, because the - sleep instruction often permits re-entrancy (this depends on the host - application). - -* Quincy now checks for updates once a week. It downloads the PAD file for Pawn - and parses it using TinyXML. You can turn this feature off. - -* Relevant modifications from the Quincy 2005 project (http://quincy.codecutter.org) - were merged into the "Quincy for Pawn" project. - -* The Windows installer now registers the file extensions .p and .pawn and - associates these with Quincy. - -* BUG fixes related to the JIT (it had not been updated in a while). - -* BUG fix: a declaration like new array[1000][1000][1000] created invalid code - because the total array size exceeds 4 GiB. A check for this limit was - missing. Reported by Bailopan on the Pawn forum. - -* BUG fix: calling a public function from within a script (where the public - function lacks a forward declaration) crashed the compiler. Reported by - Bailopan on the Pawn forum. - -* BUG fix: the amx_StrParam() macro copied one character too few to the newly - allocated string. Reported by Peter W. - -* BUG fix: a script having zero native functions still required amx_Register() - to be called. This bug was fixed earlier, but it surfaces again... Reported - by Peter W. - - -Version 3.1, build 3526 ------------------------ - -* The setup program failed to put the documentation (PDF files) in the - "Documentation" sub-menu in the Start / Program Files menu. - -* Quincy was modified so that it would work when installed in a path with a - space character. In addition, the settings are now stored in an INI file, - which resides in the same location as the Quincy.exe file. I prefer INI - files, because they allow multiple installations of a program (in different - directories) with different configurations. - -* The modifications done by Allen Cronce for the Mac OS-X port were merged with - the main sources. Apart from the port, the modified source code also features - bug fixes related to the Endianness of the debugging information, so it is - relevant to all users of Big Endian architectures (and who wish to use the - debugger). - - -Version 3.1, build 3522 ------------------------ - -* Quincy, a C++ IDE written by Al Stevens and published in Dr. Dobb's Journal, - is now adapted for Pawn. This is a Windows IDE, featuring an editor and a - debugger. - -* Remote file uploading functionality in the Pawn debugger (for hosts that - support remote debugging). - Warning: For remote debugging, port 1 now refers to COM1 in Windows (and - ttyS1 in Linux); in previous releases you had to select port 0 for COM1. - -* State variables are now available. Just like local variables have a - function-local scope, state variables have a scope restricted to a state - (or a set of states) --but they may be used across functions that implement - that state. The documentation is up to date. - -* Keyword "state" is now also an operator; it returns "true" if the automaton - is in the indicated state. - -* Macro-instructions for common repeated sequences, for more compact code and - quicker execution. The new compiler option "-O" sets the optimization level. - The JIT does not support these macro instructions, and scripts that may need - to run on the JIT must therefore be compiled with -O1 (standard optimization), - which is also the default setting. - -* Support for re-entrant events in handling the "sleep" instruction. - -* Added a delay() routine in amxTime. - -* Added file matching and counting routines: fexist() (replaces the old - exist() function) and fmatch(). These routines allow wild-cards, similar to - those in the Unix shells. - -* The Path to the XSL stylesheet is now stored into the report, and the - stylesheet information is embedded in the XSL file. The generated report can - therefore be viewed directly (with a browser). - -* Dynamically loaded extension modules are looked up from the path in the - "AMXLIB" environment variable. This is especially useful for applications - that have a "plugins" directory, for contributed extensions in the form of - Pawn extension modules. - -* There is improved support for compiling scripts for execution from read-only - memory. - -* Native and public functions can be marked "depricated", to help upgrading to - new scripting environments. - -* To avoid a frequent error: (typing) error in the name/signature of a public - function, the compiler now issues a warning if no forward declaration exists - for a public function. The idea is that the (implicitly included) include - file that the host application supplies, contains forward declarations for - all public functions. - Warning: this may require that you add forward declarations to existing - header files. - -* The BinReloc package used for Pawn is now version 2.0 (see - www.autopackage.org). This package allows the Pawn compiler to be installed - in any path; it will always find the required include files in directories - that are relative to the path to the executable. - -* The compiler uses strlcpy() and strlcat() as safe alternatives for strncpy() - and strncat(). As not all compilers include these functions in their C - library, the source code comes with standard implementations in the file - lstring.c. - -* Fixed several bugs related to the order in which automatons were used and - declared. - -* BUG fix: the generated code for the entry function (state machines, or - "automatons") had the wrong stack convention. - -* Minor corrections in macros (for masking absence of terminal support) in the - console support (amxcons.c). - -* BUG fix in strmid() concerning short destination strings. - -* BUG fixes in the string packing routine (used a.o. by strcat()). - -* CMakeLists.txt for the compiler: minor path-related fix - -* BUG fix in amxjitsn.asm, where the JIT code was split into two different - sections for no good reason (probably predating the "mprotect" support code - in amx.c). Bug reported and fixed by David "BAILOPAN" Anderson. - -* BUG fix: arrays used in logical expressions were not check for full indexing - (as they should). Specifically, after declarating "new series[10]" an - expression like "if (series || 0)" would compile without errors. Bug - reported and fixed by David "BAILOPAN" Anderson (my fix is somewhat - different, to catch more cases). - -* BUG fix: the #error directive ignored the parsing state, so an #error - directive folded inside #if 0 ... #endif still fired. Reported by "chop". - -* BUG fix: the tagof operator used as a default value for function arguments - took the tag of a variable, but not of an expression. Reported and fixed by - Jonathan on the Pawn forum. - -* BUG fix in recursion detection. - -* BUG fix for the sleep opcode: the STK and HEA registers were not updated in - the AMX structure (ANSI C and GNU C versions only; the assembler versions - were correct). Reported and fixed by "chop". - -* BUG fix: the "JIT" flag was erased under specific conditions in amx_Init(). - -* BUG fix: memory block for the JIT code must be aligned under Linux. - -* BUG fix: structure packing was incorrect for GCC. Also removed "far" - pointers from the definitions of the debug structures. - -* Warning: The fixed point function fixedstr() is renamed to strfixed() to be - in line with the string functions strval() and valstr(). Similarly, - floatstr() is renamed to strfloat(). - - - -Change log for older releases ------------------------------ - -28/07/2005 BUG fix for the "switch" opcode in the JIT, in the situation - where only the "default" case was present (no other - cases, which means that the switch was actually - redundant). This bug found and fixed by Bailopan, and - reported on the Pawn forum. - BUG fixes for debugging symbols in 64-bit mode, found and fixed - by Bailopan and reported on the Pawn forum. - Fixes in the CMakeList.txt file for compiling under Linux/UNIX. - -22/07/2005 The compiler has native support for states and automatons. - Implementing finite state machines is thereby easier, - and the compiler helps in checking that the state - machine is coherent. See the language guide for details. - Several bugs related to arrays and enumerations have been - fixed. Some of these bugs were (also) reported by - Vic Viper on the forums. - Yet one more Big Endian bug was found and fixed. - Robert Daniels found and fixed a problem related to - 3-dimensional arrays with a variable last dimension. - His fixes have been merged in the main source. - A 64-bit bug found by Bailopan was fixed. Compact Encoding - should now also work with 64-bit cells. - There are three new native function modules: one with string - manipulation functions, one with simple network packet - exchange functions and one with time/date functions. - A general purpose way to accept event sources has been - implemented in the "pawnrun" example program and in - several of the native function libraries. With this - interface, a native function library can "register" - a public function that it will call upon a specific - event. See pawnrun.c and the modules "amxCons.c" - (@keypressed) and amxTime.c ("@timer") for details and - examples. - The debug protocol has changed completely. The old debug opcodes - are replaced by a single new opcode: BREAK. The debug - information is now appended to the AMX file, instead of - being intermixed with the normal opcodes. The rationale - of the new design is improved performance when running - scripts with debug information, and the ability to - do remote debugging. - The console debugger has been enhanced to support states and to - allow debugging over a serial line (RS-232), provided - that the host application supports the protocol too. - The screen lay-out was improved as well. - The Linux compiler now uses the BinReloc package from - www.autopackage.org to locate the include files and the - configuration file. This should be more robust than the - earlier hack. - The peephole optimizer was improved. After finding an - optimization, it now recurses over all rules to find - (more) optimizations on the adjusted code. - Documentation comments have been improved (and now include the - automatons and the transitions). The lay-out has been - improved as well. - New #pragma "amxlimit" lets the compiler verify that the script - fits the abstract machine after compilation. This is - useful for embedded devices with little memory for - scripts. - -18/03/2005 Small is renamed to Pawn. Changing the name has been requested - regularly, by various individuals, because searching - for information on the "small" scripting language (on - the Internet) was not exactly easy. The word "Small" - is fairly common. The new name, "Pawn" should improve - the odds that when you search for "Pawn scripting", - you will get information on the language. Together with - the product name, names of utilities and executables - changed as well. - Warning: when your host application relies on the name - of the compiler to be "sc.exe" or "sc", you must either - rename the executable after it is built, or you must - adjust your host application to run "pawncc.exe" or - "pawncc" instead. - The compiler is now built as a shared library/DLL. The compiler - command line program is now just a driver for the - library (except for the 16-bit version of the compiler). - The abstract machine can now support the JIT and the assembler - core together. In earlier releases, you had to choose - for either the JIT or the assembler core. As the JIT - does not support the debugging hook, the new scheme - allows you to build the abstract machine such that you - debug your scripts using the assembler core and run the - final version using the JIT. - Warning: the initialization of the JIT has changed (but - only slightly). Host applications that use the JIT must - set the AMX_FLAG_JITC flag before calling amx_Init(). - -16/03/2005 BUG fix: when introducing version 7 of the binary file format - I accidentally accessed the binary file directly instead - of passing through sc_resetbin(). This made in-memory - compilation impossible. - -12/03/2005 BUG fix: declaring a global array variable with a symbolic - constant (for the array size) before that symbolic - constant is defined itself, could result in a hang - (or a significant compilation delay). - Documentation fix: the documentation for enumerations in - relation to explicit tags and array indices was - incorrect. - Global variables may now be declared both public and stock. - Functions must still be either public or stock (or - neither); note that there is not much use for public - stock functions, as functions can be "forward declared" - and variables cannot. - -28/02/2005 The debug information format and the debug hook have changed - dramatically. The existing 5 opcodes for the debug hook - FILE, LINE, SYMBOL, SRANGE and SYMTAG are now redundant, - and replaced by a single new opcode: BREAK. Other - opcodes that previously called the debug hook, such as - CALL, RETN, and STACK, no longer call the debug hook. - The information for (local and global) variables is no longer - mixed in the executable code, but now appended to the - file in a separate chunk. There is a new component, - amxdbg.c, with functions that parse the debug - information and can look up functions, line numbers and - variables, given an address. - Warning: all code that uses a debugging hook must be adapted. - The new debugging hook strategy has the following - advantages: - - the debug hook can be set up on an "as-needed" basis: - when you want to break out of a "hung" script, you - can set up a debug hook while the script is still - running; - - even with the debug hook installed, the hook is a lot - quicker because there are less opcodes that call the - hook and the amount of data that needs to be parsed - and passed on is lower; - - the presence of debug information does not influence - the performance of the script execution as much (but - scripts without debug information and bounds checking - will still run quicker that those with those checks); - - the new method is more suitable for remote debugging, - especially over slow links. - There is also a disadvantage (apart from increased - complexity of the debugger and the compiler): when an - assertion fails it only gives the code address of - failure --to get the matching file & line number, you - need to look them up using the debug information. - -22/02/2005 The estimate of stack usage has become more precise. In the - older version, the estimate could be too low, because - stack usage due to parameter passing was not taken into - account. - The XML report (script documentation) was enhanced with a list - dependencies for each function; the dependency - information is the inverse of the referral information. - -17/02/2005 The method of passing parameters to public functions has - changed. In the past, these were passed to amx_Exec(); - when arrays or strings had to be passed, you had to - allocate space, copy the array/string and release the - space after amx_Exec() returns. In the current method, - there are the functions amx_Push(), amx_PushArray() and - amx_PushString() which you call before calling - amx_Exec(). The required data is allocated and copied - implicitly; you must still release the allocated space, - however. - Function amx_Execv() is now gone, as there is no more use for - it. - The 16-bit version of the AMX DLL (AMX16.DLL) now has all - functions as "FAR PASCAL" (which is standard), rather - than "__cdecl". The 32-bit version of the AMX DLL - (AMX32.DLL) declares the exported function amx_Exec() - now as "__stdcall". This should be transparent to the - compiler. - - 8/02/2005 Support for the JIT in FreeBSD and OpenBSD is improved. A few - fixes were implemented. These were reported by Laurent - on the Small forum. - Merged in changes by Allen Cronce, for the support for Mac-OS. - The project file for Metrowerks Codewarrior was updated - as well. - - 4/02/2005 BUG fix: there was an incorrect assertion in the parser which - would break an expression like "a[0] = a[1] = a[2] = 0" - (unless you build the Small compiler without - assertions). This bug was reported by "kexz" on the - Small forum. - BUG fix: a self-assignment warning was issued in a special case - of an assignment of an array element into another - element of the same array. This bug was reported by PM - on the Small forums. - BUG fix: 64-bit support used the wrong shift counts in - generating byte offsets from cell offsets. This was - reported by BAILOPAN on the Small forum. - Better portability to 64-bit cells, for example by storing the - full 64-bit function pointer to a native function in - the internal native function table. P-code files with - a 64-bit cell size have a different "magic" value - (or "signature") in the header. Most of these - modifications were described by BAILOPAN on the Small - forum. - BUG fix: the peephole optimizer could not handle long symbol - names (i.e. over 21 characters) for local variables. - This bug was reported by BAILOPAN on the Small forum. - BUG fix: constants passed into functions that accept a variable - argument list (such as printf) caused a crash. This bug - was also reported by BAILOPAN on the Small forum. - BUG fix: when a field in an enumeration had the same name as - another symbol (name conflict/symbol redefinition), the - compile crashed instead of reporting the error. This - bug was reported by "Stu" on the Small forums. - -31/01/2005 BUG fix: the implementation of the "SWITCH" opcode in the - abstract machine would not work correctly when a cell - is 16-bit. This bug was reported by "chop" on the - Small forum. - BUG fix: in AMXJITSN.ASM (the JIT compiler in NASM format), - one symbol was incorrectly exported, which made the - file produce a linker error when used with GCC on - Cygwin. This bug was reported by Laurent on the Small - forum. - BUG fix: in amx_Execv(), the number of parameters was forwarded - to the main function amx_Exec() in a way that was - incompatible with 16-bit architectures. This was - reported by Pierre de Vos, who is porting Small to the - Atmel ATmega128 controller. - -18/01/2005 Corrections merged from Embryo, the adaption of Small from the - Enlightenment team. - The command line parsing in the Small compiler was modified to - be more flexible (and perhaps slightly more conforming - to what is common with GNU programs). - A simple "script arguments" native function library was - developed. This library provides general purpose - "command line argument" parsing functions. It is - somewhat in between of argc/argv and the getopt() - library. - A few bugs were fixed in the Microsoft Windows "terminal", - especially related to scrolling and resizing. - BUG fix: in the "switch" statement was fixed a bug would occur - if an expression between the parentheses of the switch - had a side effect. This bug was reported on the Small - forum by Lajos Molnar, and analysed by BAILOPAN. - The NASM version of the assembler core of the abstract machine - would not assemble under Cygwin. This has been fixed. - The error was reported by Lexx on the Small forum. - BUG fix: the "#pragma unused" directive did not accept symbol - names with digits, underscores or "@" characters. This - bug was reported by "chop" on the Small forum. - - 3/01/2005 The pre-build LIBSC DLL was missing an export, making the DLL - unuseable (you would have to rebuild the DLL to use it). - The self-installing setup had the version number wrong (it still - said 2.5). - The README.TXT was not up to date. The version packed in the - product came from a different directory than the one - I kept up to date. - There is a #section directive that hides all symbols declared - "static" (the #section directive simulates a file - switch). This was low on my wish list, but a recently - introduced feature in the compiler required it. - -22/12/2004 The JIT-compiler was translated to NASM by G.W.M. Vissers. This - makes the JIT available in Linux, and probably other - Unix-like operating systems. The port was initially done - for the free MMORPG "Eternal Lands" (by a member of the - team of the game). - Modifications for better support of FreeBSD and OpenBSD. - The Small compiler now allows multiple source files on the - command line. The compiler combines all sources to - build a single output file. - Improved the report file and the ability to extract - "documentation comments". The toolkit now comes with - a matching XSL file and an accompanying stylesheet. - These allow the report file to be directly readable in - a web-browser. - Constants that are part of an enumeration are now flagged as - such, this those constants to be grouped with the - enumeration definition in the report (XML documentation). - The argument comparison for forwardly declared functions (with - the actual implementation) was improved. - The tags of array indices are also now checked for arrays passed - as arguments to functions. - I increased the maximum number of function arguments to 127 (it - was 64, and this turned out to be too little for some - users!). - BUG fix: an object code generation flaw in the Watcom C/C++ - compiler caused the abstract machine to crash after - calling a native function for the second time. The code - generation problem has be circumvented by rewriting the - expression to do exactly the same thing in a slightly - different way. - There is a GraphApp terminal as an example terminal. This - terminal supports UTF-8 natively. It also supports - wide characters, if compiled as such. Look at - http://enchantia.com/software/graphapp/ for information - on the cross-platform library GraphApp. - The DLL versions of the abstract machine (AMX16.DLL and - AMX32.DLL) now use the "termwin" terminal, which allows - for font scaling and coloured text. - BUG fix: the NASM version of the abstract machine core did not - set the "debug event code" on a "line" event. - The documentation was improved, especially regarding compilation - on Linux and Unix-like platforms. There is a new section - on CMake, a cross-platform "makefile" generator utility. - - -22/07/2004 Functions can return arrays. The size of the array that is - returned must be fixed (functions returning - variable-length arrays are not supported). - The warning "function uses both `return' and `return '" - is now an error. - The compiler writes extra information related to the - declarations of constants, variables and functions to - the report file, and it now also supports documentation - comments. The toolkit comes with an XSL stylesheet to - create a HTML file from the report file (which is in - XML format). - -25/06/2004 Warning messages can be disabled individually (compiler option - -w). - I added the makefiles for FreeBSD contributed by Raphael - Raimbault to the standard distribution. In general, - FreeBSD support has been improved. - Adam D. Moss contributed a modified version of the makefile - for the abstract machine for Linux. If have called this - "makefile.linux" (because it seems more complete) and - my original "makefile_asm.linux" (because my version - compiles the assembler implementation of the core - executive). - Arrays whose size is declared with an "enum" symbol now allow - initialization by field size. In addition, the "sizeof" - and "tagof" operators look at the size and tag of the - enumeration element. This allows Small to mimic (simple) - structures with arrays. - BUG fix: when generating debug information, the compiler still - assumed that it was always writing to file (instead of - possibly writing to memory). - Two new preprocessor directives: #error, which is similar to the - same directive in C/C++, and #tryinclude, which fails - silently if the include file cannot be found. - -26/03/2004 Expressions in preprocessor directives were not preprocessed - themselves. A bug found by "SniperBeamer". - The "#elseif" directive was (finally) implemented. It allows - you to chain conditionally compiled sections more - easily. Note that in contrast to C/C++, it is called - "#elseif", not "#elif". - A few modules for the abstract machine are enhanced for Unicode - and UTF-8 support. - In AMXCONS.C, create the terminal "late", meaning that if a - script does not use a terminal, it does not pop up. - Better support for having an abstract machine that uses both - fixed and floating point calculations. The format - string of the native printf() function uses %f for - floating point, %q for fixed point and %r for either - floating point or fixed point (if floating point is - not available). - A new include file "rational.inc" allows you to write a script - using "rational numbers" and leave it to the abstract - machine as to whether this means "floating point" or - "fixed point". - -25/03/2004 Fixed a syntax problem where the conditional operator - interferes with tagnames, in an expression like: - new bool:a=(b<10)?true:false - Here "true:" is seen as a tagname, rather than as the - second part of the "? :" operator. Adding whitespace - fixes the matter, of course. The expression: - new bool:a=(b<10)?true : false - gives no problems. - The current compiler requires that tagnames in a - conditional expression appear between paranteheses, - like in: - new plain:a=(b<10)?(plain:true):(plain:false) - This bug was found by "PM", who posted it on the Small - forum. - Names of native functions were still truncated to 19 characters - even though the new binary file format no longer - imposes a length restriction on external names. This - limit is now removed. Another bug found by "PM", and - posted on the Small forum. - The logical operators did not force the tag to "bool:" (which - they should, according to the documentation). - A few type-casts were added, to allow the source to be compiled - as C++ source. - -15/03/2004 The file SCLIB.C, that compiles the "Small compiler" to a - single object file for embedding into an application, - was updated to include the new files. At the same time, - it was renamed to LIBSC (for conformance with Linux). - In addition, the library file can now be compiled as a - DLL (without needing a change in the source code) and - the DLL supports the functionality required by - RUNDLL32.EXE. - The example "SRUN" files (implementation examples for the - abstract machine) have been cleaned-up a bit and - another example, for the JIT compiler was added. The - function amx_InitJIT() is now finally documented. - The syntax for declaring an increment for a constant in an - enumeration has changed. The old syntax: - enum { - first : 10, - second : 5, - } - has become: - enum { - first[10], - second[5], - } - I need this changed syntax for a new feature that I - intent to implement. In addition, I have accidentally - used the new syntax on various occasions, so it may - be more intuitive than the old syntax. - - 3/3/2004 I added a -v switch to the compiler to set the verbosity. For - the moment, this does not change much: -v0 disables the - copyright banner and -v2 displays extra stack/heap - usage information; -v1 is the default. - The declaration and initialization of simple variables (single - cell) to constant values is significantly optimized: - from 3 opcodes to one opcode. This makes declaring a - new variable a light-weight operation. - -29/02/2004 The maximum number of dimensions for arrays has been increased - to 3. Hopefully, increasing it further now involves no - more than changing a constant. - As an example for how the Small abstract machine can be - extended, I have added a simple general purpose garbage - collector in a separate C file (AMXGC.C). The - "Implementor's Guide" discusses the interface and gives - an example of use, using the "Better String library" - (http://bstring.sourceforge.net/) for creating the - "garbage". - Basic support for UTF-8 is now also in the abstract machine. - The new functions amx_UTF8Get() and amx_UTF8Put() - extract or store a single (wide) character in UTF-8 - encoding. The new function amx_UTF8Check enables you to - verify whether some input string is in valid UTF-8. - All functions return an error code. All functions use - a strict interpretation of the UTF-8 syntax. - -23/02/2004 The compiler is now able to translate "extended" ASCII files - (i.e. 8-bit ASCII) to Unicode by using a codepage - mapping file. Only characters in unpacked strings or - in character constants are translated. Appropriate - mapping files can be found on - ftp://ftp.unicode.org/Public/MAPPINGS/. - In the compiler, the option "-c" no longer sets the - character size (there were bugs in this setting, so - I doubt that anyone ever used it). It now sets the - codepage for translation. - Robert Daniels provided fixes for bugs related to Big Endian - processors (I introduced these new bugs when adding - the "symbol names" table to the header in the AMX file - format. - Robert Daniels also gave a fix for an error that has been in - the toolkit much longer: several core functions had - to peek/poke into the data section of an abstract - machine, but they did not take the possibility of - "cloned" abstract machines into account. - -17/02/2004 The parser stack is now "growable". In earlier releases it had - a fixed size. - A memory leakage was fixed; the leakage was related to a double - declaration of a native function. - The compiler now accepts UTF-8 files on input. It translates - non-ASCII characters (that are encoded in UTF-8) to - Unicode characters in unpacked strings. See the manual - for details. - The compiler allows character codes to be entered with a - hexadecimal escape (in addition to the existing decimal - escape): '\x82' is the same as '\130'. - Unicode support uncovered a few bugs in the handling of unpacked - strings in the "core" and "console" modules: checking - whether a string is packed or unpacked did not work for - characters above 255. This is now fixed, and it also - led to a new predefined constant in the compile: - "ucharmax". - The LINE opcode now allows a debug hook function to cause the - program to "sleep". Previously, a "sleep" mode could - only be started from a native function or via the - "sleep" statement of the Small language. - - 5/02/2004 For arrays with 2 dimensions, the major dimension no longer - needs to be explicitly specified when there are - initiallers. The compiler can now count the number of - items itself. - "Johnny got his gun" reported the bug that the compiler signals - the expression "var = !var" as a self-assignment. This - bug applied to most unary operators. (It is now fixed.) - A new extension library (native function library) comes with - the toolkit: file input/output. Text files (plain ASCII - and UTF-8) and binrary files are supported. - There is a new terminal implementation: "termwin". This - terminal emulates a console on Microsoft Windows; its - primary feature is that you can have several of these - consoles at the same time and that it supports Unicode. - For the purpose of Unicode, the functions amx_GetString() and - amx_SetString() got an extra parameter, for interpreting - the source or destination string (on the "C" side) as - a "wchar_t" string. - Anthalir gave an update to the FreeBSD support. His changes - were merged into the main branch. - -16/01/2004 When you compile with option -d2, the compiler now gives you - an estimate of stack/heap usage. Even without this - option, the compiler will warn you when the stack/heap - area is too small. The stack/heap determination does - not work in the presence of recursive functions. - When you do not use the return value of a function, you mostly - do not need to enclose the function's arguments in - parantheses. That is, the snippet below is now a valid - Small program: - ----------------------------------------------------- - main() - printf "Hello world\n" - ----------------------------------------------------- - The manual has been updated to use this "friendlier" - syntax where possible. - The RET and RETN opcodes of the abstract machine now check - whether the "return address" (on the stack) lies inside - the code segment. This makes buffer overrun exploits - much less likely (perhaps impossible). This address - check is also done in "no debug" mode (unlike array - bounds checking, for example). - Opcode SYSREQ.D is now fully implemented. When calling a native - function, the "callback hook" function looks up the - function address. If it has found it, it may store this - address in the code stream and change the opcode from - SYSREQ.C to SYSREC.D. The SYSREQ.D calls the native - function directly, avoiding any overhead from the - callback hook. - - 9/01/2004 The compiler generates the intermediate (assembler) file in - memory. This is faster and cleaner: compiling a .AMX - file now no longer overwrites (and deletes) the .ASM - file, if one exists. - When you do not use the result of a function call, you may now - omit the parantheses around the function's parameters. - That is, you can say: - printf "Hello world\n" - This syntax may make Small source code a little - friendlier to read, especially for novice users. - The changes of FUTURE Interactive, to support a 64-bit cell, - were merged into the main branch. - -30/12/2003 I switched to the zLib license for the toolkit. The original - license was already quite similar to the zLib license, - and in retrospect, the clauses that I added are not - very useful. - I changed the regression test suite to a REXX script (instead - of the older DOS "batch" file). REXX is available on - many platforms, so I hope that the regression suite - will be more useful to those users that do not run - Microsoft Windows (or DOS). By the way, I use Regina - REXX (see http://regina-rexx.sourceforge.net/). - -19/12/2003 Søren Hannibal proposed the use of a private implementation - for strdup(), to make it easier to use other memory - allocators (than standard malloc()). - More options for fixed/floating point value formatting in the - printf() function (width/number of decimals) - The console functions (AMXCONS.C) were redesigned and now have - improved VT100 & Win32-console support. New native - functions are gotoxy(), wherexy(), clreol(), clrscr() - and setattr(). - The toupper() and tolower() from the "core" library now also - work with accented characters using ANSI fonts - (Microsoft Windows). - New opcodes SYMTAG and SYSREQ.D. SYMTAG is for the debugger, - it allows a debugger to choose a display format based - on the "tag" of a symbol. (It was added mostly for - displaying fixed/floating point values.) SYSREQ.D is - to optimize the performance of native function - callbacks. - The ".AMX" file format changed: it now has a separate "symbol - name" table, so that the name length limit of 19 - characters for "public" or "native" symbol names no - longer applies. The run-time (AMX.C) reads modules - with the previous file format as well. The compiler - only generates files in the new format, though. - The file header is now also padded to the requested "symbol", - alignment. This way, the code and data sections are - also automatically aligned to the chosen alignment. - The Small debugger now uses the console functions in AMXCONS.C - for output. This gives (almost) automatic recognition - of the proper "terminal" support. The debugger is also - improved in its display of fixed/floating point values. - Hard limits (number of files, number of breakpoints, - number of watches) have been removed. - -24/11/2003 The preprocessor was "fixed". One problem were various match - and replacement errors (for parametrized macros), - another problem was its slow operation. - There were "tag mismatch" errors related to the user-defined - assignment operator. These have been fixed. - AMX.C now contains various conditionally compiled sections. If, - for example, you only need to call the function - amx_Register() from an extension module, you can save - of 10 kBytes of code by compiling AMX.C with the macro - AMX_REGISTER defined. This strips out all other - functions in AMX.C. - The floating point support module got a few more native - functions: floatsqroot(), floatpower(), floatlog(), - floatsin(), floatcos(), floattan() and n_floatabs(). - In addition, I documented the floating point support - in an "application note" (just like the fixed point - library). - -20/11/2003 The fixed point module was corrected to have accurate rounding - behaviour; for example 2.0 / 3.0 now is 0.667 instead - of 0.666. These rounding rules apply to both the - multiplication and the division operators and functions. - The documentation for the fixed point library is now - separate from the "user manual". In addition, I added a - power, a square root and an absolute value function to - the library (plus a useful "multiply, then divide" - function which avoids loss of precision in the - intermediate result). - Another error was also fixed in the library: the ANSI C version - of fixed point multiplication was prone to an - intermediate overflow bug. (I didn't catch this bug - earlier, because for most compilers there is an - optimized version for this function that uses 64-bit - arithmetic.) In addition, there are a few minor - corrections in the include file. - -10/11/2003 In AMXCONS.C, I changed the definition of getstring() so that - the buffer size is now in "cells" rather than - characters. In practice, this makes it much easier to - use getstring(). It is, however, not compatible with - earlier releases. - - 5/11/2003 AMXCONS.C, the example "console" interface was extended with - an improved ANSI/VT100 terminal support and a native - Win32 console interface. New native functions are: - clrscr() clear screen - clreol() clear up to the end of line - gotoxy(x, y) set text cursor position - setattr(f, b) set foreground and background colours - I added a check for invalid "AMX" addresses in the - amx_StrParam() macro, to "fortify" native functions - against tampered ".AMX" files. - The new function amx_StrError() gives a descriptive error - string for an error code. - Frank Condello updated the project files for CodeWarrior, to - compile Small on the Macintosh. These files are found - in a subdirectory. - - 1/11/2003 The Implementor's Guide was extended again, with notably a - much improved section on writing native functions, - including how to bind methods from a C++ class to - Small. - Under Microsoft Windows and Linux, extension modules can now - also be made as a DLL or shared library. The abstract - machine will automatically load the DLLs/shared - libraries that are required for the script that you - run. This allows you to create general purpose, plug-in - extension modules that you make available to an - implementation of the Small run-time without needing to - recompile this run-time. - The example extension modules that come with the toolkit were - adapted to make them suitable for dynamic loading. - To unload all DLLs & shared libraries after running the code, - you should call the new function amx_Cleanup(). When - dynamic loading of extension modules is disabled (or - not available), this function does nothing. - There is also an AMXEXPORT macro to use for extension modules - that are compiled as a DLL/shared library. - There were a few fixes in the CMake configuration files. I - renamed the Linux makefile back to "makefile.linux" - instead of "makefile.unx". - -20/10/2003 Savas Savvides (from StockWiz.com) found a bug in the array - bounds-checking of Small: negative array indices were - not caught. This was fixed. - A bug in address range checking was fixed. The bug classified - array accesses to an array at the very end of the data - section (so a global array variable) as invalid. This - was a classic "off by one" error. It occurred rarely, - though, because there is usually "string literal data" - at the end of the data section. - The definition of MAX_PATH was made more platform-independent; - the definition of POSIX is now used when available. - -14/10/2003 Some opcodes now do a bit more checking on the environment: - block moves/compares/fills now check the validity of - the memory ranges of the destination & source arrays; - RET and RETN check whether the return address lines - inside the "code space" of the abstract machine. - A memory leak in the compiler was fixed (related to functions - that take optional values on any of the arguments). - Failure to mark a symbol "public" in the NASM version of the - abstract machine core made this file not usable. This - was easily fixed. - - 8/10/2003 I thought Small was fairly well documented, but re-reading a - few less common sections proved me otherwise: parts - of the documentation is outdated and several features/ - functions were undocumented. Especially the - "Implementors Guide" was corrected and expanded. - I cannot say that the documentation is now fully - correct and comprehensive, but the situation is at - least "better". - The compiler now tries to include the file "default.inc" from - the include directory (not from the current directory); - this fails silently if the file does not exist. The - default.inc file may be used to include other "standard" - include files (console.inc, core.inc, ...) or an - application-specific include file. This may avoid the - common error of a script-writer forgetting to include a - file (especially if user-defined operators are used). - - 3/10/2003 The GNU GCC and assembler versions of the Abstract Machine - now have alternative "non-debug" versions of a few - opcodes, to avoid checking for the "debug hook" flag - every time that particular opcode comes by. - The "#subst" directive was renamed to "#define". I feel that I - have made an error to keep the "#define" directive - (which declares only numeric constants) and add a new - "#subst" directive that is actually far more similar to - what #define does in C/C++. In addition, the syntax of - #subst is a superset of that of the old #define in - Small, so old scripts continue to compile. - While "renaming" #subst to #define, I added the #undef - directive. - -29/09/2003 The report file is now in XML format. This probably makes it - easier to integrate it into other applications. - For the #include directive, it is in most circumstances no - longer necessary to enclose the filename in quotes or - in angle brackets. - There is a syntax for "literal strings" (and also for "literal - characters", but this is less important). A literal - string does not recognize "control characters" (which - are what C/C++ calls "escape sequences"). - The default control character ("escape character") is now a - backslash (instead of the caret). I used the caret - earlier, because DOS/Windows uses the backslash as a - directory separator. The backslash is so common as a - "special character" in Unix and other programming - languages, that I now feel that choosing the caret was - a wrong choice. - For backward compatibility, you can create a SC.CFG file - and add the command line option "-^". - -18/09/2003 An "enum" can now also be given an explicit tag. If an explicit - tag is absent, the name of the enumeration will be - de default tagname (this is the old behaviour). - When there are three warning error messages referring to the - same line (or to the same multi-line expression), the - compiler now halts with a fatal error. This situation - is mostly due to the parser being unable to recover - from an earlier error. - The user-defined assignment operator is now implemented. This - operator allows you to implement your own coercions; - for example: from integer to IEEE 754 floating point - (and vive versa). - The assignment operator is also called for function - arguments that are passed "by value". - -15/09/2003 The peephole optimizer is now recursive. This allows the - optimizer to re-evaluate the code after initial - optimizations. In addition, I have added a few rules. - Some minor corrections in AMXEXECN.ASM so that it works better - with older versions of NASM. In addition, with GCC, - the assembler version was never used, due to an - incorrect conditional compilation ("#ifdef") test. - - 8/09/2003 Many bug fixes. Over the last year, several bugs (and fixes!) - were reported on the Small forum. Apart from a few that - I could not reproduce, these have been fixed in this - release. Thanks go to "chop", Chris Jones, Nacho, - Lajos Molnar, "John", Jeppe Oland, RTaylor/Akira, - Stephane Denis, James Haley, and probably many others. - A new operator "tagof", which will be useful for functions with - plurally tagged arguments. - New functions in the Abstract Machine: amx_FindNative(), - amx_GetNative() and amx_NumNatives(). - The floating point support file (FLOAT.C) was changed to no - longer require dynamic memory (malloc/free). In - addition, a new rounding mode was added, which mimics - the way that C/C++ "truncate" floating point numbers to - integers (on a type cast). - - 1/09/2003 The Small compiler now has a preprocessor. The preprocessor - matches text patterns and replaces them with other - patterns. The syntax for the patterns differs from - both the C/C++ preprocessor and from the "regular - expression" syntax, though (Small's preprocessor was - inspired by TeX macros). The Small manual was updated. - From a high-level description of the implementation of a - LINT-like tool, I got enough information to add two - more warning messages to the Small compiler: - "unreachable code" and "self-assignment". - The Small compiler creates "compact" P-code files by default, - but it cannot cope with input files whose "compact" - encoding would in fact be larger than their "plain" - encoding. (The problem lies in the "in-place" unpacking - in the abstract machine.) I prematurely fixed this - problem by generating a fatal error for those rare - cases, and requiring you to (re-)compile such input - files with "plain" encoding. - The sizeof operator now gives the number of elements in an - array. This means that for a two-dimensional array, it - can return the number of rows or the number of columns - (depending on the syntax of the sizeof operand). - -26/08/2002 An experimental "destructor" operator is implemented. The "~" - operator is automatically called when a variable drops - out of scope. - A few performance optimizations in the generated pseudo-code, - especially for "for" loops. - A bug where the "function should return a value" was not given - is fixed. This ocurred in a situation where you said - "new myvar = myfunc()" where "myfunc()" does not return - a value. - The "expand" function now also uses the stack space while - expanding. This hopefully solves the (already rare) - cases where the expand function got short of buffer - space. Bug reported by Robert Daniels. - Maurizio Ferraris reported a bug where the compiler crashed - when it tried to recover from a symatic error in a - particular context. - Frank Condello donated a Macintosh port of the compiler and - abstract machine. His changes were merged with this - release. In addition, there is a separate directory - with additional source code and a CodeWarrior project. - -19/08/2002 Native functions can now also force a "sleep", simply by - returning AMX_ERR_SLEEP. - - 6/08/2002 To avoid the problem of structure fields being aligned - differently by different compilers, the header format - was changed to exploit "natural" alignment. Even - compilers that do not support "#pragma pack()" should - not have the good alignment. The changed header lay-out - is the main reason that this release got version number - 2.0. - There is a new compiler option, -A, and a new #pragma, "align", - which allow you to align variables on a boundary that - is an arbitrary power of 2. These tricks are sometimes - convenient (or necessary) with native functions that - use SIMD instructions. These changes are based on - code donated by Stephane Denis. - New functions amx_Clone() and amx_MemInfo(), both to support - cloned abstract machines. - For using bit masks as light-weight sets, the "enum" - instruction supports automatically multiplying by 2 of - all constants. - As an optimization, the compiler now generates a "halt" - instruction at address zero, so that the "RET" and - "RETN" instructions do not have to check for a special - zero address. - Dan Andersson found a bug in the JIT, which has now been - corrected. The JIT has also been brought up to date; it - now supports the "sleep" instruction. - As suggested by Stephane Denis, amx_Exec() now verifies that - all native functions used in a script are actually - registered, before executing any of the script. - The debugger can now optionally use the Unix "readline" package - for a more convenient command line. Due to the design - of the readline package, it requires that you build the - application, with the same compiler as the one that was - used to create the readline DLL or shared library. As - such, I recommend that you only use the "readline" - package with Unix/Linux or Microsoft Visual C/C++. - One could easily make mistakes with floating point variables - and the user-defined operators without any warning from - the compiler. For example, in several situations, - forgetting a "float:" tag on a variable declaration - gives no warning but generates completely wrong code. - Therefore, I have modified the floating point support - to use "strong" tags, i.e. "Float:". You may need to - modify your scripts if you work with the new include - files "float.inc" and "console.inc". You can look up - the "strong tags" issues in the language guide. - - 6/05/2002 Oops, skipping compound blocks in the first pass, introduced - at 25/02/2002, caused several regression failures; in - retrospect, the compiler really needs to scan every - statement in the first pass, to record the function - and variable usage. - Maurizio Ferraris donated a modification of the compiler that - gives it support for multiple "include" directories. - BUG fix: there was a peculiar parsing error that started with - a call to an undefined function, continued with the - compiler confusing code with data declarations, and - ended with the compiler generating faulthy code without - any error/warning message whatsoever (bug reported by - Maurizio Ferraris). - BUG fix: when you use "#pragma ctrlchar" halfway a program, - the second pass uses the new "ctrlchar" value right - from the start, which causes trouble if include files - depend on the original (or default) value. (This issue - was brought to my attention by Florian Zschocke.) - BUG fix: the AMX function amx_GetAddr() could return success - on a negative address (bug reported by Robert Daniels). - BUG fix: when re-defining a function with more parameters than - the previous definition, the compiler could crash when - it tried to compare the parameter lists of the old and - the new definitions; the compiler didn't check the - length of both lists (bug reported by Robert Daniels). - -25/02/2002 BUG fix: when the conditional operator has unindexed arrays as - its second and third operands, the "variable type" - of the resulting expression should also be an array. - (Bug found by Linus Nuber.) - To increase the performance of the compiler, compound blocks - are skipped in the first pass (the Small compiler is - a two-pass compiler). - -14/02/2002 The manual is split in half: there are now two "Small booklets": - one covering the language and one for implementing - Small in applications. Much of the information from the - README.TXT is now the the ``Implementor's Guide''. - The new Implmentor's Guide also got a section on calling - public functions (other than "main()") and passing - parameters (both numeric and string parameters). - -13/02/2002 BUG fix: the JULIAN.SMA example program had an error in the - check for dates in the month February (bug reported - by Jan Vooijs). - -12/02/2002 "chop" found a series of bugs in the Small compiler and the - abstract machine: - BUG fix: the functions strpack() and strunpack in AMXCORE.C - check the validity of the memory range for the - destination string. However, the number of bytes that - were checked was far too small: the checking code - confused sizes of bytes and cells. - BUG fix: the functions amx_StrLen() and amx_GetString() in - AMX.C, the functions amx_StrPack() and amx_StrUnpack() - in AMXCORE.C and the function printstring() in - AMXCONS.C all had a problem with determining packed - strings, in case you use characters above ANSI 127. - The manual also had an error in the "ispacked()" - function in the chapter ``Assorted tips'' had the - same error. - BUG fix: in the Small debugger (SDBG.C) a check for an - available breakpoint entry was missing a semicolon. - BUG fix: chained operators did not work correctly with - user-defined relational operators, because the operator - functions garbled the ALT register. The ALT register is - now saved around the call. - BUG fix: a global variable being used prior to its definition - was not flagged correctly; it also caused a code - generation error. - - 7/02/2002 BUG fix: The AMX DLLs apparently had problems when being used - with Microsoft Visual C/C++, due to a calling - convention mismatch (failure to save/restore some - registers). - Clem Vasseur proposed a binary search for the opcode lookup - in the compiler. This has been implemented. - - 5/12/2001 Linus Nuber found that double-character user-defined operators - and debug information (options -d2 or -d3) do not go - well together: the size of a SYMBOL opcode may overflow - the size that the compiler initially estimated and this - causes the function to be generated at the wrong - address. - -30/11/2001 As per the request of Linus Nuber, I changed the way that the - compiler options are set and reset. Now the -C, -P and - -; options can have a "+" or "-" suffix that sets or - clears the desired option; without suffix, the option - is toggled. With this, you can set your default options - in the configuration file (SC.CFG) and toggle the - option on the command line. - -27/11/2001 "Compact encoding" of the .AMX file has become the default; use - the "-C-" compiler option to return to the old (plain) - encoding. - -23/11/2001 BUG fix: Linus Nuber found a code generation bug in the case - where a user-defined operator was called with a - constant on either size, such as "1.5 * 2.5" with - operator*(float:a, float:b). - -20/11/2001 BUG fix: Gilad Novik found that unused public variables would - be stripped from the compiled file and their addresses - re-used by other global variables (or array literals), - but that the public variable was still listed in the - file header. - BUG fix: when you ask for "sizeof x" and "x" is an array of - indeterminate size, you get a warning. The warning did - not occur if the "sizeof" expression appeared in the - default value of a function argument (in a function - definition). The lack of the warning makes the "sizeof" - default value error prone, the warning makes it safer. - - 8/11/2001 The manual was updated to include the changes since the last - public release of the Small toolkit. - The performance of the compiler was enhanced. - -30/10/2001 You may specify a hard "index" for a native function, which - omits the native function from the compiled .AMX file. - For this to work, you need to implement your own native - function dispatcher; see the manual. - As per the suggestion of Stephane Denis, I used the more - specific integer types int16_t and int32_t in structure - definitions. These are defined in the ISO C99 standard. - - 9/10/2001 The default value of a function parameter can now be the - "sizeof" of another parameter of the same function. - This is convenient to pass the sizes of array - parameters to the function without requiring the - programmer to explicitly pass the size. - The new SC_LIGHT macro allows you to exclude non-essential - components of the Small compiler upon recompilation. - These components are: the cross-reference report (-r - option), parsing of "response files" and the default - configuration file ("sc.cfg"). More may follow (for the - moment, the peephole optimizer is considered - "essential"). - -10/09/2001 BUG fix: getproperty() of the "core" native function set read - contents from a memory block after freeing it. - BUG fix: a bit of code that writes the AMX file header still - assumed that a cell is always 32-bit. - BUG fixes: in the symbol name handling of user-defined - operators. There were several bugs; the operator that - suffered the most from these is probably the unary - minus operator. - -28/08/2001 BUG fix: defining the % operator would often introduce an error - in the symbol table. Cause: the % character is special - for sprintf() functions that the compiler uses to - construct symbol names. - BUG fix: Linus Nuber reported a bug where functions that were - called before their definition would be marked as - "unused" and stripped from the compiled code. - BUG fix: Clem Vasseur noted that on a fatal error, the local - variable table was not cleared; this then subsequently - fires an assertion in the exit code. - A prototype mismatch (of sc_error()) between the source and the - header files was also reported by Clem Vasseur. - -27/08/2001 BUG fix: Dario Sacca sent in a fix for an error in the - assembler implementation of the abstract machine. In - the debug hook for the line opcode, the "frame" offset - was not updated correctly. - New compiler option: -r, to generate a cross reference report. - The report lists all constants, global variables and - functions and tells what function is accessing them. - Stock functions that are never used are still in the - report. Native functions that are never used are not - in the report. The report file is intentionally - formatted in a minimal way, to make it easier to have - it parsed by other programs (call tree, cross-reference, - etc). - - 8/08/2001 BUG fix: Linus Nuber was surprised to find that the version - uploaded 5 August no longer accepted user-defined - operators that were declared as stock. This - embarrassing bug is fixed. (Oh, and a silly error in - the Linux include file, also reported by Linus Nuber, - was fixed too.) - BUG fix: Odie Calima found a few more global variables that - needed to be cleared on exit. - - 3/08/2001 BUG fix: Robert Daniels found a code generation bug in the - situation where a "for" loop contains a variable - declaration in its first expression and a break in its - body. This is now fixed. - -23/07/2001 The debugger got a minor improvements (quiker redraw of the - screen in termibal emulation mode). - Using a "&" where a "&&" is probably intended, or a "|" where - a "||" makes more sense, is now detected by the - compiler. (Actually, the compiler already issued a - warning for this, but it did it dumbly and too often; - now, when the compiler warns for a possibly unintended - bitwise operator, it is very likely indeed an error.) - -16/07/2001 The general purpose DLL calling functions have been implemented - fully and documented in the manual. - - 2/07/2001 Stock variables: if no function accesses a global variable, - this variable gets stripped from the compiled output - file, and without warning if that variable was declared - "stock". - BUG fix: a bug in appending implicit extensions to #include - files was fixed. - Functions and global variables can be declared "static", which - restricts their scope to the current file. - -25/06/2001 BUG fix: if you omitted the colons on cases in a switch - statement, the compiler hung. This was corrected. (Bug - found by Joe Hansche.) - The detection of unused functions has improved. Specifically, - if function is called only by other functions which - are never used, that function is marked unused as well. - BUG fix: a script that was edited under DOS/Windows and - compiled under Linux, would give error "invalid line - continuation" for a "//" style comment. This was - corrected. - -27/04/2001 BUG fix: Stéphane Bouteille corrected another error that had to - do with Big Endian memory layout (in amx_Exec()). - I added "strong" tags in addition to the current "weak" tags. - See the manual for the differences. - -17/04/2001 I added a -S option to the compiler to set the size - of the stack+heap (what you would otherwise need to - do with #pragma dynamic). - The Small compiler now parses a SC.CFG file with default - options (if that file exists). If the executable of - the compiler is called "SC16.EXE" or "a.out", then the - configuration file will be "SC16.CFG" and "a.cfg" - respectively. - The DLL version of the abstract machine got two new native - functions: loaddll() and freedll(). The calldll() - function that was already present could only call into - DLLs that had already been loaded. - -10/04/2001 Added a swapchars() core function that swaps all bytes in a - cell (so the low byte becomes the high byte). - More new native functions are a set of date and time functions - in AMXTIME.C and TIME.INC. - Dieter Neubauer made a 16-bit version of the Small tools - (meaning that a cell is 16-bit, instead of 32-bit). - His changes were merged in the original distribution. - - 5/04/2001 BUG fix: Raymond Holz found that the Small compiler returned 0 - after a "fatal error", where a return value of 2 would - be expected. - BUG fix: Linus Nuber found that accented characters were - treated as either negative values or as positive - values, depending on the C compiler used to build the - Small compiler. - Linus Nuber also found that the compilation instructions in - the README.TXT were inadequate for the Linux platform. - The README.TXT is corrected and a few details in the - Small compiler were adjusted (for Linux) as well. - -23/03/2001 BUG fix: Linus Nuber found a bug in default array parameters - that were tagged as const. As an optimization, the - compiler does not copy such arrays to the heap, but the - compiler DID try to remove them from the heap. - -12/03/2001 Overloaded operators are (finally) "operational". The manual - is updated to show how this new feature works. - The compiler supports literal values with a fractional part, - but you must enable this support specifically: Small - can interpret these so-called "rational numbers" as - either fixed point or as floating point numbers. Again, - see the manual for details. - For your convenience, I updated the FIXED.INC and FLOAT.INC - include files. The pre-compiled SRUN.EXE (Win32) - includes the "float.cpp" module. - - 5/03/2001 BUG fix: native functions strpack() and strunpack() mixed up - the source and destination strings. - Maintaining correct tags became inconvenient at times; I - therefore introduced the "default tag" override "_:". - This token removes any tag from its operand (on the - right). - -23/02/2001 BUG fix: the code generation for the INC.I and DEC.I opcodes - was wrong (the compiler encoded one parameter). - BUG fix: code generated for an expression like "array[index]++" - was wrong: the loading of the expression result - garbled the address of the array cell to increment - subsequently. - -19/02/2001 Relational operators now always set a "bool" tag on their - expression result - Native functions may have an "alias" name. This lifts the - limitation of 19 characters for a native function. - -15/02/2001 On a fatal error, the Small compiler now forces a jump back - through the main function, rather than aborting the - program. This allows for easier embedding of the - compiler in an application. - -25/01/2001 The "sleep" instruction is implemented, but quite differently - than the partial implementation (of 19/12/2000). The - sleep instruction takes an optional expression (like - the "return" and the "exit" instructions) and ends the - abstract machine in a way that it can be restarted. The - tagname of the expression of "sleep" is also saved (in - the ALT register), so that you can attach a "meaning" - to the expression. - The changes from the earlier (partial) implementation - are that I used the HALT opcode rather than the SLEEP - opcode (and I subsequently removed the SLEEP opcode). - The HALT opcode needed modification to support a - restart of the AMX. - The AMX file format now saves exported tagnames (tagnames that - are used on the "sleep" and "exit" instructions) and - the abstract machine has three new functions: - amx_NumTags() - amx_GetTag() - amx_FindTagId() - The SRUN sample is adapted for the "sleep" instruction, but - simply ignores it. The SDBG sample ignores the sleep - instructions as well, but prints an informative message - when it occurs. - Due to optional semicolons, the end of an expression is now not - always easy to detect. Quite often, an error in an - expression can only be flagged when the end of the - expression has been found. As a result, an error is - now sometimes flagged one or more lines below the line - that really contains the error. This has been fixed - by giving both top and bottom line numbers between - which the error was found. - -28/12/2000 The DBG_LINE opcode can now abort the abstract machine. This - makes it possible to have a simple debug hook that - breaks out of "hung programs" (infinite loops). The - SRUN sample shows how to set this function up. - -19/12/2000 Søren Hannibal implemented a "sleep" opcode to have a - light-weight multi-tasking of abstract machines. - Preliminary support for the sleep is in this version - (basically I copied just Søren's changes). - BUG fix: adding a "tag" to a constant declared with a #define - caused an error message with a garbled symbol name. - (Bug found by Søren Hannibal.) - A few minor memory leaks were fixed. - -12/12/2000 BUG fix: the conditional operator generated wrong code if the - "false" expression was a constant. (Bug found by Linus - Nuber.) - Variables and function arguments can now be declared "const". - Two typical uses are declaring a public variable - const (so only the host application can modify them) - and declaring array arguments const (arrays are always - passed by reference). - - 4/12/2000 BUG fix: the import library for Microsoft Visual C/C++ for - AMX32.DLL had an incorrect definition for amx_Exec(). - -24/11/2000 BUG fix: public functions should not allow default values for - their parameters, as their is no way that you can set - the defaults from the C/C++ side. - Unused parameters of public functions do not issue a warning - anymore; public functions often have a "required" - interface, so an unused parameter cannot be simply - deleted. - Parameters of a function may have multiple tags between braces. - This allows the function to accept a selection of - parameter "types". For an example of the syntax: - native Move({sprite,actor,weapon}:animob, x, y) - Function "Move()" can take as its first parameter a - handle tagged as "sprite", "actor" or "weapon". You can - use this on non-native functions too. Inside the - function, the parameter "animob" has the tag that is - first in the list (so "sprite" in this example). - BUG fix: after an earlier fix, SDBG now removed symbolic - information for static variables too early. (Bug found - and corrected by Linus Nuber.) - -18/11/2000 BUG fix: the "not" operator did not work in the Assembler - code of the abstract machine (AMXEXEC.ASM), due to - an "aggressive" optimization (by me, probably). - -14/11/2000 BUG fix: an expression like "if (1==1)" gives a warning about - a test that is always true, but then continues to - generate faulthy code. (Bug found by David Burgess.) - BUG fix: the SDBG debugger did not remove symbols for static - variables, causing a new one to be declared for every - call to a function containing the static declaration. - (Bug found by Linus Nuber.) - - 1/11/2000 BUG fix: AMXEXEC.ASM can now finally be assembled with MASM - without using the "code segment" trick. This was - important because Visual C/C++ 6.0 returns incorrect - addresses for data declared in the code segment. - -26/10/2000 The Small compiler is now a two-pass compiler; prototypes are - no longer needed. - An internal problem, where the end of an expression could not - be determined (due to optional semicolons) in the - presence of a "preprocessor" directive, was fixed. - Array arguments with a default value are now copied to the heap - if the default value is used. This *fixes* the problem, - rather than trying to forbid it (as in the release of - 9/10/2000). The issue, by the way, was pointed out - by Søren Hannibal mid July (I may be slow, but I am - persistent). - The new function amx_Execv() allows programming languages other - than C/C++ use the AMX DLLs. It is limited to up to - four parameters, however (this is easy to change if - you ever need more). - A bug where a recursive function provoked a warning about a - missing return value was fixed. - -19/10/2000 The SDBG debugger prints the return value of functions. The - integrated debugger in the DLL also supports a few - function keys: - F1 = Help - F3 = List (refresh screen) - F5 = Go - F8 = Step (trace into functions) - F10 = Next (step over functions) - A new "interface function" in the compiler, sc_error(), lets - you intercept error/warning messages that are produced - by the compiler (if you statically link the compiler as - a "library function"). - -09/10/2000 BUG fix: using the -C and -d2 compiler options together caused - wrong encoding. - The debugger is integrated in the AMX DLLs. If you compile - with debug information, the debugger will launch - automatically. The AMX DLLs support a subset of the - ANSI terminal escape codes, so that it has a slightly - better interface. - The AMX DLLs have two new native functions: iswin32() allows - you to check whether you are running with the 16-bit - or 32-bit DLL and calldll() allows you to call any - DLL function (provided that it has a standard calling - convention). - Array arguments with a default value may not be modified (as - arrays are always passed by reference, and allowing - this would change the default value). - Updated documentation. - -27/09/2000 Definition of "interface functions" (called by the compiler) - allows to compile the Small compiler as a "library". - See the README.TXT file for details. - To use the Small compiler as a linkable library, a set of macro - definitions allow for a drastic reducal of namespace - polution (by global variables and functions). - A function may be declared as a "stock" function, which means - that if it isn't used, it may be stripped from the - compiled program (without warning). This way, you can - make "library" functions in header files. - -11/09/2000 A bug was fixed concerning the use of #endinput within an - #if ... #endif section; the compiler did not reset - the "#if" nesting level on #endinput. (Bug reported - by Jim McGinty from Artran, Inc.) - Expressions like "1 <= var <= 10" are now allowed. The result - of such an expression is 1 if all conditions hold, and - zero otherwise. The "chained relational expressions" - feature was copied from BCPL. - New opcodes SWAP.pri/alt, which are needed for chained - relational expressions. - New opcode PUSHADDR, which optimizes passing a variable by - reference. - By generating better pseudo-code for the "for" instruction, the - "Sieve of Erathosthenes" runs approximately 10% faster - (w/o print), and so will typically all small "for" - loops. - To better cope with the ever expanding lists of error/warning - messages and peephole optimizer sequence strings, these - strings are now compressed. They are still compiled as - literal strings in the executable, but a separate - utility, SCPACK, preprocesses the files and compresses - the strings. - -14/08/2000 Semicolons are now optional by default. This may give, in your - existing programs, warning 218 ("old style prototypes - used with optional semicolumns"). Use the "forward" - keyword to forward-declare functions; use the "/;+" - compiler option to "require" semicolons. - As per suggestion of Søren Hannibal, you may now mix positional - and named parameters in a function call, with the - restriction that all positional parameters must precede - all named parameters. Thus a call like: - getproperty(123, .value = 456) - would now be valid. - -24/07/2000 A large set of bugs, reported by Søren Hannibal, were fixed. - These include: - * code generation error for function arguments that are - passed to sub-functions by reference and that were - passed by reference themselves too; - * code generation error for labels (for "goto"); - * literal arrays passed to functions were always - flagged as "not the same size as the formal argument" - * missing "#endif" at the end of the main file was not - (always) detected - * reaching end-of-file while inside a /* ... */ style - comment was undetected - * address 0 is a valid address, so the fix in the - release of 17/07/2000 for amx_Exec() actually - introduced an error. - -19/07/2000 As per the suggestion of Søren Hannibal, the NO_OPTIMIZE - macro is replaced by a command line option in the - compiler (-d3). - -17/07/2000 Underscores between digits in a number are now allowed. This - may improve readability of large integers (for - example: 1_234_567) and for literals used in fixed - point expressions. - #pragma library is now (finally) working. This allows you to - give a tag to each native function to which - (dynamically loaded) library it belongs. The abstract - machine has functions to extract the library names that - it needs to load. - amx_Exec() will no longer start executing from address 0 if you - feed it with a program without a main() and ask to run - the "main" entry function. - The DBG_CALL event now tells to which address it is about to - jump, so a stack trace can be built. In addtition, you - will get a DBG_CALL event for the entry point (so that - the stack trace is never empty). - The sample debugger was extended with stack trace commands and - an option to print a one-dimensional array as a string. - -26/06/2000 A code generation bug (found by Dark Fiber) in the last update - was fixed. - -29/05/2000 Three bug corrections in the initialisation of the staging - buffer (that will teach me to easily change data - structures from "fixed size" to "grow as needed"). - Support for public variables (in addition to public functions). - Since the manual is not yet up to date, here is a - summary: - * Only simple (global) variables can be public, no - arrays - * To create a public variable, "public" replaces "new": - public myvar; - * Alternatively, the '@' prefix works as well: - new @myvar; - * To access public variables from a C/C++ program, use - the new AMX functions: - amx_NumPubVars() - amx_GetPubVar() - amx_FindPubVar() - amx_GetPubVar() and amx_FindPubVar() return the - address of the variable relative to the AMX; use - amx_GetAddr() to get a pointer to the cell - There was (still) a problem with the stack clean-up. I don't - know what I was thinking three months ago when I made - my first fix, but I probably only tested the 32-bit - version. - Someone sent me a bug report concerning a prototype mismatch - that I misclassified. I found it again by accident, - corrected the bug that the example demonstrated and - added it to regression testing. - The BCPL manual from Martin Richards pointed out that when you - have statements end implicitly on a line end, but still - allow expressions to wrap over multiple lines, there - may be a problem with unary operators. I tested a few - cases and, indeed, found an error. - -22/03/2000 Bug correction in the dynamic growth of the staging buffer. - Bug correction in the stack handling of amx_Exec(), which did - not remove arguments from the "abstract machine" stack. - If you ran the same AMX program over and over again - (without reloading it), you would slowly eat up the - AMX stack. - While correcting the above mentioned bug, I also added code to - clean up the stack "the hard way" on a run time error. - The extra local variable required for this also lets - me verify (with an assertion) that the normal route - indeed cleaned up the stack correctly. - Bug correction in the assembler version of the AMX: when - compiling with a stack-oriented parameter passing - convention, it must also save the value of EBX. - -13/03/2000 Using symbolic constants in the "case" statements of a "switch" - could cause the label to be interpreted as a tagname. - Marc Peter converted the JIT to use __cdecl calling convention - and added (minimal) support for the SRANGE instruction - at the same time. This means that you can now use the - JIT with Borland or Microsoft's compilers. - Dark Fiber contributes an AMX extensions with high quality - pseudo-random numbers, plus a simple card game as a - non-trivial example script in Small. - -17/02/2000 An attempt to assign a value to a constant (or any expression - that is not an lvalue) inside a test, resulted in an - assertion failure or a crash. - The compiler let invalid prototypes pass, while complaining on - correct prototypes. - Logical expressions with && and || operators were never - identified as "constant expressions", even if the - operands on either side were constants. This prevented - such logical expressions to be used in preprocessor - expressions. - The "loose indentation" warning works nicely if you use only - TABs or only space characters to indent a line, but if - you use a combination, the warning fires even if there - is no reason. To lift this problem, the current release - introduces the -t option and the "tabsize" pragma (with - which you can set the tab size). - Years ago the compiler was changed to align all opcodes to 4 - byte boundaries, to increase the speed of the virtual - machine at the expense of larger compiled files. The - current release introduces a -C switch with which the - compiler writes the output file in a more compact - encoding, at the cost of slightly longer load times. - -16/12/1999 Marc Peter corrected a problem in the JIT. - Path names with embedded spaces caused the compiler to fail if - you compiled with the -d2 option. - Bernard Fouche ported the sources to Linux. Based on his - changes and comments, the portability of the compiler - and the abstract machine have been improved. - Symbol names now have 31 significant characters. Native and - public names still have a maximum of 19 significant - characters. - -19/11/1999 Bug correction in the "for" loop concerning local variables at - the same scope as the "for" loop (found by Joe Felton). - amx_Exec() can now take NULL for the parameter for the script's - return value. - New function "random()" in AMXCORE.C. - -12/11/1999 Some changes for Greg Garner's module for floating point - support. - Two more "interface" function for the compiler. These functions - allow you to set "pre-defined" tag names and constants. - AMXCONS.C includes two more native functions to read a - character or a string from the keyboard. - - 2/11/1999 Fixed minor annoyances in the compiler like failures to find - the include path on non-DOS platforms. - -25/10/1999 Warning message for local variables that "shadow" a function - or a variable at an earlier scope (by having the same - name, they make the earlier symbol inaccessible). - Warning message for the infamous "dangling else" problem. - Bug correction: functions with upper case letters were not - assembled correctly (bug found by Greg Garner). - New control character "^e" which has value 27 ("escape"). - -12/10/1999 The abstract machine is now also available as a DLL for - Microsoft Windows. Both 16-bit and 32-bit DLLs are - provided (including source). - - 1/10/1999 Semicolons to end each statement can now be made optional with - the compiler switch "-;" or with: - #pragma semicolon false - The assembler implementation of the abstract machine now also - supports __stdcall declaration. See the README for - information on compiling. - There are now two "fixed point" libraries: binary (18:14) and - decimal (three decimal digits). The decimal fixed - point library may be more "exact" when working in "real - live" calculations (which are often based on a decimal - base). - -27/08/1999 Bug correction: parameters passed to a Small function (called - with amx_Exec() were not stored at the correct - location (bug found & corrected by Marc Peter). - Marc Peter's JIT underwent radical changes: on the "Towers of - Hanoi" benchmark the increase of performance is 80%, - see the history log in JIT.ASM for details. - -23/08/1999 The assembler version of the abstract machine (by Marc Peter) - now also compiles with Microsoft Visual C/C++ 5.0 and - 6.0. - Bug correction: using the assembler abstract machine in a - program with a default calling convention of __stdcall - resulted in a crash. - -20/08/1999 Mark Peter's Just-In-Time compiler is now integrated with - the standard release. The JIT gives yet another - major increase in performance. - -18/08/1999 The assembler version of the abstract machine (by Marc Peter) - now also compiles with Borland C++ 5.0. - Updated documentation; better lay-out too. - -31/07/1999 Small supports two-dimensional arrays. See the manual for - the precise syntax and usage of this new feature. - -18/07/1999 Plus debugging opcodes for the size and dimensions of an - array. - - 2/07/1999 Trailing spaces are ignored when concatenating lines with - a \ at the end of the line. - - 7/06/1999 Updated the Assembler AMX (by Marc Peter) for the new - opcodes (e.g. the SWITCH opcode and associated - case table). - Bug correction: the compiler could "ignore" a fatal error - in a rare condition, leading to a crash or random - output. - Bug correction: overflowing the stage buffer issued the - wrong error message ("cannot read from file"). - -24/05/1999 The switch statement was redesigned: the minor improvement - is the support for ranges (e.g. "case 1..8:"), the - major change is the fastly improved code generation. - -10/05/1999 The compiler has an option to switch the syntaxes for packed - and unpacked strings; there is also a new #pragma to - to this. - and unpacked strings. - - 1/05/1999 Array assignment is more relaxed for literal strings: the - destination array does not have to be exactly the - same size as the string length (in cells). - -17/04/1999 Terminal support (ANSI escape sequences) for the debugger. - The debugger supports "watches" and a few more commands. - -15/04/1999 Support for static local variables. - Bug correction: the compiler did not give an error message - when returning an array from a function. - New commands in the debugger: - "GO RET" (run until function exit) - "GO n" (run until line n) - "LIST ON" (list 10 source lines after each step) - "LIST OFF" (turns above option off) - Pressing repeats the last STEP or NEXT - -12/04/1999 Bug correction for line continuation (\ at the end of the - line). - Error message when a \ appears in a single line comment. - New predefined constants "language" (version of the Small - language) and "compiler" (version of the Small - compiler). - -31/03/1999 Bug corrections for three opcodes of the abstract machine (none - of which were generated by the Small compiler) were - found and corrected by Marc Peter. - A bug in the fixed point module (relating the division of - negative numbers) was found and corrected by Marc - Peter. - Array assignment is permitted, under the condition that the - arrays at both sides of the "=" operator are of equal - size. - -24/02/1999 The compiler has an option to skip a number of lines before - starting to compile; this comes handy for scripts - inside text files. - The file format can now store the names of required modules - (that must possibly be dynamically linked); this is - currently supported through "#pragma library". - The new "#endscript" directive is an alias for the existing - directive "#endinput". - User data fields in the abstract machine are now "tagged", so - that you get some kind of name/value pair; you can - now determine whether a user data field is "in use". - The compiler has a few more command line options. - - 9/12/1998 Finished integration with Marc Peter's assembler abstract - machine, including the debugger interface. - Updated documentation for new features. - -27/11/1998 Two more warnings: nested comment and loose indentation (both - frequently indicate an error). - - 6/11/1998 Integration of Marc Peter's abstract machine in assembler (this - is still an experimental version). - - 4/11/1998 Major re-design of the compiler and the ANSI C version of the - abstract machine: opcodes are now cell sized. - -30/10/1998 Major changes in the debugger interface to accomodate the - design of a re-entrant debugger. - Early relocation of JUMPs and CALLs, which speeds up execution. - Changes in instructions to make array indexing faster. - New opcode to speed up passing long argument lists to - functions. - Variable arguments may now be tagged. - The manual got another full reading... and corrections. - -23/10/1998 New directive "#emit" for those who want to program directly - in the assembler of the Small abstract machine. - New directive "#endinput" to skip the rest of the file. - New function amx_FindPublic() that returns the index of a - public function whose name is specified. - Public functions are now written to the output file in sorted - order; this allows a quicker lookup of a public - function using a binary search. - "funcidx()" is a new native function in AMXCORE.C that returns - the index of a function in the "public function table" - so that a script can return the index that the - application should call next. - -19/10/1998 BUG fix: when calling an unknown function, the compiler would - issue a diagnostic and then crash or hang. - Command line options changed; you can now also add definitions - on the command line of the compiler. - The debugging interface changed (it became simpler), a console - mode debugger is included as an example. - New function amx_Flags() to check whether the compiled program - contains symbolic (debugging) information. - The property functions (core library) got an extra parameter - to avoid ambiguity in some cases. - A new "native function" module: fixed point arithmetic. - Clarifications and corrections in the manual. - -01/10/1998 BUG fix: conditional expression was inverted! - BUG fix: conditional expressions or logical operators generated - incorrect jumps when used in function arguments - (because arguments are evaluated right-to-left, but - code is generated left-to-right). - Support for named parameters (in addition to positional - parameters). See the documentation for this major - feature. - -28/09/1998 New functions pass strings between C and Small functions. - Run-time check for Little/Big Endian machines. - Some extra compiler checks: unused local constants and - side-effects of expressions. - -24/09/1998 BUG fix: code generation bug when incrementing or decrementing - a "reference" argument with the "++" or "--" operators. - Support for accessing (packed) characters from a (cell) array - with the {..} operator (function similarly to the [..] - operator). - REMOVED module names for native functions. This turned out - to be a feature that complicated the implementation - without adding much. - Several changes in the AMX, removed amx_CheckModules() and - amx_Unregister(). No need for callback functions - in an extension module. New function amx_NativeInfo(). - -22/09/1998 Support for Unicode characters in strings and character - literals. - Support for line concatenation with a backslash at the end - of a line. - Two more predefined constants: cellbits and charbits give the - size of a cell and a character respectively. - More error messages (errors 41 and 42 are new). - Functions whose name start with an '@' are always public. - An indirect threaded interpreter of the abstract machine - (AMX.C) when compiled with GNU CC (I used Delorie - GCC). The GNU C version is twice as fast as the - ANSI C version. - BUG fix: the compiler had a memory leak in the allocation of - the type list of function arguments. - The #define directive can now easily be removed from the - language (its support is a kludge anyway). - Packed strings are now stored in Big Endian, and no longer - terminated with a full zero cell; the new specification - makes it easier to determine whether a string is - packed or unpacked. - - 3/09/1998 BUG fix: multiple initialized local arrays in a compound - block were not initialized correctly. - Memory for function arguments was not explicitly freed. - Support for literal arrays, just like literal strings, like - in "print( {'H','e','l','l','o',0} ); - Support for default values of array arguments, as in - "addvector(a[], b[] = {1, 1, 1}, size = 3);" - or - "messagebox(text[], caption[] = "error");" - -28/08/1998 BUG fix: local arrays were not initialized to their full - extent. - All unitialized variables and array elements are now set - to zero (default initialization). - A few clarifications and additions in the manual. - -24/08/1998 BUG fix: prototypes caused invalid code generation. - BUG fix: expression involving constants could generate invalid - code. - Added the FILL opcode in the abstract machine. - More compact code generation for arrays initialized to a - single value. - Extra error message 41 (invalid use of ellipsis). - -20/08/1998 Improved portability of the compiler. - -18/08/1998 First public release. +Version 3.2, build 3664 +----------------------- + +* BUG fix: using user-defined operators with the compiler option -O2 (for using + macro instructions) could produce code that the abstract machine finds + "invalid". Actually, the code is good, but the abstract machine sees a + combination of instructions that it does not expect. + +* The Linux autopackage now uses autopackage version 1.2. This should make the + Linux setup more robust. + +* BUG fix: The function libcall() in the amxProcess extension module pushed the + parameters in the wrong order under Microsoft Windows (when the module was + built with Borland C++ and perhaps with other C/C++ compilers too). + +* BUG fix: when the conditional operator is used in combination with functions + returning arrays, the heap was restored twice (once too often). In particular + the expression + a ? test1() : test2() + where test1() and test2() are both functions that return an array, had the + effect that both the "true branch" and the "false branch" allocate space for + the return value on the heap, and the heap is restored for the total of + test1() and test2() at the end of the expression. However, only one of the + branches is taken, so the heap is incremented for either test1() or test2(), + but restored for both. + + This bug was reported by Bailopan on the Pawn forum. + +* BUG fix: the heap checking (overrun and underrun) was incorrect in the JITs. + This made heap underflows go by mostly undetected. This bug was found by + Bailopan, when he investigated the bug with the conditional operator. + +* The expression "++a" in a statement like "return ++a" was optimized + incorrectly by the peephole optimizer, because it considered the expression + result as "unused". This also occurred in the statements "sleep" and "exit". + This bug was reported by Bailopan on the Pawn forum. + +* BUG fix: "nametable" field in the AMX header was swapped twice on Big Endian + architectures. This bug was reported by Pekka Nikander on the Pawn forum. + +* There is a new build macro to remove the default implementation of + amx_Callback(). A patch from Markus Schaber, on the Pawn forum. + +* The Abstract Machine core that uses computed gotos ("labels as values") is + now also used for the Intel C/C++ compiler (ICC). The Intel compiler supports + the GNU GCC extension. This change was suggested by Markus Schaber on the Pawn + forum. + +* The AMX API functions amx_PushArray() and amx_PushString() now accept NULL for + the "amx_addr" parameter. This is convenient, because amx_Release() can free + heap memory for multiple allocations at once. + +* The compiler now adds a warning for the expression + showval (a > 0) ? 1 : 2 + because this is interpreted as calling showval() with the parameter "a > 0", + like in: + (showval(a > 0)) ? 1 : 2 + What was intended is: + showval((a > 0) ? 1 : 2) + +* On Microsoft Windows, there is a second pre-compiled debugger that splits the + debugger output from the script output. This debugger is intended to be used + from an IDE like Quincy. + +* The definition of native functions has changed so that "params" is now a + "const" parameter. This gives some protection against inadvertedly changing + the stack in the abstract machine. + +* Improved support for running scripts in ROM. In this configuration, the P-code + of the script resides in ROM and the data/stack/heap is in RAM. The abstract + machine must be configured specifically for running scripts in ROM, because + various optimizations (such as relocating jump addresses) no longer work. + +* Various minor improvements to the Pawn debugger and the Quincy IDE. + +* Various minor optimizations and minor fixes. Some related to Macintosh + support, others to the Linux Autopackage. A few error/warning messages in the + compiler were made more precise/accurate too. + + +Version 3.2, build 3636 +----------------------- + +* Performance of the compiler has improved, due to a faster "memory file" + interface. The new interface was donated by the AMX Mod X team + (http://www.amxmodx.org). + +* BUG fix: for "optimize level" 2 and when using GCC or the assembler core, the + SYSREQ.N instructions were not replaced correctly by SYSREQ.ND. Mostly, it + failed to replace the instruction; when it did replace the instruction, it + did so at the wrong position, leading to a crash. This problem did not occur + with the ANSI C version of the abstract machine. + +* amxProcess now loads libffi dynamically, so that it works with both version + 1.20 and version 2.00-beta. Version 1.20 is the only release that can still be + downloaded separately, and which is needed for GCC versions before 3.4; + see http://sources.redhat.com/libffi/. + libffi is only used for the Linux version of amxProcess; the Microsoft Windows + version uses its own code. + +* Better checks for unreachable code, including a test for code following an + infinite loop. + +* If no AMXLIB environment variable is set, pawnrun and pawndbg now look for + the add-in modules in the same path as where they reside themselves. This + change makes it easier to run Pawn "out of the box" on Linux machines. + +* When making an array without specifiying the dimensions, but where the element + count at the lowest dimension is the same for all, the compiler now "counts" + this size, rather than setting the lowest dimension as "variable length". + + An example for this situation is the declaration: + new my_array[][] = { {1,0}, {2,1}, {3,1} } + No dimensions are given, but the new compiler determines that the minor + dimension is 2 (and the major dimension is 3). Previous compilers set the + minor dimension to 0 --meaning "variable". + +* BUG fix: #elseif handling did not work. Bug reported and patched by "rain" at + the Pawn forum. + +* A minor compiler bug (which surfaced when you would change the file output + stage) was reported by Bailopan on the Pawn forum, including a suggested fix. + + +Version 3.2, build 3599 +----------------------- + +* Constants (fields) in an enumeration may now be redeclared in other + enumerations, provided that all enumerations have a tag. When arrays are + declared with these enumeration tags for the index, the same constant + name may refer to different elements in different arrays. + +* The directive "#pragma depricated" now allows for a comment on the directive + line. This comment is appended to the warning message (warning 234). This + feature was requested on the Pawn forum by "Greenberet" and Felix Kollmann. + +* New extension module amxProcess, bringing process control and a "foreign + function interface" (meaning that you can call functions from dynamically + loaded DLLs in Microsoft Windows or shared libraries in Unix/Linux). There + is an example script, gtkcalc, that uses the amxProcess module to create a + simple GUI via gtk-server (see http://www.gtk-server.org/). + +* Pawn now uses autopackage 1.0.10, which fixes a problem with the zsh shell + (Linux/Unix). + +* BUG fix in handling the "precision" (i.e. the maximum width) of string + parameters in printf() and strformat() (from the amxCons and amxString + modules respectively). + +* BUG fix in using a state function before its definition, when this usage + occurs from a fall-back state. + +* BUG fix: the "@" character was not allowed in macro definitions (while the + documentation stated that they were). They are now allowed. + +* BUG fix: the retail binaries crashed when an extension module invoked a + public function on an event, and that extension module was in a DLL. The + cause was that the DLL contained its own copy of amx_Exec(), but possibly + one that was compiled differently from the amx_Exec() in the main program. + The fix is to let the main host program pass in a pointer to the correct + amx_Exec() to use. This bug was reported by Loo on the Pawn forum. + +* BUG fix: when compiling with -O2, an invalid assembler instruction + occasionally popped up. Reported by Brad Benjamin. + +* BUG fix: the OP_SYSREQ_N was not handled correctly in the assembly-optimized + version of the AMX. This opcode is only generated when the optimization level + (of the Pawn compiler) is set to 2. + +* BUG fix in amxCons in relation with amxString: when strformat() forwards to + amx_printstring() and the format string contains a %s, amx_printstring() is + re-entered, but the redirected output functions were not passed through. + + +Version 3.1, build 3541 +----------------------- + +* The debugger now allows for a "split-screen" build, meaning that the debugger + output goes to a simple console window/terminal (or "DOS box") and the + console output produced by the script goes through a second emulated terminal + (termwin for Microsoft Windows, or term_ga for GraphApp). + +* Minor improvements in the termwin pseudo-terminal, mostly concerning lay-out. + +* For warning 203 (symbol is never used), the reported line number is now the + line of the declaration of the symbol. For warning 204 (symbol is assigned a + value that is never used), the line number is the one at which the latest + assignment appears. + +* When the "sleep" instruction is used, the compiler now flags this in its stack + usage report. The stack usage may not be accurate in such case, because the + sleep instruction often permits re-entrancy (this depends on the host + application). + +* Quincy now checks for updates once a week. It downloads the PAD file for Pawn + and parses it using TinyXML. You can turn this feature off. + +* Relevant modifications from the Quincy 2005 project (http://quincy.codecutter.org) + were merged into the "Quincy for Pawn" project. + +* The Windows installer now registers the file extensions .p and .pawn and + associates these with Quincy. + +* BUG fixes related to the JIT (it had not been updated in a while). + +* BUG fix: a declaration like new array[1000][1000][1000] created invalid code + because the total array size exceeds 4 GiB. A check for this limit was + missing. Reported by Bailopan on the Pawn forum. + +* BUG fix: calling a public function from within a script (where the public + function lacks a forward declaration) crashed the compiler. Reported by + Bailopan on the Pawn forum. + +* BUG fix: the amx_StrParam() macro copied one character too few to the newly + allocated string. Reported by Peter W. + +* BUG fix: a script having zero native functions still required amx_Register() + to be called. This bug was fixed earlier, but it surfaces again... Reported + by Peter W. + + +Version 3.1, build 3526 +----------------------- + +* The setup program failed to put the documentation (PDF files) in the + "Documentation" sub-menu in the Start / Program Files menu. + +* Quincy was modified so that it would work when installed in a path with a + space character. In addition, the settings are now stored in an INI file, + which resides in the same location as the Quincy.exe file. I prefer INI + files, because they allow multiple installations of a program (in different + directories) with different configurations. + +* The modifications done by Allen Cronce for the Mac OS-X port were merged with + the main sources. Apart from the port, the modified source code also features + bug fixes related to the Endianness of the debugging information, so it is + relevant to all users of Big Endian architectures (and who wish to use the + debugger). + + +Version 3.1, build 3522 +----------------------- + +* Quincy, a C++ IDE written by Al Stevens and published in Dr. Dobb's Journal, + is now adapted for Pawn. This is a Windows IDE, featuring an editor and a + debugger. + +* Remote file uploading functionality in the Pawn debugger (for hosts that + support remote debugging). + Warning: For remote debugging, port 1 now refers to COM1 in Windows (and + ttyS1 in Linux); in previous releases you had to select port 0 for COM1. + +* State variables are now available. Just like local variables have a + function-local scope, state variables have a scope restricted to a state + (or a set of states) --but they may be used across functions that implement + that state. The documentation is up to date. + +* Keyword "state" is now also an operator; it returns "true" if the automaton + is in the indicated state. + +* Macro-instructions for common repeated sequences, for more compact code and + quicker execution. The new compiler option "-O" sets the optimization level. + The JIT does not support these macro instructions, and scripts that may need + to run on the JIT must therefore be compiled with -O1 (standard optimization), + which is also the default setting. + +* Support for re-entrant events in handling the "sleep" instruction. + +* Added a delay() routine in amxTime. + +* Added file matching and counting routines: fexist() (replaces the old + exist() function) and fmatch(). These routines allow wild-cards, similar to + those in the Unix shells. + +* The Path to the XSL stylesheet is now stored into the report, and the + stylesheet information is embedded in the XSL file. The generated report can + therefore be viewed directly (with a browser). + +* Dynamically loaded extension modules are looked up from the path in the + "AMXLIB" environment variable. This is especially useful for applications + that have a "plugins" directory, for contributed extensions in the form of + Pawn extension modules. + +* There is improved support for compiling scripts for execution from read-only + memory. + +* Native and public functions can be marked "depricated", to help upgrading to + new scripting environments. + +* To avoid a frequent error: (typing) error in the name/signature of a public + function, the compiler now issues a warning if no forward declaration exists + for a public function. The idea is that the (implicitly included) include + file that the host application supplies, contains forward declarations for + all public functions. + Warning: this may require that you add forward declarations to existing + header files. + +* The BinReloc package used for Pawn is now version 2.0 (see + www.autopackage.org). This package allows the Pawn compiler to be installed + in any path; it will always find the required include files in directories + that are relative to the path to the executable. + +* The compiler uses strlcpy() and strlcat() as safe alternatives for strncpy() + and strncat(). As not all compilers include these functions in their C + library, the source code comes with standard implementations in the file + lstring.c. + +* Fixed several bugs related to the order in which automatons were used and + declared. + +* BUG fix: the generated code for the entry function (state machines, or + "automatons") had the wrong stack convention. + +* Minor corrections in macros (for masking absence of terminal support) in the + console support (amxcons.c). + +* BUG fix in strmid() concerning short destination strings. + +* BUG fixes in the string packing routine (used a.o. by strcat()). + +* CMakeLists.txt for the compiler: minor path-related fix + +* BUG fix in amxjitsn.asm, where the JIT code was split into two different + sections for no good reason (probably predating the "mprotect" support code + in amx.c). Bug reported and fixed by David "BAILOPAN" Anderson. + +* BUG fix: arrays used in logical expressions were not check for full indexing + (as they should). Specifically, after declarating "new series[10]" an + expression like "if (series || 0)" would compile without errors. Bug + reported and fixed by David "BAILOPAN" Anderson (my fix is somewhat + different, to catch more cases). + +* BUG fix: the #error directive ignored the parsing state, so an #error + directive folded inside #if 0 ... #endif still fired. Reported by "chop". + +* BUG fix: the tagof operator used as a default value for function arguments + took the tag of a variable, but not of an expression. Reported and fixed by + Jonathan on the Pawn forum. + +* BUG fix in recursion detection. + +* BUG fix for the sleep opcode: the STK and HEA registers were not updated in + the AMX structure (ANSI C and GNU C versions only; the assembler versions + were correct). Reported and fixed by "chop". + +* BUG fix: the "JIT" flag was erased under specific conditions in amx_Init(). + +* BUG fix: memory block for the JIT code must be aligned under Linux. + +* BUG fix: structure packing was incorrect for GCC. Also removed "far" + pointers from the definitions of the debug structures. + +* Warning: The fixed point function fixedstr() is renamed to strfixed() to be + in line with the string functions strval() and valstr(). Similarly, + floatstr() is renamed to strfloat(). + + + +Change log for older releases +----------------------------- + +28/07/2005 BUG fix for the "switch" opcode in the JIT, in the situation + where only the "default" case was present (no other + cases, which means that the switch was actually + redundant). This bug found and fixed by Bailopan, and + reported on the Pawn forum. + BUG fixes for debugging symbols in 64-bit mode, found and fixed + by Bailopan and reported on the Pawn forum. + Fixes in the CMakeList.txt file for compiling under Linux/UNIX. + +22/07/2005 The compiler has native support for states and automatons. + Implementing finite state machines is thereby easier, + and the compiler helps in checking that the state + machine is coherent. See the language guide for details. + Several bugs related to arrays and enumerations have been + fixed. Some of these bugs were (also) reported by + Vic Viper on the forums. + Yet one more Big Endian bug was found and fixed. + Robert Daniels found and fixed a problem related to + 3-dimensional arrays with a variable last dimension. + His fixes have been merged in the main source. + A 64-bit bug found by Bailopan was fixed. Compact Encoding + should now also work with 64-bit cells. + There are three new native function modules: one with string + manipulation functions, one with simple network packet + exchange functions and one with time/date functions. + A general purpose way to accept event sources has been + implemented in the "pawnrun" example program and in + several of the native function libraries. With this + interface, a native function library can "register" + a public function that it will call upon a specific + event. See pawnrun.c and the modules "amxCons.c" + (@keypressed) and amxTime.c ("@timer") for details and + examples. + The debug protocol has changed completely. The old debug opcodes + are replaced by a single new opcode: BREAK. The debug + information is now appended to the AMX file, instead of + being intermixed with the normal opcodes. The rationale + of the new design is improved performance when running + scripts with debug information, and the ability to + do remote debugging. + The console debugger has been enhanced to support states and to + allow debugging over a serial line (RS-232), provided + that the host application supports the protocol too. + The screen lay-out was improved as well. + The Linux compiler now uses the BinReloc package from + www.autopackage.org to locate the include files and the + configuration file. This should be more robust than the + earlier hack. + The peephole optimizer was improved. After finding an + optimization, it now recurses over all rules to find + (more) optimizations on the adjusted code. + Documentation comments have been improved (and now include the + automatons and the transitions). The lay-out has been + improved as well. + New #pragma "amxlimit" lets the compiler verify that the script + fits the abstract machine after compilation. This is + useful for embedded devices with little memory for + scripts. + +18/03/2005 Small is renamed to Pawn. Changing the name has been requested + regularly, by various individuals, because searching + for information on the "small" scripting language (on + the Internet) was not exactly easy. The word "Small" + is fairly common. The new name, "Pawn" should improve + the odds that when you search for "Pawn scripting", + you will get information on the language. Together with + the product name, names of utilities and executables + changed as well. + Warning: when your host application relies on the name + of the compiler to be "sc.exe" or "sc", you must either + rename the executable after it is built, or you must + adjust your host application to run "pawncc.exe" or + "pawncc" instead. + The compiler is now built as a shared library/DLL. The compiler + command line program is now just a driver for the + library (except for the 16-bit version of the compiler). + The abstract machine can now support the JIT and the assembler + core together. In earlier releases, you had to choose + for either the JIT or the assembler core. As the JIT + does not support the debugging hook, the new scheme + allows you to build the abstract machine such that you + debug your scripts using the assembler core and run the + final version using the JIT. + Warning: the initialization of the JIT has changed (but + only slightly). Host applications that use the JIT must + set the AMX_FLAG_JITC flag before calling amx_Init(). + +16/03/2005 BUG fix: when introducing version 7 of the binary file format + I accidentally accessed the binary file directly instead + of passing through sc_resetbin(). This made in-memory + compilation impossible. + +12/03/2005 BUG fix: declaring a global array variable with a symbolic + constant (for the array size) before that symbolic + constant is defined itself, could result in a hang + (or a significant compilation delay). + Documentation fix: the documentation for enumerations in + relation to explicit tags and array indices was + incorrect. + Global variables may now be declared both public and stock. + Functions must still be either public or stock (or + neither); note that there is not much use for public + stock functions, as functions can be "forward declared" + and variables cannot. + +28/02/2005 The debug information format and the debug hook have changed + dramatically. The existing 5 opcodes for the debug hook + FILE, LINE, SYMBOL, SRANGE and SYMTAG are now redundant, + and replaced by a single new opcode: BREAK. Other + opcodes that previously called the debug hook, such as + CALL, RETN, and STACK, no longer call the debug hook. + The information for (local and global) variables is no longer + mixed in the executable code, but now appended to the + file in a separate chunk. There is a new component, + amxdbg.c, with functions that parse the debug + information and can look up functions, line numbers and + variables, given an address. + Warning: all code that uses a debugging hook must be adapted. + The new debugging hook strategy has the following + advantages: + - the debug hook can be set up on an "as-needed" basis: + when you want to break out of a "hung" script, you + can set up a debug hook while the script is still + running; + - even with the debug hook installed, the hook is a lot + quicker because there are less opcodes that call the + hook and the amount of data that needs to be parsed + and passed on is lower; + - the presence of debug information does not influence + the performance of the script execution as much (but + scripts without debug information and bounds checking + will still run quicker that those with those checks); + - the new method is more suitable for remote debugging, + especially over slow links. + There is also a disadvantage (apart from increased + complexity of the debugger and the compiler): when an + assertion fails it only gives the code address of + failure --to get the matching file & line number, you + need to look them up using the debug information. + +22/02/2005 The estimate of stack usage has become more precise. In the + older version, the estimate could be too low, because + stack usage due to parameter passing was not taken into + account. + The XML report (script documentation) was enhanced with a list + dependencies for each function; the dependency + information is the inverse of the referral information. + +17/02/2005 The method of passing parameters to public functions has + changed. In the past, these were passed to amx_Exec(); + when arrays or strings had to be passed, you had to + allocate space, copy the array/string and release the + space after amx_Exec() returns. In the current method, + there are the functions amx_Push(), amx_PushArray() and + amx_PushString() which you call before calling + amx_Exec(). The required data is allocated and copied + implicitly; you must still release the allocated space, + however. + Function amx_Execv() is now gone, as there is no more use for + it. + The 16-bit version of the AMX DLL (AMX16.DLL) now has all + functions as "FAR PASCAL" (which is standard), rather + than "__cdecl". The 32-bit version of the AMX DLL + (AMX32.DLL) declares the exported function amx_Exec() + now as "__stdcall". This should be transparent to the + compiler. + + 8/02/2005 Support for the JIT in FreeBSD and OpenBSD is improved. A few + fixes were implemented. These were reported by Laurent + on the Small forum. + Merged in changes by Allen Cronce, for the support for Mac-OS. + The project file for Metrowerks Codewarrior was updated + as well. + + 4/02/2005 BUG fix: there was an incorrect assertion in the parser which + would break an expression like "a[0] = a[1] = a[2] = 0" + (unless you build the Small compiler without + assertions). This bug was reported by "kexz" on the + Small forum. + BUG fix: a self-assignment warning was issued in a special case + of an assignment of an array element into another + element of the same array. This bug was reported by PM + on the Small forums. + BUG fix: 64-bit support used the wrong shift counts in + generating byte offsets from cell offsets. This was + reported by BAILOPAN on the Small forum. + Better portability to 64-bit cells, for example by storing the + full 64-bit function pointer to a native function in + the internal native function table. P-code files with + a 64-bit cell size have a different "magic" value + (or "signature") in the header. Most of these + modifications were described by BAILOPAN on the Small + forum. + BUG fix: the peephole optimizer could not handle long symbol + names (i.e. over 21 characters) for local variables. + This bug was reported by BAILOPAN on the Small forum. + BUG fix: constants passed into functions that accept a variable + argument list (such as printf) caused a crash. This bug + was also reported by BAILOPAN on the Small forum. + BUG fix: when a field in an enumeration had the same name as + another symbol (name conflict/symbol redefinition), the + compile crashed instead of reporting the error. This + bug was reported by "Stu" on the Small forums. + +31/01/2005 BUG fix: the implementation of the "SWITCH" opcode in the + abstract machine would not work correctly when a cell + is 16-bit. This bug was reported by "chop" on the + Small forum. + BUG fix: in AMXJITSN.ASM (the JIT compiler in NASM format), + one symbol was incorrectly exported, which made the + file produce a linker error when used with GCC on + Cygwin. This bug was reported by Laurent on the Small + forum. + BUG fix: in amx_Execv(), the number of parameters was forwarded + to the main function amx_Exec() in a way that was + incompatible with 16-bit architectures. This was + reported by Pierre de Vos, who is porting Small to the + Atmel ATmega128 controller. + +18/01/2005 Corrections merged from Embryo, the adaption of Small from the + Enlightenment team. + The command line parsing in the Small compiler was modified to + be more flexible (and perhaps slightly more conforming + to what is common with GNU programs). + A simple "script arguments" native function library was + developed. This library provides general purpose + "command line argument" parsing functions. It is + somewhat in between of argc/argv and the getopt() + library. + A few bugs were fixed in the Microsoft Windows "terminal", + especially related to scrolling and resizing. + BUG fix: in the "switch" statement was fixed a bug would occur + if an expression between the parentheses of the switch + had a side effect. This bug was reported on the Small + forum by Lajos Molnar, and analysed by BAILOPAN. + The NASM version of the assembler core of the abstract machine + would not assemble under Cygwin. This has been fixed. + The error was reported by Lexx on the Small forum. + BUG fix: the "#pragma unused" directive did not accept symbol + names with digits, underscores or "@" characters. This + bug was reported by "chop" on the Small forum. + + 3/01/2005 The pre-build LIBSC DLL was missing an export, making the DLL + unuseable (you would have to rebuild the DLL to use it). + The self-installing setup had the version number wrong (it still + said 2.5). + The README.TXT was not up to date. The version packed in the + product came from a different directory than the one + I kept up to date. + There is a #section directive that hides all symbols declared + "static" (the #section directive simulates a file + switch). This was low on my wish list, but a recently + introduced feature in the compiler required it. + +22/12/2004 The JIT-compiler was translated to NASM by G.W.M. Vissers. This + makes the JIT available in Linux, and probably other + Unix-like operating systems. The port was initially done + for the free MMORPG "Eternal Lands" (by a member of the + team of the game). + Modifications for better support of FreeBSD and OpenBSD. + The Small compiler now allows multiple source files on the + command line. The compiler combines all sources to + build a single output file. + Improved the report file and the ability to extract + "documentation comments". The toolkit now comes with + a matching XSL file and an accompanying stylesheet. + These allow the report file to be directly readable in + a web-browser. + Constants that are part of an enumeration are now flagged as + such, this those constants to be grouped with the + enumeration definition in the report (XML documentation). + The argument comparison for forwardly declared functions (with + the actual implementation) was improved. + The tags of array indices are also now checked for arrays passed + as arguments to functions. + I increased the maximum number of function arguments to 127 (it + was 64, and this turned out to be too little for some + users!). + BUG fix: an object code generation flaw in the Watcom C/C++ + compiler caused the abstract machine to crash after + calling a native function for the second time. The code + generation problem has be circumvented by rewriting the + expression to do exactly the same thing in a slightly + different way. + There is a GraphApp terminal as an example terminal. This + terminal supports UTF-8 natively. It also supports + wide characters, if compiled as such. Look at + http://enchantia.com/software/graphapp/ for information + on the cross-platform library GraphApp. + The DLL versions of the abstract machine (AMX16.DLL and + AMX32.DLL) now use the "termwin" terminal, which allows + for font scaling and coloured text. + BUG fix: the NASM version of the abstract machine core did not + set the "debug event code" on a "line" event. + The documentation was improved, especially regarding compilation + on Linux and Unix-like platforms. There is a new section + on CMake, a cross-platform "makefile" generator utility. + + +22/07/2004 Functions can return arrays. The size of the array that is + returned must be fixed (functions returning + variable-length arrays are not supported). + The warning "function uses both `return' and `return '" + is now an error. + The compiler writes extra information related to the + declarations of constants, variables and functions to + the report file, and it now also supports documentation + comments. The toolkit comes with an XSL stylesheet to + create a HTML file from the report file (which is in + XML format). + +25/06/2004 Warning messages can be disabled individually (compiler option + -w). + I added the makefiles for FreeBSD contributed by Raphael + Raimbault to the standard distribution. In general, + FreeBSD support has been improved. + Adam D. Moss contributed a modified version of the makefile + for the abstract machine for Linux. If have called this + "makefile.linux" (because it seems more complete) and + my original "makefile_asm.linux" (because my version + compiles the assembler implementation of the core + executive). + Arrays whose size is declared with an "enum" symbol now allow + initialization by field size. In addition, the "sizeof" + and "tagof" operators look at the size and tag of the + enumeration element. This allows Small to mimic (simple) + structures with arrays. + BUG fix: when generating debug information, the compiler still + assumed that it was always writing to file (instead of + possibly writing to memory). + Two new preprocessor directives: #error, which is similar to the + same directive in C/C++, and #tryinclude, which fails + silently if the include file cannot be found. + +26/03/2004 Expressions in preprocessor directives were not preprocessed + themselves. A bug found by "SniperBeamer". + The "#elseif" directive was (finally) implemented. It allows + you to chain conditionally compiled sections more + easily. Note that in contrast to C/C++, it is called + "#elseif", not "#elif". + A few modules for the abstract machine are enhanced for Unicode + and UTF-8 support. + In AMXCONS.C, create the terminal "late", meaning that if a + script does not use a terminal, it does not pop up. + Better support for having an abstract machine that uses both + fixed and floating point calculations. The format + string of the native printf() function uses %f for + floating point, %q for fixed point and %r for either + floating point or fixed point (if floating point is + not available). + A new include file "rational.inc" allows you to write a script + using "rational numbers" and leave it to the abstract + machine as to whether this means "floating point" or + "fixed point". + +25/03/2004 Fixed a syntax problem where the conditional operator + interferes with tagnames, in an expression like: + new bool:a=(b<10)?true:false + Here "true:" is seen as a tagname, rather than as the + second part of the "? :" operator. Adding whitespace + fixes the matter, of course. The expression: + new bool:a=(b<10)?true : false + gives no problems. + The current compiler requires that tagnames in a + conditional expression appear between paranteheses, + like in: + new plain:a=(b<10)?(plain:true):(plain:false) + This bug was found by "PM", who posted it on the Small + forum. + Names of native functions were still truncated to 19 characters + even though the new binary file format no longer + imposes a length restriction on external names. This + limit is now removed. Another bug found by "PM", and + posted on the Small forum. + The logical operators did not force the tag to "bool:" (which + they should, according to the documentation). + A few type-casts were added, to allow the source to be compiled + as C++ source. + +15/03/2004 The file SCLIB.C, that compiles the "Small compiler" to a + single object file for embedding into an application, + was updated to include the new files. At the same time, + it was renamed to LIBSC (for conformance with Linux). + In addition, the library file can now be compiled as a + DLL (without needing a change in the source code) and + the DLL supports the functionality required by + RUNDLL32.EXE. + The example "SRUN" files (implementation examples for the + abstract machine) have been cleaned-up a bit and + another example, for the JIT compiler was added. The + function amx_InitJIT() is now finally documented. + The syntax for declaring an increment for a constant in an + enumeration has changed. The old syntax: + enum { + first : 10, + second : 5, + } + has become: + enum { + first[10], + second[5], + } + I need this changed syntax for a new feature that I + intent to implement. In addition, I have accidentally + used the new syntax on various occasions, so it may + be more intuitive than the old syntax. + + 3/3/2004 I added a -v switch to the compiler to set the verbosity. For + the moment, this does not change much: -v0 disables the + copyright banner and -v2 displays extra stack/heap + usage information; -v1 is the default. + The declaration and initialization of simple variables (single + cell) to constant values is significantly optimized: + from 3 opcodes to one opcode. This makes declaring a + new variable a light-weight operation. + +29/02/2004 The maximum number of dimensions for arrays has been increased + to 3. Hopefully, increasing it further now involves no + more than changing a constant. + As an example for how the Small abstract machine can be + extended, I have added a simple general purpose garbage + collector in a separate C file (AMXGC.C). The + "Implementor's Guide" discusses the interface and gives + an example of use, using the "Better String library" + (http://bstring.sourceforge.net/) for creating the + "garbage". + Basic support for UTF-8 is now also in the abstract machine. + The new functions amx_UTF8Get() and amx_UTF8Put() + extract or store a single (wide) character in UTF-8 + encoding. The new function amx_UTF8Check enables you to + verify whether some input string is in valid UTF-8. + All functions return an error code. All functions use + a strict interpretation of the UTF-8 syntax. + +23/02/2004 The compiler is now able to translate "extended" ASCII files + (i.e. 8-bit ASCII) to Unicode by using a codepage + mapping file. Only characters in unpacked strings or + in character constants are translated. Appropriate + mapping files can be found on + ftp://ftp.unicode.org/Public/MAPPINGS/. + In the compiler, the option "-c" no longer sets the + character size (there were bugs in this setting, so + I doubt that anyone ever used it). It now sets the + codepage for translation. + Robert Daniels provided fixes for bugs related to Big Endian + processors (I introduced these new bugs when adding + the "symbol names" table to the header in the AMX file + format. + Robert Daniels also gave a fix for an error that has been in + the toolkit much longer: several core functions had + to peek/poke into the data section of an abstract + machine, but they did not take the possibility of + "cloned" abstract machines into account. + +17/02/2004 The parser stack is now "growable". In earlier releases it had + a fixed size. + A memory leakage was fixed; the leakage was related to a double + declaration of a native function. + The compiler now accepts UTF-8 files on input. It translates + non-ASCII characters (that are encoded in UTF-8) to + Unicode characters in unpacked strings. See the manual + for details. + The compiler allows character codes to be entered with a + hexadecimal escape (in addition to the existing decimal + escape): '\x82' is the same as '\130'. + Unicode support uncovered a few bugs in the handling of unpacked + strings in the "core" and "console" modules: checking + whether a string is packed or unpacked did not work for + characters above 255. This is now fixed, and it also + led to a new predefined constant in the compile: + "ucharmax". + The LINE opcode now allows a debug hook function to cause the + program to "sleep". Previously, a "sleep" mode could + only be started from a native function or via the + "sleep" statement of the Small language. + + 5/02/2004 For arrays with 2 dimensions, the major dimension no longer + needs to be explicitly specified when there are + initiallers. The compiler can now count the number of + items itself. + "Johnny got his gun" reported the bug that the compiler signals + the expression "var = !var" as a self-assignment. This + bug applied to most unary operators. (It is now fixed.) + A new extension library (native function library) comes with + the toolkit: file input/output. Text files (plain ASCII + and UTF-8) and binrary files are supported. + There is a new terminal implementation: "termwin". This + terminal emulates a console on Microsoft Windows; its + primary feature is that you can have several of these + consoles at the same time and that it supports Unicode. + For the purpose of Unicode, the functions amx_GetString() and + amx_SetString() got an extra parameter, for interpreting + the source or destination string (on the "C" side) as + a "wchar_t" string. + Anthalir gave an update to the FreeBSD support. His changes + were merged into the main branch. + +16/01/2004 When you compile with option -d2, the compiler now gives you + an estimate of stack/heap usage. Even without this + option, the compiler will warn you when the stack/heap + area is too small. The stack/heap determination does + not work in the presence of recursive functions. + When you do not use the return value of a function, you mostly + do not need to enclose the function's arguments in + parantheses. That is, the snippet below is now a valid + Small program: + ----------------------------------------------------- + main() + printf "Hello world\n" + ----------------------------------------------------- + The manual has been updated to use this "friendlier" + syntax where possible. + The RET and RETN opcodes of the abstract machine now check + whether the "return address" (on the stack) lies inside + the code segment. This makes buffer overrun exploits + much less likely (perhaps impossible). This address + check is also done in "no debug" mode (unlike array + bounds checking, for example). + Opcode SYSREQ.D is now fully implemented. When calling a native + function, the "callback hook" function looks up the + function address. If it has found it, it may store this + address in the code stream and change the opcode from + SYSREQ.C to SYSREC.D. The SYSREQ.D calls the native + function directly, avoiding any overhead from the + callback hook. + + 9/01/2004 The compiler generates the intermediate (assembler) file in + memory. This is faster and cleaner: compiling a .AMX + file now no longer overwrites (and deletes) the .ASM + file, if one exists. + When you do not use the result of a function call, you may now + omit the parantheses around the function's parameters. + That is, you can say: + printf "Hello world\n" + This syntax may make Small source code a little + friendlier to read, especially for novice users. + The changes of FUTURE Interactive, to support a 64-bit cell, + were merged into the main branch. + +30/12/2003 I switched to the zLib license for the toolkit. The original + license was already quite similar to the zLib license, + and in retrospect, the clauses that I added are not + very useful. + I changed the regression test suite to a REXX script (instead + of the older DOS "batch" file). REXX is available on + many platforms, so I hope that the regression suite + will be more useful to those users that do not run + Microsoft Windows (or DOS). By the way, I use Regina + REXX (see http://regina-rexx.sourceforge.net/). + +19/12/2003 Søren Hannibal proposed the use of a private implementation + for strdup(), to make it easier to use other memory + allocators (than standard malloc()). + More options for fixed/floating point value formatting in the + printf() function (width/number of decimals) + The console functions (AMXCONS.C) were redesigned and now have + improved VT100 & Win32-console support. New native + functions are gotoxy(), wherexy(), clreol(), clrscr() + and setattr(). + The toupper() and tolower() from the "core" library now also + work with accented characters using ANSI fonts + (Microsoft Windows). + New opcodes SYMTAG and SYSREQ.D. SYMTAG is for the debugger, + it allows a debugger to choose a display format based + on the "tag" of a symbol. (It was added mostly for + displaying fixed/floating point values.) SYSREQ.D is + to optimize the performance of native function + callbacks. + The ".AMX" file format changed: it now has a separate "symbol + name" table, so that the name length limit of 19 + characters for "public" or "native" symbol names no + longer applies. The run-time (AMX.C) reads modules + with the previous file format as well. The compiler + only generates files in the new format, though. + The file header is now also padded to the requested "symbol", + alignment. This way, the code and data sections are + also automatically aligned to the chosen alignment. + The Small debugger now uses the console functions in AMXCONS.C + for output. This gives (almost) automatic recognition + of the proper "terminal" support. The debugger is also + improved in its display of fixed/floating point values. + Hard limits (number of files, number of breakpoints, + number of watches) have been removed. + +24/11/2003 The preprocessor was "fixed". One problem were various match + and replacement errors (for parametrized macros), + another problem was its slow operation. + There were "tag mismatch" errors related to the user-defined + assignment operator. These have been fixed. + AMX.C now contains various conditionally compiled sections. If, + for example, you only need to call the function + amx_Register() from an extension module, you can save + of 10 kBytes of code by compiling AMX.C with the macro + AMX_REGISTER defined. This strips out all other + functions in AMX.C. + The floating point support module got a few more native + functions: floatsqroot(), floatpower(), floatlog(), + floatsin(), floatcos(), floattan() and n_floatabs(). + In addition, I documented the floating point support + in an "application note" (just like the fixed point + library). + +20/11/2003 The fixed point module was corrected to have accurate rounding + behaviour; for example 2.0 / 3.0 now is 0.667 instead + of 0.666. These rounding rules apply to both the + multiplication and the division operators and functions. + The documentation for the fixed point library is now + separate from the "user manual". In addition, I added a + power, a square root and an absolute value function to + the library (plus a useful "multiply, then divide" + function which avoids loss of precision in the + intermediate result). + Another error was also fixed in the library: the ANSI C version + of fixed point multiplication was prone to an + intermediate overflow bug. (I didn't catch this bug + earlier, because for most compilers there is an + optimized version for this function that uses 64-bit + arithmetic.) In addition, there are a few minor + corrections in the include file. + +10/11/2003 In AMXCONS.C, I changed the definition of getstring() so that + the buffer size is now in "cells" rather than + characters. In practice, this makes it much easier to + use getstring(). It is, however, not compatible with + earlier releases. + + 5/11/2003 AMXCONS.C, the example "console" interface was extended with + an improved ANSI/VT100 terminal support and a native + Win32 console interface. New native functions are: + clrscr() clear screen + clreol() clear up to the end of line + gotoxy(x, y) set text cursor position + setattr(f, b) set foreground and background colours + I added a check for invalid "AMX" addresses in the + amx_StrParam() macro, to "fortify" native functions + against tampered ".AMX" files. + The new function amx_StrError() gives a descriptive error + string for an error code. + Frank Condello updated the project files for CodeWarrior, to + compile Small on the Macintosh. These files are found + in a subdirectory. + + 1/11/2003 The Implementor's Guide was extended again, with notably a + much improved section on writing native functions, + including how to bind methods from a C++ class to + Small. + Under Microsoft Windows and Linux, extension modules can now + also be made as a DLL or shared library. The abstract + machine will automatically load the DLLs/shared + libraries that are required for the script that you + run. This allows you to create general purpose, plug-in + extension modules that you make available to an + implementation of the Small run-time without needing to + recompile this run-time. + The example extension modules that come with the toolkit were + adapted to make them suitable for dynamic loading. + To unload all DLLs & shared libraries after running the code, + you should call the new function amx_Cleanup(). When + dynamic loading of extension modules is disabled (or + not available), this function does nothing. + There is also an AMXEXPORT macro to use for extension modules + that are compiled as a DLL/shared library. + There were a few fixes in the CMake configuration files. I + renamed the Linux makefile back to "makefile.linux" + instead of "makefile.unx". + +20/10/2003 Savas Savvides (from StockWiz.com) found a bug in the array + bounds-checking of Small: negative array indices were + not caught. This was fixed. + A bug in address range checking was fixed. The bug classified + array accesses to an array at the very end of the data + section (so a global array variable) as invalid. This + was a classic "off by one" error. It occurred rarely, + though, because there is usually "string literal data" + at the end of the data section. + The definition of MAX_PATH was made more platform-independent; + the definition of POSIX is now used when available. + +14/10/2003 Some opcodes now do a bit more checking on the environment: + block moves/compares/fills now check the validity of + the memory ranges of the destination & source arrays; + RET and RETN check whether the return address lines + inside the "code space" of the abstract machine. + A memory leak in the compiler was fixed (related to functions + that take optional values on any of the arguments). + Failure to mark a symbol "public" in the NASM version of the + abstract machine core made this file not usable. This + was easily fixed. + + 8/10/2003 I thought Small was fairly well documented, but re-reading a + few less common sections proved me otherwise: parts + of the documentation is outdated and several features/ + functions were undocumented. Especially the + "Implementors Guide" was corrected and expanded. + I cannot say that the documentation is now fully + correct and comprehensive, but the situation is at + least "better". + The compiler now tries to include the file "default.inc" from + the include directory (not from the current directory); + this fails silently if the file does not exist. The + default.inc file may be used to include other "standard" + include files (console.inc, core.inc, ...) or an + application-specific include file. This may avoid the + common error of a script-writer forgetting to include a + file (especially if user-defined operators are used). + + 3/10/2003 The GNU GCC and assembler versions of the Abstract Machine + now have alternative "non-debug" versions of a few + opcodes, to avoid checking for the "debug hook" flag + every time that particular opcode comes by. + The "#subst" directive was renamed to "#define". I feel that I + have made an error to keep the "#define" directive + (which declares only numeric constants) and add a new + "#subst" directive that is actually far more similar to + what #define does in C/C++. In addition, the syntax of + #subst is a superset of that of the old #define in + Small, so old scripts continue to compile. + While "renaming" #subst to #define, I added the #undef + directive. + +29/09/2003 The report file is now in XML format. This probably makes it + easier to integrate it into other applications. + For the #include directive, it is in most circumstances no + longer necessary to enclose the filename in quotes or + in angle brackets. + There is a syntax for "literal strings" (and also for "literal + characters", but this is less important). A literal + string does not recognize "control characters" (which + are what C/C++ calls "escape sequences"). + The default control character ("escape character") is now a + backslash (instead of the caret). I used the caret + earlier, because DOS/Windows uses the backslash as a + directory separator. The backslash is so common as a + "special character" in Unix and other programming + languages, that I now feel that choosing the caret was + a wrong choice. + For backward compatibility, you can create a SC.CFG file + and add the command line option "-^". + +18/09/2003 An "enum" can now also be given an explicit tag. If an explicit + tag is absent, the name of the enumeration will be + de default tagname (this is the old behaviour). + When there are three warning error messages referring to the + same line (or to the same multi-line expression), the + compiler now halts with a fatal error. This situation + is mostly due to the parser being unable to recover + from an earlier error. + The user-defined assignment operator is now implemented. This + operator allows you to implement your own coercions; + for example: from integer to IEEE 754 floating point + (and vive versa). + The assignment operator is also called for function + arguments that are passed "by value". + +15/09/2003 The peephole optimizer is now recursive. This allows the + optimizer to re-evaluate the code after initial + optimizations. In addition, I have added a few rules. + Some minor corrections in AMXEXECN.ASM so that it works better + with older versions of NASM. In addition, with GCC, + the assembler version was never used, due to an + incorrect conditional compilation ("#ifdef") test. + + 8/09/2003 Many bug fixes. Over the last year, several bugs (and fixes!) + were reported on the Small forum. Apart from a few that + I could not reproduce, these have been fixed in this + release. Thanks go to "chop", Chris Jones, Nacho, + Lajos Molnar, "John", Jeppe Oland, RTaylor/Akira, + Stephane Denis, James Haley, and probably many others. + A new operator "tagof", which will be useful for functions with + plurally tagged arguments. + New functions in the Abstract Machine: amx_FindNative(), + amx_GetNative() and amx_NumNatives(). + The floating point support file (FLOAT.C) was changed to no + longer require dynamic memory (malloc/free). In + addition, a new rounding mode was added, which mimics + the way that C/C++ "truncate" floating point numbers to + integers (on a type cast). + + 1/09/2003 The Small compiler now has a preprocessor. The preprocessor + matches text patterns and replaces them with other + patterns. The syntax for the patterns differs from + both the C/C++ preprocessor and from the "regular + expression" syntax, though (Small's preprocessor was + inspired by TeX macros). The Small manual was updated. + From a high-level description of the implementation of a + LINT-like tool, I got enough information to add two + more warning messages to the Small compiler: + "unreachable code" and "self-assignment". + The Small compiler creates "compact" P-code files by default, + but it cannot cope with input files whose "compact" + encoding would in fact be larger than their "plain" + encoding. (The problem lies in the "in-place" unpacking + in the abstract machine.) I prematurely fixed this + problem by generating a fatal error for those rare + cases, and requiring you to (re-)compile such input + files with "plain" encoding. + The sizeof operator now gives the number of elements in an + array. This means that for a two-dimensional array, it + can return the number of rows or the number of columns + (depending on the syntax of the sizeof operand). + +26/08/2002 An experimental "destructor" operator is implemented. The "~" + operator is automatically called when a variable drops + out of scope. + A few performance optimizations in the generated pseudo-code, + especially for "for" loops. + A bug where the "function should return a value" was not given + is fixed. This ocurred in a situation where you said + "new myvar = myfunc()" where "myfunc()" does not return + a value. + The "expand" function now also uses the stack space while + expanding. This hopefully solves the (already rare) + cases where the expand function got short of buffer + space. Bug reported by Robert Daniels. + Maurizio Ferraris reported a bug where the compiler crashed + when it tried to recover from a symatic error in a + particular context. + Frank Condello donated a Macintosh port of the compiler and + abstract machine. His changes were merged with this + release. In addition, there is a separate directory + with additional source code and a CodeWarrior project. + +19/08/2002 Native functions can now also force a "sleep", simply by + returning AMX_ERR_SLEEP. + + 6/08/2002 To avoid the problem of structure fields being aligned + differently by different compilers, the header format + was changed to exploit "natural" alignment. Even + compilers that do not support "#pragma pack()" should + not have the good alignment. The changed header lay-out + is the main reason that this release got version number + 2.0. + There is a new compiler option, -A, and a new #pragma, "align", + which allow you to align variables on a boundary that + is an arbitrary power of 2. These tricks are sometimes + convenient (or necessary) with native functions that + use SIMD instructions. These changes are based on + code donated by Stephane Denis. + New functions amx_Clone() and amx_MemInfo(), both to support + cloned abstract machines. + For using bit masks as light-weight sets, the "enum" + instruction supports automatically multiplying by 2 of + all constants. + As an optimization, the compiler now generates a "halt" + instruction at address zero, so that the "RET" and + "RETN" instructions do not have to check for a special + zero address. + Dan Andersson found a bug in the JIT, which has now been + corrected. The JIT has also been brought up to date; it + now supports the "sleep" instruction. + As suggested by Stephane Denis, amx_Exec() now verifies that + all native functions used in a script are actually + registered, before executing any of the script. + The debugger can now optionally use the Unix "readline" package + for a more convenient command line. Due to the design + of the readline package, it requires that you build the + application, with the same compiler as the one that was + used to create the readline DLL or shared library. As + such, I recommend that you only use the "readline" + package with Unix/Linux or Microsoft Visual C/C++. + One could easily make mistakes with floating point variables + and the user-defined operators without any warning from + the compiler. For example, in several situations, + forgetting a "float:" tag on a variable declaration + gives no warning but generates completely wrong code. + Therefore, I have modified the floating point support + to use "strong" tags, i.e. "Float:". You may need to + modify your scripts if you work with the new include + files "float.inc" and "console.inc". You can look up + the "strong tags" issues in the language guide. + + 6/05/2002 Oops, skipping compound blocks in the first pass, introduced + at 25/02/2002, caused several regression failures; in + retrospect, the compiler really needs to scan every + statement in the first pass, to record the function + and variable usage. + Maurizio Ferraris donated a modification of the compiler that + gives it support for multiple "include" directories. + BUG fix: there was a peculiar parsing error that started with + a call to an undefined function, continued with the + compiler confusing code with data declarations, and + ended with the compiler generating faulthy code without + any error/warning message whatsoever (bug reported by + Maurizio Ferraris). + BUG fix: when you use "#pragma ctrlchar" halfway a program, + the second pass uses the new "ctrlchar" value right + from the start, which causes trouble if include files + depend on the original (or default) value. (This issue + was brought to my attention by Florian Zschocke.) + BUG fix: the AMX function amx_GetAddr() could return success + on a negative address (bug reported by Robert Daniels). + BUG fix: when re-defining a function with more parameters than + the previous definition, the compiler could crash when + it tried to compare the parameter lists of the old and + the new definitions; the compiler didn't check the + length of both lists (bug reported by Robert Daniels). + +25/02/2002 BUG fix: when the conditional operator has unindexed arrays as + its second and third operands, the "variable type" + of the resulting expression should also be an array. + (Bug found by Linus Nuber.) + To increase the performance of the compiler, compound blocks + are skipped in the first pass (the Small compiler is + a two-pass compiler). + +14/02/2002 The manual is split in half: there are now two "Small booklets": + one covering the language and one for implementing + Small in applications. Much of the information from the + README.TXT is now the the ``Implementor's Guide''. + The new Implmentor's Guide also got a section on calling + public functions (other than "main()") and passing + parameters (both numeric and string parameters). + +13/02/2002 BUG fix: the JULIAN.SMA example program had an error in the + check for dates in the month February (bug reported + by Jan Vooijs). + +12/02/2002 "chop" found a series of bugs in the Small compiler and the + abstract machine: + BUG fix: the functions strpack() and strunpack in AMXCORE.C + check the validity of the memory range for the + destination string. However, the number of bytes that + were checked was far too small: the checking code + confused sizes of bytes and cells. + BUG fix: the functions amx_StrLen() and amx_GetString() in + AMX.C, the functions amx_StrPack() and amx_StrUnpack() + in AMXCORE.C and the function printstring() in + AMXCONS.C all had a problem with determining packed + strings, in case you use characters above ANSI 127. + The manual also had an error in the "ispacked()" + function in the chapter ``Assorted tips'' had the + same error. + BUG fix: in the Small debugger (SDBG.C) a check for an + available breakpoint entry was missing a semicolon. + BUG fix: chained operators did not work correctly with + user-defined relational operators, because the operator + functions garbled the ALT register. The ALT register is + now saved around the call. + BUG fix: a global variable being used prior to its definition + was not flagged correctly; it also caused a code + generation error. + + 7/02/2002 BUG fix: The AMX DLLs apparently had problems when being used + with Microsoft Visual C/C++, due to a calling + convention mismatch (failure to save/restore some + registers). + Clem Vasseur proposed a binary search for the opcode lookup + in the compiler. This has been implemented. + + 5/12/2001 Linus Nuber found that double-character user-defined operators + and debug information (options -d2 or -d3) do not go + well together: the size of a SYMBOL opcode may overflow + the size that the compiler initially estimated and this + causes the function to be generated at the wrong + address. + +30/11/2001 As per the request of Linus Nuber, I changed the way that the + compiler options are set and reset. Now the -C, -P and + -; options can have a "+" or "-" suffix that sets or + clears the desired option; without suffix, the option + is toggled. With this, you can set your default options + in the configuration file (SC.CFG) and toggle the + option on the command line. + +27/11/2001 "Compact encoding" of the .AMX file has become the default; use + the "-C-" compiler option to return to the old (plain) + encoding. + +23/11/2001 BUG fix: Linus Nuber found a code generation bug in the case + where a user-defined operator was called with a + constant on either size, such as "1.5 * 2.5" with + operator*(float:a, float:b). + +20/11/2001 BUG fix: Gilad Novik found that unused public variables would + be stripped from the compiled file and their addresses + re-used by other global variables (or array literals), + but that the public variable was still listed in the + file header. + BUG fix: when you ask for "sizeof x" and "x" is an array of + indeterminate size, you get a warning. The warning did + not occur if the "sizeof" expression appeared in the + default value of a function argument (in a function + definition). The lack of the warning makes the "sizeof" + default value error prone, the warning makes it safer. + + 8/11/2001 The manual was updated to include the changes since the last + public release of the Small toolkit. + The performance of the compiler was enhanced. + +30/10/2001 You may specify a hard "index" for a native function, which + omits the native function from the compiled .AMX file. + For this to work, you need to implement your own native + function dispatcher; see the manual. + As per the suggestion of Stephane Denis, I used the more + specific integer types int16_t and int32_t in structure + definitions. These are defined in the ISO C99 standard. + + 9/10/2001 The default value of a function parameter can now be the + "sizeof" of another parameter of the same function. + This is convenient to pass the sizes of array + parameters to the function without requiring the + programmer to explicitly pass the size. + The new SC_LIGHT macro allows you to exclude non-essential + components of the Small compiler upon recompilation. + These components are: the cross-reference report (-r + option), parsing of "response files" and the default + configuration file ("sc.cfg"). More may follow (for the + moment, the peephole optimizer is considered + "essential"). + +10/09/2001 BUG fix: getproperty() of the "core" native function set read + contents from a memory block after freeing it. + BUG fix: a bit of code that writes the AMX file header still + assumed that a cell is always 32-bit. + BUG fixes: in the symbol name handling of user-defined + operators. There were several bugs; the operator that + suffered the most from these is probably the unary + minus operator. + +28/08/2001 BUG fix: defining the % operator would often introduce an error + in the symbol table. Cause: the % character is special + for sprintf() functions that the compiler uses to + construct symbol names. + BUG fix: Linus Nuber reported a bug where functions that were + called before their definition would be marked as + "unused" and stripped from the compiled code. + BUG fix: Clem Vasseur noted that on a fatal error, the local + variable table was not cleared; this then subsequently + fires an assertion in the exit code. + A prototype mismatch (of sc_error()) between the source and the + header files was also reported by Clem Vasseur. + +27/08/2001 BUG fix: Dario Sacca sent in a fix for an error in the + assembler implementation of the abstract machine. In + the debug hook for the line opcode, the "frame" offset + was not updated correctly. + New compiler option: -r, to generate a cross reference report. + The report lists all constants, global variables and + functions and tells what function is accessing them. + Stock functions that are never used are still in the + report. Native functions that are never used are not + in the report. The report file is intentionally + formatted in a minimal way, to make it easier to have + it parsed by other programs (call tree, cross-reference, + etc). + + 8/08/2001 BUG fix: Linus Nuber was surprised to find that the version + uploaded 5 August no longer accepted user-defined + operators that were declared as stock. This + embarrassing bug is fixed. (Oh, and a silly error in + the Linux include file, also reported by Linus Nuber, + was fixed too.) + BUG fix: Odie Calima found a few more global variables that + needed to be cleared on exit. + + 3/08/2001 BUG fix: Robert Daniels found a code generation bug in the + situation where a "for" loop contains a variable + declaration in its first expression and a break in its + body. This is now fixed. + +23/07/2001 The debugger got a minor improvements (quiker redraw of the + screen in termibal emulation mode). + Using a "&" where a "&&" is probably intended, or a "|" where + a "||" makes more sense, is now detected by the + compiler. (Actually, the compiler already issued a + warning for this, but it did it dumbly and too often; + now, when the compiler warns for a possibly unintended + bitwise operator, it is very likely indeed an error.) + +16/07/2001 The general purpose DLL calling functions have been implemented + fully and documented in the manual. + + 2/07/2001 Stock variables: if no function accesses a global variable, + this variable gets stripped from the compiled output + file, and without warning if that variable was declared + "stock". + BUG fix: a bug in appending implicit extensions to #include + files was fixed. + Functions and global variables can be declared "static", which + restricts their scope to the current file. + +25/06/2001 BUG fix: if you omitted the colons on cases in a switch + statement, the compiler hung. This was corrected. (Bug + found by Joe Hansche.) + The detection of unused functions has improved. Specifically, + if function is called only by other functions which + are never used, that function is marked unused as well. + BUG fix: a script that was edited under DOS/Windows and + compiled under Linux, would give error "invalid line + continuation" for a "//" style comment. This was + corrected. + +27/04/2001 BUG fix: Stéphane Bouteille corrected another error that had to + do with Big Endian memory layout (in amx_Exec()). + I added "strong" tags in addition to the current "weak" tags. + See the manual for the differences. + +17/04/2001 I added a -S option to the compiler to set the size + of the stack+heap (what you would otherwise need to + do with #pragma dynamic). + The Small compiler now parses a SC.CFG file with default + options (if that file exists). If the executable of + the compiler is called "SC16.EXE" or "a.out", then the + configuration file will be "SC16.CFG" and "a.cfg" + respectively. + The DLL version of the abstract machine got two new native + functions: loaddll() and freedll(). The calldll() + function that was already present could only call into + DLLs that had already been loaded. + +10/04/2001 Added a swapchars() core function that swaps all bytes in a + cell (so the low byte becomes the high byte). + More new native functions are a set of date and time functions + in AMXTIME.C and TIME.INC. + Dieter Neubauer made a 16-bit version of the Small tools + (meaning that a cell is 16-bit, instead of 32-bit). + His changes were merged in the original distribution. + + 5/04/2001 BUG fix: Raymond Holz found that the Small compiler returned 0 + after a "fatal error", where a return value of 2 would + be expected. + BUG fix: Linus Nuber found that accented characters were + treated as either negative values or as positive + values, depending on the C compiler used to build the + Small compiler. + Linus Nuber also found that the compilation instructions in + the README.TXT were inadequate for the Linux platform. + The README.TXT is corrected and a few details in the + Small compiler were adjusted (for Linux) as well. + +23/03/2001 BUG fix: Linus Nuber found a bug in default array parameters + that were tagged as const. As an optimization, the + compiler does not copy such arrays to the heap, but the + compiler DID try to remove them from the heap. + +12/03/2001 Overloaded operators are (finally) "operational". The manual + is updated to show how this new feature works. + The compiler supports literal values with a fractional part, + but you must enable this support specifically: Small + can interpret these so-called "rational numbers" as + either fixed point or as floating point numbers. Again, + see the manual for details. + For your convenience, I updated the FIXED.INC and FLOAT.INC + include files. The pre-compiled SRUN.EXE (Win32) + includes the "float.cpp" module. + + 5/03/2001 BUG fix: native functions strpack() and strunpack() mixed up + the source and destination strings. + Maintaining correct tags became inconvenient at times; I + therefore introduced the "default tag" override "_:". + This token removes any tag from its operand (on the + right). + +23/02/2001 BUG fix: the code generation for the INC.I and DEC.I opcodes + was wrong (the compiler encoded one parameter). + BUG fix: code generated for an expression like "array[index]++" + was wrong: the loading of the expression result + garbled the address of the array cell to increment + subsequently. + +19/02/2001 Relational operators now always set a "bool" tag on their + expression result + Native functions may have an "alias" name. This lifts the + limitation of 19 characters for a native function. + +15/02/2001 On a fatal error, the Small compiler now forces a jump back + through the main function, rather than aborting the + program. This allows for easier embedding of the + compiler in an application. + +25/01/2001 The "sleep" instruction is implemented, but quite differently + than the partial implementation (of 19/12/2000). The + sleep instruction takes an optional expression (like + the "return" and the "exit" instructions) and ends the + abstract machine in a way that it can be restarted. The + tagname of the expression of "sleep" is also saved (in + the ALT register), so that you can attach a "meaning" + to the expression. + The changes from the earlier (partial) implementation + are that I used the HALT opcode rather than the SLEEP + opcode (and I subsequently removed the SLEEP opcode). + The HALT opcode needed modification to support a + restart of the AMX. + The AMX file format now saves exported tagnames (tagnames that + are used on the "sleep" and "exit" instructions) and + the abstract machine has three new functions: + amx_NumTags() + amx_GetTag() + amx_FindTagId() + The SRUN sample is adapted for the "sleep" instruction, but + simply ignores it. The SDBG sample ignores the sleep + instructions as well, but prints an informative message + when it occurs. + Due to optional semicolons, the end of an expression is now not + always easy to detect. Quite often, an error in an + expression can only be flagged when the end of the + expression has been found. As a result, an error is + now sometimes flagged one or more lines below the line + that really contains the error. This has been fixed + by giving both top and bottom line numbers between + which the error was found. + +28/12/2000 The DBG_LINE opcode can now abort the abstract machine. This + makes it possible to have a simple debug hook that + breaks out of "hung programs" (infinite loops). The + SRUN sample shows how to set this function up. + +19/12/2000 Søren Hannibal implemented a "sleep" opcode to have a + light-weight multi-tasking of abstract machines. + Preliminary support for the sleep is in this version + (basically I copied just Søren's changes). + BUG fix: adding a "tag" to a constant declared with a #define + caused an error message with a garbled symbol name. + (Bug found by Søren Hannibal.) + A few minor memory leaks were fixed. + +12/12/2000 BUG fix: the conditional operator generated wrong code if the + "false" expression was a constant. (Bug found by Linus + Nuber.) + Variables and function arguments can now be declared "const". + Two typical uses are declaring a public variable + const (so only the host application can modify them) + and declaring array arguments const (arrays are always + passed by reference). + + 4/12/2000 BUG fix: the import library for Microsoft Visual C/C++ for + AMX32.DLL had an incorrect definition for amx_Exec(). + +24/11/2000 BUG fix: public functions should not allow default values for + their parameters, as their is no way that you can set + the defaults from the C/C++ side. + Unused parameters of public functions do not issue a warning + anymore; public functions often have a "required" + interface, so an unused parameter cannot be simply + deleted. + Parameters of a function may have multiple tags between braces. + This allows the function to accept a selection of + parameter "types". For an example of the syntax: + native Move({sprite,actor,weapon}:animob, x, y) + Function "Move()" can take as its first parameter a + handle tagged as "sprite", "actor" or "weapon". You can + use this on non-native functions too. Inside the + function, the parameter "animob" has the tag that is + first in the list (so "sprite" in this example). + BUG fix: after an earlier fix, SDBG now removed symbolic + information for static variables too early. (Bug found + and corrected by Linus Nuber.) + +18/11/2000 BUG fix: the "not" operator did not work in the Assembler + code of the abstract machine (AMXEXEC.ASM), due to + an "aggressive" optimization (by me, probably). + +14/11/2000 BUG fix: an expression like "if (1==1)" gives a warning about + a test that is always true, but then continues to + generate faulthy code. (Bug found by David Burgess.) + BUG fix: the SDBG debugger did not remove symbols for static + variables, causing a new one to be declared for every + call to a function containing the static declaration. + (Bug found by Linus Nuber.) + + 1/11/2000 BUG fix: AMXEXEC.ASM can now finally be assembled with MASM + without using the "code segment" trick. This was + important because Visual C/C++ 6.0 returns incorrect + addresses for data declared in the code segment. + +26/10/2000 The Small compiler is now a two-pass compiler; prototypes are + no longer needed. + An internal problem, where the end of an expression could not + be determined (due to optional semicolons) in the + presence of a "preprocessor" directive, was fixed. + Array arguments with a default value are now copied to the heap + if the default value is used. This *fixes* the problem, + rather than trying to forbid it (as in the release of + 9/10/2000). The issue, by the way, was pointed out + by Søren Hannibal mid July (I may be slow, but I am + persistent). + The new function amx_Execv() allows programming languages other + than C/C++ use the AMX DLLs. It is limited to up to + four parameters, however (this is easy to change if + you ever need more). + A bug where a recursive function provoked a warning about a + missing return value was fixed. + +19/10/2000 The SDBG debugger prints the return value of functions. The + integrated debugger in the DLL also supports a few + function keys: + F1 = Help + F3 = List (refresh screen) + F5 = Go + F8 = Step (trace into functions) + F10 = Next (step over functions) + A new "interface function" in the compiler, sc_error(), lets + you intercept error/warning messages that are produced + by the compiler (if you statically link the compiler as + a "library function"). + +09/10/2000 BUG fix: using the -C and -d2 compiler options together caused + wrong encoding. + The debugger is integrated in the AMX DLLs. If you compile + with debug information, the debugger will launch + automatically. The AMX DLLs support a subset of the + ANSI terminal escape codes, so that it has a slightly + better interface. + The AMX DLLs have two new native functions: iswin32() allows + you to check whether you are running with the 16-bit + or 32-bit DLL and calldll() allows you to call any + DLL function (provided that it has a standard calling + convention). + Array arguments with a default value may not be modified (as + arrays are always passed by reference, and allowing + this would change the default value). + Updated documentation. + +27/09/2000 Definition of "interface functions" (called by the compiler) + allows to compile the Small compiler as a "library". + See the README.TXT file for details. + To use the Small compiler as a linkable library, a set of macro + definitions allow for a drastic reducal of namespace + polution (by global variables and functions). + A function may be declared as a "stock" function, which means + that if it isn't used, it may be stripped from the + compiled program (without warning). This way, you can + make "library" functions in header files. + +11/09/2000 A bug was fixed concerning the use of #endinput within an + #if ... #endif section; the compiler did not reset + the "#if" nesting level on #endinput. (Bug reported + by Jim McGinty from Artran, Inc.) + Expressions like "1 <= var <= 10" are now allowed. The result + of such an expression is 1 if all conditions hold, and + zero otherwise. The "chained relational expressions" + feature was copied from BCPL. + New opcodes SWAP.pri/alt, which are needed for chained + relational expressions. + New opcode PUSHADDR, which optimizes passing a variable by + reference. + By generating better pseudo-code for the "for" instruction, the + "Sieve of Erathosthenes" runs approximately 10% faster + (w/o print), and so will typically all small "for" + loops. + To better cope with the ever expanding lists of error/warning + messages and peephole optimizer sequence strings, these + strings are now compressed. They are still compiled as + literal strings in the executable, but a separate + utility, SCPACK, preprocesses the files and compresses + the strings. + +14/08/2000 Semicolons are now optional by default. This may give, in your + existing programs, warning 218 ("old style prototypes + used with optional semicolumns"). Use the "forward" + keyword to forward-declare functions; use the "/;+" + compiler option to "require" semicolons. + As per suggestion of Søren Hannibal, you may now mix positional + and named parameters in a function call, with the + restriction that all positional parameters must precede + all named parameters. Thus a call like: + getproperty(123, .value = 456) + would now be valid. + +24/07/2000 A large set of bugs, reported by Søren Hannibal, were fixed. + These include: + * code generation error for function arguments that are + passed to sub-functions by reference and that were + passed by reference themselves too; + * code generation error for labels (for "goto"); + * literal arrays passed to functions were always + flagged as "not the same size as the formal argument" + * missing "#endif" at the end of the main file was not + (always) detected + * reaching end-of-file while inside a /* ... */ style + comment was undetected + * address 0 is a valid address, so the fix in the + release of 17/07/2000 for amx_Exec() actually + introduced an error. + +19/07/2000 As per the suggestion of Søren Hannibal, the NO_OPTIMIZE + macro is replaced by a command line option in the + compiler (-d3). + +17/07/2000 Underscores between digits in a number are now allowed. This + may improve readability of large integers (for + example: 1_234_567) and for literals used in fixed + point expressions. + #pragma library is now (finally) working. This allows you to + give a tag to each native function to which + (dynamically loaded) library it belongs. The abstract + machine has functions to extract the library names that + it needs to load. + amx_Exec() will no longer start executing from address 0 if you + feed it with a program without a main() and ask to run + the "main" entry function. + The DBG_CALL event now tells to which address it is about to + jump, so a stack trace can be built. In addtition, you + will get a DBG_CALL event for the entry point (so that + the stack trace is never empty). + The sample debugger was extended with stack trace commands and + an option to print a one-dimensional array as a string. + +26/06/2000 A code generation bug (found by Dark Fiber) in the last update + was fixed. + +29/05/2000 Three bug corrections in the initialisation of the staging + buffer (that will teach me to easily change data + structures from "fixed size" to "grow as needed"). + Support for public variables (in addition to public functions). + Since the manual is not yet up to date, here is a + summary: + * Only simple (global) variables can be public, no + arrays + * To create a public variable, "public" replaces "new": + public myvar; + * Alternatively, the '@' prefix works as well: + new @myvar; + * To access public variables from a C/C++ program, use + the new AMX functions: + amx_NumPubVars() + amx_GetPubVar() + amx_FindPubVar() + amx_GetPubVar() and amx_FindPubVar() return the + address of the variable relative to the AMX; use + amx_GetAddr() to get a pointer to the cell + There was (still) a problem with the stack clean-up. I don't + know what I was thinking three months ago when I made + my first fix, but I probably only tested the 32-bit + version. + Someone sent me a bug report concerning a prototype mismatch + that I misclassified. I found it again by accident, + corrected the bug that the example demonstrated and + added it to regression testing. + The BCPL manual from Martin Richards pointed out that when you + have statements end implicitly on a line end, but still + allow expressions to wrap over multiple lines, there + may be a problem with unary operators. I tested a few + cases and, indeed, found an error. + +22/03/2000 Bug correction in the dynamic growth of the staging buffer. + Bug correction in the stack handling of amx_Exec(), which did + not remove arguments from the "abstract machine" stack. + If you ran the same AMX program over and over again + (without reloading it), you would slowly eat up the + AMX stack. + While correcting the above mentioned bug, I also added code to + clean up the stack "the hard way" on a run time error. + The extra local variable required for this also lets + me verify (with an assertion) that the normal route + indeed cleaned up the stack correctly. + Bug correction in the assembler version of the AMX: when + compiling with a stack-oriented parameter passing + convention, it must also save the value of EBX. + +13/03/2000 Using symbolic constants in the "case" statements of a "switch" + could cause the label to be interpreted as a tagname. + Marc Peter converted the JIT to use __cdecl calling convention + and added (minimal) support for the SRANGE instruction + at the same time. This means that you can now use the + JIT with Borland or Microsoft's compilers. + Dark Fiber contributes an AMX extensions with high quality + pseudo-random numbers, plus a simple card game as a + non-trivial example script in Small. + +17/02/2000 An attempt to assign a value to a constant (or any expression + that is not an lvalue) inside a test, resulted in an + assertion failure or a crash. + The compiler let invalid prototypes pass, while complaining on + correct prototypes. + Logical expressions with && and || operators were never + identified as "constant expressions", even if the + operands on either side were constants. This prevented + such logical expressions to be used in preprocessor + expressions. + The "loose indentation" warning works nicely if you use only + TABs or only space characters to indent a line, but if + you use a combination, the warning fires even if there + is no reason. To lift this problem, the current release + introduces the -t option and the "tabsize" pragma (with + which you can set the tab size). + Years ago the compiler was changed to align all opcodes to 4 + byte boundaries, to increase the speed of the virtual + machine at the expense of larger compiled files. The + current release introduces a -C switch with which the + compiler writes the output file in a more compact + encoding, at the cost of slightly longer load times. + +16/12/1999 Marc Peter corrected a problem in the JIT. + Path names with embedded spaces caused the compiler to fail if + you compiled with the -d2 option. + Bernard Fouche ported the sources to Linux. Based on his + changes and comments, the portability of the compiler + and the abstract machine have been improved. + Symbol names now have 31 significant characters. Native and + public names still have a maximum of 19 significant + characters. + +19/11/1999 Bug correction in the "for" loop concerning local variables at + the same scope as the "for" loop (found by Joe Felton). + amx_Exec() can now take NULL for the parameter for the script's + return value. + New function "random()" in AMXCORE.C. + +12/11/1999 Some changes for Greg Garner's module for floating point + support. + Two more "interface" function for the compiler. These functions + allow you to set "pre-defined" tag names and constants. + AMXCONS.C includes two more native functions to read a + character or a string from the keyboard. + + 2/11/1999 Fixed minor annoyances in the compiler like failures to find + the include path on non-DOS platforms. + +25/10/1999 Warning message for local variables that "shadow" a function + or a variable at an earlier scope (by having the same + name, they make the earlier symbol inaccessible). + Warning message for the infamous "dangling else" problem. + Bug correction: functions with upper case letters were not + assembled correctly (bug found by Greg Garner). + New control character "^e" which has value 27 ("escape"). + +12/10/1999 The abstract machine is now also available as a DLL for + Microsoft Windows. Both 16-bit and 32-bit DLLs are + provided (including source). + + 1/10/1999 Semicolons to end each statement can now be made optional with + the compiler switch "-;" or with: + #pragma semicolon false + The assembler implementation of the abstract machine now also + supports __stdcall declaration. See the README for + information on compiling. + There are now two "fixed point" libraries: binary (18:14) and + decimal (three decimal digits). The decimal fixed + point library may be more "exact" when working in "real + live" calculations (which are often based on a decimal + base). + +27/08/1999 Bug correction: parameters passed to a Small function (called + with amx_Exec() were not stored at the correct + location (bug found & corrected by Marc Peter). + Marc Peter's JIT underwent radical changes: on the "Towers of + Hanoi" benchmark the increase of performance is 80%, + see the history log in JIT.ASM for details. + +23/08/1999 The assembler version of the abstract machine (by Marc Peter) + now also compiles with Microsoft Visual C/C++ 5.0 and + 6.0. + Bug correction: using the assembler abstract machine in a + program with a default calling convention of __stdcall + resulted in a crash. + +20/08/1999 Mark Peter's Just-In-Time compiler is now integrated with + the standard release. The JIT gives yet another + major increase in performance. + +18/08/1999 The assembler version of the abstract machine (by Marc Peter) + now also compiles with Borland C++ 5.0. + Updated documentation; better lay-out too. + +31/07/1999 Small supports two-dimensional arrays. See the manual for + the precise syntax and usage of this new feature. + +18/07/1999 Plus debugging opcodes for the size and dimensions of an + array. + + 2/07/1999 Trailing spaces are ignored when concatenating lines with + a \ at the end of the line. + + 7/06/1999 Updated the Assembler AMX (by Marc Peter) for the new + opcodes (e.g. the SWITCH opcode and associated + case table). + Bug correction: the compiler could "ignore" a fatal error + in a rare condition, leading to a crash or random + output. + Bug correction: overflowing the stage buffer issued the + wrong error message ("cannot read from file"). + +24/05/1999 The switch statement was redesigned: the minor improvement + is the support for ranges (e.g. "case 1..8:"), the + major change is the fastly improved code generation. + +10/05/1999 The compiler has an option to switch the syntaxes for packed + and unpacked strings; there is also a new #pragma to + to this. + and unpacked strings. + + 1/05/1999 Array assignment is more relaxed for literal strings: the + destination array does not have to be exactly the + same size as the string length (in cells). + +17/04/1999 Terminal support (ANSI escape sequences) for the debugger. + The debugger supports "watches" and a few more commands. + +15/04/1999 Support for static local variables. + Bug correction: the compiler did not give an error message + when returning an array from a function. + New commands in the debugger: + "GO RET" (run until function exit) + "GO n" (run until line n) + "LIST ON" (list 10 source lines after each step) + "LIST OFF" (turns above option off) + Pressing repeats the last STEP or NEXT + +12/04/1999 Bug correction for line continuation (\ at the end of the + line). + Error message when a \ appears in a single line comment. + New predefined constants "language" (version of the Small + language) and "compiler" (version of the Small + compiler). + +31/03/1999 Bug corrections for three opcodes of the abstract machine (none + of which were generated by the Small compiler) were + found and corrected by Marc Peter. + A bug in the fixed point module (relating the division of + negative numbers) was found and corrected by Marc + Peter. + Array assignment is permitted, under the condition that the + arrays at both sides of the "=" operator are of equal + size. + +24/02/1999 The compiler has an option to skip a number of lines before + starting to compile; this comes handy for scripts + inside text files. + The file format can now store the names of required modules + (that must possibly be dynamically linked); this is + currently supported through "#pragma library". + The new "#endscript" directive is an alias for the existing + directive "#endinput". + User data fields in the abstract machine are now "tagged", so + that you get some kind of name/value pair; you can + now determine whether a user data field is "in use". + The compiler has a few more command line options. + + 9/12/1998 Finished integration with Marc Peter's assembler abstract + machine, including the debugger interface. + Updated documentation for new features. + +27/11/1998 Two more warnings: nested comment and loose indentation (both + frequently indicate an error). + + 6/11/1998 Integration of Marc Peter's abstract machine in assembler (this + is still an experimental version). + + 4/11/1998 Major re-design of the compiler and the ANSI C version of the + abstract machine: opcodes are now cell sized. + +30/10/1998 Major changes in the debugger interface to accomodate the + design of a re-entrant debugger. + Early relocation of JUMPs and CALLs, which speeds up execution. + Changes in instructions to make array indexing faster. + New opcode to speed up passing long argument lists to + functions. + Variable arguments may now be tagged. + The manual got another full reading... and corrections. + +23/10/1998 New directive "#emit" for those who want to program directly + in the assembler of the Small abstract machine. + New directive "#endinput" to skip the rest of the file. + New function amx_FindPublic() that returns the index of a + public function whose name is specified. + Public functions are now written to the output file in sorted + order; this allows a quicker lookup of a public + function using a binary search. + "funcidx()" is a new native function in AMXCORE.C that returns + the index of a function in the "public function table" + so that a script can return the index that the + application should call next. + +19/10/1998 BUG fix: when calling an unknown function, the compiler would + issue a diagnostic and then crash or hang. + Command line options changed; you can now also add definitions + on the command line of the compiler. + The debugging interface changed (it became simpler), a console + mode debugger is included as an example. + New function amx_Flags() to check whether the compiled program + contains symbolic (debugging) information. + The property functions (core library) got an extra parameter + to avoid ambiguity in some cases. + A new "native function" module: fixed point arithmetic. + Clarifications and corrections in the manual. + +01/10/1998 BUG fix: conditional expression was inverted! + BUG fix: conditional expressions or logical operators generated + incorrect jumps when used in function arguments + (because arguments are evaluated right-to-left, but + code is generated left-to-right). + Support for named parameters (in addition to positional + parameters). See the documentation for this major + feature. + +28/09/1998 New functions pass strings between C and Small functions. + Run-time check for Little/Big Endian machines. + Some extra compiler checks: unused local constants and + side-effects of expressions. + +24/09/1998 BUG fix: code generation bug when incrementing or decrementing + a "reference" argument with the "++" or "--" operators. + Support for accessing (packed) characters from a (cell) array + with the {..} operator (function similarly to the [..] + operator). + REMOVED module names for native functions. This turned out + to be a feature that complicated the implementation + without adding much. + Several changes in the AMX, removed amx_CheckModules() and + amx_Unregister(). No need for callback functions + in an extension module. New function amx_NativeInfo(). + +22/09/1998 Support for Unicode characters in strings and character + literals. + Support for line concatenation with a backslash at the end + of a line. + Two more predefined constants: cellbits and charbits give the + size of a cell and a character respectively. + More error messages (errors 41 and 42 are new). + Functions whose name start with an '@' are always public. + An indirect threaded interpreter of the abstract machine + (AMX.C) when compiled with GNU CC (I used Delorie + GCC). The GNU C version is twice as fast as the + ANSI C version. + BUG fix: the compiler had a memory leak in the allocation of + the type list of function arguments. + The #define directive can now easily be removed from the + language (its support is a kludge anyway). + Packed strings are now stored in Big Endian, and no longer + terminated with a full zero cell; the new specification + makes it easier to determine whether a string is + packed or unpacked. + + 3/09/1998 BUG fix: multiple initialized local arrays in a compound + block were not initialized correctly. + Memory for function arguments was not explicitly freed. + Support for literal arrays, just like literal strings, like + in "print( {'H','e','l','l','o',0} ); + Support for default values of array arguments, as in + "addvector(a[], b[] = {1, 1, 1}, size = 3);" + or + "messagebox(text[], caption[] = "error");" + +28/08/1998 BUG fix: local arrays were not initialized to their full + extent. + All unitialized variables and array elements are now set + to zero (default initialization). + A few clarifications and additions in the manual. + +24/08/1998 BUG fix: prototypes caused invalid code generation. + BUG fix: expression involving constants could generate invalid + code. + Added the FILL opcode in the abstract machine. + More compact code generation for arrays initialized to a + single value. + Extra error message 41 (invalid use of ellipsis). + +20/08/1998 Improved portability of the compiler. + +18/08/1998 First public release. diff --git a/license.txt b/license.txt index aaf8b26..51b14d4 100644 --- a/license.txt +++ b/license.txt @@ -1,35 +1,35 @@ -The software toolkit "Pawn" (the compiler, the abstract machine and the -documentation) are copyright (c) 1997-2006 by ITB CompuPhase. The Intel -assembler implementation of the abstract machine and the just-in-time -compiler (specifically the files AMXEXEC.ASM, JITR.ASM and JITS.ASM) are -copyright (c) 1998-2003 Marc Peter. The file JITSN.ASM is translated from -JITS.ASM and is partially copyright G.W.M. Vissers. The file AMXEXECN.ASM -is translated from AMXEXEC.ASM and is partially copyright ITB CompuPhase. - -Pawn is distributed under the "zLib/libpng" license, which is reproduced -below: - ------------------------------------------------------------------------------ - -This software is provided "as-is", without any express or implied warranty. -In no event will the authors be held liable for any damages arising from -the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software in - a product, an acknowledgment in the product documentation would be - appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and must not - be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source distribution. - ------------------------------------------------------------------------------ - -The zLib/libpng license has been approved by the "Open Source Initiative" -organization. +The software toolkit "Pawn" (the compiler, the abstract machine and the +documentation) are copyright (c) 1997-2006 by ITB CompuPhase. The Intel +assembler implementation of the abstract machine and the just-in-time +compiler (specifically the files AMXEXEC.ASM, JITR.ASM and JITS.ASM) are +copyright (c) 1998-2003 Marc Peter. The file JITSN.ASM is translated from +JITS.ASM and is partially copyright G.W.M. Vissers. The file AMXEXECN.ASM +is translated from AMXEXEC.ASM and is partially copyright ITB CompuPhase. + +Pawn is distributed under the "zLib/libpng" license, which is reproduced +below: + +----------------------------------------------------------------------------- + +This software is provided "as-is", without any express or implied warranty. +In no event will the authors be held liable for any damages arising from +the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software in + a product, an acknowledgment in the product documentation would be + appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not + be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source distribution. + +----------------------------------------------------------------------------- + +The zLib/libpng license has been approved by the "Open Source Initiative" +organization. diff --git a/readme.txt b/readme.txt index 28e73f0..fe375f7 100644 --- a/readme.txt +++ b/readme.txt @@ -1,297 +1,297 @@ -the Pawn embedded scripting language -==================================== -Pawn is a simple, typeless, 32-bit extension language with a C-like syntax. -The Pawn compiler outputs P-code (or bytecode) that subsequently runs on an -abstract machine. Execution speed, stability, simplicity and a small footprint -were essential design criterions for both the language and the abstract -machine. - -Through the evolution of the Pawn toolkit, this README had steadily been -growing, as more and more compilers were tested and more components were added. -More recently, the compiling instructions were moved to a separate document -entitled "The Pawn booklet: Implementor's Guide". To get the Pawn toolkit -working on your system, please (also) consult that document. To learn about -the Pawn language, read the document "The Pawn booklet: The Language". If you -installed Pawn via the Setup utility (for Microsoft Windows) or the autopackage -(for Linux), you probably have these documents already. Otherwise, you can -obtain both these documents from the web page devoted to Pawn: - http://www.compuphase.com/pawn.htm - -Below is a list of topics that this README covers, in this order: - -o Getting started - How to get your first Pawn program running - -o Building with CMake - For a portable way to (re-)build the software - -o Acknowledgements - For components not written by CompuPhase - -o Using the AMX DLL - How to create a program that uses the pre-built DLL. - -o Building the AMX DLL - Notes on how the DLL must be built itself. - -o Building extension modules for the AMX DLL - - -Getting started -=============== -The first question is: what do you need? If you are using Microsoft Windows, -download the Pawn toolkit as a self-extracting setup file; this gives -everything that you need to get started: -o binaries for Win32 -o full source of all tools/libraries -o documentation (Adobe Acrobat format) - -Users of other operating systems should download either the "pawnkit.zip" -file or the "pawnkit.tgz" file ("Pawn toolkit" archives), because it -contains the full source code. The difference between the "ZIP" file and the -"TGZ" file is, apart from the different archiving tool used, that the source -file in the ZIP file has DOS/Windows line endings (CR/LF) and the "TGZ" file -has Unix line endings (LF only). When "unpacking" these archives, make sure -that the directory structure in the ZIP/TGZ files is retained. Otherwise, the -Pawn compiler will not be able to find its "include" files, for example. - -You should also download the two documentation files "pawn-lng.pdf" and -"pawn-imp.pdf" --the "Language guide" and the "Implementor's guide" -respectively. You may need to build the compiler and abstract machine, and -the "Implementor's guide" is likely to give you precise guidelines (or at -least, it will point you in the right direction). There are a few guidelines -for building the system with CMake in the section "Building with CMake", below. - -Assuming that you have obtained (somehow) an executable version of the Pawn -compiler and the Pawn run-time, you should put it in a directory. However, -the Pawn compiler also needs to locate "include files". On many operating -systems, the Pawn compiler is able to automatically read these header files -from the directory "include" that is below the directory that the compiler is -in itself. Thus, if the Pawn compiler (the executable file) is in directory -"C:\WhatEver\Pawn\bin", I suggest that you create either the directory -"C:\WhatEver\Pawn\include" or "C:\WhatEver\Pawn\bin\include" and copy the -".inc" files there. If your operating system is not compatible with Win32 or -Linux, the Pawn compiler may not know how to locate the "include" directory -and you have to specify it yourself with the "-i" command line option (when -running the compiler). - -That behind your back, locate one of the example scripts (e.g. "hello.p") and -compile it with: - - pawncc hello - -This should produce "hello.amx", which you can then run with: - - pawnrun hello.amx - -Many applications that use Pawn, run the Pawn compiler as a child process; -i.e. the Pawn compiler is often a separate, self-contained program. The -abstract machine, however, is almost never a separate process: typically you -want the abstract machine to be integrated in the application so that scripts -can call into the application. In other words, you might be using "pawncc" as -is, but you won't be using "pawnrun" as is. This is why pawnrun is kept short -and dump, "pawnrun" is a program that is mostly developed in the Pawn manual to -show you what you should do at a minimum to embed Pawn into a program. - - -Building with CMake -=================== -CMake is a cross-platform, open-source make system, which generates "makefile's" -or project files for diverse compilers and platforms. See http://www.cmake.org/ -for more information on CMake plus a freely downloadable copy. - -The Pawn toolkit comes with a CMake project file that builds the compiler, a -simple run-time program that embeds the abstract machine, and a simple console -debugger. The CMake project file is in the "source" subdirectory of where the -Pawn toolkit is installed, when you installed the self-extracting "setup" for -Microsoft Windows. When unpacking the Pawn source code from a "ZIP" or "TGZ" -archive, the CMake project file is in the main directory where you unpacked -the archive into. - -Microsoft Windows ------------------ -1. Launch CMakeSetup. - -2. Select for the source code directory, the "source" subdirectory in the - directory tree for the toolkit. - - For example, if you installed the toolkit in C:\Pawn, the source directory - is C:\Pawn\source. - -3. Select as destination the "bin" subdirectory, or any other directory of your - choice. The makefile (or project files) will be generated in the destination - directory. - -4. Select the compiler to use, as well. On Microsoft Windows, CMake supports - Microsoft and Borland compilers, as well as GNU GCC. - -5. Click on the "Configure" button. After an initial configuration, you may - have items displayed in red. By this, CMake indicates that these items - may need adjustment, but in the case of Pawn, this is rarely needed. Click - "Configure" once more for the final configuration. - -6. Click on the "OK" button. This exits the CMakeSetup program after creating a - number of files in the destination subdirectory. - -7. Build the program in the usual way. For Microsoft Visual C/C++, CMake has - created a Visual Studio project and "Workspace" file; for other compilers - CMake builds a makefile. - - -Linux / Unix ------------- -1. Change to the "bin" subdirectory where the archive was extracted into. For - example, if you unpacked the toolkit in /opt/Pawn, go to /opt/Pawn/bin. - - If you installed Pawn as root, then you must also be root when you recompile - Pawn. - -2. Launch "ccmake ../source" if you installed the Linux autopackage. If you got - the "tarball", you may need to use "ccmake .." instead. The parameter of - ccmake must be the relative path to where the CMakeLists.txt file is found. - -3. Press the "c" key for "configure". After an initial configuration, you may - have items in the list that have a "*" in front of their value. By this, - CMake indicates that these items may need adjustment, but in the case of - Pawn, this is rarely needed. Type "c" once more for the final configuration. - -4. Press the "g" button for "generate and quit". Then build the program by - typing "make". The programs will be built in the subdirectory "bin". - - -Acknowledgements -================ -This work is based on the "Small C Compiler" by Ron Cain and James E. Hendrix, -as published in the book "Dr. Dobb's Toolbook of C", Brady Books, 1986. - -The assembler version of the abstract machine (five times faster than the ANSI -C version and over two times faster than the GNU C version) was written by -Marc Peter (macpete@gmx.de). Marc holds the copyright of the file AMXEXEC.ASM, -but its distribution and license fall under the same conditions as those -stated in LICENSE.TXT. - -The Just-In-Time compiler (JIT) included in this release was also written by -Marc Peter. As is apparent from the source code, the JIT is an evolutionary -step from his earlier abstract machine. The JIT falls under the same (liberal) -license as the other components in the Pawn toolkit. The abstract machine -has evolved slightly since Marc Peter write the JIT and the JIT does currently -not handle the "sleep" instruction correctly. - -The power user David "Bailopan" Anderson (see www.bailopan.net) found many bugs -in Pawn, and provided patches and detailed reports. He and his team also -provided a new "memory file" module that make the compiler process large scripts -quicker. - -G.W.M. Vissers translated Marc Peter's JIT to NASM. This makes the JIT available -to Linux and Unix-like platforms. - -Greg Garner from Artran Inc. compiled the source files as C++ files (rather -than C), added type casts where needed and fixed two bugs in the Pawn compiler -in the process. Greg Garner also wrote (and contributed) the extension module -for floating point support (files FLOAT.CPP and FLOAT.INC). I am currently -maintaining these modules, in order to keep them up to date with new features -in the Pawn toolkit. - -Dark Fiber contributed an extension module for the AMX to provide decent -quality pseudo-random numbers, starting with any seed. To illustrate the -module, he also wrote a simple card game (TWENTY1.SMA) as a non-trivial -Pawn script. - -Dieter Neubauer made a 16-bit version of the Pawn tools (meaning that a cell -is 16-bit, instead of the default 32-bit). His changes were merged in the -original distribution. Note that fixed or floating point arithmetic will be -near to impossible with a 16-bit cell. - -Robert Daniels ported Pawn to ucLinux and corrected a few errors that had to -do with the "Endianness" of the CPU. His corrections make the Pawn compiler -and abstract machine better portable to Big Endian machines. - -Frank Condello made a port of the Pawn toolkit to MacOS (CFM Carbon). His -changes are merged into the main source trunk. - - -Using the AMX DLL -================= -The 32-bit AMX DLL (file AMX32.DLL) uses __stdcall calling convention, which -is the most common calling convention for Win32 DLLs. If your compiler defaults -to a different calling convention (most do), you must specify the __stdcall -calling convention explicitly. This can be done in two ways: -1. a command line option for the C/C++ compiler (look up the manual) -2. setting the macros AMX_NATIVE_CALL and AMXAPI to __stdcall before including - AMX.H. The macros AMX_NATIVE_CALL and AMXAPI are explained earlier in this - README. - -The 32-bit AMX DLL comes with import libraries for various Win32 compilers: -o for Microsoft Visual C/C++ version 4.0 and above, use AMX32M.LIB -o for Borland C++ version 5.0 and for Borland C++ Builder, use AMX32B.LIB -o for Watcom C/C++ version 10.6 and 11.0, use AMX32W.LIB - -The AMX DLL already includes "core" and "console" functions, which are the -equivalents of the C files AMXCORE.C and AMXCONS.C. Console output goes to a -text window (with 30 lines of 80 characters per line) that the DLL creates. -The core and console functions are automatically registered to any Pawn -program by amx_Init(). - - Microsoft Visual C/C++ version 5.0 or 6.0, 32-bit: - cl -DAMXAPI=__stdcall prun-dll.c amx32m.lib - - (Note: the "prun-dll" example does not register additional native - functions. Therefore, AMX_NATIVE_CALL does not need to be defined.) - - Watcom C/C++ version 11.0, 32-bit: - wcl386 /l=nt_win /dAMXAPI=__stdcall prun-dll.c amx32w.lib - - (Note: the "prun-dll" example does not register additional native - functions. Therefore, AMX_NATIVE_CALL does not need to be defined.) - - Borland C++ version 3.1, 16-bit: - bcc -DAMXAPI=__cdecl -W -ml prun-dll.c amx16.lib - - (Note: the program must be compiled as a Win16 application, because - only Windows programs can use DLLs (option -W). Using large memory - model, option -ml, is not strictly required, but it is the most - convenient. Finally, note that the 16-bit DLL uses __cdecl calling - convention for its exported functions, for reasons explained below.) - - -Building the AMX DLL -==================== -The 32-bit DLL is made from the files AMX.C, AMXDLL.C, AMXCONS.C, AMXCORE.C -and AMXEXEC.ASM. - -The first point to address is, again, that of calling conventions. AMXAPI and -AMX_NATIVE_CALL must be set to __stdcall. I did this by adding the macros onto -the command line for the compiler, but you could also create an include file -with these macros before including AMX.H. - -The function amx_Init() of the DLL is not identical to the standard version: -it also registers the "core" and "console" modules and registers external -libraries if it can find these. The original amx_Init() in AMX.C is renamed to -amx_InitAMX(), via macros, at compile time. AMXDLL.C implements the new -amx_Init() and this one is not translated. - -All in all, the makefile for the AMX DLL plays a few tricks with macros in -order to keep the original distribution untouched. When you need to recompile -the AMX DLL, you may, of course, also opt for modifying AMX.H and AMX.C to -suit the needs for Win32 DLLs. - -If you rebuild the DLL for 16-bit Windows, keep the following points in mind: -o You must use the ANSI C version of the abstract machine; there is no - 16-bit assembler implementation. -o Use large memory model: pointers used in "interface" functions must be far - pointers to bridge the data spaces of the .EXE and the DLL. The source - code is (mostly) ANSI C, however, and "far pointers" are an extension to - ANSI C. The easiest way out is to make all pointers "far" by using large - memory model. -o AMX_NATIVE_CALL are best set to "__far __pascal". This is the "standard" - calling convention for have interface functions in 16-bit Windows. -o The native functions should also be exported, so that the data segment is - set to that of the module that the native functions reside in. -o AMXAPI, however, must be set to "__cdecl", because amx_Exec() uses a - variable length argument list. This is incompatible with the "pascal" - calling convention. - -The distribution for the AMX DLL comes with two makefiles: the makefile for the -32-bit DLL is for Watcom C/C++ and the makefile for the 16-bit DLL is for -Borland C++ (Inprise). - +the Pawn embedded scripting language +==================================== +Pawn is a simple, typeless, 32-bit extension language with a C-like syntax. +The Pawn compiler outputs P-code (or bytecode) that subsequently runs on an +abstract machine. Execution speed, stability, simplicity and a small footprint +were essential design criterions for both the language and the abstract +machine. + +Through the evolution of the Pawn toolkit, this README had steadily been +growing, as more and more compilers were tested and more components were added. +More recently, the compiling instructions were moved to a separate document +entitled "The Pawn booklet: Implementor's Guide". To get the Pawn toolkit +working on your system, please (also) consult that document. To learn about +the Pawn language, read the document "The Pawn booklet: The Language". If you +installed Pawn via the Setup utility (for Microsoft Windows) or the autopackage +(for Linux), you probably have these documents already. Otherwise, you can +obtain both these documents from the web page devoted to Pawn: + http://www.compuphase.com/pawn.htm + +Below is a list of topics that this README covers, in this order: + +o Getting started + How to get your first Pawn program running + +o Building with CMake + For a portable way to (re-)build the software + +o Acknowledgements + For components not written by CompuPhase + +o Using the AMX DLL + How to create a program that uses the pre-built DLL. + +o Building the AMX DLL + Notes on how the DLL must be built itself. + +o Building extension modules for the AMX DLL + + +Getting started +=============== +The first question is: what do you need? If you are using Microsoft Windows, +download the Pawn toolkit as a self-extracting setup file; this gives +everything that you need to get started: +o binaries for Win32 +o full source of all tools/libraries +o documentation (Adobe Acrobat format) + +Users of other operating systems should download either the "pawnkit.zip" +file or the "pawnkit.tgz" file ("Pawn toolkit" archives), because it +contains the full source code. The difference between the "ZIP" file and the +"TGZ" file is, apart from the different archiving tool used, that the source +file in the ZIP file has DOS/Windows line endings (CR/LF) and the "TGZ" file +has Unix line endings (LF only). When "unpacking" these archives, make sure +that the directory structure in the ZIP/TGZ files is retained. Otherwise, the +Pawn compiler will not be able to find its "include" files, for example. + +You should also download the two documentation files "pawn-lng.pdf" and +"pawn-imp.pdf" --the "Language guide" and the "Implementor's guide" +respectively. You may need to build the compiler and abstract machine, and +the "Implementor's guide" is likely to give you precise guidelines (or at +least, it will point you in the right direction). There are a few guidelines +for building the system with CMake in the section "Building with CMake", below. + +Assuming that you have obtained (somehow) an executable version of the Pawn +compiler and the Pawn run-time, you should put it in a directory. However, +the Pawn compiler also needs to locate "include files". On many operating +systems, the Pawn compiler is able to automatically read these header files +from the directory "include" that is below the directory that the compiler is +in itself. Thus, if the Pawn compiler (the executable file) is in directory +"C:\WhatEver\Pawn\bin", I suggest that you create either the directory +"C:\WhatEver\Pawn\include" or "C:\WhatEver\Pawn\bin\include" and copy the +".inc" files there. If your operating system is not compatible with Win32 or +Linux, the Pawn compiler may not know how to locate the "include" directory +and you have to specify it yourself with the "-i" command line option (when +running the compiler). + +That behind your back, locate one of the example scripts (e.g. "hello.p") and +compile it with: + + pawncc hello + +This should produce "hello.amx", which you can then run with: + + pawnrun hello.amx + +Many applications that use Pawn, run the Pawn compiler as a child process; +i.e. the Pawn compiler is often a separate, self-contained program. The +abstract machine, however, is almost never a separate process: typically you +want the abstract machine to be integrated in the application so that scripts +can call into the application. In other words, you might be using "pawncc" as +is, but you won't be using "pawnrun" as is. This is why pawnrun is kept short +and dump, "pawnrun" is a program that is mostly developed in the Pawn manual to +show you what you should do at a minimum to embed Pawn into a program. + + +Building with CMake +=================== +CMake is a cross-platform, open-source make system, which generates "makefile's" +or project files for diverse compilers and platforms. See http://www.cmake.org/ +for more information on CMake plus a freely downloadable copy. + +The Pawn toolkit comes with a CMake project file that builds the compiler, a +simple run-time program that embeds the abstract machine, and a simple console +debugger. The CMake project file is in the "source" subdirectory of where the +Pawn toolkit is installed, when you installed the self-extracting "setup" for +Microsoft Windows. When unpacking the Pawn source code from a "ZIP" or "TGZ" +archive, the CMake project file is in the main directory where you unpacked +the archive into. + +Microsoft Windows +----------------- +1. Launch CMakeSetup. + +2. Select for the source code directory, the "source" subdirectory in the + directory tree for the toolkit. + + For example, if you installed the toolkit in C:\Pawn, the source directory + is C:\Pawn\source. + +3. Select as destination the "bin" subdirectory, or any other directory of your + choice. The makefile (or project files) will be generated in the destination + directory. + +4. Select the compiler to use, as well. On Microsoft Windows, CMake supports + Microsoft and Borland compilers, as well as GNU GCC. + +5. Click on the "Configure" button. After an initial configuration, you may + have items displayed in red. By this, CMake indicates that these items + may need adjustment, but in the case of Pawn, this is rarely needed. Click + "Configure" once more for the final configuration. + +6. Click on the "OK" button. This exits the CMakeSetup program after creating a + number of files in the destination subdirectory. + +7. Build the program in the usual way. For Microsoft Visual C/C++, CMake has + created a Visual Studio project and "Workspace" file; for other compilers + CMake builds a makefile. + + +Linux / Unix +------------ +1. Change to the "bin" subdirectory where the archive was extracted into. For + example, if you unpacked the toolkit in /opt/Pawn, go to /opt/Pawn/bin. + + If you installed Pawn as root, then you must also be root when you recompile + Pawn. + +2. Launch "ccmake ../source" if you installed the Linux autopackage. If you got + the "tarball", you may need to use "ccmake .." instead. The parameter of + ccmake must be the relative path to where the CMakeLists.txt file is found. + +3. Press the "c" key for "configure". After an initial configuration, you may + have items in the list that have a "*" in front of their value. By this, + CMake indicates that these items may need adjustment, but in the case of + Pawn, this is rarely needed. Type "c" once more for the final configuration. + +4. Press the "g" button for "generate and quit". Then build the program by + typing "make". The programs will be built in the subdirectory "bin". + + +Acknowledgements +================ +This work is based on the "Small C Compiler" by Ron Cain and James E. Hendrix, +as published in the book "Dr. Dobb's Toolbook of C", Brady Books, 1986. + +The assembler version of the abstract machine (five times faster than the ANSI +C version and over two times faster than the GNU C version) was written by +Marc Peter (macpete@gmx.de). Marc holds the copyright of the file AMXEXEC.ASM, +but its distribution and license fall under the same conditions as those +stated in LICENSE.TXT. + +The Just-In-Time compiler (JIT) included in this release was also written by +Marc Peter. As is apparent from the source code, the JIT is an evolutionary +step from his earlier abstract machine. The JIT falls under the same (liberal) +license as the other components in the Pawn toolkit. The abstract machine +has evolved slightly since Marc Peter write the JIT and the JIT does currently +not handle the "sleep" instruction correctly. + +The power user David "Bailopan" Anderson (see www.bailopan.net) found many bugs +in Pawn, and provided patches and detailed reports. He and his team also +provided a new "memory file" module that make the compiler process large scripts +quicker. + +G.W.M. Vissers translated Marc Peter's JIT to NASM. This makes the JIT available +to Linux and Unix-like platforms. + +Greg Garner from Artran Inc. compiled the source files as C++ files (rather +than C), added type casts where needed and fixed two bugs in the Pawn compiler +in the process. Greg Garner also wrote (and contributed) the extension module +for floating point support (files FLOAT.CPP and FLOAT.INC). I am currently +maintaining these modules, in order to keep them up to date with new features +in the Pawn toolkit. + +Dark Fiber contributed an extension module for the AMX to provide decent +quality pseudo-random numbers, starting with any seed. To illustrate the +module, he also wrote a simple card game (TWENTY1.SMA) as a non-trivial +Pawn script. + +Dieter Neubauer made a 16-bit version of the Pawn tools (meaning that a cell +is 16-bit, instead of the default 32-bit). His changes were merged in the +original distribution. Note that fixed or floating point arithmetic will be +near to impossible with a 16-bit cell. + +Robert Daniels ported Pawn to ucLinux and corrected a few errors that had to +do with the "Endianness" of the CPU. His corrections make the Pawn compiler +and abstract machine better portable to Big Endian machines. + +Frank Condello made a port of the Pawn toolkit to MacOS (CFM Carbon). His +changes are merged into the main source trunk. + + +Using the AMX DLL +================= +The 32-bit AMX DLL (file AMX32.DLL) uses __stdcall calling convention, which +is the most common calling convention for Win32 DLLs. If your compiler defaults +to a different calling convention (most do), you must specify the __stdcall +calling convention explicitly. This can be done in two ways: +1. a command line option for the C/C++ compiler (look up the manual) +2. setting the macros AMX_NATIVE_CALL and AMXAPI to __stdcall before including + AMX.H. The macros AMX_NATIVE_CALL and AMXAPI are explained earlier in this + README. + +The 32-bit AMX DLL comes with import libraries for various Win32 compilers: +o for Microsoft Visual C/C++ version 4.0 and above, use AMX32M.LIB +o for Borland C++ version 5.0 and for Borland C++ Builder, use AMX32B.LIB +o for Watcom C/C++ version 10.6 and 11.0, use AMX32W.LIB + +The AMX DLL already includes "core" and "console" functions, which are the +equivalents of the C files AMXCORE.C and AMXCONS.C. Console output goes to a +text window (with 30 lines of 80 characters per line) that the DLL creates. +The core and console functions are automatically registered to any Pawn +program by amx_Init(). + + Microsoft Visual C/C++ version 5.0 or 6.0, 32-bit: + cl -DAMXAPI=__stdcall prun-dll.c amx32m.lib + + (Note: the "prun-dll" example does not register additional native + functions. Therefore, AMX_NATIVE_CALL does not need to be defined.) + + Watcom C/C++ version 11.0, 32-bit: + wcl386 /l=nt_win /dAMXAPI=__stdcall prun-dll.c amx32w.lib + + (Note: the "prun-dll" example does not register additional native + functions. Therefore, AMX_NATIVE_CALL does not need to be defined.) + + Borland C++ version 3.1, 16-bit: + bcc -DAMXAPI=__cdecl -W -ml prun-dll.c amx16.lib + + (Note: the program must be compiled as a Win16 application, because + only Windows programs can use DLLs (option -W). Using large memory + model, option -ml, is not strictly required, but it is the most + convenient. Finally, note that the 16-bit DLL uses __cdecl calling + convention for its exported functions, for reasons explained below.) + + +Building the AMX DLL +==================== +The 32-bit DLL is made from the files AMX.C, AMXDLL.C, AMXCONS.C, AMXCORE.C +and AMXEXEC.ASM. + +The first point to address is, again, that of calling conventions. AMXAPI and +AMX_NATIVE_CALL must be set to __stdcall. I did this by adding the macros onto +the command line for the compiler, but you could also create an include file +with these macros before including AMX.H. + +The function amx_Init() of the DLL is not identical to the standard version: +it also registers the "core" and "console" modules and registers external +libraries if it can find these. The original amx_Init() in AMX.C is renamed to +amx_InitAMX(), via macros, at compile time. AMXDLL.C implements the new +amx_Init() and this one is not translated. + +All in all, the makefile for the AMX DLL plays a few tricks with macros in +order to keep the original distribution untouched. When you need to recompile +the AMX DLL, you may, of course, also opt for modifying AMX.H and AMX.C to +suit the needs for Win32 DLLs. + +If you rebuild the DLL for 16-bit Windows, keep the following points in mind: +o You must use the ANSI C version of the abstract machine; there is no + 16-bit assembler implementation. +o Use large memory model: pointers used in "interface" functions must be far + pointers to bridge the data spaces of the .EXE and the DLL. The source + code is (mostly) ANSI C, however, and "far pointers" are an extension to + ANSI C. The easiest way out is to make all pointers "far" by using large + memory model. +o AMX_NATIVE_CALL are best set to "__far __pascal". This is the "standard" + calling convention for have interface functions in 16-bit Windows. +o The native functions should also be exported, so that the data segment is + set to that of the module that the native functions reside in. +o AMXAPI, however, must be set to "__cdecl", because amx_Exec() uses a + variable length argument list. This is incompatible with the "pascal" + calling convention. + +The distribution for the AMX DLL comes with two makefiles: the makefile for the +32-bit DLL is for Watcom C/C++ and the makefile for the 16-bit DLL is for +Borland C++ (Inprise). + diff --git a/source/compiler/CMakeLists.txt b/source/compiler/CMakeLists.txt index d15ec87..d7e3244 100644 --- a/source/compiler/CMakeLists.txt +++ b/source/compiler/CMakeLists.txt @@ -1,74 +1,74 @@ -#build file for CMake, see http://www.cmake.org/ - -PROJECT(pawnc) - -CMAKE_MINIMUM_REQUIRED(VERSION 2.6) - -# check for optional include files -INCLUDE(${CMAKE_ROOT}/Modules/CheckIncludeFile.cmake) -CHECK_INCLUDE_FILE("unistd.h" HAVE_UNISTD_H) -IF(HAVE_UNISTD_H) - ADD_DEFINITIONS(-DHAVE_UNISTD_H) -ENDIF(HAVE_UNISTD_H) -CHECK_INCLUDE_FILE("inttypes.h" HAVE_INTTYPES_H) -IF(HAVE_INTTYPES_H) - ADD_DEFINITIONS(-DHAVE_INTTYPES_H) -ENDIF(HAVE_INTTYPES_H) -CHECK_INCLUDE_FILE("stdint.h" HAVE_STDINT_H) -IF(HAVE_STDINT_H) - ADD_DEFINITIONS(-DHAVE_STDINT_H) -ENDIF(HAVE_STDINT_H) -CHECK_INCLUDE_FILE("alloca.h" HAVE_ALLOCA_H) -IF(HAVE_ALLOCA_H) - ADD_DEFINITIONS(-DHAVE_ALLOCA_H) -ENDIF(HAVE_ALLOCA_H) - -IF(UNIX) - ADD_DEFINITIONS(-DLINUX -DENABLE_BINRELOC -g) - INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../linux) - LINK_LIBRARIES(pthread) #CMake adds the "lib" prefix, so "pthread" becomes "libpthread" -ENDIF(UNIX) - -# The Pawn compiler shared library -SET(PAWNC_SRCS sc1.c sc2.c sc3.c sc4.c sc5.c sc6.c sc7.c - scexpand.c sci18n.c sclist.c scmemfil.c scstate.c scvars.c - lstring.c memfile.c libpawnc.c) -SET_SOURCE_FILES_PROPERTIES(sc1.c COMPILE_FLAGS -DNO_MAIN) -IF(WIN32) - SET(PAWNC_SRCS ${PAWNC_SRCS} libpawnc.rc) - SET_SOURCE_FILES_PROPERTIES(libpawnc.c COMPILE_FLAGS -DPAWNC_DLL) - IF(BORLAND) - # Borland linker uses a DEF file if one is in the output directory - CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/libpawnc.def.borland ${CMAKE_BINARY_DIR}/pawnc.def COPY_ONLY) - ELSE(BORLAND) - # Microsoft Visual C/C++ supports a DEF file as if it were a source file - SET(PAWNC_SRCS ${PAWNC_SRCS} libpawnc.def) - ENDIF(BORLAND) -ENDIF(WIN32) -IF(UNIX) - SET(PAWNC_SRCS ${PAWNC_SRCS} ${CMAKE_CURRENT_SOURCE_DIR}/../linux/binreloc.c) -ENDIF(UNIX) -ADD_LIBRARY(pawnc SHARED ${PAWNC_SRCS}) -IF(WATCOM) #Watcom C/C++ does not support a .DEF file for the exports - SET_TARGET_PROPERTIES(pawnc PROPERTIES LINK_FLAGS "/exp=libpawnc") -ENDIF(WATCOM) -IF(UNIX AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug") - # Unix exports all symbols by default; we want only a very select few exported symbols - ADD_CUSTOM_COMMAND(TARGET pawnc POST_BUILD COMMAND strip ARGS -K pc_compile -K pc_addconstant -K pc_addtag -K pc_enablewarning ${CMAKE_BINARY_DIR}/libpawnc.so) -ENDIF(UNIX AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug") - - -# The Pawn compiler driver (console program) -SET(PAWNCC_SRCS pawncc.c) -IF(WIN32) - SET(PAWNCC_SRCS ${PAWNCC_SRCS} libpawnc.rc) - IF(BORLAND) - # Borland linker uses a DEF file if one is in the output directory - CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/pawncc.def.borland ${CMAKE_BINARY_DIR}/pawncc.def COPY_ONLY) - ELSE(BORLAND) - # Microsoft Visual C/C++ supports a DEF file as if it were a source file - SET(PAWNC_SRCS ${PAWNC_SRCS} pawncc.def) - ENDIF(BORLAND) -ENDIF(WIN32) -ADD_EXECUTABLE(pawncc ${PAWNCC_SRCS}) -TARGET_LINK_LIBRARIES(pawncc pawnc) +#build file for CMake, see http://www.cmake.org/ + +PROJECT(pawnc) + +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +# check for optional include files +INCLUDE(${CMAKE_ROOT}/Modules/CheckIncludeFile.cmake) +CHECK_INCLUDE_FILE("unistd.h" HAVE_UNISTD_H) +IF(HAVE_UNISTD_H) + ADD_DEFINITIONS(-DHAVE_UNISTD_H) +ENDIF(HAVE_UNISTD_H) +CHECK_INCLUDE_FILE("inttypes.h" HAVE_INTTYPES_H) +IF(HAVE_INTTYPES_H) + ADD_DEFINITIONS(-DHAVE_INTTYPES_H) +ENDIF(HAVE_INTTYPES_H) +CHECK_INCLUDE_FILE("stdint.h" HAVE_STDINT_H) +IF(HAVE_STDINT_H) + ADD_DEFINITIONS(-DHAVE_STDINT_H) +ENDIF(HAVE_STDINT_H) +CHECK_INCLUDE_FILE("alloca.h" HAVE_ALLOCA_H) +IF(HAVE_ALLOCA_H) + ADD_DEFINITIONS(-DHAVE_ALLOCA_H) +ENDIF(HAVE_ALLOCA_H) + +IF(UNIX) + ADD_DEFINITIONS(-DLINUX -DENABLE_BINRELOC -g) + INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../linux) + LINK_LIBRARIES(pthread) #CMake adds the "lib" prefix, so "pthread" becomes "libpthread" +ENDIF(UNIX) + +# The Pawn compiler shared library +SET(PAWNC_SRCS sc1.c sc2.c sc3.c sc4.c sc5.c sc6.c sc7.c + scexpand.c sci18n.c sclist.c scmemfil.c scstate.c scvars.c + lstring.c memfile.c libpawnc.c) +SET_SOURCE_FILES_PROPERTIES(sc1.c COMPILE_FLAGS -DNO_MAIN) +IF(WIN32) + SET(PAWNC_SRCS ${PAWNC_SRCS} libpawnc.rc) + SET_SOURCE_FILES_PROPERTIES(libpawnc.c COMPILE_FLAGS -DPAWNC_DLL) + IF(BORLAND) + # Borland linker uses a DEF file if one is in the output directory + CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/libpawnc.def.borland ${CMAKE_BINARY_DIR}/pawnc.def COPY_ONLY) + ELSE(BORLAND) + # Microsoft Visual C/C++ supports a DEF file as if it were a source file + SET(PAWNC_SRCS ${PAWNC_SRCS} libpawnc.def) + ENDIF(BORLAND) +ENDIF(WIN32) +IF(UNIX) + SET(PAWNC_SRCS ${PAWNC_SRCS} ${CMAKE_CURRENT_SOURCE_DIR}/../linux/binreloc.c) +ENDIF(UNIX) +ADD_LIBRARY(pawnc SHARED ${PAWNC_SRCS}) +IF(WATCOM) #Watcom C/C++ does not support a .DEF file for the exports + SET_TARGET_PROPERTIES(pawnc PROPERTIES LINK_FLAGS "/exp=libpawnc") +ENDIF(WATCOM) +IF(UNIX AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug") + # Unix exports all symbols by default; we want only a very select few exported symbols + ADD_CUSTOM_COMMAND(TARGET pawnc POST_BUILD COMMAND strip ARGS -K pc_compile -K pc_addconstant -K pc_addtag -K pc_enablewarning ${CMAKE_BINARY_DIR}/libpawnc.so) +ENDIF(UNIX AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug") + + +# The Pawn compiler driver (console program) +SET(PAWNCC_SRCS pawncc.c) +IF(WIN32) + SET(PAWNCC_SRCS ${PAWNCC_SRCS} libpawnc.rc) + IF(BORLAND) + # Borland linker uses a DEF file if one is in the output directory + CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/pawncc.def.borland ${CMAKE_BINARY_DIR}/pawncc.def COPY_ONLY) + ELSE(BORLAND) + # Microsoft Visual C/C++ supports a DEF file as if it were a source file + SET(PAWNC_SRCS ${PAWNC_SRCS} pawncc.def) + ENDIF(BORLAND) +ENDIF(WIN32) +ADD_EXECUTABLE(pawncc ${PAWNCC_SRCS}) +TARGET_LINK_LIBRARIES(pawncc pawnc) diff --git a/source/compiler/libpawnc.def b/source/compiler/libpawnc.def index eb90517..b4fe172 100644 --- a/source/compiler/libpawnc.def +++ b/source/compiler/libpawnc.def @@ -1,8 +1,8 @@ -LIBRARY PAWNC -DESCRIPTION 'Pawn compiler' - -EXPORTS Compile - pc_compile - pc_addconstant - pc_addtag - pc_enablewarning +LIBRARY PAWNC +DESCRIPTION 'Pawn compiler' + +EXPORTS Compile + pc_compile + pc_addconstant + pc_addtag + pc_enablewarning diff --git a/source/compiler/libpawnc.def.borland b/source/compiler/libpawnc.def.borland index 37eed64..955801e 100644 --- a/source/compiler/libpawnc.def.borland +++ b/source/compiler/libpawnc.def.borland @@ -1,8 +1,8 @@ -LIBRARY PAWNC -DESCRIPTION 'Pawn compiler' - -EXPORTS Compile - pc_compile = _pc_compile - pc_addconstant = _pc_addconstant - pc_addtag = _pc_addtag - pc_enablewarning = _pc_enablewarning +LIBRARY PAWNC +DESCRIPTION 'Pawn compiler' + +EXPORTS Compile + pc_compile = _pc_compile + pc_addconstant = _pc_addconstant + pc_addtag = _pc_addtag + pc_enablewarning = _pc_enablewarning diff --git a/source/compiler/libpawnc.lbc b/source/compiler/libpawnc.lbc index 529c192..1ad8a58 100644 --- a/source/compiler/libpawnc.lbc +++ b/source/compiler/libpawnc.lbc @@ -1,6 +1,6 @@ -++_Compile@16 .libpawnc .Compile -++pc_compile .libpawnc .pc_compile -++pc_addconstant .libpawnc .pc_addconstant -++pc_addtag .libpawnc .pc_addtag -++pc_enablewarning .libpawnc .pc_enablewarning -++pc_printf .libpawnc .pc_printf +++_Compile@16 .libpawnc .Compile +++pc_compile .libpawnc .pc_compile +++pc_addconstant .libpawnc .pc_addconstant +++pc_addtag .libpawnc .pc_addtag +++pc_enablewarning .libpawnc .pc_enablewarning +++pc_printf .libpawnc .pc_printf diff --git a/source/compiler/libpawnc.rc b/source/compiler/libpawnc.rc index d85d749..277aedd 100644 --- a/source/compiler/libpawnc.rc +++ b/source/compiler/libpawnc.rc @@ -1,63 +1,63 @@ -#include -#if defined WIN32 || defined _WIN32 || defined __WIN32__ -# include -#else -# include -#endif -#include "svnrev.h" - -AppIcon ICON "../bin/pawn.ico" - -/* Version information - * - * All strings MUST have an explicit \0. See the Windows SDK documentation - * for details on version information and the VERSIONINFO structure. - */ -#define VERSION 3 -#define REVISION 2 -#define BUILD SVN_REV -#define VERSIONSTR "3.2." SVN_REVSTR "\0" -#if defined STAND_ALONE -#define VERSIONNAME "pawncc.exe\0" -#define VERSIONDESCRIPTION "Pawn Compiler\0" -#define VERSIONPRODUCTNAME "pawncc\0" -#else -#define VERSIONNAME "libpawnc.dll\0" -#define VERSIONDESCRIPTION "Pawn Compiler library\0" -#define VERSIONPRODUCTNAME "libpawnc\0" -#endif -#define VERSIONCOMPANYNAME "ITB CompuPhase\0" -#define VERSIONCOPYRIGHT "Copyright \251 1998-2006 ITB CompuPhase\0" - -VS_VERSION_INFO VERSIONINFO -FILEVERSION VERSION, REVISION, BUILD, 0 -PRODUCTVERSION VERSION, REVISION, BUILD, 0 -FILEFLAGSMASK 0x0000003FL -FILEFLAGS 0 -#if defined(WIN32) - FILEOS VOS__WINDOWS32 -#else - FILEOS VOS__WINDOWS16 -#endif -FILETYPE VFT_DLL -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904E4" - BEGIN - VALUE "CompanyName", VERSIONCOMPANYNAME - VALUE "FileDescription", VERSIONDESCRIPTION - VALUE "FileVersion", VERSIONSTR - VALUE "InternalName", VERSIONNAME - VALUE "LegalCopyright", VERSIONCOPYRIGHT - VALUE "OriginalFilename", VERSIONNAME - VALUE "ProductName", VERSIONPRODUCTNAME - VALUE "ProductVersion", VERSIONSTR - END - END - - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1252 - END -END +#include +#if defined WIN32 || defined _WIN32 || defined __WIN32__ +# include +#else +# include +#endif +#include "svnrev.h" + +AppIcon ICON "../bin/pawn.ico" + +/* Version information + * + * All strings MUST have an explicit \0. See the Windows SDK documentation + * for details on version information and the VERSIONINFO structure. + */ +#define VERSION 3 +#define REVISION 2 +#define BUILD SVN_REV +#define VERSIONSTR "3.2." SVN_REVSTR "\0" +#if defined STAND_ALONE +#define VERSIONNAME "pawncc.exe\0" +#define VERSIONDESCRIPTION "Pawn Compiler\0" +#define VERSIONPRODUCTNAME "pawncc\0" +#else +#define VERSIONNAME "libpawnc.dll\0" +#define VERSIONDESCRIPTION "Pawn Compiler library\0" +#define VERSIONPRODUCTNAME "libpawnc\0" +#endif +#define VERSIONCOMPANYNAME "ITB CompuPhase\0" +#define VERSIONCOPYRIGHT "Copyright \251 1998-2006 ITB CompuPhase\0" + +VS_VERSION_INFO VERSIONINFO +FILEVERSION VERSION, REVISION, BUILD, 0 +PRODUCTVERSION VERSION, REVISION, BUILD, 0 +FILEFLAGSMASK 0x0000003FL +FILEFLAGS 0 +#if defined(WIN32) + FILEOS VOS__WINDOWS32 +#else + FILEOS VOS__WINDOWS16 +#endif +FILETYPE VFT_DLL +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + BEGIN + VALUE "CompanyName", VERSIONCOMPANYNAME + VALUE "FileDescription", VERSIONDESCRIPTION + VALUE "FileVersion", VERSIONSTR + VALUE "InternalName", VERSIONNAME + VALUE "LegalCopyright", VERSIONCOPYRIGHT + VALUE "OriginalFilename", VERSIONNAME + VALUE "ProductName", VERSIONPRODUCTNAME + VALUE "ProductVersion", VERSIONSTR + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END diff --git a/source/compiler/pawncc.def b/source/compiler/pawncc.def index 63cf717..388c0c5 100644 --- a/source/compiler/pawncc.def +++ b/source/compiler/pawncc.def @@ -1,2 +1,2 @@ -NAME PAWNCC -DESCRIPTION 'Pawn compiler' +NAME PAWNCC +DESCRIPTION 'Pawn compiler' diff --git a/source/compiler/pawncc.def.borland b/source/compiler/pawncc.def.borland index 32898f4..310f428 100644 --- a/source/compiler/pawncc.def.borland +++ b/source/compiler/pawncc.def.borland @@ -1,5 +1,5 @@ -NAME PAWNCC -DESCRIPTION 'Pawn compiler' - -IMPORTS - _pc_compile = pawnc.pc_compile +NAME PAWNCC +DESCRIPTION 'Pawn compiler' + +IMPORTS + _pc_compile = pawnc.pc_compile diff --git a/source/compiler/sc5.scp b/source/compiler/sc5.scp index ae44b97..49baf58 100644 --- a/source/compiler/sc5.scp +++ b/source/compiler/sc5.scp @@ -1,342 +1,342 @@ -/* Pawn compiler - Error message strings (plain and compressed formats) - * - * Copyright (c) ITB CompuPhase, 2000-2006 - * - * This software is provided "as-is", without any express or implied warranty. - * In no event will the authors be held liable for any damages arising from - * the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software in - * a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - * - * Version: $Id: sc5.sch 3633 2006-08-11 16:20:18Z thiadmer $ - */ - -SC_FUNC int strexpand(char *dest, unsigned char *source, int maxlen, unsigned char pairtable[128][2]); - -#define SCPACK_TABLE errstr_table -/*-*SCPACK start of pair table, do not change or remove this line */ -unsigned char errstr_table[][2] = { - {101,32}, {111,110}, {116,32}, {105,110}, {97,114}, {116,105}, {100,32}, {115,32}, {101,114}, {97,108}, {101,110}, {37,115}, {133,129}, {34,139}, {141,34}, {117,110}, - {114,101}, {110,111}, {115,105}, {121,32}, {97,116}, {111,114}, {97,110}, {32,142}, {109,98}, {115,116}, {41,10}, {100,101}, {109,138}, {101,134}, {98,108}, {140,32}, - {111,108}, {114,97}, {145,130}, {118,137}, {143,99}, {102,164}, {115,121}, {166,152}, {167,160}, {117,115}, {97,32}, {115,146}, {97,158}, {149,32}, {132,161}, {105,134}, - {103,32}, {163,175}, {103,117}, {178,156}, {136,32}, {132,179}, {131,177}, {111,102}, {116,104}, {101,120}, {105,135}, {165,159}, {101,100}, {99,104}, {118,132}, {168,151}, - {105,172}, {190,192}, {155,102}, {174,147}, {183,32}, {109,97}, {116,111}, {99,129}, {101,135}, {112,144}, {181,130}, {98,128}, {115,10}, {153,148}, {44,32}, {40,191}, - {169,130}, {151,10}, {101,10}, {207,154}, {109,208}, {116,97}, {194,131}, {193,128}, {34,32}, {129,32}, {105,99}, {132,97}, {100,105}, {146,122}, {110,32}, {137,32}, - {104,97}, {101,108}, {117,108}, {99,111}, {108,111}, {109,148}, {199,153}, {58,209}, {111,112}, {97,115}, {108,128}, {232,136}, {230,150}, {150,32}, {201,171}, {131,176}, - {212,203}, {102,105}, {119,105}, {185,238}, {109,112}, {116,136}, {165,140}, {197,147}, {102,149}, {111,32}, {131,32}, {213,176}, {110,117}, {115,117}, {118,128} -}; -/*-*SCPACK end of pair table, do not change or remove this line */ - -static char *errmsg[] = { -#ifdef SCPACK -/*001*/ "expected token: \"%s\", but found \"%s\"\n", -/*002*/ "only a single statement (or expression) can follow each \"case\"\n", -/*003*/ "declaration of a local variable must appear in a compound block\n", -/*004*/ "function \"%s\" is not implemented\n", -/*005*/ "function may not have arguments\n", -/*006*/ "must be assigned to an array\n", -/*007*/ "operator cannot be redefined\n", -/*008*/ "must be a constant expression; assumed zero\n", -/*009*/ "invalid array size (negative, zero or out of bounds)\n", -/*010*/ "invalid function or declaration\n", -/*011*/ "invalid outside functions\n", -/*012*/ "invalid function call, not a valid address\n", -/*013*/ "no entry point (no public functions)\n", -/*014*/ "invalid statement; not in switch\n", -/*015*/ "\"default\" case must be the last case in switch statement\n", -/*016*/ "multiple defaults in \"switch\"\n", -/*017*/ "undefined symbol \"%s\"\n", -/*018*/ "initialization data exceeds declared size\n", -/*019*/ "not a label: \"%s\"\n", -/*020*/ "invalid symbol name \"%s\"\n", -/*021*/ "symbol already defined: \"%s\"\n", -/*022*/ "must be lvalue (non-constant)\n", -/*023*/ "array assignment must be simple assignment\n", -/*024*/ "\"break\" or \"continue\" is out of context\n", -/*025*/ "function heading differs from prototype\n", -/*026*/ "no matching \"#if...\"\n", -/*027*/ "invalid character constant\n", -/*028*/ "invalid subscript (not an array or too many subscripts): \"%s\"\n", -/*029*/ "invalid expression, assumed zero\n", -/*030*/ "compound statement not closed at the end of file (started at line %d)\n", -/*031*/ "unknown directive\n", -/*032*/ "array index out of bounds (variable \"%s\")\n", -/*033*/ "array must be indexed (variable \"%s\")\n", -/*034*/ "argument does not have a default value (argument %d)\n", -/*035*/ "argument type mismatch (argument %d)\n", -/*036*/ "empty statement\n", -/*037*/ "invalid string (possibly non-terminated string)\n", -/*038*/ "extra characters on line\n", -/*039*/ "constant symbol has no size\n", -/*040*/ "duplicate \"case\" label (value %d)\n", -/*041*/ "invalid ellipsis, array size is not known\n", -/*042*/ "invalid combination of class specifiers\n", -/*043*/ "character constant exceeds range for packed string\n", -/*044*/ "positional parameters must precede all named parameters\n", -/*045*/ "too many function arguments\n", -/*046*/ "unknown array size (variable \"%s\")\n", -/*047*/ "array sizes do not match, or destination array is too small\n", -/*048*/ "array dimensions do not match\n", -/*049*/ "invalid line continuation\n", -/*050*/ "invalid range\n", -/*051*/ "invalid subscript, use \"[ ]\" operators on major dimensions\n", -/*052*/ "multi-dimensional arrays must be fully initialized\n", -/*053*/ "exceeding maximum number of dimensions\n", -/*054*/ "unmatched closing brace (\"}\")\n", -/*055*/ "start of function body without function header\n", -/*056*/ "arrays, local variables and function arguments cannot be public (variable \"%s\")\n", -/*057*/ "unfinished expression before compiler directive\n", -/*058*/ "duplicate argument; same argument is passed twice\n", -/*059*/ "function argument may not have a default value (variable \"%s\")\n", -/*060*/ "multiple \"#else\" directives between \"#if ... #endif\"\n", -/*061*/ "\"#elseif\" directive follows an \"#else\" directive\n", -/*062*/ "number of operands does not fit the operator\n", -/*063*/ "function result tag of operator \"%s\" must be \"%s\"\n", -/*064*/ "cannot change predefined operators\n", -/*065*/ "function argument may only have a single tag (argument %d)\n", -/*066*/ "function argument may not be a reference argument or an array (argument \"%s\")\n", -/*067*/ "variable cannot be both a reference and an array (variable \"%s\")\n", -/*068*/ "invalid rational number precision in #pragma\n", -/*069*/ "rational number format already defined\n", -/*070*/ "rational number support was not enabled\n", -/*071*/ "user-defined operator must be declared before use (function \"%s\")\n", -/*072*/ "\"sizeof\" operator is invalid on \"function\" symbols\n", -/*073*/ "function argument must be an array (argument \"%s\")\n", -/*074*/ "#define pattern must start with an alphabetic character\n", -/*075*/ "input line too long (after substitutions)\n", -/*076*/ "syntax error in the expression, or invalid function call\n", -/*077*/ "malformed UTF-8 encoding, or corrupted file: %s\n", -/*078*/ "function uses both \"return\" and \"return \"\n", -/*079*/ "inconsistent return types (array & non-array)\n", -/*080*/ "unknown symbol, or not a constant symbol (symbol \"%s\")\n", -/*081*/ "cannot take a tag as a default value for an indexed array parameter (symbol \"%s\")\n", -/*082*/ "user-defined operators and native functions may not have states\n", -/*083*/ "a function or variable may only belong to a single automaton (symbol \"%s\")\n", -/*084*/ "state conflict: one of the states is already assigned to another implementation (symbol \"%s\")\n", -/*085*/ "no states are defined for symbol \"%s\"\n", -/*086*/ "unknown automaton \"%s\"\n", -/*087*/ "unknown state \"%s\" for automaton \"%s\"\n", -/*088*/ "public variables and local variables may not have states (symbol \"%s\")\n", -/*089*/ "state variables may not be initialized (symbol \"%s\")\n", -/*090*/ "public functions may not return arrays (symbol \"%s\")\n", -/*091*/ "ambiguous constant; tag override is required (symbol \"%s\")\n" -#else - "\271pect\235\306k\212:\227\316bu\202fo\217\206\216\012", - "\201l\223\252s\203g\352\315e\234\202(\255\363\201) c\355f\240\344w ea\275 \042c\351e\042\012", - "\233cl\333\237\304\252\344c\337\327\324appe\204 \372\252\343\364o\217\206\236ock\012", - "\366\227 \272\242i\364le\234t\274\012", - "\273\367\242\340\376\265t\314", - "\360a\253gn\235\306 \355\256y\012", - "\353\224\255c\226\242\313\220\326\274\012", - "\360\252\354\202\363\201; \351\375m\235z\210o\012", - "\266\303\335\200(nega\205ve\316z\210\371\255ou\202\304bo\217ds\232", - "\266\273\255\233cl\333\214\012", - "\266out\222d\200\366\314", - "\266\273c\211l\316\242\252\261add\220s\314", - "\221 \212tr\223po\203\202(\221 pu\236\332 \366s\232", - "\266\315e\234t; \242\372s\362t\275\012", - "\042\302a\342t\330c\351\200\360\270\200l\351\202c\351\200\372s\362t\275 \315e\234t\012", - "m\342\205p\352\302a\342t\207\372\042s\362t\275\042\012", - "\217\326\235\277\012", - "\203i\205\211iza\237d\224\252\271ce\274\207\233cl\204\235\335\322", - "\242\252lab\341\347", - "\266\250 nam\200\216\012", - "\250 \211\220ad\223\326\274\347", - "\360l\243u\200(n\201-\354t\232", - "\303a\253gn\234\202\360\222\364\352a\253gn\234t\012", - "\042b\220ak\330\255\042\307t\203ue\330\272ou\202\304\307t\271t\012", - "\273head\357\334ff\210\207from pro\306typ\322", - "\221 \345\275\357\042#if...\042\012", - "\266\275\333ct\264\354t\012", - "\266\375bscrip\202(\242\355\303\255\306\371m\226\223\375bscripts)\347", - "\266\363\201\316\351\375m\235z\210o\012", - "\343\364o\217\206\315e\234\202\242c\344s\235a\202\270\200\212\206\304\361\352(\231\204t\235a\202l\203\200%d\232", - "\217k\221w\336\334\220c\205v\322", - "\303\203\233x ou\202\304bo\217d\207(\327\216\232", - "\303\360\203\233x\235(\327\216\232", - "\312do\310\242\340\376\252\302a\342\202\243u\200(\312%d\232", - "\312typ\200mis\345\275 (\312%d\232", - "e\364t\223\315e\234t\012", - "\266\231r\357(po\253\236\223n\201-\365m\203\224\235\231r\203g\232", - "\271t\241 \275\333c\365\207\331l\203\322", - "\354\202\250 \340\207\221 \335\322", - "dupl\332\224\200\042c\351e\330lab\341 (\243u\200%d\232", - "\266\341lip\222s\316\303\335\200\272\242k\221wn\012", - "\266\343\230\203a\237\304cl\351\207speci\361\210\314", - "\275\333ct\264\354\202\271ce\274\207r\226g\200f\255pack\235\231r\203g\012", - "po\222\214\337p\333me\365\207\324\311c\274\200\211l nam\235p\333me\365\314", - "\306\371m\226\223\273\265t\314", - "\217k\221w\336\303\335\200(\327\216\232", - "\303\335\310d\371\242\345\275\316\255\233\231\203a\237\303\272\306\371sm\211l\012", - "\303\334\234\222\201\207d\371\242\345\275\012", - "\266l\203\200\307t\203ua\214\012", - "\266r\226g\322", - "\266\375bscript\316\251\200\042[ ]\330\353\224\225\207\331\305j\255\334\234\222\201\314", - "m\342\205-\334\234\222\201\337\256y\207\360f\342l\223\203i\205\211iz\274\012", - "\271ce\274\357\305ximum \374\230\264\304\334\234\222\201\314", - "\217\345\275\235c\344s\357b\241c\200(\042}\042\232", - "\231\204\202\304\273bod\223\362\270ou\202\273head\210\012", - "\256ys\316\344c\337\301\310\226\206\273\265t\207c\226\242\313pu\236\332 (\327\216\232", - "\217f\203ish\235\363\331be\370\200\343\364il\264\334\220c\205v\322", - "dupl\332\224\200\265t; sam\200\312\272p\351s\235tw\332\322", - "\273\312\367\242\340\376\252\302a\342\202\243u\200(\327\216\232", - "m\342\205p\352\042#\341se\330\334\220c\205v\310betwe\212 \042#if ... #\212\334f\042\012", - "\042#\341seif\330\334\220c\205\376f\240\344w\207\355\042#\341se\330\334\220c\205v\322", - "\374\230\264\304\353\226d\207do\310\242\361\202\270\200\353\224\225\012", - "\273\220s\342\202\373\304\353\224\225\227 \360\216\012", - "c\226\242\275\226g\200\311\326\235\353\224\225\314", - "\273\312\367\201l\223\340\376\252s\203g\352\373(\312%d\232", - "\273\312\367\242\313\252\220f\210\212c\200\312\255\355\303(\312\216\232", - "\327c\226\242\313bo\270 \252\220f\210\212c\200\226\206\355\303(\327\216\232", - "\266\241\214\337\374\230\264\311ci\222\331\372#p\241g\305\012", - "\241\214\337\374\230\264\370\305\202\211\220ad\223\326\274\012", - "\241\214\337\374\230\264\375pp\225\202wa\207\242\212\254\274\012", - "\251\210-\326\235\353\224\255\360\233cl\204\235be\370\200\251\200(\366\227\232", - "\042\335e\267\330\353\224\255\272\266\331\042\366\330\250\314", - "\273\312\360\355\303(\312\216\232", - "#\326\200p\224\365\336\324\231\204\202\362\270 \355\211p\340be\205c \275\333c\365\012", - "\203pu\202l\203\200\306\371l\201\260(aft\264\375bs\205tu\214s\232", - "\246n\325x \210r\255\372\270\200\363\201\316\255\266\273c\211l\012", - "m\211\370m\235UTF-8 \212\343d\203g\316\255c\225rupt\235\361le: \213\012", - "\273\251\310bo\270 \042\220turn\330\226\206\042\220tur\336<\243ue>\042\012", - "\203\307\222\231\212\202\220tur\336typ\310(\303& n\201-\256y\232", - "\217k\221w\336\250\316\255\242\252\354\202\250 \323", - "c\226\242\325k\200\252\373a\207\252\302a\342\202\243u\200f\255\355\203\233x\235\303p\333met\264\323", - "\251\210-\326\235\353\224\225\207\226\206na\205\376\366\207\367\242\340\376\315e\314", - "\252\273\255\327\367\201l\223b\341\201\260\306 \252s\203g\352au\306\345\331\323", - "\315\200\307fl\332t: \201\200\304\270\200\315\310\272\211\220ad\223a\253gn\235\306 a\221\270\264i\364le\234\325\237\323", - "\221 \315\310\204\200\326\235f\255\277\012", - "\217k\221w\336au\306\345\201\321", - "\217k\221w\336\315\200\216 f\255au\306\345\201\321", - "pu\236\332 \301\310\226\206\344c\337\301\310\367\242\340\376\315\310\323", - "\315\200\301\310\367\242\313\203i\205\211iz\235\323", - "pu\236\332 \366\207\367\242\220tur\336\256y\207\323", - "a\230i\262ou\207\354t; \373ov\210rid\200\272\220qui\220\206\323" -#endif - }; - -static char *fatalmsg[] = { -#ifdef SCPACK -/*100*/ "cannot read from file: \"%s\"\n", -/*101*/ "cannot write to file: \"%s\"\n", -/*102*/ "table overflow: \"%s\"\n", - /* table can be: loop table - * literal table - * staging buffer - * option table (response file) - * peephole optimizer table - */ -/*103*/ "insufficient memory\n", -/*104*/ "invalid assembler instruction \"%s\"\n", -/*105*/ "numeric overflow, exceeding capacity\n", -/*106*/ "compiled script exceeds the maximum memory size (%ld bytes)\n", -/*107*/ "too many error messages on one line\n", -/*108*/ "codepage mapping file not found\n", -/*109*/ "invalid path: \"%s\"\n", -/*110*/ "assertion failed: %s\n", -/*111*/ "user error: %s\n", -#else - "c\226\242\220a\206from \361le\347", - "c\226\242writ\200\306 \361le\347", - "t\254\200ov\210f\344w\347", - "\203\375ff\332i\212\202mem\225y\012", - "\266\351se\230l\264\203\231ruc\214\321", - "\374m\210\332 ov\210f\344w\316\271ce\274\357capacity\012", - "\343\364il\235scrip\202\271ce\274\207\270\200\305ximum mem\225\223\335\200(%l\206bytes\232", - "\306\371m\226\223\210r\255messag\310\331\201\200l\203\322", - "\343\233pag\200\305pp\357\361\352\242fo\217d\012", - "\266p\224h\347", - "\351s\210\237fail\274: \213\012", - "\251\264\210r\225: \213\012" -#endif - }; - -static char *warnmsg[] = { -#ifdef SCPACK -/*200*/ "symbol \"%s\" is truncated to %d characters\n", -/*201*/ "redefinition of constant/macro (symbol \"%s\")\n", -/*202*/ "number of arguments does not match definition\n", -/*203*/ "symbol is never used: \"%s\"\n", -/*204*/ "symbol is assigned a value that is never used: \"%s\"\n", -/*205*/ "redundant code: constant expression is zero\n", -/*206*/ "redundant test: constant expression is non-zero\n", -/*207*/ "unknown #pragma\n", -/*208*/ "function with tag result used before definition, forcing reparse\n", -/*209*/ "function \"%s\" should return a value\n", -/*210*/ "possible use of symbol before initialization: \"%s\"\n", -/*211*/ "possibly unintended assignment\n", -/*212*/ "possibly unintended bitwise operation\n", -/*213*/ "tag mismatch\n", -/*214*/ "possibly a \"const\" array argument was intended: \"%s\"\n", -/*215*/ "expression has no effect\n", -/*216*/ "nested comment\n", -/*217*/ "loose indentation\n", -/*218*/ "old style prototypes used with optional semicolumns\n", -/*219*/ "local variable \"%s\" shadows a variable at a preceding level\n", -/*220*/ "expression with tag override must appear between parentheses\n", -/*221*/ "label name \"%s\" shadows tag name\n", -/*222*/ "number of digits exceeds rational number precision\n", -/*223*/ "redundant \"sizeof\": argument size is always 1 (symbol \"%s\")\n", -/*224*/ "indeterminate array size in \"sizeof\" expression (symbol \"%s\")\n", -/*225*/ "unreachable code\n", -/*226*/ "a variable is assigned to itself (symbol \"%s\")\n", -/*227*/ "more initiallers than enum fields\n", -/*228*/ "length of initialler exceeds size of the enum field\n", -/*229*/ "index tag mismatch (symbol \"%s\")\n", -/*230*/ "no implementation for state \"%s\" in function \"%s\", no fall-back\n", -/*231*/ "state specification on forward declaration is ignored\n", -/*232*/ "output file is written, but with compact encoding disabled\n", -/*233*/ "state variable \"%s\" shadows a global variable\n", -/*234*/ "function is deprecated (symbol \"%s\") %s\n", -/*235*/ "public function lacks forward declaration (symbol \"%s\")\n", -/*236*/ "unknown parameter in substitution (incorrect #define pattern)\n" -#else - "\277 \272tr\244\224\235\306 %\206\275\333c\365\314", - "\220\326i\237\304\354t/\305cr\371\323", - "\374\230\264\304\265t\207do\310\242\345\275 \326i\214\012", - "\250 \272nev\264\251\274\347", - "\250 \272a\253gn\235\252\243u\200\270a\202\272nev\264\251\274\347", - "\220d\217d\226\202\343\233: \354\202\363\331\272z\210o\012", - "\220d\217d\226\202te\231: \354\202\363\331\272n\201-z\210o\012", - "\217k\221w\336#p\241g\305\012", - "\273\362\270 \373\220s\342\202\251\235be\370\200\326i\214\316\370c\357\220p\204s\322", - "\366\227 sho\342\206\220tur\336\252\243u\322", - "po\253\236\200\251\200\304\250 be\370\200\203i\205\211iza\214\347", - "po\253\236\223\217\203t\212\233\206a\253gn\234t\012", - "po\253\236\223\217\203t\212\233\206bit\362s\200\353a\214\012", - "\373mis\345\275\012", - "po\253\236\223\252\042\346\330\303\312wa\207\203t\212\233d\347", - "\363\331\340\207\221 effect\012", - "ne\231\235\343m\234t\012", - "\344os\200\203d\212\325\214\012", - "\240\206\231y\352pro\306typ\310\251\235\362\270 \350\214\337sem\332\240umn\314", - "\344c\337\327\216 s\340dow\207\252\327a\202\252\311c\274\357lev\341\012", - "\363\331\362\270 \373ov\210rid\200\324appe\204 betwe\212 p\204\212\270ese\314", - "lab\341 nam\200\216 s\340dow\207\373nam\322", - "\374\230\264\304\334git\207\271ce\274\207\241\214\337\374\230\264\311ci\222\201\012", - "\220d\217d\226\202\042\335e\267\042: \312\335\200\272\211way\2071 \323", - "\203\233\365m\203\224\200\303\335\200\372\042\335e\267\330\363\331\323", - "\217\220a\275\254\200\343\233\012", - "\252\327\272a\253gn\235\306 its\341f \323", - "m\225\200\203i\205\211l\210\207\270\355\212um \361\341d\314", - "l\212g\270 \304\203i\205\211l\264\271ce\274\207\335\200\304\270\200\212um \361\341d\012", - "\203\233x \373mis\345\275 \323", - "\221 i\364le\234\325\237f\255\315\200\216 \372\366\227\316\221 f\211l-back\012", - "\315\200specif\332a\237\331\370w\204\206\233cl\333\237\272ig\221\220d\012", - "outpu\202\361\352\272writt\212\316bu\202\362\270 \343\364ac\202\212\343d\357\334s\254\274\012", - "\315\200\327\216 s\340dow\207\252g\344b\337\301\322", - "\273\272\233\311c\224\235\317) \213\012", - "pu\236\332 \273lack\207\370w\204\206\233cl\333\237\323", - "\217k\221w\336p\333met\264\372\375bs\205tu\237(\203c\225\220c\202#\326\200p\224\365n\232" -#endif - }; +/* Pawn compiler - Error message strings (plain and compressed formats) + * + * Copyright (c) ITB CompuPhase, 2000-2006 + * + * This software is provided "as-is", without any express or implied warranty. + * In no event will the authors be held liable for any damages arising from + * the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software in + * a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + * Version: $Id: sc5.sch 3633 2006-08-11 16:20:18Z thiadmer $ + */ + +SC_FUNC int strexpand(char *dest, unsigned char *source, int maxlen, unsigned char pairtable[128][2]); + +#define SCPACK_TABLE errstr_table +/*-*SCPACK start of pair table, do not change or remove this line */ +unsigned char errstr_table[][2] = { + {101,32}, {111,110}, {116,32}, {105,110}, {97,114}, {116,105}, {100,32}, {115,32}, {101,114}, {97,108}, {101,110}, {37,115}, {133,129}, {34,139}, {141,34}, {117,110}, + {114,101}, {110,111}, {115,105}, {121,32}, {97,116}, {111,114}, {97,110}, {32,142}, {109,98}, {115,116}, {41,10}, {100,101}, {109,138}, {101,134}, {98,108}, {140,32}, + {111,108}, {114,97}, {145,130}, {118,137}, {143,99}, {102,164}, {115,121}, {166,152}, {167,160}, {117,115}, {97,32}, {115,146}, {97,158}, {149,32}, {132,161}, {105,134}, + {103,32}, {163,175}, {103,117}, {178,156}, {136,32}, {132,179}, {131,177}, {111,102}, {116,104}, {101,120}, {105,135}, {165,159}, {101,100}, {99,104}, {118,132}, {168,151}, + {105,172}, {190,192}, {155,102}, {174,147}, {183,32}, {109,97}, {116,111}, {99,129}, {101,135}, {112,144}, {181,130}, {98,128}, {115,10}, {153,148}, {44,32}, {40,191}, + {169,130}, {151,10}, {101,10}, {207,154}, {109,208}, {116,97}, {194,131}, {193,128}, {34,32}, {129,32}, {105,99}, {132,97}, {100,105}, {146,122}, {110,32}, {137,32}, + {104,97}, {101,108}, {117,108}, {99,111}, {108,111}, {109,148}, {199,153}, {58,209}, {111,112}, {97,115}, {108,128}, {232,136}, {230,150}, {150,32}, {201,171}, {131,176}, + {212,203}, {102,105}, {119,105}, {185,238}, {109,112}, {116,136}, {165,140}, {197,147}, {102,149}, {111,32}, {131,32}, {213,176}, {110,117}, {115,117}, {118,128} +}; +/*-*SCPACK end of pair table, do not change or remove this line */ + +static char *errmsg[] = { +#ifdef SCPACK +/*001*/ "expected token: \"%s\", but found \"%s\"\n", +/*002*/ "only a single statement (or expression) can follow each \"case\"\n", +/*003*/ "declaration of a local variable must appear in a compound block\n", +/*004*/ "function \"%s\" is not implemented\n", +/*005*/ "function may not have arguments\n", +/*006*/ "must be assigned to an array\n", +/*007*/ "operator cannot be redefined\n", +/*008*/ "must be a constant expression; assumed zero\n", +/*009*/ "invalid array size (negative, zero or out of bounds)\n", +/*010*/ "invalid function or declaration\n", +/*011*/ "invalid outside functions\n", +/*012*/ "invalid function call, not a valid address\n", +/*013*/ "no entry point (no public functions)\n", +/*014*/ "invalid statement; not in switch\n", +/*015*/ "\"default\" case must be the last case in switch statement\n", +/*016*/ "multiple defaults in \"switch\"\n", +/*017*/ "undefined symbol \"%s\"\n", +/*018*/ "initialization data exceeds declared size\n", +/*019*/ "not a label: \"%s\"\n", +/*020*/ "invalid symbol name \"%s\"\n", +/*021*/ "symbol already defined: \"%s\"\n", +/*022*/ "must be lvalue (non-constant)\n", +/*023*/ "array assignment must be simple assignment\n", +/*024*/ "\"break\" or \"continue\" is out of context\n", +/*025*/ "function heading differs from prototype\n", +/*026*/ "no matching \"#if...\"\n", +/*027*/ "invalid character constant\n", +/*028*/ "invalid subscript (not an array or too many subscripts): \"%s\"\n", +/*029*/ "invalid expression, assumed zero\n", +/*030*/ "compound statement not closed at the end of file (started at line %d)\n", +/*031*/ "unknown directive\n", +/*032*/ "array index out of bounds (variable \"%s\")\n", +/*033*/ "array must be indexed (variable \"%s\")\n", +/*034*/ "argument does not have a default value (argument %d)\n", +/*035*/ "argument type mismatch (argument %d)\n", +/*036*/ "empty statement\n", +/*037*/ "invalid string (possibly non-terminated string)\n", +/*038*/ "extra characters on line\n", +/*039*/ "constant symbol has no size\n", +/*040*/ "duplicate \"case\" label (value %d)\n", +/*041*/ "invalid ellipsis, array size is not known\n", +/*042*/ "invalid combination of class specifiers\n", +/*043*/ "character constant exceeds range for packed string\n", +/*044*/ "positional parameters must precede all named parameters\n", +/*045*/ "too many function arguments\n", +/*046*/ "unknown array size (variable \"%s\")\n", +/*047*/ "array sizes do not match, or destination array is too small\n", +/*048*/ "array dimensions do not match\n", +/*049*/ "invalid line continuation\n", +/*050*/ "invalid range\n", +/*051*/ "invalid subscript, use \"[ ]\" operators on major dimensions\n", +/*052*/ "multi-dimensional arrays must be fully initialized\n", +/*053*/ "exceeding maximum number of dimensions\n", +/*054*/ "unmatched closing brace (\"}\")\n", +/*055*/ "start of function body without function header\n", +/*056*/ "arrays, local variables and function arguments cannot be public (variable \"%s\")\n", +/*057*/ "unfinished expression before compiler directive\n", +/*058*/ "duplicate argument; same argument is passed twice\n", +/*059*/ "function argument may not have a default value (variable \"%s\")\n", +/*060*/ "multiple \"#else\" directives between \"#if ... #endif\"\n", +/*061*/ "\"#elseif\" directive follows an \"#else\" directive\n", +/*062*/ "number of operands does not fit the operator\n", +/*063*/ "function result tag of operator \"%s\" must be \"%s\"\n", +/*064*/ "cannot change predefined operators\n", +/*065*/ "function argument may only have a single tag (argument %d)\n", +/*066*/ "function argument may not be a reference argument or an array (argument \"%s\")\n", +/*067*/ "variable cannot be both a reference and an array (variable \"%s\")\n", +/*068*/ "invalid rational number precision in #pragma\n", +/*069*/ "rational number format already defined\n", +/*070*/ "rational number support was not enabled\n", +/*071*/ "user-defined operator must be declared before use (function \"%s\")\n", +/*072*/ "\"sizeof\" operator is invalid on \"function\" symbols\n", +/*073*/ "function argument must be an array (argument \"%s\")\n", +/*074*/ "#define pattern must start with an alphabetic character\n", +/*075*/ "input line too long (after substitutions)\n", +/*076*/ "syntax error in the expression, or invalid function call\n", +/*077*/ "malformed UTF-8 encoding, or corrupted file: %s\n", +/*078*/ "function uses both \"return\" and \"return \"\n", +/*079*/ "inconsistent return types (array & non-array)\n", +/*080*/ "unknown symbol, or not a constant symbol (symbol \"%s\")\n", +/*081*/ "cannot take a tag as a default value for an indexed array parameter (symbol \"%s\")\n", +/*082*/ "user-defined operators and native functions may not have states\n", +/*083*/ "a function or variable may only belong to a single automaton (symbol \"%s\")\n", +/*084*/ "state conflict: one of the states is already assigned to another implementation (symbol \"%s\")\n", +/*085*/ "no states are defined for symbol \"%s\"\n", +/*086*/ "unknown automaton \"%s\"\n", +/*087*/ "unknown state \"%s\" for automaton \"%s\"\n", +/*088*/ "public variables and local variables may not have states (symbol \"%s\")\n", +/*089*/ "state variables may not be initialized (symbol \"%s\")\n", +/*090*/ "public functions may not return arrays (symbol \"%s\")\n", +/*091*/ "ambiguous constant; tag override is required (symbol \"%s\")\n" +#else + "\271pect\235\306k\212:\227\316bu\202fo\217\206\216\012", + "\201l\223\252s\203g\352\315e\234\202(\255\363\201) c\355f\240\344w ea\275 \042c\351e\042\012", + "\233cl\333\237\304\252\344c\337\327\324appe\204 \372\252\343\364o\217\206\236ock\012", + "\366\227 \272\242i\364le\234t\274\012", + "\273\367\242\340\376\265t\314", + "\360a\253gn\235\306 \355\256y\012", + "\353\224\255c\226\242\313\220\326\274\012", + "\360\252\354\202\363\201; \351\375m\235z\210o\012", + "\266\303\335\200(nega\205ve\316z\210\371\255ou\202\304bo\217ds\232", + "\266\273\255\233cl\333\214\012", + "\266out\222d\200\366\314", + "\266\273c\211l\316\242\252\261add\220s\314", + "\221 \212tr\223po\203\202(\221 pu\236\332 \366s\232", + "\266\315e\234t; \242\372s\362t\275\012", + "\042\302a\342t\330c\351\200\360\270\200l\351\202c\351\200\372s\362t\275 \315e\234t\012", + "m\342\205p\352\302a\342t\207\372\042s\362t\275\042\012", + "\217\326\235\277\012", + "\203i\205\211iza\237d\224\252\271ce\274\207\233cl\204\235\335\322", + "\242\252lab\341\347", + "\266\250 nam\200\216\012", + "\250 \211\220ad\223\326\274\347", + "\360l\243u\200(n\201-\354t\232", + "\303a\253gn\234\202\360\222\364\352a\253gn\234t\012", + "\042b\220ak\330\255\042\307t\203ue\330\272ou\202\304\307t\271t\012", + "\273head\357\334ff\210\207from pro\306typ\322", + "\221 \345\275\357\042#if...\042\012", + "\266\275\333ct\264\354t\012", + "\266\375bscrip\202(\242\355\303\255\306\371m\226\223\375bscripts)\347", + "\266\363\201\316\351\375m\235z\210o\012", + "\343\364o\217\206\315e\234\202\242c\344s\235a\202\270\200\212\206\304\361\352(\231\204t\235a\202l\203\200%d\232", + "\217k\221w\336\334\220c\205v\322", + "\303\203\233x ou\202\304bo\217d\207(\327\216\232", + "\303\360\203\233x\235(\327\216\232", + "\312do\310\242\340\376\252\302a\342\202\243u\200(\312%d\232", + "\312typ\200mis\345\275 (\312%d\232", + "e\364t\223\315e\234t\012", + "\266\231r\357(po\253\236\223n\201-\365m\203\224\235\231r\203g\232", + "\271t\241 \275\333c\365\207\331l\203\322", + "\354\202\250 \340\207\221 \335\322", + "dupl\332\224\200\042c\351e\330lab\341 (\243u\200%d\232", + "\266\341lip\222s\316\303\335\200\272\242k\221wn\012", + "\266\343\230\203a\237\304cl\351\207speci\361\210\314", + "\275\333ct\264\354\202\271ce\274\207r\226g\200f\255pack\235\231r\203g\012", + "po\222\214\337p\333me\365\207\324\311c\274\200\211l nam\235p\333me\365\314", + "\306\371m\226\223\273\265t\314", + "\217k\221w\336\303\335\200(\327\216\232", + "\303\335\310d\371\242\345\275\316\255\233\231\203a\237\303\272\306\371sm\211l\012", + "\303\334\234\222\201\207d\371\242\345\275\012", + "\266l\203\200\307t\203ua\214\012", + "\266r\226g\322", + "\266\375bscript\316\251\200\042[ ]\330\353\224\225\207\331\305j\255\334\234\222\201\314", + "m\342\205-\334\234\222\201\337\256y\207\360f\342l\223\203i\205\211iz\274\012", + "\271ce\274\357\305ximum \374\230\264\304\334\234\222\201\314", + "\217\345\275\235c\344s\357b\241c\200(\042}\042\232", + "\231\204\202\304\273bod\223\362\270ou\202\273head\210\012", + "\256ys\316\344c\337\301\310\226\206\273\265t\207c\226\242\313pu\236\332 (\327\216\232", + "\217f\203ish\235\363\331be\370\200\343\364il\264\334\220c\205v\322", + "dupl\332\224\200\265t; sam\200\312\272p\351s\235tw\332\322", + "\273\312\367\242\340\376\252\302a\342\202\243u\200(\327\216\232", + "m\342\205p\352\042#\341se\330\334\220c\205v\310betwe\212 \042#if ... #\212\334f\042\012", + "\042#\341seif\330\334\220c\205\376f\240\344w\207\355\042#\341se\330\334\220c\205v\322", + "\374\230\264\304\353\226d\207do\310\242\361\202\270\200\353\224\225\012", + "\273\220s\342\202\373\304\353\224\225\227 \360\216\012", + "c\226\242\275\226g\200\311\326\235\353\224\225\314", + "\273\312\367\201l\223\340\376\252s\203g\352\373(\312%d\232", + "\273\312\367\242\313\252\220f\210\212c\200\312\255\355\303(\312\216\232", + "\327c\226\242\313bo\270 \252\220f\210\212c\200\226\206\355\303(\327\216\232", + "\266\241\214\337\374\230\264\311ci\222\331\372#p\241g\305\012", + "\241\214\337\374\230\264\370\305\202\211\220ad\223\326\274\012", + "\241\214\337\374\230\264\375pp\225\202wa\207\242\212\254\274\012", + "\251\210-\326\235\353\224\255\360\233cl\204\235be\370\200\251\200(\366\227\232", + "\042\335e\267\330\353\224\255\272\266\331\042\366\330\250\314", + "\273\312\360\355\303(\312\216\232", + "#\326\200p\224\365\336\324\231\204\202\362\270 \355\211p\340be\205c \275\333c\365\012", + "\203pu\202l\203\200\306\371l\201\260(aft\264\375bs\205tu\214s\232", + "\246n\325x \210r\255\372\270\200\363\201\316\255\266\273c\211l\012", + "m\211\370m\235UTF-8 \212\343d\203g\316\255c\225rupt\235\361le: \213\012", + "\273\251\310bo\270 \042\220turn\330\226\206\042\220tur\336<\243ue>\042\012", + "\203\307\222\231\212\202\220tur\336typ\310(\303& n\201-\256y\232", + "\217k\221w\336\250\316\255\242\252\354\202\250 \323", + "c\226\242\325k\200\252\373a\207\252\302a\342\202\243u\200f\255\355\203\233x\235\303p\333met\264\323", + "\251\210-\326\235\353\224\225\207\226\206na\205\376\366\207\367\242\340\376\315e\314", + "\252\273\255\327\367\201l\223b\341\201\260\306 \252s\203g\352au\306\345\331\323", + "\315\200\307fl\332t: \201\200\304\270\200\315\310\272\211\220ad\223a\253gn\235\306 a\221\270\264i\364le\234\325\237\323", + "\221 \315\310\204\200\326\235f\255\277\012", + "\217k\221w\336au\306\345\201\321", + "\217k\221w\336\315\200\216 f\255au\306\345\201\321", + "pu\236\332 \301\310\226\206\344c\337\301\310\367\242\340\376\315\310\323", + "\315\200\301\310\367\242\313\203i\205\211iz\235\323", + "pu\236\332 \366\207\367\242\220tur\336\256y\207\323", + "a\230i\262ou\207\354t; \373ov\210rid\200\272\220qui\220\206\323" +#endif + }; + +static char *fatalmsg[] = { +#ifdef SCPACK +/*100*/ "cannot read from file: \"%s\"\n", +/*101*/ "cannot write to file: \"%s\"\n", +/*102*/ "table overflow: \"%s\"\n", + /* table can be: loop table + * literal table + * staging buffer + * option table (response file) + * peephole optimizer table + */ +/*103*/ "insufficient memory\n", +/*104*/ "invalid assembler instruction \"%s\"\n", +/*105*/ "numeric overflow, exceeding capacity\n", +/*106*/ "compiled script exceeds the maximum memory size (%ld bytes)\n", +/*107*/ "too many error messages on one line\n", +/*108*/ "codepage mapping file not found\n", +/*109*/ "invalid path: \"%s\"\n", +/*110*/ "assertion failed: %s\n", +/*111*/ "user error: %s\n", +#else + "c\226\242\220a\206from \361le\347", + "c\226\242writ\200\306 \361le\347", + "t\254\200ov\210f\344w\347", + "\203\375ff\332i\212\202mem\225y\012", + "\266\351se\230l\264\203\231ruc\214\321", + "\374m\210\332 ov\210f\344w\316\271ce\274\357capacity\012", + "\343\364il\235scrip\202\271ce\274\207\270\200\305ximum mem\225\223\335\200(%l\206bytes\232", + "\306\371m\226\223\210r\255messag\310\331\201\200l\203\322", + "\343\233pag\200\305pp\357\361\352\242fo\217d\012", + "\266p\224h\347", + "\351s\210\237fail\274: \213\012", + "\251\264\210r\225: \213\012" +#endif + }; + +static char *warnmsg[] = { +#ifdef SCPACK +/*200*/ "symbol \"%s\" is truncated to %d characters\n", +/*201*/ "redefinition of constant/macro (symbol \"%s\")\n", +/*202*/ "number of arguments does not match definition\n", +/*203*/ "symbol is never used: \"%s\"\n", +/*204*/ "symbol is assigned a value that is never used: \"%s\"\n", +/*205*/ "redundant code: constant expression is zero\n", +/*206*/ "redundant test: constant expression is non-zero\n", +/*207*/ "unknown #pragma\n", +/*208*/ "function with tag result used before definition, forcing reparse\n", +/*209*/ "function \"%s\" should return a value\n", +/*210*/ "possible use of symbol before initialization: \"%s\"\n", +/*211*/ "possibly unintended assignment\n", +/*212*/ "possibly unintended bitwise operation\n", +/*213*/ "tag mismatch\n", +/*214*/ "possibly a \"const\" array argument was intended: \"%s\"\n", +/*215*/ "expression has no effect\n", +/*216*/ "nested comment\n", +/*217*/ "loose indentation\n", +/*218*/ "old style prototypes used with optional semicolumns\n", +/*219*/ "local variable \"%s\" shadows a variable at a preceding level\n", +/*220*/ "expression with tag override must appear between parentheses\n", +/*221*/ "label name \"%s\" shadows tag name\n", +/*222*/ "number of digits exceeds rational number precision\n", +/*223*/ "redundant \"sizeof\": argument size is always 1 (symbol \"%s\")\n", +/*224*/ "indeterminate array size in \"sizeof\" expression (symbol \"%s\")\n", +/*225*/ "unreachable code\n", +/*226*/ "a variable is assigned to itself (symbol \"%s\")\n", +/*227*/ "more initiallers than enum fields\n", +/*228*/ "length of initialler exceeds size of the enum field\n", +/*229*/ "index tag mismatch (symbol \"%s\")\n", +/*230*/ "no implementation for state \"%s\" in function \"%s\", no fall-back\n", +/*231*/ "state specification on forward declaration is ignored\n", +/*232*/ "output file is written, but with compact encoding disabled\n", +/*233*/ "state variable \"%s\" shadows a global variable\n", +/*234*/ "function is deprecated (symbol \"%s\") %s\n", +/*235*/ "public function lacks forward declaration (symbol \"%s\")\n", +/*236*/ "unknown parameter in substitution (incorrect #define pattern)\n" +#else + "\277 \272tr\244\224\235\306 %\206\275\333c\365\314", + "\220\326i\237\304\354t/\305cr\371\323", + "\374\230\264\304\265t\207do\310\242\345\275 \326i\214\012", + "\250 \272nev\264\251\274\347", + "\250 \272a\253gn\235\252\243u\200\270a\202\272nev\264\251\274\347", + "\220d\217d\226\202\343\233: \354\202\363\331\272z\210o\012", + "\220d\217d\226\202te\231: \354\202\363\331\272n\201-z\210o\012", + "\217k\221w\336#p\241g\305\012", + "\273\362\270 \373\220s\342\202\251\235be\370\200\326i\214\316\370c\357\220p\204s\322", + "\366\227 sho\342\206\220tur\336\252\243u\322", + "po\253\236\200\251\200\304\250 be\370\200\203i\205\211iza\214\347", + "po\253\236\223\217\203t\212\233\206a\253gn\234t\012", + "po\253\236\223\217\203t\212\233\206bit\362s\200\353a\214\012", + "\373mis\345\275\012", + "po\253\236\223\252\042\346\330\303\312wa\207\203t\212\233d\347", + "\363\331\340\207\221 effect\012", + "ne\231\235\343m\234t\012", + "\344os\200\203d\212\325\214\012", + "\240\206\231y\352pro\306typ\310\251\235\362\270 \350\214\337sem\332\240umn\314", + "\344c\337\327\216 s\340dow\207\252\327a\202\252\311c\274\357lev\341\012", + "\363\331\362\270 \373ov\210rid\200\324appe\204 betwe\212 p\204\212\270ese\314", + "lab\341 nam\200\216 s\340dow\207\373nam\322", + "\374\230\264\304\334git\207\271ce\274\207\241\214\337\374\230\264\311ci\222\201\012", + "\220d\217d\226\202\042\335e\267\042: \312\335\200\272\211way\2071 \323", + "\203\233\365m\203\224\200\303\335\200\372\042\335e\267\330\363\331\323", + "\217\220a\275\254\200\343\233\012", + "\252\327\272a\253gn\235\306 its\341f \323", + "m\225\200\203i\205\211l\210\207\270\355\212um \361\341d\314", + "l\212g\270 \304\203i\205\211l\264\271ce\274\207\335\200\304\270\200\212um \361\341d\012", + "\203\233x \373mis\345\275 \323", + "\221 i\364le\234\325\237f\255\315\200\216 \372\366\227\316\221 f\211l-back\012", + "\315\200specif\332a\237\331\370w\204\206\233cl\333\237\272ig\221\220d\012", + "outpu\202\361\352\272writt\212\316bu\202\362\270 \343\364ac\202\212\343d\357\334s\254\274\012", + "\315\200\327\216 s\340dow\207\252g\344b\337\301\322", + "\273\272\233\311c\224\235\317) \213\012", + "pu\236\332 \273lack\207\370w\204\206\233cl\333\237\323", + "\217k\221w\336p\333met\264\372\375bs\205tu\237(\203c\225\220c\202#\326\200p\224\365n\232" +#endif + }; diff --git a/source/compiler/sc7.scp b/source/compiler/sc7.scp index 0dd4224..76180f1 100644 --- a/source/compiler/sc7.scp +++ b/source/compiler/sc7.scp @@ -1,2023 +1,2023 @@ -/* Pawn compiler - Peephole optimizer "sequences" strings (plain - * and compressed formats) - * - * Copyright (c) ITB CompuPhase, 2000-2006 - * - * This software is provided "as-is", without any express or implied warranty. - * In no event will the authors be held liable for any damages arising from - * the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software in - * a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - * - * Version: $Id: sc7.sch 3662 2006-11-07 08:44:33Z thiadmer $ - */ - -SC_FUNC int strexpand(char *dest, unsigned char *source, int maxlen, unsigned char pairtable[128][2]); - -#define SCPACK_TERMINATOR , /* end each section with a comma */ - -#define SCPACK_TABLE sequences_table -/*-*SCPACK start of pair table, do not change or remove this line */ -unsigned char sequences_table[][2] = { - {49,33}, {37,128}, {32,129}, {32,37}, {114,105}, {112,132}, {46,133}, {97,100}, {46,97}, {136,108}, {137,116}, {115,104}, {111,135}, {117,139}, {112,141}, {108,140}, - {131,50}, {144,33}, {46,115}, {59,36}, {138,33}, {134,130}, {143,146}, {115,116}, {134,145}, {114,33}, {110,151}, {111,154}, {99,155}, {112,148}, {135,100}, {134,33}, - {97,153}, {112,160}, {147,161}, {111,157}, {112,163}, {46,99}, {138,130}, {142,159}, {131,51}, {150,152}, {112,33}, {120,170}, {101,171}, {147,172}, {168,33}, {162,142}, - {101,113}, {110,100}, {122,101}, {178,114}, {149,167}, {158,114}, {33,164}, {131,49}, {103,33}, {158,33}, {104,184}, {99,186}, {120,187}, {98,111}, {118,101}, {111,190}, - {109,191}, {130,173}, {131,52}, {115,103}, {115,108}, {138,145}, {180,169}, {192,148}, {108,165}, {166,169}, {143,149}, {115,174}, {117,177}, {204,203}, {139,200}, {189,205}, - {105,100}, {208,120}, {46,135}, {176,33}, {106,179}, {210,114}, {206,134}, {156,149}, {142,165}, {183,145}, {150,149}, {143,152}, {194,33}, {130,175}, {97,177}, {179,111}, - {212,130}, {182,185}, {143,46}, {183,144}, {156,152}, {145,175}, {114,101}, {230,102}, {196,101}, {108,231}, {232,115}, {234,115}, {195,114}, {236,116}, {142,148}, {105,33}, - {156,166}, {176,130}, {214,32}, {242,50}, {156,198}, {181,198}, {143,197}, {181,201}, {108,209}, {46,98}, {243,225}, {106,110}, {237,153}, {223,159}, {143,166} -}; -/*-*SCPACK end of pair table, do not change or remove this line */ - -#define seqsize(o,p) (opcodes(o)+opargs(p)) -typedef struct { - char *find; - char *replace; - int savesize; /* number of bytes saved (in bytecode) */ -} SEQUENCE; -static SEQUENCE sequences_cmp[] = { - /* A very common sequence in four varieties - * load.s.pri n1 load.s.pri n2 - * push.pri load.s.alt n1 - * load.s.pri n2 - - * pop.alt - - * -------------------------------------- - * load.pri n1 load.s.pri n2 - * push.pri load.alt n1 - * load.s.pri n2 - - * pop.alt - - * -------------------------------------- - * load.s.pri n1 load.pri n2 - * push.pri load.s.alt n1 - * load.pri n2 - - * pop.alt - - * -------------------------------------- - * load.pri n1 load.pri n2 - * push.pri load.alt n1 - * load.pri n2 - - * pop.alt - - */ - { - #ifdef SCPACK - "load.s.pri %1!push.pri!load.s.pri %2!pop.alt!", - "load.s.pri %2!load.s.alt %1!", - #else - "\226\306\244", - "\251\226\246", - #endif - seqsize(4,2) - seqsize(2,2) - }, - { - #ifdef SCPACK - "load.pri %1!push.pri!load.s.pri %2!pop.alt!", - "load.s.pri %2!load.alt %1!", - #else - "\217\306\244", - "\251\376", - #endif - seqsize(4,2) - seqsize(2,2) - }, - { - #ifdef SCPACK - "load.s.pri %1!push.pri!load.pri %2!pop.alt!", - "load.pri %2!load.s.alt %1!", - #else - "\226\264\333\244", - "\333\226\246", - #endif - seqsize(4,2) - seqsize(2,2) - }, - { - #ifdef SCPACK - "load.pri %1!push.pri!load.pri %2!pop.alt!", - "load.pri %2!load.alt %1!", - #else - "\217\264\333\244", - "\333\376", - #endif - seqsize(4,2) - seqsize(2,2) - }, - /* (#1#) The above also occurs with "addr.pri" (array - * indexing) as the first line; so that adds 2 cases. - */ - { - #ifdef SCPACK - "addr.pri %1!push.pri!load.s.pri %2!pop.alt!", - "addr.alt %1!load.s.pri %2!", - #else - "\365\244", - "\367", - #endif - seqsize(4,2) - seqsize(2,2) - }, - { - #ifdef SCPACK - "addr.pri %1!push.pri!load.pri %2!pop.alt!", - "addr.alt %1!load.pri %2!", - #else - "\265\264\333\244", - "\265\246\333", - #endif - seqsize(4,2) - seqsize(2,2) - }, - /* And the same sequence with const.pri as either the first - * or the second load instruction: four more cases. - */ - { - #ifdef SCPACK - "const.pri %1!push.pri!load.s.pri %2!pop.alt!", - "load.s.pri %2!const.alt %1!", - #else - "\364\244", - "\251\360", - #endif - seqsize(4,2) - seqsize(2,2) - }, - { - #ifdef SCPACK - "const.pri %1!push.pri!load.pri %2!pop.alt!", - "load.pri %2!const.alt %1!", - #else - "\234\264\333\244", - "\333\360", - #endif - seqsize(4,2) - seqsize(2,2) - }, - { - #ifdef SCPACK - "load.s.pri %1!push.pri!const.pri %2!pop.alt!", - "const.pri %2!load.s.alt %1!", - #else - "\226\264\344\244", - "\344\226\246", - #endif - seqsize(4,2) - seqsize(2,2) - }, - { - #ifdef SCPACK - "load.pri %1!push.pri!const.pri %2!pop.alt!", - "const.pri %2!load.alt %1!", - #else - "\217\264\344\244", - "\344\376", - #endif - seqsize(4,2) - seqsize(2,2) - }, - /* The same as above, but now with "addr.pri" (array - * indexing) on the first line and const.pri on - * the second. - */ - { - #ifdef SCPACK - "addr.pri %1!push.pri!const.pri %2!pop.alt!", - "addr.alt %1!const.pri %2!", - #else - "\265\264\344\244", - "\265\246\344", - #endif - seqsize(4,2) - seqsize(2,2) - }, - { - #ifdef SCPACK - "addr.pri %1!push.pri!zero.pri!pop.alt!", - "addr.alt %1!zero.pri!", - #else - "\265\264\375\244", - "\265\246\375", - #endif - seqsize(4,1) - seqsize(2,1) - }, - /* ??? add references */ - /* Chained relational operators can contain sequences like: - * move.pri load.s.pri n1 - * push.pri - - * load.s.pri n1 - - * pop.alt - - * The above also accurs for "load.pri" and for "const.pri", - * so add another two cases. - */ - { - #ifdef SCPACK - "move.pri!push.pri!load.s.pri %1!pop.alt!", - "load.s.pri %1!", - #else - "\300\237\247\332\244", - "\332", - #endif - seqsize(4,1) - seqsize(1,1) - }, - { - #ifdef SCPACK - "move.pri!push.pri!load.pri %1!pop.alt!", - "load.pri %1!", - #else - "\300\237\247\312\244", - "\312", - #endif - seqsize(4,1) - seqsize(1,1) - }, - { - #ifdef SCPACK - "move.pri!push.pri!const.pri %1!pop.alt!", - "const.pri %1!", - #else - "\300\237\247\327\244", - "\327", - #endif - seqsize(4,1) - seqsize(1,1) - }, - /* More optimizations for chained relational operators; the - * continuation sequences can be simplified if they turn out - * to be termination sequences: - * xchg sless also for sless, sgeq and sleq - * sgrtr pop.alt - * swap.alt and - * and ;$exp - * pop.alt - - * ;$exp - - * -------------------------------------- - * xchg sless also for sless, sgeq and sleq - * sgrtr pop.alt - * swap.alt and - * and jzer n1 - * pop.alt - - * jzer n1 - - * -------------------------------------- - * xchg jsgeq n1 also for sless, sgeq and sleq - * sgrtr ;$exp (occurs for non-chained comparisons) - * jzer n1 - - * ;$exp - - * -------------------------------------- - * xchg sless also for sless, sgeq and sleq - * sgrtr ;$exp (occurs for non-chained comparisons) - * ;$exp - - */ - { - #ifdef SCPACK - "xchg!sgrtr!swap.alt!and!pop.alt!;$exp!", - "sless!pop.alt!and!;$exp!", - #else - "\274\374swa\235\336\266\255", - "\353\266\336!\255", - #endif - seqsize(5,0) - seqsize(3,0) - }, - { - #ifdef SCPACK - "xchg!sless!swap.alt!and!pop.alt!;$exp!", - "sgrtr!pop.alt!and!;$exp!", - #else - "\274\353!swa\235\336\266\255", - "\374\244\336!\255", - #endif - seqsize(5,0) - seqsize(3,0) - }, - { - #ifdef SCPACK - "xchg!sgeq!swap.alt!and!pop.alt!;$exp!", - "sleq!pop.alt!and!;$exp!", - #else - "\274\303\323swa\235\336\266\255", - "\304\260\266\336!\255", - #endif - seqsize(5,0) - seqsize(3,0) - }, - { - #ifdef SCPACK - "xchg!sleq!swap.alt!and!pop.alt!;$exp!", - "sgeq!pop.alt!and!;$exp!", - #else - "\274\304\323swa\235\336\266\255", - "\303\260\266\336!\255", - #endif - seqsize(5,0) - seqsize(3,0) - }, - { - #ifdef SCPACK - "xchg!sgrtr!swap.alt!and!pop.alt!jzer %1!", - "sless!pop.alt!and!jzer %1!", - #else - "\274\374swa\235\336\266\340", - "\353\266\336!\340", - #endif - seqsize(5,0) - seqsize(3,0) - }, - { - #ifdef SCPACK - "xchg!sless!swap.alt!and!pop.alt!jzer %1!", - "sgrtr!pop.alt!and!jzer %1!", - #else - "\274\353!swa\235\336\266\340", - "\374\244\336!\340", - #endif - seqsize(5,0) - seqsize(3,0) - }, - { - #ifdef SCPACK - "xchg!sgeq!swap.alt!and!pop.alt!jzer %1!", - "sleq!pop.alt!and!jzer %1!", - #else - "\274\303\323swa\235\336\266\340", - "\304\260\266\336!\340", - #endif - seqsize(5,0) - seqsize(3,0) - }, - { - #ifdef SCPACK - "xchg!sleq!swap.alt!and!pop.alt!jzer %1!", - "sgeq!pop.alt!and!jzer %1!", - #else - "\274\304\323swa\235\336\266\340", - "\303\260\266\336!\340", - #endif - seqsize(5,0) - seqsize(3,0) - }, - { - #ifdef SCPACK - "xchg!sgrtr!jzer %1!;$exp!", - "jsgeq %1!;$exp!", - #else - "\274\374\324\301", - "j\303\260\301", - #endif - seqsize(3,1) - seqsize(1,1) - }, - { - #ifdef SCPACK - "xchg!sless!jzer %1!;$exp!", - "jsleq %1!;$exp!", - #else - "\274\353!\324\301", - "j\304\260\301", - #endif - seqsize(3,1) - seqsize(1,1) - }, - { - #ifdef SCPACK - "xchg!sgeq!jzer %1!;$exp!", - "jsgrtr %1!;$exp!", - #else - "\274\303\323\324\301", - "j\355r\301", - #endif - seqsize(3,1) - seqsize(1,1) - }, - { - #ifdef SCPACK - "xchg!sleq!jzer %1!;$exp!", - "jsless %1!;$exp!", - #else - "\274\304\323\324\301", - "j\353\301", - #endif - seqsize(3,1) - seqsize(1,1) - }, - { - #ifdef SCPACK - "xchg!sgrtr!;$exp!", - "sless!;$exp!", - #else - "\274\374\255", - "\353!\255", - #endif - seqsize(2,0) - seqsize(1,0) - }, - { - #ifdef SCPACK - "xchg!sless!;$exp!", - "sgrtr!;$exp!", - #else - "\274\353!\255", - "\374\255", - #endif - seqsize(2,0) - seqsize(1,0) - }, - { - #ifdef SCPACK - "xchg!sgeq!;$exp!", - "sleq!;$exp!", - #else - "\274\303\323\255", - "\304\323\255", - #endif - seqsize(2,0) - seqsize(1,0) - }, - { - #ifdef SCPACK - "xchg!sleq!;$exp!", - "sgeq!;$exp!", - #else - "\274\304\323\255", - "\303\323\255", - #endif - seqsize(2,0) - seqsize(1,0) - }, - /* The entry to chained operators is also opt to optimization - * load.s.pri n1 load.s.pri n2 - * load.s.alt n2 load.s.alt n1 - * xchg - - * -------------------------------------- - * load.s.pri n1 load.pri n2 - * load.alt n2 load.s.alt n1 - * xchg - - * -------------------------------------- - * load.s.pri n1 const.pri n2 - * const.alt n2 load.s.alt n1 - * xchg - - * -------------------------------------- - * and all permutations... - */ - { - #ifdef SCPACK - "load.s.pri %1!load.s.alt %2!xchg!", - "load.s.pri %2!load.s.alt %1!", - #else - "\332\226\305\274", - "\251\226\246", - #endif - seqsize(3,2) - seqsize(2,2) - }, - { - #ifdef SCPACK - "load.s.pri %1!load.alt %2!xchg!", - "load.pri %2!load.s.alt %1!", - #else - "\332\366\274", - "\333\226\246", - #endif - seqsize(3,2) - seqsize(2,2) - }, - { - #ifdef SCPACK - "load.s.pri %1!const.alt %2!xchg!", - "const.pri %2!load.s.alt %1!", - #else - "\332\234\305\274", - "\344\226\246", - #endif - seqsize(3,2) - seqsize(2,2) - }, - { - #ifdef SCPACK - "load.pri %1!load.s.alt %2!xchg!", - "load.s.pri %2!load.alt %1!", - #else - "\312\226\305\274", - "\251\376", - #endif - seqsize(3,2) - seqsize(2,2) - }, - { - #ifdef SCPACK - "load.pri %1!load.alt %2!xchg!", - "load.pri %2!load.alt %1!", - #else - "\312\366\274", - "\333\376", - #endif - seqsize(3,2) - seqsize(2,2) - }, - { - #ifdef SCPACK - "load.pri %1!const.alt %2!xchg!", - "const.pri %2!load.alt %1!", - #else - "\312\234\305\274", - "\344\376", - #endif - seqsize(3,2) - seqsize(2,2) - }, - { - #ifdef SCPACK - "const.pri %1!load.s.alt %2!xchg!", - "load.s.pri %2!const.alt %1!", - #else - "\327\226\305\274", - "\251\360", - #endif - seqsize(3,2) - seqsize(2,2) - }, - { - #ifdef SCPACK - "const.pri %1!load.alt %2!xchg!", - "load.pri %2!const.alt %1!", - #else - "\327\366\274", - "\333\360", - #endif - seqsize(3,2) - seqsize(2,2) - }, - /* some sequences where PRI is moved to ALT can be optimized - * further when considering what follows - * move.alt const.alt n1 - * const.pri %1 - - * xchg - - * (also for load.s.pri and load.pri) - * -------------------------------------- - * lref.pri %1 lref.alt %1 - * move.alt [load.pri %2] - * [load.pri %2] - - * (where [load.pri %2] may also be another operatrion loading PRI) - */ - { - #ifdef SCPACK - "move.alt!const.pri %1!xchg!", - "const.alt %1!", - #else - "\307\327\274", - "\360", - #endif - seqsize(3,1) - seqsize(1,1) - }, - { - #ifdef SCPACK - "move.alt!load.pri %1!xchg!", - "load.alt %1!", - #else - "\307\312\274", - "\376", - #endif - seqsize(3,1) - seqsize(1,1) - }, - { - #ifdef SCPACK - "move.alt!load.s.pri %1!xchg!", - "load.s.alt %1!", - #else - "\307\332\274", - "\226\246", - #endif - seqsize(3,1) - seqsize(1,1) - }, - /* ----- */ - { - #ifdef SCPACK - "lref.pri %1!move.alt!load.pri %2!", - "lref.alt %1!load.pri %2!", - #else - "\351\225\307\333", - "\351\246\333", - #endif - seqsize(3,2) - seqsize(2,2) - }, - { - #ifdef SCPACK - "lref.pri %1!move.alt!load.s.pri %2!", - "lref.alt %1!load.s.pri %2!", - #else - "\351\225\307\251", - "\351\311", - #endif - seqsize(3,2) - seqsize(2,2) - }, - { - #ifdef SCPACK - "lref.pri %1!move.alt!const.pri %2!", - "lref.alt %1!const.pri %2!", - #else - "\351\225\307\344", - "\351\246\344", - #endif - seqsize(3,2) - seqsize(2,2) - }, - { - #ifdef SCPACK - "lref.s.pri %1!move.alt!load.pri %2!", - "lref.s.alt %1!load.pri %2!", - #else - "\351\222\225\307\333", - "\351\222\246\333", - #endif - seqsize(3,2) - seqsize(2,2) - }, - { - #ifdef SCPACK - "lref.s.pri %1!move.alt!load.s.pri %2!", - "lref.s.alt %1!load.s.pri %2!", - #else - "\351\222\225\307\251", - "\351\222\311", - #endif - seqsize(3,2) - seqsize(2,2) - }, - { - #ifdef SCPACK - "lref.s.pri %1!move.alt!const.pri %2!", - "lref.s.alt %1!const.pri %2!", - #else - "\351\222\225\307\344", - "\351\222\246\344", - #endif - seqsize(3,2) - seqsize(2,2) - }, - /* Array indexing can merit from special instructions. - * Simple indexed array lookup can be optimized quite - * a bit. - * addr.pri n1 addr.alt n1 - * push.pri load.s.pri n2 - * load.s.pri n2 bounds n3 - * bounds n3 lidx.b n4 - * shl.c.pri n4 - - * pop.alt - - * add - - * load.i - - * - * And to prepare for storing a value in an array - * addr.pri n1 addr.alt n1 - * push.pri load.s.pri n2 - * load.s.pri n2 bounds n3 - * bounds n3 idxaddr.b n4 - * shl.c.pri n4 - - * pop.alt - - * add - - * - * Notes (additional cases): - * 1. instruction addr.pri can also be const.pri (for - * global arrays) - * 2. the bounds instruction can be absent - * 3. when "n4" (the shift value) is the 2 (with 32-bit cells), use the - * even more optimal instructions LIDX and IDDXADDR - * - * If the array index is more complex, one can only optimize - * the last four instructions: - * shl.c.pri n1 pop.alt - * pop.alt lidx.b n1 - * add - - * loadi - - * -------------------------------------- - * shl.c.pri n1 pop.alt - * pop.alt idxaddr.b n1 - * add - - */ -#if !defined BIT16 - /* loading from array, "cell" shifted */ - { - #ifdef SCPACK - "addr.pri %1!push.pri!load.s.pri %2!bounds %3!shl.c.pri 2!pop.alt!add!load.i!", - "addr.alt %1!load.s.pri %2!bounds %3!lidx!", - #else - "\365\317\372\342\357", - "\367\317\370!", - #endif - seqsize(8,4) - seqsize(4,3) - }, - { - #ifdef SCPACK - "const.pri %1!push.pri!load.s.pri %2!bounds %3!shl.c.pri 2!pop.alt!add!load.i!", - "const.alt %1!load.s.pri %2!bounds %3!lidx!", - #else - "\364\317\372\342\357", - "\234\311\317\370!", - #endif - seqsize(8,4) - seqsize(4,3) - }, - { - #ifdef SCPACK - "addr.pri %1!push.pri!load.s.pri %2!shl.c.pri 2!pop.alt!add!load.i!", - "addr.alt %1!load.s.pri %2!lidx!", - #else - "\365\372\342\357", - "\367\370!", - #endif - seqsize(7,3) - seqsize(3,2) - }, - { - #ifdef SCPACK - "const.pri %1!push.pri!load.s.pri %2!shl.c.pri 2!pop.alt!add!load.i!", - "const.alt %1!load.s.pri %2!lidx!", - #else - "\364\372\342\357", - "\234\311\370!", - #endif - seqsize(7,3) - seqsize(3,2) - }, -#endif - /* loading from array, not "cell" shifted */ - { - #ifdef SCPACK - "addr.pri %1!push.pri!load.s.pri %2!bounds %3!shl.c.pri %4!pop.alt!add!load.i!", - "addr.alt %1!load.s.pri %2!bounds %3!lidx.b %4!", - #else - "\365\317\326\302\341\342\357", - "\367\317\370\371\334", - #endif - seqsize(8,4) - seqsize(4,4) - }, - { - #ifdef SCPACK - "const.pri %1!push.pri!load.s.pri %2!bounds %3!shl.c.pri %4!pop.alt!add!load.i!", - "const.alt %1!load.s.pri %2!bounds %3!lidx.b %4!", - #else - "\364\317\326\302\341\342\357", - "\234\311\317\370\371\334", - #endif - seqsize(8,4) - seqsize(4,4) - }, - { - #ifdef SCPACK - "addr.pri %1!push.pri!load.s.pri %2!shl.c.pri %3!pop.alt!add!load.i!", - "addr.alt %1!load.s.pri %2!lidx.b %3!", - #else - "\365\326\256\244\271\342\357", - "\367\370\371\256", - #endif - seqsize(7,3) - seqsize(3,3) - }, - { - #ifdef SCPACK - "const.pri %1!push.pri!load.s.pri %2!shl.c.pri %3!pop.alt!add!load.i!", - "const.alt %1!load.s.pri %2!lidx.b %3!", - #else - "\364\326\256\244\271\342\357", - "\234\311\370\371\256", - #endif - seqsize(7,3) - seqsize(3,3) - }, -#if !defined BIT16 - /* array index calculation for storing a value, "cell" aligned */ - { - #ifdef SCPACK - "addr.pri %1!push.pri!load.s.pri %2!bounds %3!shl.c.pri 2!pop.alt!add!", - "addr.alt %1!load.s.pri %2!bounds %3!idxaddr!", - #else - "\365\317\372", - "\367\317\321\236\231", - #endif - seqsize(7,4) - seqsize(4,3) - }, - { - #ifdef SCPACK - "const.pri %1!push.pri!load.s.pri %2!bounds %3!shl.c.pri 2!pop.alt!add!", - "const.alt %1!load.s.pri %2!bounds %3!idxaddr!", - #else - "\364\317\372", - "\234\311\317\321\236\231", - #endif - seqsize(7,4) - seqsize(4,3) - }, - { - #ifdef SCPACK - "addr.pri %1!push.pri!load.s.pri %2!shl.c.pri 2!pop.alt!add!", - "addr.alt %1!load.s.pri %2!idxaddr!", - #else - "\365\372", - "\367\321\236\231", - #endif - seqsize(6,3) - seqsize(3,2) - }, - { - #ifdef SCPACK - "const.pri %1!push.pri!load.s.pri %2!shl.c.pri 2!pop.alt!add!", - "const.alt %1!load.s.pri %2!idxaddr!", - #else - "\364\372", - "\234\311\321\236\231", - #endif - seqsize(6,3) - seqsize(3,2) - }, -#endif - /* array index calculation for storing a value, not "cell" packed */ - { - #ifdef SCPACK - "addr.pri %1!push.pri!load.s.pri %2!bounds %3!shl.c.pri %4!pop.alt!add!", - "addr.alt %1!load.s.pri %2!bounds %3!idxaddr.b %4!", - #else - "\365\317\326\302\341", - "\367\317\321\265\371\334", - #endif - seqsize(7,4) - seqsize(4,4) - }, - { - #ifdef SCPACK - "const.pri %1!push.pri!load.s.pri %2!bounds %3!shl.c.pri %4!pop.alt!add!", - "const.alt %1!load.s.pri %2!bounds %3!idxaddr.b %4!", - #else - "\364\317\326\302\341", - "\234\311\317\321\265\371\334", - #endif - seqsize(7,4) - seqsize(4,4) - }, - { - #ifdef SCPACK - "addr.pri %1!push.pri!load.s.pri %2!shl.c.pri %3!pop.alt!add!", - "addr.alt %1!load.s.pri %2!idxaddr.b %3!", - #else - "\365\326\256\244\271", - "\367\321\265\371\256", - #endif - seqsize(6,3) - seqsize(3,3) - }, - { - #ifdef SCPACK - "const.pri %1!push.pri!load.s.pri %2!shl.c.pri %3!pop.alt!add!", - "const.alt %1!load.s.pri %2!idxaddr.b %3!", - #else - "\364\326\256\244\271", - "\234\311\321\265\371\256", - #endif - seqsize(6,3) - seqsize(3,3) - }, -#if !defined BIT16 - /* the shorter array indexing sequences, see above for comments */ - { - #ifdef SCPACK - "shl.c.pri 2!pop.alt!add!loadi!", - "pop.alt!lidx!", - #else - "\372\217\357", - "\244\370!", - #endif - seqsize(4,1) - seqsize(2,0) - }, - { - #ifdef SCPACK - "shl.c.pri 2!pop.alt!add!", - "pop.alt!idxaddr!", - #else - "\372", - "\244\321\236\231", - #endif - seqsize(3,1) - seqsize(2,0) - }, -#endif - { - #ifdef SCPACK - "shl.c.pri %1!pop.alt!add!loadi!", - "pop.alt!lidx.b %1!", - #else - "\316\225\244\271\217\357", - "\244\370\371\202", - #endif - seqsize(4,1) - seqsize(2,1) - }, - { - #ifdef SCPACK - "shl.c.pri %1!pop.alt!add!", - "pop.alt!idxaddr.b %1!", - #else - "\316\225\244\271", - "\244\321\265\371\202", - #endif - seqsize(3,1) - seqsize(2,1) - }, - /* For packed arrays, there is another case (packed arrays - * do not take advantage of the LIDX or IDXADDR instructions). - * addr.pri n1 addr.alt n1 - * push.pri load.s.pri n2 - * load.s.pri n2 bounds n3 - * bounds n3 - - * pop.alt - - * - * Notes (additional cases): - * 1. instruction addr.pri can also be const.pri (for - * global arrays) - * 2. the bounds instruction can be absent, but that - * case is already handled (see #1#) - */ - { - #ifdef SCPACK - "addr.pri %1!push.pri!load.s.pri %2!bounds %3!pop.alt!", - "addr.alt %1!load.s.pri %2!bounds %3!", - #else - "\365\317\244", - "\367\317", - #endif - seqsize(5,3) - seqsize(3,3) - }, - { - #ifdef SCPACK - "const.pri %1!push.pri!load.s.pri %2!bounds %3!pop.alt!", - "const.alt %1!load.s.pri %2!bounds %3!", - #else - "\364\317\244", - "\234\311\317", - #endif - seqsize(5,3) - seqsize(3,3) - }, - /* Declaration of simple variables often follows the sequence: - * ;$lcl ;$lcl - * stack -4 push.c - * const.pri ;$exp - * stor.s.pri - - * ;$exp - - */ - { - #ifdef SCPACK - ";$lcl %1 %2!stack -4!const.pri %3!stor.s.pri %2!;$exp!", - ";$lcl %1 %2!push.c %3!;$exp!", - #else - "\223lcl\331\227ack -4!\234\206\256\227or\222\230\255", - "\223lcl\331\330\256\255", - #endif - seqsize(3,3) - seqsize(1,1) - }, - { - #ifdef SCPACK - ";$lcl %1 %2!stack -4!zero.pri!stor.s.pri %2!;$exp!", - ";$lcl %1 %2!push.c 0!;$exp!", - #else - "\223lcl\331\227ack -4!\375\227or\222\230\255", - "\223lcl\331\330 0!\255", - #endif - seqsize(3,2) - seqsize(1,1) - }, - /* During a calculation, the intermediate result must sometimes - * be moved from PRI to ALT, like in: - * push.pri move.alt - * load.s.pri n1 load.s.pri n1 - * pop.alt - - * - * The above also accurs for "load.pri" and for "const.pri", - * so add another two cases. - */ - { - #ifdef SCPACK - "push.pri!load.s.pri %1!pop.alt!", - "move.alt!load.s.pri %1!", - #else - "\247\332\244", - "\307\332", - #endif - seqsize(3,1) - seqsize(2,1) - }, - { - #ifdef SCPACK - "push.pri!load.pri %1!pop.alt!", - "move.alt!load.pri %1!", - #else - "\247\312\244", - "\307\312", - #endif - seqsize(3,1) - seqsize(2,1) - }, - { - #ifdef SCPACK - "push.pri!const.pri %1!pop.alt!", - "move.alt!const.pri %1!", - #else - "\247\327\244", - "\307\327", - #endif - seqsize(3,1) - seqsize(2,1) - }, - { - #ifdef SCPACK - "push.pri!zero.pri!pop.alt!", - "move.alt!zero.pri!", - #else - "\247\375\244", - "\307\375", - #endif - seqsize(3,0) - seqsize(2,0) - }, - /* saving PRI and then loading from its address - * occurs when indexing a multi-dimensional array - */ - { - #ifdef SCPACK - "push.pri!load.i!pop.alt!", - "move.alt!load.i!", - #else - "\247\342i\266", - "\307\342\357", - #endif - seqsize(3,0) - seqsize(2,0) - }, - /* An even simpler PUSH/POP optimization (occurs in - * switch statements): - * push.pri move.alt - * pop.alt - - */ - { - #ifdef SCPACK - "push.pri!pop.alt!", - "move.alt!", - #else - "\247\244", - "\307", - #endif - seqsize(2,0) - seqsize(1,0) - }, - /* Some simple arithmetic sequences - */ - { - #ifdef SCPACK - "move.alt!load.s.pri %1!add!", - "load.s.alt %1!add!", - #else - "\307\332\271", - "\226\246\271", - #endif - seqsize(3,1) - seqsize(2,1) - }, - { - #ifdef SCPACK - "move.alt!load.pri %1!add!", - "load.alt %1!add!", - #else - "\307\312\271", - "\376\271", - #endif - seqsize(3,1) - seqsize(2,1) - }, - { - #ifdef SCPACK - "move.alt!const.pri %1!add!", - "const.alt %1!add!", - #else - "\307\327\271", - "\360\271", - #endif - seqsize(3,1) - seqsize(2,1) - }, - { - #ifdef SCPACK - "move.alt!load.s.pri %1!sub.alt!", - "load.s.alt %1!sub!", - #else - "\307\332sub\224", - "\226\246sub!", - #endif - seqsize(3,1) - seqsize(2,1) - }, - { - #ifdef SCPACK - "move.alt!load.pri %1!sub.alt!", - "load.alt %1!sub!", - #else - "\307\312sub\224", - "\376sub!", - #endif - seqsize(3,1) - seqsize(2,1) - }, - { - #ifdef SCPACK - "move.alt!const.pri %1!sub.alt!", - "const.alt %1!sub!", - #else - "\307\327sub\224", - "\360sub!", - #endif - seqsize(3,1) - seqsize(2,1) - }, - /* User-defined operators first load the operands into registers and - * then have them pushed onto the stack. This can give rise to sequences - * like: - * const.pri n1 push.c n1 - * const.alt n2 push.c n2 - * push.pri - - * push.alt - - * A similar sequence occurs with the two PUSH.pri/alt instructions inverted. - * The first, second, or both CONST.pri/alt instructions can also be - * LOAD.pri/alt. - * This gives 2 x 4 cases. - */ - { - #ifdef SCPACK - "const.pri %1!const.alt %2!push.pri!push.alt!", - "push.c %1!push.c %2!", - #else - "\327\234\305\247\356", - "\330\202\330\221", - #endif - seqsize(4,2) - seqsize(2,2) - }, - { - #ifdef SCPACK - "const.pri %1!const.alt %2!push.alt!push.pri!", - "push.c %2!push.c %1!", - #else - "\327\234\305\356\247", - "\330\221\330\202", - #endif - seqsize(4,2) - seqsize(2,2) - }, - { - #ifdef SCPACK - "const.pri %1!load.alt %2!push.pri!push.alt!", - "push.c %1!push %2!", - #else - "\327\366\247\356", - "\330\202\216\221", - #endif - seqsize(4,2) - seqsize(2,2) - }, - { - #ifdef SCPACK - "const.pri %1!load.alt %2!push.alt!push.pri!", - "push %2!push.c %1!", - #else - "\327\366\356\247", - "\216\221\330\202", - #endif - seqsize(4,2) - seqsize(2,2) - }, - { - #ifdef SCPACK - "load.pri %1!const.alt %2!push.pri!push.alt!", - "push %1!push.c %2!", - #else - "\312\234\305\247\356", - "\216\202\330\221", - #endif - seqsize(4,2) - seqsize(2,2) - }, - { - #ifdef SCPACK - "load.pri %1!const.alt %2!push.alt!push.pri!", - "push.c %2!push %1!", - #else - "\312\234\305\356\247", - "\330\221\216\202", - #endif - seqsize(4,2) - seqsize(2,2) - }, - { - #ifdef SCPACK - "load.pri %1!load.alt %2!push.pri!push.alt!", - "push %1!push %2!", - #else - "\312\366\247\356", - "\216\202\216\221", - #endif - seqsize(4,2) - seqsize(2,2) - }, - { - #ifdef SCPACK - "load.pri %1!load.alt %2!push.alt!push.pri!", - "push %2!push %1!", - #else - "\312\366\356\247", - "\216\221\216\202", - #endif - seqsize(4,2) - seqsize(2,2) - }, - /* Function calls (parameters are passed on the stack) - * load.s.pri n1 push.s n1 - * push.pri - - * -------------------------------------- - * load.pri n1 push n1 - * push.pri - - * -------------------------------------- - * const.pri n1 push.c n1 - * push.pri - - * -------------------------------------- - * zero.pri push.c 0 - * push.pri - - * -------------------------------------- - * addr.pri n1 push.adr n1 - * push.pri - - * - * However, PRI must not be needed after this instruction - * if this shortcut is used. Check for the ;$par comment. - */ - { - #ifdef SCPACK - "load.s.pri %1!push.pri!;$par!", - "push.s %1!;$par!", - #else - "\226\264\242", - "\216\222\202\242", - #endif - seqsize(2,1) - seqsize(1,1) - }, - { - #ifdef SCPACK - "load.pri %1!push.pri!;$par!", - "push %1!;$par!", - #else - "\217\264\242", - "\216\202\242", - #endif - seqsize(2,1) - seqsize(1,1) - }, - { - #ifdef SCPACK - "const.pri %1!push.pri!;$par!", - "push.c %1!;$par!", - #else - "\234\264\242", - "\330\202\242", - #endif - seqsize(2,1) - seqsize(1,1) - }, - { - #ifdef SCPACK - "zero.pri!push.pri!;$par!", - "push.c 0!;$par!", - #else - "\375\247\242", - "\330 0!\242", - #endif - seqsize(2,0) - seqsize(1,1) - }, - { - #ifdef SCPACK - "addr.pri %1!push.pri!;$par!", - "push.adr %1!;$par!", - #else - "\265\264\242", - "\216\325\202\242", - #endif - seqsize(2,1) - seqsize(1,1) - }, - /* References with a default value generate new cells on the heap - * dynamically. That code often ends with: - * move.pri push.alt - * push.pri - - */ - { - #ifdef SCPACK - "move.pri!push.pri!", - "push.alt!", - #else - "\300\237\247", - "\356", - #endif - seqsize(2,0) - seqsize(1,0) - }, - /* Simple arithmetic operations on constants. Noteworthy is the - * subtraction of a constant, since it is converted to the addition - * of the inverse value. - * const.alt n1 add.c n1 - * add - - * -------------------------------------- - * const.alt n1 add.c -n1 - * sub - - * -------------------------------------- - * const.alt n1 smul.c n1 - * smul - - * -------------------------------------- - * const.alt n1 eq.c.pri n1 - * eq - - */ - { - #ifdef SCPACK - "const.alt %1!add!", - "add.c %1!", - #else - "\360\271", - "\236\245\202", - #endif - seqsize(2,1) - seqsize(1,1) - }, - { - #ifdef SCPACK - "const.alt %1!sub!", - "add.c -%1!", - #else - "\360sub!", - "\236\245 -\201", - #endif - seqsize(2,1) - seqsize(1,1) - }, - { - #ifdef SCPACK - "const.alt %1!smul!", - "smul.c %1!", - #else - "\360smul!", - "smu\310\202", - #endif - seqsize(2,1) - seqsize(1,1) - }, - { - #ifdef SCPACK - "const.alt %1!eq!", - "eq.c.pri %1!", - #else - "\360\323", - "\260\245\225", - #endif - seqsize(2,1) - seqsize(1,1) - }, - /* Some operations use the alternative subtraction operation --these - * can also be optimized. - * const.pri n1 load.s.pri n2 - * load.s.alt n2 add.c -n1 - * sub.alt - - * -------------------------------------- - * const.pri n1 load.pri n2 - * load.alt n2 add.c -n1 - * sub.alt - - */ - { - #ifdef SCPACK - "const.pri %1!load.s.alt %2!sub.alt!", - "load.s.pri %2!add.c -%1!", - #else - "\327\226\305sub\224", - "\251\236\245 -\201", - #endif - seqsize(3,2) - seqsize(2,2) - }, - { - #ifdef SCPACK - "const.pri %1!load.alt %2!sub.alt!", - "load.pri %2!add.c -%1!", - #else - "\327\366sub\224", - "\333\236\245 -\201", - #endif - seqsize(3,2) - seqsize(2,2) - }, - /* With arrays indexed with constants that come from enumerations, it happens - * multiple add.c opcodes follow in sequence. - * add.c n1 add.c n1+n2 - * add.c n2 - - */ - { - #ifdef SCPACK - "add.c %1!add.c %2!", - "add.c %1+%2!", - #else - "\236\245\202\236\245\221", - "\236\245\267+%2!", - #endif - seqsize(2,2) - seqsize(1,1) - }, - /* Compare and jump - * eq jneq n1 - * jzer n1 - - * -------------------------------------- - * eq jeq n1 - * jnz n1 - - * -------------------------------------- - * neq jeq n1 - * jzer n1 - - * -------------------------------------- - * neq jneq n1 - * jnz n1 - - * An similarly for other relations - * sless jsgeq n1 - * jzer n1 - - * -------------------------------------- - * sless jsless n1 - * jnz n1 - - * -------------------------------------- - * sleq jsgrtr n1 - * jzer n1 - - * -------------------------------------- - * sleq jsleq n1 - * jnz n1 - - * -------------------------------------- - * sgrtr jsleq n1 - * jzer n1 - - * -------------------------------------- - * sgrtr jsgrtr n1 - * jnz n1 - - * -------------------------------------- - * sgeq jsless n1 - * jzer n1 - - * -------------------------------------- - * sgeq jsgeq n1 - * jnz n1 - - * We can relax the optimizations for the unsigned comparisons, - * because the Pawn compiler currently only generates signed - * comparisons. - */ - { - #ifdef SCPACK - "eq!jzer %1!", - "jneq %1!", - #else - "\323\340", - "\373\361", - #endif - seqsize(2,1) - seqsize(1,1) - }, - { - #ifdef SCPACK - "eq!jnz %1!", - "jeq %1!", - #else - "\323\373z\202", - "j\361", - #endif - seqsize(2,1) - seqsize(1,1) - }, - { - #ifdef SCPACK - "neq!jzer %1!", - "jeq %1!", - #else - "n\323\340", - "j\361", - #endif - seqsize(2,1) - seqsize(1,1) - }, - { - #ifdef SCPACK - "neq!jnz %1!", - "jneq %1!", - #else - "n\323\373z\202", - "\373\361", - #endif - seqsize(2,1) - seqsize(1,1) - }, - { - #ifdef SCPACK - "sless!jzer %1!", - "jsgeq %1!", - #else - "\353!\340", - "j\303\361", - #endif - seqsize(2,1) - seqsize(1,1) - }, - { - #ifdef SCPACK - "sless!jnz %1!", - "jsless %1!", - #else - "\353!\373z\202", - "j\353\202", - #endif - seqsize(2,1) - seqsize(1,1) - }, - { - #ifdef SCPACK - "sleq!jzer %1!", - "jsgrtr %1!", - #else - "\304\323\340", - "j\355r\202", - #endif - seqsize(2,1) - seqsize(1,1) - }, - { - #ifdef SCPACK - "sleq!jnz %1!", - "jsleq %1!", - #else - "\304\323\373z\202", - "j\304\361", - #endif - seqsize(2,1) - seqsize(1,1) - }, - { - #ifdef SCPACK - "sgrtr!jzer %1!", - "jsleq %1!", - #else - "\374\340", - "j\304\361", - #endif - seqsize(2,1) - seqsize(1,1) - }, - { - #ifdef SCPACK - "sgrtr!jnz %1!", - "jsgrtr %1!", - #else - "\374\373z\202", - "j\355r\202", - #endif - seqsize(2,1) - seqsize(1,1) - }, - { - #ifdef SCPACK - "sgeq!jzer %1!", - "jsless %1!", - #else - "\303\323\340", - "j\353\202", - #endif - seqsize(2,1) - seqsize(1,1) - }, - { - #ifdef SCPACK - "sgeq!jnz %1!", - "jsgeq %1!", - #else - "\303\323\373z\202", - "j\303\361", - #endif - seqsize(2,1) - seqsize(1,1) - }, - /* Test for zero (common case, especially for strings) - * E.g. the test expression of: "for (i=0; str{i}!=0; ++i)" - * - * zero.alt jzer n1 - * jeq n1 - - * -------------------------------------- - * zero.alt jnz n1 - * jneq n1 - - */ - { - #ifdef SCPACK - "zero.alt!jeq %1!", - "jzer %1!", - #else - "\337\224j\361", - "\340", - #endif - seqsize(2,1) - seqsize(1,1) - }, - { - #ifdef SCPACK - "zero.alt!jneq %1!", - "jnz %1!", - #else - "\337\224\373\361", - "\373z\202", - #endif - seqsize(2,1) - seqsize(1,1) - }, - /* Incrementing and decrementing leaves a value in - * in PRI which may not be used (for example, as the - * third expression in a "for" loop). - * inc n1 inc n1 ; ++n - * load.pri n1 ;$exp - * ;$exp - - * -------------------------------------- - * load.pri n1 inc n1 ; n++, e.g. "for (n=0; n<10; n++)" - * inc n1 ;$exp - * ;$exp - - * Plus the varieties for stack relative increments - * and decrements. - */ - { - #ifdef SCPACK - "inc %1!load.pri %1!;$exp!", - "inc %1!;$exp!", - #else - "inc\202\312\255", - "inc\301", - #endif - seqsize(2,2) - seqsize(1,1) - }, - { - #ifdef SCPACK - "load.pri %1!inc %1!;$exp!", - "inc %1!;$exp!", - #else - "\312inc\301", - "inc\301", - #endif - seqsize(2,2) - seqsize(1,1) - }, - { - #ifdef SCPACK - "inc.s %1!load.s.pri %1!;$exp!", - "inc.s %1!;$exp!", - #else - "inc\222\202\332\255", - "inc\222\301", - #endif - seqsize(2,2) - seqsize(1,1) - }, - { - #ifdef SCPACK - "load.s.pri %1!inc.s %1!;$exp!", - "inc.s %1!;$exp!", - #else - "\332inc\222\301", - "inc\222\301", - #endif - seqsize(2,2) - seqsize(1,1) - }, - { - #ifdef SCPACK - "dec %1!load.pri %1!;$exp!", - "dec %1!;$exp!", - #else - "dec\202\312\255", - "dec\301", - #endif - seqsize(2,2) - seqsize(1,1) - }, - { - #ifdef SCPACK - "load.pri %1!dec %1!;$exp!", - "dec %1!;$exp!", - #else - "\312dec\301", - "dec\301", - #endif - seqsize(2,2) - seqsize(1,1) - }, - { - #ifdef SCPACK - "dec.s %1!load.s.pri %1!;$exp!", - "dec.s %1!;$exp!", - #else - "dec\222\202\332\255", - "dec\222\301", - #endif - seqsize(2,2) - seqsize(1,1) - }, - { - #ifdef SCPACK - "load.s.pri %1!dec.s %1!;$exp!", - "dec.s %1!;$exp!", - #else - "\332dec\222\301", - "dec\222\301", - #endif - seqsize(2,2) - seqsize(1,1) - }, - /* ??? the same (increments and decrements) for references */ - /* Loading the constant zero has a special opcode. - * When storing zero in memory, the value of PRI must not be later on. - * const.pri 0 zero n1 - * stor.pri n1 ;$exp - * ;$exp - - * -------------------------------------- - * const.pri 0 zero.s n1 - * stor.s.pri n1 ;$exp - * ;$exp - - * -------------------------------------- - * zero.pri zero n1 - * stor.pri n1 ;$exp - * ;$exp - - * -------------------------------------- - * zero.pri zero.s n1 - * stor.s.pri n1 ;$exp - * ;$exp - - * -------------------------------------- - * const.pri 0 zero.pri - * -------------------------------------- - * const.alt 0 zero.alt - * The last two alternatives save more memory than they save - * time, but anyway... - */ - { - #ifdef SCPACK - "const.pri 0!stor.pri %1!;$exp!", - "zero %1!;$exp!", - #else - "\234\206 0!\227or\225\255", - "\337\301", - #endif - seqsize(2,2) - seqsize(1,1) - }, - { - #ifdef SCPACK - "const.pri 0!stor.s.pri %1!;$exp!", - "zero.s %1!;$exp!", - #else - "\234\206 0!\227or\222\225\255", - "\337\222\301", - #endif - seqsize(2,2) - seqsize(1,1) - }, - { - #ifdef SCPACK - "zero.pri!stor.pri %1!;$exp!", - "zero %1!;$exp!", - #else - "\375\227or\225\255", - "\337\301", - #endif - seqsize(2,1) - seqsize(1,1) - }, - { - #ifdef SCPACK - "zero.pri!stor.s.pri %1!;$exp!", - "zero.s %1!;$exp!", - #else - "\375\227or\222\225\255", - "\337\222\301", - #endif - seqsize(2,1) - seqsize(1,1) - }, - { - #ifdef SCPACK - "const.pri 0!", - "zero.pri!", - #else - "\234\206 0!", - "\375", - #endif - seqsize(1,1) - seqsize(1,0) - }, - { - #ifdef SCPACK - "const.alt 0!", - "zero.alt!", - #else - "\234\212 0!", - "\337\224", - #endif - seqsize(1,1) - seqsize(1,0) - }, - - /* ------------------ */ - /* Macro instructions */ - /* ------------------ */ - - { "", "", 0 }, /* separator, so optimizer can stop before generating macro opcodes */ - - /* optimizing the calling of native functions (which always have a parameter - * count pushed before, and the stack pointer restored afterwards - */ - { - #ifdef SCPACK - "push.c %1!sysreq.c %2!stack %3!", //note: %3 == %1 + 4 - "sysreq.n %2 %1!", - #else - "\330\202sysr\260\245\221\227ack\256", - "sysr\260.n\220\202", - #endif - seqsize(3,3) - seqsize(1,2) - }, - /* ----- */ - /* Functions with many parameters with the same "type" have sequences like: - * push.c n1 push3.c n1 n2 n3 - * ;$par ;$par - * push.c n2 - - * ;$par - - * push.c n3 - - * ;$par - - * etc. etc. - * - * Similar sequences occur with PUSH, PUSH.s and PUSHADDR - */ - { - #ifdef SCPACK - "push.c %1!;$par!push.c %2!;$par!push.c %3!;$par!push.c %4!;$par!push.c %5!;$par!", - "push5.c %1 %2 %3 %4 %5!", - #else - "\330\335\245\345\245\256\257\245\334\257\245\2035!\242", - "\2165\245\343\250\302\2035!", - #endif - seqsize(5,5) - seqsize(1,5) - }, - { - #ifdef SCPACK - "push.c %1!;$par!push.c %2!;$par!push.c %3!;$par!push.c %4!;$par!", - "push4.c %1 %2 %3 %4!", - #else - "\330\335\245\345\245\256\257\245\334\242", - "\2164\245\343\250\334", - #endif - seqsize(4,4) - seqsize(1,4) - }, - { - #ifdef SCPACK - "push.c %1!;$par!push.c %2!;$par!push.c %3!;$par!", - "push3.c %1 %2 %3!", - #else - "\330\335\245\345\245\256\242", - "\2163\245\343\256", - #endif - seqsize(3,3) - seqsize(1,3) - }, - { - #ifdef SCPACK - "push.c %1!;$par!push.c %2!;$par!", - "push2.c %1 %2!", - #else - "\330\335\245\221\242", - "\2162\245\331", - #endif - seqsize(2,2) - seqsize(1,2) - }, - /* ----- */ - { - #ifdef SCPACK - "push %1!;$par!push %2!;$par!push %3!;$par!push %4!;$par!push %5!;$par!", - "push5 %1 %2 %3 %4 %5!", - #else - "\216\335\345\256\257\334\257\2035!\242", - "\2165\343\250\302\2035!", - #endif - seqsize(5,5) - seqsize(1,5) - }, - { - #ifdef SCPACK - "push %1!;$par!push %2!;$par!push %3!;$par!push %4!;$par!", - "push4 %1 %2 %3 %4!", - #else - "\216\335\345\256\257\334\242", - "\2164\343\250\334", - #endif - seqsize(4,4) - seqsize(1,4) - }, - { - #ifdef SCPACK - "push %1!;$par!push %2!;$par!push %3!;$par!", - "push3 %1 %2 %3!", - #else - "\216\335\345\256\242", - "\2163\343\256", - #endif - seqsize(3,3) - seqsize(1,3) - }, - { - #ifdef SCPACK - "push %1!;$par!push %2!;$par!", - "push2 %1 %2!", - #else - "\216\335\221\242", - "\2162\331", - #endif - seqsize(2,2) - seqsize(1,2) - }, - /* ----- */ - { - #ifdef SCPACK - "push.s %1!;$par!push.s %2!;$par!push.s %3!;$par!push.s %4!;$par!push.s %5!;$par!", - "push5.s %1 %2 %3 %4 %5!", - #else - "\216\222\335\222\345\222\256\257\222\334\257\222\2035!\242", - "\2165\222\343\250\302\2035!", - #endif - seqsize(5,5) - seqsize(1,5) - }, - { - #ifdef SCPACK - "push.s %1!;$par!push.s %2!;$par!push.s %3!;$par!push.s %4!;$par!", - "push4.s %1 %2 %3 %4!", - #else - "\216\222\335\222\345\222\256\257\222\334\242", - "\2164\222\343\250\334", - #endif - seqsize(4,4) - seqsize(1,4) - }, - { - #ifdef SCPACK - "push.s %1!;$par!push.s %2!;$par!push.s %3!;$par!", - "push3.s %1 %2 %3!", - #else - "\216\222\335\222\345\222\256\242", - "\2163\222\343\256", - #endif - seqsize(3,3) - seqsize(1,3) - }, - { - #ifdef SCPACK - "push.s %1!;$par!push.s %2!;$par!", - "push2.s %1 %2!", - #else - "\216\222\335\222\221\242", - "\2162\222\331", - #endif - seqsize(2,2) - seqsize(1,2) - }, - /* ----- */ - { - #ifdef SCPACK - "push.adr %1!;$par!push.adr %2!;$par!push.adr %3!;$par!push.adr %4!;$par!push.adr %5!;$par!", - "push5.adr %1 %2 %3 %4 %5!", - #else - "\216\325\335\325\345\325\256\257\325\334\257\325\2035!\242", - "\2165\325\343\250\302\2035!", - #endif - seqsize(5,5) - seqsize(1,5) - }, - { - #ifdef SCPACK - "push.adr %1!;$par!push.adr %2!;$par!push.adr %3!;$par!push.adr %4!;$par!", - "push4.adr %1 %2 %3 %4!", - #else - "\216\325\335\325\345\325\256\257\325\334\242", - "\2164\325\343\250\334", - #endif - seqsize(4,4) - seqsize(1,4) - }, - { - #ifdef SCPACK - "push.adr %1!;$par!push.adr %2!;$par!push.adr %3!;$par!", - "push3.adr %1 %2 %3!", - #else - "\216\325\335\325\345\325\256\242", - "\2163\325\343\256", - #endif - seqsize(3,3) - seqsize(1,3) - }, - { - #ifdef SCPACK - "push.adr %1!;$par!push.adr %2!;$par!", - "push2.adr %1 %2!", - #else - "\216\325\335\325\221\242", - "\2162\325\331", - #endif - seqsize(2,2) - seqsize(1,2) - }, - /* Loading two registers at a time - * load.pri n1 load.both n1 n2 - * load.alt n2 - - * -------------------------------------- - * load.alt n2 load.both n1 n2 - * load.pri n1 - - * -------------------------------------- - * load.s.pri n1 load.s.both n1 n2 - * load.s.alt n2 - - * -------------------------------------- - * load.s.alt n2 load.s.both n1 n2 - * load.s.pri n1 - - */ - { - #ifdef SCPACK - "load.pri %1!load.alt %2!", - "load.both %1 %2!", - #else - "\312\366", - "\342\275th\331", - #endif - seqsize(2,2) - seqsize(1,2) - }, - { - #ifdef SCPACK - "load.alt %2!load.pri %1!", - "load.both %1 %2!", - #else - "\366\312", - "\342\275th\331", - #endif - seqsize(2,2) - seqsize(1,2) - }, - { - #ifdef SCPACK - "load.s.pri %1!load.s.alt %2!", - "load.s.both %1 %2!", - #else - "\332\226\305", - "\226.\275th\331", - #endif - seqsize(2,2) - seqsize(1,2) - }, - { - #ifdef SCPACK - "load.s.alt %2!load.s.pri %1!", - "load.s.both %1 %2!", - #else - "\226\305\332", - "\226.\275th\331", - #endif - seqsize(2,2) - seqsize(1,2) - }, - /* Loading two registers and then pushing them occurs with user operators - * load.both n1 n2 push2 n1 n2 - * push.pri - - * push.alt - - * -------------------------------------- - * load.s.both n1 n2 push2.s n1 n2 - * push.pri - - * push.alt - - */ - { - #ifdef SCPACK - "load.both %1 %2!push.pri!push.alt!", - "push2 %1 %2!", - #else - "\342\275th\331\247\356", - "\2162\331", - #endif - seqsize(3,2) - seqsize(1,2) - }, - { - #ifdef SCPACK - "load.s.both %1 %2!push.pri!push.alt!", - "push2.s %1 %2!", - #else - "\226.\275th\331\247\356", - "\2162\222\331", - #endif - seqsize(3,2) - seqsize(1,2) - }, - /* Load a constant in a variable - * const.pri n1 const n2 n1 - * stor.pri n2 - - * -------------------------------------- - * const.pri n1 const.s n2 n1 - * stor.s.pri n2 - - */ - { - #ifdef SCPACK - "const.pri %1!stor.pri %2!", - "const %2 %1!", - #else - "\327\227or\230", - "\234\220\202", - #endif - seqsize(2,2) - seqsize(1,2) - }, - { - #ifdef SCPACK - "const.pri %1!stor.s.pri %2!", - "const.s %2 %1!", - #else - "\327\227or\222\230", - "\234\222\220\202", - #endif - seqsize(2,2) - seqsize(1,2) - }, - /* ----- */ - { NULL, NULL, 0 } -}; +/* Pawn compiler - Peephole optimizer "sequences" strings (plain + * and compressed formats) + * + * Copyright (c) ITB CompuPhase, 2000-2006 + * + * This software is provided "as-is", without any express or implied warranty. + * In no event will the authors be held liable for any damages arising from + * the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software in + * a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + * Version: $Id: sc7.sch 3662 2006-11-07 08:44:33Z thiadmer $ + */ + +SC_FUNC int strexpand(char *dest, unsigned char *source, int maxlen, unsigned char pairtable[128][2]); + +#define SCPACK_TERMINATOR , /* end each section with a comma */ + +#define SCPACK_TABLE sequences_table +/*-*SCPACK start of pair table, do not change or remove this line */ +unsigned char sequences_table[][2] = { + {49,33}, {37,128}, {32,129}, {32,37}, {114,105}, {112,132}, {46,133}, {97,100}, {46,97}, {136,108}, {137,116}, {115,104}, {111,135}, {117,139}, {112,141}, {108,140}, + {131,50}, {144,33}, {46,115}, {59,36}, {138,33}, {134,130}, {143,146}, {115,116}, {134,145}, {114,33}, {110,151}, {111,154}, {99,155}, {112,148}, {135,100}, {134,33}, + {97,153}, {112,160}, {147,161}, {111,157}, {112,163}, {46,99}, {138,130}, {142,159}, {131,51}, {150,152}, {112,33}, {120,170}, {101,171}, {147,172}, {168,33}, {162,142}, + {101,113}, {110,100}, {122,101}, {178,114}, {149,167}, {158,114}, {33,164}, {131,49}, {103,33}, {158,33}, {104,184}, {99,186}, {120,187}, {98,111}, {118,101}, {111,190}, + {109,191}, {130,173}, {131,52}, {115,103}, {115,108}, {138,145}, {180,169}, {192,148}, {108,165}, {166,169}, {143,149}, {115,174}, {117,177}, {204,203}, {139,200}, {189,205}, + {105,100}, {208,120}, {46,135}, {176,33}, {106,179}, {210,114}, {206,134}, {156,149}, {142,165}, {183,145}, {150,149}, {143,152}, {194,33}, {130,175}, {97,177}, {179,111}, + {212,130}, {182,185}, {143,46}, {183,144}, {156,152}, {145,175}, {114,101}, {230,102}, {196,101}, {108,231}, {232,115}, {234,115}, {195,114}, {236,116}, {142,148}, {105,33}, + {156,166}, {176,130}, {214,32}, {242,50}, {156,198}, {181,198}, {143,197}, {181,201}, {108,209}, {46,98}, {243,225}, {106,110}, {237,153}, {223,159}, {143,166} +}; +/*-*SCPACK end of pair table, do not change or remove this line */ + +#define seqsize(o,p) (opcodes(o)+opargs(p)) +typedef struct { + char *find; + char *replace; + int savesize; /* number of bytes saved (in bytecode) */ +} SEQUENCE; +static SEQUENCE sequences_cmp[] = { + /* A very common sequence in four varieties + * load.s.pri n1 load.s.pri n2 + * push.pri load.s.alt n1 + * load.s.pri n2 - + * pop.alt - + * -------------------------------------- + * load.pri n1 load.s.pri n2 + * push.pri load.alt n1 + * load.s.pri n2 - + * pop.alt - + * -------------------------------------- + * load.s.pri n1 load.pri n2 + * push.pri load.s.alt n1 + * load.pri n2 - + * pop.alt - + * -------------------------------------- + * load.pri n1 load.pri n2 + * push.pri load.alt n1 + * load.pri n2 - + * pop.alt - + */ + { + #ifdef SCPACK + "load.s.pri %1!push.pri!load.s.pri %2!pop.alt!", + "load.s.pri %2!load.s.alt %1!", + #else + "\226\306\244", + "\251\226\246", + #endif + seqsize(4,2) - seqsize(2,2) + }, + { + #ifdef SCPACK + "load.pri %1!push.pri!load.s.pri %2!pop.alt!", + "load.s.pri %2!load.alt %1!", + #else + "\217\306\244", + "\251\376", + #endif + seqsize(4,2) - seqsize(2,2) + }, + { + #ifdef SCPACK + "load.s.pri %1!push.pri!load.pri %2!pop.alt!", + "load.pri %2!load.s.alt %1!", + #else + "\226\264\333\244", + "\333\226\246", + #endif + seqsize(4,2) - seqsize(2,2) + }, + { + #ifdef SCPACK + "load.pri %1!push.pri!load.pri %2!pop.alt!", + "load.pri %2!load.alt %1!", + #else + "\217\264\333\244", + "\333\376", + #endif + seqsize(4,2) - seqsize(2,2) + }, + /* (#1#) The above also occurs with "addr.pri" (array + * indexing) as the first line; so that adds 2 cases. + */ + { + #ifdef SCPACK + "addr.pri %1!push.pri!load.s.pri %2!pop.alt!", + "addr.alt %1!load.s.pri %2!", + #else + "\365\244", + "\367", + #endif + seqsize(4,2) - seqsize(2,2) + }, + { + #ifdef SCPACK + "addr.pri %1!push.pri!load.pri %2!pop.alt!", + "addr.alt %1!load.pri %2!", + #else + "\265\264\333\244", + "\265\246\333", + #endif + seqsize(4,2) - seqsize(2,2) + }, + /* And the same sequence with const.pri as either the first + * or the second load instruction: four more cases. + */ + { + #ifdef SCPACK + "const.pri %1!push.pri!load.s.pri %2!pop.alt!", + "load.s.pri %2!const.alt %1!", + #else + "\364\244", + "\251\360", + #endif + seqsize(4,2) - seqsize(2,2) + }, + { + #ifdef SCPACK + "const.pri %1!push.pri!load.pri %2!pop.alt!", + "load.pri %2!const.alt %1!", + #else + "\234\264\333\244", + "\333\360", + #endif + seqsize(4,2) - seqsize(2,2) + }, + { + #ifdef SCPACK + "load.s.pri %1!push.pri!const.pri %2!pop.alt!", + "const.pri %2!load.s.alt %1!", + #else + "\226\264\344\244", + "\344\226\246", + #endif + seqsize(4,2) - seqsize(2,2) + }, + { + #ifdef SCPACK + "load.pri %1!push.pri!const.pri %2!pop.alt!", + "const.pri %2!load.alt %1!", + #else + "\217\264\344\244", + "\344\376", + #endif + seqsize(4,2) - seqsize(2,2) + }, + /* The same as above, but now with "addr.pri" (array + * indexing) on the first line and const.pri on + * the second. + */ + { + #ifdef SCPACK + "addr.pri %1!push.pri!const.pri %2!pop.alt!", + "addr.alt %1!const.pri %2!", + #else + "\265\264\344\244", + "\265\246\344", + #endif + seqsize(4,2) - seqsize(2,2) + }, + { + #ifdef SCPACK + "addr.pri %1!push.pri!zero.pri!pop.alt!", + "addr.alt %1!zero.pri!", + #else + "\265\264\375\244", + "\265\246\375", + #endif + seqsize(4,1) - seqsize(2,1) + }, + /* ??? add references */ + /* Chained relational operators can contain sequences like: + * move.pri load.s.pri n1 + * push.pri - + * load.s.pri n1 - + * pop.alt - + * The above also accurs for "load.pri" and for "const.pri", + * so add another two cases. + */ + { + #ifdef SCPACK + "move.pri!push.pri!load.s.pri %1!pop.alt!", + "load.s.pri %1!", + #else + "\300\237\247\332\244", + "\332", + #endif + seqsize(4,1) - seqsize(1,1) + }, + { + #ifdef SCPACK + "move.pri!push.pri!load.pri %1!pop.alt!", + "load.pri %1!", + #else + "\300\237\247\312\244", + "\312", + #endif + seqsize(4,1) - seqsize(1,1) + }, + { + #ifdef SCPACK + "move.pri!push.pri!const.pri %1!pop.alt!", + "const.pri %1!", + #else + "\300\237\247\327\244", + "\327", + #endif + seqsize(4,1) - seqsize(1,1) + }, + /* More optimizations for chained relational operators; the + * continuation sequences can be simplified if they turn out + * to be termination sequences: + * xchg sless also for sless, sgeq and sleq + * sgrtr pop.alt + * swap.alt and + * and ;$exp + * pop.alt - + * ;$exp - + * -------------------------------------- + * xchg sless also for sless, sgeq and sleq + * sgrtr pop.alt + * swap.alt and + * and jzer n1 + * pop.alt - + * jzer n1 - + * -------------------------------------- + * xchg jsgeq n1 also for sless, sgeq and sleq + * sgrtr ;$exp (occurs for non-chained comparisons) + * jzer n1 - + * ;$exp - + * -------------------------------------- + * xchg sless also for sless, sgeq and sleq + * sgrtr ;$exp (occurs for non-chained comparisons) + * ;$exp - + */ + { + #ifdef SCPACK + "xchg!sgrtr!swap.alt!and!pop.alt!;$exp!", + "sless!pop.alt!and!;$exp!", + #else + "\274\374swa\235\336\266\255", + "\353\266\336!\255", + #endif + seqsize(5,0) - seqsize(3,0) + }, + { + #ifdef SCPACK + "xchg!sless!swap.alt!and!pop.alt!;$exp!", + "sgrtr!pop.alt!and!;$exp!", + #else + "\274\353!swa\235\336\266\255", + "\374\244\336!\255", + #endif + seqsize(5,0) - seqsize(3,0) + }, + { + #ifdef SCPACK + "xchg!sgeq!swap.alt!and!pop.alt!;$exp!", + "sleq!pop.alt!and!;$exp!", + #else + "\274\303\323swa\235\336\266\255", + "\304\260\266\336!\255", + #endif + seqsize(5,0) - seqsize(3,0) + }, + { + #ifdef SCPACK + "xchg!sleq!swap.alt!and!pop.alt!;$exp!", + "sgeq!pop.alt!and!;$exp!", + #else + "\274\304\323swa\235\336\266\255", + "\303\260\266\336!\255", + #endif + seqsize(5,0) - seqsize(3,0) + }, + { + #ifdef SCPACK + "xchg!sgrtr!swap.alt!and!pop.alt!jzer %1!", + "sless!pop.alt!and!jzer %1!", + #else + "\274\374swa\235\336\266\340", + "\353\266\336!\340", + #endif + seqsize(5,0) - seqsize(3,0) + }, + { + #ifdef SCPACK + "xchg!sless!swap.alt!and!pop.alt!jzer %1!", + "sgrtr!pop.alt!and!jzer %1!", + #else + "\274\353!swa\235\336\266\340", + "\374\244\336!\340", + #endif + seqsize(5,0) - seqsize(3,0) + }, + { + #ifdef SCPACK + "xchg!sgeq!swap.alt!and!pop.alt!jzer %1!", + "sleq!pop.alt!and!jzer %1!", + #else + "\274\303\323swa\235\336\266\340", + "\304\260\266\336!\340", + #endif + seqsize(5,0) - seqsize(3,0) + }, + { + #ifdef SCPACK + "xchg!sleq!swap.alt!and!pop.alt!jzer %1!", + "sgeq!pop.alt!and!jzer %1!", + #else + "\274\304\323swa\235\336\266\340", + "\303\260\266\336!\340", + #endif + seqsize(5,0) - seqsize(3,0) + }, + { + #ifdef SCPACK + "xchg!sgrtr!jzer %1!;$exp!", + "jsgeq %1!;$exp!", + #else + "\274\374\324\301", + "j\303\260\301", + #endif + seqsize(3,1) - seqsize(1,1) + }, + { + #ifdef SCPACK + "xchg!sless!jzer %1!;$exp!", + "jsleq %1!;$exp!", + #else + "\274\353!\324\301", + "j\304\260\301", + #endif + seqsize(3,1) - seqsize(1,1) + }, + { + #ifdef SCPACK + "xchg!sgeq!jzer %1!;$exp!", + "jsgrtr %1!;$exp!", + #else + "\274\303\323\324\301", + "j\355r\301", + #endif + seqsize(3,1) - seqsize(1,1) + }, + { + #ifdef SCPACK + "xchg!sleq!jzer %1!;$exp!", + "jsless %1!;$exp!", + #else + "\274\304\323\324\301", + "j\353\301", + #endif + seqsize(3,1) - seqsize(1,1) + }, + { + #ifdef SCPACK + "xchg!sgrtr!;$exp!", + "sless!;$exp!", + #else + "\274\374\255", + "\353!\255", + #endif + seqsize(2,0) - seqsize(1,0) + }, + { + #ifdef SCPACK + "xchg!sless!;$exp!", + "sgrtr!;$exp!", + #else + "\274\353!\255", + "\374\255", + #endif + seqsize(2,0) - seqsize(1,0) + }, + { + #ifdef SCPACK + "xchg!sgeq!;$exp!", + "sleq!;$exp!", + #else + "\274\303\323\255", + "\304\323\255", + #endif + seqsize(2,0) - seqsize(1,0) + }, + { + #ifdef SCPACK + "xchg!sleq!;$exp!", + "sgeq!;$exp!", + #else + "\274\304\323\255", + "\303\323\255", + #endif + seqsize(2,0) - seqsize(1,0) + }, + /* The entry to chained operators is also opt to optimization + * load.s.pri n1 load.s.pri n2 + * load.s.alt n2 load.s.alt n1 + * xchg - + * -------------------------------------- + * load.s.pri n1 load.pri n2 + * load.alt n2 load.s.alt n1 + * xchg - + * -------------------------------------- + * load.s.pri n1 const.pri n2 + * const.alt n2 load.s.alt n1 + * xchg - + * -------------------------------------- + * and all permutations... + */ + { + #ifdef SCPACK + "load.s.pri %1!load.s.alt %2!xchg!", + "load.s.pri %2!load.s.alt %1!", + #else + "\332\226\305\274", + "\251\226\246", + #endif + seqsize(3,2) - seqsize(2,2) + }, + { + #ifdef SCPACK + "load.s.pri %1!load.alt %2!xchg!", + "load.pri %2!load.s.alt %1!", + #else + "\332\366\274", + "\333\226\246", + #endif + seqsize(3,2) - seqsize(2,2) + }, + { + #ifdef SCPACK + "load.s.pri %1!const.alt %2!xchg!", + "const.pri %2!load.s.alt %1!", + #else + "\332\234\305\274", + "\344\226\246", + #endif + seqsize(3,2) - seqsize(2,2) + }, + { + #ifdef SCPACK + "load.pri %1!load.s.alt %2!xchg!", + "load.s.pri %2!load.alt %1!", + #else + "\312\226\305\274", + "\251\376", + #endif + seqsize(3,2) - seqsize(2,2) + }, + { + #ifdef SCPACK + "load.pri %1!load.alt %2!xchg!", + "load.pri %2!load.alt %1!", + #else + "\312\366\274", + "\333\376", + #endif + seqsize(3,2) - seqsize(2,2) + }, + { + #ifdef SCPACK + "load.pri %1!const.alt %2!xchg!", + "const.pri %2!load.alt %1!", + #else + "\312\234\305\274", + "\344\376", + #endif + seqsize(3,2) - seqsize(2,2) + }, + { + #ifdef SCPACK + "const.pri %1!load.s.alt %2!xchg!", + "load.s.pri %2!const.alt %1!", + #else + "\327\226\305\274", + "\251\360", + #endif + seqsize(3,2) - seqsize(2,2) + }, + { + #ifdef SCPACK + "const.pri %1!load.alt %2!xchg!", + "load.pri %2!const.alt %1!", + #else + "\327\366\274", + "\333\360", + #endif + seqsize(3,2) - seqsize(2,2) + }, + /* some sequences where PRI is moved to ALT can be optimized + * further when considering what follows + * move.alt const.alt n1 + * const.pri %1 - + * xchg - + * (also for load.s.pri and load.pri) + * -------------------------------------- + * lref.pri %1 lref.alt %1 + * move.alt [load.pri %2] + * [load.pri %2] - + * (where [load.pri %2] may also be another operatrion loading PRI) + */ + { + #ifdef SCPACK + "move.alt!const.pri %1!xchg!", + "const.alt %1!", + #else + "\307\327\274", + "\360", + #endif + seqsize(3,1) - seqsize(1,1) + }, + { + #ifdef SCPACK + "move.alt!load.pri %1!xchg!", + "load.alt %1!", + #else + "\307\312\274", + "\376", + #endif + seqsize(3,1) - seqsize(1,1) + }, + { + #ifdef SCPACK + "move.alt!load.s.pri %1!xchg!", + "load.s.alt %1!", + #else + "\307\332\274", + "\226\246", + #endif + seqsize(3,1) - seqsize(1,1) + }, + /* ----- */ + { + #ifdef SCPACK + "lref.pri %1!move.alt!load.pri %2!", + "lref.alt %1!load.pri %2!", + #else + "\351\225\307\333", + "\351\246\333", + #endif + seqsize(3,2) - seqsize(2,2) + }, + { + #ifdef SCPACK + "lref.pri %1!move.alt!load.s.pri %2!", + "lref.alt %1!load.s.pri %2!", + #else + "\351\225\307\251", + "\351\311", + #endif + seqsize(3,2) - seqsize(2,2) + }, + { + #ifdef SCPACK + "lref.pri %1!move.alt!const.pri %2!", + "lref.alt %1!const.pri %2!", + #else + "\351\225\307\344", + "\351\246\344", + #endif + seqsize(3,2) - seqsize(2,2) + }, + { + #ifdef SCPACK + "lref.s.pri %1!move.alt!load.pri %2!", + "lref.s.alt %1!load.pri %2!", + #else + "\351\222\225\307\333", + "\351\222\246\333", + #endif + seqsize(3,2) - seqsize(2,2) + }, + { + #ifdef SCPACK + "lref.s.pri %1!move.alt!load.s.pri %2!", + "lref.s.alt %1!load.s.pri %2!", + #else + "\351\222\225\307\251", + "\351\222\311", + #endif + seqsize(3,2) - seqsize(2,2) + }, + { + #ifdef SCPACK + "lref.s.pri %1!move.alt!const.pri %2!", + "lref.s.alt %1!const.pri %2!", + #else + "\351\222\225\307\344", + "\351\222\246\344", + #endif + seqsize(3,2) - seqsize(2,2) + }, + /* Array indexing can merit from special instructions. + * Simple indexed array lookup can be optimized quite + * a bit. + * addr.pri n1 addr.alt n1 + * push.pri load.s.pri n2 + * load.s.pri n2 bounds n3 + * bounds n3 lidx.b n4 + * shl.c.pri n4 - + * pop.alt - + * add - + * load.i - + * + * And to prepare for storing a value in an array + * addr.pri n1 addr.alt n1 + * push.pri load.s.pri n2 + * load.s.pri n2 bounds n3 + * bounds n3 idxaddr.b n4 + * shl.c.pri n4 - + * pop.alt - + * add - + * + * Notes (additional cases): + * 1. instruction addr.pri can also be const.pri (for + * global arrays) + * 2. the bounds instruction can be absent + * 3. when "n4" (the shift value) is the 2 (with 32-bit cells), use the + * even more optimal instructions LIDX and IDDXADDR + * + * If the array index is more complex, one can only optimize + * the last four instructions: + * shl.c.pri n1 pop.alt + * pop.alt lidx.b n1 + * add - + * loadi - + * -------------------------------------- + * shl.c.pri n1 pop.alt + * pop.alt idxaddr.b n1 + * add - + */ +#if !defined BIT16 + /* loading from array, "cell" shifted */ + { + #ifdef SCPACK + "addr.pri %1!push.pri!load.s.pri %2!bounds %3!shl.c.pri 2!pop.alt!add!load.i!", + "addr.alt %1!load.s.pri %2!bounds %3!lidx!", + #else + "\365\317\372\342\357", + "\367\317\370!", + #endif + seqsize(8,4) - seqsize(4,3) + }, + { + #ifdef SCPACK + "const.pri %1!push.pri!load.s.pri %2!bounds %3!shl.c.pri 2!pop.alt!add!load.i!", + "const.alt %1!load.s.pri %2!bounds %3!lidx!", + #else + "\364\317\372\342\357", + "\234\311\317\370!", + #endif + seqsize(8,4) - seqsize(4,3) + }, + { + #ifdef SCPACK + "addr.pri %1!push.pri!load.s.pri %2!shl.c.pri 2!pop.alt!add!load.i!", + "addr.alt %1!load.s.pri %2!lidx!", + #else + "\365\372\342\357", + "\367\370!", + #endif + seqsize(7,3) - seqsize(3,2) + }, + { + #ifdef SCPACK + "const.pri %1!push.pri!load.s.pri %2!shl.c.pri 2!pop.alt!add!load.i!", + "const.alt %1!load.s.pri %2!lidx!", + #else + "\364\372\342\357", + "\234\311\370!", + #endif + seqsize(7,3) - seqsize(3,2) + }, +#endif + /* loading from array, not "cell" shifted */ + { + #ifdef SCPACK + "addr.pri %1!push.pri!load.s.pri %2!bounds %3!shl.c.pri %4!pop.alt!add!load.i!", + "addr.alt %1!load.s.pri %2!bounds %3!lidx.b %4!", + #else + "\365\317\326\302\341\342\357", + "\367\317\370\371\334", + #endif + seqsize(8,4) - seqsize(4,4) + }, + { + #ifdef SCPACK + "const.pri %1!push.pri!load.s.pri %2!bounds %3!shl.c.pri %4!pop.alt!add!load.i!", + "const.alt %1!load.s.pri %2!bounds %3!lidx.b %4!", + #else + "\364\317\326\302\341\342\357", + "\234\311\317\370\371\334", + #endif + seqsize(8,4) - seqsize(4,4) + }, + { + #ifdef SCPACK + "addr.pri %1!push.pri!load.s.pri %2!shl.c.pri %3!pop.alt!add!load.i!", + "addr.alt %1!load.s.pri %2!lidx.b %3!", + #else + "\365\326\256\244\271\342\357", + "\367\370\371\256", + #endif + seqsize(7,3) - seqsize(3,3) + }, + { + #ifdef SCPACK + "const.pri %1!push.pri!load.s.pri %2!shl.c.pri %3!pop.alt!add!load.i!", + "const.alt %1!load.s.pri %2!lidx.b %3!", + #else + "\364\326\256\244\271\342\357", + "\234\311\370\371\256", + #endif + seqsize(7,3) - seqsize(3,3) + }, +#if !defined BIT16 + /* array index calculation for storing a value, "cell" aligned */ + { + #ifdef SCPACK + "addr.pri %1!push.pri!load.s.pri %2!bounds %3!shl.c.pri 2!pop.alt!add!", + "addr.alt %1!load.s.pri %2!bounds %3!idxaddr!", + #else + "\365\317\372", + "\367\317\321\236\231", + #endif + seqsize(7,4) - seqsize(4,3) + }, + { + #ifdef SCPACK + "const.pri %1!push.pri!load.s.pri %2!bounds %3!shl.c.pri 2!pop.alt!add!", + "const.alt %1!load.s.pri %2!bounds %3!idxaddr!", + #else + "\364\317\372", + "\234\311\317\321\236\231", + #endif + seqsize(7,4) - seqsize(4,3) + }, + { + #ifdef SCPACK + "addr.pri %1!push.pri!load.s.pri %2!shl.c.pri 2!pop.alt!add!", + "addr.alt %1!load.s.pri %2!idxaddr!", + #else + "\365\372", + "\367\321\236\231", + #endif + seqsize(6,3) - seqsize(3,2) + }, + { + #ifdef SCPACK + "const.pri %1!push.pri!load.s.pri %2!shl.c.pri 2!pop.alt!add!", + "const.alt %1!load.s.pri %2!idxaddr!", + #else + "\364\372", + "\234\311\321\236\231", + #endif + seqsize(6,3) - seqsize(3,2) + }, +#endif + /* array index calculation for storing a value, not "cell" packed */ + { + #ifdef SCPACK + "addr.pri %1!push.pri!load.s.pri %2!bounds %3!shl.c.pri %4!pop.alt!add!", + "addr.alt %1!load.s.pri %2!bounds %3!idxaddr.b %4!", + #else + "\365\317\326\302\341", + "\367\317\321\265\371\334", + #endif + seqsize(7,4) - seqsize(4,4) + }, + { + #ifdef SCPACK + "const.pri %1!push.pri!load.s.pri %2!bounds %3!shl.c.pri %4!pop.alt!add!", + "const.alt %1!load.s.pri %2!bounds %3!idxaddr.b %4!", + #else + "\364\317\326\302\341", + "\234\311\317\321\265\371\334", + #endif + seqsize(7,4) - seqsize(4,4) + }, + { + #ifdef SCPACK + "addr.pri %1!push.pri!load.s.pri %2!shl.c.pri %3!pop.alt!add!", + "addr.alt %1!load.s.pri %2!idxaddr.b %3!", + #else + "\365\326\256\244\271", + "\367\321\265\371\256", + #endif + seqsize(6,3) - seqsize(3,3) + }, + { + #ifdef SCPACK + "const.pri %1!push.pri!load.s.pri %2!shl.c.pri %3!pop.alt!add!", + "const.alt %1!load.s.pri %2!idxaddr.b %3!", + #else + "\364\326\256\244\271", + "\234\311\321\265\371\256", + #endif + seqsize(6,3) - seqsize(3,3) + }, +#if !defined BIT16 + /* the shorter array indexing sequences, see above for comments */ + { + #ifdef SCPACK + "shl.c.pri 2!pop.alt!add!loadi!", + "pop.alt!lidx!", + #else + "\372\217\357", + "\244\370!", + #endif + seqsize(4,1) - seqsize(2,0) + }, + { + #ifdef SCPACK + "shl.c.pri 2!pop.alt!add!", + "pop.alt!idxaddr!", + #else + "\372", + "\244\321\236\231", + #endif + seqsize(3,1) - seqsize(2,0) + }, +#endif + { + #ifdef SCPACK + "shl.c.pri %1!pop.alt!add!loadi!", + "pop.alt!lidx.b %1!", + #else + "\316\225\244\271\217\357", + "\244\370\371\202", + #endif + seqsize(4,1) - seqsize(2,1) + }, + { + #ifdef SCPACK + "shl.c.pri %1!pop.alt!add!", + "pop.alt!idxaddr.b %1!", + #else + "\316\225\244\271", + "\244\321\265\371\202", + #endif + seqsize(3,1) - seqsize(2,1) + }, + /* For packed arrays, there is another case (packed arrays + * do not take advantage of the LIDX or IDXADDR instructions). + * addr.pri n1 addr.alt n1 + * push.pri load.s.pri n2 + * load.s.pri n2 bounds n3 + * bounds n3 - + * pop.alt - + * + * Notes (additional cases): + * 1. instruction addr.pri can also be const.pri (for + * global arrays) + * 2. the bounds instruction can be absent, but that + * case is already handled (see #1#) + */ + { + #ifdef SCPACK + "addr.pri %1!push.pri!load.s.pri %2!bounds %3!pop.alt!", + "addr.alt %1!load.s.pri %2!bounds %3!", + #else + "\365\317\244", + "\367\317", + #endif + seqsize(5,3) - seqsize(3,3) + }, + { + #ifdef SCPACK + "const.pri %1!push.pri!load.s.pri %2!bounds %3!pop.alt!", + "const.alt %1!load.s.pri %2!bounds %3!", + #else + "\364\317\244", + "\234\311\317", + #endif + seqsize(5,3) - seqsize(3,3) + }, + /* Declaration of simple variables often follows the sequence: + * ;$lcl ;$lcl + * stack -4 push.c + * const.pri ;$exp + * stor.s.pri - + * ;$exp - + */ + { + #ifdef SCPACK + ";$lcl %1 %2!stack -4!const.pri %3!stor.s.pri %2!;$exp!", + ";$lcl %1 %2!push.c %3!;$exp!", + #else + "\223lcl\331\227ack -4!\234\206\256\227or\222\230\255", + "\223lcl\331\330\256\255", + #endif + seqsize(3,3) - seqsize(1,1) + }, + { + #ifdef SCPACK + ";$lcl %1 %2!stack -4!zero.pri!stor.s.pri %2!;$exp!", + ";$lcl %1 %2!push.c 0!;$exp!", + #else + "\223lcl\331\227ack -4!\375\227or\222\230\255", + "\223lcl\331\330 0!\255", + #endif + seqsize(3,2) - seqsize(1,1) + }, + /* During a calculation, the intermediate result must sometimes + * be moved from PRI to ALT, like in: + * push.pri move.alt + * load.s.pri n1 load.s.pri n1 + * pop.alt - + * + * The above also accurs for "load.pri" and for "const.pri", + * so add another two cases. + */ + { + #ifdef SCPACK + "push.pri!load.s.pri %1!pop.alt!", + "move.alt!load.s.pri %1!", + #else + "\247\332\244", + "\307\332", + #endif + seqsize(3,1) - seqsize(2,1) + }, + { + #ifdef SCPACK + "push.pri!load.pri %1!pop.alt!", + "move.alt!load.pri %1!", + #else + "\247\312\244", + "\307\312", + #endif + seqsize(3,1) - seqsize(2,1) + }, + { + #ifdef SCPACK + "push.pri!const.pri %1!pop.alt!", + "move.alt!const.pri %1!", + #else + "\247\327\244", + "\307\327", + #endif + seqsize(3,1) - seqsize(2,1) + }, + { + #ifdef SCPACK + "push.pri!zero.pri!pop.alt!", + "move.alt!zero.pri!", + #else + "\247\375\244", + "\307\375", + #endif + seqsize(3,0) - seqsize(2,0) + }, + /* saving PRI and then loading from its address + * occurs when indexing a multi-dimensional array + */ + { + #ifdef SCPACK + "push.pri!load.i!pop.alt!", + "move.alt!load.i!", + #else + "\247\342i\266", + "\307\342\357", + #endif + seqsize(3,0) - seqsize(2,0) + }, + /* An even simpler PUSH/POP optimization (occurs in + * switch statements): + * push.pri move.alt + * pop.alt - + */ + { + #ifdef SCPACK + "push.pri!pop.alt!", + "move.alt!", + #else + "\247\244", + "\307", + #endif + seqsize(2,0) - seqsize(1,0) + }, + /* Some simple arithmetic sequences + */ + { + #ifdef SCPACK + "move.alt!load.s.pri %1!add!", + "load.s.alt %1!add!", + #else + "\307\332\271", + "\226\246\271", + #endif + seqsize(3,1) - seqsize(2,1) + }, + { + #ifdef SCPACK + "move.alt!load.pri %1!add!", + "load.alt %1!add!", + #else + "\307\312\271", + "\376\271", + #endif + seqsize(3,1) - seqsize(2,1) + }, + { + #ifdef SCPACK + "move.alt!const.pri %1!add!", + "const.alt %1!add!", + #else + "\307\327\271", + "\360\271", + #endif + seqsize(3,1) - seqsize(2,1) + }, + { + #ifdef SCPACK + "move.alt!load.s.pri %1!sub.alt!", + "load.s.alt %1!sub!", + #else + "\307\332sub\224", + "\226\246sub!", + #endif + seqsize(3,1) - seqsize(2,1) + }, + { + #ifdef SCPACK + "move.alt!load.pri %1!sub.alt!", + "load.alt %1!sub!", + #else + "\307\312sub\224", + "\376sub!", + #endif + seqsize(3,1) - seqsize(2,1) + }, + { + #ifdef SCPACK + "move.alt!const.pri %1!sub.alt!", + "const.alt %1!sub!", + #else + "\307\327sub\224", + "\360sub!", + #endif + seqsize(3,1) - seqsize(2,1) + }, + /* User-defined operators first load the operands into registers and + * then have them pushed onto the stack. This can give rise to sequences + * like: + * const.pri n1 push.c n1 + * const.alt n2 push.c n2 + * push.pri - + * push.alt - + * A similar sequence occurs with the two PUSH.pri/alt instructions inverted. + * The first, second, or both CONST.pri/alt instructions can also be + * LOAD.pri/alt. + * This gives 2 x 4 cases. + */ + { + #ifdef SCPACK + "const.pri %1!const.alt %2!push.pri!push.alt!", + "push.c %1!push.c %2!", + #else + "\327\234\305\247\356", + "\330\202\330\221", + #endif + seqsize(4,2) - seqsize(2,2) + }, + { + #ifdef SCPACK + "const.pri %1!const.alt %2!push.alt!push.pri!", + "push.c %2!push.c %1!", + #else + "\327\234\305\356\247", + "\330\221\330\202", + #endif + seqsize(4,2) - seqsize(2,2) + }, + { + #ifdef SCPACK + "const.pri %1!load.alt %2!push.pri!push.alt!", + "push.c %1!push %2!", + #else + "\327\366\247\356", + "\330\202\216\221", + #endif + seqsize(4,2) - seqsize(2,2) + }, + { + #ifdef SCPACK + "const.pri %1!load.alt %2!push.alt!push.pri!", + "push %2!push.c %1!", + #else + "\327\366\356\247", + "\216\221\330\202", + #endif + seqsize(4,2) - seqsize(2,2) + }, + { + #ifdef SCPACK + "load.pri %1!const.alt %2!push.pri!push.alt!", + "push %1!push.c %2!", + #else + "\312\234\305\247\356", + "\216\202\330\221", + #endif + seqsize(4,2) - seqsize(2,2) + }, + { + #ifdef SCPACK + "load.pri %1!const.alt %2!push.alt!push.pri!", + "push.c %2!push %1!", + #else + "\312\234\305\356\247", + "\330\221\216\202", + #endif + seqsize(4,2) - seqsize(2,2) + }, + { + #ifdef SCPACK + "load.pri %1!load.alt %2!push.pri!push.alt!", + "push %1!push %2!", + #else + "\312\366\247\356", + "\216\202\216\221", + #endif + seqsize(4,2) - seqsize(2,2) + }, + { + #ifdef SCPACK + "load.pri %1!load.alt %2!push.alt!push.pri!", + "push %2!push %1!", + #else + "\312\366\356\247", + "\216\221\216\202", + #endif + seqsize(4,2) - seqsize(2,2) + }, + /* Function calls (parameters are passed on the stack) + * load.s.pri n1 push.s n1 + * push.pri - + * -------------------------------------- + * load.pri n1 push n1 + * push.pri - + * -------------------------------------- + * const.pri n1 push.c n1 + * push.pri - + * -------------------------------------- + * zero.pri push.c 0 + * push.pri - + * -------------------------------------- + * addr.pri n1 push.adr n1 + * push.pri - + * + * However, PRI must not be needed after this instruction + * if this shortcut is used. Check for the ;$par comment. + */ + { + #ifdef SCPACK + "load.s.pri %1!push.pri!;$par!", + "push.s %1!;$par!", + #else + "\226\264\242", + "\216\222\202\242", + #endif + seqsize(2,1) - seqsize(1,1) + }, + { + #ifdef SCPACK + "load.pri %1!push.pri!;$par!", + "push %1!;$par!", + #else + "\217\264\242", + "\216\202\242", + #endif + seqsize(2,1) - seqsize(1,1) + }, + { + #ifdef SCPACK + "const.pri %1!push.pri!;$par!", + "push.c %1!;$par!", + #else + "\234\264\242", + "\330\202\242", + #endif + seqsize(2,1) - seqsize(1,1) + }, + { + #ifdef SCPACK + "zero.pri!push.pri!;$par!", + "push.c 0!;$par!", + #else + "\375\247\242", + "\330 0!\242", + #endif + seqsize(2,0) - seqsize(1,1) + }, + { + #ifdef SCPACK + "addr.pri %1!push.pri!;$par!", + "push.adr %1!;$par!", + #else + "\265\264\242", + "\216\325\202\242", + #endif + seqsize(2,1) - seqsize(1,1) + }, + /* References with a default value generate new cells on the heap + * dynamically. That code often ends with: + * move.pri push.alt + * push.pri - + */ + { + #ifdef SCPACK + "move.pri!push.pri!", + "push.alt!", + #else + "\300\237\247", + "\356", + #endif + seqsize(2,0) - seqsize(1,0) + }, + /* Simple arithmetic operations on constants. Noteworthy is the + * subtraction of a constant, since it is converted to the addition + * of the inverse value. + * const.alt n1 add.c n1 + * add - + * -------------------------------------- + * const.alt n1 add.c -n1 + * sub - + * -------------------------------------- + * const.alt n1 smul.c n1 + * smul - + * -------------------------------------- + * const.alt n1 eq.c.pri n1 + * eq - + */ + { + #ifdef SCPACK + "const.alt %1!add!", + "add.c %1!", + #else + "\360\271", + "\236\245\202", + #endif + seqsize(2,1) - seqsize(1,1) + }, + { + #ifdef SCPACK + "const.alt %1!sub!", + "add.c -%1!", + #else + "\360sub!", + "\236\245 -\201", + #endif + seqsize(2,1) - seqsize(1,1) + }, + { + #ifdef SCPACK + "const.alt %1!smul!", + "smul.c %1!", + #else + "\360smul!", + "smu\310\202", + #endif + seqsize(2,1) - seqsize(1,1) + }, + { + #ifdef SCPACK + "const.alt %1!eq!", + "eq.c.pri %1!", + #else + "\360\323", + "\260\245\225", + #endif + seqsize(2,1) - seqsize(1,1) + }, + /* Some operations use the alternative subtraction operation --these + * can also be optimized. + * const.pri n1 load.s.pri n2 + * load.s.alt n2 add.c -n1 + * sub.alt - + * -------------------------------------- + * const.pri n1 load.pri n2 + * load.alt n2 add.c -n1 + * sub.alt - + */ + { + #ifdef SCPACK + "const.pri %1!load.s.alt %2!sub.alt!", + "load.s.pri %2!add.c -%1!", + #else + "\327\226\305sub\224", + "\251\236\245 -\201", + #endif + seqsize(3,2) - seqsize(2,2) + }, + { + #ifdef SCPACK + "const.pri %1!load.alt %2!sub.alt!", + "load.pri %2!add.c -%1!", + #else + "\327\366sub\224", + "\333\236\245 -\201", + #endif + seqsize(3,2) - seqsize(2,2) + }, + /* With arrays indexed with constants that come from enumerations, it happens + * multiple add.c opcodes follow in sequence. + * add.c n1 add.c n1+n2 + * add.c n2 - + */ + { + #ifdef SCPACK + "add.c %1!add.c %2!", + "add.c %1+%2!", + #else + "\236\245\202\236\245\221", + "\236\245\267+%2!", + #endif + seqsize(2,2) - seqsize(1,1) + }, + /* Compare and jump + * eq jneq n1 + * jzer n1 - + * -------------------------------------- + * eq jeq n1 + * jnz n1 - + * -------------------------------------- + * neq jeq n1 + * jzer n1 - + * -------------------------------------- + * neq jneq n1 + * jnz n1 - + * An similarly for other relations + * sless jsgeq n1 + * jzer n1 - + * -------------------------------------- + * sless jsless n1 + * jnz n1 - + * -------------------------------------- + * sleq jsgrtr n1 + * jzer n1 - + * -------------------------------------- + * sleq jsleq n1 + * jnz n1 - + * -------------------------------------- + * sgrtr jsleq n1 + * jzer n1 - + * -------------------------------------- + * sgrtr jsgrtr n1 + * jnz n1 - + * -------------------------------------- + * sgeq jsless n1 + * jzer n1 - + * -------------------------------------- + * sgeq jsgeq n1 + * jnz n1 - + * We can relax the optimizations for the unsigned comparisons, + * because the Pawn compiler currently only generates signed + * comparisons. + */ + { + #ifdef SCPACK + "eq!jzer %1!", + "jneq %1!", + #else + "\323\340", + "\373\361", + #endif + seqsize(2,1) - seqsize(1,1) + }, + { + #ifdef SCPACK + "eq!jnz %1!", + "jeq %1!", + #else + "\323\373z\202", + "j\361", + #endif + seqsize(2,1) - seqsize(1,1) + }, + { + #ifdef SCPACK + "neq!jzer %1!", + "jeq %1!", + #else + "n\323\340", + "j\361", + #endif + seqsize(2,1) - seqsize(1,1) + }, + { + #ifdef SCPACK + "neq!jnz %1!", + "jneq %1!", + #else + "n\323\373z\202", + "\373\361", + #endif + seqsize(2,1) - seqsize(1,1) + }, + { + #ifdef SCPACK + "sless!jzer %1!", + "jsgeq %1!", + #else + "\353!\340", + "j\303\361", + #endif + seqsize(2,1) - seqsize(1,1) + }, + { + #ifdef SCPACK + "sless!jnz %1!", + "jsless %1!", + #else + "\353!\373z\202", + "j\353\202", + #endif + seqsize(2,1) - seqsize(1,1) + }, + { + #ifdef SCPACK + "sleq!jzer %1!", + "jsgrtr %1!", + #else + "\304\323\340", + "j\355r\202", + #endif + seqsize(2,1) - seqsize(1,1) + }, + { + #ifdef SCPACK + "sleq!jnz %1!", + "jsleq %1!", + #else + "\304\323\373z\202", + "j\304\361", + #endif + seqsize(2,1) - seqsize(1,1) + }, + { + #ifdef SCPACK + "sgrtr!jzer %1!", + "jsleq %1!", + #else + "\374\340", + "j\304\361", + #endif + seqsize(2,1) - seqsize(1,1) + }, + { + #ifdef SCPACK + "sgrtr!jnz %1!", + "jsgrtr %1!", + #else + "\374\373z\202", + "j\355r\202", + #endif + seqsize(2,1) - seqsize(1,1) + }, + { + #ifdef SCPACK + "sgeq!jzer %1!", + "jsless %1!", + #else + "\303\323\340", + "j\353\202", + #endif + seqsize(2,1) - seqsize(1,1) + }, + { + #ifdef SCPACK + "sgeq!jnz %1!", + "jsgeq %1!", + #else + "\303\323\373z\202", + "j\303\361", + #endif + seqsize(2,1) - seqsize(1,1) + }, + /* Test for zero (common case, especially for strings) + * E.g. the test expression of: "for (i=0; str{i}!=0; ++i)" + * + * zero.alt jzer n1 + * jeq n1 - + * -------------------------------------- + * zero.alt jnz n1 + * jneq n1 - + */ + { + #ifdef SCPACK + "zero.alt!jeq %1!", + "jzer %1!", + #else + "\337\224j\361", + "\340", + #endif + seqsize(2,1) - seqsize(1,1) + }, + { + #ifdef SCPACK + "zero.alt!jneq %1!", + "jnz %1!", + #else + "\337\224\373\361", + "\373z\202", + #endif + seqsize(2,1) - seqsize(1,1) + }, + /* Incrementing and decrementing leaves a value in + * in PRI which may not be used (for example, as the + * third expression in a "for" loop). + * inc n1 inc n1 ; ++n + * load.pri n1 ;$exp + * ;$exp - + * -------------------------------------- + * load.pri n1 inc n1 ; n++, e.g. "for (n=0; n<10; n++)" + * inc n1 ;$exp + * ;$exp - + * Plus the varieties for stack relative increments + * and decrements. + */ + { + #ifdef SCPACK + "inc %1!load.pri %1!;$exp!", + "inc %1!;$exp!", + #else + "inc\202\312\255", + "inc\301", + #endif + seqsize(2,2) - seqsize(1,1) + }, + { + #ifdef SCPACK + "load.pri %1!inc %1!;$exp!", + "inc %1!;$exp!", + #else + "\312inc\301", + "inc\301", + #endif + seqsize(2,2) - seqsize(1,1) + }, + { + #ifdef SCPACK + "inc.s %1!load.s.pri %1!;$exp!", + "inc.s %1!;$exp!", + #else + "inc\222\202\332\255", + "inc\222\301", + #endif + seqsize(2,2) - seqsize(1,1) + }, + { + #ifdef SCPACK + "load.s.pri %1!inc.s %1!;$exp!", + "inc.s %1!;$exp!", + #else + "\332inc\222\301", + "inc\222\301", + #endif + seqsize(2,2) - seqsize(1,1) + }, + { + #ifdef SCPACK + "dec %1!load.pri %1!;$exp!", + "dec %1!;$exp!", + #else + "dec\202\312\255", + "dec\301", + #endif + seqsize(2,2) - seqsize(1,1) + }, + { + #ifdef SCPACK + "load.pri %1!dec %1!;$exp!", + "dec %1!;$exp!", + #else + "\312dec\301", + "dec\301", + #endif + seqsize(2,2) - seqsize(1,1) + }, + { + #ifdef SCPACK + "dec.s %1!load.s.pri %1!;$exp!", + "dec.s %1!;$exp!", + #else + "dec\222\202\332\255", + "dec\222\301", + #endif + seqsize(2,2) - seqsize(1,1) + }, + { + #ifdef SCPACK + "load.s.pri %1!dec.s %1!;$exp!", + "dec.s %1!;$exp!", + #else + "\332dec\222\301", + "dec\222\301", + #endif + seqsize(2,2) - seqsize(1,1) + }, + /* ??? the same (increments and decrements) for references */ + /* Loading the constant zero has a special opcode. + * When storing zero in memory, the value of PRI must not be later on. + * const.pri 0 zero n1 + * stor.pri n1 ;$exp + * ;$exp - + * -------------------------------------- + * const.pri 0 zero.s n1 + * stor.s.pri n1 ;$exp + * ;$exp - + * -------------------------------------- + * zero.pri zero n1 + * stor.pri n1 ;$exp + * ;$exp - + * -------------------------------------- + * zero.pri zero.s n1 + * stor.s.pri n1 ;$exp + * ;$exp - + * -------------------------------------- + * const.pri 0 zero.pri + * -------------------------------------- + * const.alt 0 zero.alt + * The last two alternatives save more memory than they save + * time, but anyway... + */ + { + #ifdef SCPACK + "const.pri 0!stor.pri %1!;$exp!", + "zero %1!;$exp!", + #else + "\234\206 0!\227or\225\255", + "\337\301", + #endif + seqsize(2,2) - seqsize(1,1) + }, + { + #ifdef SCPACK + "const.pri 0!stor.s.pri %1!;$exp!", + "zero.s %1!;$exp!", + #else + "\234\206 0!\227or\222\225\255", + "\337\222\301", + #endif + seqsize(2,2) - seqsize(1,1) + }, + { + #ifdef SCPACK + "zero.pri!stor.pri %1!;$exp!", + "zero %1!;$exp!", + #else + "\375\227or\225\255", + "\337\301", + #endif + seqsize(2,1) - seqsize(1,1) + }, + { + #ifdef SCPACK + "zero.pri!stor.s.pri %1!;$exp!", + "zero.s %1!;$exp!", + #else + "\375\227or\222\225\255", + "\337\222\301", + #endif + seqsize(2,1) - seqsize(1,1) + }, + { + #ifdef SCPACK + "const.pri 0!", + "zero.pri!", + #else + "\234\206 0!", + "\375", + #endif + seqsize(1,1) - seqsize(1,0) + }, + { + #ifdef SCPACK + "const.alt 0!", + "zero.alt!", + #else + "\234\212 0!", + "\337\224", + #endif + seqsize(1,1) - seqsize(1,0) + }, + + /* ------------------ */ + /* Macro instructions */ + /* ------------------ */ + + { "", "", 0 }, /* separator, so optimizer can stop before generating macro opcodes */ + + /* optimizing the calling of native functions (which always have a parameter + * count pushed before, and the stack pointer restored afterwards + */ + { + #ifdef SCPACK + "push.c %1!sysreq.c %2!stack %3!", //note: %3 == %1 + 4 + "sysreq.n %2 %1!", + #else + "\330\202sysr\260\245\221\227ack\256", + "sysr\260.n\220\202", + #endif + seqsize(3,3) - seqsize(1,2) + }, + /* ----- */ + /* Functions with many parameters with the same "type" have sequences like: + * push.c n1 push3.c n1 n2 n3 + * ;$par ;$par + * push.c n2 - + * ;$par - + * push.c n3 - + * ;$par - + * etc. etc. + * + * Similar sequences occur with PUSH, PUSH.s and PUSHADDR + */ + { + #ifdef SCPACK + "push.c %1!;$par!push.c %2!;$par!push.c %3!;$par!push.c %4!;$par!push.c %5!;$par!", + "push5.c %1 %2 %3 %4 %5!", + #else + "\330\335\245\345\245\256\257\245\334\257\245\2035!\242", + "\2165\245\343\250\302\2035!", + #endif + seqsize(5,5) - seqsize(1,5) + }, + { + #ifdef SCPACK + "push.c %1!;$par!push.c %2!;$par!push.c %3!;$par!push.c %4!;$par!", + "push4.c %1 %2 %3 %4!", + #else + "\330\335\245\345\245\256\257\245\334\242", + "\2164\245\343\250\334", + #endif + seqsize(4,4) - seqsize(1,4) + }, + { + #ifdef SCPACK + "push.c %1!;$par!push.c %2!;$par!push.c %3!;$par!", + "push3.c %1 %2 %3!", + #else + "\330\335\245\345\245\256\242", + "\2163\245\343\256", + #endif + seqsize(3,3) - seqsize(1,3) + }, + { + #ifdef SCPACK + "push.c %1!;$par!push.c %2!;$par!", + "push2.c %1 %2!", + #else + "\330\335\245\221\242", + "\2162\245\331", + #endif + seqsize(2,2) - seqsize(1,2) + }, + /* ----- */ + { + #ifdef SCPACK + "push %1!;$par!push %2!;$par!push %3!;$par!push %4!;$par!push %5!;$par!", + "push5 %1 %2 %3 %4 %5!", + #else + "\216\335\345\256\257\334\257\2035!\242", + "\2165\343\250\302\2035!", + #endif + seqsize(5,5) - seqsize(1,5) + }, + { + #ifdef SCPACK + "push %1!;$par!push %2!;$par!push %3!;$par!push %4!;$par!", + "push4 %1 %2 %3 %4!", + #else + "\216\335\345\256\257\334\242", + "\2164\343\250\334", + #endif + seqsize(4,4) - seqsize(1,4) + }, + { + #ifdef SCPACK + "push %1!;$par!push %2!;$par!push %3!;$par!", + "push3 %1 %2 %3!", + #else + "\216\335\345\256\242", + "\2163\343\256", + #endif + seqsize(3,3) - seqsize(1,3) + }, + { + #ifdef SCPACK + "push %1!;$par!push %2!;$par!", + "push2 %1 %2!", + #else + "\216\335\221\242", + "\2162\331", + #endif + seqsize(2,2) - seqsize(1,2) + }, + /* ----- */ + { + #ifdef SCPACK + "push.s %1!;$par!push.s %2!;$par!push.s %3!;$par!push.s %4!;$par!push.s %5!;$par!", + "push5.s %1 %2 %3 %4 %5!", + #else + "\216\222\335\222\345\222\256\257\222\334\257\222\2035!\242", + "\2165\222\343\250\302\2035!", + #endif + seqsize(5,5) - seqsize(1,5) + }, + { + #ifdef SCPACK + "push.s %1!;$par!push.s %2!;$par!push.s %3!;$par!push.s %4!;$par!", + "push4.s %1 %2 %3 %4!", + #else + "\216\222\335\222\345\222\256\257\222\334\242", + "\2164\222\343\250\334", + #endif + seqsize(4,4) - seqsize(1,4) + }, + { + #ifdef SCPACK + "push.s %1!;$par!push.s %2!;$par!push.s %3!;$par!", + "push3.s %1 %2 %3!", + #else + "\216\222\335\222\345\222\256\242", + "\2163\222\343\256", + #endif + seqsize(3,3) - seqsize(1,3) + }, + { + #ifdef SCPACK + "push.s %1!;$par!push.s %2!;$par!", + "push2.s %1 %2!", + #else + "\216\222\335\222\221\242", + "\2162\222\331", + #endif + seqsize(2,2) - seqsize(1,2) + }, + /* ----- */ + { + #ifdef SCPACK + "push.adr %1!;$par!push.adr %2!;$par!push.adr %3!;$par!push.adr %4!;$par!push.adr %5!;$par!", + "push5.adr %1 %2 %3 %4 %5!", + #else + "\216\325\335\325\345\325\256\257\325\334\257\325\2035!\242", + "\2165\325\343\250\302\2035!", + #endif + seqsize(5,5) - seqsize(1,5) + }, + { + #ifdef SCPACK + "push.adr %1!;$par!push.adr %2!;$par!push.adr %3!;$par!push.adr %4!;$par!", + "push4.adr %1 %2 %3 %4!", + #else + "\216\325\335\325\345\325\256\257\325\334\242", + "\2164\325\343\250\334", + #endif + seqsize(4,4) - seqsize(1,4) + }, + { + #ifdef SCPACK + "push.adr %1!;$par!push.adr %2!;$par!push.adr %3!;$par!", + "push3.adr %1 %2 %3!", + #else + "\216\325\335\325\345\325\256\242", + "\2163\325\343\256", + #endif + seqsize(3,3) - seqsize(1,3) + }, + { + #ifdef SCPACK + "push.adr %1!;$par!push.adr %2!;$par!", + "push2.adr %1 %2!", + #else + "\216\325\335\325\221\242", + "\2162\325\331", + #endif + seqsize(2,2) - seqsize(1,2) + }, + /* Loading two registers at a time + * load.pri n1 load.both n1 n2 + * load.alt n2 - + * -------------------------------------- + * load.alt n2 load.both n1 n2 + * load.pri n1 - + * -------------------------------------- + * load.s.pri n1 load.s.both n1 n2 + * load.s.alt n2 - + * -------------------------------------- + * load.s.alt n2 load.s.both n1 n2 + * load.s.pri n1 - + */ + { + #ifdef SCPACK + "load.pri %1!load.alt %2!", + "load.both %1 %2!", + #else + "\312\366", + "\342\275th\331", + #endif + seqsize(2,2) - seqsize(1,2) + }, + { + #ifdef SCPACK + "load.alt %2!load.pri %1!", + "load.both %1 %2!", + #else + "\366\312", + "\342\275th\331", + #endif + seqsize(2,2) - seqsize(1,2) + }, + { + #ifdef SCPACK + "load.s.pri %1!load.s.alt %2!", + "load.s.both %1 %2!", + #else + "\332\226\305", + "\226.\275th\331", + #endif + seqsize(2,2) - seqsize(1,2) + }, + { + #ifdef SCPACK + "load.s.alt %2!load.s.pri %1!", + "load.s.both %1 %2!", + #else + "\226\305\332", + "\226.\275th\331", + #endif + seqsize(2,2) - seqsize(1,2) + }, + /* Loading two registers and then pushing them occurs with user operators + * load.both n1 n2 push2 n1 n2 + * push.pri - + * push.alt - + * -------------------------------------- + * load.s.both n1 n2 push2.s n1 n2 + * push.pri - + * push.alt - + */ + { + #ifdef SCPACK + "load.both %1 %2!push.pri!push.alt!", + "push2 %1 %2!", + #else + "\342\275th\331\247\356", + "\2162\331", + #endif + seqsize(3,2) - seqsize(1,2) + }, + { + #ifdef SCPACK + "load.s.both %1 %2!push.pri!push.alt!", + "push2.s %1 %2!", + #else + "\226.\275th\331\247\356", + "\2162\222\331", + #endif + seqsize(3,2) - seqsize(1,2) + }, + /* Load a constant in a variable + * const.pri n1 const n2 n1 + * stor.pri n2 - + * -------------------------------------- + * const.pri n1 const.s n2 n1 + * stor.s.pri n2 - + */ + { + #ifdef SCPACK + "const.pri %1!stor.pri %2!", + "const %2 %1!", + #else + "\327\227or\230", + "\234\220\202", + #endif + seqsize(2,2) - seqsize(1,2) + }, + { + #ifdef SCPACK + "const.pri %1!stor.s.pri %2!", + "const.s %2 %1!", + #else + "\327\227or\222\230", + "\234\222\220\202", + #endif + seqsize(2,2) - seqsize(1,2) + }, + /* ----- */ + { NULL, NULL, 0 } +};