Program The rantings of a lunatic Scientist

Posts tagged as PEG.js


99 Bottles of beer

L2Program Language

Still very much a work in progress but it’s at least 99% there. And what better way to celebrate than with a round of 99 bottles of beer on the wall!

1.1 Do part 2 for a = 99(-1)2.
1.2 Do part 3.
1.3 Line.

2.1 Type a in form 1.
2.2 Type a in form 2.
2.3 Do step 4.1.
2.4 Set b = a - 1.
2.5 Do step 3.1 if b = 1.
2.6 Do step 3.5 if b != 1.
2.7 Line.

3.1 Type "1 bottle of beer on the wall".
3.2 Type "1 bottle of beer".
3.3 Do step 4.1.
3.4 Set b = 0.
3.5 Type b in form 1.

4.1 Type "You take one down, you pass it around".

Form 1:
_._ bottles of beer on the wall
Form 2:
_._ bottles of beer

Parsing begins!

L2Program Language

The PEG.js parser is now complete!!! Now all that is left to do is write the functions for the evaluator and control flow. For now I have locked the parser to only testing commands against MathExp as the root node. The function eval_math(tree) accepts a syntax tree with a root node marked as num for a plain numerical value, var for a reference to a variable, math for a simple add/sub/mult/div between two other math trees, or function which represents a call to a math function (built into the language). Below is an overview of the parse tree for a math expression (MathExp).

Math::Number

{ tag: "num", val: 0 }

Math::Variable

{
    tag: "var", 
    val: {
        id: "a",
        index: {
            // Another Math Expression
        }
    } 
}

Math::Math

{
    tag: "math", 
    val: {
        op: "+",
        left: {
            // Another Math Expression
        },
        right: {
            // Another Math Expression
        }
    } 
}

Math::Function

{
    tag: "function", 
    val: {
        func: "sqrt",
        param: {
            // Another Math Expression
        }
    } 
}

Math::Function (multiple params)

{
    tag: "function", 
    val: {
        func: "min",
        param: [
            {}, // Another Math Expression
            {}, // Another Math Expression
            {}  // Another Math Expression
        ]
    } 
}

Simulator Progress

L2Program Language

Progress on the JOSS language simulator is coming along nicely. I decided to take a break from transcribing and converting the grammar so I could work on the ui for a bit. This will be helpful as soon I’ll need a way to parse input commands and output the system replies.

So far the terminal is designed along with the input bar. Upon pressing enter the currently written command is added to the bottom of the terminal feed and (if necessary) the terminal is smoothly scrolled down to it’s new bottom. Like the original typewriter consoles on JOHNNIAC, inputs typed by the user appeared in black type and responses from the system are shown in green.

Further plans for the ui are to eventually include some form of modal or accordion based content organisation to allow a pane describing the history of JOHNNIAC, and a pane to describe the syntax for the language.

A JOSS simulator

L2Program Language

As I alluded to at the end of my last post on the subject of the JOSS programming language, my goal is to revive the language and create a usable version of it. (Why, you ask? Why not)

The design for the Simulator is to construct a webpage with a black/green terminal style display with a text box at the base of the terminal to allow command statements to be prepared and submitted to the system. On the backend the simulator will run entirely in Javascript, utilizing the PEG.js parser builder to tokenize and execute commands.

When a command is submitted to the terminal it will be given to PEG.js to parse and turn into a syntax tree of tokens. PEG.js also gives very precise parse errors which will allow the simulator to give the user feedback on their commands. If a command is successfully parsed the parse tree and the text version of the command will either be stored as as elements in the “program tape” a javascript object of the form:

{cmds:[
    1:{ // Part 1
        1:{ // Step 1
            text: "Do part 2.",
            tree: [{ /* JSON PARSE TREE */ }]
        }
    },
    2:{ // Part 2
        1:{ // Step 1
            text: "Stop.",
            tree: [{ token:"STOP", value:"Stop", children:[] }]
        }
    },
    ...
], vars:[
    a:[0:26, 1:3.14], // a = a(0) = 26, a(1) = 3.14
    b:[0:17],         // b = b(0) = 17
    ...
]}

By expressing the entire program and state of the simulator in JSON we gain the ability to easily have access to any part of the program or data. We also have the ability to save the current session using the browser’s local storage api or share the program by simply saving the serialized JSON to the server with a unique link. JSON is also the reason for storing the parse trees as objects rather than compiling them to an intermediary before use. By walking and evaluating a command by climbing through it’s parse tree we can use recursion to jump to other commands in the program tape. When we have fully climbed back up the tree to the root node or a command returns the Stop. token we know the program has finished executing.

One problem I see currently is that the language is based around the use of fixed precision arithmetic using 9 decimal places for precision. Currently I don’t know of any way to do math in fixed precision in JavaScript short of rolling my own set of maths classes, and I’d really rather not. For now we’ll work in standard floating point and see if it can be added in later.

The Grammar

Citation: "JOSS: Experience with an experimental computing service for users at remote typing consoles", J. C. Shaw, May 1965, Page: 10
Citation: "JOSS: Experience with an experimental computing service for users at remote typing consoles", J. C. Shaw, May 1965, Page: 10

Using the paper I found previously discussing the use of JOSS on JOHNNIAC over a 16 month period, I have been able to piece together a Context Free Grammar. While I am pretty happy with it, it’s not perfect. Every now and then I spot an error and fix it but for the most part I’m satisfied it’s solid.

There are however a couple of things intentionally in there which aren’t perfect but there is good reason for them. For instance, because JOSS lacks the ability to have user defined functions I have created a function token and within it an array of tokens, each representing a different standard math function available to the user. The reason for this is to allow parse time error checking of the number of variables.

Converting for PEG.js

So far I have gotten numbers and math expressions converted into a PEG.js parser. The current state of the parse can be seen on this Gist along with the BNF Grammar. Eventually I will move all of this into its own repo on Github but for now it’s all being developed in the browser; that is, I’m writing the PEG.js parse directly into their online compiler to test it as I go, so there is nothing local to save to a repo at the moment.

Below is the current BNF Grammar for the language.