/cmm

Cmm is a C++ interpreter that can be embedded in the browser.

Primary LanguageCoffeeScript

Build Status

C--

C-- is a C++ interpreter that can be embedded in the browser.

The project is in early stages, so things may go wrong.

Supported language features

  • Primitive types: int, double, char, bool
  • Compound types: Arrays (static size), pointers
  • Strings (partially, they are immutable, individual characters cannot be accessed and they cannot be passed as function arguments)
  • Variable declaration and assignment
  • Arithmetic operators: binary +,-,\*,/,%, unary +,-
  • Logic operators: binary &&,||, unary ! together with their aliases and,or,not
  • Comparison operators: ==, !=, >, >=, <, <=
  • Dereferencing (unary * operator), addressing (unary & operator) and subscripting ([] operator)
  • while and for loops
  • if, if-else statements
  • Functions (including void functions, and return statement)
  • Global variables
  • Const specifier
  • new and delete operators
  • cin and cout (partially, they are simulated as language constructs instead of using objects and operator overloading as in C++)

Other features

  • Step-by-step execution, the program can be paused and resumed as desired
  • Debugger API

How it works

  1. The program is parsed using a parser produced with the jison parser generator, which generates an AST.
  2. The AST is semantically analysed.
  3. Each variable is mapped into a memory address. Memory is simulated using Javascript Typed Arrays, with heap and stack memory 'compartments'.
  4. A list of instructions is produced for each function.
  5. The list of instructions is interpreted one by one starting from the main function.

Command Line Interface

Installation

npm, node, coffeescript and gulp are required to run cmm.

Once these are installed, run:

npm install
gulp generate-parser
chmod +x cmm

and you're all set.

Usage

cmm [program-path] [input-path]

  1. Compiles the program specified in program-path (or a hello world program in its defect), printing its AST and list of instructions. Gives compilation errors in case they occur.

  2. If compilation is successful, runs the program with the input specified in input-path (or empty input otherwise) and prints the stdout and interleaved(stdout + stderr) outputs from the execution.

Embedding in the browser

gulp is required to build the project into a single .js file.

Run npm install followed by gulp. The resulting index.min.js and index.js files are written inside the build directory.

Now you can include this index.js file in the browser and access the C-- interface by using the cmm object exported.

Using as an npm package

Run

gulp generate-parser
coffee -cb .

Now you can require() the index.js file in the root of the project:

var cmm = require('path-to-index.js');

Example usage

var compiled = cmm.compile("int main() { int n; cin >> n; cout << n; }");

var ast = compiled.ast; // Can be printed with console.log(ast.toString())
var program = compiled.program; // Instructions can be printed with program.writeInstructions()

var execResult = cmm.runSync(program, "2");

var stdout = execResult.stdout; // "2"
var stderr = execResult.stderr; // "" (Non empty in case of execution errors such as stack overflow or division by zero)
var output = execResult.output; // "2" (Combination of stdout and stderr)
var status = execResult.status; // Value returned by main, in this case 0

// Step by step execution
var iterator = cmm.run(program, "2");

vm = iterator.next().value; // vm holds the execution status right before the first instruction execution

while (!vm.finished) {
    vm = iterator.next().value; // vm holds the execution status right after the 1st, 2nd, ... instruction execution
}

// vm at this point is exactly equal to execResult in the synchronous example