Unimal helper for C-SLang 2.0

What on earth is it?

C-SLang makes a great claim that it is compatible with any ISO/ANSI C compiler.

Unfortunately, standards compliance proves to be an insurmountable challenge to some of the C compiler vendors.


To help the users of those compilers, MacroExpressions makes a Unimal helper available. It is a Unimal include file which you include instead of standard C-SLang headers. The format of C-SLang script definitions changes a little to replace with Unimal macro calls those C-SLang constructs that your compiler won’t understand.

Where do I get it?

You can download ucslang-simple.inc here.

What compilers are known to be compliant or not?

For desktop development, the Microsoft compiler for Win32, cl.exe, will give undeserved warnings but produce the correct result.


For embedded development, the following vendors appear to comply with the standard, at least to the extent of C-SLang needs:


The following vendors fall short of compliance:


Please note that each vendor sells compilers for many target platforms. Since compliance issues relate to the compiler’s front end (which is believed to be mostly common across the vendor’s products), each vendor was tried on one target platform.

How do I know if it is my compiler’s fault or C-SLang’s?

There is a test file, compileme.c. You can establish its correctness by inspection. If your compiler doesn’t compile it successfully, it is not compliant. If it does compile, it should compile C-SLang scripts; if it fails on that, it’s a C-SLang problem: please report it to MacroExpressions at feedback@macroexpressions.com.

How do I use Unimal helper?

The Unimal helper is only needed to make C-SLang scripts digestible by a non-compliant compiler.

A generic format of a script can be understood by converting an example included in the distribution, sample2.c, to the helper format, say, usample2.u:


#MP Include #@ucslang-simple.inc# ;instead of cslpubl.h, csldef.h

#include "sample.h"


/********************** Sample Script *******************/

#MP Expand CSLang_ScriptStart(#@uCharcount#) ;for ScriptStart()

#MP Expand      CSLang_RegStart()            ;for RegStart(




#MP Expand      CSLang_RegEnd()   ;for the ‘)’ of RegStart

/*Count the number of occurences of the first

  character in the input string


#MP Expand  CSLang_Function(#@charcount#) ;for Function


    StoreX(TempVar, 1) /*counter*/

    Call(charhelper) /*a hand-made loop must be a function */

    Move(TempVar, 1, VPIO, 0) /*output the result*/

#MP Expand  CSLang_EndFunction()          ;for EndFunction

/*Illustrates a function wrapper for a loop*/

#MP Expand  CSLang_Function(#@charhelper#) ;for Function

    LoadAI(InpVar, 1) /* InpVar[1+X] loaded */

    Subtract(Literal, 0) /*Check for 0 character*/

    RetZ                 /*return if end*/

    Subtract(InpVar, 0) /*Compare with char*/

    CallZ(increment)     /*Increment if equal*/

    MoveXA               /*Increment index X*/

    Add(Literal, 1)


    Jump(charhelper) /* repeat */

#MP Expand  CSLang_EndFunction()          ;for EndFunction

#MP Expand  CSLang_Function(#@increment#) ;for Function

    LoadA(TempVar, 1) /* increment TempVar 1 */

    Add(Literal, 1)

    StoreA(TempVar, 1)

#MP Expand  CSLang_EndFunction()          ;for EndFunction

#MP Expand  CSLang_ScriptEnd()            ;for EndScript




That is, only the script itself changes (by replacing C-SLang constructs with Unimal macro calls); the rest of the file, such as the definition of the virtual machine, remains unchanged.


To make a C file, say, usample2.c, run the command


unimal usample2.u > usample2.c


(Of course, the file ucslang-simple.inc must be visible; you may need to use -I or -i command-line option.)


The resulting data format is not exactly the same as C-SLang would make with a compliant C compiler but it is equivalent, and C-SLang virtual machine understands it.

A little sweetener

Registration of functions in a C-SLang script serves two purposes:


If you want to export all functions (as normally would be the case), Unimal helper allows you to omit the function registration section altogether. In this case, all functions will be registered automatically in the order of their appearance in the script. In the example above, the fragment


#MP Expand      CSLang_RegStart()




#MP Expand      CSLang_RegEnd()

would be gone.


Note that in a native C-SLang source, you cannot omit the registration section.