Compare commits

..

No commits in common. "07737d23c26b762a9d718f231efd2e2f26dfbcad" and "cb6c71b31061082f3eae9744423f2163b325c8c6" have entirely different histories.

7 changed files with 37 additions and 99 deletions

2
.gitignore vendored
View File

@ -1,3 +1 @@
parser.out.ts parser.out.ts
new.ast.out.ts

21
ast
View File

@ -1,27 +1,20 @@
Statement { Statement {
Enum(Enum) Enum(enum_: Enum)
Node(Node) Node(node: Node)
} }
Enum(name: Name, nodes: Node[]) Enum(name: Name, nodes: Node[])
Node(name: Name, params: Param[]) Node(name: Name, params: Param[])
Param { Param(name: Name, type_: Type)
Named(name: Name, type_: Type)
Unnamed(Type)
}
Type { Type {
Name(Name) Name(name: Name)
Optional(Type) Optional(type_: Type)
Multiple(Type) Multiple(type_: Type)
} }
Name( Name(value: string)
string,
line: number,
col: number,
)

View File

@ -1,14 +1,14 @@
// Generated file by ast_generator // Generated file by ast_generator
export type EnumStatement = { export type EnumStatement = {
kind: "Enum"; kind: "Enum";
[0]: Enum; enum_: Enum;
}; };
export const EnumStatement = (v0: Enum): EnumStatement => ({ kind: "Enum", [0]: v0 }); export const EnumStatement = (enum_: Enum): EnumStatement => ({ kind: "Enum", enum_ });
export type NodeStatement = { export type NodeStatement = {
kind: "Node"; kind: "Node";
[0]: Node; node: Node;
}; };
export const NodeStatement = (v0: Node): NodeStatement => ({ kind: "Node", [0]: v0 }); export const NodeStatement = (node: Node): NodeStatement => ({ kind: "Node", node });
export type Statement = EnumStatement | NodeStatement; export type Statement = EnumStatement | NodeStatement;
export type Enum = { export type Enum = {
name: Name; name: Name;
@ -20,38 +20,29 @@ export type Node = {
params: Param[]; params: Param[];
}; };
export const Node = (name: Name, params: Param[]): Node => ({ name, params }); export const Node = (name: Name, params: Param[]): Node => ({ name, params });
export type NamedParam = { export type Param = {
kind: "Named";
name: Name; name: Name;
type_: Type; type_: Type;
}; };
export const NamedParam = (name: Name, type_: Type): NamedParam => ({ kind: "Named", name, type_ }); export const Param = (name: Name, type_: Type): Param => ({ name, type_ });
export type UnnamedParam = {
kind: "Unnamed";
[0]: Type;
};
export const UnnamedParam = (v0: Type): UnnamedParam => ({ kind: "Unnamed", [0]: v0 });
export type Param = NamedParam | UnnamedParam;
export type NameType = { export type NameType = {
kind: "Name"; kind: "Name";
[0]: Name; name: Name;
}; };
export const NameType = (v0: Name): NameType => ({ kind: "Name", [0]: v0 }); export const NameType = (name: Name): NameType => ({ kind: "Name", name });
export type OptionalType = { export type OptionalType = {
kind: "Optional"; kind: "Optional";
[0]: Type; type_: Type;
}; };
export const OptionalType = (v0: Type): OptionalType => ({ kind: "Optional", [0]: v0 }); export const OptionalType = (type_: Type): OptionalType => ({ kind: "Optional", type_ });
export type MultipleType = { export type MultipleType = {
kind: "Multiple"; kind: "Multiple";
[0]: Type; type_: Type;
}; };
export const MultipleType = (v0: Type): MultipleType => ({ kind: "Multiple", [0]: v0 }); export const MultipleType = (type_: Type): MultipleType => ({ kind: "Multiple", type_ });
export type Type = NameType | OptionalType | MultipleType; export type Type = NameType | OptionalType | MultipleType;
export type Name = { export type Name = {
[0]: string; value: string;
line: number;
col: number;
}; };
export const Name = (v0: string, line: number, col: number): Name => ({ [0]: v0, line, col }); export const Name = (value: string): Name => ({ value });

View File

@ -4,7 +4,7 @@ import {
} from "https://deno.land/x/nearley@2.19.7-deno/mod.ts"; } from "https://deno.land/x/nearley@2.19.7-deno/mod.ts";
import compiledParserGrammar from "./parser.out.ts"; import compiledParserGrammar from "./parser.out.ts";
import { Enum, Name, NamedParam, Node, Statement, Type } from "./ast.out.ts"; import { Enum, Name, Node, Param, Statement, Type } from "./ast.out.ts";
class TypescriptGenerator { class TypescriptGenerator {
private result = ""; private result = "";
@ -14,10 +14,10 @@ class TypescriptGenerator {
for (const statement of ast) { for (const statement of ast) {
switch (statement.kind) { switch (statement.kind) {
case "Enum": case "Enum":
this.generateEnum(statement[0]); this.generateEnum(statement.enum_);
break; break;
case "Node": case "Node":
this.generateNode(statement[0]); this.generateNode(statement.node);
break; break;
} }
} }
@ -49,47 +49,22 @@ class TypescriptGenerator {
if (kind) { if (kind) {
this.result += ` kind: "${kind}";\n`; this.result += ` kind: "${kind}";\n`;
} }
for ( for (const param of node.params) {
const [param, index] of node.params this.result += ` ${this.makeParam(param)};\n`;
.map((v, i) => [v, i] as const)
) {
switch (param.kind) {
case "Named":
this.result += ` ${this.makeNamedParam(param)};\n`;
break;
case "Unnamed":
this.result += ` [${index}]: ${
this.makeType(param[0])
};\n`;
}
} }
this.result += "};\n"; this.result += "};\n";
const fnParams = node.params const fnParams = node.params.map((param) => this.makeParam(param)).join(
.map((param, index) => { ", ",
switch (param.kind) { );
case "Named":
return this.makeNamedParam(param);
case "Unnamed":
return `v${index}: ${this.makeType(param[0])}`;
}
})
.join(", ");
const fields = [ const fields = [
...(kind ? [`kind: "${kind}"`] : []), ...(kind ? [`kind: "${kind}"`] : []),
...node.params.map((param, index) => { ...node.params.map((param) => this.makeName(param.name)),
switch (param.kind) {
case "Named":
return this.makeName(param.name);
case "Unnamed":
return `[${index}]: v${index}`;
}
}),
].join(", "); ].join(", ");
this.result += this.result +=
`export const ${name} = (${fnParams}): ${name} => ({ ${fields} });\n`; `export const ${name} = (${fnParams}): ${name} => ({ ${fields} });\n`;
} }
private makeNamedParam(param: NamedParam): string { private makeParam(param: Param): string {
const name = this.makeName(param.name); const name = this.makeName(param.name);
const type_ = this.makeType(param.type_); const type_ = this.makeType(param.type_);
return `${name}: ${type_}`; return `${name}: ${type_}`;
@ -98,16 +73,16 @@ class TypescriptGenerator {
private makeType(type_: Type): string { private makeType(type_: Type): string {
switch (type_.kind) { switch (type_.kind) {
case "Name": case "Name":
return this.makeName(type_[0]); return this.makeName(type_.name);
case "Optional": case "Optional":
return `${this.makeType(type_[0])} | null`; return `${this.makeType(type_.type_)} | null`;
case "Multiple": case "Multiple":
return `${this.makeType(type_[0])}[]`; return `${this.makeType(type_.type_)}[]`;
} }
} }
private makeName(name: Name): string { private makeName(name: Name): string {
return name[0]; return name.value;
} }
} }

View File

@ -1,5 +0,0 @@
{
"fmt": {
"indentWidth": 4
}
}

View File

@ -1,9 +0,0 @@
{
"version": "3",
"remote": {
"https://deno.land/x/moo@0.5.1-deno.2/mod.ts": "fbccad242a370172385c0545886e8051ab4c2cc86b4635798fcf490db718af4e",
"https://deno.land/x/moo@0.5.1-deno.2/moo.js": "90e55b04d273feb1ccf0bd7f20df24259715bbfbbffe0e462882c5c5caeb232b",
"https://deno.land/x/nearley@2.19.7-deno/lib/nearley.js": "4d69e17885788c78f0aa4776de6ce587a99e1562468fb826c5a5b649a59b9d43",
"https://deno.land/x/nearley@2.19.7-deno/mod.ts": "a52f8fe208afc6790bd4167e433f397c578838547bf7161eef144810c28d57db"
}
}

View File

@ -55,12 +55,7 @@ params -> _ (param paramTail (_ ","):? _):? {% v => v[1] ? [v[1][0], ...v[1][1]]
paramTail -> ("," _ param):* {% v => v[0].map(w => w[2]) %} paramTail -> ("," _ param):* {% v => v[0].map(w => w[2]) %}
param -> namedParam {% id %} param -> name _ ":" _ type {% v => ast.Param(v[0], v[4]) %}
| unnamedParam {% id %}
namedParam -> name _ ":" _ type {% v => ast.NamedParam(v[0], v[4]) %}
unnamedParam -> type {% v => ast.UnnamedParam(v[0]) %}
type -> optional {% id %} type -> optional {% id %}
| multiple {% id %} | multiple {% id %}
@ -70,7 +65,7 @@ optional -> type "?" {% v => ast.OptionalType(v[0]) %}
multiple -> type "[" "]" {% v => ast.MultipleType(v[0]) %} multiple -> type "[" "]" {% v => ast.MultipleType(v[0]) %}
name -> %name {% v => ast.Name(v[0].value, v[0].line, v[0].col) %} name -> %name {% v => ast.Name(v[0]) %}
_ -> __:? _ -> __:?
__ -> (%whitespace|%newline|%singeLineComment|%multiLineComment):+ __ -> (%whitespace|%newline|%singeLineComment|%multiLineComment):+