felixhao28 / JSCPP
- вторник, 28 августа 2018 г. в 00:16:24
CoffeeScript
A simple C++ interpreter written in JavaScript
This is a simple C++ interpreter written in JavaScript.
Try it out on github.io!
As far as I know, every public online C++ excuting environment requires backend servers to compile and run the produced executable. A portable and lightweight interpreter that can be run in browsers can be a fine substitute for those who do not intend to pay for such services.
I also want to make a strict interpreter. The reason being C++ has too many undefined and platform-dependent behaviors and popular C++ compilers tend to be an "over-caring mother" who tries to ignore or even justify the undocumented usages. The abuse of them should be avoided as much as possible IMO. For example, I do not want my students to take it as guaranteed that sizeof int produces 4, because on Arduino Uno, an int is a 2-byte value.
Currently, it is mainly for educational uses for a MOOC course I am running (and fun).
Installation
npm install JSCPP
or (to use lastest cutting-edge version or to contribute)
git clone https://github.com/felixhao28/JSCPP.git
cd JSCPP
npm install .
var JSCPP = require("JSCPP");
var code = "#include <iostream>"
+ "using namespace std;"
+ "int main() {"
+ " int a;"
+ " cin >> a;"
+ " cout << a << endl;"
+ " return 0;"
+ "}"
;
var input = "4321";
var exitcode = JSCPP.run(code, input);
console.info("program exited with code " + exitcode);See demo/example.coffee for example.
Use debugger
As of 2.0.0, there is a simple but functional real debugger available.
A list of debugger API:
var JSCPP = require("JSCPP")
var mydebugger = JSCPP.run(code, input);
// continue to the next interpreting operation
var done = mydebugger.next();
// if you have an active breakpoint condition, you can just continue
var done = mydebugger.continue();
// by default, debugger pauses at every new line, but you can change it
mydebugger.stopConditions = {
isStatement: true
positionChanged: true
lineChanged: false
};
// so that debugger only stops at a statement of a new position
// or you can add your own condition, i.e. stops at line 10
mydebugger.conditions["line10"] = function (prevNode, nextNode) {
if (nextNode.sLine=== 10) {
// disable itself so that it only triggers once on line 10
mydebugger.stopConditions["line10"] = false
return true;
} else {
return false;
}
};
// then enable it
mydebugger.stopConditions["line10"] = true
// we need to explicitly use "false" because exit code can be 0
if (done !== false) {
console.log("program exited with code " + done);
}
// the AST node to be executed next
var s = mydebugger.nextNode();
// sometimes a breakpoint can be set without a statement to be executed next,
// i.e. entering a function call.
while ((s = mydebugger.nextNode()) == null) {
mydebugger.next();
}
// the content of the statement to be executed next
var nextLine = mydebugger.nextLine();
// it is essentially same as
nextLine = mydebugger.src.slice(s.sOffset, s.eOffset).trim()
console.log("from " + s.sLine + ":" + s.sColumn + "(" + s.sOffset + ")");
console.log("to " + s.eLine + ":" + s.eColumn + "(" + s.eOffset + ")");
console.log("==> " + nextLine);
// examine the internal registry for a type
mydebugger.type("int");
// examine the value of variable "a"
mydebugger.variable("a");
// or list all local variables
mydebugger.variable();A full interactive example is available in demo/debug.coffee. Use node -harmony demo/debug A+B -debug to debug "A+B" test.
There should be a newest version of JSCPP.js in dist ready for you. If not, use grunt build to generate one.
Then you can add it to your html. The exported global name for this package is "JSCPP".
<script src="JSCPP.es5.min.js"></script>
<script type="text/javascript">
var code = "#include <iostream>"+
"using namespace std;"+
"int main() {"+
" int a;"+
" cin >> a;"+
" cout << a << endl;"+
" return 0;"+
"}"
;
var input = "4321";
var output = "";
var config = {
stdio: {
write: function(s) {
output += s;
}
}
};
var exitCode = JSCPP.run(code, input, config);
alert(output + "\nprogram exited with code " + exitCode);
</script>If you do not provide a customized write method for stdio configuration, console output will not be correctly shown. See demo/demo.html for example.
npm test
If you want to run C++ programs effciently, compile your C++ code to LLVM-bitcode and then use Emscripten.
See current progress in includes folder.
Post it on Issues.
test.jsonJSCPP.run is all you needtest/test.coffee directlyint getchar(void)char *gets(char *str)int putchar(int char)int puts(const char *str)int scanf(const char *format, ...)int sscanf(const char *str, const char *format, ...)test\class_basics.cpp).