UNPKG

sai-language

Version:

An object-oriented language designed to afford code comprehension and maintenance. Transpiles in-place to Javascript.

242 lines (158 loc) 5.07 kB
# SAI ## A Humane Language ### For the node ecosystem --- ## Compiles to plain JS ### Real-Time or Bulid-Ahead --- # Just-in-time compiler const SAI = require('sai-language') const objectNameProto = SAI.create('ObjectName') # Compiles __ObjectName.sai__ ## Resulting prototype is pure JS Compiles once per prototype, caches result --- # Build-ahead compiler > sai-build -o lib src ## Compile __.SAI__ files in _src_ to __.JS__ files in _lib_ ### Now it's all just Javascript const ObjectNameProto = require('ObjectName') --- # Bad News ## The generated JS is efficient but ugly > Basically > __It's object code__ > You can debug with it > But not strictly intended for human consumption ## There are (will be) source maps, though --- # Design Goals - Readable - Maintainable - Object oriented - Easy to integrate - Minimal speed penalty - Modern & Extensible --- # Tutorial --- # Code goes in objects $ cat HelloWorld.sai // Just regular text files object HelloWorld main // One object per source file // "main" object is the program start point Instantiate task // Instantiate invoked on object creation debug 'Hello World!' // A "task" is a standard function // Level of indent replaces {} // debug is a verb invoking console.log $ sai-run HelloWorld // Just-in-time compiler Hello World! _Future short examples omit the `object` wrapper for brevity._ --- # Every line starts with an action ply corpus as line // ply (iterator) set weight to 1 // set (assignment) ply line as word // ply (iterator) if number word // if (conditional) set weight to trial // set (assignment) elsif word.length >= window // elsif (conditional) push! valid word // push (Array method) if word.length > window // if (conditional) AddWord it, weight // AddWord (own method) _Level of indent replaces the use of structural braces {}._ --- # Readable - few structural symbols - expressive keywords - whitespace significant - conversational syntax - bareword instance variables --- # Maintainable - simple coding style - compile/runtime sanity checks - debugging hooks - source maps --- # Object oriented - multiple parent inheritance - `super` method calls - static initializers, `singleton` - Contracts a.k.a. "virtual methods" - Natural `this` binding & orphan code checks --- # Easy integration - Just-in-time compiler: for full SAI/JS integration - Build-ahead compiler: for lightweight/fast deploy - One run-time package needed: `sai-library` - No other external dependencies - Both compilers produce native JS prototypes - Easy to include and integrate in any project --- # Minimal speed penalty - Most constructs compile to simple JS - Extensive use of temp variables and clear syntax - Modern JS compilers optimize SAI very well - Runtime library `sai-library` is light weight - No other dependencies needed - SAI projects are self-contained and run fast --- # Modern & Extensible - Full support for generators & promises - Here documents, string composition - Value chaining & pipe-like operators - User-defined globals, constructs, operators --- # Okay but ## What does it look like? --- #### Whitespace matters while results's length < wordcount and duplicate > 0 set word from GetWord unless tally\word or word's length < minimum push'd results word else dec duplicate inc tally\word --- #### Every line begins with a verb. ply corpus as line set weight to 1 ply line as word if number word set weight to trial elsif word's length >= window push'd valid word if word's length > window AddWord it, weight --- #### Just read it. ProcessArg task given path, branch if IsDirectory(path) every FS.readdirSync(path) as leaf local candidate PATH.join(path, leaf) if '.sai' is PATH.extname(leaf) ProcessArg candidate, branch elsif leaf isnt '.' and leaf isnt '..' and IsDirectory(candidate) ProcessArg candidate, PATH.join(branch, leaf) else Build path, DestPath(path, branch) --- Inline function calls use `from` before the verb clause. set path from PATH.join basepath, filename Use `;` if necessary, to end a verb clause. --- ```` object Permutations main 1.0.0 AllHands to process given cards local Pick process given hand, deck if deck count every deck as card, index yielding !Pick hand concat card, deck delete index else yield hand yielding !Pick empty, cards Instantiate to task debug "Permutation sample: three fruit." every !@AllHands list apple, banana, cherry debug . ````