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.json
JSCPP.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
).