User:Dinsdale247/sandbox

From Wikipedia, the free encyclopedia
Jsi
ParadigmMulti-paradigm: JavaScript, scripting (glue language), imperative (procedural, prototype-based, object-oriented), functional
Designed byPeter MacDonald
DeveloperPeter MacDonald
First appeared2016; 8 years ago (2016)
Stable release
2.4.4 / December 27 2017
Typing disciplinedynamic, strong, duck
Implementation languageANSI C-C99
OSCross-platform
LicenseMIT License, libraries are various[1]
Websitewww.jsish.org
Influenced by
Tcl, quad-wheel interpreter

JavaScript Interpreter Shell (Jsish or Jsi for short) is a glue language designed for use in embedded systems. Jsi is compliant to C99 which allows for a broad range of cross platform compatibility.

Design[edit]

Jsi is a JavaScript based glue language designed to be embedded in applications written in C or C++. The interpreter is optimized to be lightweight and easily embedded rather than seeking the highest possible runtime performance. While the overall goal is a small total footprint, Jsi is designed to include many of the major components that developers require such as a built in SQLite database support, compression, sockets and support for secure web communications, a lightweight web server and a built in debugger.

Jsi has also been designed to reduce or eliminate the need to write threaded software by taking advantage of the Javascript Event Loop. Developers can hook into the event loop using setInverval and Event.Update and create complex applications where time sensitivity is not a factor.

History[edit]

Jsi was conceived based on Peter MacDonald's experience working with embedded applications. Peter noted that a large number of bugs in embedded software were in non-time-sensitive code and those bugs were usually simple in nature. These routines were often written in C or C++ due to necessity, rather than the language being a good choice for the task. It was also evident to Peter that most developers have some familiarity with Javascript due to the ubiquity of web development. It seemed natural then that a new language was required that wedded the familiarity people have with JavaScript, to the tool sets commonly used to embedded systems software.

Jsi began as a simple fork of the quad-wheel interpreter by ?. Much of the original code was replaced as the system was brought up to date with later revisions of ecmascript. The tokenization of the scripts was changed to be loosely modeled on the Tcl line based interpreter. Revision 1 was release in June 2016 after the code was stabalized on Ecmascript 5.1 and features such as SQLite, websockets and compression were added.

Jsi verison 2 was released in June 2017 with a large number of improvments and some additions from ecmascript 6. Version 2 also included an improved debugger, a web server and a web client interface to the debugger.

Features[edit]

Syntax[edit]

See JavaScript Syntax.

ECMAScript Compliance[edit]

Jsi implements version 5.1 of the Ecma-script 262 standard, with the following deviations:

  • Semicolons are not auto-inserted.
  • Empty array/object elements are not supported, eg. [1,,3].
  • It is an error to use return inside of a try/catch body.
  • The Error object is unimplemented: the argument to catch() is just a string.
  • The Date object is unimplemented: use strftime/strptime.
  • The value of typeof [] is "array" instead of "object".
  • UTF is currently not supported.

Extensions to the 5.1 standard include:

  • Function support for parameter types and defaults.
  • Support for Array of iterator, eg: for (var X of Y) (as in Ecma-script 6).
  • Partial support for Array forEach command, eg: lst.forEach(function(val){}).

Interpreter[edit]

Jsi is a byte code based interpreter.

Type Checking[edit]

Jsi supports type checking across function calls to reduce errors caused by implicit conversions when passing arguments.

Modules[edit]

Jsi Modules are a set of programmatic conventions that allow a script to be run from the command line or be "required" by another script for inclusion and use as an object. Modules provide command line option parsing and simple help output.

The 7 parts of a module are:

Section Description
function All code is wrapped in a function with the same name as the file basename, providing bindings for incoming arguments.
options The var options = object itemizes the all options that can come in via the opts parameter.
that Local object state is stored in the that object. All defined and incoming options will be copied into that.
Jsi_Opts The call Jsi_Opts(that, options, opts) performs option parsing as well as implementing -h help output
provide The provide statement makes the module available as a package.
Info.isMain The Info.isMain() command returns true if the current file was the one invoked from the command-line.
Jsi_Main The Jsi_Main() command parses command-line options and then invokes the current module.

Here is an example module ./fileSize.jsi:

    #!/usr/bin/env jsish
    function fileSize(fargs:array|string=void, opts:object=void) {

        var options = { // Count bytes in files
            debug       :false, // Debug output
            max         :10     // Max number of files
        };
        var that = {
            package:'fileSize', // Note: "package" is used by Jsi_Opts to support "-h".
            cnt:0
        };
        
        function getLength(fargs:array|string) {
            if (typeof fargs === 'string')
                fargs = [fargs];
                
            for (var i in fargs) {
                if (i>=that.max) break;
                if (that.debug)
                    puts('Count: '+fargs[i]);
                that.cnt += File.size(fargs[i]);
            }
            return that.cnt;
        }

        Jsi_Opts(that, options, opts);
        
        if (fargs)
            return getLength(fargs);
            
        that.getLength = getLength; // Return object-command
        return that;
    }

    provide('fileSize');

    if (Info.isMain()) {
        puts(Jsi_Main('fileSize'));
    }

Invoked as:

   ./fileSize.jsi -debug true file1 file2 file3

Leading switches are passed in opts with the remaining arguments in fargs.

Note that options coming in from the command-line must be primitives.

C API[edit]

Jsi is intended to be embedded into other applications.

The following example creates Jsi commands in C, initializes an interpreter and then runs the C functions from within the JavaScript Interpeter

/*
  Multi-command object: Cmd.add, Cmd.diff

  BUILDING:
    cc cmds.c -lz -lm -ldl -lpthread
*/
#include "../jsi.c"

static Jsi_CmdProcDecl(AddCmd) {
    int i, n = Jsi_ValueGetLength(interp, args);
    Jsi_Number m, sum = 0;
    for (i=0; i<n; i++) {
        if (Jsi_ValueGetNumber(interp, Jsi_ValueArrayIndex(interp, args, i), &m) != JSI_OK)
            return JSI_ERROR;
        sum += m;
    }
    Jsi_ValueMakeNumber(interp, ret, sum);
    return JSI_OK;
}


static Jsi_CmdProcDecl(DiffCmd) {
    Jsi_Number m, n, diff;
    char buf[BUFSIZ];
    if (Jsi_ValueGetNumber(interp, Jsi_ValueArrayIndex(interp, args, 0), &m) != JSI_OK)
        return JSI_ERROR;
    if (Jsi_ValueGetNumber(interp, Jsi_ValueArrayIndex(interp, args, 1), &n) != JSI_OK)
        return JSI_ERROR;
    diff = m-n;
    // Non-strict JSON makes it easy to return complex objects in C.
    snprintf(buf, sizeof(buf), "{ diff:%g, values:[%g, %g] }", diff, m, n);
    Jsi_JSONParse(interp, buf, ret, 0);
    return JSI_OK;
}

static Jsi_CmdSpec myCmds[] = {
    { "add",        AddCmd,        0, -1, "...", .help="Return sum of all arguments", .retType=JSI_TT_NUMBER },
    { "diff",       DiffCmd,       2,  2, "v1:number, v2:number", .help="Return object with difference of values", .retType=JSI_TT_OBJECT },
    { NULL, 0,0,0,0,.help="My test commands" }
};

int Jsi_InitCmds(Jsi_Interp *interp) {
    Jsi_CommandCreateSpecs(interp, "Cmd", myCmds, NULL, 0);
    return JSI_OK;
}

int main(int argc, char *argv[])
{
    Jsi_InterpOpts opts = {.argc=argc, .argv=argv};
    Jsi_Interp *interp = Jsi_InterpNew(&opts);
    if (Jsi_InitCmds(interp) != JSI_OK)
        exit(1);
    Jsi_EvalString(interp, "puts(Cmd.add(1,2,3)); puts(Cmd.diff(17,9));", 0);
    Jsi_Interactive(interp, 0);
    exit(0);
}

Jsi Extensions[edit]

Shell and Stand alone Interpreter[edit]

Additional tools[edit]

Jsi was designed to be convenient for embedded development. The base system contains a number of tools that make Jsi convenient to debug when using target hardware:

SQLite[edit]

Jsi contains a built in SQLite interface.

Debugger[edit]

The built in debugger used by calling a Jsi script from the command line using -d for the command line interface. If a GUI web browser is available the -D option can be used and the code can be browsed and debugged in a debugger.

Applications[edit]

See also[edit]

References[edit]

Further reading[edit]

External links[edit]


Category:Cross-platform free software Category:Cross-platform software Category:Dynamically typed programming languages Category:Embedded systems Category:Free compilers and interpreters Category:Free computer libraries Category:Free software programmed in C Category:Prototype-based programming languages Category:Scripting languages Category:Software using the MIT license