249 lines
4.3 KiB
Typst
249 lines
4.3 KiB
Typst
#import "@preview/acrostiche:0.7.0": acr
|
|
#import "@local/codly:1.3.1": codly-disable, codly-enable
|
|
|
|
#let token-types = (
|
|
"Punctuation": (
|
|
"LEFT_PAREN",
|
|
"RIGHT_PAREN",
|
|
"LEFT_BRACKET",
|
|
"RIGHT_BRACKET",
|
|
"LEFT_BRACE",
|
|
"RIGHT_BRACE",
|
|
"COLON",
|
|
"COMMA",
|
|
"UNDERSCORE",
|
|
"ARROW",
|
|
"AND",
|
|
"QMARK",
|
|
"DOT",
|
|
),
|
|
|
|
"Operators": (
|
|
"PLUS",
|
|
"MINUS",
|
|
"STAR",
|
|
"SLASH",
|
|
"GREATER",
|
|
"GREATER_EQUAL",
|
|
"LESS",
|
|
"LESS_EQUAL",
|
|
"EQUAL",
|
|
"EQUAL_EQUAL",
|
|
"BANG_EQUAL",
|
|
"BANG",
|
|
),
|
|
|
|
"Literals": (
|
|
"IDENTIFIER",
|
|
"NUMBER",
|
|
"TRUE",
|
|
"FALSE",
|
|
"NONE",
|
|
"STRING",
|
|
),
|
|
|
|
"Keywords": (
|
|
"TYPE",
|
|
"ALIAS",
|
|
"PREDICATE",
|
|
"EXTEND",
|
|
"WHERE",
|
|
"PROP",
|
|
"DEF",
|
|
"FUNC",
|
|
),
|
|
|
|
"Misc": (
|
|
"COMMENT",
|
|
"WHITESPACE",
|
|
"EOF",
|
|
"NEWLINE",
|
|
),
|
|
)
|
|
|
|
#let token-types-cells = {
|
|
let cells = ()
|
|
for (category, types) in token-types.pairs() {
|
|
cells.push([*#category*])
|
|
cells += types
|
|
}
|
|
|
|
// Transpose
|
|
let per-col = calc.ceil(cells.len() / 4)
|
|
let total = per-col * 4
|
|
|
|
cells = (cells + (none,) * (total - cells.len())).chunks(per-col)
|
|
cells = cells.first().zip(..cells.slice(1)).flatten()
|
|
|
|
cells
|
|
}
|
|
|
|
#let ast-nodes = (
|
|
("Other classes", none, ```python
|
|
class TypeParam:
|
|
location: Location
|
|
name: Token
|
|
bound: Optional[Type]
|
|
|
|
class MemberKind(Enum):
|
|
PROPERTY = auto()
|
|
METHOD = auto()
|
|
|
|
class ParamSpec:
|
|
l_paren: Token
|
|
pos: list[FunctionType.Parameter]
|
|
mixed: list[FunctionType.Parameter]
|
|
kw: list[FunctionType.Parameter]
|
|
```),
|
|
("Statements", `Stmt`, ```python
|
|
class TypeStmt:
|
|
name: Token
|
|
params: list[TypeParam]
|
|
type: Type
|
|
|
|
class AliasStmt:
|
|
name: Token
|
|
type: Type
|
|
|
|
class MemberStmt:
|
|
name: Token
|
|
type: Type
|
|
kind: MemberKind
|
|
|
|
class ExtendStmt:
|
|
name: Token
|
|
params: list[TypeParam]
|
|
members: list[MemberStmt]
|
|
|
|
class PredicateStmt:
|
|
name: Token
|
|
params: list[ParamSpec]
|
|
body: Expr
|
|
```),
|
|
("Expressions", `Expr`, ```python
|
|
class LogicalExpr:
|
|
left: Expr
|
|
operator: Token
|
|
right: Expr
|
|
|
|
class BinaryExpr:
|
|
left: Expr
|
|
operator: Token
|
|
right: Expr
|
|
|
|
class UnaryExpr:
|
|
operator: Token
|
|
right: Expr
|
|
|
|
class CallExpr:
|
|
callee: Expr
|
|
arguments: list[Expr]
|
|
keywords: dict[str, Expr]
|
|
|
|
class GetExpr:
|
|
expr: Expr
|
|
name: Token
|
|
|
|
class VariableExpr:
|
|
name: Token
|
|
|
|
class GroupingExpr:
|
|
expr: Expr
|
|
|
|
class LiteralExpr:
|
|
value: Any
|
|
|
|
class WildcardExpr:
|
|
token: Token
|
|
```),
|
|
("Types", `Type`, ```python
|
|
class NamedType:
|
|
name: Token
|
|
|
|
class GenericType:
|
|
type: Type
|
|
args: list[Type]
|
|
|
|
class ConstraintType:
|
|
type: Type
|
|
constraint: Expr
|
|
|
|
class FunctionType:
|
|
params: ParamSpec
|
|
returns: Type
|
|
|
|
class Parameter:
|
|
location: Optional[Location] = None
|
|
name: Optional[Token]
|
|
type: Type
|
|
required: bool
|
|
|
|
class FrameType:
|
|
columns: list[Column]
|
|
|
|
class Column:
|
|
location: Optional[Location] = None
|
|
name: Token
|
|
type: Type
|
|
```),
|
|
)
|
|
|
|
#let format-ast-nodes(name, base-cls, code) = {
|
|
let nodes = code.text.split(regex(`\n\nclass`.text)).map(n => if n.starts-with("class") {n} else {"class" + n})
|
|
|
|
let cells = nodes.map(n => raw(n, block: true, lang: "python"))
|
|
|
|
if calc.rem(cells.len(), 3) == 2 {
|
|
let last-two = cells.slice(-2)
|
|
cells = cells.slice(0, -2)
|
|
let last = grid.cell(
|
|
colspan: 3,
|
|
stack(
|
|
dir: ltr,
|
|
spacing: 1fr,
|
|
none,
|
|
..last-two,
|
|
none
|
|
)
|
|
)
|
|
cells.push(last)
|
|
}
|
|
|
|
align(center)[*#name*]
|
|
if base-cls != none [Base class: #base-cls]
|
|
|
|
codly-disable()
|
|
grid(
|
|
columns: 3,
|
|
column-gutter: 1fr,
|
|
row-gutter: 2em,
|
|
align: left + top,
|
|
..cells
|
|
)
|
|
codly-enable()
|
|
}
|
|
|
|
#let midas-ast-nodes = stack(
|
|
dir: ttb,
|
|
spacing: 2em,
|
|
..ast-nodes.map(nodes => format-ast-nodes(..nodes))
|
|
)
|
|
|
|
#figure(
|
|
grid(
|
|
columns: 4,
|
|
column-gutter: 3em,
|
|
inset: .5em,
|
|
..token-types-cells,
|
|
),
|
|
caption: [Midas Token Types],
|
|
kind: table,
|
|
supplement: [Table],
|
|
) <tab:token-types>
|
|
|
|
#figure(
|
|
midas-ast-nodes,
|
|
caption: [Midas #acr("AST") Nodes],
|
|
kind: table,
|
|
supplement: [Table],
|
|
) <tab:midas-ast-nodes> |