UNPKG

sai-language

Version:

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

939 lines (932 loc) 51.2 kB
#!/usr/bin/env node // Javascript source for IterateC.sai transpiled by SAI // "use strict"; var prototype=new function() { this.Constructor=function(){}; this.__tobelocked=[]; this.__tobefrozen=[]; this.__contracts=[]; this.__unverified=true; this.isof={}; return this; }(); var $AI=require("sai-library"); // Generated code follows var __context={"loader":"SAI.GetSourceFromFilename","path":"/Users/seanmpuckett/Documents/ProjSync/Node/sai/src/Construct.sai","workdir":"/Users/seanmpuckett/Documents/ProjSync/Node/sai/src","mtime":"2018-04-04T23:09:42.435Z","fetched":"2018-04-11T22:24:02.512Z"}; var __path=require('path'); var __require=function(fn) { try { return require(fn); } catch (e) { try { return require(__path.join(process.cwd(),fn)); } catch (e) { return require(__path.join(process.cwd(),'node_modules',fn)); } } } var isa = prototype.isa = 'Construct'; var $bindfail = function(m) { throw new Error("SAI: A call to " + m + " on object " + isa + " has come unbound from any instance of that object. (If this is not in error, mark the declaration of " + m + " as unbound.)"); } prototype.isof['Construct'] = { version: '0.0.0-unspecified', isa: isa, context: __context, type: "singleton" }; prototype.__tobelocked = prototype.__tobelocked.concat(["OutVarHelper", "ExprsHelper", "isa"]); prototype.__tobefrozen = prototype.__tobefrozen.concat(["isof"]); prototype.__contracts = prototype.__contracts.concat(['manifest']); var $12g = prototype['OutVarHelper'] || function() {}; prototype['OutVarHelper'] = function(p) { var $0_this, $1_key, $2_list, $3_length, $4_none, $5_trial, $ = this['OutVarHelper'] ? this : $bindfail('OutVarHelper'), $_c, $_d, _out = p, _vars; { _vars = []; if ($5_trial = (_out)) { var $2_list = _out, $1_key; if (undefined === $2_list) $2_list = []; var $3_length = $2_list.length; for ($1_key = 0; $1_key < $3_length; $1_key++) { $0_this = $2_list[$1_key]; _vars.push($0_this[0][1]);; } } return (_vars); } }; var $13g = prototype['ExprsHelper'] || function() {}; prototype['ExprsHelper'] = function(p) { var $6_this, $ = this['ExprsHelper'] ? this : $bindfail('ExprsHelper'), $_b, _exprs = p; { return (((undefined !== ($_b = (undefined === ($_b = (_exprs)) ? undefined : ($_b[2])))) ? $_b : [])); } }; var __context={"loader":"SAI.GetSourceFromFilename","path":"/Users/seanmpuckett/Documents/ProjSync/Node/sai/src/IterateC.sai","workdir":"/Users/seanmpuckett/Documents/ProjSync/Node/sai/src","mtime":"2018-04-11T16:42:21.070Z","fetched":"2018-04-11T22:24:02.191Z"}; var __path=require('path'); var __require=function(fn) { try { return require(fn); } catch (e) { try { return require(__path.join(process.cwd(),fn)); } catch (e) { return require(__path.join(process.cwd(),'node_modules',fn)); } } } var isa = prototype.isa = 'IterateC'; var $bindfail = function(m) { throw new Error("SAI: A call to " + m + " on object " + isa + " has come unbound from any instance of that object. (If this is not in error, mark the declaration of " + m + " as unbound.)"); } prototype.isof['IterateC'] = { version: '0.0.0-unspecified', isa: isa, context: __context, type: "singleton" }; prototype.__tobelocked = prototype.__tobelocked.concat(["manifest", "docs", "FlowControlConstruct", "EveryConstruct", "IndexedConstruct", "IterateConstruct", "EachConstruct", "PlyConstruct", "WhileConstruct", "CountConstruct", "Documents", "isa"]); prototype.__tobefrozen = prototype.__tobefrozen.concat(["isof"]); prototype.isof[prototype.isa].inherit = prototype.__inherits = ['Construct']; Object.defineProperty(prototype, "manifest", { configurable: true, enumerable: true, get: function(p) { var $ = this; { return ({ 'constructs': { 'every': { repeats: false, clauses: { 'every': { exprusing: true, exproutblock: true }, 'else': { block: true } }, handler: function() { return ($.EveryConstruct).apply($, arguments); } }, 'iterate': { repeats: false, clauses: { 'iterate': { exprusing: true, exproutblock: true }, 'else': { block: true } }, handler: function() { return ($.IterateConstruct).apply($, arguments); } }, 'each': { repeats: false, clauses: { 'each': { exprusing: true, exproutblock: true }, 'else': { block: true } }, handler: function() { return ($.EachConstruct).apply($, arguments); } }, 'index': { repeats: false, clauses: { 'index': { exprsusing: true, exprsoutblock: true }, 'else': { block: true } }, handler: function() { return ($.IndexedConstruct).apply($, arguments); } }, 'ply': { repeats: false, clauses: { 'ply': { exprusing: true, exproutblock: true }, 'else': { block: true } }, handler: function() { return ($.PlyConstruct).apply($, arguments); } }, 'while': { repeats: false, clauses: { 'while': { exproutblock: true } }, handler: function() { return ($.WhileConstruct).apply($, arguments); } }, 'until': { repeats: false, clauses: { 'until': { exproutblock: true } }, handler: function() { return ($.WhileConstruct).apply($, arguments); } }, 'dowhile': { repeats: false, clauses: { 'dowhile': { exproutblock: true } }, handler: function() { return ($.WhileConstruct).apply($, arguments); } }, 'dountil': { repeats: false, clauses: { 'dountil': { exproutblock: true } }, handler: function() { return ($.WhileConstruct).apply($, arguments); } }, 'break': { repeats: false, clauses: { 'break': { none: true } }, handler: function() { return ($.FlowControlConstruct).apply($, arguments); } }, 'continue': { repeats: false, clauses: { 'continue': { none: true } }, handler: function() { return ($.FlowControlConstruct).apply($, arguments); } }, 'count': { repeats: false, clauses: { 'count': { exprsoutblock: true }, 'else': { block: true } }, handler: function() { return ($.CountConstruct).apply($, arguments); } }, 'countdown': { repeats: false, clauses: { 'countdown': { exprsoutblock: true }, 'else': { block: true } }, handler: function() { return ($.CountConstruct).apply($, arguments); } } } }); } }, set: undefined }); Object.defineProperty(prototype, "docs", { configurable: true, enumerable: true, get: function(p) { var $0_this, $ = this, $_c, $_d; { return ($.Documents()); } }, set: undefined }); var $3g = prototype['FlowControlConstruct'] || function() {}; prototype['FlowControlConstruct'] = function(p) { var $1_this, $2, $3_this, $ = this['FlowControlConstruct'] ? this : $bindfail('FlowControlConstruct'), _body; $AI.expectsThrow(p, { "clauses": true, "tools": true }, '\'FlowControlConstruct\''); { _body = ''; var $3_this = p.clauses[0]; switch ($2 = ($3_this.type)) { case 'break.none': _body = 'break;\n'; break; case 'continue.none': _body = 'continue;\n'; break; default: return ({ error: 'SAI compiler: unhandled ' + $3_this.type + ' in FlowControlConstruct -- this is a compiler bug.' }); break; }; return ({ body: _body }); } }; var $4g = prototype['EveryConstruct'] || function() {}; prototype['EveryConstruct'] = function(p) { var $4_this, $5_trial, $6, $7_error, $ = this['EveryConstruct'] ? this : $bindfail('EveryConstruct'), $_b, $_c, $_d, _elseclause, _loop, _main, _none, _outs, _preface, _text, _vars; $AI.expectsThrow(p, { "clauses": true, "tools": true }, '\'EveryConstruct\''); { if ($5_trial = ((p.clauses.length > 2))) { return ({ error: 'SAI compile: EVERY can have at most one ELSE clause.' }); } _main = p.clauses[0]; _none = p.clauses[1]; try { switch ($6 = (_main.type)) { case 'every.exproutblock': _outs = $.OutVarHelper(_main.args.out); _vars = { block: _main.args.block, 'source': _main.args.expr, 'this': ((undefined !== ($_b = _outs[0])) ? $_b : false), 'key': ((undefined !== ($_b = _outs[1])) ? $_b : false), iter: false, elem: false, none: (undefined === ($_b = ((undefined === ($_b = (_none)) ? undefined : ($_b.args)))) ? undefined : ($_b.block)) }; _preface = 'var \x5e{iter}=$AI.kviterate_op(\x5e{source});' + '\n' + 'var \x5e{elem}=\x5e{iter}.next();' + '\n' + ''; _elseclause = function(p) { { if (!(_none)) { return ('if (!\x5e{elem}.done)'); } else { return ('if (\x5e{elem}.done) { \x5e{none} } else' + '\n' + ''); } } }(); _loop = 'do {' + '\n' + '\x5e{this}=\x5e{elem}.value[1];' + '\n' + '\x5e{key}=\x5e{elem}.value[0];' + '\n' + '\x5e{block}' + '\n' + '\x5e{elem}=\x5e{iter}.next();' + '\n' + '} while (!\x5e{elem}.done);' + '\n' + ''; _text = p.tools.replacer((_preface + (_elseclause + _loop)), _vars); break; case 'every.exprusing': _vars = { 'task': _main.args.using, source: _main.args.expr, iter: false, elem: false, none: (undefined === ($_b = ((undefined === ($_b = (_none)) ? undefined : ($_b.args)))) ? undefined : ($_b.block)) }; _preface = 'var \x5e{iter}=$AI.kviterate_op(\x5e{source});' + '\n' + 'var \x5e{elem}=\x5e{iter}.next();' + '\n' + ''; _elseclause = function(p) { { if (!(_none)) { return ('if (!\x5e{elem}.done)'); } else { return ('if (\x5e{elem}.done) { \x5e{none} } else' + '\n' + ''); } } }(); _loop = 'do {' + '\n' + '\x5e{task}(\x5e{elem}.value[1], \x5e{elem}.value[0]);' + '\n' + '\x5e{elem}=\x5e{iter}.next();' + '\n' + '} while (!\x5e{elem}.done);' + '\n' + ''; _text = p.tools.replacer((_preface + (_elseclause + _loop)), _vars); break; default: return ({ error: 'Unhandled construct type ' + _main.type + ' in EveryConstruct' }); break; } } catch ($7_error) { $AI.debug_op($7_error); } return ({ body: _text }); } }; var $5g = prototype['IndexedConstruct'] || function() {}; prototype['IndexedConstruct'] = function(p) { var $10, $11_error, $8_this, $9_trial, $ = this['IndexedConstruct'] ? this : $bindfail('IndexedConstruct'), $_b, $_c, $_d, _elseclause, _loop, _main, _none, _outs, _preface, _text, _vars; $AI.expectsThrow(p, { "clauses": true, "tools": true }, '\'IndexedConstruct\''); { if ($9_trial = ((p.clauses.length > 2))) { return ({ error: 'SAI compile: INDEX can have at most one ELSE clause.' }); } _main = p.clauses[0]; _none = p.clauses[1]; if (!((_main.args.exprs.length === 2))) { return ({ error: 'SAI Compiler: the INDEX construct requires two comma-separated expressions, the first is the array/object to traverse, the second an array of keys.' }); } try { switch ($10 = (_main.type)) { case 'index.exprsoutblock': _outs = $.OutVarHelper(_main.args.out); _vars = { 'rawlist': _main.args.exprs[0], 'rawkeys': _main.args.exprs[1], 'this': ((undefined !== ($_b = _outs[0])) ? $_b : false), 'key': ((undefined !== ($_b = _outs[1])) ? $_b : false), 'list': ((undefined !== ($_b = _outs[2])) ? $_b : false), 'iterator': false, 'next': false, 'block': _main.args.block, none: ((undefined !== ($_b = (undefined === ($_b = ((undefined === ($_b = (_none)) ? undefined : ($_b.args)))) ? undefined : ($_b.block)))) ? $_b : false) }; _preface = 'var \x5e{list}=\x5e{rawlist},\x5e{key},' + '\n' + ' \x5e{iterator}=$AI.kviterate_op(\x5e{rawkeys});' + '\n' + ' \x5e{next}=\x5e{iterator}.next();' + '\n' + ''; _loop = 'while (!\x5e{next}.done) {' + '\n' + ' \x5e{key}=\x5e{next}.value[1]; \x5e{this}=\x5e{list}[\x5e{key}];' + '\n' + ' \x5e{block};' + '\n' + ' \x5e{next}=\x5e{iterator}.next();' + '\n' + '}' + '\n' + ''; _elseclause = function(p) { { if (!(_none)) { return (''); } else { return ('if (\x5e{next}.done) { \x5e{none} } else' + '\n' + ''); } } }(); _text = p.tools.replacer((_preface + (_elseclause + _loop)), _vars); break; case 'index.exprsusing': _vars = { 'rawlist': _main.args.exprs[0], 'rawkeys': _main.args.exprs[1], 'list': false, 'iterator': false, 'next': false, 'fn': _main.args.using, none: ((undefined !== ($_b = (undefined === ($_b = ((undefined === ($_b = (_none)) ? undefined : ($_b.args)))) ? undefined : ($_b.block)))) ? $_b : false) }; _preface = 'var \x5e{list}=\x5e{rawlist},' + '\n' + ' \x5e{iterator}=$AI.kviterate_op(\x5e{rawkeys});' + '\n' + ' \x5e{next}=\x5e{iterator}.next();' + '\n' + ''; _loop = 'while (!\x5e{next}.done) {' + '\n' + ' \x5e{fn}(\x5e{list}[\x5e{next}.value[1]],\x5e{next}.value[1],\x5e{list});' + '\n' + ' \x5e{next}=\x5e{iterator}.next();' + '\n' + '}' + '\n' + ''; _elseclause = function(p) { { if (!(_none)) { return (''); } else { return ('if (\x5e{next}.done) { \x5e{none} } else' + '\n' + ''); } } }(); _text = p.tools.replacer((_preface + (_elseclause + _loop)), _vars); break; default: return ({ error: 'Unhandled construct type ' + _main.type + ' in IndexConstruct' }); break; } } catch ($11_error) { $AI.debug_op($11_error); } return ({ body: _text }); } }; var $6g = prototype['IterateConstruct'] || function() {}; prototype['IterateConstruct'] = function(p) { var $12_this, $13_trial, $14, $15_error, $ = this['IterateConstruct'] ? this : $bindfail('IterateConstruct'), $_b, $_c, $_d, _elseclause, _loop, _main, _none, _outs, _preface, _text, _vars; $AI.expectsThrow(p, { "clauses": true, "tools": true }, '\'IterateConstruct\''); { if ($13_trial = ((p.clauses.length > 2))) { return ({ error: 'SAI compile: ITERATE can have at most one ELSE clause.' }); } _main = p.clauses[0]; _none = p.clauses[1]; try { switch ($14 = (_main.type)) { case 'iterate.exproutblock': _outs = $.OutVarHelper(_main.args.out); _vars = { block: _main.args.block, 'source': _main.args.expr, 'this': ((undefined !== ($_b = _outs[0])) ? $_b : false), 'key': ((undefined !== ($_b = _outs[1])) ? $_b : false), iter: false, elem: false, none: ((undefined !== ($_b = (undefined === ($_b = ((undefined === ($_b = (_none)) ? undefined : ($_b.args)))) ? undefined : ($_b.block)))) ? $_b : false) }; _preface = 'var \x5e{iter}=$AI.iterator_op(\x5e{source});' + '\n' + 'var \x5e{elem}=\x5e{iter}.next();' + '\n' + ''; _elseclause = function(p) { { if (!(_none)) { return ('if (!\x5e{elem}.done)'); } else { return ('if (\x5e{elem}.done) { \x5e{none} } else' + '\n' + ''); } } }(); _loop = 'for (var \x5e{key}=0; !\x5e{elem}.done; \x5e{elem}=\x5e{iter}.next()){' + '\n' + '\x5e{this}=\x5e{elem}.value;' + '\n' + '\x5e{block};' + '\n' + '\x5e{key}++;' + '\n' + '}' + '\n' + ''; _text = p.tools.replacer((_preface + (_elseclause + _loop)), _vars); break; case 'iterate.exprusing': _vars = { 'task': _main.args.using, source: _main.args.expr, 'key': false, iter: false, elem: false, none: ((undefined !== ($_b = (undefined === ($_b = ((undefined === ($_b = (_none)) ? undefined : ($_b.args)))) ? undefined : ($_b.block)))) ? $_b : false) }; _preface = 'var \x5e{iter}=$AI.iterator_op(\x5e{source});' + '\n' + 'var \x5e{elem}=\x5e{iter}.next();' + '\n' + 'var \x5e{key}=0;' + '\n' + ''; _elseclause = function(p) { { if (!(_none)) { return ('if (!\x5e{elem}.done)'); } else { return ('if (\x5e{elem}.done) { \x5e{none} } else' + '\n' + ''); } } }(); _loop = 'do {' + '\n' + '\x5e{task}(\x5e{elem}.value, \x5e{key});' + '\n' + '\x5e{key}++;' + '\n' + '\x5e{elem}=\x5e{iter}.next();' + '\n' + '} while (!\x5e{elem}.done);' + '\n' + ''; _text = p.tools.replacer((_preface + (_elseclause + _loop)), _vars); break; default: return ({ error: 'Unhandled construct type ' + _main.type + ' in IterateConstruct' }); break; } } catch ($15_error) { $AI.debug_op($15_error); } return ({ body: _text }); } }; var $7g = prototype['EachConstruct'] || function() {}; prototype['EachConstruct'] = function(p) { var $16_this, $17_trial, $18, $19_error, $ = this['EachConstruct'] ? this : $bindfail('EachConstruct'), $_b, $_c, $_d, _elseclause, _loop, _main, _none, _outs, _preface, _text, _vars; $AI.expectsThrow(p, { "clauses": true, "tools": true }, '\'EachConstruct\''); { if ($17_trial = ((p.clauses.length > 2))) { return ({ error: 'SAI compile: EACH can have at most one ELSE clause.' }); } _main = p.clauses[0]; _none = p.clauses[1]; try { switch ($18 = (_main.type)) { case 'each.exproutblock': _outs = $.OutVarHelper(_main.args.out); _vars = { block: _main.args.block, 'source': _main.args.expr, 'this': ((undefined !== ($_b = _outs[0])) ? $_b : false), 'key': ((undefined !== ($_b = _outs[1])) ? $_b : false), 'list': ((undefined !== ($_b = _outs[2])) ? $_b : false), none: ((undefined !== ($_b = (undefined === ($_b = ((undefined === ($_b = (_none)) ? undefined : ($_b.args)))) ? undefined : ($_b.block)))) ? $_b : false) }; _preface = 'var \x5e{list}=\x5e{source},\x5e{key}=undefined;' + '\n' + 'if (undefined===\x5e{list}) \x5e{list}={};' + '\n' + ''; _loop = 'for (\x5e{key} in \x5e{list}) {' + '\n' + '\x5e{this}=\x5e{list}[\x5e{key}];' + '\n' + '\x5e{block};' + '\n' + '}' + '\n' + ''; _elseclause = function(p) { { if (!(_none)) { return (''); } else { return ('if (\x5e{key}===undefined) { \x5e{none} }' + '\n' + ''); } } }(); _text = p.tools.replacer((_preface + (_loop + _elseclause)), _vars); break; case 'each.exprusing': _vars = { 'task': _main.args.using, source: _main.args.expr, 'key': false, 'list': false, none: ((undefined !== ($_b = (undefined === ($_b = ((undefined === ($_b = (_none)) ? undefined : ($_b.args)))) ? undefined : ($_b.block)))) ? $_b : false) }; _preface = 'var \x5e{list}=\x5e{source},\x5e{key}=undefined;' + '\n' + 'if (undefined===\x5e{list}) \x5e{list}={};' + '\n' + ''; _elseclause = function(p) { { if (!(_none)) { return (''); } else { return ('if (\x5e{key}===undefined) { \x5e{none} }' + '\n' + ''); } } }(); _loop = 'for (\x5e{key} in \x5e{list}) {' + '\n' + '\x5e{task}(\x5e{list}[\x5e{key}],\x5e{key},\x5e{list});' + '\n' + '}' + '\n' + ''; _text = p.tools.replacer((_preface + (_loop + _elseclause)), _vars); break; default: return ({ error: 'Unhandled construct type ' + _main.type + ' in EachConstruct' }); break; } } catch ($19_error) { $AI.debug_op($19_error); } return ({ body: _text }); } }; var $8g = prototype['PlyConstruct'] || function() {}; prototype['PlyConstruct'] = function(p) { var $20_this, $21_trial, $22, $23_error, $ = this['PlyConstruct'] ? this : $bindfail('PlyConstruct'), $_b, $_c, $_d, _elseclause, _loop, _main, _none, _outs, _preface, _text, _vars; $AI.expectsThrow(p, { "clauses": true, "tools": true }, '\'PlyConstruct\''); { if ($21_trial = ((p.clauses.length > 2))) { return ({ error: 'SAI compile: PLY can have at most one ELSE clause.' }); } _main = p.clauses[0]; _none = p.clauses[1]; try { switch ($22 = (_main.type)) { case 'ply.exproutblock': _outs = $.OutVarHelper(_main.args.out); _vars = { block: _main.args.block, 'source': _main.args.expr, 'this': ((undefined !== ($_b = _outs[0])) ? $_b : false), 'key': ((undefined !== ($_b = _outs[1])) ? $_b : false), 'list': ((undefined !== ($_b = _outs[2])) ? $_b : false), 'length': false, none: ((undefined !== ($_b = (undefined === ($_b = ((undefined === ($_b = (_none)) ? undefined : ($_b.args)))) ? undefined : ($_b.block)))) ? $_b : false) }; _preface = 'var \x5e{list}=\x5e{source},\x5e{key};' + '\n' + 'if (undefined===\x5e{list}) \x5e{list}=[];' + '\n' + 'var \x5e{length}=\x5e{list}.length;' + '\n' + ''; _loop = 'for (\x5e{key}=0; \x5e{key}<\x5e{length}; \x5e{key}++) {' + '\n' + '\x5e{this}=\x5e{list}[\x5e{key}];' + '\n' + '\x5e{block};' + '\n' + '}' + '\n' + ''; _elseclause = function(p) { { if (!(_none)) { return (''); } else { return ('if (\x5e{key}===0) { \x5e{none} }' + '\n' + ''); } } }(); _text = p.tools.replacer((_preface + (_loop + _elseclause)), _vars); break; case 'ply.exprusing': _vars = { 'task': _main.args.using, source: _main.args.expr, 'key': false, 'list': false, 'length': false, none: ((undefined !== ($_b = (undefined === ($_b = ((undefined === ($_b = (_none)) ? undefined : ($_b.args)))) ? undefined : ($_b.block)))) ? $_b : false) }; _preface = 'var \x5e{list}=\x5e{source},\x5e{key};' + '\n' + 'if (undefined===\x5e{list}) \x5e{list}=[];' + '\n' + 'var \x5e{length}=\x5e{list}.length;' + '\n' + ''; _elseclause = function(p) { { if (!(_none)) { return (''); } else { return ('if (\x5e{key}===0) { \x5e{none} }' + '\n' + ''); } } }(); _loop = 'for (\x5e{key}=0; \x5e{key}<\x5e{length}; \x5e{key}++) {' + '\n' + '\x5e{task}(\x5e{list}[\x5e{key}],\x5e{key},\x5e{list});' + '\n' + '}' + '\n' + ''; _text = p.tools.replacer((_preface + (_loop + _elseclause)), _vars); break; default: return ({ error: 'Unhandled construct type ' + _main.type + ' in PlyConstruct' }); break; } } catch ($23_error) { $AI.debug_op($23_error); } return ({ body: _text }); } }; var $9g = prototype['WhileConstruct'] || function() {}; prototype['WhileConstruct'] = function(p) { var $24_this, $25, $26_error, $ = this['WhileConstruct'] ? this : $bindfail('WhileConstruct'), $_b, $_c, $_d, _loop, _main, _outs, _preface, _text, _vars; $AI.expectsThrow(p, { "clauses": true, "tools": true }, '\'WhileConstruct\''); { _main = p.clauses[0]; try { switch ($25 = (_main.type)) { case 'while.exproutblock': _outs = $.OutVarHelper(_main.args.out); _vars = { block: _main.args.block, 'source': _main.args.expr, 'this': ((undefined !== ($_b = _outs[0])) ? $_b : false) }; _preface = 'var \x5e{this};' + '\n' + ''; _loop = 'while (\x5e{this}=(\x5e{source})) {' + '\n' + '\x5e{block}' + '\n' + '}' + '\n' + ''; _text = p.tools.replacer((_preface + _loop), _vars); break; case 'until.exproutblock': _vars = { block: _main.args.block, 'source': _main.args.expr }; _loop = 'while (!(\x5e{source})) {' + '\n' + '\x5e{block}' + '\n' + '}' + '\n' + ''; _text = p.tools.replacer(_loop, _vars); break; case 'dowhile.exproutblock': _vars = { block: _main.args.block, 'source': _main.args.expr }; _loop = 'do {' + '\n' + '\x5e{block}' + '\n' + '} while (\x5e{source});' + '\n' + ''; _text = p.tools.replacer(_loop, _vars); break; case 'dountil.exproutblock': _vars = { block: _main.args.block, 'source': _main.args.expr }; _loop = 'do {' + '\n' + '\x5e{block}' + '\n' + '} while (!(\x5e{source}));' + '\n' + ''; _text = p.tools.replacer(_loop, _vars); break; default: return ({ error: 'Unhandled construct type ' + _main.type + ' in WhileConstruct' }); break; } } catch ($26_error) { $AI.debug_op($26_error); } return ({ body: _text }); } }; var $10g = prototype['CountConstruct'] || function() {}; prototype['CountConstruct'] = function(p) { var $27_this, $28_trial, $29_trial, $30, $31_error, $ = this['CountConstruct'] ? this : $bindfail('CountConstruct'), $_b, $_c, $_d, _elseclause, _iStart, _iStep, _iStop, _loop, _main, _none, _outs, _preface, _text, _tools, _vars; $AI.expectsThrow(p, { "clauses": true, "tools": true }, '\'CountConstruct\''); { if ($28_trial = ((p.clauses.length > 2))) { return ({ error: 'SAI compile: COUNT can have at most one ELSE clause.' }); } _main = p.clauses[0]; _none = p.clauses[1]; _tools = []; try { _outs = $.OutVarHelper(_main.args.out); switch ($30 = (_main.type)) { case 'count.exprsoutblock': if (!(_main.args.exprs[0])) { return ({ error: 'SAI Compiler: Missing end value in COUNT' }); } _iStart = _main.args.exprs[0]; _iStop = _main.args.exprs[1]; _iStep = ((undefined !== ($_b = _main.args.exprs[2])) ? $_b : 1); if ($29_trial = ((undefined === _iStop))) { _iStop = _iStart; _iStart = 0; } _tools.push('var $count$stepup=function(v){throw new Error("SAI Runtime: COUNT STEP value should be positive, not "+v);};' + '\n' + ''); _vars = { block: _main.args.block, 'start': _iStart, 'kstop': _iStop, 'stop': false, 'kstep': _iStep, 'step': false, 'counter': ((undefined !== ($_b = _outs[0])) ? $_b : false), none: ((undefined !== ($_b = (undefined === ($_b = ((undefined === ($_b = (_none)) ? undefined : ($_b.args)))) ? undefined : ($_b.block)))) ? $_b : false) }; _preface = 'var \x5e{counter}=\x5e{start},\x5e{stop}=\x5e{kstop},\x5e{step}=\x5e{kstep};' + '\n' + 'if (!(\x5e{step}>0)) $count$stepup(\x5e{step});' + '\n' + ''; _elseclause = function(p) { { if (!(_none)) { return (''); } else { return ('if (\x5e{counter}>=\x5e{stop}) { \x5e{none} } else' + '\n' + ''); } } }(); _loop = 'for (; \x5e{counter}<\x5e{stop}; \x5e{counter}=\x5e{counter}+\x5e{step}) {' + '\n' + '\x5e{block};' + '\n' + '}' + '\n' + ''; _text = p.tools.replacer((_preface + (_elseclause + _loop)), _vars); break; case 'countdown.exprsoutblock': if (!(_main.args.exprs[0])) { return ({ error: 'SAI Compiler: Missing start value in COUNTDOWN' }); } _tools.push('var $count$stepdown=function(v){throw new Error("SAI Runtime: COUNT STEP value should be negative, not "+v);};' + '\n' + ''); _iStart = _main.args.exprs[0]; _iStop = ((undefined !== ($_b = _main.args.exprs[1])) ? $_b : 0); _iStep = ((undefined !== ($_b = _main.args.exprs[2])) ? $_b : (0 - (1))); _vars = { block: _main.args.block, 'start': _iStart, 'kstop': _iStop, 'stop': false, 'kstep': _iStep, 'step': false, 'counter': ((undefined !== ($_b = _outs[0])) ? $_b : false), none: ((undefined !== ($_b = (undefined === ($_b = ((undefined === ($_b = (_none)) ? undefined : ($_b.args)))) ? undefined : ($_b.block)))) ? $_b : false) }; _preface = 'var \x5e{stop}=\x5e{kstop},\x5e{step}=\x5e{kstep},\x5e{counter}=\x5e{start}+\x5e{step};' + '\n' + 'if (!(\x5e{step}<0)) $count$stepdown(\x5e{step});' + '\n' + ''; _elseclause = function(p) { { if (!(_none)) { return (''); } else { return ('if (\x5e{counter}<\x5e{stop}) { \x5e{none} } else' + '\n' + ''); } } }(); _loop = 'for (; \x5e{counter}>=\x5e{stop}; \x5e{counter}=\x5e{counter}+\x5e{step}) {' + '\n' + '\x5e{block};' + '\n' + '}' + '\n' + ''; _text = p.tools.replacer((_preface + (_elseclause + _loop)), _vars); break; default: return ({ error: 'Unhandled construct type ' + _main.type + ' in CountConstruct' }); break; } } catch ($31_error) { $AI.debug_op($31_error); } return ({ body: _text, tools: _tools }); } }; var $11g = prototype['Documents'] || function() {}; prototype['Documents'] = function(p) { var $32_this, $ = this['Documents'] ? this : $bindfail('Documents'); { return ({ 'constructs': { 'every': { subtitle: 'general-purpose collection iterator', summary: '**Every** is a general-purpose iterator that can handle any collection -- array, object or iterable -- or a even single value (which case it executes the block once).', detail: '__Every__ steps through each element of the collection, in order if possible (array, iterable), in' + '\n' + 'random order otherwise (objects), setting **it** and **key** pronouns, and executing the code block.' + '\n' + '' + '\n' + 'The **key** pronoun will be the index number for arrays, the attribute name for objects, or a row' + '\n' + 'counter for iterables. It will be `0` for the single pass granted a single value.' + '\n' + '' + '\n' + 'If the collection is empty, executes the (optional) **else** block instead.' + '\n' + '' + '\n' + ' set friend to friends first' + '\n' + ' every friend' + '\n' + ' debug `$\{key}: $\{it}' + '\n' + ' else' + '\n' + ' debug `You have no friends.' + '\n' + '' + '\n' + ' > name: Jon' + '\n' + ' > age: 19' + '\n' + ' > cat: true' + '\n' + ' > dog: true' + '\n' + ' > province: QC' + '\n' + '' + '\n' + 'Recall that you can rename **it** and **key** with the **as** clause:' + '\n' + '' + '\n' + ' every friend as value, fieldname' + '\n' + ' debug `$\{fieldname}: $\{value}' + '\n' + '' + '\n' + '' + '\n' + '_Note:_ there is a slight performance penalty associated with using __every__ instead of a more specific iterator, as SAI must wrap the collection in a thin iteration in order to generically handle all cases. It is, however, very useful when you are not sure what kind of collection you\'ll be working with.' + '\n' + '' + '\n' + '#### every ... using' + '\n' + '' + '\n' + '**Every** can also call out to a function with the **every ... using** variation.' + '\n' + '' + '\n' + ' set handler to task given value, field' + '\n' + ' debug `$\{field}: $\{value}' + '\n' + '' + '\n' + ' every friend using handler' + '\n' + '' + '\n' + 'The function is called for each attribute of the collection with two parameters:' + '\n' + '' + '\n' + ' - attribute value (e.g. __it__)' + '\n' + ' - attribute name (e.g. __key__)' + '\n' + '' + '\n' + 'You can use __break__ to exit out of the loop prematurely, and __continue__ to shortcut to the start.' + '\n' + 'See the documentation on these terms for more.' + '\n' + '' + '\n' + '' }, 'iterate': { subtitle: 'sequentially examine values from a generator/iterator', summary: 'The **iterate** statement steps through each value in an _iterable expression_.' + '\n' + 'This can be an object with fields/traits, an array/list with numbered elements, or a passive' + '\n' + 'iterator/generator that **yield**s values for iteration.', detail: 'What’s an iterable expression? It’s an object that **yield**s values for iteration, or an object that' + '\n' + 'on demand (via call to **[Symbol.iterator]** produces such an expression. (In ES6, native collection' + '\n' + 'types based on **Array**, **Map**, and **Set** support lazy iteration.)' + '\n' + '' + '\n' + 'This construct steps through each result of an _iterable expression_, passing it through a block' + '\n' + 'of code via the **it** pronoun. If an **else** clause is present, that code is executed only if there is' + '\n' + 'no iteration.' + '\n' + '' + '\n' + 'Even though generators don\'t provide a key to match the value, when using a generator **iterate**' + '\n' + 'nevertheless provides **key**, giving you the row number of each value returned.' + '\n' + '' + '\n' + ' set seen to new ~Set' + '\n' + ' seen.add \'horse\'' + '\n' + ' seen.add \'pig\'' + '\n' + ' seen.add \'horse\'' + '\n' + ' iterate seen' + '\n' + ' debug \'$\{key} - $\{it}\'' + '\n' + '' + '\n' + ' > 0 - horse' + '\n' + ' > 1 - pig' + '\n' + '' + '\n' + '#### iterate ... using' + '\n' + '' + '\n' + 'This variation calls the given function with two parameters, the iteration value and the current row number:' + '\n' + '' + '\n' + ' set fruit list Apple, Banana, Citron, Durian' + '\n' + ' set SeeFunctionParameters to task' + '\n' + ' debug $$' + '\n' + '' + '\n' + ' iterate (fruit iterate) using SeeFunctionParameters' + '\n' + '' + '\n' + ' > { \'0\': \'Apple\', \'1\': 0 }' + '\n' + ' > { \'0\': \'Banana\', \'1\': 1 }' + '\n' + ' > { \'0\': \'Citron\', \'1\': 2 }' + '\n' + ' > { \'0\': \'Durian\', \'1\': 3 }' + '\n' + '' + '\n' + 'You can use __break__ to exit out of the loop prematurely, and __continue__ to shortcut to the start.' + '\n' + 'See the documentation on these terms for more.' + '\n' + '' + '\n' + '' }, 'each': { subtitle: 'object attribute enumeration', summary: '**Each** uses Javascript\'s `for-in` loop construct to iterate through an object\'s' + '\n' + 'enumerable properties. It steps through each element of the collection, in arbitrary' + '\n' + 'order, setting **it** and **key** variables, and executing the code block for each one.' + '\n' + 'If the collection is empty, executes the (optional) **else** block instead.', detail: 'Example:' + '\n' + '' + '\n' + ' set friend to friends | first' + '\n' + ' each friend' + '\n' + ' debug `$\{key}: $\{it}' + '\n' + ' else' + '\n' + ' debug `You have no friends.' + '\n' + '' + '\n' + ' > name: Jon' + '\n' + ' > age: 19' + '\n' + ' > cat: true' + '\n' + ' > dog: true' + '\n' + ' > province: QC' + '\n' + '' + '\n' + 'Recall that you can rename **it** and **key** with the **as** clause:' + '\n' + '' + '\n' + ' each friend as value, field' + '\n' + ' debug `$\{field}: $\{value}' + '\n' + '' + '\n' + '#### each ... using' + '\n' + '' + '\n' + '**Each** can also call out to a function with the **each using** variation.' + '\n' + '' + '\n' + ' set handler to task given value, field, collection' + '\n' + ' debug `$\{field}: $\{value}' + '\n' + '' + '\n' + ' each friend using handler' + '\n' + '' + '\n' + 'The function is called for each attribute of the collection with three parameters:' + '\n' + '' + '\n' + ' - attribute value (e.g. __it__)' + '\n' + ' - attribute name (e.g. __key__)' + '\n' + ' - reference to the collection itself' + '\n' + '' + '\n' + 'You can use __break__ to exit out of the loop prematurely, and __continue__ to shortcut to the start.' + '\n' + 'See the documentation on these terms for more.' + '\n' + '' + '\n' + '' }, 'index': { subtitle: 'custom order iterator', summary: '__Index__ iterates through an array or object sequentially using a separately provided collection of' + '\n' + 'keys. The index is stepped through one row at a time, and the value of the object with that index is' + '\n' + 'presented in the enclosed block of code.', detail: 'You provide a collection, and the index, separated by a comma.' + '\n' + '' + '\n' + ' index [collection], [index]' + '\n' + '' + '\n' + 'In pseudo-code, this happens:' + '\n' + '' + '\n' + ' ply index as key' + '\n' + ' with collection\key as it' + '\n' + ' [ code ]' + '\n' + '' + '\n' + 'A real example:' + '\n' + '' + '\n' + ' set fruit to traits a Apple, b Banana, c Cherry' + '\n' + ' index fruit, list b, c, a, c' + '\n' + ' debug it' + '\n' + '' + '\n' + ' > Banana' + '\n' + ' > Cherry' + '\n' + ' > Apple' + '\n' + ' > Cherry' + '\n' + '' + '\n' + 'It is relatively easy to synthesize the function of __index__ using a normal iterator and __with__,' + '\n' + 'nevertheless it is such a common pattern it makes sense to abstract it slightly for better clarity.' + '\n' + '' + '\n' + '__Index__ can accept an iterator as the index, in which case it will be stepped through until it is' + '\n' + 'exhausted (or you __break__ out of the loop).' + '\n' + '' + '\n' + 'If the index requests a key that does not exist in the collection, __undefined__ is presented to the block.' + '\n' + 'In other words, missing values are neither skipped nor thrown as an error.' + '\n' + '' + '\n' + '#### index using' + '\n' + '' + '\n' + '__Index__ also offers the __using__ variant, where a function is called rather than a block of code executed.' + '\n' + '' + '\n' + ' set tally blank' + '\n' + ' set Tally to task as name' + '\n' + ' inc tally\name' + '\n' + '' + '\n' + ' set fruit to traits a Apple, b Banana, c Cherry' + '\n' + ' index fruit, list b, c, a, c' + '\n' + ' Tally it' + '\n' + '' + '\n' + ' debug tally' + '\n' + '' + '\n' + ' > { Banana: 1, Cherry: 2, Apple: 1 }' + '\n' + '' + '\n' + 'You can use __break__ to exit out of the loop prematurely, and __continue__ to shortcut to the start.' + '\n' + 'See the documentation on these terms for more.' + '\n' + '' + '\n' + '' }, 'ply': { subtitle: 'iterate over an array-like collection', summary: 'The **ply** iterator sequentially steps through all elements in an _array-like_ collection;' + '\n' + 'it works on any object that has a **length** trait.' + '\n' + 'It accesses numeric traits from 0 to **length**-1, sending each trait value to the code' + '\n' + 'block or function. If **length** is 0, the **else** clause is invoked instead.', detail: 'The trait value is captured in the **it** pronoun, and the trait number is captured as **key**.' + '\n' + '' + '\n' + ' ply fruit' + '\n' + ' debug \'$\{key}: $\{it}\'' + '\n' + ' else' + '\n' + ' debug \'There is no fruit.\'' + '\n' + '' + '\n' + ' > 0: Apple' + '\n' + ' > 1: Banana' + '\n' + ' > 2: Citron' + '\n' + '' + '\n' + '#### ply ... using' + '\n' + '' + '\n' + '**Ply** can also call out to a function with the **ply using** variation.' + '\n' + '' + '\n' + ' set handler to task given value, field, collection' + '\n' + ' debug `$\{field}: $\{value}' + '\n' + '' + '\n' + ' ply fruit using handler' + '\n' + '' + '\n' + 'The function is called for each element of the array with three parameters:' + '\n' + '' + '\n' + ' - element value (__it__)' + '\n' + ' - element index # (__key__)' + '\n' + ' - a reference to the array itself' + '\n' + '' + '\n' + 'You can use __break__ to exit out of the loop prematurely, and __continue__ to shortcut to the start.' + '\n' + 'See the documentation on these terms for more.' + '\n' + '' + '\n' + '' }, 'while': { subtitle: 'loop over a block of code while an expression is true', summary: 'Executes the code block repeatedly, as long as the expression is true.', detail: 'The basic **while** variation performs the test first, so there is a chance the code will not execute.' + '\n' + 'The **dowhile** variation executes the block first, then performs the test.' + '\n' + '' + '\n' + ' while false' + '\n' + ' debug \'You will never see this.\'' + '\n' + '' + '\n' + ' dowhile false' + '\n' + ' debug \'You will see this once.\'' + '\n' + '' + '\n' + '**While** makes its value available for use as **it**, as below.' + '\n' + '' + '\n' + ' while file.NextLine()' + '\n' + ' @story.push it' + '\n' + '' + '\n' + '**Dowhile** _does not_ use **it**, because the expression is not evaluated until after the first pass' + '\n' + 'through the code, thus the first **it** result would always be **undefined**.' + '\n' + '' + '\n' + 'You can use __break__ to exit out of the loop prematurely, and __continue__ to shortcut to the start.' + '\n' + 'See the documentation on these terms for more.' + '\n' + '' + '\n' + '' }, 'until': { subtitle: 'loop over a block of code while an expression is false', summary: 'Executes the code block repeatedly, as long as the expression is false. This is essentially' + '\n' + 'a **while** statement with the test inverted.', detail: 'The basic **until** variation performs the test first, so there is a chance the code will not execute.' + '\n' + 'The **dountil** variation executes the block first, then performs the test.' + '\n' + '' + '\n' + ' until true' + '\n' + ' debug \'You will never see this.\'' + '\n' + '' + '\n' + ' dountil true' + '\n' + ' debug \'You will see this once.\'' + '\n' + '' + '\n' + '**Until** _does not_ make its test value available for use as **it**. Because the code block' + '\n' + 'only executes when the test value is _falsy_, there’s really no point.' + '\n' + '' + '\n' + 'You can use __break__ to exit out of the loop prematurely, and __continue__ to shortcut to the start.' + '\n' + 'See the documentation on these terms for more.' + '\n' + '' + '\n' + '' }, 'dowhile': { subtitle: 'while variant that always executes the loop once', summary: 'Functions just like the __while__ loop, except that the block of code is always executed once _first_,' + '\n' + 'before the test.', detail: 'Check out these wacky examples.' + '\n' + '' + '\n' + ' dountil true' + '\n' + ' debug \'Hello, World!\'' + '\n' + '' + '\n' + ' dowhile false' + '\n' + ' debug \'Hello, World!\'' + '\n' + '' + '\n' + 'Note there\'s no space in there. It\'s __dowhile__ and __dountil__. Makes parsing easier when it\'s one word.' + '\n' + '' + '\n' + 'You can use __break__ to exit out of the loop prematurely, and __continue__ to shortcut to the start.' + '\n' + 'See the documentation on these terms for more. See __while__ for more.' + '\n' + '' + '\n' + '' }, 'dountil': { subtitle: 'until variant that always executes the loop once', summary: 'Functions just like the __until__ loop, except that the block of code is always executed once _first_,' + '\n' + 'before the test.', detail: 'I could duplicate text here or just refer you to __dowhile__ and __while__. Which would you like?' + '\n' + '' + '\n' + '' }, 'break': { subtitle: 'exit a loop or switch case', summary: 'To exit a loop, iterator or switch case before its natural end, use the **break** keyword.', detail: 'As in:' + '\n' + '' + '\n' + ' ply collection' + '\n' + ' unless FileExists(collection)' + '\n' + ' break' + '\n' + '' + '\n' + 'or ..' + '\n' + '' + '\n' + ' switch choice' + '\n' + ' case \'exit\'' + '\n' + ' if exiting' + '\n' + ' break' + '\n' + ' set exiting true' + '\n' + ' ...' + '\n' + '' + '\n' + 'or ...' + '\n' + '' + '\n' + ' count 5' + '\n' + ' debug it' + '\n' + ' if it=2' + '\n' + ' debug \'Nevermind...\'' + '\n' + ' break' + '\n' + '' + '\n' + ' > 1' + '\n' + ' > 2' + '\n' + ' > Nevermind…' + '\n' + '' + '\n' + '' }, 'continue': { subtitle: 'shortcut to the next iteration of a loop', summary: 'In a loop or otherwise iterating block of code, **continue** short-cuts the remaining code in' + '\n' + 'the block, causing the loop to continue its next iteration immediately.', detail: 'An example:' + '\n' + '' + '\n' + ' count 10' + '\n' + ' unless key % 2' + '\n' + ' continue' + '\n' + ' debug key' + '\n' + '' + '\n' + ' > 1' + '\n' + ' > 3' + '\n' + ' > 5' + '\n' + ' > 7' + '\n' + ' > 9' + '\n' + '' + '\n' + '' }, 'count': { subtitle: 'numerically controlled looping', summary: 'In this most basic kind of loop, a block of code is executed a certain number of times with a counter' + '\n' + 'keeping track of iteration count. More complexity is available if needed.', detail: 'Specifically designed as an integer iterator for list elements, **count** always counts 1 at a time' + '\n' + '(unless a **step** value is provided), and its highest value is always the step value less than the' + '\n' + 'high value provided (both when counting up and down).' + '\n' + '' + '\n' + 'To reiterate, **count** _never_ outputs the high value.' + '\n' + '' + '\n' + 'Variants:' + '\n' + '' + '\n' + ' count [low expr], [high expr] ( as [counter ident] )' + '\n' + ' count [low expr], [high expr], [step amount expr] ( as [counter ident] )' + '\n' + '' + '\n' + ' countdown [high expr] ( as [counter ident] )' + '\n' + ' countdown [high expr], [low expr] ( as [counter ident])' + '\n' + ' countdown [high expr], [low expr], [step expr] ( as [counter ident])' + '\n' + '' + '\n' + '**Count** uses the pronoun **counter** for the value.' + '\n' + '' + '\n' + ' count 10' + '\n' + ' debug counter' + '\n' + ' .. counts from 0 to 9' + '\n' + '' + '\n' + ' count 5, 10' + '\n' + ' ... numbers 5 to 9' + '\n' + '' + '\n' + ' countdown 10 as i' + '\n' + ' ... numbers from 9 to 0' + '\n' + '' + '\n' + ' countdown 25, 15' + '\n' + ' ... numbers 24 to 15' + '\n' + '' + '\n' + ' count 0, 50, 10' + '\n' + ' ... 0, 10, 20, 30, 40' + '\n' + '' + '\n' + ' countdown 45, 0, -10' + '\n' + ' ... 35, 25, 15, 5' + '\n' + '' + '\n' + 'When using a step with **count down**, be sure that the step expression is negative, otherwise an infinite loop will result.' + '\n' + '' + '\n' + ' count aList.length' + '\n' + ' debug \'List element $\{counter} is $\{aList[counter]}\'' + '\n' + ' else' + '\n' + ' debug \'The list is empty.\'' + '\n' +