Pnuts Quickstart Guide

This guide quickly explains the basics of getting down and using the Pnuts JVM language. Click here for more of a high level overview of the language.

Contexts

Each Pnuts script is run with a context object. This object stores information about the executing script, such as the stack frame, current package, imported Java classes, classloader, etc. Each time you execute a script you should create a new context instance (or use the copy constructor).

The simplest way to execute a Pnuts script from Java is as follows...
For debugging, exception stack traces and some other useful messages can be turned on by calling context.setVerbose(true).

Imports

Imports in Pnuts work very much like they do in Java. This gives Pnuts access to the entire JDK and any other Java class on the classpath...
Note that the "new" keyword when invoking a constructor is optional in Pnuts.

Bean Properties

Java bean properties can be be accessed as if they were a field...
Functions

Functions in Pnuts are defined in this way...
Multiple functions of the same name can be defined with a different number of arguments...
Like an "if" statement, the curly braces may be omitted if a function has only a single statement...
An anonymous function can be created by omitting the function name...
A value can be returned from a function with the return keyword. If there is no return keyword, the function returns the result of the last statement...
Packages

Pnuts has a package object which stores defined variables and functions. The context stores what package is the current package for that context. Only one package may be the current package at any given time. When a package is made the current package, all variables and functions defined in the package are available to the script. If a context is created without specifying a package, a special package called the "global package" is used.

The following executes a script using a package that has the symbol "name" defined...
Note that the symbol name must be an "interned" String. The String class maintains a pool of Strings. When you call String#intern(), if the pool already contains a String equal to this String object as determined by the equals method, then the string from the pool is returned. Otherwise, this String is added to the pool and a reference to this String is returned. What this means is that "value".intern() == "value".intern() is always true, because intern() returns the exact same String instance. Pnuts stores symbols as interned Strings because then symbols can be compared with "==" rather than the "equals" method and this is much, much faster.

A Pnuts function can be defined in Java by extending the PnutsFunction class and overriding the "exec" method. The following is one way to expose the function to a Pnuts script...
Scripts can change the current package at runtime using the "package" statement...
Packages can have names. This allows you to reference the package by name to set the current package.
You can also directly access the contents of a package by name with the "::" syntax...
Packages can have a hierarchy when named with "::". For example...
When the symbol "name" is encountered, Pnuts first looks in the current package "foo::bar". When the symbol is not found it looks in the parent package "foo".

Modules (in Pnuts)

Pnuts has the concept of a "module". When a module is "used", it makes the contents of its package available in the current package. In this example, the "hello" method is defined in the "foo.bar" module...
When use("foo.bar") is called, Pnuts first executes the file on the classpath "foo/bar/init.pnut", then makes the contents of the "foo.bar" package available to the current package. The "foo/bar/init.pnut" file looks like this...
By default all functions in the package are automatically exported, but variables are not. Variables can be exported by calling the export method on the package object...
If the export method is used, only the functions and variables specified are exported (the default of exporting all functions is no longer in effect). Exported variables are available from a used module just like functions...
Module Autoloading (in Pnuts)

If a module defines many functions, it may defer loading the functions until they are actually invoked. This can reduce the start up time of a module. To do so, use the autoload built-in function...
If some other script tried to use this function...
The cdplayer.pnut file would not be loaded until the play method was invoked.

Modules (in Java)

Modules can also be defined in Java. To do so, do not include an init.pnut file. In its place, put an init.class file. The init class should extend ModuleBase, like this...
The execute method is invoked when the module is used. This allows the module to manipulate the context. For example, the module could define a symbol...
Module Autoloading (in Java)

If a module written in Java defines a Pnuts function in a script, it can defer the loading of the script file until the function is invoked. This is done with the ModuleBase#autoload() method...
The cdplayer.pnut file would not be loaded until the play method was invoked.

If a module written in Java wants to export a Pnuts function written in Java, it can do so with the following...
However, if the module has many functions it can reduce the start up time by defering the loading and instantiation of the PnutsFunction classes by using the ModuleBase#autoloadFunction() method...
A module written in Java can export class names with the following...
A script using the module can then use the autoloaded classes without importing the classes itself...
Conclusion

That concludes this brief guide to get started with Pnuts. The above information will take you a long way with the Pnuts JVM language. For more information see the Resources below.

Resources

The Pnuts Language
Pnuts User's Guide
Pnuts syntax quick reference
Pnuts downloads
Other articles

Author: Nathan Sweet