No announcement yet.

Assembler for NSIS

  • Filter
  • Time
  • Show
Clear All
new posts

  • Assembler for NSIS
    nsL is a high-level language for NSIS ( The nsL assembler takes nsL code and translates it into NSIS script which can then be compiled into an NSIS installation wizard. nsL has a uniform syntax that is similar to familiar programming languages such as C and Java. Complex expressions can be written freely while being assembled into basic NSIS instructions. Functions are defined and called much like they are in C and Java with the additional syntax for multiple return values. nsL introduces assemble time scope checking of variables as well as automatic declaration and support for global variables declaration and initialization. nsL also provides more powerful pre-processor directives such as macros which can have multiple inputs and outputs, just like run-time functions.
    This is still work in progress but everything is there that allows one to write and build NSIS installers using the new language. Included is the source code, some example scripts and a first draft reference document. I am very interested in getting some feedback such as suggestions for changes, feature requests and bug reports.

    This project is part of my University degree but it's time for me to move on to other University related work before my exams in May/June. That does not mean I will be stopping work on nsL. I plan on adding support for arrays with the help of a small plug-in (among other things) but that will be done at a later stage. My demonstration for this project is on Tuesday (29th) so I would be grateful to get feedback tomorrow or Monday! I apologise for posting so close to the demonstration date but there was so many features that I wanted to add I got a little carried away.

    Anyway, run the executable file from the SourceForge page and then you will have a "Compile nsL Script" right-click option on ".nsl" files. You'll find some example scripts in NSIS\Examples\NSL.

    Edit: Attached an example script.

    Attached Files

  • #2
    It is very interesting, I like its style very much.
    Contact me: [email protected]


    • #3
      (All of my comments are based on just reading the .pdf)

      "Before a variable can be used, it must
      be assigned to" I don't really like this, I'm used to variables defaulting to "" if you never set them (And they don't need an initial value if you are going to be pop'ing into them)

      Using \ as escape is a bit painful in a installer since it usually contains a lot of paths, maybe you could add @"this\is\not\escaped" like C#? Or use ^ or something like that?

      Real functions (with overloading even) looks great!

      I'm not really a fan of the section syntax, what if we add another flag? Named arguments would also be better so you don't have to remember the order. What about something like
      section MySection("hello world",/ReadOnly,"/newflag=space string",/Bold,1,2,...N), also, "optional" is not a good word for /o, IMHO you should call it unselected or unchecked. (I'm assuming /o is supposed to simulate [O] vs [X] )

      Did you forget about the /ENABLECANCEL flag for custom pages?

      Is there a way to tell how many parameters have been passed to a #macro? getmacroargcount() or something like that?

      There is an old bug in the nsis parser, MessageBox mb_ok "$${foo}" this should display "${foo}" and not "$" + the content of ${foo}, maybe you can either add a working escape for \$ ($\$ in nsis, but does not exist) or work around it in other ways in your string handling?

      Are functions merged? aka can you have more than one .onInit() assuming they have the same number of parameters? (You don't want this for normal functions, but it would be nice to have for the nsis callbacks)

      I assume the .docx is the same as the .pdf? I think .rtf has table support, all I know is, I can't (and will not try to) read .docx

      Not a big fan of java, but hey, the author gets to choose the language =)
      IntOp $PostCount $PostCount + 1


      • #4
        This looks totally awesome!

        I am very happy about C like syntax and case sensitivity.
        Making own functions is fantastic, variable scope (finally!), arithmetic operators, code blocks, inlining NSIS code these all are great!
        Using hash for defines is a little strange, but it reminds me a old-good C/C++

        I am a little disappointed from function calls:
        CopyFiles("source", "dest", true, true, 99);
        CopyFiles /SILENT /FILESONLY "source" "dest" 99

        WTF is that true, true, 99 ?
        Althought I am skilled NSIS user on first signt I didn't have any idea what it means. I suggest to use enums for parameters [flags] - is this possible?
        Maybe these flags should be ORed someone??
        PHP Code:
        Also sending some parameters as string is not good idea e.g
        MessageBox("MB_OK|MB_ICONEXCLAMATION", "NSIS is not installed on this machine. Setup will now exit.");
        MB_OK|MB_ICONEXCLAMATION would fit perfectly for enums
        PHP Code:
        enum MessageBox

        I tried your .nsl with MUI2 and it does not work (as I assumed) so everything should be rewritten into .nsl which is enormus work.
        I noticed that generated .nsi file requires a little of brushing.

        Anyway: nsL looks very promising and you made a really good job on it!

        In this state I suggest using nsL in this style:
        Create .nsl file where you create all logic, functions, etc because in nsL it is easier than in .nsi
        and then generate .nsi file which you later include in your installer, you brush it a little and generate final installer.
        Last edited by T.Slappy; 27 March 2011, 06:57. Reason: Adding some stuff
        Cool looking installers with custom design:
        Create Setup Pages easily:
        Build installers in Visual Studio 2005-2022:
        or RAD Studio 2009 - 11 Alexandria:


        • #5
          Thanks for the feedback guys. Keep it coming! I will make note of everything.
          Did you forget about the /ENABLECANCEL flag for custom pages?
          It is there; the last parameter after page callbacks can be a Boolean.

          "Before a variable can be used, it must
          be assigned to" I don't really like this, I'm used to variables defaulting to "" if you never set them (And they don't need an initial value if you are going to be pop'ing into them)
          If you are popping into them then you are assigning to them, i.e. $0 = Pop();. You don't need to set them to an empty string. The point of having to assign to them before referring to variables is to avoid the problem of clobbering values. If you want to make a variable global, just stick an assignment to it outside functions and sections. I will add an optimisation that $R0 = ""; in global scope doesn't assemble anything (it will already be empty).

          getmacroargcount() is a good idea. There are probably plenty more that I could add really such as macrodef(name) and perhaps date() etc.

          Are functions merged?
          That's a nice idea. I could allow this for all functions by adding a partial keyword (C#) or just allow it for callbacks?

          The docx was included in the source code. The pdf is the Docs copy. The original plan was to write it in C++ but using Java of course allowed me to write code and debug much faster.

          Yes the \\ in strings is a real pain. I will add support for the C# @ prefix.

          MB_OK|MB_ICONEXCLAMATION would fit perfectly for enums
          I agree. This was something I wanted to change/add but again because of time constraints I had to leave as strings. If you want enums, would you prefer C style or C#. For example with C# you'd need "MessageBox." in front of each value; however I could have the assembler look for an enum with the same name as the current function and match those . Either way you can use enums now (no constructor mind) as the | operator exists and you can define constants as numbers.

          As for MUI, I should include an example. It's actually very simple. Just add #nsis ... #nsisend sections with the MUI code in it. Maybe not very pretty but that's the best we can do probably. I need to add an #nsisdef or something similar to !define constants to nsL values (i.e. import values from nsL into NSIS) but maybe there is a nicer way. Any thoughts? (Defining all nsL constants as NSIS ones... no).

          Edit: New build uploaded which has the @ string prefix added. Also included a simple Modern UI 2 example script.



          • #6
            I can't stand C# enums, and you should try to keep the amount of extra typing to a minimum and emulate the nsis constant names when possible...
            IntOp $PostCount $PostCount + 1


            • #7
              Yeh I agree. I will keep it simple and predefine MB_* as constants (among others). Something else I need to add is to assemble MessageBox (and other jump instructions) specially in switch statements. Currently you can use them, sure, but it will first StrCpy IDOK for example to a register and use that register for the switch. This is not the case when used in if statements or while loops - e.g. the MessageBox or IfSilent go-to label arguments will be used instead, but you are limited to a true or false (i.e. IDOK or not).



              • #8
                1.0.2 released.
                1.0.2 - 28th March 2011
                * Global assignments of "" to registers are no longer assembled
                (registers are intialised to an empty string by NSIS).
                * Fixed < and > operators using incorrect jump labels.
                * Jump instructions when used in switch statements now receive similar
                optimisations to their use in if statements. For example, MessageBox
                can be used with cases "IDYES", "IDNO", "IDCANCEL" and so on. IfSilent
                can be used with cases true or false. The go-to labels for each case
                will be used directly on the jump instruction (i.e. IfSilent
                label_case_true label_case_false) as is also done with if statements.
                * Switch cases must have literal string, Boolean or integer values.
                * Added missing 'default:' case for switch statements.
                * Fixed Boolean values or instructions not being accepted as operands
                for a Boolean operator.
                * Fixed MessageBox being accepted as a Boolean value.
                * Fixed MessageBox using 3 goto jumps on the end when only 2 are
                * Fixed If statements accepting a non-boolean expression.
                * Fixed Boolean logic for || operator with left and right operands as
                relative/equality comparisons.
                * Added error on literal division by zero.
                * More example scripts!


                • #9
                  Installation Issue

                  I'm using a PortableApps version of NSIS so the install "Claims" that NSIS is not installed. I took a look at the SVN source and find that the installer get the install path from the registry, if the registry key is missing then kaboom. Install.nsl --> Line 18

                  For a simple workaround, just add the portable apps path to the registry.. here is a VBScript that dose the trick:
                  PHP Code:
                  '## VBScript to provide a work around for installing nsL-Assembler

                  Dim NSISPath

                  Set fso = CreateObject("Scripting.FileSystemObject")
                  Set objDialog = CreateObject("UserAccounts.CommonDialog")
                  Set WshShell = CreateObject("Wscript.Shell")

                  ## Get the Current NSIS path if it exists in the registry
                  NSISPath GetRegValue()
                  Not fso.FolderExists(NSISPathThen NSISPath WScript.Path

                  '## Define the "Open File" Dialog
                  ## Prompt user to locate the makensis.exe file
                  objDialog.Filter "makensis.exe|makensis.exe|All Files|*.*"
                  objDialog.FilterIndex 1
                  .InitialDir NSISPath

                  If intResult 0 Then
                  If GetRegValue() <> "" Then
                  If MsgBox("Do you want to delete the existing registry key?",36) = 6 Then
                              On Error Resume Next
                  On Error Goto 0
                  ElseIf MsgBox("Do you want to delete the existing registry value?",36) = 6 Then
                              On Error Resume Next
                              On Error Goto 0
                          End If
                          MsgBox "
                  ABORTConfiguration Aborted by user."
                      End If
                  ElseIf fso.FileExists(objDialog.FileName) Then
                      '## Found it..  Setting the registry to match
                          NSISPath = fso.GetFile(objDialog.FileName).ParentFolder.Path
                          Wshshell.RegWrite "
                  HKLM\SOFTWARE\NSIS\", NSISPath
                      '## Validate
                          If GetRegValue() = NSISPath Then
                              MsgBox "
                  SuccessRegistry Path was set to [" & NSISPath & "]"
                              MsgBox "
                  FAILEDUnable to set registry settingYou might not have administrative access to edit the registry."
                          End If
                      MsgBox "
                  ERRORFile was not found!"
                  End If

                  Function GetRegValue()
                      Dim Value
                      Value = ""
                      On Error Resume Next
                          Value = WshShell.RegRead("
                      On Error Goto 0
                      GetRegValue = Value
                  End Function 
                  ↓ Your Welcome
                  Last edited by Zinthose; 29 March 2011, 21:04.
                  Regards ^_^

                  Search the Forums and the Wiki


                  • #10
                    Ah thanks. I may just remove that code as people can still use the assembler without NSIS installed anyway.



                    • #11
                      If anyone else would like to play around with the language and post some more feedback I would be grateful.



                      • #12
                        Sublime Text plugin supporting nsL Assember is now available, adding language syntax, command completion (WIP) and a build system.

                        Will make the command completion more useful, but the nsL documentation isn't too much of an help (also, why docx?!)
                        NSIS IDE for Atom | NSIS for Visual Studio Code | NSIS for Sublime Text | NSIS.docset


                        • #13
                          @AfrowUK: please have a look at this and consider merging Frisch12's changes into the official version
                          NSIS IDE for Atom | NSIS for Visual Studio Code | NSIS for Sublime Text | NSIS.docset


                          • #14
                            I wasn't aware people were still using nsL? It was a project when I was at University 6 years ago (hence Java and docx).