Files
TB-Docs/report/appendices/midas_parsing.typ

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>