mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-06-14 08:24:04 +09:00
executing print hello world
This commit is contained in:
@@ -43,7 +43,7 @@ var reLineNum = /^[0-9]+ /;
|
|||||||
|
|
||||||
// must match partial
|
// must match partial
|
||||||
var reNumber = /([0-9]*[.][0-9]+[eE]*[\-+0-9]*[fF]*|[0-9]+[.eEfF][0-9+\-]*[fF]?)|([0-9_]+)|(0[Xx][0-9A-Fa-f_]+)|(0[Bb][01_]+)/;
|
var reNumber = /([0-9]*[.][0-9]+[eE]*[\-+0-9]*[fF]*|[0-9]+[.eEfF][0-9+\-]*[fF]?)|([0-9_]+)|(0[Xx][0-9A-Fa-f_]+)|(0[Bb][01_]+)/;
|
||||||
var reOps = /\^|\*|\/|\+|\-|[<>=]{1,2}/;
|
var reOps = /\^|;|\*|\/|\+|\-|[<>=]{1,2}/;
|
||||||
|
|
||||||
var reNum = /[0-9]+/;
|
var reNum = /[0-9]+/;
|
||||||
var tbasexit = false;
|
var tbasexit = false;
|
||||||
@@ -51,7 +51,6 @@ var tbasexit = false;
|
|||||||
println("Terran BASIC 1.0 "+vmemsize+" bytes free");
|
println("Terran BASIC 1.0 "+vmemsize+" bytes free");
|
||||||
println(prompt);
|
println(prompt);
|
||||||
|
|
||||||
var basicInterpreterStatus = {};
|
|
||||||
// variable object constructor
|
// variable object constructor
|
||||||
function BasicVar(linenum, literal, type) {
|
function BasicVar(linenum, literal, type) {
|
||||||
this.literal = literal;
|
this.literal = literal;
|
||||||
@@ -92,7 +91,7 @@ function BasicAST() {
|
|||||||
this.depth = 0;
|
this.depth = 0;
|
||||||
this.leaves = [];
|
this.leaves = [];
|
||||||
this.value = undefined;
|
this.value = undefined;
|
||||||
this.type = "null"; // literal, operator, variable, function, null
|
this.type = "null"; // literal, operator, string, number, function, null
|
||||||
|
|
||||||
this.toString = function() {
|
this.toString = function() {
|
||||||
var sb = "";
|
var sb = "";
|
||||||
@@ -107,12 +106,12 @@ function BasicAST() {
|
|||||||
return sb;
|
return sb;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
var basicInterpreterStatus = {};
|
||||||
basicInterpreterStatus.gosubStack = [];
|
basicInterpreterStatus.gosubStack = [];
|
||||||
basicInterpreterStatus.variables = {};
|
basicInterpreterStatus.variables = {};
|
||||||
basicInterpreterStatus.defuns = {};
|
basicInterpreterStatus.defuns = {};
|
||||||
basicInterpreterStatus.builtin = {};
|
basicInterpreterStatus.builtin = {};
|
||||||
basicInterpreterStatus.builtin.print = function() {
|
basicInterpreterStatus.builtin.PRINT = function(args) {
|
||||||
var args = Array.from(arguments);
|
|
||||||
if (args.length == 0)
|
if (args.length == 0)
|
||||||
println();
|
println();
|
||||||
else
|
else
|
||||||
@@ -149,10 +148,11 @@ basicFunctions._isSeparator = function(code) {
|
|||||||
};
|
};
|
||||||
basicFunctions._operatorPrecedence = {
|
basicFunctions._operatorPrecedence = {
|
||||||
// function call in itself has highest precedence
|
// function call in itself has highest precedence
|
||||||
"^":2,
|
"^":1,
|
||||||
"*":3,"/":3,
|
"*":2,"/":2,
|
||||||
"MOD":4,
|
"MOD":3,
|
||||||
"+":5,"-":5,
|
"+":4,"-":4,
|
||||||
|
";":5,
|
||||||
"<<":6,">>":6,
|
"<<":6,">>":6,
|
||||||
"==":7,"<>":7,"><":7,"<":7,">":7,"<=":7,"=<":7,">=":7,"=>":7,
|
"==":7,"<>":7,"><":7,"<":7,">":7,"<=":7,"=<":7,">=":7,"=>":7,
|
||||||
"BAND":8,
|
"BAND":8,
|
||||||
@@ -163,7 +163,7 @@ basicFunctions._operatorPrecedence = {
|
|||||||
"=":13
|
"=":13
|
||||||
};
|
};
|
||||||
basicFunctions._isUnaryOp = function(word) {
|
basicFunctions._isUnaryOp = function(word) {
|
||||||
return 13 == basicFunctions._operatorPrecedence[word];
|
return 5 == basicFunctions._operatorPrecedence[word];
|
||||||
};
|
};
|
||||||
basicFunctions._isOperatorWord = function(word) {
|
basicFunctions._isOperatorWord = function(word) {
|
||||||
return (basicFunctions._operatorPrecedence[word] !== undefined) // force the return type to be a boolean
|
return (basicFunctions._operatorPrecedence[word] !== undefined) // force the return type to be a boolean
|
||||||
@@ -530,7 +530,7 @@ basicFunctions._tokenise = function(lnum, cmd) {
|
|||||||
return { "tokens": tokens, "states": states };
|
return { "tokens": tokens, "states": states };
|
||||||
};
|
};
|
||||||
basicFunctions._parserElaboration = function(lnum, tokens, states) {
|
basicFunctions._parserElaboration = function(lnum, tokens, states) {
|
||||||
var _debugprintElaboration = true;
|
var _debugprintElaboration = false;
|
||||||
if (_debugprintElaboration) println("@@ ELABORATION @@");
|
if (_debugprintElaboration) println("@@ ELABORATION @@");
|
||||||
var k = 0;
|
var k = 0;
|
||||||
|
|
||||||
@@ -618,7 +618,7 @@ for input "DEFUN sinc(x) = sin(x) / x"
|
|||||||
"quote" == state || "number" == state || "bool" == state || "literal" == state;
|
"quote" == state || "number" == state || "bool" == state || "literal" == state;
|
||||||
}
|
}
|
||||||
|
|
||||||
var _debugSyntaxAnalysis = true;
|
var _debugSyntaxAnalysis = false;
|
||||||
|
|
||||||
if (_debugSyntaxAnalysis) println("@@ SYNTAX ANALYSIS @@");
|
if (_debugSyntaxAnalysis) println("@@ SYNTAX ANALYSIS @@");
|
||||||
|
|
||||||
@@ -647,7 +647,7 @@ for input "DEFUN sinc(x) = sin(x) / x"
|
|||||||
if (tokens.length == 1 && (isSemanticLiteral(tokens[0], states[0]))) {
|
if (tokens.length == 1 && (isSemanticLiteral(tokens[0], states[0]))) {
|
||||||
if (_debugSyntaxAnalysis) println("literal/number: "+tokens[0]);
|
if (_debugSyntaxAnalysis) println("literal/number: "+tokens[0]);
|
||||||
treeHead.value = ("quote" == states[0]) ? tokens[0] : tokens[0].toUpperCase();
|
treeHead.value = ("quote" == states[0]) ? tokens[0] : tokens[0].toUpperCase();
|
||||||
treeHead.type = "literal";
|
treeHead.type = ("quote" == states[0]) ? "string" : ("number" == states[0]) ? "number" : "literal";
|
||||||
}
|
}
|
||||||
else if (tokens[0].toUpperCase() == "IF" && states[0] != "quote") {
|
else if (tokens[0].toUpperCase() == "IF" && states[0] != "quote") {
|
||||||
// find ELSE and THEN
|
// find ELSE and THEN
|
||||||
@@ -873,8 +873,35 @@ for input "DEFUN sinc(x) = sin(x) / x"
|
|||||||
|
|
||||||
};
|
};
|
||||||
// @returns: line number for the next command, normally (lnum + 1); if GOTO or GOSUB was met, returns its line number
|
// @returns: line number for the next command, normally (lnum + 1); if GOTO or GOSUB was met, returns its line number
|
||||||
|
basicFunctions._executeSyntaxTree = function(lnum, syntaxTree) {
|
||||||
|
var _debugExec = true;
|
||||||
|
|
||||||
|
if (_debugExec) serial.println("@@ EXECUTE @@");
|
||||||
|
if (_debugExec) serial.println(syntaxTree.toString());
|
||||||
|
|
||||||
|
if (syntaxTree.type == "function") {
|
||||||
|
var func = basicInterpreterStatus.builtin[syntaxTree.value.toUpperCase()];
|
||||||
|
var args = syntaxTree.leaves.map(function(it) { return basicFunctions._executeSyntaxTree(lnum, it); });
|
||||||
|
if (_debugExec) serial.println("fn call args: "+args.join(" "));
|
||||||
|
func(args);
|
||||||
|
}
|
||||||
|
else if (syntaxTree.type == "number") {
|
||||||
|
return +(syntaxTree.value);
|
||||||
|
}
|
||||||
|
else if (syntaxTree.type == "string") {
|
||||||
|
return syntaxTree.value;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
serial.println("Parse error at line "+lnum);
|
||||||
|
serial.println(syntaxTree.toString);
|
||||||
|
throw "Parse error";
|
||||||
|
}
|
||||||
|
|
||||||
|
return lnum + 1;
|
||||||
|
};
|
||||||
|
// @returns: line number for the next command, normally (lnum + 1); if GOTO or GOSUB was met, returns its line number
|
||||||
basicFunctions._interpretLine = function(lnum, cmd) {
|
basicFunctions._interpretLine = function(lnum, cmd) {
|
||||||
var _debugprintHighestLevel = true;
|
var _debugprintHighestLevel = false;
|
||||||
|
|
||||||
// TOKENISE
|
// TOKENISE
|
||||||
var tokenisedObject = basicFunctions._tokenise(lnum, cmd);
|
var tokenisedObject = basicFunctions._tokenise(lnum, cmd);
|
||||||
@@ -896,12 +923,13 @@ basicFunctions._interpretLine = function(lnum, cmd) {
|
|||||||
// PARSING (SYNTAX ANALYSIS)
|
// PARSING (SYNTAX ANALYSIS)
|
||||||
var syntaxTree = basicFunctions._parseTokens(lnum, tokens, states, 0);
|
var syntaxTree = basicFunctions._parseTokens(lnum, tokens, states, 0);
|
||||||
|
|
||||||
|
var nextLine = basicFunctions._executeSyntaxTree(lnum, syntaxTree);
|
||||||
|
|
||||||
serial.println(syntaxTree.toString());
|
serial.println(syntaxTree.toString());
|
||||||
|
|
||||||
|
|
||||||
// EXECUTO
|
// EXECUTE
|
||||||
return lnum + 1;
|
return nextLine;
|
||||||
|
|
||||||
|
|
||||||
}; // end INTERPRETLINE
|
}; // end INTERPRETLINE
|
||||||
|
|||||||
Reference in New Issue
Block a user