Paisley

Paisley is a scripting language designed to allow for easy command-based behavior scripting. It’s designed to be a simple, light-weight way to chain together more complex behavior from existing commands, while also having a “batteries included” mindset when it comes to manipulating the output of those commands. As such, there is a whole suite of operations and functions for quick and easy data manipulation.

The ethos behind Paisley was not to create a particularly fast language (most of the compiler optimizations are for reducing the size of the generated bytecode), but instead to have a shell-like language that can be embedded in any Lua environment, even ones that exist in an extremely limited sandbox with minimal Lua features available.


FAQ

Q: Where does the name “Paisley” come from?
A: Originally it was an acronym “PAISLey” with an embarrassing leftover “ey” that didn’t stand for anything; but nowadays its name is just “Paisley”, no acronym. If you want to assign a meaning to the name, you could say that paisleys are a simple pattern where you repeat pretty little curlies over and over all the way down. Likewise, Paisley is a simple language whose expression syntax uses curly braces all the way down. That’s a potential answer at least. The real answer is that I like how paisleys look.

Q: What niche does Paisley fill?
A: Paisley would fill a similar niche to Bash scripts, where you’re chaining together other scripts/programs to make more complex logic. Similar to bash, commands can be run just by typing the command name and parameters separated by spaces. Basically, it’s somewhere between Bash and Python; fitting close to the shell-language niche while also having batteries included.

Q: Is Paisley a true shell language? Can I replace Bash with it?
A: You could absolutely replace your Bash scripts if you wanted to. However I would not recommend replacing your Bash REPL with Paisley’s. For one, while Paisley does support piping, the language is not by any means POSIX-compliant, and in particular there are no async capabilities. Paisley’s use case is more like Python in that regard where, while it does have a REPL, it’s really meant to be used in self-contained scripts.

Q: What does Paisley do different?
A: Simple and consistent syntax for one. As much as I love Bash, the syntax is quite frankly a mess. There are so many gotchas and oddities. E.g. expressions use $((...)) but don’t support floats, the language itself doesn’t have actual types, not to mention constantly having to think about globbing and whether stuff is escaped or not. Paisley is very simple in that, if it’s inside {...}, then it’s an expression. It also supports arbitrarily nested data (3d arrays anyone?), which Bash does not.

Q: Why is this written in Lua?
A: Originally this was written for use in a game called Plasma; this game would let you create node-based programs and Lua scripts to control machines, though the version of Lua was quite limited in features. This language was written to get around the tedium and limitations of certain aspects of the game engine, but snowballed into a bit of a passion project as well as a proof of concept that, yes, you can write a compiler in Lua without any extra dependencies. Many, many updates later, we have Paisley as it stands now. There is still a Plasma Version FAQ if you’re interested in that.


Installing Paisley

Required Dependencies to run: - At least lua5.1 for basic functionality. However, if you want to create standalone applications, lua5.3 or greater is required.

Required dependencies to build standalone applications: - lua5.3 or greater.

Optional dependencies to enable extra features: - luarocks which likely will require: - liblua5.3-dev or greater (Or whatever Lua development libraries for your OS). NOTE This needs to be the same as your Lua version!

Dependencies required for creating standalone applications: - Some C compiler (cc, gcc, clang or mingw32-gcc). This is only for --target=c - Some C++ compiler (c++, g++, clang++ or mingw32-c++) as well as make. This is only for --target=cpp

If you want to keep dependencies to a minimum, you can just install lua and then run paisley (via lua paisley or lua54 paisley/lua5.4 paisley; whatever your specific version of Lua is) and it should work fine. Nothing else is needed, but extra features are disabled in this case.

Optional extra features include: - Building the Paisley compiler into a standalone application and installing it on your system. - Compiling Paisley scripts into standalone applications. - Compressing Paisley bytecode with zlib compression. - Advanced controls in REPL mode, along with syntax highlighting.

Note: If most rocks install fine, but the lua-zlib rock specifically fails, you probably need to install zlib development files on your system. On Ubuntu, that would be sudo apt install zlib1g-dev.

If you have all the requirements to build standalone applications

On Linux systems, just run ./install.sh and it will install Lua rocks for all extra features, then compile Paisley into a single file and install on your system. To uninstall, just run ./uninstall.sh.

NOTE: If you can’t or don’t want to install ANY dependencies on your system, there is also a standalone build available in the latest tag. This build is available for both Linux and Windows.

Running Paisley

Running a basic Paisley script is pretty straightforward.

# If Paisley is installed on your machine, you can run the following:
paisley examples/helloworld.pai
paisley --help

# If it's not installed, just keep in mind that this is a Lua project;
# you can run Paisley as you would any other Lua script:
lua paisley examples/helloworld.pai
lua paisley --help

There are lots of options available to play around with, so be sure and run paisley --help for a rundown of all of them.

A particularly useful feature is the --introspect flag, which allows outputting detailed information about functions or commands. This information is often more detailed than the readme, though the readme is often plenty detailed. For example:

paisley --introspect -ifnormalize

The above will print out detailed info about the normalize() function.

paisley --introspect -icsleep

The above will print out detailed info about the sleep command.

Programming in Paisley

For a detailed breakdown of all the syntax and usage thereof, feel free to read through the complete syntax walkthrough (linked below).

Also see the examples/ for real working sample code.


Examples | Language Walkthrough >