Update AST to support multiple original nodes
This commit is contained in:
parent
365de4e3f7
commit
aae14a275c
1 changed files with 273 additions and 57 deletions
330
src/ast.ts
330
src/ast.ts
|
@ -1,7 +1,5 @@
|
||||||
|
|
||||||
import "reflect-metadata"
|
import { Stream, StreamWrapper } from "./util"
|
||||||
|
|
||||||
import { Stream } from "./util"
|
|
||||||
|
|
||||||
interface JsonArray extends Array<Json> { };
|
interface JsonArray extends Array<Json> { };
|
||||||
interface JsonObject { [key: string]: Json }
|
interface JsonObject { [key: string]: Json }
|
||||||
|
@ -9,6 +7,18 @@ type Json = null | string | boolean | number | JsonArray | JsonObject;
|
||||||
|
|
||||||
export type TokenStream = Stream<Token>;
|
export type TokenStream = Stream<Token>;
|
||||||
|
|
||||||
|
function jsonify(value: any): Json {
|
||||||
|
if (value === null || typeof value === 'string' || typeof value === 'number') {
|
||||||
|
return value;
|
||||||
|
} else if (Array.isArray(value)) {
|
||||||
|
return value.map(element => jsonify(element));
|
||||||
|
} else if (typeof value === 'object' && 'toJSON' in value) {
|
||||||
|
return value.toJSON();
|
||||||
|
} else {
|
||||||
|
throw new Error(`I don't know how to convert ${value} to a JSON representation`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export enum SyntaxKind {
|
export enum SyntaxKind {
|
||||||
|
|
||||||
// Tokens
|
// Tokens
|
||||||
|
@ -36,6 +46,8 @@ export enum SyntaxKind {
|
||||||
|
|
||||||
Param,
|
Param,
|
||||||
|
|
||||||
|
EOS,
|
||||||
|
|
||||||
// Patterns
|
// Patterns
|
||||||
|
|
||||||
BindPatt,
|
BindPatt,
|
||||||
|
@ -44,20 +56,20 @@ export enum SyntaxKind {
|
||||||
// Expressions
|
// Expressions
|
||||||
|
|
||||||
ConstExpr,
|
ConstExpr,
|
||||||
ReferenceExpr,
|
RefExpr,
|
||||||
|
|
||||||
// Statements
|
// Stmts
|
||||||
|
|
||||||
ReturnStatement,
|
RetStmt,
|
||||||
|
|
||||||
// Type declarations
|
// Type declarations
|
||||||
|
|
||||||
TypeReference,
|
TypeRef,
|
||||||
|
|
||||||
// Declaration nodes
|
// Declaration nodes
|
||||||
|
|
||||||
VariableDecl,
|
VarDecl,
|
||||||
FunctionDecl,
|
FuncDecl,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,8 +137,27 @@ export class TextSpan {
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class SyntaxBase {
|
abstract class SyntaxBase {
|
||||||
|
|
||||||
abstract kind: SyntaxKind;
|
abstract kind: SyntaxKind;
|
||||||
|
abstract origNode: [Syntax, Syntax] | Syntax | null;
|
||||||
abstract parentNode: Syntax | null;
|
abstract parentNode: Syntax | null;
|
||||||
|
abstract span: TextSpan | null;
|
||||||
|
|
||||||
|
getSpan() {
|
||||||
|
|
||||||
|
let curr: Syntax | null = this as any as Syntax;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (curr.span !== null ) {
|
||||||
|
return curr.span;
|
||||||
|
}
|
||||||
|
curr = curr.origNode
|
||||||
|
} while (curr !== null)
|
||||||
|
|
||||||
|
throw new Error(`No TextSpan object found in this node or any of its originating nodes.`);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Literal extends SyntaxBase {
|
export class Literal extends SyntaxBase {
|
||||||
|
@ -139,7 +170,8 @@ export class Literal extends SyntaxBase {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public value: string | bigint,
|
public value: string | bigint,
|
||||||
public span: TextSpan,
|
public span: TextSpan | null = null,
|
||||||
|
public origNode: [Syntax, Syntax] | Syntax | null = null,
|
||||||
public parentNode: Syntax | null = null
|
public parentNode: Syntax | null = null
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
@ -147,8 +179,9 @@ export class Literal extends SyntaxBase {
|
||||||
|
|
||||||
toJSON(): Json {
|
toJSON(): Json {
|
||||||
return {
|
return {
|
||||||
value: typeof this.value === 'bigint' ? Number(this.value) : this.value,
|
value: typeof this.value === 'bigint' ? { type: 'bigint', value: this.value.toString() } : this.value,
|
||||||
span: this.span.toJSON(),
|
span: this.span !== null ? this.span.toJSON() : null,
|
||||||
|
origNode: this.origNode !== null ? jsonify(this.origNode) : null,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,6 +193,26 @@ export enum PunctType {
|
||||||
Brace,
|
Brace,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class EOS extends SyntaxBase {
|
||||||
|
|
||||||
|
kind: SyntaxKind.EOS = SyntaxKind.EOS;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
public span: TextSpan | null = null,
|
||||||
|
public origNode: [Syntax, Syntax] | Syntax | null = null,
|
||||||
|
public parentNode: Syntax | null = null
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
toJSON() {
|
||||||
|
return {
|
||||||
|
kind: 'EOS'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
export class Parenthesized extends SyntaxBase {
|
export class Parenthesized extends SyntaxBase {
|
||||||
|
|
||||||
kind: SyntaxKind.Parenthesized = SyntaxKind.Parenthesized;
|
kind: SyntaxKind.Parenthesized = SyntaxKind.Parenthesized;
|
||||||
|
@ -171,15 +224,25 @@ export class Parenthesized extends SyntaxBase {
|
||||||
constructor(
|
constructor(
|
||||||
public elements: Token[],
|
public elements: Token[],
|
||||||
public span: TextSpan,
|
public span: TextSpan,
|
||||||
|
public origNode: [Syntax, Syntax] | Syntax | null = null,
|
||||||
public parentNode: Syntax | null = null
|
public parentNode: Syntax | null = null
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toStream() {
|
||||||
|
return new StreamWrapper(
|
||||||
|
this.elements,
|
||||||
|
() => new EOS(new TextSpan(this.getSpan().file, this.getSpan().end.clone(), this.getSpan().end.clone()))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
toJSON(): Json {
|
toJSON(): Json {
|
||||||
return {
|
return {
|
||||||
kind: 'Parenthesized',
|
kind: 'Parenthesized',
|
||||||
elements: this.elements.map(element => element.toJSON()),
|
elements: this.elements.map(element => element.toJSON()),
|
||||||
|
span: this.span !== null ? this.span.toJSON() : null,
|
||||||
|
origNode: this.origNode !== null ? jsonify(this.origNode) : null,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,15 +260,25 @@ export class Braced extends SyntaxBase {
|
||||||
constructor(
|
constructor(
|
||||||
public elements: Token[],
|
public elements: Token[],
|
||||||
public span: TextSpan,
|
public span: TextSpan,
|
||||||
|
public origNode: [Syntax, Syntax] | Syntax | null = null,
|
||||||
public parentNode: Syntax | null = null
|
public parentNode: Syntax | null = null
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toStream() {
|
||||||
|
return new StreamWrapper(
|
||||||
|
this.elements,
|
||||||
|
() => new EOS(new TextSpan(this.getSpan().file, this.getSpan().end.clone(), this.getSpan().end.clone()))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
toJSON(): Json {
|
toJSON(): Json {
|
||||||
return {
|
return {
|
||||||
kind: 'Braced',
|
kind: 'Braced',
|
||||||
elements: this.elements.map(element => element.toJSON()),
|
elements: this.elements.map(element => element.toJSON()),
|
||||||
|
span: this.span !== null ? this.span.toJSON() : null,
|
||||||
|
origNode: this.origNode !== null ? jsonify(this.origNode) : null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,15 +295,25 @@ export class Bracketed extends SyntaxBase {
|
||||||
constructor(
|
constructor(
|
||||||
public elements: Token[],
|
public elements: Token[],
|
||||||
public span: TextSpan,
|
public span: TextSpan,
|
||||||
|
public origNode: [Syntax, Syntax] | Syntax | null = null,
|
||||||
public parentNode: Syntax | null = null
|
public parentNode: Syntax | null = null
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toStream() {
|
||||||
|
return new StreamWrapper(
|
||||||
|
this.elements,
|
||||||
|
() => new EOS(new TextSpan(this.getSpan().file, this.getSpan().end.clone(), this.getSpan().end.clone()))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
toJSON(): Json {
|
toJSON(): Json {
|
||||||
return {
|
return {
|
||||||
kind: 'Bracketed',
|
kind: 'Bracketed',
|
||||||
elements: this.elements.map(element => element.toJSON()),
|
elements: this.elements.map(element => element.toJSON()),
|
||||||
|
span: this.span !== null ? this.span.toJSON() : null,
|
||||||
|
origNode: this.origNode !== null ? jsonify(this.origNode) : null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,7 +329,8 @@ export class Identifier extends SyntaxBase {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public text: string,
|
public text: string,
|
||||||
public span: TextSpan,
|
public span: TextSpan | null = null,
|
||||||
|
public origNode: [Syntax, Syntax] | Syntax | null = null,
|
||||||
public parentNode: Syntax | null = null
|
public parentNode: Syntax | null = null
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
@ -256,7 +340,8 @@ export class Identifier extends SyntaxBase {
|
||||||
return {
|
return {
|
||||||
kind: 'Identifier',
|
kind: 'Identifier',
|
||||||
text: this.text,
|
text: this.text,
|
||||||
span: this.span.toJSON(),
|
span: this.span !== null ? this.span.toJSON() : null,
|
||||||
|
origNode: this.origNode !== null ? jsonify(this.origNode) : null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,8 +357,8 @@ export class Operator extends SyntaxBase {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public text: string,
|
public text: string,
|
||||||
public span: TextSpan,
|
public span: TextSpan | null = null,
|
||||||
public origNode: Syntax | null = null,
|
public origNode: [Syntax, Syntax] | Syntax | null = null,
|
||||||
public parentNode: Syntax | null = null
|
public parentNode: Syntax | null = null
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
@ -284,6 +369,7 @@ export class Operator extends SyntaxBase {
|
||||||
kind: 'Operator',
|
kind: 'Operator',
|
||||||
text: this.text,
|
text: this.text,
|
||||||
span: this.span !== null ? this.span.toJSON() : null,
|
span: this.span !== null ? this.span.toJSON() : null,
|
||||||
|
origNode: this.origNode !== null ? jsonify(this.origNode) : null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,7 +381,7 @@ export class Semi extends SyntaxBase {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public span: TextSpan | null = null,
|
public span: TextSpan | null = null,
|
||||||
public origNode: Syntax | null = null,
|
public origNode: [Syntax, Syntax] | Syntax | null = null,
|
||||||
public parentNode: Syntax | null = null
|
public parentNode: Syntax | null = null
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
@ -305,6 +391,7 @@ export class Semi extends SyntaxBase {
|
||||||
return {
|
return {
|
||||||
kind: 'Semi',
|
kind: 'Semi',
|
||||||
span: this.span !== null ? this.span.toJSON() : null,
|
span: this.span !== null ? this.span.toJSON() : null,
|
||||||
|
origNode: this.origNode !== null ? jsonify(this.origNode) : null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,8 +402,8 @@ export class Colon extends SyntaxBase {
|
||||||
kind: SyntaxKind.Colon = SyntaxKind.Colon;
|
kind: SyntaxKind.Colon = SyntaxKind.Colon;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public span: TextSpan,
|
public span: TextSpan | null = null,
|
||||||
public origNode: Syntax | null = null,
|
public origNode: [Syntax, Syntax] | Syntax | null = null,
|
||||||
public parentNode: Syntax | null = null
|
public parentNode: Syntax | null = null
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
@ -326,6 +413,7 @@ export class Colon extends SyntaxBase {
|
||||||
return {
|
return {
|
||||||
kind: 'Colon',
|
kind: 'Colon',
|
||||||
span: this.span !== null ? this.span.toJSON() : null,
|
span: this.span !== null ? this.span.toJSON() : null,
|
||||||
|
origNode: this.origNode !== null ? jsonify(this.origNode) : null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,7 +425,7 @@ export class Comma extends SyntaxBase {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public span: TextSpan | null = null,
|
public span: TextSpan | null = null,
|
||||||
public origNode: Syntax | null = null,
|
public origNode: [Syntax, Syntax] | Syntax | null = null,
|
||||||
public parentNode: Syntax | null = null
|
public parentNode: Syntax | null = null
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
@ -347,6 +435,7 @@ export class Comma extends SyntaxBase {
|
||||||
return {
|
return {
|
||||||
kind: 'Comma',
|
kind: 'Comma',
|
||||||
span: this.span !== null ? this.span.toJSON() : null,
|
span: this.span !== null ? this.span.toJSON() : null,
|
||||||
|
origNode: this.origNode !== null ? jsonify(this.origNode) : null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,7 +448,7 @@ export class RArrow extends SyntaxBase {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public span: TextSpan | null = null,
|
public span: TextSpan | null = null,
|
||||||
public origNode: Syntax | null = null,
|
public origNode: [Syntax, Syntax] | Syntax | null = null,
|
||||||
public parentNode: Syntax | null = null
|
public parentNode: Syntax | null = null
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
@ -369,6 +458,7 @@ export class RArrow extends SyntaxBase {
|
||||||
return {
|
return {
|
||||||
kind: 'RArrow',
|
kind: 'RArrow',
|
||||||
span: this.span !== null ? this.span.toJSON() : null,
|
span: this.span !== null ? this.span.toJSON() : null,
|
||||||
|
origNode: this.origNode !== null ? jsonify(this.origNode) : null,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,7 +472,7 @@ export class EqSign extends SyntaxBase {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public span: TextSpan | null = null,
|
public span: TextSpan | null = null,
|
||||||
public origNode: Syntax | null = null,
|
public origNode: [Syntax, Syntax] | Syntax | null = null,
|
||||||
public parentNode: Syntax | null = null
|
public parentNode: Syntax | null = null
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
@ -392,6 +482,7 @@ export class EqSign extends SyntaxBase {
|
||||||
return {
|
return {
|
||||||
kind: 'EqSign',
|
kind: 'EqSign',
|
||||||
span: this.span !== null ? this.span.toJSON() : null,
|
span: this.span !== null ? this.span.toJSON() : null,
|
||||||
|
origNode: this.origNode !== null ? jsonify(this.origNode) : null,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,16 +494,17 @@ export class Dot extends SyntaxBase {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public span: TextSpan | null = null,
|
public span: TextSpan | null = null,
|
||||||
public origNode: Syntax | null = null,
|
public origNode: [Syntax, Syntax] | Syntax | null = null,
|
||||||
public parentNode: Syntax | null = null
|
public parentNode: Syntax | null = null
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
toJSON() {
|
toJSON(): Json {
|
||||||
return {
|
return {
|
||||||
kind: 'Dot',
|
kind: 'Dot',
|
||||||
span: this.span !== null ? this.span.toJSON() : null,
|
span: this.span !== null ? this.span.toJSON() : null,
|
||||||
|
origNode: this.origNode !== null ? jsonify(this.origNode) : null,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -425,6 +517,7 @@ export type Token
|
||||||
| EqSign
|
| EqSign
|
||||||
| Dot
|
| Dot
|
||||||
| RArrow
|
| RArrow
|
||||||
|
| EOS
|
||||||
| Identifier
|
| Identifier
|
||||||
| Operator
|
| Operator
|
||||||
| Literal
|
| Literal
|
||||||
|
@ -434,21 +527,30 @@ export type Token
|
||||||
|
|
||||||
export class Sentence extends SyntaxBase {
|
export class Sentence extends SyntaxBase {
|
||||||
|
|
||||||
kind = SyntaxKind.Sentence;
|
kind: SyntaxKind.Sentence = SyntaxKind.Sentence;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public tokens: Token[],
|
public tokens: Token[],
|
||||||
public span: TextSpan,
|
public span: TextSpan | null = null,
|
||||||
|
public origNode: [Syntax, Syntax] | Syntax | null = null,
|
||||||
public parentNode: Syntax | null = null
|
public parentNode: Syntax | null = null
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toStream() {
|
||||||
|
return new StreamWrapper(
|
||||||
|
this.tokens,
|
||||||
|
() => new EOS(new TextSpan(this.getSpan().file, this.getSpan().end.clone(), this.getSpan().end.clone()))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
toJSON(): Json {
|
toJSON(): Json {
|
||||||
return {
|
return {
|
||||||
kind: 'Sentence',
|
kind: 'Sentence',
|
||||||
tokens: this.tokens.map(token => token.toJSON()),
|
tokens: this.tokens.map(token => token.toJSON()),
|
||||||
span: this.span.toJSON(),
|
span: this.span !== null ? this.span.toJSON() : null,
|
||||||
|
origNode: this.origNode !== null ? jsonify(this.origNode) : null,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -466,12 +568,23 @@ export class QualName {
|
||||||
constructor(
|
constructor(
|
||||||
public name: Identifier | Operator,
|
public name: Identifier | Operator,
|
||||||
public path: Identifier[],
|
public path: Identifier[],
|
||||||
public span: TextSpan,
|
public span: TextSpan | null = null,
|
||||||
|
public origNode: [Syntax, Syntax] | Syntax | null = null,
|
||||||
public parentNode: Syntax | null = null
|
public parentNode: Syntax | null = null
|
||||||
) {
|
) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toJSON(): Json {
|
||||||
|
return {
|
||||||
|
kind: 'QualName',
|
||||||
|
name: this.name.toJSON(),
|
||||||
|
path: this.path.map(p => p.toJSON()),
|
||||||
|
span: this.span !== null ? this.span.toJSON() : null,
|
||||||
|
origNode: this.origNode !== null ? jsonify(this.origNode) : null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Param extends SyntaxBase {
|
export class Param extends SyntaxBase {
|
||||||
|
@ -479,15 +592,27 @@ export class Param extends SyntaxBase {
|
||||||
kind: SyntaxKind.Param = SyntaxKind.Param;
|
kind: SyntaxKind.Param = SyntaxKind.Param;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public bindings: Pattern,
|
public bindings: Patt,
|
||||||
public typeDecl: TypeDecl | null,
|
public typeDecl: TypeDecl | null,
|
||||||
public defaultValue: Expr | null,
|
public defaultValue: Expr | null,
|
||||||
public span: TextSpan | null = null,
|
public span: TextSpan | null = null,
|
||||||
|
public origNode: [Syntax, Syntax] | Syntax | null = null,
|
||||||
public parentNode: Syntax | null = null,
|
public parentNode: Syntax | null = null,
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toJSON(): Json {
|
||||||
|
return {
|
||||||
|
kind: 'Param',
|
||||||
|
bindings: this.bindings.toJSON(),
|
||||||
|
typeDecl: this.typeDecl !== null ? this.typeDecl.toJSON() : null,
|
||||||
|
defaultValue: this.defaultValue !== null ? this.defaultValue.toJSON() : null,
|
||||||
|
span: this.span !== null ? this.span.toJSON() : null,
|
||||||
|
origNode: this.origNode !== null ? jsonify(this.origNode) : null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class BindPatt extends SyntaxBase {
|
export class BindPatt extends SyntaxBase {
|
||||||
|
@ -497,25 +622,53 @@ export class BindPatt extends SyntaxBase {
|
||||||
constructor(
|
constructor(
|
||||||
public name: Identifier,
|
public name: Identifier,
|
||||||
public span: TextSpan | null = null,
|
public span: TextSpan | null = null,
|
||||||
public origNode: Syntax | null = null,
|
public origNode: [Syntax, Syntax] | Syntax | null = null,
|
||||||
public parentNode: Syntax | null = null
|
public parentNode: Syntax | null = null
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
toJSON() {
|
toJSON(): Json {
|
||||||
return {
|
return {
|
||||||
kind: 'BindPatt',
|
kind: 'BindPatt',
|
||||||
name: this.name.toJSON(),
|
name: this.name.toJSON(),
|
||||||
span: this.span !== null ? this.span.toJSON() : null,
|
span: this.span !== null ? this.span.toJSON() : null,
|
||||||
|
origNode: this.origNode !== null ? jsonify(this.origNode) : null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ConstExpr {
|
export type Patt
|
||||||
|
= BindPatt
|
||||||
|
|
||||||
kind = SyntaxKind.ConstExpr;
|
export class RefExpr extends SyntaxBase {
|
||||||
|
|
||||||
|
kind: SyntaxKind.RefExpr = SyntaxKind.RefExpr;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
public name: QualName,
|
||||||
|
public span: TextSpan | null = null,
|
||||||
|
public origNode: [Syntax, Syntax] | Syntax | null = null,
|
||||||
|
public parentNode: Syntax | null = null
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
toJSON(): Json {
|
||||||
|
return {
|
||||||
|
kind: 'RefExpr',
|
||||||
|
name: this.name.toJSON(),
|
||||||
|
span: this.span !== null ? this.span.toJSON() : null,
|
||||||
|
origNode: this.origNode !== null ? jsonify(this.origNode) : null,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ConstExpr extends SyntaxBase {
|
||||||
|
|
||||||
|
kind: SyntaxKind.ConstExpr = SyntaxKind.ConstExpr;
|
||||||
|
|
||||||
static META = {
|
static META = {
|
||||||
value: EdgeType.Primitive,
|
value: EdgeType.Primitive,
|
||||||
|
@ -523,36 +676,58 @@ export class ConstExpr {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public value: string | bigint,
|
public value: string | bigint,
|
||||||
public span: TextSpan,
|
public span: TextSpan | null = null,
|
||||||
|
public origNode: [Syntax, Syntax] | Syntax | null = null,
|
||||||
public parentNode: Syntax | null = null
|
public parentNode: Syntax | null = null
|
||||||
) {
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
toJSON(): Json {
|
||||||
|
return {
|
||||||
|
kind: 'ConstExpr',
|
||||||
|
value: typeof this.value === 'bigint' ? { 'type': 'bigint', value: this.value.toString() } : this.value,
|
||||||
|
span: this.span !== null ? this.span.toJSON() : null,
|
||||||
|
origNode: this.origNode !== null ? jsonify(this.origNode) : null,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Expr
|
export type Expr
|
||||||
= ConstExpr
|
= ConstExpr
|
||||||
|
| RefExpr
|
||||||
|
|
||||||
class ReturnStatement extends SyntaxBase {
|
export class RetStmt extends SyntaxBase {
|
||||||
|
|
||||||
kind: SyntaxKind.ReturnStatement = SyntaxKind.ReturnStatement;
|
kind: SyntaxKind.RetStmt = SyntaxKind.RetStmt;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public value: Expr | null,
|
public value: Expr | null,
|
||||||
public span: TextSpan,
|
public span: TextSpan | null = null,
|
||||||
|
public origNode: [Syntax, Syntax] | Syntax | null = null,
|
||||||
public parentNode: Syntax | null = null
|
public parentNode: Syntax | null = null
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toJSON(): Json {
|
||||||
|
return {
|
||||||
|
kind: 'RetStmt',
|
||||||
|
value: this.value !== null ? this.value.toJSON() : null,
|
||||||
|
span: this.span !== null ? this.span.toJSON() : null,
|
||||||
|
origNode: this.origNode !== null ? jsonify(this.origNode) : null,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Statement
|
}
|
||||||
= ReturnStatement
|
|
||||||
|
|
||||||
export class TypeReference {
|
export type Stmt
|
||||||
|
= RetStmt
|
||||||
|
|
||||||
kind: SyntaxKind.TypeReference = SyntaxKind.TypeReference;
|
export class TypeRef extends SyntaxBase {
|
||||||
|
|
||||||
|
kind: SyntaxKind.TypeRef = SyntaxKind.TypeRef;
|
||||||
|
|
||||||
static META = {
|
static META = {
|
||||||
name: EdgeType.Node,
|
name: EdgeType.Node,
|
||||||
|
@ -562,16 +737,27 @@ export class TypeReference {
|
||||||
constructor(
|
constructor(
|
||||||
public name: QualName,
|
public name: QualName,
|
||||||
public args: TypeDecl[],
|
public args: TypeDecl[],
|
||||||
public span: TextSpan,
|
public span: TextSpan | null = null,
|
||||||
|
public origNode: [Syntax, Syntax] | Syntax | null = null,
|
||||||
public parentNode: Syntax | null = null
|
public parentNode: Syntax | null = null
|
||||||
) {
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
toJSON(): Json {
|
||||||
|
return {
|
||||||
|
kind: 'TypeRef',
|
||||||
|
name: this.name.toJSON(),
|
||||||
|
args: this.args.map(a => a.toJSON()),
|
||||||
|
span: this.span !== null ? this.span.toJSON() : null,
|
||||||
|
origNode: this.origNode !== null ? jsonify(this.origNode) : null,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TypeDecl
|
export type TypeDecl
|
||||||
= TypeReference
|
= TypeRef
|
||||||
|
|
||||||
// export class Unexpanded {
|
// export class Unexpanded {
|
||||||
//
|
//
|
||||||
|
@ -589,9 +775,9 @@ export type TypeDecl
|
||||||
//
|
//
|
||||||
// }
|
// }
|
||||||
|
|
||||||
export class FunctionDecl extends SyntaxBase {
|
export class FuncDecl extends SyntaxBase {
|
||||||
|
|
||||||
kind = SyntaxKind.FunctionDecl;
|
kind: SyntaxKind.FuncDecl = SyntaxKind.FuncDecl;
|
||||||
|
|
||||||
static META = {
|
static META = {
|
||||||
name: EdgeType.Node,
|
name: EdgeType.Node,
|
||||||
|
@ -604,19 +790,31 @@ export class FunctionDecl extends SyntaxBase {
|
||||||
public name: QualName,
|
public name: QualName,
|
||||||
public params: Param[],
|
public params: Param[],
|
||||||
public returnType: TypeDecl | null,
|
public returnType: TypeDecl | null,
|
||||||
public body: Statement[] | null,
|
public body: Stmt[] | null,
|
||||||
public span: TextSpan,
|
public span: TextSpan | null = null,
|
||||||
|
public origNode: [Syntax, Syntax] | Syntax | null = null,
|
||||||
public parentNode: Syntax | null = null
|
public parentNode: Syntax | null = null
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toJSON(): Json {
|
||||||
|
return {
|
||||||
|
kind: 'FuncDecl',
|
||||||
|
name: this.name.toJSON(),
|
||||||
|
params: this.params.map(p => p.toJSON()),
|
||||||
|
returnType: this.returnType !== null ? this.returnType.toJSON() : null,
|
||||||
|
body: this.body !== null ? this.body.map(s => s.toJSON()) : null,
|
||||||
|
origNode: this.origNode !== null ? jsonify(this.origNode) : null,
|
||||||
|
span: this.span !== null ? this.span.toJSON() : this.span,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class VariableDecl extends SyntaxBase {
|
export class VarDecl extends SyntaxBase {
|
||||||
|
|
||||||
kind = SyntaxKind.VariableDecl;
|
kind: SyntaxKind.VarDecl = SyntaxKind.VarDecl;
|
||||||
|
|
||||||
static META = {
|
static META = {
|
||||||
bindings: EdgeType.Node,
|
bindings: EdgeType.Node,
|
||||||
|
@ -625,20 +823,33 @@ export class VariableDecl extends SyntaxBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public bindings: Pattern,
|
public bindings: Patt,
|
||||||
public typeDecl: TypeDecl | null,
|
public typeDecl: TypeDecl | null,
|
||||||
public value: Expr | null,
|
public value: Expr | null,
|
||||||
public span: TextSpan
|
public span: TextSpan | null = null,
|
||||||
|
public origNode: [Syntax, Syntax] | Syntax | null = null,
|
||||||
|
public parentNode: Syntax | null = null
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toJSON(): Json {
|
||||||
|
return {
|
||||||
|
type: 'VarDecl',
|
||||||
|
bindings: this.bindings.toJSON(),
|
||||||
|
typeDecl: this.typeDecl !== null ? this.typeDecl.toJSON() : null,
|
||||||
|
value: this.value !== null ? this.value.toJSON() : null,
|
||||||
|
origNode: this.origNode !== null ? jsonify(this.origNode) : null,
|
||||||
|
span: this.span !== null ? this.span.toJSON() : this.span,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Decl
|
export type Decl
|
||||||
= Sentence
|
= Sentence
|
||||||
| FunctionDecl
|
| FuncDecl
|
||||||
| VariableDecl
|
| VarDecl
|
||||||
|
|
||||||
export type Syntax
|
export type Syntax
|
||||||
= Decl
|
= Decl
|
||||||
|
@ -646,23 +857,28 @@ export type Syntax
|
||||||
| Token
|
| Token
|
||||||
| SourceFile
|
| SourceFile
|
||||||
| QualName
|
| QualName
|
||||||
|
| Param
|
||||||
|
| EOS
|
||||||
|
|
||||||
export class SourceFile extends SyntaxBase {
|
export class SourceFile extends SyntaxBase {
|
||||||
|
|
||||||
kind: SyntaxKind.SourceFile = SyntaxKind.SourceFile;
|
kind: SyntaxKind.SourceFile = SyntaxKind.SourceFile;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public elements: (Decl | Statement)[],
|
public elements: (Decl | Stmt)[],
|
||||||
public span: TextSpan,
|
public span: TextSpan | null = null,
|
||||||
|
public origNode: [Syntax, Syntax] | Syntax | null = null,
|
||||||
public parentNode: Syntax | null = null
|
public parentNode: Syntax | null = null
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
toJSON() {
|
toJSON(): Json {
|
||||||
return {
|
return {
|
||||||
|
kind: 'SourceFile',
|
||||||
elements: this.elements.map(element => element.toJSON()),
|
elements: this.elements.map(element => element.toJSON()),
|
||||||
span: this.span.toJSON(),
|
origNode: this.origNode !== null ? jsonify(this.origNode) : null,
|
||||||
|
span: this.span !== null ? this.span.toJSON() : null,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue