add types and code blocks
This commit is contained in:
parent
99383fd9c1
commit
a0d27dafe2
3
ast
3
ast
@ -1,9 +1,12 @@
|
|||||||
|
|
||||||
Statement {
|
Statement {
|
||||||
|
CodeBlock(CodeBlock)
|
||||||
Enum(Enum)
|
Enum(Enum)
|
||||||
Node(Node)
|
Node(Node)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CodeBlock(string)
|
||||||
|
|
||||||
Enum(name: Name, nodes: Node[])
|
Enum(name: Name, nodes: Node[])
|
||||||
|
|
||||||
Node(name: Name, params: Param[])
|
Node(name: Name, params: Param[])
|
||||||
|
46
ast.out.ts
46
ast.out.ts
@ -1,66 +1,88 @@
|
|||||||
// Generated file by ast_generator
|
// Generated file by ast_generator
|
||||||
|
export type Statement_CodeBlock = {
|
||||||
|
type: "Statement",
|
||||||
|
kind: "CodeBlock",
|
||||||
|
[0]: CodeBlock,
|
||||||
|
};
|
||||||
|
export const Statement_CodeBlock = (v0: CodeBlock): Statement_CodeBlock => ({ type: "Statement", kind: "CodeBlock", [0]: v0 });
|
||||||
export type Statement_Enum = {
|
export type Statement_Enum = {
|
||||||
|
type: "Statement",
|
||||||
kind: "Enum",
|
kind: "Enum",
|
||||||
[0]: Enum,
|
[0]: Enum,
|
||||||
};
|
};
|
||||||
export const Statement_Enum = (v0: Enum): Statement_Enum => ({ kind: "Enum", [0]: v0 });
|
export const Statement_Enum = (v0: Enum): Statement_Enum => ({ type: "Statement", kind: "Enum", [0]: v0 });
|
||||||
export type Statement_Node = {
|
export type Statement_Node = {
|
||||||
|
type: "Statement",
|
||||||
kind: "Node",
|
kind: "Node",
|
||||||
[0]: Node,
|
[0]: Node,
|
||||||
};
|
};
|
||||||
export const Statement_Node = (v0: Node): Statement_Node => ({ kind: "Node", [0]: v0 });
|
export const Statement_Node = (v0: Node): Statement_Node => ({ type: "Statement", kind: "Node", [0]: v0 });
|
||||||
export type Statement = Statement_Enum | Statement_Node;
|
export type Statement = Statement_CodeBlock | Statement_Enum | Statement_Node;
|
||||||
export const Statement = { Enum: Statement_Enum, Node: Statement_Node } as const;
|
export const Statement = { CodeBlock: Statement_CodeBlock, Enum: Statement_Enum, Node: Statement_Node } as const;
|
||||||
|
|
||||||
|
export type CodeBlock = {
|
||||||
|
type: "CodeBlock";
|
||||||
|
[0]: string;
|
||||||
|
};
|
||||||
|
export const CodeBlock = (v0: string): CodeBlock => ({ type: "CodeBlock", [0]: v0 });
|
||||||
|
|
||||||
export type Enum = {
|
export type Enum = {
|
||||||
|
type: "Enum";
|
||||||
name: Name;
|
name: Name;
|
||||||
nodes: Node[];
|
nodes: Node[];
|
||||||
};
|
};
|
||||||
export const Enum = (name: Name, nodes: Node[]): Enum => ({ name, nodes });
|
export const Enum = (name: Name, nodes: Node[]): Enum => ({ type: "Enum", name, nodes });
|
||||||
|
|
||||||
export type Node = {
|
export type Node = {
|
||||||
|
type: "Node";
|
||||||
name: Name;
|
name: Name;
|
||||||
params: Param[];
|
params: Param[];
|
||||||
};
|
};
|
||||||
export const Node = (name: Name, params: Param[]): Node => ({ name, params });
|
export const Node = (name: Name, params: Param[]): Node => ({ type: "Node", name, params });
|
||||||
|
|
||||||
export type Param_Named = {
|
export type Param_Named = {
|
||||||
|
type: "Param",
|
||||||
kind: "Named",
|
kind: "Named",
|
||||||
name: Name,
|
name: Name,
|
||||||
type_: Type,
|
type_: Type,
|
||||||
};
|
};
|
||||||
export const Param_Named = (name: Name, type_: Type): Param_Named => ({ kind: "Named", name, type_ });
|
export const Param_Named = (name: Name, type_: Type): Param_Named => ({ type: "Param", kind: "Named", name, type_ });
|
||||||
export type Param_Unnamed = {
|
export type Param_Unnamed = {
|
||||||
|
type: "Param",
|
||||||
kind: "Unnamed",
|
kind: "Unnamed",
|
||||||
[0]: Type,
|
[0]: Type,
|
||||||
};
|
};
|
||||||
export const Param_Unnamed = (v0: Type): Param_Unnamed => ({ kind: "Unnamed", [0]: v0 });
|
export const Param_Unnamed = (v0: Type): Param_Unnamed => ({ type: "Param", kind: "Unnamed", [0]: v0 });
|
||||||
export type Param = Param_Named | Param_Unnamed;
|
export type Param = Param_Named | Param_Unnamed;
|
||||||
export const Param = { Named: Param_Named, Unnamed: Param_Unnamed } as const;
|
export const Param = { Named: Param_Named, Unnamed: Param_Unnamed } as const;
|
||||||
|
|
||||||
export type Type_Name = {
|
export type Type_Name = {
|
||||||
|
type: "Type",
|
||||||
kind: "Name",
|
kind: "Name",
|
||||||
[0]: Name,
|
[0]: Name,
|
||||||
};
|
};
|
||||||
export const Type_Name = (v0: Name): Type_Name => ({ kind: "Name", [0]: v0 });
|
export const Type_Name = (v0: Name): Type_Name => ({ type: "Type", kind: "Name", [0]: v0 });
|
||||||
export type Type_Optional = {
|
export type Type_Optional = {
|
||||||
|
type: "Type",
|
||||||
kind: "Optional",
|
kind: "Optional",
|
||||||
[0]: Type,
|
[0]: Type,
|
||||||
};
|
};
|
||||||
export const Type_Optional = (v0: Type): Type_Optional => ({ kind: "Optional", [0]: v0 });
|
export const Type_Optional = (v0: Type): Type_Optional => ({ type: "Type", kind: "Optional", [0]: v0 });
|
||||||
export type Type_Multiple = {
|
export type Type_Multiple = {
|
||||||
|
type: "Type",
|
||||||
kind: "Multiple",
|
kind: "Multiple",
|
||||||
[0]: Type,
|
[0]: Type,
|
||||||
};
|
};
|
||||||
export const Type_Multiple = (v0: Type): Type_Multiple => ({ kind: "Multiple", [0]: v0 });
|
export const Type_Multiple = (v0: Type): Type_Multiple => ({ type: "Type", kind: "Multiple", [0]: v0 });
|
||||||
export type Type = Type_Name | Type_Optional | Type_Multiple;
|
export type Type = Type_Name | Type_Optional | Type_Multiple;
|
||||||
export const Type = { Name: Type_Name, Optional: Type_Optional, Multiple: Type_Multiple } as const;
|
export const Type = { Name: Type_Name, Optional: Type_Optional, Multiple: Type_Multiple } as const;
|
||||||
|
|
||||||
export type Name = {
|
export type Name = {
|
||||||
|
type: "Name";
|
||||||
[0]: string;
|
[0]: string;
|
||||||
line: number;
|
line: number;
|
||||||
col: number;
|
col: number;
|
||||||
};
|
};
|
||||||
export const Name = (v0: string, line: number, col: number): Name => ({ [0]: v0, line, col });
|
export const Name = (v0: string, line: number, col: number): Name => ({ type: "Name", [0]: v0, line, col });
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import {
|
|||||||
|
|
||||||
import compiledParserGrammar from "./parser.out.ts";
|
import compiledParserGrammar from "./parser.out.ts";
|
||||||
import {
|
import {
|
||||||
|
CodeBlock,
|
||||||
Enum,
|
Enum,
|
||||||
Name,
|
Name,
|
||||||
Node,
|
Node,
|
||||||
@ -21,6 +22,9 @@ class TypescriptGenerator {
|
|||||||
this.result += "// Generated file by ast_generator\n";
|
this.result += "// Generated file by ast_generator\n";
|
||||||
for (const statement of ast) {
|
for (const statement of ast) {
|
||||||
switch (statement.kind) {
|
switch (statement.kind) {
|
||||||
|
case "CodeBlock":
|
||||||
|
this.generateCodeBlock(statement[0]);
|
||||||
|
break;
|
||||||
case "Enum":
|
case "Enum":
|
||||||
this.generateEnum(statement[0]);
|
this.generateEnum(statement[0]);
|
||||||
break;
|
break;
|
||||||
@ -33,6 +37,10 @@ class TypescriptGenerator {
|
|||||||
return this.result;
|
return this.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private generateCodeBlock(block: CodeBlock) {
|
||||||
|
this.result += `${block[0]}\n`;
|
||||||
|
}
|
||||||
|
|
||||||
private generateEnum(enum_: Enum) {
|
private generateEnum(enum_: Enum) {
|
||||||
if (this.isShallowEnum(enum_)) {
|
if (this.isShallowEnum(enum_)) {
|
||||||
return this.generateShallowEnumBody(enum_);
|
return this.generateShallowEnumBody(enum_);
|
||||||
@ -62,6 +70,7 @@ class TypescriptGenerator {
|
|||||||
const fullName = `${enumName}_${name}`;
|
const fullName = `${enumName}_${name}`;
|
||||||
nodeNames.push([name, fullName]);
|
nodeNames.push([name, fullName]);
|
||||||
this.result += `export type ${fullName} = {\n`;
|
this.result += `export type ${fullName} = {\n`;
|
||||||
|
this.result += ` type: "${enumName}",\n`;
|
||||||
this.result += ` kind: "${name}",\n`;
|
this.result += ` kind: "${name}",\n`;
|
||||||
this.result += node.params.map((p, i) => this.makeParamField(p, i))
|
this.result += node.params.map((p, i) => this.makeParamField(p, i))
|
||||||
.map((field) => ` ${field},\n`).join("");
|
.map((field) => ` ${field},\n`).join("");
|
||||||
@ -70,7 +79,7 @@ class TypescriptGenerator {
|
|||||||
const fields = this.makeFnFields(node.params);
|
const fields = this.makeFnFields(node.params);
|
||||||
this.result += `export const ${fullName}` +
|
this.result += `export const ${fullName}` +
|
||||||
` = (${fnParams}): ${fullName}` +
|
` = (${fnParams}): ${fullName}` +
|
||||||
` => ({ kind: "${name}", ${fields} });\n`;
|
` => ({ type: "${enumName}", kind: "${name}", ${fields} });\n`;
|
||||||
}
|
}
|
||||||
const typeList = nodeNames
|
const typeList = nodeNames
|
||||||
.map(([_, fullName]) => fullName)
|
.map(([_, fullName]) => fullName)
|
||||||
@ -97,6 +106,7 @@ class TypescriptGenerator {
|
|||||||
) {
|
) {
|
||||||
const name = this.makeName(node.name);
|
const name = this.makeName(node.name);
|
||||||
this.result += `export type ${name} = {\n`;
|
this.result += `export type ${name} = {\n`;
|
||||||
|
this.result += ` type: "${name}";\n`;
|
||||||
for (
|
for (
|
||||||
const [param, index] of node.params
|
const [param, index] of node.params
|
||||||
.map((v, i) => [v, i] as const)
|
.map((v, i) => [v, i] as const)
|
||||||
@ -117,7 +127,7 @@ class TypescriptGenerator {
|
|||||||
const fields = this.makeFnFields(node.params);
|
const fields = this.makeFnFields(node.params);
|
||||||
this.result += `export const ${name}` +
|
this.result += `export const ${name}` +
|
||||||
` = (${fnParams}): ${name}` +
|
` = (${fnParams}): ${name}` +
|
||||||
` => ({ ${fields} });\n`;
|
` => ({ type: "${name}", ${fields} });\n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private makeFnParams(params: Param[]): string {
|
private makeFnParams(params: Param[]): string {
|
||||||
|
11
parser.ne
11
parser.ne
@ -13,6 +13,12 @@ const lexer: any = moo.compile({
|
|||||||
singleLineComment: /\/\/.*?$/,
|
singleLineComment: /\/\/.*?$/,
|
||||||
multiLineComment: { match: /\*[^*]*\*+(?:[^/*][^*]*\*+)*/, lineBreaks: true },
|
multiLineComment: { match: /\*[^*]*\*+(?:[^/*][^*]*\*+)*/, lineBreaks: true },
|
||||||
|
|
||||||
|
codeBlock: {
|
||||||
|
match: /\{%[^%]*?%\}/,
|
||||||
|
lineBreaks: true,
|
||||||
|
value: s => s.slice(2, s.length - 2),
|
||||||
|
},
|
||||||
|
|
||||||
name: {
|
name: {
|
||||||
match: /[a-zA-Z0-9_]+/,
|
match: /[a-zA-Z0-9_]+/,
|
||||||
type: moo.keywords({
|
type: moo.keywords({
|
||||||
@ -40,9 +46,12 @@ elements -> _ (element elementTail _):? {% v => v[1] ? [v[1][0], ...v[1][1]] : [
|
|||||||
|
|
||||||
elementTail -> (nl__ element):* {% v => v[0].map(w => w[1]) %}
|
elementTail -> (nl__ element):* {% v => v[0].map(w => w[1]) %}
|
||||||
|
|
||||||
element -> enum {% v => ast.Statement.Enum(v[0]) %}
|
element -> codeBlock {% v => ast.Statement.CodeBlock(v[0]) %}
|
||||||
|
| enum {% v => ast.Statement.Enum(v[0]) %}
|
||||||
| node {% v => ast.Statement.Node(v[0]) %}
|
| node {% v => ast.Statement.Node(v[0]) %}
|
||||||
|
|
||||||
|
codeBlock -> %codeBlock {% v => ast.CodeBlock(v[0].value) %}
|
||||||
|
|
||||||
enum -> name _ "{" nodes "}" {% v => ast.Enum(v[0], v[3]) %}
|
enum -> name _ "{" nodes "}" {% v => ast.Enum(v[0], v[3]) %}
|
||||||
|
|
||||||
nodes -> _ (node nodeTail _):? {% v => v[1] ? [v[1][0], ...v[1][1]] : [] %}
|
nodes -> _ (node nodeTail _):? {% v => v[1] ? [v[1][0], ...v[1][1]] : [] %}
|
||||||
|
Loading…
Reference in New Issue
Block a user