Skip to content

Commit

Permalink
progress
Browse files Browse the repository at this point in the history
  • Loading branch information
EthanThatOneKid committed Nov 27, 2021
1 parent d9d9c1f commit 8bafc86
Show file tree
Hide file tree
Showing 9 changed files with 166 additions and 125 deletions.
3 changes: 3 additions & 0 deletions lib/cartridge/cartridge.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import { CartridgeEvent } from "./cartridge_event.ts";
*/
Deno.test("hello world", () => {
const cartridge = new Cartridge();
cartridge.on(CartridgeEvent.Load, (event) => {
event.data;
});
cartridge.on(CartridgeEvent.FileStart, console.log);
assertEquals(1, 1);
});
34 changes: 23 additions & 11 deletions lib/cartridge/cartridge.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CartridgeEvent } from "./cartridge_event.ts";
import { CartridgeEvent, CartridgeEventReturnType } from "./cartridge_event.ts";
import type {
CartridgeEventContext,
CartridgeHandler,
Expand All @@ -14,35 +14,35 @@ export class Cartridge {
private handlers: CartridgeHandlerMap = {},
) {}

addEventListener(
public addEventListener(
name: CartridgeEvent.FileStart,
handler: CartridgeHandler<CartridgeEvent.FileStart>,
): void;
addEventListener(
public addEventListener(
name: CartridgeEvent.InlineComment,
handler: CartridgeHandler<CartridgeEvent.InlineComment>,
): void;
addEventListener(
public addEventListener(
name: CartridgeEvent.MultilineComment,
handler: CartridgeHandler<CartridgeEvent.MultilineComment>,
): void;
addEventListener(
public addEventListener(
name: CartridgeEvent.Load,
handler: CartridgeHandler<CartridgeEvent.Load>,
): void;
addEventListener(
public addEventListener(
name: CartridgeEvent.StructOpen,
handler: CartridgeHandler<CartridgeEvent.StructOpen>,
): void;
addEventListener(
public addEventListener(
name: CartridgeEvent.SetProperty,
handler: CartridgeHandler<CartridgeEvent.StructClose>,
): void;
addEventListener(
public addEventListener(
name: CartridgeEvent.FileEnd,
handler: CartridgeHandler<CartridgeEvent.FileEnd>,
): void;
addEventListener(
public addEventListener(
name: CartridgeEvent,
// deno-lint-ignore no-explicit-any
handler: any,
Expand All @@ -53,12 +53,24 @@ export class Cartridge {
/**
* `on` is an alias for `addEventListener`
*/
on = this.addEventListener.bind(this);
public on = this.addEventListener.bind(this);

removeEventListener(name: CartridgeEvent) {
public removeEventListener(name: CartridgeEvent) {
delete this.handlers[name];
}

public async dispatch<T extends CartridgeEvent>(
name: CartridgeEvent,
ctx: CartridgeEventContext<T>,
): Promise<string | null | void> {
const handleEvent = this.handlers[name] as CartridgeHandler<T>;
if (handleEvent === undefined) return null;
const executionResult = handleEvent(ctx);
return executionResult instanceof Promise
? await executionResult
: executionResult;
}

// TODO(@ethanthatonekid): add a `dispatch` method
// @see <https://github.com/EthanThatOneKid/fart/blob/c43f233345/lib/gen/cart.ts#L120>
}
14 changes: 12 additions & 2 deletions lib/cartridge/cartridge_event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,19 @@ export enum CartridgeEvent {
FileEnd = "file_end",
}

export type CartridgeEventReturnType = (
| void
| Promise<void>
| string
| Promise<string>
| null
);

export interface CartridgeEventContext<T extends CartridgeEvent> {
type: T;
code: { append: (code: string) => void };
code: {
append: (code: string) => CartridgeEventReturnType;
};
tokens: Token[];
data: T extends CartridgeEvent.InlineComment ? { comments: string[] }
: T extends CartridgeEvent.MultilineComment ? { comments: string[] }
Expand All @@ -32,7 +42,7 @@ export interface CartridgeEventContext<T extends CartridgeEvent> {
*/
export type CartridgeHandler<T extends CartridgeEvent> = (
event: CartridgeEventContext<T>,
) => void | Promise<void>;
) => CartridgeEventReturnType;

export interface CartridgeHandlerMap {
[CartridgeEvent.FileStart]?: CartridgeHandler<CartridgeEvent.FileStart>;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,54 +1,54 @@
import { assertEquals } from "../../../deps/std/testing.ts";
import { CodeBlock } from "./code_block.ts";

Deno.test("new code block is empty", () => {
assertEquals(new CodeBlock().export(), "");
});

Deno.test("add 3 lines of code to the block", () => {
const block = new CodeBlock();
block.append("a");
block.append("b");
block.append("c");
const expectation = "a\nb\nc";
const reality = block.export();
assertEquals(expectation, reality);
});

Deno.test("add 3 lines of code to the block (indented)", () => {
const block = new CodeBlock();
block.append("a", 0);
block.append("b", 1);
block.append("c", 2);
const expectation = "a\n b\n c";
const reality = block.export();
assertEquals(expectation, reality);
});

Deno.test("join 3 code blocks", () => {
const block1 = new CodeBlock();
block1.append("a", 0);
block1.append("b", 1);
block1.append("c", 2);
const block2 = new CodeBlock();
block2.append("d", 1);
block2.append("e", 0);
block2.append("f", 1);
const block3 = new CodeBlock();
block3.append("g", 2);
block3.append("h", 1);
block3.append("i", 0);
const expectation = `a
b
c
d
e
f
g
h
i`;
const reality = CodeBlock.join(block1, block2, block3);
assertEquals(expectation, reality);
});
import { assertEquals } from "../../deps/std/testing.ts";
import { CodeBlock } from "./code_block.ts";

Deno.test("new code block is empty", () => {
assertEquals(new CodeBlock().export(), "");
});

Deno.test("add 3 lines of code to the block", () => {
const block = new CodeBlock();
block.append("a");
block.append("b");
block.append("c");
const expectation = "a\nb\nc";
const reality = block.export();
assertEquals(expectation, reality);
});

Deno.test("add 3 lines of code to the block (indented)", () => {
const block = new CodeBlock();
block.append("a", 0);
block.append("b", 1);
block.append("c", 2);
const expectation = "a\n b\n c";
const reality = block.export();
assertEquals(expectation, reality);
});

Deno.test("join 3 code blocks", () => {
const block1 = new CodeBlock();
block1.append("a", 0);
block1.append("b", 1);
block1.append("c", 2);
const block2 = new CodeBlock();
block2.append("d", 1);
block2.append("e", 0);
block2.append("f", 1);
const block3 = new CodeBlock();
block3.append("g", 2);
block3.append("h", 1);
block3.append("i", 0);
const expectation = `a
b
c
d
e
f
g
h
i`;
const reality = CodeBlock.join(block1, block2, block3);
assertEquals(expectation, reality);
});
Original file line number Diff line number Diff line change
@@ -1,54 +1,58 @@
import { getIndent, Indent, IndentOption } from "../../indent/mod.ts";

export interface LineOfCode {
content: string;
indentLevel: number;
}

/**
* Represents a block of code.
*/
export class CodeBlock {
public code: LineOfCode[] = [];

append(content: string, indentLevel = 0): void {
this.code.push(
...content.split("\n").map((line) => ({ content: line, indentLevel })),
);
}

export(indent: IndentOption = Indent.Space2): string {
return this.code
.map(({ content, indentLevel }) =>
getIndent(indent, indentLevel) + content
)
.join("\n");
}

/**
* `toString` is an alias for `CodeBlock.export`.
*/
toString = this.export.bind(this);

static join(
indentOrFirstBlock: IndentOption | CodeBlock,
...blocks: CodeBlock[]
): string {
const blockPadding = 2; // lines between each code block
const blockSeparator = "\n".repeat(blockPadding);
const indentSpecified = !(indentOrFirstBlock instanceof CodeBlock);
if (!indentSpecified) blocks = [indentOrFirstBlock, ...blocks];
return blocks
.filter((block) => block !== null)
.reduce(
(file, block, i) => {
const exportedCode = indentSpecified
? block.export(indentOrFirstBlock)
: block.export();
return file + exportedCode +
(blocks.length - 1 > i ? blockSeparator : "");
},
"",
);
}
}
import { getIndent, Indent, IndentOption } from "../indent/mod.ts";

export interface LineOfCode {
content: string;
indentLevel: number;
}

/**
* Represents a block of code.
*/
export class CodeBlock {
public code: LineOfCode[] = [];

/**
* @param content string that is split up by line break
* @param indentLevel depth of nesting; defaults to 0
*/
append(content: string, indentLevel = 0): void {
this.code.push(
...content.split("\n").map((line) => ({ content: line, indentLevel })),
);
}

export(indent: IndentOption = Indent.Space2): string {
return this.code
.map(({ content, indentLevel }) =>
getIndent(indent, indentLevel) + content
)
.join("\n");
}

/**
* `toString` is an alias for `CodeBlock.export`.
*/
toString = this.export.bind(this);

static join(
indentOrFirstBlock: IndentOption | CodeBlock,
...blocks: CodeBlock[]
): string {
const blockPadding = 2; // lines between each code block
const blockSeparator = "\n".repeat(blockPadding);
const indentSpecified = !(indentOrFirstBlock instanceof CodeBlock);
if (!indentSpecified) blocks = [indentOrFirstBlock, ...blocks];
return blocks
.filter((block) => block !== null)
.reduce(
(file, block, i) => {
const exportedCode = indentSpecified
? block.export(indentOrFirstBlock)
: block.export();
const isLast = blocks.length - 1 <= i;
return file + exportedCode + (isLast ? "" : blockSeparator);
},
"",
);
}
}
File renamed without changes.
1 change: 0 additions & 1 deletion lib/text_builder/mod.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export { TextBuilder } from "./text_builder.ts";
export { CodeBlock } from "./code_block/mod.ts";
11 changes: 8 additions & 3 deletions lib/text_builder/text_builder.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { CodeBlock } from "./code_block/mod.ts";
import { CodeBlock } from "../code_block/mod.ts";
import { Indent, IndentOption } from "../indent/mod.ts";
import { Cartridge, CartridgeEvent } from "../cartridge/mod.ts";
import { Token } from "../tokenize/mod.ts";
import { makeFileStartEventContext } from "./utils.ts";

export class TextBuilder {
private blocks: CodeBlock[];
Expand All @@ -18,10 +19,14 @@ export class TextBuilder {
* @todo @ethanthatonekid complete this method
* @see https://github.com/EthanThatOneKid/fart/blob/c43f233345/lib/gen/builder.ts#L20
*/
// deno-lint-ignore no-unused-vars
append(event: CartridgeEvent, tokens: Token[]): void {
async append(event: CartridgeEvent, tokens: Token[]): Promise<void> {
switch (event) {
case CartridgeEvent.FileStart: {
const code = await this.cartridge.dispatch(
CartridgeEvent.FileStart,
makeFileStartEventContext(this.currentBlock, tokens),
);
if (typeof code === "string") this.currentBlock.append(code);
break;
}
case CartridgeEvent.InlineComment: {
Expand Down
8 changes: 8 additions & 0 deletions lib/text_builder/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type { CodeBlock } from "../code_block/mod.ts";
import type { Token } from "../tokenize/mod.ts";
import { CartridgeEvent } from "../cartridge/mod.ts";

export const makeFileStartEventContext = (
code: CodeBlock,
tokens: Token[],
) => ({ type: CartridgeEvent.FileStart, code, tokens, data: null });

1 comment on commit 8bafc86

@deno-deploy
Copy link

@deno-deploy deno-deploy bot commented on 8bafc86 Nov 27, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Failed to deploy:

failed to fetch 'https://raw.githubusercontent.com/EthanThatOneKid/fart/8bafc86a379c5aa9df7a2da4de5e701ae81e1f8c/std/server/worker.ts': HTTP status client error (404 Not Found) for url (https://raw.githubusercontent.com/EthanThatOneKid/fart/8bafc86a379c5aa9df7a2da4de5e701ae81e1f8c/std/server/worker.ts)

Please sign in to comment.