# The PLIB Scripting Language Programming Guide

By Steve Baker

# Introduction

This document explains how to write PSL programs.

How you actually run those programs depends on which PSL-enabled application you are running. There is a stand-alone PSL interpreter in plib/examples/src/psl/psl_demo - but it doesn't include any application-specific language extensions - so a PSL program that's written for a specific application may not run on `psl_demo`.

However, psl_demo is great for learning to write PSL scripts.

# The PSL Language

PSL is designed to be as close to the C Programming Language - although we cut a few corners - we extended the language in a few places - and we consciously omitted other features that are dangerous in a scripting language.

The following C features are implemented much as you'd expect:

- Types 'void', 'int' and 'float' (and arrays of those things).
- Function definitions.
- Global variable definitions.
- Statement types:
  - Local variable definitions.
  - Static variable definitions.
  - "return"
  - "break"
  - "continue"
  - "for"
  - "do/while"
  - "switch/case/default"
  - "while"
  - "if"
  - "if/else"
  - "{}" compound statements.
  - Assignment statements.
  - Procedure calls.
- Most Arithmetic operators.
- Comments '/*' '*/'.
- C preprocessor directives:
  - "#include"
  - "#define" without parameters.
  - "#undef"
  - "#ifdef/#endif"
  - "#ifdef/#else/#endif"
  - "#ifndef/#endif"
  - "#ifndef/#else/#endif"
- Special characters in strings:
  - "\n"
  - "\r"
  - "\a"
  - "\b"
  - "\f"
  - "\t"
  - "\\"
  - "\""
- Recursion, etc.

Some new features have been added that are not part of C:

- "pause" -- Pause the program until next frame.
- "string" data type (and arrays of strings).
- Casts are unnecessary between compatible types.
- C++ style '//' comments.
- C++ style local variable declarations.

Some features of C are NOT IMPLEMENTED in PSL:

- Pointers.
- Casts.
- Dynamic Memory Allocation.
- ',' and '?:' operators in expressions.
- "static", "auto" and "register" storage class reserved words.
- "char", "short", "unsigned", "signed", "long", "double".
- "typedef"
- "enum", "union", bitfields.
- "goto".
- "#if"
- "#pragma"
- "#define" with parameters.
- 'f' and 'l' suffixes for float and long numbers.
- All preprocessor directives must have the '#' as the very first character on the line - they cannot be preceded with whitespace.

The following features are "NOT IMPLEMENTED YET" - but will hopefully arrive soon:

- Multiple variable definitions like 'int i, j, k ;'
- Structs.
- '\' to escape the end-of-line character in strings and macro's.
- Parameter passing by name.
- Many of C's standard library functions are needed.

# Compatibility Notes:

### C++ style local variables.

With PSL's C++ style locals, you can say things like this:

        for ( int i = 0 ; i < 10 ; i++ )  /* Do something */ ;

In standard C++, the scope of the variable 'i' is from it's declaration to the end of the 'for' loop. However, Microsoft's Visual C++ uses an obsolete version of the C++ standard that allows the scope of 'i' to continue to the end of the block that contains the for loop. So:

WINDOWS USERS BEWARE: PSL IMPLEMENTS THIS CORRECTLY - *NOT* LIKE MSVC.

# Hard Limits

Currently there are hard limits in many places - the number of variables, the size of the program, the depth of nesting, etc. These limits will gradually be removed as PSL is developed.

# Debugging PSL Programs

Specific PSL-enabled applications may have their own special features to assist with debugging - but all PSL-enabled applications support several 'shell variables' that enable certain debugging features.

When using a command line shell, you can set these variables using one of the following commands before you run your application:

        setenv VARIABLE value     -- csh or tcsh
        export VARIABLE=value     -- bash or sh
        set VARIABLE=value        -- DOS shell

### Byte-Code Dump

It's possible to view the byte code that PSL generated by setting the shell variable 'PSL_DUMP' to either:

- never (the default) -- Never produce a dump unless the application demands it.
- on_error -- Produce a dump whenever the PSL program fails to compile for whatever reason.
- always -- Always produce a dump after the PSL program finishes compiling.

### Byte-Code Execution Trace

It's possible to view the byte code as it's executed by setting the shell variable 'PSL_TRACE' to either:

- never (the default) -- Never produce a trace unless the application demands it.
- always -- Always produce a trace.

When the execution trace is enabled, extra instructions will be inserted into the byte code to enable the PSL interpreter to produce debug indicating which lines of the source code are being traced.

### Byte-Code Stack Display

If you have PSL_TRACE turned on (either via the config variable or by the application program), then the shell variable 'PSL_STACK' can be set to display the contents of the top eight stack locations as the program is traced. If PSL_TRACE is disabled then PSL_STACK has no effect.

- never (the default) -- Never produce stack dumps within a trace.
- always -- Always produce a stack dump within trace.