Skip to content

Commit

Permalink
Add support for while loop blocks in code generator
Browse files Browse the repository at this point in the history
- Introduce WhileLoopBlock type
- Implement while block handler and TypeScript generation
- Add unit tests for while loop blocks
- Update block generator to handle while loops
- Update imports
  • Loading branch information
ozhanefemeral committed Jul 26, 2024
1 parent f4b2fd0 commit 2f048fc
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 1 deletion.
71 changes: 71 additions & 0 deletions src/generator/__tests__/while.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { CodeBlock } from "../../types/blocks";
import { FunctionInfo } from "../../types/common";
import { CodeGeneratorState } from "../../types/generator";
import { createFunctionCallBlock } from "../blocks/function-call";
import { createWhileBlock } from "../blocks/while-block";

describe("While Block Generator", () => {
let initialState: CodeGeneratorState;
let dummyFunctionInfo: FunctionInfo;

beforeEach(() => {
initialState = {
blocks: [],
variables: [],
isAsync: false,
};
dummyFunctionInfo = {
name: "dummyFunction",
returnType: "void",
};
});

test("generates simple while block successfully", () => {
const condition = "x < 10";
const loopBlocks: CodeBlock[] = [
createFunctionCallBlock(dummyFunctionInfo, initialState),
];

const result = createWhileBlock(condition, loopBlocks, initialState);

expect(result).toBeDefined();
expect(result.blockType).toBe("while");
expect(result.condition).toBe(condition);
expect(result.loopBlocks).toEqual(loopBlocks);
expect(result.index).toBe(1); // 0 is the dummy function block
});

test("generates nested while block successfully", () => {
const outerCondition = "x < 10";
const innerWhileBlock = createWhileBlock(
"y < 5",
[createFunctionCallBlock(dummyFunctionInfo, initialState)],
initialState
);

const result = createWhileBlock(
outerCondition,
[innerWhileBlock],
initialState
);

expect(result).toBeDefined();
expect(result.blockType).toBe("while");
expect(result.condition).toBe(outerCondition);
expect(result.loopBlocks).toHaveLength(1);
expect(result.loopBlocks[0]).toBe(innerWhileBlock);
expect(result.index).toBe(2); // 0 is the dummy function block, 1 is the inner while block
});

test("updates state correctly after creating while block", () => {
const condition = "x < 10";
const loopBlocks: CodeBlock[] = [
createFunctionCallBlock(dummyFunctionInfo, initialState),
];

const result = createWhileBlock(condition, loopBlocks, initialState);

expect(initialState.blocks).toHaveLength(2);
expect(initialState.blocks[1]).toBe(result);
});
});
3 changes: 3 additions & 0 deletions src/generator/block-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { CodeBlock } from "types";
import { CodeGeneratorState } from "types/generator";
import { Statement } from "typescript";
import { ifBlockToTypeScript } from "./blocks/if-block";
import { whileBlockToTypeScript } from "./blocks/while-block";

export function blockToTypeScript(
block: CodeBlock,
Expand All @@ -13,5 +14,7 @@ export function blockToTypeScript(
return functionCallBlockToTypeScript(block, state);
case "if":
return ifBlockToTypeScript(block, state);
case "while":
return whileBlockToTypeScript(block, state);
}
}
37 changes: 37 additions & 0 deletions src/generator/blocks/while-block.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { CodeBlock, WhileLoopBlock } from "../../types/blocks";
import { CodeGeneratorState } from "../../types/generator";
import { factory, Statement } from "typescript";
import { blockToTypeScript } from "../block-generator";

export function whileBlockToTypeScript(
block: WhileLoopBlock,
state: CodeGeneratorState
): Statement {
const loopBody = factory.createBlock(
block.loopBlocks.map((b) => blockToTypeScript(b, state))
);

return factory.createWhileStatement(
factory.createIdentifier(block.condition),
loopBody
);
}

export function createWhileBlock(
condition: string,
loopBlocks: CodeBlock[],
state: CodeGeneratorState
): WhileLoopBlock {
const index = state.blocks.length;

const block: WhileLoopBlock = {
condition,
loopBlocks,
index,
blockType: "while",
};

state.blocks.push(block);

return block;
}
1 change: 1 addition & 0 deletions src/generator/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from "./code-generator";
export * from "./utils";
export * from "./blocks/function-call";
export * from "./blocks/if-block";
export * from "./blocks/while-block";
3 changes: 3 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ export {
functionCallBlockToTypeScript,
ifBlockToTypeScript,
createIfBlock,
createWhileBlock,
whileBlockToTypeScript,
} from "./generator";

export type {
Expand All @@ -27,6 +29,7 @@ export type {
ElseIfBlock,
IfBlock,
CodeBlock,
WhileLoopBlock,
} from "./types";

export { scanCodebase } from "./codebase-scanner";
Expand Down
8 changes: 7 additions & 1 deletion src/types/blocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,11 @@ export interface ElseBlock {
blocks: CodeBlock[];
}

export interface WhileLoopBlock extends Block {
condition: string;
loopBlocks: CodeBlock[];
blockType: "while";
}

// Add more block types as implemented
export type CodeBlock = FunctionCallBlock | IfBlock;
export type CodeBlock = FunctionCallBlock | IfBlock | WhileLoopBlock;

0 comments on commit 2f048fc

Please sign in to comment.