Skip to content

Commit

Permalink
feat: new asm parser
Browse files Browse the repository at this point in the history
WIP WIP WIP
  • Loading branch information
novusnota committed Nov 21, 2024
1 parent 6320faa commit 82a65b1
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 3,052 deletions.
13 changes: 11 additions & 2 deletions src/grammar/ast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,26 @@ export type AstAsmFunctionDef = {
name: AstId;
return: AstType | null;
params: AstTypedParameter[];
instructions: AstAsmInstruction[];
expressions: AstAsmExpression[];
id: number;
loc: SrcInfo;
};

export type AstAsmInstruction = string;
export type AstAsmShuffle = {
args: AstId[];
ret: AstNumber[];
};

export type AstAsmExpression =
| AstAsmExpressionList
| string;

export type AstAsmExpressionList = {
kind: "asm_expr_list";
expressions: AstAsmExpression[];
loc: SrcInfo;
};

export type AstFunctionDecl = {
kind: "function_decl";
attributes: AstFunctionAttribute[];
Expand Down
6 changes: 3 additions & 3 deletions src/grammar/compare.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ import {
AstNode,
AstFuncId,
AstAsmFunctionDef,
AstAsmInstruction,
AstAsmExpression,
AstDestructMapping,
AstStatementDestruct,
} from "./ast";
Expand Down Expand Up @@ -850,8 +850,8 @@ export class AstComparator {
}

private compareAsmInstructions(
instructions1: AstAsmInstruction[],
instructions2: AstAsmInstruction[],
instructions1: AstAsmExpression[],
instructions2: AstAsmExpression[],
): boolean {
if (instructions1.length !== instructions2.length) {
return false;
Expand Down
66 changes: 54 additions & 12 deletions src/grammar/grammar.ohm
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Tact {
ModuleFunction = FunctionDefinition
| AsmFunction

AsmFunction = "asm" AsmShuffle? FunctionAttribute* fun id Parameters (":" Type)? "{" AsmInstruction* "}"
AsmFunction = "asm" AsmShuffle? FunctionAttribute* fun id Parameters (":" Type)? "{" AsmExpression* "}"

ModuleConstant = ConstantDefinition

Expand Down Expand Up @@ -99,20 +99,62 @@ Tact {
| external "(" Parameter? ")" "{" Statement* "}" --externalRegular
| external "(" stringLiteral ")" "{" Statement* "}" --externalComment

AsmInstruction = "[" &#whiteSpace AsmInstruction* "]" &#whiteSpace --internal
| "{" &#whiteSpace AsmInstruction* "}" &#whiteSpace --list
| "({)" &#whiteSpace AsmInstruction* "(})" &#whiteSpace --listNoStateCheck
| ("abort\"" | ".\"" | "+\"" | "\"") (~"\"" any)* "\"" &#whiteSpace --string
| "'" &#whiteSpace asmInstruction --tick
| "char" &#whiteSpace (~whiteSpace any) &#whiteSpace --char
| ("x{" | "B{") ~#whiteSpace hexDigit* ~#whiteSpace ("_" ~#whiteSpace)? "}" &#whiteSpace --hexLiteral
| "b{" ~#whiteSpace binDigit* ~#whiteSpace "}" &#whiteSpace --binLiteral
| asmInstruction --custom
// FIXME: grammar.ts, prettyPrinter.ts, hash.ts, compare.ts
AsmExpression = "{" &#whiteSpace AsmExpression* "}" &#whiteSpace --list
| "SETEXITALT:<{" &#whiteSpace AsmExpression* AsmBlockEnd --setExitAlt
| "ATEXITALT:<{" &#whiteSpace AsmExpression* AsmBlockEnd --atExitAlt
| "ATEXIT:<{" &#whiteSpace AsmExpression* AsmBlockEnd --atExit
| "PROCINLINE:<{" &#whiteSpace AsmExpression* AsmBlockEnd --procInline
| "PROCREF:<{" &#whiteSpace AsmExpression* AsmBlockEnd --procRef
| "PROC:<{" &#whiteSpace AsmExpression* AsmBlockEnd --proc
| "CONT:<{" &#whiteSpace AsmExpression* AsmBlockEnd --cont
| "WHILEBRK:<{" &#whiteSpace AsmExpression* AsmDo AsmBlockEnd --whileBrk
| "WHILE:<{" &#whiteSpace AsmExpression* AsmDo AsmBlockEnd --while
| "UNTILBRK:<{" &#whiteSpace AsmExpression* AsmBlockEnd --untilBrk
| "UNTIL:<{" &#whiteSpace AsmExpression* AsmBlockEnd --until
| "AGAINBRK:<{" &#whiteSpace AsmExpression* AsmBlockEnd --againBrk
| "AGAIN:<{" &#whiteSpace AsmExpression* AsmBlockEnd --again
| "REPEATBRK:<{" &#whiteSpace AsmExpression* AsmBlockEnd --repeatBrk
| "REPEAT:<{" &#whiteSpace AsmExpression* AsmBlockEnd --repeat
| "TRY:<{" &#whiteSpace AsmExpression* "}>CATCH<{" &#whiteSpace AsmExpression* AsmBlockEnd --tryCatch
| "IFNOTJMP:<{" &#whiteSpace AsmExpression* AsmElse AsmBlockEnd --ifNotJmpWithElse
| "IFNOTJMP:<{" &#whiteSpace AsmExpression* AsmBlockEnd --ifNotJmp
| "IFNOT:<{" &#whiteSpace AsmExpression* AsmElse AsmBlockEnd --ifNotWithElse
| "IFNOT:<{" &#whiteSpace AsmExpression* AsmBlockEnd --ifNot
| "IFJMP:<{" &#whiteSpace AsmExpression* AsmElse AsmBlockEnd --ifJmpWithElse
| "IFJMP:<{" &#whiteSpace AsmExpression* AsmBlockEnd --ifJmp
| AsmPrimitive
| "IF:<{" &#whiteSpace AsmExpression* AsmElse AsmBlockEnd --ifWithElse
| "IF:<{" &#whiteSpace AsmExpression* AsmBlockEnd --if
| AsmPrimitive

// Common parts, not standalone instructions or words
AsmElse = "}>ELSE<{" &#whiteSpace AsmExpression* --block
| "}>ELSE:" &#whiteSpace AsmExpression* --colon
AsmDo = "}>DO<{" &#whiteSpace AsmExpression* --block
| "}>DO:" &#whiteSpace AsmExpression* --colon
// TODO(grammar.ts): check that --cont version matches the prefix
AsmBlockEnd = "}>" #asmWord &#whiteSpace --cont
| "}>" &#whiteSpace --base

// Various instructions not forming a block
// TODO(grammar.ts): perform checks for inner contents of the string
AsmPrimitive = "\"" (~"\"" any)* "\"" &#whiteSpace --string
| ("x{" | "B{") ~#whiteSpace hexDigit* ~#whiteSpace ("_" ~#whiteSpace)? "}" &#whiteSpace --hexLiteral
| "b{" ~#whiteSpace binDigit* ~#whiteSpace "}" &#whiteSpace --binLiteral
// TODO(grammar.ts): limit up to 15
| "c" #(digit digit?) &#whiteSpace --controlRegister
// TODO(grammar.ts): limit up to 15
| "s" #(digit digit?) &#whiteSpace --stackRegister
// TODO(grammar.ts): limit up to 255
| digit #(digit digit?)? &#whiteSpace "s()" &#whiteSpace --stackRegister255
| digit+ &#whiteSpace --number
| asmInstruction --custom

// Instructions exclude some begin and end words to ensure correct parse
asmInstruction = ~(("[" | "]" | "{" | "}" | "({)" | "(})") ~asmWord) asmWord
asmInstruction = ~(("{" | "}") ~asmWord) asmWord

// A chunk of non-whitespace characters forms a word in Fift
// A chunk of non-whitespace characters forms a word
asmWord = (~whiteSpace any)+

Statement = StatementLet
Expand Down
16 changes: 1 addition & 15 deletions src/grammar/grammar.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { parse } from "./grammar";
import { AstModule, SrcInfo, __DANGER_resetNodeId } from "./ast";
import { SrcInfo, __DANGER_resetNodeId } from "./ast";
import { loadCases } from "../utils/loadCases";

expect.addSnapshotSerializer({
Expand All @@ -12,20 +12,6 @@ describe("grammar", () => {
__DANGER_resetNodeId();
});

// Test parsing of known Fift projects, wrapped in asm functions of Tact
for (const r of loadCases(__dirname + "/test-asm/")) {
it("should parse " + r.name, () => {
const parsed: AstModule | undefined = parse(
r.code,
"<unknown>",
"user",
);

// Don't produce snapshots
expect(parsed).toBeDefined();
});
}

for (const r of loadCases(__dirname + "/test/")) {
it("should parse " + r.name, () => {
expect(parse(r.code, "<unknown>", "user")).toMatchSnapshot();
Expand Down
18 changes: 13 additions & 5 deletions src/grammar/grammar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ semantics.addOperation<AstNode>("astOfItem", {
_optColon,
optReturnType,
_lbrace,
asmInstructions,
asmExpressions,
_rbrace,
) {
const shuffle = optAsmShuffle.children[0]?.astsOfAsmShuffle() ?? {
Expand All @@ -363,8 +363,8 @@ semantics.addOperation<AstNode>("astOfItem", {
name: funId.astOfExpression(),
return: unwrapOptNode(optReturnType, (t) => t.astOfType()),
params: funParameters.astsOfList(),
instructions: asmInstructions.children.map((s) =>
s.astOfAsmInstruction(),
expressions: asmExpressions.children.map((s) =>
s.astOfAsmExpression(),
),
loc: createRef(this),
});
Expand Down Expand Up @@ -502,11 +502,19 @@ semantics.addOperation<AstNode>("astOfItem", {
},
});

// Beginnings of the possible future AST for Fift-asm
semantics.addOperation<string>("astOfAsmInstruction", {
// TVM instructions
semantics.addOperation<string>("astOfAsmExpression", {
asmInstruction(word) {
// TODO: make a node here!
return word.sourceString;
},
AsmExpression(expression) {
return expression.astOfAsmExpression();
},
AsmExpression_list(_lbrace, _ws1, _arg2, _rbrace, _ws2) {
// TODO: make a node here!
return '';
},
AsmInstruction(instruction) {

Check failure on line 518 in src/grammar/grammar.ts

View workflow job for this annotation

GitHub Actions / test (22, ubuntu-latest)

Object literal may only specify known properties, but 'AsmInstruction' does not exist in type 'TactActionDict<string>'. Did you mean to write 'asmInstruction'?

Check failure on line 518 in src/grammar/grammar.ts

View workflow job for this annotation

GitHub Actions / test (22, ubuntu-latest)

Parameter 'instruction' implicitly has an 'any' type.

Check failure on line 518 in src/grammar/grammar.ts

View workflow job for this annotation

GitHub Actions / test-blueprint (22, macos-latest, bun)

Object literal may only specify known properties, but 'AsmInstruction' does not exist in type 'TactActionDict<string>'. Did you mean to write 'asmInstruction'?

Check failure on line 518 in src/grammar/grammar.ts

View workflow job for this annotation

GitHub Actions / test-blueprint (22, macos-latest, bun)

Parameter 'instruction' implicitly has an 'any' type.

Check failure on line 518 in src/grammar/grammar.ts

View workflow job for this annotation

GitHub Actions / test-blueprint (22, ubuntu-latest, yarn)

Object literal may only specify known properties, but 'AsmInstruction' does not exist in type 'TactActionDict<string>'. Did you mean to write 'asmInstruction'?

Check failure on line 518 in src/grammar/grammar.ts

View workflow job for this annotation

GitHub Actions / test-blueprint (22, ubuntu-latest, yarn)

Parameter 'instruction' implicitly has an 'any' type.

Check failure on line 518 in src/grammar/grammar.ts

View workflow job for this annotation

GitHub Actions / test-blueprint (22, ubuntu-latest, npm)

Object literal may only specify known properties, but 'AsmInstruction' does not exist in type 'TactActionDict<string>'. Did you mean to write 'asmInstruction'?

Check failure on line 518 in src/grammar/grammar.ts

View workflow job for this annotation

GitHub Actions / test-blueprint (22, ubuntu-latest, npm)

Parameter 'instruction' implicitly has an 'any' type.

Check failure on line 518 in src/grammar/grammar.ts

View workflow job for this annotation

GitHub Actions / test-blueprint (22, macos-latest, npm)

Object literal may only specify known properties, but 'AsmInstruction' does not exist in type 'TactActionDict<string>'. Did you mean to write 'asmInstruction'?

Check failure on line 518 in src/grammar/grammar.ts

View workflow job for this annotation

GitHub Actions / test-blueprint (22, macos-latest, npm)

Parameter 'instruction' implicitly has an 'any' type.

Check failure on line 518 in src/grammar/grammar.ts

View workflow job for this annotation

GitHub Actions / test-blueprint (22, ubuntu-latest, bun)

Object literal may only specify known properties, but 'AsmInstruction' does not exist in type 'TactActionDict<string>'. Did you mean to write 'asmInstruction'?

Check failure on line 518 in src/grammar/grammar.ts

View workflow job for this annotation

GitHub Actions / test-blueprint (22, ubuntu-latest, bun)

Parameter 'instruction' implicitly has an 'any' type.

Check failure on line 518 in src/grammar/grammar.ts

View workflow job for this annotation

GitHub Actions / test-blueprint (22, macos-latest, pnpm)

Object literal may only specify known properties, but 'AsmInstruction' does not exist in type 'TactActionDict<string>'. Did you mean to write 'asmInstruction'?

Check failure on line 518 in src/grammar/grammar.ts

View workflow job for this annotation

GitHub Actions / test-blueprint (22, macos-latest, pnpm)

Parameter 'instruction' implicitly has an 'any' type.

Check failure on line 518 in src/grammar/grammar.ts

View workflow job for this annotation

GitHub Actions / test-blueprint (22, ubuntu-latest, pnpm)

Object literal may only specify known properties, but 'AsmInstruction' does not exist in type 'TactActionDict<string>'. Did you mean to write 'asmInstruction'?

Check failure on line 518 in src/grammar/grammar.ts

View workflow job for this annotation

GitHub Actions / test-blueprint (22, ubuntu-latest, pnpm)

Parameter 'instruction' implicitly has an 'any' type.

Check failure on line 518 in src/grammar/grammar.ts

View workflow job for this annotation

GitHub Actions / test (22, macos-latest)

Object literal may only specify known properties, but 'AsmInstruction' does not exist in type 'TactActionDict<string>'. Did you mean to write 'asmInstruction'?

Check failure on line 518 in src/grammar/grammar.ts

View workflow job for this annotation

GitHub Actions / test (22, macos-latest)

Parameter 'instruction' implicitly has an 'any' type.

Check failure on line 518 in src/grammar/grammar.ts

View workflow job for this annotation

GitHub Actions / test-blueprint (22, macos-latest, yarn)

Object literal may only specify known properties, but 'AsmInstruction' does not exist in type 'TactActionDict<string>'. Did you mean to write 'asmInstruction'?

Check failure on line 518 in src/grammar/grammar.ts

View workflow job for this annotation

GitHub Actions / test-blueprint (22, macos-latest, yarn)

Parameter 'instruction' implicitly has an 'any' type.

Check failure on line 518 in src/grammar/grammar.ts

View workflow job for this annotation

GitHub Actions / test-blueprint (22, windows-latest, bun)

Object literal may only specify known properties, but 'AsmInstruction' does not exist in type 'TactActionDict<string>'. Did you mean to write 'asmInstruction'?

Check failure on line 518 in src/grammar/grammar.ts

View workflow job for this annotation

GitHub Actions / test-blueprint (22, windows-latest, bun)

Parameter 'instruction' implicitly has an 'any' type.

Check failure on line 518 in src/grammar/grammar.ts

View workflow job for this annotation

GitHub Actions / test-blueprint (22, windows-latest, yarn)

Object literal may only specify known properties, but 'AsmInstruction' does not exist in type 'TactActionDict<string>'. Did you mean to write 'asmInstruction'?

Check failure on line 518 in src/grammar/grammar.ts

View workflow job for this annotation

GitHub Actions / test-blueprint (22, windows-latest, yarn)

Parameter 'instruction' implicitly has an 'any' type.

Check failure on line 518 in src/grammar/grammar.ts

View workflow job for this annotation

GitHub Actions / test-blueprint (22, windows-latest, pnpm)

Object literal may only specify known properties, but 'AsmInstruction' does not exist in type 'TactActionDict<string>'. Did you mean to write 'asmInstruction'?

Check failure on line 518 in src/grammar/grammar.ts

View workflow job for this annotation

GitHub Actions / test-blueprint (22, windows-latest, pnpm)

Parameter 'instruction' implicitly has an 'any' type.

Check failure on line 518 in src/grammar/grammar.ts

View workflow job for this annotation

GitHub Actions / test (22, windows-latest)

Object literal may only specify known properties, but 'AsmInstruction' does not exist in type 'TactActionDict<string>'. Did you mean to write 'asmInstruction'?

Check failure on line 518 in src/grammar/grammar.ts

View workflow job for this annotation

GitHub Actions / test (22, windows-latest)

Parameter 'instruction' implicitly has an 'any' type.

Check failure on line 518 in src/grammar/grammar.ts

View workflow job for this annotation

GitHub Actions / test (22, windows-latest)

Object literal may only specify known properties, but 'AsmInstruction' does not exist in type 'TactActionDict<string>'. Did you mean to write 'asmInstruction'?

Check failure on line 518 in src/grammar/grammar.ts

View workflow job for this annotation

GitHub Actions / test (22, windows-latest)

Parameter 'instruction' implicitly has an 'any' type.

Check failure on line 518 in src/grammar/grammar.ts

View workflow job for this annotation

GitHub Actions / test-blueprint (22, windows-latest, npm)

Object literal may only specify known properties, but 'AsmInstruction' does not exist in type 'TactActionDict<string>'. Did you mean to write 'asmInstruction'?

Check failure on line 518 in src/grammar/grammar.ts

View workflow job for this annotation

GitHub Actions / test-blueprint (22, windows-latest, npm)

Parameter 'instruction' implicitly has an 'any' type.
return instruction.astOfAsmInstruction();
},
Expand Down
4 changes: 2 additions & 2 deletions src/grammar/hash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {
AstFieldDecl,
AstNode,
AstAsmFunctionDef,
AstAsmInstruction,
AstAsmExpression,
} from "./ast";
import { createHash } from "crypto";
import { throwInternalCompilerError } from "../errors";
Expand Down Expand Up @@ -312,7 +312,7 @@ export class AstHasher {
return hashedStatements.join("|");
}

private hashInstructions(instructions: AstAsmInstruction[]): string {
private hashInstructions(instructions: AstAsmExpression[]): string {
return instructions.join("|");
}

Expand Down
Loading

0 comments on commit 82a65b1

Please sign in to comment.