npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

aboveaveragescript

v1.0.0

Published

Ever so slightly above average

Downloads

42

Readme

#AboveAverageScript

Javascript forcefully mutated into a syntactically beautiful language. This is AboveAverageScript. Formed from a mixture of ECMAScript 6, Python, and CoffeeScript, AboveAverageScript forces you to space your code perfectly, without confining you to one specific style for doing so. In addition, several new operators await you, allowing you to hastily deal with objects and properties. Give it a shot. Love it or hate it, one thing is for sure: It sure as hell beats writing in Java.

AboveAverageScript Logo

##Grammar ###Macrosyntax


    Program         ::= Stmt Block EOF
    Block           ::= (Newline Stmt)*
    Stmt            ::= DeclareStmt  
                     |  AssignStmt
                     |  NativeStmt
                     |  SwitchStmt
                     |  Loop
                     |  IfStmt
                     |  ConsumeStmt
                     |  ReturnStmt
                     |  ControlStmt
                     |  Exp

    DeclareStmt     ::= 'let' (ExpList '=' (ObjInd | ExpList)) | (SetEqual (',' Indent Newline SetEqual (',' Newline SetEqual)* Dedent ) )
    AssignStmt      ::= (ExpList AssignOp (ObjInd | ExpList)) | (SetAssign (',' Indent Newline SetAssign (',' Newline SetAssign)* Dedent ) )
    ConsumeStmt     ::= ExpList? '<-' Exp
    ReturnStmt      ::= 'ret' Exp?
    ControlStmt     ::= 'stop' | 'skip'
    SetAssign       ::= Exp AssignOp Exp
    SetEqual        ::= Exp '=' Exp

    IfStmt          ::= 'if' Exp ':' Indent Block Dedent (Newline 'elif' Exp ':' Indent Block Dedent)* (Newline 'else' Indent Block Dedent)?
    SwitchStmt      ::= 'switch' Exp ':' Indent Case+ Defaults? Dedent
    Case            ::= Newline 'case' Exp18 ':' Indent Block Dedent
    Defaults        ::= Newline 'default' ':' Indent Block Dedent
    NativeStmt      ::= '***native***'

    Loop            ::= WhileLoop | ForLoop
    WhileLoop       ::= DoWhile | While
    DoWhile         ::= 'do' Indent Block Dedent Newline 'while' Exp
    While           ::= 'while' Exp ':' Indent Block Dedent
    ForLoop         ::= (ForIn | ForColon | For) ':' Indent Block Dedent
    ForIn           ::= 'for' Id (',' Id)? 'in' Exp
    ForColon        ::= 'for' Id ':' Exp
    For             ::= 'for' ( ('let'? Id '=')? Exp ',')? Exp ',' Exp

    Exp             ::= Exp1 (ForIn | ForColon)*
    Exp1            ::= Exp2 ('if' Exp2 ('else' Exp2)?)?
    Exp2            ::= Exp3 ('in' Exp3)*
    Exp3            ::= Exp4 ('?' Exp4 ':' Exp4)?
    Exp4            ::= Exp5 ('or' Exp5)*
    Exp5            ::= Exp6 ('and' Exp6)*
    Exp6            ::= Exp7 ('|' Exp7)*
    Exp7            ::= Exp8 ('^' Exp8)*
    Exp8            ::= Exp9 ('&' Exp9)*
    Exp9            ::= Exp10 (EqualOp Exp10)*
    Exp10           ::= Exp11 (CompareOp Exp11)*
    Exp11           ::= Exp12 (ShiftOp Exp12)*
    Exp12           ::= Exp13 (AddOp Exp13)*
    Exp13           ::= Exp14 (MulOp Exp14)*
    Exp14           ::= PrefixOp? Exp15
    Exp15           ::= Exp16 PostfixOp?
    Exp16           ::= 'new'? Exp17 Call?
    Exp17           ::= Exp18 (ArrayCont | Call | '.' Exp17)*
    Exp18           ::= Id | BoolLit | IntLit | StringLit | '(' Exp Newline? ')' | Func | ArrayLit | ObjectInline | This | RegExpLit

    ArrayLit        ::= ('[' ']') | ArrayCont
    ArrayCont       ::= '[' (Exp (',' Exp)*) | (Indent Newline Exp (',' Newline? Exp)* Dedent Newline) Newline? ']'
    ExpList         ::= Exp (Newline? ',' Exp)*
    RegExpLit       ::= '\/[^\/\\]+(?:\\.[^\/\\]*)*\/[igm]{0,3}'
    Func            ::= 'func' (Id (',' Id)* )? '->' ('ret'? Exp) | (Indent Block Dedent)
    ObjectInline    ::= '{' (Property (',' Property)*) | (Indent Newline Property (',' Newline Property)* Dedent Newline) '}'
    ObjInd          ::= Indent (Newline (Prop|PropInd) )+ Dedent
    Prop            ::= (Id | BoolLit | StringLit) ':' Exp
    PropInd         ::= (Id | BoolLit | StringLit) ':' (Exp | ObjInd)
    Call            ::= '(' ( ExpList (Newline? ',' Indent Newline Exp (Newline ',' Exp)* Dedent)? Newline?)? ')'

###Microsyntax


    AssignOp        ::= '=' | '+=' |'-=' | '*=' | '/=' | '%=' | '<<=' | '>>=' | '>>>=' | '&=' | '^=' | '|='
    EqualOp         ::= '!==' | '===' | '!=' | '=='
    CompareOp       ::= '>=' | '>' | '<=' | '<'
    ShiftOp         ::= '>>>' | '>>' | '<<'
    AddOp           ::= '+' | '-'
    MulOp           ::= '%' | '/' | '*'
    PrefixOp        ::= '--' | '++' | '-' | '+' | '~' | 'not'
    PostfixOp       ::= '--' | '++'

    IntLit          ::= '[+-]?((0x[a-fA-F0-9]+)|(\d+(\.\d+)?([eE][+-]?\d+)?))'
    StringLit       ::= '\"[^\"\\]*(?:\\.[^\"\\]*)*\"|\'[^\'\\]*(?:\\.[^\'\\]*)*\''
    Id              ::= '[_$a-zA-Z][$\w]*(?=[^$\w]|$)'
    This            ::= '_'
    Newline         ::= '\n'
    Indent          ::= '\i'
    Dedent          ::= '\d'
    EOF             ::= '@EOF'

The Macrosyntax doesn't actually capture everything, in particular indents within expressions. The reason being that it isn't context free, and for good reason. If it were based on context, it would completely ruin precedence. So, indents and dedents follow a simple rule: indent before or after any operator, and dedent at the end of an expression. If you enter a parenthesized expression or enter a series of dot accessors, you're in a new expression until it stops. Long story short, just take a look at the examples. You'll see the pattern. It's hard to explain what perfect style means.

Here's some basic variable code:


    let a = 70                                  var a = 70;
    a++                                         a++;
    let b, c = a/20                             _['$t0'] = a/20;
                                                var b = _['$t0'];
                                                var c = _['$t0'];
    a %= c                                      a %= c;
    b, c = a, b                                 _['$t0'] = a;
                                                _['$t1'] = b;
                                                b = _['$t0'];
                                                c = _['$t1'];
    let d = a/b,                                var d = a/b;
        e = b/c,                                var e = b/c;
        f = c/d                                 var f = c/d;
    a, b, c, d, e, f >>= 1                      _['$t0'] = 1;
                                                a >>= _['$t0'], b >>= _['$t0'], c >>= _['$t0'],
                                                d >>= _['$t0'], e >>= _['$t0'], f >>= _['$t0'];

AboveAverageScript is still Javascript, and as such is object oriented.


    let fib = func a, amt ->                                    var fib = function(a, amt) {
        amt = defaults(amt, 1)                                      amt = defaults(amt, 1);
        ret amt if a in '01' else fib(a - 1, amt * a)               if('01'.indexOf(a) >= 0) {
                                                                        return amt;
                                                                    else {
                                                                        return fib(a - 1, amt*a);
                                                                    }
                                                                }

    let z = fib(3)                                              var z = fib(30;)

    let Chicken =                                               var Chicken = {
        breed: 'Bantam'                                             breed: 'Bantam',
        gender: 'Male'                                              gender: 'Male',
        eggsLaid: 14                                                eggsLaid: 14,
        cry: func -> log('COCKADOODLEDOO!')                         cry: function() {
                                                                        log('COCKADOODLEDOO!');
                                                                    }

    let Circle = func props ->             // For the translation of the rest of this section, check
        _['x', 'y', 'radius'] = 0          // the wiki. It can get quite involved when explaining how
        _ <- props                         // the property consumption ('<-') operator works.
        _.setLocation = func point ->
            _ <- point

    let Ellipse = new Circle({x: 0, y: 0, radius: 5})
    Ellipse <- {stroke: 'dashed', color: 'rgb(100,200,50)'}

I'm sure you noticed the funny little operator above, not to mention the odd new syntax for property access. Well, that's part of the new design. In a nutshell, the property consumption operator will look for named properties on the outermost expression of the righthand side, and assign them with the same name to the left hand side as properties. If no named properties are found, then it will simply take ALL properties from the right hand side. Please note that means the right hand side MUST be an object. Now, as for the left hand side, you have a few options. You can put in a series of expressions, whom all of which will recieve the properties. However, if no expression is given, then it will actually assign those variables to the local scope. However, assigning to the local scope tends to be slower (because it prevents modern Javascript engines from optimizing that code fragment), so you're better off not using it too often or too rapidly. As this is a much more involved concept, especially the code it translates to, you can find far more information on the wiki.

Of course, there was that other thing. The property access that was treated as if it were an array. Well, that's actually the most accurate description I can give. It's just your average property access with square brackets, except that you can list multiple items. Oh, and in case it wasn't clear, AboveAverageScript uses _ to specify the containing object, opposed to using this.

Pressing on...


    let term = 300,                                                     var term = 300;
        list = [3, 5, 7, 9],                                            var list = [3, 5, 7, 9];
        index = 0                                                       var index = 0;
    while term > 0:                                                     while(term > 0) {
        for(i, val in list):                                                for(var i = 0; i < list.length; i++) {
                                                                                var val = list[i];
            term -= val                                                         term -= val;
            index = i                                                           index = i;
            if term <= 0:                                                       if(term <= 0) {
                stop                                                                break;
                                                                                }
                                                                            }
                                                                        }

Conditionals look a tad different, however.


    let x = int(input("Please enter a number"))                           var x = int( input("Please enter a number") );   // input function is user defined.
    if x > 0:                                                             if( x > 0 ) {
        log("Feeling positive?")                                              log("Feeling positive?");
    elif x === 0:                                                         } else if( x === 0 ) {
        log("Zero? Really?")                                                  log("Zero? Really?");
    else                                                                  } else {
        log("Don't be so negative")                                          log("Don't be so negative");
                                                                          }

Comments are casual.


    let teascript = "Awesome"                                             var teascript = "Awesome";   // Variables should be declared with let.
    CoffeeScript = "Casual"                                               CoffeeScript = "Casual";     // Variables can be declared without let,
    $ = "$"                                                               $ = "$";                     // but its far less clear.
                            /* Multiline comments are also available! */

Moving on. We've all used JQuery at one time or another. Well, since AboveAverageScript creates a few built-in functions, they need to be placed somewhere. When using JQuery, the $(function() { }) often proves helpful for ensuring your webpage loads quickly. Should you want these built-ins to be placed within your JQuery function, simply say ***native***, and the compiler will know to place the built-ins there. Otherwise, they will just go to the top of your script.


    $(func ->
        ***native***
        log("Now you can use these built-ins in your code without slowing down your webpage!")
    )

Here are the current (more pythonic) built-ins:


    type(x)         // A replacement for typeof, function-ified.
    defaults(a, b)  // A function that helps make default parameters. If a is defined, then it returns a. Otherwise, b is returned.
    int(x, base)    // A function that is a wrapper for the much more verbose parseInt function
    float(x)        // A function that is a wrapper for the much more verbose parseFloat function
    is(x, y)        // A replacement for instanceof, function-ified, translating into 'x instanceof y'
    log(x)          // A wrapper for console.log
    error(x)        // A wrapper for console.error
    del(x, y)       // A replacement for delete, function-ified, translating into 'delete y[x]'
    len(obj)        // Quite literally a method call instead of saying '.length'
    size(obj)       // Returns the number of keys the object has.
    range(x, y, z)  // It works exactly the same way it does in Python. To save space, I'll defer you to their documentation.
    isUndef(val)    // Returns true if val is undefined. Its like isNaN for undefined.
    abs(x)          // A wrapper for Math.abs
    pow(x, y)       // A wrapper for Math.pow
    lazy(x, *)      // Returns a function that calls x with all of the remaining arguments when called.
    lazier(x, args) // Returns a function that calls x with the all of the arguments in the array args when called.

Just to make sure everything has been listed, here are all of the available loops.


    let y = ["true", "false", true, 0, 9, {}]

    // for val in -> iterates over property values of object
    log(x) for x in y   // prints: "true", "false", true, 0, 9, {}

    // for key, val in -> iterates over property values of object
    log(a, b) for a, b in y   // prints: 0 "true", 1 "false", 2 true, 3 0, 4 9, 5 {}

    // for key:  -> iterates over key-value pairs?
    log(x) for x : y   // prints: 0, 1, 2, 3, 4, 5

Minor notes:

  • Camel Casing is preferred
  • Spacing norm is 4 spaces (NOT TABS)
  • Expect the (ever so slightly) above average
  • Not sure if you should use a semicolon? Don't use it. Ever. Ever. They have been banned.