Added support for arrays and integer variables.

git-svn-id: https://shellinabox.googlecode.com/svn/trunk@112 0da03de8-d603-11dd-86c2-0f8696b7b6f9
This commit is contained in:
zodiac 2009-04-12 17:00:21 +00:00
parent ea033cbd18
commit 8c077b9a85
2 changed files with 234 additions and 38 deletions

View file

@ -74,12 +74,6 @@
// #define TYPE_STRING 0 // #define TYPE_STRING 0
// #define TYPE_NUMBER 1 // #define TYPE_NUMBER 1
// #define TYPE_VAR 2
// #define TYPE_STRVAR 3
// #define TYPE_INTVAR 4
// #define TYPE_ARR 5
// #define TYPE_STRARR 6
// #define TYPE_INTARR 7
function extend(subClass, baseClass) { function extend(subClass, baseClass) {
function inheritance() { } function inheritance() { }
@ -287,13 +281,16 @@ Demo.prototype.doCommand = function() {
Demo.prototype.doEval = function() { Demo.prototype.doEval = function() {
this.gotoState(2 /* STATE_PROMPT */); this.gotoState(2 /* STATE_PROMPT */);
var token = this.tokens.peekToken(); var token = this.tokens.peekToken();
if (token == "HELP") { if (token == "DIM") {
this.tokens.consume();
this.doDim();
} else if (token == "HELP") {
this.tokens.consume(); this.tokens.consume();
if (this.tokens.nextToken() != undefined) { if (this.tokens.nextToken() != undefined) {
this.error('HELP does not take any arguments'); this.error('HELP does not take any arguments');
} else { } else {
this.vt100('Supported commands:\r\n' + this.vt100('Supported commands:\r\n' +
'HELP LET LIST NEW PRINT RUN\r\n'+ 'DIM HELP LET LIST NEW PRINT RUN\r\n'+
'\r\n'+ '\r\n'+
'Supported functions:\r\n'+ 'Supported functions:\r\n'+
'ABS() ASC() ATN() CHR$() COS() EXP() INT() LEFT$() LEN()\r\n'+ 'ABS() ASC() ATN() CHR$() COS() EXP() INT() LEFT$() LEN()\r\n'+
@ -327,6 +324,7 @@ Demo.prototype.doEval = function() {
this.error('RUN does not take any parameters'); this.error('RUN does not take any parameters');
} else if (this.program.length > 0) { } else if (this.program.length > 0) {
this.currentLineIndex = 0; this.currentLineIndex = 0;
this.vars = new Object();
this.gotoState(6 /* STATE_EXEC */); this.gotoState(6 /* STATE_EXEC */);
} else { } else {
this.ok(); this.ok();
@ -337,17 +335,102 @@ Demo.prototype.doEval = function() {
return false; return false;
}; };
Demo.prototype.doDim = function() {
for (;;) {
var token = this.tokens.nextToken();
if (token == undefined) {
return;
}
if (!token || !token.match(/^[A-Za-z][A-Za-z0-9_]*$/)) {
return this.error('Identifier expected');
}
token = this.tokens.nextToken();
if (token == '$' || token == '%') {
token = this.tokens.nextToken();
}
if (token != '(') {
return this.error('"(" expected');
}
do {
var size = this.expr();
if (!size) {
return size;
}
if (size.type() != 1 /* TYPE_NUMBER */) {
return this.error('Numeric value expected');
}
if (Math.floor(size.val()) < 1) {
return this.error('Range error');
}
token = this.tokens.nextToken();
} while (token == ',');
if (token != ')') {
return this.error('")" expected');
}
if (this.tokens.peekToken() != ',') {
break;
}
this.tokens.consume();
}
if (this.tokens.peekToken() != undefined) {
return this.error();
}
};
Demo.prototype.arrayIndex = function() {
var token = this.tokens.peekToken();
var arr = '';
if (token == '(') {
this.tokens.consume();
do {
var idx = this.expr();
if (idx == undefined) {
return idx;
} else if (idx.type() != 1 /* TYPE_NUMBER */) {
return this.error('Numeric value expected');
}
idx = Math.floor(idx.val());
if (idx < 0) {
return this.error('Indices have to be positive');
}
arr += ',' + idx;
token = this.tokens.nextToken();
} while (token == ',');
if (token != ')') {
return this.error('")" expected');
}
}
return arr;
};
Demo.prototype.toInt = function(v) {
if (v < 0) {
return -Math.floor(-v);
} else {
return Math.floor( v);
}
};
Demo.prototype.doAssignment = function() { Demo.prototype.doAssignment = function() {
var id = this.tokens.nextToken(); var id = this.tokens.nextToken();
if (!id || !id.match(/^[A-Za-z][A-Za-z0-9_]*$/)) { if (!id || !id.match(/^[A-Za-z][A-Za-z0-9_]*$/)) {
return this.error('Identifier expected'); return this.error('Identifier expected');
} }
var token = this.tokens.nextToken(); var token = this.tokens.peekToken();
var isString = false; var isString = false;
var isInt = false;
if (token == '$') { if (token == '$') {
isString = true; isString = true;
token = this.tokens.nextToken(); this.tokens.consume();
} else if (token == '%') {
isInt = true;
this.tokens.consume();
} }
var arr = this.arrayIndex();
if (arr == undefined) {
return arr;
}
token = this.tokens.nextToken();
if (token != '=') { if (token != '=') {
return this.error('"=" expected'); return this.error('"=" expected');
} }
@ -359,12 +442,18 @@ Demo.prototype.doAssignment = function() {
if (value.type() != 0 /* TYPE_STRING */) { if (value.type() != 0 /* TYPE_STRING */) {
return this.error('String expected'); return this.error('String expected');
} }
this.vars['str_' + id] = value; this.vars['str_' + id + arr] = value;
} else { } else {
if (value.type() != 1 /* TYPE_NUMBER */) { if (value.type() != 1 /* TYPE_NUMBER */) {
return this.error('Numeric value expected'); return this.error('Numeric value expected');
} }
this.vars['var_' + id] = value; if (isInt) {
value = this.toInt(value.val());
value = new this.Value(1 /* TYPE_NUMBER */, '' + value, value);
this.vars['int_' + id + arr] = value;
} else {
this.vars['var_' + id + arr] = value;
}
} }
}; };
@ -601,11 +690,7 @@ Demo.prototype.term = function() {
} else { } else {
v = value.val() / v.val(); v = value.val() / v.val();
if (token == '\\') { if (token == '\\') {
if (v < 0) { v = this.toInt(v);
v = -Math.floor(-v);
} else {
v = Math.floor( v);
}
} }
} }
if (v == NaN) { if (v == NaN) {
@ -853,12 +938,25 @@ Demo.prototype.factor = function() {
} else if (token.match(/^[A-Za-z][A-Za-z0-9_]*$/)) { } else if (token.match(/^[A-Za-z][A-Za-z0-9_]*$/)) {
if (this.tokens.peekToken() == '$') { if (this.tokens.peekToken() == '$') {
this.tokens.consume(); this.tokens.consume();
value = this.vars['str_' + token]; var arr= this.arrayIndex();
if (arr == undefined) {
return arr;
}
value = this.vars['str_' + token + arr];
if (value == undefined) { if (value == undefined) {
value= new this.Value(0 /* TYPE_STRING */, '', ''); value= new this.Value(0 /* TYPE_STRING */, '', '');
} }
} else { } else {
value = this.vars['var_' + token]; var n = 'var_';
if (this.tokens.peekToken() == '%') {
this.tokens.consume();
n = 'int_';
}
var arr= this.arrayIndex();
if (arr == undefined) {
return arr;
}
value = this.vars[n + token + arr];
if (value == undefined) { if (value == undefined) {
value= new this.Value(1 /* TYPE_NUMBER */, '0', 0); value= new this.Value(1 /* TYPE_NUMBER */, '0', 0);
} }

View file

@ -74,12 +74,6 @@
#define TYPE_STRING 0 #define TYPE_STRING 0
#define TYPE_NUMBER 1 #define TYPE_NUMBER 1
#define TYPE_VAR 2
#define TYPE_STRVAR 3
#define TYPE_INTVAR 4
#define TYPE_ARR 5
#define TYPE_STRARR 6
#define TYPE_INTARR 7
function extend(subClass, baseClass) { function extend(subClass, baseClass) {
function inheritance() { } function inheritance() { }
@ -287,13 +281,16 @@ Demo.prototype.doCommand = function() {
Demo.prototype.doEval = function() { Demo.prototype.doEval = function() {
this.gotoState(STATE_PROMPT); this.gotoState(STATE_PROMPT);
var token = this.tokens.peekToken(); var token = this.tokens.peekToken();
if (token == "HELP") { if (token == "DIM") {
this.tokens.consume();
this.doDim();
} else if (token == "HELP") {
this.tokens.consume(); this.tokens.consume();
if (this.tokens.nextToken() != undefined) { if (this.tokens.nextToken() != undefined) {
this.error('HELP does not take any arguments'); this.error('HELP does not take any arguments');
} else { } else {
this.vt100('Supported commands:\r\n' + this.vt100('Supported commands:\r\n' +
'HELP LET LIST NEW PRINT RUN\r\n'+ 'DIM HELP LET LIST NEW PRINT RUN\r\n'+
'\r\n'+ '\r\n'+
'Supported functions:\r\n'+ 'Supported functions:\r\n'+
'ABS() ASC() ATN() CHR$() COS() EXP() INT() LEFT$() LEN()\r\n'+ 'ABS() ASC() ATN() CHR$() COS() EXP() INT() LEFT$() LEN()\r\n'+
@ -327,6 +324,7 @@ Demo.prototype.doEval = function() {
this.error('RUN does not take any parameters'); this.error('RUN does not take any parameters');
} else if (this.program.length > 0) { } else if (this.program.length > 0) {
this.currentLineIndex = 0; this.currentLineIndex = 0;
this.vars = new Object();
this.gotoState(STATE_EXEC); this.gotoState(STATE_EXEC);
} else { } else {
this.ok(); this.ok();
@ -337,17 +335,102 @@ Demo.prototype.doEval = function() {
return false; return false;
}; };
Demo.prototype.doDim = function() {
for (;;) {
var token = this.tokens.nextToken();
if (token == undefined) {
return;
}
if (!token || !token.match(/^[A-Za-z][A-Za-z0-9_]*$/)) {
return this.error('Identifier expected');
}
token = this.tokens.nextToken();
if (token == '$' || token == '%') {
token = this.tokens.nextToken();
}
if (token != '(') {
return this.error('"(" expected');
}
do {
var size = this.expr();
if (!size) {
return size;
}
if (size.type() != TYPE_NUMBER) {
return this.error('Numeric value expected');
}
if (Math.floor(size.val()) < 1) {
return this.error('Range error');
}
token = this.tokens.nextToken();
} while (token == ',');
if (token != ')') {
return this.error('")" expected');
}
if (this.tokens.peekToken() != ',') {
break;
}
this.tokens.consume();
}
if (this.tokens.peekToken() != undefined) {
return this.error();
}
};
Demo.prototype.arrayIndex = function() {
var token = this.tokens.peekToken();
var arr = '';
if (token == '(') {
this.tokens.consume();
do {
var idx = this.expr();
if (idx == undefined) {
return idx;
} else if (idx.type() != TYPE_NUMBER) {
return this.error('Numeric value expected');
}
idx = Math.floor(idx.val());
if (idx < 0) {
return this.error('Indices have to be positive');
}
arr += ',' + idx;
token = this.tokens.nextToken();
} while (token == ',');
if (token != ')') {
return this.error('")" expected');
}
}
return arr;
};
Demo.prototype.toInt = function(v) {
if (v < 0) {
return -Math.floor(-v);
} else {
return Math.floor( v);
}
};
Demo.prototype.doAssignment = function() { Demo.prototype.doAssignment = function() {
var id = this.tokens.nextToken(); var id = this.tokens.nextToken();
if (!id || !id.match(/^[A-Za-z][A-Za-z0-9_]*$/)) { if (!id || !id.match(/^[A-Za-z][A-Za-z0-9_]*$/)) {
return this.error('Identifier expected'); return this.error('Identifier expected');
} }
var token = this.tokens.nextToken(); var token = this.tokens.peekToken();
var isString = false; var isString = false;
var isInt = false;
if (token == '$') { if (token == '$') {
isString = true; isString = true;
token = this.tokens.nextToken(); this.tokens.consume();
} else if (token == '%') {
isInt = true;
this.tokens.consume();
} }
var arr = this.arrayIndex();
if (arr == undefined) {
return arr;
}
token = this.tokens.nextToken();
if (token != '=') { if (token != '=') {
return this.error('"=" expected'); return this.error('"=" expected');
} }
@ -359,12 +442,18 @@ Demo.prototype.doAssignment = function() {
if (value.type() != TYPE_STRING) { if (value.type() != TYPE_STRING) {
return this.error('String expected'); return this.error('String expected');
} }
this.vars['str_' + id] = value; this.vars['str_' + id + arr] = value;
} else { } else {
if (value.type() != TYPE_NUMBER) { if (value.type() != TYPE_NUMBER) {
return this.error('Numeric value expected'); return this.error('Numeric value expected');
} }
this.vars['var_' + id] = value; if (isInt) {
value = this.toInt(value.val());
value = new this.Value(TYPE_NUMBER, '' + value, value);
this.vars['int_' + id + arr] = value;
} else {
this.vars['var_' + id + arr] = value;
}
} }
}; };
@ -601,11 +690,7 @@ Demo.prototype.term = function() {
} else { } else {
v = value.val() / v.val(); v = value.val() / v.val();
if (token == '\\') { if (token == '\\') {
if (v < 0) { v = this.toInt(v);
v = -Math.floor(-v);
} else {
v = Math.floor( v);
}
} }
} }
if (v == NaN) { if (v == NaN) {
@ -853,12 +938,25 @@ Demo.prototype.factor = function() {
} else if (token.match(/^[A-Za-z][A-Za-z0-9_]*$/)) { } else if (token.match(/^[A-Za-z][A-Za-z0-9_]*$/)) {
if (this.tokens.peekToken() == '$') { if (this.tokens.peekToken() == '$') {
this.tokens.consume(); this.tokens.consume();
value = this.vars['str_' + token]; var arr= this.arrayIndex();
if (arr == undefined) {
return arr;
}
value = this.vars['str_' + token + arr];
if (value == undefined) { if (value == undefined) {
value= new this.Value(TYPE_STRING, '', ''); value= new this.Value(TYPE_STRING, '', '');
} }
} else { } else {
value = this.vars['var_' + token]; var n = 'var_';
if (this.tokens.peekToken() == '%') {
this.tokens.consume();
n = 'int_';
}
var arr= this.arrayIndex();
if (arr == undefined) {
return arr;
}
value = this.vars[n + token + arr];
if (value == undefined) { if (value == undefined) {
value= new this.Value(TYPE_NUMBER, '0', 0); value= new this.Value(TYPE_NUMBER, '0', 0);
} }