cxx-frontend

A compiler front end for the C++ language

Usage no npm install needed!

<script type="module">
  import cxxFrontend from 'https://cdn.skypack.dev/cxx-frontend';
</script>

README

A compiler front end for the C++ language

This repository contains a work in progress compiler front end for C++ 20.

Install

For the latest stable version of the JavaScript bindings:

npm install cxx-frontend

JS Fiddle Playgrounds

Build

On Linux, macOS and Windows:

# configure cxx-frontend
cmake . \
 -G Ninja \
 -B build \
 -DCMAKE_BUILD_TYPE=Release \
 -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=1

# build cxx-frontend
cmake --build build

Dump the AST

Use -ast-dump to dump the AST of a C++ program.

echo 'int main() { auto f = []{ return 1; }; return f(); }' |
  ./build/cxx-frontend  -ast-dump -

Build the npm package using docker

cd packages/cxx-frontend

# prepare the package
npm ci

# compile WASM and TypeScript code
npm run build

# build the package
npm pack

Use the JavaScript API with Node.JS

//
// example.mjs
//

import { Parser, AST, ASTKind } from "cxx-frontend";
import { readFile } from "fs/promises";
import { fileURLToPath } from "url";

const source = `
template <typename T>
concept CanAdd = requires(T n) {
  n + n;
};

auto twice(CanAdd auto n) {
  return n + n;
}

int main() {
  return twice(2);
}
`;

async function main() {
  const wasmBinaryFile = fileURLToPath(Parser.DEFAULT_WASM_BINARY_URL);

  const wasmBinary = await readFile(wasmBinaryFile);

  // initialize the parser
  await Parser.init({ wasmBinary });

  const parser = new Parser({ source, path: "source.cc" });

  parser.parse();

  const diagnostics = parser.getDiagnostics();

  if (diagnostics.length > 0) {
    console.log("diagnostics", diagnostics);
  }

  const ast = parser.getAST();

  if (ast) {
    ast.walk().preVisit((node, depth) => {
      if (node instanceof AST) {
        const ind = " ".repeat(depth * 2);
        const kind = ASTKind[node.getKind()];
        console.log(`${ind}${kind}`);
      }
    });
  }

  parser.dispose();
}

main().catch(console.error);

Use the JavaScript API in a web browser

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>C++ Playground</title>
  </head>
  <body>
    <script type="module">
      import {
        Parser,
        AST,
        ASTKind,
      } from "https://unpkg.com/cxx-frontend@latest/dist/index.js";

      const response = await fetch(Parser.DEFAULT_WASM_BINARY_URL);

      const wasmBinary = new Uint8Array(await response.arrayBuffer());

      await Parser.init({ wasmBinary });

      const source = `int main()\n{\n  return 0;\n}\n`;

      const parser = new Parser({
        path: "source.cc",
        source,
      });

      parser.parse();

      const rows = [];

      const ast = parser.getAST();

      ast?.walk().preVisit((node, depth) => {
        if (node instanceof AST)
          rows.push("  ".repeat(depth) + ASTKind[node.getKind()]);
      });

      parser.dispose();

      const sourceOutput = document.createElement("pre");
      sourceOutput.style.borderStyle = "solid";
      sourceOutput.innerText = source;
      document.body.appendChild(sourceOutput);

      const astOutput = document.createElement("pre");
      astOutput.style.borderStyle = "solid";
      astOutput.innerText = rows.join("\n");
      document.body.appendChild(astOutput);
    </script>
  </body>
</html>

Release Notes

Changelog

License

Copyright (c) 2021 Roberto Raggi roberto.raggi@gmail.com

Licensed under the MIT license.