Skip to content

Commit

Permalink
big changes
Browse files Browse the repository at this point in the history
  • Loading branch information
JeanJPNM committed Apr 17, 2024
1 parent f751439 commit 91582fe
Show file tree
Hide file tree
Showing 60 changed files with 1,720 additions and 1,268 deletions.
95 changes: 95 additions & 0 deletions compiler/src/BlockCursor.ts
@@ -0,0 +1,95 @@
import { CompilerError } from "./CompilerError";
import {
Block,
BreakInstruction,
InstructionNode,
TBlockEndInstruction,
TBlockInstruction,
} from "./flow";
import { Location, es } from "./types";

export interface IBlockCursor {
currentBlock: Block;
position: InstructionNode | undefined;

/**
* Adds an instruction after the instruction currently pointed at by the
* cursor
*/
addInstruction(instruction: TBlockInstruction): void;
/** Removes the instruction currently pointed at by the cursor */
removeInstruction(): void;

/** Attempts to connect a block to the current block pointed at by this cursor. */
connectBlock(block: Block, node: es.Node): void;

setEndInstruction(instruction: TBlockEndInstruction): void;

discardFollowing(): void;
}

export type CursorMode = "create" | "edit";

export class BlockCursor implements IBlockCursor {
private _currentBlock: Block;
position: InstructionNode | undefined;

constructor(
public mode: CursorMode,
currentBlock: Block,
) {
this._currentBlock = currentBlock;
}

get currentBlock(): Block {
return this._currentBlock;
}

set currentBlock(block: Block) {
this._currentBlock = block;
this.position = undefined;
}

addInstruction(instruction: TBlockInstruction) {
if (this.mode === "create" && this.currentBlock.endInstruction) return;

if (this.position === undefined) {
this.currentBlock.instructions.add(instruction);
return;
}

this.currentBlock.instructions.insertAfter(this.position, instruction);
this.position = this.position.next;
}

removeInstruction() {
if (this.position === undefined) {
this.currentBlock.instructions.removeLast();
return;
}

const { previous } = this.position;
this.currentBlock.instructions.remove(this.position);
this.position = previous;
}

connectBlock(block: Block, loc: Location) {
if (block === this.currentBlock) return;
this.setEndInstruction(new BreakInstruction(block, loc));
this.currentBlock = block;
}

setEndInstruction(instruction: TBlockEndInstruction) {
if (this.mode === "create" && this.currentBlock.endInstruction) return;
this.currentBlock.endInstruction = instruction;
}

discardFollowing(): void {
if (!this.position)
throw new CompilerError(
"Attempted to discard instructions without a position",
);
this.position.next = undefined;
this.currentBlock.instructions.tail = this.position;
}
}
13 changes: 6 additions & 7 deletions compiler/src/Compiler.ts
Expand Up @@ -5,7 +5,7 @@ import { createGlobalScope } from "./modules";
import { es, IInstruction, THandler } from "./types";
import { hideRedundantJumps } from "./utils";
import { CompilerContext } from "./CompilerContext";
import { HandlerContext } from "./HandlerContext";
import { BlockCursor } from "./BlockCursor";
import { Block, EndInstruction, Graph } from "./flow";

type THandlerMap = { [k in es.Node["type"]]?: THandler };
Expand Down Expand Up @@ -45,14 +45,13 @@ export class Compiler {
// the script, since it is treated as a module
const scope = globalScope.createScope();

const rootContext = new HandlerContext(
new Block([]),
new Block([], new EndInstruction()),
);
const entryBlock = new Block();
const exitBlock = new Block(new EndInstruction());
const cursor = new BlockCursor("create", entryBlock);

c.handle(scope, rootContext, program);
c.handle(scope, cursor, program);

const rootGraph = Graph.from(rootContext.entry, rootContext.exit);
const rootGraph = Graph.from(entryBlock, exitBlock);

const inst = rootGraph.toMlog(c);

Expand Down
74 changes: 41 additions & 33 deletions compiler/src/CompilerContext.ts
Expand Up @@ -9,11 +9,10 @@ import {
TDeclarationKind,
} from "./types";
import { CompilerOptions } from "./Compiler";
import { HandlerContext } from "./HandlerContext";
import { nullId } from "./utils";
import { Block } from "./flow";
import { LiteralValue, StoreValue } from "./values";
import { ImmutableId, ValueId } from "./flow/id";
import { GlobalId, ImmutableId, ValueId } from "./flow/id";
import { IBlockCursor } from "./BlockCursor";

export interface ICompilerContext {
readonly compactNames: boolean;
Expand All @@ -23,30 +22,32 @@ export interface ICompilerContext {
setValueName(id: ValueId, name: string): void;
getValueId(name: string): ValueId | undefined;

getValue(id: ValueId): IValue | undefined;
getValue(id: ValueId | undefined): IValue | undefined;
getValueOrTemp(id: ValueId): IValue;
setValue(id: ValueId, value: IValue): void;
registerValue(value: IValue): ImmutableId;
setAlias(alias: ImmutableId, original: ImmutableId): void;
setGlobalAlias(alias: ImmutableId, original: GlobalId): void;

handle(
scope: IScope,
handlerContext: HandlerContext,
cursor: IBlockCursor,
node: es.Node,
handler?: THandler,
arg?: unknown,
): ImmutableId;

handleWrite(
scope: IScope,
handlerContext: HandlerContext,
cursor: IBlockCursor,
node: es.Node,
handler?: THandler,
arg?: unknown,
): TWriteCallback;

handleDeclaration(
scope: IScope,
handlerContext: HandlerContext,
cursor: IBlockCursor,
node: es.Node,
kind: TDeclarationKind,
init?: ImmutableId,
Expand All @@ -63,19 +64,19 @@ export interface ICompilerContext {
*/
handleMany<T extends es.Node>(
scope: IScope,
handlerContext: HandlerContext,
cursor: IBlockCursor,
nodes: T[],
handler?: (node: T) => ValueId,
): ImmutableId;
}

export class CompilerContext implements ICompilerContext {
protected handlers: Partial<Record<es.Node["type"], THandler>> = handlers;
// 0 is reserved for LiteralValue(null)
#tempCounter = 1;
#tempCounter = 0;
#names = new Map<ValueId, string>();
#ids = new Map<string, ValueId>();
#values = new Map<ValueId, IValue>();
#aliases = new Map<ImmutableId, ValueId>();

readonly compactNames: boolean;
readonly sourcemap: boolean;
Expand All @@ -88,8 +89,15 @@ export class CompilerContext implements ICompilerContext {
this.sourcemap = sourcemap;
this.setValue(nullId, new LiteralValue(null));
}
getValue(id: ValueId): IValue | undefined {
return this.#values.get(id);

#resolveId(id: ValueId): ValueId {
if (id.type === "global") return id;
return this.#aliases.get(id) ?? id;
}

getValue(id: ValueId | undefined): IValue | undefined {
if (!id) return;
return this.#values.get(this.#resolveId(id));
}

getValueOrTemp(id: ValueId): IValue {
Expand All @@ -102,7 +110,7 @@ export class CompilerContext implements ICompilerContext {
return store;
}
setValue(id: ValueId, value: IValue): void {
this.#values.set(id, value);
this.#values.set(this.#resolveId(id), value);
}

registerValue(value: IValue): ImmutableId {
Expand All @@ -111,11 +119,22 @@ export class CompilerContext implements ICompilerContext {
return id;
}

setAlias(alias: ImmutableId, original: ImmutableId): void {
const id = this.#aliases.get(original) ?? original;
this.#aliases.set(alias, id);
}

setGlobalAlias(alias: ImmutableId, original: GlobalId): void {
// const id = this.#aliases.get(original) ?? original;
this.#aliases.set(alias, original);
}

getValueName(id: ValueId): string | undefined {
return this.#names.get(id);
return this.#names.get(this.#resolveId(id));
}

setValueName(id: ValueId, name: string): void {
id = this.#resolveId(id);
this.#names.set(id, name);
this.#ids.set(name, id);
}
Expand All @@ -126,14 +145,14 @@ export class CompilerContext implements ICompilerContext {

handle(
scope: IScope,
handlerContext: HandlerContext,
cursor: IBlockCursor,
node: es.Node,
handler = this.handlers[node.type],
arg?: unknown,
): ImmutableId {
try {
if (!handler) throw new CompilerError("Missing handler for " + node.type);
const result = handler(this, scope, handlerContext, node, arg);
const result = handler(this, scope, cursor, node, arg);
// if (this.sourcemap) return appendSourceLocations(result, node);
return result;
} catch (error) {
Expand All @@ -146,21 +165,15 @@ export class CompilerContext implements ICompilerContext {

handleWrite(
scope: IScope,
handlerContext: HandlerContext,
cursor: IBlockCursor,
node: es.Node,
handler = this.handlers[node.type],
arg?: unknown,
): TWriteCallback {
try {
if (!handler?.handleWrite)
throw new CompilerError("Missing handler for " + node.type);
const result = handler.handleWrite(
this,
scope,
handlerContext,
node,
arg,
);
const result = handler.handleWrite(this, scope, cursor, node, arg);
// if (this.sourcemap) return appendSourceLocations(result, node);
return result;
} catch (error) {
Expand All @@ -173,7 +186,7 @@ export class CompilerContext implements ICompilerContext {

handleDeclaration(
scope: IScope,
handlerContext: HandlerContext,
cursor: IBlockCursor,
node: es.Node,
kind: TDeclarationKind,
init?: ImmutableId,
Expand All @@ -182,7 +195,7 @@ export class CompilerContext implements ICompilerContext {
try {
if (!handler?.handleDeclaration)
throw new CompilerError("Missing handler for " + node.type);
handler.handleDeclaration(this, scope, handlerContext, node, kind, init);
handler.handleDeclaration(this, scope, cursor, node, kind, init);
} catch (error) {
if (error instanceof CompilerError) {
error.loc ??= node.loc as es.SourceLocation;
Expand All @@ -201,17 +214,12 @@ export class CompilerContext implements ICompilerContext {
*/
handleMany<T extends es.Node>(
scope: IScope,
handlerContext: HandlerContext,
cursor: IBlockCursor,
nodes: T[],
handler?: (node: T) => ImmutableId,
): ImmutableId {
for (const node of hoistedFunctionNodes(nodes)) {
this.handle(
scope,
handlerContext,
node,
handler && (() => handler(node)),
);
this.handle(scope, cursor, node, handler && (() => handler(node)));
}
return nullId;
}
Expand Down
12 changes: 6 additions & 6 deletions compiler/src/CompilerError.ts
@@ -1,4 +1,4 @@
import { es } from "./types";
import { Location, es } from "./types";

/**
* Error thrown by the babel parser.
Expand All @@ -15,7 +15,7 @@ export interface ParsingError extends Error {
}

type CompilerErrorSource =
| es.Node
| Location
| es.SourceLocation
| {
line: number;
Expand Down Expand Up @@ -43,15 +43,15 @@ export class CompilerError extends Error {

set loc(value: CompilerErrorSource | undefined) {
if (!value) return;
if ("type" in value) {
this._loc = value.loc as es.SourceLocation;
} else if ("start" in value) {
if ("start" in value) {
this._loc = value;
} else {
} else if ("line" in value) {
this._loc = {
start: value,
end: value,
};
} else {
this._loc = value.loc!;
}
}

Expand Down
35 changes: 0 additions & 35 deletions compiler/src/HandlerContext.ts

This file was deleted.

0 comments on commit 91582fe

Please sign in to comment.