2024-07-21 20:56:42 +01:00
|
|
|
|
|
|
|
@preprocessor typescript
|
|
|
|
|
|
|
|
@{%
|
|
|
|
import * as moo from "https://deno.land/x/moo@0.5.1-deno.2/mod.ts";
|
|
|
|
import * as ast from "./ast.out.ts";
|
|
|
|
|
|
|
|
const lexer: any = moo.compile({
|
|
|
|
|
|
|
|
newline: { match: /[\n]+/, lineBreaks: true },
|
|
|
|
whitespace: /[ \t]+/,
|
|
|
|
|
|
|
|
singleLineComment: /\/\/.*?$/,
|
|
|
|
multiLineComment: { match: /\*[^*]*\*+(?:[^/*][^*]*\*+)*/, lineBreaks: true },
|
|
|
|
|
|
|
|
name: {
|
|
|
|
match: /[a-zA-Z0-9_]+/,
|
|
|
|
type: moo.keywords({
|
|
|
|
keyword: [],
|
|
|
|
}),
|
|
|
|
},
|
|
|
|
|
|
|
|
lparen: "(",
|
|
|
|
rparen: ")",
|
|
|
|
lbrace: "{",
|
|
|
|
rbrace: "}",
|
|
|
|
lbracket: "[",
|
|
|
|
rbracket: "]",
|
|
|
|
colon: ":",
|
|
|
|
comma: ",",
|
|
|
|
questionmark: "?",
|
|
|
|
});
|
|
|
|
%}
|
|
|
|
|
|
|
|
@lexer lexer
|
|
|
|
|
|
|
|
file -> elements {% id %}
|
|
|
|
|
|
|
|
elements -> _ (element elementTail _):? {% v => v[1] ? [v[1][0], ...v[1][1]] : [] %}
|
|
|
|
|
|
|
|
elementTail -> (nl__ element):* {% v => v[0].map(w => w[1]) %}
|
|
|
|
|
|
|
|
element -> enum {% v => ast.EnumStatement(v[0]) %}
|
|
|
|
| node {% v => ast.NodeStatement(v[0]) %}
|
|
|
|
|
|
|
|
enum -> name _ "{" nodes "}" {% v => ast.Enum(v[0], v[3]) %}
|
|
|
|
|
|
|
|
nodes -> _ (node nodeTail _):? {% v => v[1] ? [v[1][0], ...v[1][1]] : [] %}
|
|
|
|
|
|
|
|
nodeTail -> (nl__ node):* {% v => v[0].map(w => w[1]) %}
|
|
|
|
|
|
|
|
node -> name _ "(" params ")" {% v => ast.Node(v[0], v[3]) %}
|
|
|
|
|
|
|
|
params -> _ (param paramTail (_ ","):? _):? {% v => v[1] ? [v[1][0], ...v[1][1]] : [] %}
|
|
|
|
|
|
|
|
paramTail -> ("," _ param):* {% v => v[0].map(w => w[2]) %}
|
|
|
|
|
2024-07-21 22:35:34 +01:00
|
|
|
param -> namedParam {% id %}
|
|
|
|
| unnamedParam {% id %}
|
|
|
|
|
|
|
|
namedParam -> name _ ":" _ type {% v => ast.NamedParam(v[0], v[4]) %}
|
|
|
|
|
|
|
|
unnamedParam -> type {% v => ast.UnnamedParam(v[0]) %}
|
2024-07-21 20:56:42 +01:00
|
|
|
|
|
|
|
type -> optional {% id %}
|
|
|
|
| multiple {% id %}
|
|
|
|
| name {% v => ast.NameType(v[0]) %}
|
|
|
|
|
|
|
|
optional -> type "?" {% v => ast.OptionalType(v[0]) %}
|
|
|
|
|
|
|
|
multiple -> type "[" "]" {% v => ast.MultipleType(v[0]) %}
|
|
|
|
|
2024-07-21 22:35:34 +01:00
|
|
|
name -> %name {% v => ast.Name(v[0].value, v[0].line, v[0].col) %}
|
2024-07-21 20:56:42 +01:00
|
|
|
|
|
|
|
_ -> __:?
|
|
|
|
__ -> (%whitespace|%newline|%singeLineComment|%multiLineComment):+
|
|
|
|
|
|
|
|
nl__ -> sl_ (%newline sl_):+
|
|
|
|
|
|
|
|
sl_ -> sl__:?
|
|
|
|
sl__ -> (%whitespace|%singleLineComment|%multiLineComment):+
|