Extensions - LightningLaser8/ISL GitHub Wiki

ISL as a language can be limited, so extensions can be made to extend functionality or provide integration into other programs.

ISL Extensions are made with the ISLExtension class, provided in the core. They contain any number of custom keywords and global variables that can then be imported into an interpreter.

Creating

[!] Requires module core\extensions THe best way to learn this, is by example, so this section will create a new extension, multiplier which adds 2 keywords, mult and multiplier, and a global variable, \_multi\, which multiplier modifies.

First, create a new .js file, and open it in an IDE of your choice. We'll call it multiplier.js. Creating an extension requires the ISLExtension class from module core\extensions, so, first, import ISLExtension from the core module of ISL.

import ISLExtension from "./isl/core/extensions.js"

Now, instantiate ISLExtension as a constant. ISLExtension takes one parameter, identifier, which will be used to identify it. We will be using multiplier as the identifier.

import ISLExtension from "./isl/core/extensions.js"
const ext = new ISLExtension("multiplier")

Now we have a blank extension. Time to add a variable, using the ISLExtension.addVariable() method:

import ISLExtension from "./isl/core/extensions.js"
const ext = new ISLExtension("multiplier")
ext.addVariable("multi", 1)

The extension now has a variable: multi, with a default value of 1. However, it's pretty useless right now, so let's add a keyword to change it, using the ISLExtension.addKeyword() method.

import ISLExtension from "./isl/core/extensions.js"
const ext = new ISLExtension("multiplier")
ext.addVariable("multi", 1)
ext.addKeyword("mult", function(labels, newMult){/* Now what?*/})

The callback is sent the current labels of the keyword as an array in the first parameter, labels But, there's a problem! ISLInterpreter has no method to access global variables, and they're private properties! To get around this, ISLExtension.addVariable() returns the variable made, so the code becomes

import ISLExtension from "./isl/core/extensions.js"
const ext = new ISLExtension("multiplier")
let multi = ext.addVariable("multi", 1)
ext.addKeyword("multiplier",
  function(labels, newMult){
    multi.value = newMult
  }
)

Now, our extension has the keyword multiplier, which takes one argument: newMult, the new multiplier. Any interpreter with this extension will now read multiplier 4 as "set the global variable multi's value to 4".
Now, let's give the extension some actual functionality. As this is an example, we'll keep it simple, but there's no real limit to how much you can add.

import ISLExtension from "./isl/core/extensions.js"
const ext = new ISLExtension("multiplier")
let multi = ext.addVariable("multi", 1)
ext.addKeyword("multiplier",
  function(labels, newMult){
    multi.value = newMult
  }
)
ext.addKeyword("mult",
  function(labels, variable){
    this.setVar(variable, this.getVar(variable) * multi)
  }
)

The keyword mult will multiply a variable's value by the stored multiplier, multi.
Now, it's time to export the new extension. We'll use export default to keep imports nice and concise, and as we're exporting only one thing.

import ISLExtension from "./isl/core/extensions.js"
const ext = new ISLExtension("multiplier")
let multi = ext.addVariable("multi", 1)
ext.addKeyword("multiplier",
  function(labels, newMult){
    multi.value = newMult
  }
)
ext.addKeyword("mult",
  function(labels, variable){
    this.setVar(variable, this.getVar(variable) * multi)
  }
)
export default ext

To use this, however, we'll need to import it into an interpreter. We'll assume there is already an ISL-enabled program (it's simple, but not relevant to this example), with an interpreter stored in interpreter.
In that file, import your extension:

import ext from "./multiplier.js"

Then call ISLInterpreter.extend() on the interpreter:

import ext from "./multiplier.js"
interpreter.extend(ext)

That's it! You've created 2 new ISL keywords, both getting and setting a global variable, and applied them to an ISL interpreter. Remember to add [require multiplier] to the top of any ISL files, to tell users (and interpreters) that they need your multiplier extension to run it.

Importing

ISLInterpreter.extend() can be used to import an extension's content to the interpreter. Imported extensions apply to that interpreter only.

Reference

ISLInterpreter.extend()

Imports an ISLExtension into the interpreter, copying its keywords, labels, functions and types.

ISLInterpreter.extend(extension: ISLExtension)

extension

Extension to import.

ISLExtension.addKeyword()

Adds a custom keyword to the extension.

ISLExtension.addKeyword(name: string, callback: Function)

name

The name of the keyword.

callback

ISLExtension.addVariable()

Adds a custom variable to the extension. The only dynamically typed part of ISL.

ISLExtension.addVariable(name: string, initialValue: any)

name

Name/identifier of the variable.

initialValue

Initial value of the variable.

ISLExtension.addLabel()

Adds a custom label to the extension.

ISLExtension.addLabel(name: string, for: Array<string>)

name

Name of the label.

for

Array of keywords the label is applicable to.

⚠️ **GitHub.com Fallback** ⚠️