From b70ba48e0a8d2ea57df315ded16dca728373b1ae Mon Sep 17 00:00:00 2001 From: sfja Date: Mon, 3 Feb 2025 22:34:45 +0100 Subject: [PATCH] finish mir def --- compiler/middle/mir.ts | 93 +++++++++++++++++++++++++++++++++-------- compiler/parse/lexer.ts | 3 +- 2 files changed, 77 insertions(+), 19 deletions(-) diff --git a/compiler/middle/mir.ts b/compiler/middle/mir.ts index 66f465f..8d5200e 100644 --- a/compiler/middle/mir.ts +++ b/compiler/middle/mir.ts @@ -1,4 +1,11 @@ import { Span } from "../diagnostics.ts"; +import { IdBase } from "../ids.ts"; + +export type Block = { + id: BlockId; + stmts: Stmt[]; + terminator?: Terminator; +}; export type Stmt = { kind: StmtKind; @@ -6,22 +13,37 @@ export type Stmt = { export type StmtKind = | { tag: "error" } - | { tag: "assign" } & AssignStmt - | { tag: "fake_read" } & FakeReadStmt - | { tag: "deinit" } & DeinitStmt - | { tag: "live" } & LiveStmt - | { tag: "dead" } & DeadStmt - | { tag: "mention" } & MentionStmt; + | { tag: "assign"; place: Place; rval: RVal } + | { tag: "fake_read"; place: Place } + | { tag: "deinit"; place: Place } + | { tag: "live"; local: LocalId } + | { tag: "dead"; local: LocalId } + | { tag: "mention"; place: Place }; -export type AssignStmt = { place: Place; rval: RVal }; -export type FakeReadStmt = { place: Place }; -export type DeinitStmt = { place: Place }; -export type LiveStmt = { local: Local }; -export type DeadStmt = { local: Local }; -export type MentionStmt = { place: Place }; +export type Terminator = { + kind: TerminatorKind; +}; + +export type TerminatorKind = + | { tag: "goto"; target: BlockId } + | { + tag: "switch"; + discr: Operand; + targets: SwitchTarget[]; + otherwise: BlockId; + } + | { tag: "return" } + | { tag: "unreachable" } + | { tag: "drop"; place: Place; target: BlockId } + | { tag: "call"; func: Operand; args: Operand[]; dest: Operand }; + +export type SwitchTarget = { + value: number; + target: BlockId; +}; export type Place = { - local: Local; + local: LocalId; proj: ProjElem[]; }; @@ -30,11 +52,48 @@ export type ProjElem = | { tag: "deref" } | { tag: "repeat" } | { tag: "field"; fieldIdx: number } - | { tag: "index": local: Local } - | { tag: } + | { tag: "index"; local: LocalId } + | { tag: "downcast"; variantIdx: number }; // https://doc.rust-lang.org/beta/nightly-rustc/rustc_middle/mir/enum.Rvalue.html -export type RVal = {}; +export type RVal = + | { tag: "use"; operand: Operand } + | { tag: "repeat"; operand: Operand; length: Const } + | { tag: "ref"; place: Place; mut: boolean } + | { tag: "ptr"; place: Place; mut: boolean } + | { tag: "binary"; binaryType: BinaryType; left: Operand; right: Operand } + | { tag: "unary"; unaryType: UnaryType; operand: Operand }; -export type Local = {}; +export type BinaryType = + | "add" + | "sub" + | "mul" + | "div" + | "rem" + | "xor" + | "and" + | "or" + | "shl" + | "shr" + | "eq" + | "ne" + | "lt" + | "lte" + | "gt" + | "gte"; +export type UnaryType = "not" | "neg"; + +export type Operand = + | { tag: "copy"; place: Place } + | { tag: "move"; place: Place } + | { tag: "const"; val: Const }; + +export type Const = + | { tag: "null" } + | { tag: "int"; value: number } + | { tag: "bool"; value: boolean } + | { tag: "string"; value: string }; + +export type LocalId = IdBase & { readonly _: unique symbol }; +export type BlockId = IdBase & { readonly _: unique symbol }; diff --git a/compiler/parse/lexer.ts b/compiler/parse/lexer.ts index 019e8ca..3c7e390 100644 --- a/compiler/parse/lexer.ts +++ b/compiler/parse/lexer.ts @@ -1,6 +1,5 @@ -import { Ctx } from "../ctx.ts"; +import { Ctx, File } from "../ctx.ts"; import { Pos, Span } from "../diagnostics.ts"; -import { File } from "../ids.ts"; import { ControlFlow, range } from "../util.ts"; import { Token, TokenIter } from "./token.ts";