Skip to content

Commit f1f11a8

Browse files
committed
feat(js): Add TokenKind and Token.getKind()
1 parent 146b166 commit f1f11a8

File tree

8 files changed

+319
-57
lines changed

8 files changed

+319
-57
lines changed

README.md

Lines changed: 29 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
1-
# A compiler front end for the C++ language"
1+
# A compiler front end for the C++ language
22

33
This repository contains a _work in progress_ compiler front end for C++ 20.
44

5+
## Install
6+
7+
For the latest stable version:
8+
9+
```
10+
npm install -g cxx-frontend
11+
```
12+
513
## Build
614

715
On Linux, macOS and Windows:
@@ -46,45 +54,25 @@ npm pack
4654

4755
```js
4856
//
49-
// fact.mjs
57+
// example.mjs
5058
//
5159

52-
import { Parser, RecursiveASTVisitor, ASTKind } from "cxx-frontend";
60+
import { Parser, AST, ASTKind } from "cxx-frontend";
5361
import { readFile } from "fs/promises";
5462
import { fileURLToPath } from "url";
5563

56-
class DumpAST extends RecursiveASTVisitor {
57-
#stack = [];
58-
59-
accept(node) {
60-
if (!node) return;
61-
62-
const nodeKind = ASTKind[node.getKind()];
63-
64-
const entry = [nodeKind];
65-
66-
const parentNode = this.#stack.slice(-1)[0];
67-
68-
parentNode?.push(entry);
69-
70-
this.#stack.push(entry);
71-
72-
super.accept(node);
73-
74-
this.#stack.pop();
75-
76-
return entry;
77-
}
78-
}
79-
8064
const source = `
81-
int fact(int n) {
82-
if (n < 2) return 1;
83-
return n * fact(n - 1);
65+
template <typename T>
66+
concept CanAdd = requires(T n) {
67+
n + n;
68+
};
69+
70+
auto twice(CanAdd auto n) {
71+
return n + n;
8472
}
8573
8674
int main() {
87-
return fact(3);
75+
return twice(2);
8876
}
8977
`;
9078

@@ -96,7 +84,7 @@ async function main() {
9684
// initialize the parser
9785
await Parser.init({ wasmBinary });
9886

99-
const parser = new Parser({ source, path: "fact.cc" });
87+
const parser = new Parser({ source, path: "source.cc" });
10088

10189
parser.parse();
10290

@@ -108,11 +96,17 @@ async function main() {
10896

10997
const ast = parser.getAST();
11098

111-
const tree = new DumpAST().accept(ast);
99+
if (ast) {
100+
ast.walk().preVisit((node, depth) => {
101+
if (node instanceof AST) {
102+
const ind = " ".repeat(depth * 2);
103+
const kind = ASTKind[node.getKind()];
104+
console.log(`${ind}${kind}`);
105+
}
106+
});
107+
}
112108

113109
parser.dispose();
114-
115-
console.log(tree);
116110
}
117111

118112
main().catch(console.error);

packages/cxx-frontend/src/AST.ts

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -24,27 +24,7 @@ import { ASTCursor } from "./ASTCursor.js";
2424
import { ASTVisitor } from "./ASTVisitor.js";
2525
import { ASTKind } from "./ASTKind.js";
2626
import { Parser } from "./Parser.js";
27-
28-
export class Token {
29-
constructor(private readonly handle: number, private readonly parser: Parser) {
30-
}
31-
32-
getHandle() {
33-
return this.handle;
34-
}
35-
36-
getText(): string {
37-
return cxx.getTokenText(this.handle, this.parser.getUnitHandle());
38-
}
39-
40-
getLocation(): SourceLocation {
41-
return cxx.getTokenLocation(this.handle, this.parser.getUnitHandle());
42-
}
43-
44-
static from(handle: number, parser: Parser): Token | undefined {
45-
return handle ? new Token(handle, parser) : undefined;
46-
}
47-
}
27+
import { Token } from "./Token.js";
4828

4929
export abstract class AST {
5030
constructor(private readonly handle: number,

packages/cxx-frontend/src/ASTCursor.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1919
// SOFTWARE.
2020

21-
import { AST, Token } from "./AST.js";
21+
import { AST } from "./AST.js";
22+
import { Token } from "./Token";
2223
import { ASTSlotKind, cxx } from "./cxx.js";
2324
import { Parser } from "./Parser.js";
2425

packages/cxx-frontend/src/Token.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Copyright (c) 2021 Roberto Raggi <[email protected]>
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a copy
4+
// of this software and associated documentation files (the "Software"), to deal
5+
// in the Software without restriction, including without limitation the rights
6+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
// copies of the Software, and to permit persons to whom the Software is
8+
// furnished to do so, subject to the following conditions:
9+
//
10+
// The above copyright notice and this permission notice shall be included in
11+
// all copies or substantial portions of the Software.
12+
//
13+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
// SOFTWARE.
20+
21+
import { cxx } from "./cxx.js";
22+
import { SourceLocation } from "./SourceLocation.js";
23+
import { Parser } from "./Parser.js";
24+
import { TokenKind } from "./TokenKind.js";
25+
26+
export class Token {
27+
constructor(private readonly handle: number, private readonly parser: Parser) {
28+
}
29+
30+
getHandle() {
31+
return this.handle;
32+
}
33+
34+
getKind(): TokenKind {
35+
return cxx.getTokenKind(this.handle, this.parser.getUnitHandle());
36+
}
37+
38+
is(kind: TokenKind) {
39+
return this.getKind() === kind;
40+
}
41+
42+
isNot(kind: TokenKind) {
43+
return this.getKind() !== kind;
44+
}
45+
46+
getText(): string {
47+
return cxx.getTokenText(this.handle, this.parser.getUnitHandle());
48+
}
49+
50+
getLocation(): SourceLocation {
51+
return cxx.getTokenLocation(this.handle, this.parser.getUnitHandle());
52+
}
53+
54+
static from(handle: number, parser: Parser): Token | undefined {
55+
return handle ? new Token(handle, parser) : undefined;
56+
}
57+
}

0 commit comments

Comments
 (0)