project: haxON scripting language

Details

An early specification for a simple, JSON based, scripting language – haxON. haxON stands for "Hacks Object Notation", or "Hacks on!" (meaning not off), or "Hack son!". At some point this project will include haXON parser and executor implementations.

  • current version: 0.1
  • first created: September 12, 2018
  • last updated: October 31, 2018
Download source

Source explorer

README.md

View raw
# The haXON scripting language

<a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-sa/4.0/88x31.png" /></a><br />This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0 International License</a>


## Goals

- Lightweight;
- Easy and computationally cheap for parsing;
- Allowing code structures, which can be linked to native implementations;
- Having a native json representation;


## Parsing rules

1. If no left side of a key-value pair `<a>: <b>` is present, then the `<a>` takes a numerical value, which specifies a sequence index. For example:
```json
{
    "cat",
    ["foo", "bar"]
    {},
    flag: false,
    "dog"
}
```
is understood as:
```json
{
    "0": "cat",
    "1": ["foo", "bar"]
    "2": {},
    "flag": false
    "3": "dog"
}
```

2. The closing bracket `}`, is implicitely understood as `},`. For example, the haxON snippet:
```json
{
    a: {}
    b: ["foo", "bar"],
    c: {}
    d: "cat"
}
```
is translated to:
```json
{
    "a": {},
    "b": ["foo", "bar"],
    "c": {},
    "d": "cat"
}
```

3. The right side of any `<a>: <b>` key-value pair, can contain an *expression*, a *literal*, an *object*, an *array*, be *empty* (empty line), or contain a more complicated structure like a *command object*.

4. The `<command_name>"(" params object({}) | array([]) | literal | expression | empty ")" <body object({})>|empty` is refered to as a **command object**. Command objects can be used as *language statements*, *aliases* for native functions, *function calls*, *constructors*, etc. Here is an example of some of the usages of command objects:
```json
{
    a: 3,
    b: 4,
    
    //command object as a function declaration
    main: function({ o: 4, f: "a", g: false, s: []})
    {        
        c, d, e,//declarations
        ,,,//empty lines
        //meaningles scopes
        {
            
            o: o+4,
            c: 3
        }//implicit ,

        //command object as an if statement
        if(0<2 && 4<e){
           h,k,l,
           {
               h: 67,
               l: 23,
               k: h-l,//valid, but not prefered
               k= h-l,//prefered, because we can have += and other operators               
           }
           l=3+2,//translates to (#:l=3+2) key-value pair

        }//implicit ,
        elif(){
           
        }
        else{
           
        }

        o+=o*4,
        loop({ a: 0, cck: {a<3}, bupd: {a: a+1}, aupd: (){} }){            
        }
        
        return({k,j})
    }

    ...
}
```

## Ideas about more advanced features

* The `#...#` expressions, can be used for preprocessor expressions, like `include()`.
```json
{
    a: 3,
    b: 4,
    private: {
        c: 3,
        d: "hello!"
    }
    update: function({ o: 4, f: "a", g: false, s: []}){ ... }
    other-namespace: #include(./other.haxon)#
}
```
* Javascript like prototype inheritance. Example:

```json
{
    j: 5,
    k: 67,
    foo: prototype{
        c: 4, 
        d: 67, 
        foo: ({d: -1}){ this.d=d }
    }

    bar: that + prototype{
        make:(){}, 
        bar: ({d: 0}){
            base.foo({d})
        }
    }
    
    func: function(){ ... }

    main: function(){
        newobj,

        arr: [4, 2, 5, 67],

        arr= arr-[2, 4, 5],
        newobj= bar.make({d: 43})

        func<newobj>({o: 4, f: a, g: false}),//call func with internal this:= newobj
    }
}
```

<!--
- The command objects can be nested, support closure, other crazy scopes,
- If two of the same left sides are in an object, this means redeclaration and error! Any reassignment, using ":" must be done in an inner object in the sequential bit (1:, 2:, 3:, ...)
- no "<>" on a function call means <this>, where this refers to the outer object.
- objects and arrays can also be added (+ operator)
    * adding objects means concatenating and overriding properties (merging);
    * subtracting objects means removing fields from the first one
    * multiplying by an empty object means clear object;
- every object (assoc array) and array have a length property
- adding arrays means concatenating
- multiplying array by an empty array means empty the left side array
- subtracting arrays means find and remove elements by value
- subtracting arrays with objects means find and remove by key (arr)-({0,1,2,3})
- adding prototypes means inheritance
- make of prototype is constructor
- refferences are done using the & symbol or ref()
-->