Completed list of intrisics.
git-svn-id: https://shellinabox.googlecode.com/svn/trunk@110 0da03de8-d603-11dd-86c2-0f8696b7b6f9
This commit is contained in:
parent
2d6973ceab
commit
f2dc904c0c
2 changed files with 176 additions and 24 deletions
100
demo/demo.js
100
demo/demo.js
|
@ -288,7 +288,9 @@ Demo.prototype.doEval = function() {
|
||||||
var token = this.tokens.nextToken();
|
var token = this.tokens.nextToken();
|
||||||
if (token == "HELP") {
|
if (token == "HELP") {
|
||||||
this.vt100('Supported commands:\r\n' +
|
this.vt100('Supported commands:\r\n' +
|
||||||
' HELP LIST NEW PRINT RUN\r\n');
|
'ABS ASC ATN CHR$ COS EXP HELP INT LEFT$ LIST LEN LOG MID$\r\n'+
|
||||||
|
'NEW POS PRINT RIGHT$ RND RUN SGN SIN SPC SQR STR$ TAB TAN\r\n'+
|
||||||
|
'TI VAL\r\n');
|
||||||
} else if (token == "LIST") {
|
} else if (token == "LIST") {
|
||||||
this.doList();
|
this.doList();
|
||||||
} else if (token == "NEW") {
|
} else if (token == "NEW") {
|
||||||
|
@ -583,10 +585,10 @@ Demo.prototype.expn = function() {
|
||||||
Demo.prototype.intrinsic = function() {
|
Demo.prototype.intrinsic = function() {
|
||||||
var token = this.tokens.peekToken();
|
var token = this.tokens.peekToken();
|
||||||
var args = undefined;
|
var args = undefined;
|
||||||
var fnc, arg1, arg2, arg3;
|
var value, v, fnc, arg1, arg2, arg3;
|
||||||
if (!token) {
|
if (!token) {
|
||||||
return this.error('Unexpected end of input');
|
return this.error('Unexpected end of input');
|
||||||
} else if (token.match(/^(?:ABS|ASC|ATN|CHR\$|COS|EXP|INT|LEN|LOG|POS|RND|SGN|SIN|SPC|SQR|STR\$|TAN|VAL)$/)) {
|
} else if (token.match(/^(?:ABS|ASC|ATN|CHR\$|COS|EXP|INT|LEN|LOG|POS|RND|SGN|SIN|SPC|SQR|STR\$|TAB|TAN|VAL)$/)) {
|
||||||
fnc = token;
|
fnc = token;
|
||||||
args = 1;
|
args = 1;
|
||||||
} else if (token.match(/^(?:LEFT\$|RIGHT\$)$/)) {
|
} else if (token.match(/^(?:LEFT\$|RIGHT\$)$/)) {
|
||||||
|
@ -595,6 +597,10 @@ Demo.prototype.intrinsic = function() {
|
||||||
} else if (token == 'MID$') {
|
} else if (token == 'MID$') {
|
||||||
fnc = token;
|
fnc = token;
|
||||||
args = 3;
|
args = 3;
|
||||||
|
} else if (token == 'TI') {
|
||||||
|
this.tokens.consume();
|
||||||
|
v = (new Date()).getTime() / 1000.0;
|
||||||
|
return new this.Value(1 /* TYPE_NUMBER */, '' + v, v);
|
||||||
} else {
|
} else {
|
||||||
return this.factor();
|
return this.factor();
|
||||||
}
|
}
|
||||||
|
@ -631,25 +637,69 @@ Demo.prototype.intrinsic = function() {
|
||||||
if (token != ')') {
|
if (token != ')') {
|
||||||
return this.error('")" expected');
|
return this.error('")" expected');
|
||||||
}
|
}
|
||||||
var value, v;
|
|
||||||
switch (fnc) {
|
switch (fnc) {
|
||||||
case 'ASC':
|
case 'ASC':
|
||||||
if (arg1.type() != 0 /* TYPE_STRING */ || arg1.val().length < 1) {
|
if (arg1.type() != 0 /* TYPE_STRING */ || arg1.val().length < 1) {
|
||||||
return this.error('Non-empty string expected');
|
return this.error('Non-empty string expected');
|
||||||
}
|
}
|
||||||
v = arg1.val().charCodeAt[0];
|
v = arg1.val().charCodeAt(0);
|
||||||
value = new this.Value(1 /* TYPE_NUMBER */, '' + v, v);
|
value = new this.Value(1 /* TYPE_NUMBER */, '' + v, v);
|
||||||
break;
|
break;
|
||||||
case 'LEN':
|
case 'LEN':
|
||||||
|
if (arg1.type() != 0 /* TYPE_STRING */) {
|
||||||
|
return this.error('String expected');
|
||||||
|
}
|
||||||
|
v = arg1.val().length;
|
||||||
|
value = new this.Value(1 /* TYPE_NUMBER */, '' + v, v);
|
||||||
|
break;
|
||||||
case 'LEFT$':
|
case 'LEFT$':
|
||||||
|
if (arg1.type() != 0 /* TYPE_STRING */ || arg2.type() != 1 /* TYPE_NUMBER */ ||
|
||||||
|
arg2.type() < 0) {
|
||||||
|
return this.error('Invalid arguments');
|
||||||
|
}
|
||||||
|
v = arg1.val().substr(0, Math.floor(arg2.val()));
|
||||||
|
value = new this.Value(0 /* TYPE_STRING */, v, v);
|
||||||
|
break;
|
||||||
case 'MID$':
|
case 'MID$':
|
||||||
|
if (arg1.type() != 0 /* TYPE_STRING */ || arg2.type() != 1 /* TYPE_NUMBER */ ||
|
||||||
|
arg3.type() != 1 /* TYPE_NUMBER */ || arg2.val() < 0 || arg3.val() < 0) {
|
||||||
|
return this.error('Invalid arguments');
|
||||||
|
}
|
||||||
|
v = arg1.val().substr(Math.floor(arg2.val()),
|
||||||
|
Math.floor(arg3.val()));
|
||||||
|
value = new this.Value(0 /* TYPE_STRING */, v, v);
|
||||||
|
break;
|
||||||
case 'RIGHT$':
|
case 'RIGHT$':
|
||||||
|
if (arg1.type() != 0 /* TYPE_STRING */ || arg2.type() != 1 /* TYPE_NUMBER */ ||
|
||||||
|
arg2.type() < 0) {
|
||||||
|
return this.error('Invalid arguments');
|
||||||
|
}
|
||||||
|
v = Math.floor(arg2.val());
|
||||||
|
if (v > arg1.val().length) {
|
||||||
|
v = arg1.val().length;
|
||||||
|
}
|
||||||
|
v = arg1.val().substr(arg1.val().length - v);
|
||||||
|
value = new this.Value(0 /* TYPE_STRING */, v, v);
|
||||||
|
break;
|
||||||
case 'STR$':
|
case 'STR$':
|
||||||
|
value = new this.Value(0 /* TYPE_STRING */, arg1.toString(),
|
||||||
|
arg1.toString());
|
||||||
|
break;
|
||||||
case 'VAL':
|
case 'VAL':
|
||||||
return this.error('Unimplemented');
|
if (arg1.type() == 1 /* TYPE_NUMBER */) {
|
||||||
|
value = arg1;
|
||||||
|
} else {
|
||||||
|
if (arg1.val().match(/^[0-9]+$/)) {
|
||||||
|
v = parseInt(arg1.val());
|
||||||
|
} else {
|
||||||
|
v = parseFloat(arg1.val());
|
||||||
|
}
|
||||||
|
value = new this.Value(1 /* TYPE_NUMBER */, '' + v, v);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (arg1.type() != 1 /* TYPE_NUMBER */) {
|
if (arg1.type() != 1 /* TYPE_NUMBER */) {
|
||||||
return this.error('Need a numeric argument');
|
return this.error('Numeric value expected');
|
||||||
}
|
}
|
||||||
switch (fnc) {
|
switch (fnc) {
|
||||||
case 'CHR$':
|
case 'CHR$':
|
||||||
|
@ -667,6 +717,14 @@ Demo.prototype.intrinsic = function() {
|
||||||
'\u001B[' + Math.floor(arg1.val()) + 'C' : '';
|
'\u001B[' + Math.floor(arg1.val()) + 'C' : '';
|
||||||
value = new this.Value(0 /* TYPE_STRING */, v, v);
|
value = new this.Value(0 /* TYPE_STRING */, v, v);
|
||||||
break;
|
break;
|
||||||
|
case 'TAB':
|
||||||
|
if (arg1.val() < 0) {
|
||||||
|
return this.error('Range error');
|
||||||
|
}
|
||||||
|
v = '\r' + (arg1.val() >= 1 ?
|
||||||
|
'\u001B[' + (Math.floor(arg1.val())*8) + 'C' : '');
|
||||||
|
value = new this.Value(0 /* TYPE_STRING */, v, v);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
switch (fnc) {
|
switch (fnc) {
|
||||||
case 'ABS': v = Math.abs(arg1.val()); break;
|
case 'ABS': v = Math.abs(arg1.val()); break;
|
||||||
|
@ -680,10 +738,19 @@ Demo.prototype.intrinsic = function() {
|
||||||
case 'SIN': v = Math.sin(arg1.val()); break;
|
case 'SIN': v = Math.sin(arg1.val()); break;
|
||||||
case 'SQR': v = Math.sqrt(arg1.val()); break;
|
case 'SQR': v = Math.sqrt(arg1.val()); break;
|
||||||
case 'TAN': v = Math.tan(arg1.val()); break;
|
case 'TAN': v = Math.tan(arg1.val()); break;
|
||||||
|
|
||||||
case 'RND':
|
case 'RND':
|
||||||
default:
|
if (this.prng == undefined) {
|
||||||
return this.error('Unimplemented');
|
this.prng = 1013904223;
|
||||||
|
}
|
||||||
|
if (arg1.type() == 1 /* TYPE_NUMBER */ && arg1.val() < 0) {
|
||||||
|
this.prng = Math.floor(1664525*arg1.val()) & 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
if (arg1.type() != 1 /* TYPE_NUMBER */ || arg1.val() != 0) {
|
||||||
|
this.prng = Math.floor(1664525*this.prng + 1013904223) &
|
||||||
|
0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
v = ((this.prng & 0x7FFFFFFF) / 65536.0) / 32768;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
value = new this.Value(1 /* TYPE_NUMBER */, '' + v, v);
|
value = new this.Value(1 /* TYPE_NUMBER */, '' + v, v);
|
||||||
}
|
}
|
||||||
|
@ -696,11 +763,20 @@ Demo.prototype.intrinsic = function() {
|
||||||
|
|
||||||
Demo.prototype.factor = function() {
|
Demo.prototype.factor = function() {
|
||||||
var token = this.tokens.nextToken();
|
var token = this.tokens.nextToken();
|
||||||
|
var value;
|
||||||
|
if (token == '-') {
|
||||||
|
value = this.expr();
|
||||||
|
if (!value) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
if (value.type() != 1 /* TYPE_NUMBER */) {
|
||||||
|
return this.error('Numeric value expected');
|
||||||
|
}
|
||||||
|
return new this.Value(1 /* TYPE_NUMBER */, '' + -value.val(), -value.val());
|
||||||
|
}
|
||||||
if (!token) {
|
if (!token) {
|
||||||
return this.error();
|
return this.error();
|
||||||
}
|
}
|
||||||
|
|
||||||
var value = undefined;
|
|
||||||
if (token == '(') {
|
if (token == '(') {
|
||||||
value = this.expr();
|
value = this.expr();
|
||||||
token = this.tokens.nextToken();
|
token = this.tokens.nextToken();
|
||||||
|
|
100
demo/demo.jspp
100
demo/demo.jspp
|
@ -288,7 +288,9 @@ Demo.prototype.doEval = function() {
|
||||||
var token = this.tokens.nextToken();
|
var token = this.tokens.nextToken();
|
||||||
if (token == "HELP") {
|
if (token == "HELP") {
|
||||||
this.vt100('Supported commands:\r\n' +
|
this.vt100('Supported commands:\r\n' +
|
||||||
' HELP LIST NEW PRINT RUN\r\n');
|
'ABS ASC ATN CHR$ COS EXP HELP INT LEFT$ LIST LEN LOG MID$\r\n'+
|
||||||
|
'NEW POS PRINT RIGHT$ RND RUN SGN SIN SPC SQR STR$ TAB TAN\r\n'+
|
||||||
|
'TI VAL\r\n');
|
||||||
} else if (token == "LIST") {
|
} else if (token == "LIST") {
|
||||||
this.doList();
|
this.doList();
|
||||||
} else if (token == "NEW") {
|
} else if (token == "NEW") {
|
||||||
|
@ -583,10 +585,10 @@ Demo.prototype.expn = function() {
|
||||||
Demo.prototype.intrinsic = function() {
|
Demo.prototype.intrinsic = function() {
|
||||||
var token = this.tokens.peekToken();
|
var token = this.tokens.peekToken();
|
||||||
var args = undefined;
|
var args = undefined;
|
||||||
var fnc, arg1, arg2, arg3;
|
var value, v, fnc, arg1, arg2, arg3;
|
||||||
if (!token) {
|
if (!token) {
|
||||||
return this.error('Unexpected end of input');
|
return this.error('Unexpected end of input');
|
||||||
} else if (token.match(/^(?:ABS|ASC|ATN|CHR\$|COS|EXP|INT|LEN|LOG|POS|RND|SGN|SIN|SPC|SQR|STR\$|TAN|VAL)$/)) {
|
} else if (token.match(/^(?:ABS|ASC|ATN|CHR\$|COS|EXP|INT|LEN|LOG|POS|RND|SGN|SIN|SPC|SQR|STR\$|TAB|TAN|VAL)$/)) {
|
||||||
fnc = token;
|
fnc = token;
|
||||||
args = 1;
|
args = 1;
|
||||||
} else if (token.match(/^(?:LEFT\$|RIGHT\$)$/)) {
|
} else if (token.match(/^(?:LEFT\$|RIGHT\$)$/)) {
|
||||||
|
@ -595,6 +597,10 @@ Demo.prototype.intrinsic = function() {
|
||||||
} else if (token == 'MID$') {
|
} else if (token == 'MID$') {
|
||||||
fnc = token;
|
fnc = token;
|
||||||
args = 3;
|
args = 3;
|
||||||
|
} else if (token == 'TI') {
|
||||||
|
this.tokens.consume();
|
||||||
|
v = (new Date()).getTime() / 1000.0;
|
||||||
|
return new this.Value(TYPE_NUMBER, '' + v, v);
|
||||||
} else {
|
} else {
|
||||||
return this.factor();
|
return this.factor();
|
||||||
}
|
}
|
||||||
|
@ -631,25 +637,69 @@ Demo.prototype.intrinsic = function() {
|
||||||
if (token != ')') {
|
if (token != ')') {
|
||||||
return this.error('")" expected');
|
return this.error('")" expected');
|
||||||
}
|
}
|
||||||
var value, v;
|
|
||||||
switch (fnc) {
|
switch (fnc) {
|
||||||
case 'ASC':
|
case 'ASC':
|
||||||
if (arg1.type() != TYPE_STRING || arg1.val().length < 1) {
|
if (arg1.type() != TYPE_STRING || arg1.val().length < 1) {
|
||||||
return this.error('Non-empty string expected');
|
return this.error('Non-empty string expected');
|
||||||
}
|
}
|
||||||
v = arg1.val().charCodeAt[0];
|
v = arg1.val().charCodeAt(0);
|
||||||
value = new this.Value(TYPE_NUMBER, '' + v, v);
|
value = new this.Value(TYPE_NUMBER, '' + v, v);
|
||||||
break;
|
break;
|
||||||
case 'LEN':
|
case 'LEN':
|
||||||
|
if (arg1.type() != TYPE_STRING) {
|
||||||
|
return this.error('String expected');
|
||||||
|
}
|
||||||
|
v = arg1.val().length;
|
||||||
|
value = new this.Value(TYPE_NUMBER, '' + v, v);
|
||||||
|
break;
|
||||||
case 'LEFT$':
|
case 'LEFT$':
|
||||||
|
if (arg1.type() != TYPE_STRING || arg2.type() != TYPE_NUMBER ||
|
||||||
|
arg2.type() < 0) {
|
||||||
|
return this.error('Invalid arguments');
|
||||||
|
}
|
||||||
|
v = arg1.val().substr(0, Math.floor(arg2.val()));
|
||||||
|
value = new this.Value(TYPE_STRING, v, v);
|
||||||
|
break;
|
||||||
case 'MID$':
|
case 'MID$':
|
||||||
|
if (arg1.type() != TYPE_STRING || arg2.type() != TYPE_NUMBER ||
|
||||||
|
arg3.type() != TYPE_NUMBER || arg2.val() < 0 || arg3.val() < 0) {
|
||||||
|
return this.error('Invalid arguments');
|
||||||
|
}
|
||||||
|
v = arg1.val().substr(Math.floor(arg2.val()),
|
||||||
|
Math.floor(arg3.val()));
|
||||||
|
value = new this.Value(TYPE_STRING, v, v);
|
||||||
|
break;
|
||||||
case 'RIGHT$':
|
case 'RIGHT$':
|
||||||
|
if (arg1.type() != TYPE_STRING || arg2.type() != TYPE_NUMBER ||
|
||||||
|
arg2.type() < 0) {
|
||||||
|
return this.error('Invalid arguments');
|
||||||
|
}
|
||||||
|
v = Math.floor(arg2.val());
|
||||||
|
if (v > arg1.val().length) {
|
||||||
|
v = arg1.val().length;
|
||||||
|
}
|
||||||
|
v = arg1.val().substr(arg1.val().length - v);
|
||||||
|
value = new this.Value(TYPE_STRING, v, v);
|
||||||
|
break;
|
||||||
case 'STR$':
|
case 'STR$':
|
||||||
|
value = new this.Value(TYPE_STRING, arg1.toString(),
|
||||||
|
arg1.toString());
|
||||||
|
break;
|
||||||
case 'VAL':
|
case 'VAL':
|
||||||
return this.error('Unimplemented');
|
if (arg1.type() == TYPE_NUMBER) {
|
||||||
|
value = arg1;
|
||||||
|
} else {
|
||||||
|
if (arg1.val().match(/^[0-9]+$/)) {
|
||||||
|
v = parseInt(arg1.val());
|
||||||
|
} else {
|
||||||
|
v = parseFloat(arg1.val());
|
||||||
|
}
|
||||||
|
value = new this.Value(TYPE_NUMBER, '' + v, v);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (arg1.type() != TYPE_NUMBER) {
|
if (arg1.type() != TYPE_NUMBER) {
|
||||||
return this.error('Need a numeric argument');
|
return this.error('Numeric value expected');
|
||||||
}
|
}
|
||||||
switch (fnc) {
|
switch (fnc) {
|
||||||
case 'CHR$':
|
case 'CHR$':
|
||||||
|
@ -667,6 +717,14 @@ Demo.prototype.intrinsic = function() {
|
||||||
'\u001B[' + Math.floor(arg1.val()) + 'C' : '';
|
'\u001B[' + Math.floor(arg1.val()) + 'C' : '';
|
||||||
value = new this.Value(TYPE_STRING, v, v);
|
value = new this.Value(TYPE_STRING, v, v);
|
||||||
break;
|
break;
|
||||||
|
case 'TAB':
|
||||||
|
if (arg1.val() < 0) {
|
||||||
|
return this.error('Range error');
|
||||||
|
}
|
||||||
|
v = '\r' + (arg1.val() >= 1 ?
|
||||||
|
'\u001B[' + (Math.floor(arg1.val())*8) + 'C' : '');
|
||||||
|
value = new this.Value(TYPE_STRING, v, v);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
switch (fnc) {
|
switch (fnc) {
|
||||||
case 'ABS': v = Math.abs(arg1.val()); break;
|
case 'ABS': v = Math.abs(arg1.val()); break;
|
||||||
|
@ -680,10 +738,19 @@ Demo.prototype.intrinsic = function() {
|
||||||
case 'SIN': v = Math.sin(arg1.val()); break;
|
case 'SIN': v = Math.sin(arg1.val()); break;
|
||||||
case 'SQR': v = Math.sqrt(arg1.val()); break;
|
case 'SQR': v = Math.sqrt(arg1.val()); break;
|
||||||
case 'TAN': v = Math.tan(arg1.val()); break;
|
case 'TAN': v = Math.tan(arg1.val()); break;
|
||||||
|
|
||||||
case 'RND':
|
case 'RND':
|
||||||
default:
|
if (this.prng == undefined) {
|
||||||
return this.error('Unimplemented');
|
this.prng = 1013904223;
|
||||||
|
}
|
||||||
|
if (arg1.type() == TYPE_NUMBER && arg1.val() < 0) {
|
||||||
|
this.prng = Math.floor(1664525*arg1.val()) & 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
if (arg1.type() != TYPE_NUMBER || arg1.val() != 0) {
|
||||||
|
this.prng = Math.floor(1664525*this.prng + 1013904223) &
|
||||||
|
0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
v = ((this.prng & 0x7FFFFFFF) / 65536.0) / 32768;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
value = new this.Value(TYPE_NUMBER, '' + v, v);
|
value = new this.Value(TYPE_NUMBER, '' + v, v);
|
||||||
}
|
}
|
||||||
|
@ -696,11 +763,20 @@ Demo.prototype.intrinsic = function() {
|
||||||
|
|
||||||
Demo.prototype.factor = function() {
|
Demo.prototype.factor = function() {
|
||||||
var token = this.tokens.nextToken();
|
var token = this.tokens.nextToken();
|
||||||
|
var value;
|
||||||
|
if (token == '-') {
|
||||||
|
value = this.expr();
|
||||||
|
if (!value) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
if (value.type() != TYPE_NUMBER) {
|
||||||
|
return this.error('Numeric value expected');
|
||||||
|
}
|
||||||
|
return new this.Value(TYPE_NUMBER, '' + -value.val(), -value.val());
|
||||||
|
}
|
||||||
if (!token) {
|
if (!token) {
|
||||||
return this.error();
|
return this.error();
|
||||||
}
|
}
|
||||||
|
|
||||||
var value = undefined;
|
|
||||||
if (token == '(') {
|
if (token == '(') {
|
||||||
value = this.expr();
|
value = this.expr();
|
||||||
token = this.tokens.nextToken();
|
token = this.tokens.nextToken();
|
||||||
|
|
Loading…
Reference in a new issue