katra
Version:
BASIC language interpreter in CoffeeScript
1,824 lines (1,587 loc) • 65.8 kB
JavaScript
// Generated by CoffeeScript 1.6.3
(function() {
var ABS, AND, ATN, Add, Base, BuiltIn, COS, Chain, Com, Comma, Con, Console, Const, Data, Def, Dim, Div, EQ, EXP, End, Enter, FN, FOR, For, GE, GOSUB, GT, Gosub, Goto, INT, If, Image, Input, Keyword, LCASE, LE, LEFT, LEN, LIN, LOG, LT, Let, MID, MODE_REPL, MODE_RUN, Mat, MatRead, Max, Min, Mul, NE, NOT, Next, OR, Operator, PHASE_EXEC, PHASE_SCAN, PRINTF, Pow, Print, RIGHT, RND, Randomize, Read, Rem, Restore, Return, SGN, SIN, SPA, SQR, SUBSTR, Semic, Statement, Stop, Sub, TAB, TAN, TIM, UCASE, Using, V_ATARI, V_GWBASIC, V_HP2000, Var, Zer, katra, rte, __con, __fs, _ary, _bind, _chain, _clean, _com, _dat, _dbg, _dim, _dp, _elapsed_time, _eop, _eval, _exec, _fixup_if, _fixup_print, _flatten, _fn, _format, _gw, _init, _load, _mark, _mrk, _nam, _ofs, _pad, _parse, _pc, _prg, _qualify, _raw, _ref, _ref1, _ref10, _ref11, _ref12, _ref13, _ref14, _ref15, _ref16, _ref17, _ref18, _ref19, _ref2, _ref20, _ref21, _ref22, _ref23, _ref24, _ref25, _ref26, _ref27, _ref28, _ref29, _ref3, _ref30, _ref31, _ref32, _ref33, _ref34, _ref35, _ref36, _ref37, _ref38, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9, _run, _save, _sprintf, _start, _stk, _str, _txt, _var, _ver, _wel, _xrf,
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
__slice = [].slice;
rte = typeof window !== "undefined" && window !== null ? window.rte : require("./rte.node");
V_HP2000 = 0;
V_ATARI = 1;
V_GWBASIC = 2;
GOSUB = 1;
FOR = 2;
PHASE_SCAN = 0;
PHASE_EXEC = 1;
MODE_REPL = 0;
MODE_RUN = 1;
PRINTF = /(\%)([-])?([+])?([0])?(\d*)?(\.\d*)?([\%ds])/g;
__con = null;
__fs = null;
_ary = {};
_com = [];
_dat = [];
_dbg = false;
_dp = 0;
_eop = false;
_fn = {};
_gw = false;
_mrk = {};
_nam = '';
_ofs = 0;
_pc = 0;
_prg = [];
_raw = {};
_stk = [];
_str = {};
_txt = '';
_var = {};
_ver = 0;
_wel = '';
_xrf = {};
_bind = function() {
return Object.defineProperties(this, {
_con: {
get: function() {
if (__con == null) {
return __con = new Console(_wel);
} else {
return __con;
}
}
},
_fs: {
get: function() {
if (__fs == null) {
return __fs = new rte.FileSystem();
} else {
return __fs;
}
}
}
});
};
_init = function($all) {
_ary = {};
_com = [];
_dat = [];
_dp = 0;
_eop = false;
_fn = {};
_mrk = {};
_ofs = 0;
_pc = 0;
if ($all) {
_raw = {};
}
_stk = [];
_str = {};
_var = {};
return _xrf = {};
};
_eval = function($value) {
if ($value["eval"] != null) {
return $value["eval"]();
} else {
return $value;
}
};
_qualify = function($name, $version) {
if ($version == null) {
$version = V_HP2000;
}
switch ($version) {
case V_ATARI:
return 'bas/atari/' + $name;
case V_GWBASIC:
return 'bas/gwbasic/' + $name;
case V_HP2000:
switch ($name[0]) {
case "*":
return 'bas/hp2k/group/' + $name.slice(1);
case "$":
return 'bas/hp2k/system/' + $name.slice(1);
case "#":
return 'bas/hp2k/test/' + $name.slice(1);
default:
return 'bas/hp2k/' + $name;
}
}
};
_clean = function($code) {
if ($code.charCodeAt(0) === 0xfeff) {
$code = $code.slice(1);
}
return $code = ($code + '\n').replace(/\r/g, '\n').replace(/\n+/g, '\n');
};
_save = function($version, $name, $data, $next) {
$name = $name[0] === '"' ? $name.slice(1, -1) : $name;
_con.pause(true);
_fs.writeFile(_qualify($name, $version), $data, function() {
if (typeof $next === "function") {
$next();
}
return _con.pause(false);
});
return true;
};
_load = function($version, $name, $init, $next) {
if ($init == null) {
$init = true;
}
$name = $name[0] === '"' ? $name.slice(1, -1) : $name;
_init($init);
_con.pause(true);
_fs.readFile(_qualify($name, $version), function($err, $data) {
if ($err != null) {
_con.println($err);
} else {
$data = _clean($data).split('\n');
if (isNaN($data[0][0])) {
$data.shift();
}
if ($data[0] === "") {
$data.shift();
}
_nam = /^[A-Za-z]/.test($name) ? $name : $name.slice(1);
_ver = $version;
_gw = _ver === V_GWBASIC ? true : false;
_txt = $data.join('\n');
if (typeof $next === "function") {
$next(_txt);
}
_parse(_txt);
}
return _con.pause(false);
});
return true;
};
_exec = function($version, $name, $init) {
if ($init == null) {
$init = true;
}
_init($init);
_con.pause(true);
_fs.readFile(_qualify($name, $version), function($err, $data) {
if ($err != null) {
_con.println($err);
} else {
$data = _clean($data).split('\n');
if (isNaN($data[0][0])) {
$data.shift();
}
if ($data[0] === "") {
$data.shift();
}
_nam = /^[A-Za-z]/.test($name) ? $name : $name.slice(1);
_ver = $version;
_gw = _ver === V_GWBASIC ? true : false;
_txt = $data.join('\n');
_parse(_txt);
_start();
_run();
_con.reset();
}
return _con.pause(false);
});
return true;
};
_start = function() {
var $lineno, $statement, _i, _len, _ref;
_prg = [];
for ($lineno in _raw) {
$statement = _raw[$lineno];
while ($lineno.length < 4) {
$lineno = '0' + $lineno;
}
_prg.push([$lineno, $statement]);
}
_prg.sort();
_init(false);
for (_i = 0, _len = _prg.length; _i < _len; _i++) {
_ref = _prg[_i], $lineno = _ref[0], $statement = _ref[1];
if ($statement.code.type === PHASE_SCAN) {
$statement.code["eval"]();
}
_xrf[parseInt($lineno, 10)] = _pc++;
}
return _pc = 0;
};
_run = function() {
var $code, $e, $lineno, $statement, $wait, _ref;
$wait = false;
_con.mode = MODE_RUN;
try {
while (!(_eop || $wait)) {
_ref = _prg[_pc++], $lineno = _ref[0], $statement = _ref[1];
$code = $statement.code;
if ($statement.code.type === PHASE_EXEC) {
if (_dbg) {
_con.debug($lineno + ' ' + $code.toString());
}
$wait = $code["eval"]();
}
_con.setPrompt($wait);
if (_pc >= _prg.length) {
_eop = true;
}
}
} catch (_error) {
$e = _error;
_con.println($e);
$wait = false;
}
if (!$wait) {
_con.mode = MODE_REPL;
return _con.println('DONE');
}
};
_chain = function($code) {
var $ix, $save, $var, _i, _j, _len, _len1;
$save = Array(_com.length);
for ($ix = _i = 0, _len = _com.length; _i < _len; $ix = ++_i) {
$var = _com[$ix];
switch ($var.type) {
case 0:
$save[$ix] = _str[$var.name];
break;
case 1:
$save[$ix] = _var[$var.name];
break;
case 2:
$save[$ix] = _ary[$var.name];
}
}
_init(true);
_parse($code);
_start();
for ($ix = _j = 0, _len1 = _com.length; _j < _len1; $ix = ++_j) {
$var = _com[$ix];
switch ($var.type) {
case 0:
_str[$var.name] = $save[$ix];
break;
case 1:
_var[$var.name] = $save[$ix];
break;
case 2:
_ary[$var.name] = $save[$ix];
}
}
return _run();
};
_parse = function($code) {
var $e, $index, $line, kc, _i, _len;
kc = typeof window !== "undefined" && window !== null ? window.kc : require("./kc");
$code = $code.split('\n');
for ($index = _i = 0, _len = $code.length; _i < _len; $index = ++_i) {
$line = $code[$index];
if (/^\d*\s*IF/i.test($line)) {
$code[$index] = $line = _fixup_if($line);
}
if (/^\d*\s*PRINT/i.test($line)) {
$code[$index] = $line = _fixup_print($line);
}
if (/\'(?=[^"]*(?:"[^"]*"[^"]*)*$)/.test($line)) {
$code[$index] = $line = $line.replace(/(\'.*(?=[^"]*(?:"[^"]*"[^"]*)*$))/g, "");
}
if (/\*\*(?=[^"]*(?:"[^"]*"[^"]*)*$)/.test($line)) {
$code[$index] = $line = $line.replace(/(\*\*(?=[^"]*(?:"[^"]*"[^"]*)*$))/g, "^");
}
}
try {
kc.parse($code.join('\n'));
} catch (_error) {
$e = _error;
_con.debug(String($e));
}
return true;
};
_fixup_if = function($line) {
$line = $line.split(/THEN/i);
$line[0] = $line[0].replace(/\=/g, '==').replace(/\<\=\=/g, '<=').replace(/\>\=\=/g, '>=').replace(/\#/g, '<>');
return $line.join(" THEN ");
};
_fixup_print = function($line) {
var $chunk, $index, $is_string, $match, $sep, SEP, _i, _len, _ref, _ref1;
SEP = ';:,';
$is_string = false;
$match = (function() {
var _i, _len, _ref, _results;
_ref = $line.match(/[^"]*(?!\\"[^"]*\")/g);
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
$chunk = _ref[_i];
if ($chunk !== '') {
_results.push($chunk);
}
}
return _results;
})();
for ($index = _i = 0, _len = $match.length; _i < _len; $index = ++_i) {
$chunk = $match[$index];
$sep = /^\d*\s*PRINT\s*$/i.test($chunk) || $index === $match.length - 1 ? '' : ';';
if ($is_string) {
$match[$index] = $chunk = '"' + $chunk + '"';
if (SEP.indexOf((_ref = (_ref1 = $match[$index + 1]) != null ? _ref1[0] : void 0) != null ? _ref : '') === -1) {
$match[$index] = $chunk + $sep;
}
} else {
if (SEP.indexOf($chunk.substr(-1)) === -1) {
$match[$index] = $chunk + $sep;
}
}
$is_string = !$is_string;
}
return $match.join('');
};
_dim = function($init, $dim1, $dim2) {
var $a, $i, $j, _i, _j, _k, _ref, _ref1, _ref2;
$a = [];
switch (arguments.length) {
case 2:
for ($i = _i = _ofs, _ref = $dim1 + 1; _ofs <= _ref ? _i < _ref : _i > _ref; $i = _ofs <= _ref ? ++_i : --_i) {
$a[$i] = $init;
}
break;
case 3:
for ($i = _j = _ofs, _ref1 = $dim1 + 1; _ofs <= _ref1 ? _j < _ref1 : _j > _ref1; $i = _ofs <= _ref1 ? ++_j : --_j) {
$a[$i] = [];
for ($j = _k = _ofs, _ref2 = $dim2 + 1; _ofs <= _ref2 ? _k < _ref2 : _k > _ref2; $j = _ofs <= _ref2 ? ++_k : --_k) {
$a[$i][$j] = $init;
}
}
}
return $a;
};
_flatten = function($list) {
var $a, $item, _i, _len;
if ($list == null) {
return [];
}
$a = [];
for (_i = 0, _len = $list.length; _i < _len; _i++) {
$item = $list[_i];
if (Array.isArray($item)) {
$a = $a.concat(_flatten($item));
} else {
$a.push($item);
}
}
return $a;
};
_sprintf = function($fmt, $list) {
var $count, _foreach;
$count = 0;
_foreach = function($match, $pct, $just, $sign, $pad, $width, $prec, $spec, $ofset, $string) {
var $value;
if ($pad == null) {
$pad = ' ';
}
$value = String($list[$count++]);
switch ($spec) {
case '%':
return '%';
case 's':
if ($width != null) {
$width = parseInt($width, 10);
if ($value.length < $width) {
if ($just != null) {
return Array($width - $value.length + 1).join($pad) + $value;
} else {
return $value + Array($width - $value.length + 1).join($pad);
}
}
}
return $value;
case 'd':
if ($width != null) {
$width = parseInt($width, 10);
if ($value.length < $width) {
if ($just != null) {
return $value + Array($width - $value.length + 1).join($pad);
} else {
return Array($width - $value.length + 1).join($pad) + $value;
}
}
}
return $value;
}
};
return $fmt.replace(PRINTF, _foreach);
};
_format = function($image) {
var $count, $head, $out;
if ($image == null) {
$image = [];
}
$out = '';
$count = 1;
while ($image.length > 0) {
$head = $image.shift();
if (isNaN($head)) {
switch ($head) {
case ',':
$count = 1;
break;
case 'D':
$out += $count > 1 ? '%' + $count + 'd' : '%d';
$count = 1;
break;
case 'A':
$out += $count > 1 ? '%' + $count + 's' : '%s';
$count = 1;
break;
case 'X':
$out += Array($count + 1).join(' ');
$count = 1;
break;
case '(':
$out += Array($count + 1).join(_format($image));
$count = 1;
break;
case ')':
return $out;
default:
$out += $head.slice(1, -1);
$count = 1;
}
} else {
$count = $head;
}
}
return $out;
};
_pad = function($value, $len, $pad) {
var $right;
if ($pad == null) {
$pad = ' ';
}
$right = !isNaN($value);
$value = String($value);
if ($right) {
if ($value.length < $len) {
return Array($len - $value.length + 1, $pad) + $value;
} else {
return $value.substr(0, $len);
}
} else {
if ($value.length < $len) {
return $value + Array($len - $value.length + 1, $pad);
} else {
return $value.substr(0, $len);
}
}
};
_mark = function($name) {
return _mrk[$name] = new Date();
};
_elapsed_time = function($point1, $point2) {
if (_mrk[$point1] == null) {
return 0;
}
if (_mrk[$point2] == null) {
_mrk[$point2] = new Date();
}
return _mrk[$point2] - _mrk[$point1];
};
Zer = {
"eval": function() {
return 0;
},
toString: function() {
return 'ZER';
}
};
Con = {
"eval": function() {
return 1;
},
toString: function() {
return 'CON';
}
};
Semic = {
"eval": function() {
return '';
},
toString: function() {
return ';';
}
};
Comma = {
"eval": function() {
return ' ';
},
toString: function() {
return ',';
}
};
Operator = (function() {
function Operator(left, right) {
this.left = left;
this.right = right;
}
return Operator;
})();
BuiltIn = (function() {
function BuiltIn($0, $1, $2) {
this.$0 = $0;
this.$1 = $1;
this.$2 = $2;
}
BuiltIn.prototype.toString = function() {
return "" + (this.constructor.name.toUpperCase()) + "(" + this.$0 + ")";
};
return BuiltIn;
})();
Keyword = (function() {
function Keyword() {}
Keyword.prototype.type = PHASE_EXEC;
Keyword.prototype["eval"] = function() {
return false;
};
return Keyword;
})();
Console = (function(_super) {
__extends(Console, _super);
Console.prototype.mode = MODE_REPL;
Console.prototype.exec = true;
function Console($welcome) {
this.commandHandle = __bind(this.commandHandle, this);
this.welcomeMessage = $welcome;
Console.__super__.constructor.call(this);
}
Console.prototype.cancelHandle = function() {
_eop = true;
_con.print('^C');
_con.reset();
_con.setPrompt(false);
_run();
return _con.console.scrollToBottom();
};
Console.prototype.commandHandle = function($line) {
var $item, $ix, $name, _i, _j, _len, _len1, _ref, _ref1;
switch (this.mode) {
case MODE_RUN:
_ref = $line.trim().split(",");
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
$item = _ref[_i];
this.buffer.push(isNaN($item) ? String($item) : Number($item));
}
if (this.buffer.length < this.vars.length) {
this.continuedPrompt = true;
} else {
_ref1 = this.vars;
for ($ix = _j = 0, _len1 = _ref1.length; _j < _len1; $ix = ++_j) {
$name = _ref1[$ix];
if (/\$$/.test($name)) {
_str[$name] = this.buffer[$ix];
} else {
_var[$name] = this.buffer[$ix];
}
}
this.continuedPrompt = false;
_run();
return true;
}
break;
case MODE_REPL:
$line = /\n$/.test($line) ? $line : "" + $line + "\n";
return _parse($line);
}
};
return Console;
})(rte.Console);
_bind();
katra = {
main: function($args) {
var _ref;
_wel = (_ref = $args.title) != null ? _ref : _wel;
switch ($args.basic) {
case 'atari':
return _exec(V_ATARI, $args.program);
case 'gwbasic':
return _exec(V_GWBASIC, $args.program);
case 'hp2k':
return _exec(V_HP2000, $args.program);
default:
return _con.reset();
}
},
setRoot: function($root) {
return _fs.setRoot($root);
},
getText: function() {
return _txt;
},
command: {
append: function($0) {
return _load(V_HP2000, $0.split('-')[1], false);
},
atari: function($0, $next) {
return _load(V_ATARI, $0, true, $next);
},
cat: function($dir) {
var $cw, $hdr, $nc;
$nc = 4;
$cw = 20;
$hdr = 'name ';
return _fs.readDir($dir, function($files) {
var $col, $file, _i, _len;
$col = 0;
_con.hilite("\n" + $dir + "\n" + (Array($nc + 1).join($hdr)));
for (_i = 0, _len = $files.length; _i < _len; _i++) {
$file = $files[_i];
$file = $file.split('.')[0];
while ($file.length < $cw) {
$file += " ";
}
_con.print($file);
if (($col++) % $nc === $nc - 1) {
_con.println();
}
}
if (typeof window === "undefined" || window === null) {
return _con.print("\n" + _con.prompt);
}
});
},
cls: function() {
return _con.clear();
},
del: function($0) {
var $end, $lineno, $start, _i, _ref, _results;
_ref = $0.split('-')[1].split(','), $start = _ref[0], $end = _ref[1];
if (!$end) {
$end = $start;
}
_results = [];
for ($lineno = _i = $start; $start <= $end ? _i < $end : _i > $end; $lineno = $start <= $end ? ++_i : --_i) {
if (_raw[$lineno] != null) {
_results.push(delete _raw[$lineno]);
} else {
_results.push(void 0);
}
}
return _results;
},
dir: function($0) {},
exec: function($0) {
return _exec(V_HP2000, $0.split('-')[1]);
},
files: function($0) {},
get: function($0, $next) {
return _load(V_HP2000, $0.split('-')[1], true, $next);
},
gwbasic: function($0, $next) {
return _load(V_GWBASIC, $0, true, $next);
},
list: function($0) {
var $1, $code, $end, $lineno, $lines, $start, $statement, _i, _len, _ref, _ref1, _results;
$1 = $0.split('-')[1];
if ($1 != null) {
_ref = $1.split(','), $start = _ref[0], $end = _ref[1];
}
if ($start != null) {
$end = $end != null ? $end : $start;
$start = parseInt($start, 10);
$end = parseInt($end, 10);
} else {
$start = 1;
$end = 9999;
}
$lines = [];
for ($lineno in _raw) {
$statement = _raw[$lineno];
while ($lineno.length < 5) {
$lineno = '0' + $lineno;
}
$lines.push([$lineno, $statement]);
}
$lines.sort();
_results = [];
for (_i = 0, _len = $lines.length; _i < _len; _i++) {
_ref1 = $lines[_i], $lineno = _ref1[0], $statement = _ref1[1];
$lineno = parseInt($statement.lineno, 10);
$code = $statement.code;
if ($start != null) {
if ($lineno >= parseInt($start, 10) && $lineno <= parseInt($end, 10)) {
_results.push(_con.println($lineno + ' ' + $code));
} else {
_results.push(void 0);
}
} else {
_results.push(_con.println($lineno + ' ' + $code));
}
}
return _results;
},
name: function($0) {
return _nam = $0.split('-')[1];
},
purge: function($0) {
return _fs.deleteFile(_qualify($0.split('-')[1], _ver), function($err) {
if ($err != null) {
return _con.println($err);
}
});
},
quit: function() {
return typeof process !== "undefined" && process !== null ? process.exit() : void 0;
},
renum: function($0) {
return _con.println("Renumber Not Implemented");
},
run: function($0) {
if (Object.keys(_raw).length > 0) {
_start();
return _run();
}
},
save: function() {
var $code, $lineno, $lines, $statement, $text, _i, _len, _ref;
if (_nam === '') {
return _con.println("Name not set");
}
$lines = [];
$text = '';
for ($lineno in _raw) {
$statement = _raw[$lineno];
$lines.push([$lineno, $statement.code]);
}
$lines.sort();
for (_i = 0, _len = $lines.length; _i < _len; _i++) {
_ref = $lines[_i], $lineno = _ref[0], $code = _ref[1];
$text += $lineno + ' ' + $code + '\n';
}
return _save(_ver, _nam, $text.slice(0, -1), function($err) {
if ($err != null) {
return _con.println($err);
}
});
},
scr: function() {
return _init(true);
},
troff: function() {
return _dbg = false;
},
tron: function() {
return _dbg = true;
}
},
keyword: {
Zer: Zer,
Con: Con,
Semic: Semic,
Comma: Comma,
Statement: Statement = (function() {
function Statement($code, $lineno) {
if ($lineno != null) {
_raw[$lineno] = {
lineno: $lineno,
code: $code
};
} else {
if ($code != null) {
if (typeof $code["eval"] === "function") {
$code["eval"]();
}
}
}
}
return Statement;
})(),
Const: Const = (function() {
function Const(value) {
this.value = value;
this.is_string = 'string' === typeof this.value ? true : false;
if (this.is_string) {
if (this.value.charAt(0) === '"') {
this.value = this.value.slice(1, -1);
}
}
}
Const.prototype.value = function() {
return this.value;
};
Const.prototype["eval"] = function() {
return this.value;
};
Const.prototype.toString = function() {
if (this.is_string) {
return "\"" + this.value + "\"";
} else {
return "" + this.value;
}
};
return Const;
})(),
Var: Var = (function() {
function Var(name, $delim, $dims) {
this.name = name;
this.is_string = /\$$/.test(this.name);
if ($delim != null) {
this.is_array = true;
this.dims = _flatten($dims);
this.dim1 = this.dims[0];
this.dim2 = this.dims[1];
} else {
this.is_array = false;
}
}
Var.prototype["let"] = function($value) {
var $dim1, $dim2, $end, $len, $start, $str;
if (this.is_string) {
if (_gw) {
if (this.dim2 != null) {
$dim1 = this.dim1["eval"]();
$dim2 = this.dim2["eval"]();
return _str[this.name][$dim1][$dim2] = $value;
} else if (this.dim1 != null) {
$dim1 = this.dim1["eval"]();
return _str[this.name][$dim1] = $value;
} else {
return _str[this.name] = $value;
}
} else {
if (this.dim2 != null) {
$start = this.dim1["eval"]() - 1;
$end = this.dim2["eval"]();
if ($end < $start) {
throw 'Invalid String index: ' + this.toString();
}
$len = $end - $start;
$value = $value.substr(0, $len);
$value = _pad($value, $len);
$str = _str[this.name];
return _str[this.name] = $str.substr(0, $start) + $value + $str.substr($end);
} else if (this.dim1 != null) {
$start = this.dim1["eval"]() - 1;
$str = _str[this.name];
return _str[this.name] = $str.substr(0, $start) + $value + $str.substr($start + $value.length);
} else {
$len = _str[this.name].length;
if ($value.length < $len) {
$value += Array($len - $value.length + 1).join(' ');
}
return _str[this.name] = $value;
}
}
} else if (this.dim2 != null) {
$dim1 = this.dim1["eval"]();
$dim2 = this.dim2["eval"]();
return _ary[this.name][$dim1][$dim2] = $value;
} else if (this.dim1 != null) {
$dim1 = this.dim1["eval"]();
return _ary[this.name][$dim1] = $value;
} else {
return _var[this.name] = $value;
}
};
Var.prototype["eval"] = function() {
var $dim1, $dim2, $end, $start, _ref, _ref1, _ref10, _ref11, _ref12, _ref13, _ref14, _ref15, _ref16, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9;
if (this.is_string) {
if (_gw) {
if (this.dim2 != null) {
$dim1 = this.dim1["eval"]();
$dim2 = this.dim2["eval"]();
return (_ref = (_ref1 = _str[this.name]) != null ? (_ref2 = _ref1[$dim1]) != null ? _ref2[$dim2] : void 0 : void 0) != null ? _ref : '';
} else if (this.dim1 != null) {
$dim1 = this.dim1["eval"]();
return (_ref3 = (_ref4 = _str[this.name]) != null ? _ref4[$dim1] : void 0) != null ? _ref3 : '';
} else {
return (_ref5 = _str[this.name]) != null ? _ref5 : '';
}
} else {
if (this.dim2 != null) {
$start = this.dim1["eval"]() - 1;
$end = this.dim2["eval"]();
if ($end < $start) {
throw 'Invalid String index: ' + this.toString();
}
return (_ref6 = (_ref7 = _str[this.name]) != null ? _ref7.slice($start, $end) : void 0) != null ? _ref6 : '';
} else if (this.dim1 != null) {
$start = this.dim1["eval"]() - 1;
return (_ref8 = (_ref9 = _str[this.name]) != null ? _ref9.slice($start) : void 0) != null ? _ref8 : '';
} else {
return (_ref10 = _str[this.name]) != null ? _ref10 : '';
}
}
} else if (this.dim2 != null) {
$dim1 = this.dim1["eval"]();
$dim2 = this.dim2["eval"]();
return (_ref11 = (_ref12 = _ary[this.name]) != null ? (_ref13 = _ref12[$dim1]) != null ? _ref13[$dim2] : void 0 : void 0) != null ? _ref11 : 0;
} else if (this.dim1 != null) {
$dim1 = this.dim1["eval"]();
return (_ref14 = (_ref15 = _ary[this.name]) != null ? _ref15[$dim1] : void 0) != null ? _ref14 : 0;
} else {
return (_ref16 = _var[this.name]) != null ? _ref16 : 0;
}
};
Var.prototype.toString = function() {
if (this.is_array) {
return "" + this.name + "[" + (this.dims.join(',')) + "]";
} else {
return this.name;
}
};
return Var;
})(),
Base: Base = (function(_super) {
__extends(Base, _super);
function Base(base) {
this.base = base;
}
Base.prototype["eval"] = function() {
_ofs = this.base;
return false;
};
Base.prototype.toString = function() {
return "BASE " + this.base;
};
return Base;
})(Keyword),
Chain: Chain = (function(_super) {
__extends(Chain, _super);
function Chain(program) {
this.program = program;
}
Chain.prototype["eval"] = function() {
_con.pause(true);
return _fs.readFile(this.program, function($err, $data) {
if ($err != null) {
_con.println($err);
} else {
_ver = $data.type;
_nam = $data.name;
_gw = _ver === V_GWBASIC ? true : false;
_chain($data.data);
}
return _con.pause(false);
});
};
Chain.prototype.toString = function() {
return "CHAIN \"" + this.program + "\"";
};
return Chain;
})(Keyword),
Com: Com = (function(_super) {
__extends(Com, _super);
Com.prototype.type = PHASE_SCAN;
function Com($vars) {
this.vars = _flatten($vars);
}
Com.prototype["eval"] = function() {
var $var, _i, _len, _ref;
_ref = this.vars;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
$var = _ref[_i];
if (/\$$/.test($var.name)) {
if (_gw) {
if ($var.dims.length === 0) {
_str[$var.name] = '';
} else {
_str[$var.name] = _dim.apply(null, [''].concat(__slice.call($var.dims)));
}
} else {
_str[$var.name] = Array($var.dims[0] + 1).join(' ');
_com.push({
type: 0,
name: $var.name
});
}
} else {
if ($var.dims.length === 0) {
_var[$var.name] = 0;
_com.push({
type: 1,
name: $var.name
});
} else {
_ary[$var.name] = _dim.apply(null, [0].concat(__slice.call($var.dims)));
_com.push({
type: 2,
name: $var.name
});
}
}
}
return false;
};
Com.prototype.toString = function() {
return "COM " + (this.vars.join(', '));
};
return Com;
})(Keyword),
Data: Data = (function(_super) {
__extends(Data, _super);
Data.prototype.type = PHASE_SCAN;
function Data($data) {
this.data = _flatten($data);
}
Data.prototype["eval"] = function() {
if (_dat === null) {
_dat = [];
}
_dat = _dat.concat(this.data);
return false;
};
Data.prototype.toString = function() {
return "DATA " + (this.data.join(', '));
};
return Data;
})(Keyword),
Def: Def = (function(_super) {
__extends(Def, _super);
Def.prototype.type = PHASE_SCAN;
function Def(name, par, body) {
this.name = name;
this.par = par;
this.body = body;
}
Def.prototype["eval"] = function() {
var _this = this;
_fn[this.name] = function($par) {
var $ret, $tmp;
$tmp = _var[_this.par];
_var[_this.par] = $par;
$ret = _this.body["eval"]();
_var[_this.par] = $tmp;
return $ret;
};
return false;
};
Def.prototype.toString = function() {
return "DEF " + this.name + "(" + this.par + ") = " + this.body;
};
return Def;
})(Keyword),
Dim: Dim = (function(_super) {
__extends(Dim, _super);
Dim.prototype.type = PHASE_SCAN;
function Dim($vars) {
this.vars = _flatten($vars);
}
Dim.prototype["eval"] = function() {
var $var, _i, _len, _ref;
_ref = this.vars;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
$var = _ref[_i];
if (/\$$/.test($var.name)) {
if (_gw) {
if ($var.dims.length === 0) {
_str[$var.name] = '';
} else {
_str[$var.name] = _dim.apply(null, [''].concat(__slice.call($var.dims)));
}
} else {
_str[$var.name] = Array($var.dims[0] + 1).join(' ');
}
} else {
if ($var.dims.length === 0) {
_var[$var.name] = 0;
} else {
_ary[$var.name] = _dim.apply(null, [0].concat(__slice.call($var.dims)));
}
}
}
return false;
};
Dim.prototype.toString = function() {
return "DIM " + (this.vars.join(', '));
};
return Dim;
})(Keyword),
End: End = (function(_super) {
__extends(End, _super);
function End() {
_ref = End.__super__.constructor.apply(this, arguments);
return _ref;
}
End.prototype["eval"] = function() {
_eop = true;
return false;
};
End.prototype.toString = function() {
return "END";
};
return End;
})(Keyword),
Enter: Enter = (function(_super) {
__extends(Enter, _super);
function Enter(port, time, status, _var1) {
var _ref1;
this.port = port;
this.time = time;
this.status = status;
this["var"] = _var1;
if (this["var"] == null) {
_ref1 = [null, this.port, this.time, this.status], this.port = _ref1[0], this.time = _ref1[1], this.status = _ref1[2], this["var"] = _ref1[3];
}
}
Enter.prototype["eval"] = function() {
_con.input('', [this["var"]]);
return true;
};
Enter.prototype.toString = function() {
return "ENTER " + this.port + ", " + this.time + ", " + this.status + ", " + this["var"];
};
return Enter;
})(Keyword),
For: For = (function(_super) {
__extends(For, _super);
function For(_var1, start, end, step) {
this["var"] = _var1;
this.start = start;
this.end = end;
this.step = step != null ? step : new Const(1);
}
For.prototype["eval"] = function() {
_var[this["var"]] = _eval(this.start);
_stk.push({
id: FOR,
pc: _pc,
name: this["var"],
end: this.end,
step: this.step
});
return false;
};
For.prototype.toString = function() {
if (this.step === 1) {
return "FOR " + this["var"] + " = " + this.start + " TO " + this.end;
} else {
return "FOR " + this["var"] + " = " + this.start + " TO " + this.end + " STEP " + this.step;
}
};
return For;
})(Keyword),
Goto: Goto = (function(_super) {
__extends(Goto, _super);
function Goto(lineno, $of) {
this.lineno = lineno;
this.of = _flatten($of);
}
Goto.prototype["eval"] = function() {
var $index;
if (this.of.length > 0) {
$index = _eval(this.lineno) - 1;
if (this.of[$index] != null) {
_pc = _xrf[this.of[$index]];
}
} else {
_pc = _xrf[parseInt(this.lineno, 10)];
}
return false;
};
Goto.prototype.toString = function() {
if (this.of.length > (0 != null)) {
return "GOTO " + this.lineno + " OF " + (this.of.join(','));
} else {
return "GOTO " + this.lineno;
}
};
return Goto;
})(Keyword),
Gosub: Gosub = (function(_super) {
__extends(Gosub, _super);
function Gosub(lineno, $of) {
this.lineno = lineno;
this.of = _flatten($of);
}
Gosub.prototype["eval"] = function() {
_stk.push({
id: GOSUB,
pc: _pc
});
return Gosub.__super__["eval"].call(this);
};
Gosub.prototype.toString = function() {
if (this.of.length > (0 != null)) {
return "GOSUB " + this.lineno + " OF " + (this.of.join(','));
} else {
return "GOSUB " + this.lineno;
}
};
return Gosub;
})(Goto),
If: If = (function(_super) {
__extends(If, _super);
function If(cond, then) {
this.cond = cond;
this.then = then;
}
If.prototype["eval"] = function() {
if (this.cond["eval"]()) {
if (this.then["eval"] != null) {
this.then["eval"]();
} else {
_pc = _xrf[parseInt(this.then, 10)];
}
}
return false;
};
If.prototype.toString = function() {
return "IF " + this.cond + " THEN " + this.then;
};
return If;
})(Keyword),
Image: Image = (function(_super) {
__extends(Image, _super);
function Image($format) {
if ($format == null) {
$format = [];
}
this.source = _flatten($format);
this.format = _format(this.source);
}
Image.prototype["eval"] = function() {
return false;
};
Image.prototype.toString = function() {
return "IMAGE " + (this.source.join(''));
};
return Image;
})(Keyword),
Input: Input = (function(_super) {
__extends(Input, _super);
function Input($vars, prompt) {
this.prompt = prompt;
this.vars = _flatten($vars);
}
Input.prototype["eval"] = function() {
_con.input(this.prompt, this.vars);
return true;
};
Input.prototype.toString = function() {
if (this.prompt != null) {
return "INPUT " + this.prompt + ", " + (this.vars.join(','));
} else {
return "INPUT " + (this.vars.join(','));
}
};
return Input;
})(Keyword),
Let: Let = (function(_super) {
__extends(Let, _super);
function Let($vars, value) {
var $var, _i, _len, _ref1;
this.value = value;
this.vars = [];
_ref1 = _flatten($vars);
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
$var = _ref1[_i];
if ('string' === typeof $var) {
this.vars.push(new Var($var));
} else {
this.vars.push($var);
}
}
}
Let.prototype["eval"] = function() {
var $value, $var, _i, _len, _ref1;
$value = _eval(this.value);
_ref1 = this.vars;
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
$var = _ref1[_i];
$var["let"]($value);
}
return false;
};
Let.prototype.toString = function() {
var $s, $var, _i, _len, _ref1;
$s = '';
_ref1 = this.vars;
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
$var = _ref1[_i];
$s += $var + ' = ';
}
return "LET " + $s + this.value;
};
return Let;
})(Keyword),
Mat: Mat = (function(_super) {
__extends(Mat, _super);
function Mat(_var1, value) {
this["var"] = _var1;
this.value = value;
}
Mat.prototype["eval"] = function() {
var $i, $j, $value;
$value = this.value["eval"]();
if (_ary[this["var"]] != null) {
$i = _ary[this["var"]].length;
$j = _ary[this["var"]][_ofs].length;
_ary[this["var"]] = _dim($value, $i, $j);
} else {
_ary[this["var"]] = _dim($value, 10);
}
return false;
};
return Mat;
})(Keyword),
MatRead: MatRead = (function(_super) {
__extends(MatRead, _super);
function MatRead($vars) {
this.vars = _flatten($vars);
}
MatRead.prototype["eval"] = function() {
var $var, _i, _len, _ref1;
_ref1 = this.vars;
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
$var = _ref1[_i];
if (_dp < _dat.length) {
$var["let"](_dat[_dp++].value);
} else {
$var["let"](void 0);
}
}
return false;
};
MatRead.prototype.toString = function() {
return "MAT READ " + (this.vars.join(','));
};
return MatRead;
})(Keyword),
Next: Next = (function(_super) {
__extends(Next, _super);
function Next(_var1) {
this["var"] = _var1;
}
Next.prototype["eval"] = function() {
var $counter, $frame, $name, $step;
$frame = _stk[_stk.length - 1];
if ($frame.id !== FOR) {
throw "Next without for";
}
$name = this["var"].name;
if ($frame.name !== $name) {
throw "Mismatched For/Next " + $name;
}
$step = _eval($frame.step);
$counter = this["var"]["eval"]() + $step;
this["var"]["let"]($counter);
if ($step < 0) {
if ($counter < _eval($frame.end)) {
_stk.pop();
} else {
_pc = $frame.pc;
}
} else {
if ($counter > _eval($frame.end)) {
_stk.pop();
} else {
_pc = $frame.pc;
}
}
return false;
};
Next.prototype.toString = function() {
return "NEXT " + this["var"];
};
return Next;
})(Keyword),
Print: Print = (function(_super) {
__extends(Print, _super);
function Print() {
var $items;
$items = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
this.items = _flatten([$items]);
}
Print.prototype["eval"] = function() {
var $item, $str, $val, _i, _len, _ref1;
$str = '';
_ref1 = this.items;
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
$item = _ref1[_i];
$str += isNaN($val = _eval($item)) ? $val : ' ' + $val;
}
if ($item === Semic || $item === Comma) {
_con.print($str);
} else {
_con.println($str);
}
return false;
};
Print.prototype.toString = function() {
var $item, $str, _i, _len, _ref1;
$str = '';
_ref1 = this.items;
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
$item = _ref1[_i];
$str += $item.toString();
}
return "PRINT " + $str;
};
return Print;
})(Keyword),
Using: Using = (function(_super) {
__extends(Using, _super);
function Using() {
var $items, lineno;
lineno = arguments[0], $items = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
this.lineno = lineno;
this.items = _flatten($items);
}
Using.prototype["eval"] = function() {
var $args, $i, $item, $lineno, $statement, _i, _len, _ref1, _ref2;
$i = _xrf[this.lineno];
_ref1 = _prg[$i], $lineno = _ref1[0], $statement = _ref1[1];
$args = [];
_ref2 = this.items;
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
$item = _ref2[_i];
$args.push(_eval($item));
}
if ($item === Semic || $item === Comma) {
_con.print(_sprintf($statement.code.format, $args));
} else {
_con.println(_sprintf($statement.code.format, $args));
}
return false;
};
Using.prototype.toString = function() {
var $item, $str, _i, _len, _ref1;
if (this.items.length === 0) {
return "PRINT USING " + this.lineno;
} else {
$str = '';
_ref1 = this.items;
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
$item = _ref1[_i];
$str += $item.toString() + ',';
}
$str = $str.slice(0, -1);
return "PRINT USING " + this.lineno + ";" + $str;
}
};
return Using;
})(Keyword),
Randomize: Randomize = (function(_super) {
__extends(Randomize, _super);
function Randomize() {}
Randomize.prototype["eval"] = function() {
return false;
};
Randomize.prototype.toString = function() {
return "RANDOMIZE";
};
return Randomize;
})(Keyword),
Read: Read = (function(_super) {
__extends(Read, _super);
function Read($vars) {
this.vars = _flatten($vars);
}
Read.prototype["eval"] = function() {
var $var, _i, _len, _ref1;
_ref1 = this.vars;
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
$var = _ref1[_i];
if (_dp < _dat.length) {
$var["let"](_dat[_dp++].value);
} else {
$var["let"](void 0);
}
}
return false;
};
Read.prototype.toString = function() {
return "READ " + (this.vars.join(','));
};
return Read;
})(Keyword),
Restore: Restore = (function(_super) {
__extends(Restore, _super);
function Restore(lineno) {
this.lineno = lineno;
}
Restore.prototype["eval"] = function() {
_dp = 0;
return false;
};
Restore.prototype.toString = function() {
if (this.lineno != null) {
return "RESTORE " + this.lineno;
} else {
return "RESTORE";
}
};
return Restore;
})(Keyword),
Return: Return = (function(_super) {
__extends(Return, _super);
function Return() {}
Return.prototype["eval"] = function() {
var $frame;
$frame = _stk.pop();
while ($frame.id !== GOSUB) {
$frame = _stk.pop();
}
_pc = $frame.pc;
return false;
};
Return.prototype.toString = function() {
return "RETURN";
};
return Return;
})(Keyword),
Rem: Rem = (function(_super) {
__extends(Rem, _super);
function Rem($text) {
this.text = $text.replace(/^REM/i, '');
}
Rem.prototype["eval"] = function() {
return false;
};
Rem.prototype.toString = function() {
return "REM" + this.text;
};
return Rem;
})(Keyword),
Stop: Stop = (function(_super) {
__extends(Stop, _super);
function Stop() {}
Stop.prototype["eval"] = function() {
_eop = true;
return false;
};
Stop.prototype.toString = function() {
return "STOP";
};
return Stop;
})(Keyword),
Max: Max = (function(_super) {
__extends(Max, _super);
function Max() {
_ref1 = Max.__super__.constructor.apply(this, arguments);
return _ref1;
}
Max.prototype["eval"] = function() {
return Math.max(_eval(this.left), _eval(this.right));
};
Max.prototype.toString = function() {
return "" + this.left + " MAX " + this.right;
};
return Max;
})(Operator),
Min: Min = (function(_super) {
__extends(Min, _super);
function Min() {
_ref2 = Min.__super__.constructor.apply(this, arguments);
return _ref2;
}
Min.prototype["eval"] = function() {
return Math.min(_eval(this.left), _eval(this.right));
};
Min.prototype.toString = function() {
return "" + this.left + " MIN " + this.right;
};
return Min;
})(Operator),
Add: Add = (function(_super) {
__extends(Add, _super);
function Add() {
_ref3 = Add._