SIMPL+ Tips and Tricks

I’ve spent the last week or so diving into Crestron SIMPL+ and have been reminded what a quirky language it is.  Here are some of the concepts I’ve been bitten by.

No Forward References

In somewhat of a throwback to the days of Turbo Pascal, SIMPL+ doesn’t allow you to reference a function or variable before it is declared.  This means you end up with most utility functions written near the top of the file and manager functions near the bottom.  For example, the Trim function must be declared before the ProcessConfigLine function that uses it:

String_Function Trim (STRING text)
{
    // ...
    Return(Mid(text, i, j - i + 1));
}

Integer_Function ProcessConfigLine (STRING text)
{
    STRING temp[100];

    // Trim spaces, comments, and newlines
    temp = Trim(text);

    // ...
}

If you try to move Trim below ProcessConfigLine, the compiler spits out:

Error 1400 [Line 7] - Illegal Assignment

This is likely due to the design of the SIMPL+ compiler (SPlusCC) as it appears to only do a single-pass of the program.  However, you can still write recursive functions:

Integer_Function Fib (INTEGER n)
{
    If (n < 3)
    {
        Return(1);
    }
    Return(Fib(n - 1) + Fib(n - 2));
}

Calling Fib(23) returns 28,657 in roughly one second.  Unfortunately, anything above Fib(23) overflows Signed_Integer.

Structures May Not Include Other Structures

From the help file, Structures may only contain: Integer, Long_Integer, Signed_Integer, Signed_Long_Integer, and String fields.  Also, String arrays are not allowed, but Integer arrays may be 1 or 2 dimensional.  Classic example:

STRUCTURE PhoneBookEntry
{
    STRING Name[50];
    STRING Address[100];
    STRING Number[50];
};

If you wanted a structure that could store multiple numbers per name, you’d have to create additional fields:

STRUCTURE PhoneBookEntry
{
    STRING Name[50];
    STRING Address[100];
    STRING Number1[50];
    STRING Number2[50];
}

If you pass a structure into a function, it is passed by reference, which leads to the next topic…

No Pointers

Representing complex data structures in memory using SIMPL+ is a bit of a challenge when you can’t reference anything directly.  References do exist (in the case of passing a structure or string array into a function) but they aren’t exposed by the language.  One way around this is to use the index into a record set as the pointer.

For example, say we have a phonebook we’re trying to display to the user.  But it can have multiple layers of folder structure.

STRUCTURE PhoneBookEntry
{
    INTEGER Type;
    INTEGER Index;
};

STRUCTURE FolderEntry
{
    STRING  Name[100];
    INTEGER Index[100];
};

STRUCTURE NumberEntry
{
    STRING Name[100];
    STRING Number[50];
};

Here we’ve defined our structures while staying within the limitations of what they may contain.  We can index from one record set into another to create the essence of references. For example, say we start with PhoneBookEntry[1] represents the root folder of the phonebook: Type would be set to 1 (to indicate it’s a folder), and Index would be set to 1 (to point into the FolderEntry table).  Now we check FolderEntry[1] (since Type=1 told us Index=1 pointed there).  FolderEntry[1] tells us the name of the current folder (say “Contacts”) and a list of up to 100 entries that can be stored there in Index.  These entries can be other folders or number entries since they point back into PhoneBookEntry.  A value of 0 is used to indicate empty or unused space within the folder.

We would need to develop some utility functions to make this less of a headache than it is.  To list the contents of a folder, we might write:

PhoneBookEntry PhoneBook[200];
FolderEntry    Folders[100];
NumberEntry    Numbers[100];

Function ListFolderContents (INTEGER i)
{
    INTEGER j;

    For (j = 1 To 100)
    {
        // Check for non-empty slots
        If (Folders[i].Index[j] > 0)
        {
            If (PhoneBook[Folders[i].Index[j]].Type = 1) // Folder
            {
                Trace("[%s]",
                    Folders[PhoneBook[Folders[i].Index[j]].Index].Name);
            }
            Else // Name and Number
            {
                Trace("%s - %s",
                    Numbers[PhoneBook[Folders[i].Index[j]].Index].Name,
                    Numbers[PhoneBook[Folders[i].Index[j]].Index].Number);
            }
        }
    }
}

As you can see, working around not having pointers can look a little ugly.  That’s all I have time to write down for today, but there is still more quirkiness to document in Crestron’s SIMPL+ compiler.

4 thoughts on “SIMPL+ Tips and Tricks

  1. Rereading the quirks I’ve encountered in SIMPL+, it’s no wonder most programmers move to SIMPL# when the opportunity is there. I tend to not use SIMPL+ for much more than string manipulation if that’s all I need in my SIMPL programs. SIMPL handles everything else much easier.

    Like

    1. Hello Kiel

      Thank for all the info. I am new to Simpl+. I have managed creating simple Simpl+ drivers(mostly writing the commands of a device and pass them to STRING_OUTPUTS after manipulating them). Do you think that i should continue with Simpl# or keep diving into Simpl+?

      Like

  2. Hello Kiel

    Thank for all the info. I am new to Simpl+. I have managed creating simple Simpl+ drivers(mostly writing the commands of a device and pass them to STRING_OUTPUTS after manipulating them). Do you think that i should continue with Simpl# or keep diving into Simpl+?

    Like

    1. Hello Kyriakos, thank you for reading my blog. I think programming in SIMPL is a good way to quickly turn out a working program, but it is hard to scale. If you want to write one program that works for multiple types of systems, SIMPL# Pro is the way to go. I write most of my programs in SIMPL because I have to share them with other programmers who don’t want to touch SIMPL#. Occasionally, I need to write a core piece of a module in SIMPL#, then wrap that in SIMPL+, so that I can drop it into my SIMPL program. Having that knowledge is helpful because it gives you access to a better tool (SIMPL#) when you need it.

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s