Completed arithmetic support, added initial incomplete code for intrinsic functions.

git-svn-id: https://shellinabox.googlecode.com/svn/trunk@108 0da03de8-d603-11dd-86c2-0f8696b7b6f9
This commit is contained in:
zodiac 2009-04-02 17:48:33 +00:00
parent c1e181ec98
commit 82a68e1797
2 changed files with 132 additions and 44 deletions

View file

@ -514,14 +514,14 @@ Demo.prototype.expr = function() {
};
Demo.prototype.term = function() {
var value = this.factor();
var value = this.expn();
while (value) {
var token = this.tokens.peekToken();
if (token != '*' && token != '/' && token != '\\') {
break;
}
this.tokens.consume();
var v = this.factor();
var v = this.expn();
if (!v) {
return v;
}
@ -548,6 +548,37 @@ Demo.prototype.term = function() {
return value;
};
Demo.prototype.expn = function() {
var value = this.intrinsic();
var token = this.tokens.peekToken();
if (token == '^') {
this.tokens.consume();
var exp = this.intrinsic();
if (exp == undefined || exp.val() == NaN) {
return exp;
}
if (value.type() != 1 /* TYPE_NUMBER */ || exp.type() != 1 /* TYPE_NUMBER */) {
return this.error("Numeric value expected");
}
var v = Math.pow(value.val(), exp.val());
value = new this.Value(1 /* TYPE_NUMBER */, '' + v, v);
}
return value;
};
Demo.prototype.intrinsic = function() {
var token = this.tokens.peekToken();
if (token.match(/^(?:ABS|ASC|ATN|CHR\$|COS|EXP|INT|LEN|LOG|POS|RND|SGN|SIN|SPC|SQR|STR\$|TAN|VAL)$/)) {
return this.error('Unimplemented');
} else if (token.match(/^(?:LEFT\$|RIGHT\$)$/)) {
return this.error('Unimplemented');
} else if (token == 'MID$') {
return this.error('Unimplemented');
} else {
return this.factor();
}
};
Demo.prototype.factor = function() {
var token = this.tokens.nextToken();
if (!token) {
@ -555,6 +586,13 @@ Demo.prototype.factor = function() {
}
var value = undefined;
if (token == '(') {
value = this.expr();
token = this.tokens.nextToken();
if (token != ')' && value != undefined) {
return this.error('")" expected');
}
} else {
var str;
if ((str = token.match(/^"(.*)"/)) != null) {
value = new this.Value(0 /* TYPE_STRING */, str[1], str[1]);
@ -572,6 +610,7 @@ Demo.prototype.factor = function() {
} else {
return this.error();
}
}
return value;
};
@ -641,12 +680,17 @@ Demo.prototype.Tokens.prototype.peekToken = function() {
}
} else if (token >= 'A' && token <= 'Z' ||
token >= 'a' && token <= 'z') {
token = tokens.match(/^(?:CHR\$|STR\$|LEFT\$|RIGHT\$|MID\$)/i);
if (token) {
token = token[0].toUpperCase();
} else {
token = tokens.match(/^[A-Za-z][A-Za-z0-9_]*/);
if (!token) {
token = undefined;
} else {
token = token[0].toUpperCase();
}
}
} else {
token = '';
}

View file

@ -514,14 +514,14 @@ Demo.prototype.expr = function() {
};
Demo.prototype.term = function() {
var value = this.factor();
var value = this.expn();
while (value) {
var token = this.tokens.peekToken();
if (token != '*' && token != '/' && token != '\\') {
break;
}
this.tokens.consume();
var v = this.factor();
var v = this.expn();
if (!v) {
return v;
}
@ -548,6 +548,37 @@ Demo.prototype.term = function() {
return value;
};
Demo.prototype.expn = function() {
var value = this.intrinsic();
var token = this.tokens.peekToken();
if (token == '^') {
this.tokens.consume();
var exp = this.intrinsic();
if (exp == undefined || exp.val() == NaN) {
return exp;
}
if (value.type() != TYPE_NUMBER || exp.type() != TYPE_NUMBER) {
return this.error("Numeric value expected");
}
var v = Math.pow(value.val(), exp.val());
value = new this.Value(TYPE_NUMBER, '' + v, v);
}
return value;
};
Demo.prototype.intrinsic = function() {
var token = this.tokens.peekToken();
if (token.match(/^(?:ABS|ASC|ATN|CHR\$|COS|EXP|INT|LEN|LOG|POS|RND|SGN|SIN|SPC|SQR|STR\$|TAN|VAL)$/)) {
return this.error('Unimplemented');
} else if (token.match(/^(?:LEFT\$|RIGHT\$)$/)) {
return this.error('Unimplemented');
} else if (token == 'MID$') {
return this.error('Unimplemented');
} else {
return this.factor();
}
};
Demo.prototype.factor = function() {
var token = this.tokens.nextToken();
if (!token) {
@ -555,6 +586,13 @@ Demo.prototype.factor = function() {
}
var value = undefined;
if (token == '(') {
value = this.expr();
token = this.tokens.nextToken();
if (token != ')' && value != undefined) {
return this.error('")" expected');
}
} else {
var str;
if ((str = token.match(/^"(.*)"/)) != null) {
value = new this.Value(TYPE_STRING, str[1], str[1]);
@ -572,6 +610,7 @@ Demo.prototype.factor = function() {
} else {
return this.error();
}
}
return value;
};
@ -641,12 +680,17 @@ Demo.prototype.Tokens.prototype.peekToken = function() {
}
} else if (token >= 'A' && token <= 'Z' ||
token >= 'a' && token <= 'z') {
token = tokens.match(/^(?:CHR\$|STR\$|LEFT\$|RIGHT\$|MID\$)/i);
if (token) {
token = token[0].toUpperCase();
} else {
token = tokens.match(/^[A-Za-z][A-Za-z0-9_]*/);
if (!token) {
token = undefined;
} else {
token = token[0].toUpperCase();
}
}
} else {
token = '';
}