Rename directory "engines" to "languages"
This commit is contained in:
25
languages/chef/tests/index.test.ts
Normal file
25
languages/chef/tests/index.test.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { executeProgram, readTestProgram } from "../../test-utils";
|
||||
import ChefRuntime from "../runtime";
|
||||
|
||||
/** Absolute path to directory of sample programs */
|
||||
const DIRNAME = __dirname + "/samples";
|
||||
|
||||
describe("Test programs", () => {
|
||||
test("Hello World Souffle", async () => {
|
||||
const code = readTestProgram(DIRNAME, "hello-world-souffle");
|
||||
const result = await executeProgram(new ChefRuntime(), code);
|
||||
expect(result.output).toBe("Hello world!");
|
||||
});
|
||||
|
||||
test("Fibonacci Du Fromage", async () => {
|
||||
const code = readTestProgram(DIRNAME, "fibonacci-fromage");
|
||||
const result = await executeProgram(new ChefRuntime(), code, "10");
|
||||
expect(result.output).toBe(" 1 1 2 3 5 8 13 21 34 55");
|
||||
});
|
||||
|
||||
test("Hello World Cake with Chocolate Sauce", async () => {
|
||||
const code = readTestProgram(DIRNAME, "hello-world-cake");
|
||||
const result = await executeProgram(new ChefRuntime(), code);
|
||||
expect(result.output).toBe("Hello world!");
|
||||
});
|
||||
});
|
389
languages/chef/tests/parser-core.test.ts
Normal file
389
languages/chef/tests/parser-core.test.ts
Normal file
@ -0,0 +1,389 @@
|
||||
import { ChefOperation, StackItemType } from "../types";
|
||||
import { JumpAddressPlaceholder } from "../parser/constants";
|
||||
import { parseIngredientItem, parseMethodStep } from "../parser/core";
|
||||
|
||||
/** Test the result of parsing an ingredient definition string */
|
||||
const testIngredientItem = (
|
||||
str: string,
|
||||
name: string,
|
||||
value: number | undefined,
|
||||
type: StackItemType
|
||||
) => {
|
||||
const result = parseIngredientItem(str);
|
||||
expect(result.name).toBe(name);
|
||||
expect(result.item.value).toBe(value);
|
||||
expect(result.item.type).toBe(type);
|
||||
};
|
||||
|
||||
/** Test the result of parsing a method operation string */
|
||||
const testMethodOp = (str: string, op: ChefOperation) => {
|
||||
const result = parseMethodStep(str);
|
||||
expect(result).toEqual(op);
|
||||
};
|
||||
|
||||
describe("Parsing ingredient definitions", () => {
|
||||
test("dry ingredients", () => {
|
||||
testIngredientItem("10 g sugar", "sugar", 10, "dry");
|
||||
testIngredientItem("2 kg dry almonds", "dry almonds", 2, "dry");
|
||||
testIngredientItem("1 pinch chilli powder", "chilli powder", 1, "dry");
|
||||
testIngredientItem("3 pinches chilli powder", "chilli powder", 3, "dry");
|
||||
});
|
||||
|
||||
test("liquid ingredients", () => {
|
||||
testIngredientItem("10 ml essence", "essence", 10, "liquid");
|
||||
testIngredientItem("2 l milk", "milk", 2, "liquid");
|
||||
testIngredientItem("1 dash oil", "oil", 1, "liquid");
|
||||
testIngredientItem("3 dashes oil", "oil", 3, "liquid");
|
||||
});
|
||||
|
||||
test("dry-or-liquid ingredients", () => {
|
||||
testIngredientItem("1 cup flour", "flour", 1, "unknown");
|
||||
testIngredientItem("2 cups flour", "flour", 2, "unknown");
|
||||
testIngredientItem("1 teaspoon salt", "salt", 1, "unknown");
|
||||
testIngredientItem("2 teaspoons salt", "salt", 2, "unknown");
|
||||
testIngredientItem("1 tablespoon ketchup", "ketchup", 1, "unknown");
|
||||
testIngredientItem("2 tablespoons ketchup", "ketchup", 2, "unknown");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Parsing method instructions", () => {
|
||||
test("Take `ing` from refrigerator", () => {
|
||||
testMethodOp("Take chilli powder from refrigerator", {
|
||||
code: "STDIN",
|
||||
ing: "chilli powder",
|
||||
});
|
||||
});
|
||||
|
||||
test("Put `ing` into [the] [`nth`] mixing bowl", () => {
|
||||
testMethodOp("Put dry ice into the mixing bowl", {
|
||||
code: "PUSH",
|
||||
ing: "dry ice",
|
||||
bowlId: 1,
|
||||
});
|
||||
testMethodOp("Put dry ice into the 21nd mixing bowl", {
|
||||
code: "PUSH",
|
||||
ing: "dry ice",
|
||||
bowlId: 21,
|
||||
});
|
||||
testMethodOp("Put dry ice into mixing bowl", {
|
||||
code: "PUSH",
|
||||
ing: "dry ice",
|
||||
bowlId: 1,
|
||||
});
|
||||
testMethodOp("Put dry ice into 21nd mixing bowl", {
|
||||
code: "PUSH",
|
||||
ing: "dry ice",
|
||||
bowlId: 21,
|
||||
});
|
||||
});
|
||||
|
||||
test("Fold `ing` into [the] [`nth`] mixing bowl", () => {
|
||||
testMethodOp("Fold dry ice into the mixing bowl", {
|
||||
code: "POP",
|
||||
ing: "dry ice",
|
||||
bowlId: 1,
|
||||
});
|
||||
testMethodOp("Fold dry ice into the 21nd mixing bowl", {
|
||||
code: "POP",
|
||||
ing: "dry ice",
|
||||
bowlId: 21,
|
||||
});
|
||||
testMethodOp("Fold dry ice into mixing bowl", {
|
||||
code: "POP",
|
||||
ing: "dry ice",
|
||||
bowlId: 1,
|
||||
});
|
||||
testMethodOp("Fold dry ice into 21nd mixing bowl", {
|
||||
code: "POP",
|
||||
ing: "dry ice",
|
||||
bowlId: 21,
|
||||
});
|
||||
});
|
||||
|
||||
test("Add `ing` [to [the] [`nth`] mixing bowl]", () => {
|
||||
testMethodOp("Add black salt", {
|
||||
code: "ADD",
|
||||
ing: "black salt",
|
||||
bowlId: 1,
|
||||
});
|
||||
testMethodOp("Add black salt to the mixing bowl", {
|
||||
code: "ADD",
|
||||
ing: "black salt",
|
||||
bowlId: 1,
|
||||
});
|
||||
testMethodOp("Add black salt to the 100th mixing bowl", {
|
||||
code: "ADD",
|
||||
ing: "black salt",
|
||||
bowlId: 100,
|
||||
});
|
||||
testMethodOp("Add black salt to mixing bowl", {
|
||||
code: "ADD",
|
||||
ing: "black salt",
|
||||
bowlId: 1,
|
||||
});
|
||||
testMethodOp("Add black salt to 100th mixing bowl", {
|
||||
code: "ADD",
|
||||
ing: "black salt",
|
||||
bowlId: 100,
|
||||
});
|
||||
});
|
||||
|
||||
test("Remove `ing` [from [the] [`nth`] mixing bowl]", () => {
|
||||
testMethodOp("Remove black salt", {
|
||||
code: "SUBTRACT",
|
||||
ing: "black salt",
|
||||
bowlId: 1,
|
||||
});
|
||||
testMethodOp("Remove black salt from the mixing bowl", {
|
||||
code: "SUBTRACT",
|
||||
ing: "black salt",
|
||||
bowlId: 1,
|
||||
});
|
||||
testMethodOp("Remove black salt from the 100th mixing bowl", {
|
||||
code: "SUBTRACT",
|
||||
ing: "black salt",
|
||||
bowlId: 100,
|
||||
});
|
||||
testMethodOp("Remove black salt from mixing bowl", {
|
||||
code: "SUBTRACT",
|
||||
ing: "black salt",
|
||||
bowlId: 1,
|
||||
});
|
||||
testMethodOp("Remove black salt from 100th mixing bowl", {
|
||||
code: "SUBTRACT",
|
||||
ing: "black salt",
|
||||
bowlId: 100,
|
||||
});
|
||||
});
|
||||
|
||||
test("Combine `ing` [into [the] [`nth`] mixing bowl]", () => {
|
||||
testMethodOp("Combine black salt", {
|
||||
code: "MULTIPLY",
|
||||
ing: "black salt",
|
||||
bowlId: 1,
|
||||
});
|
||||
testMethodOp("Combine black salt into the mixing bowl", {
|
||||
code: "MULTIPLY",
|
||||
ing: "black salt",
|
||||
bowlId: 1,
|
||||
});
|
||||
testMethodOp("Combine black salt into the 2nd mixing bowl", {
|
||||
code: "MULTIPLY",
|
||||
ing: "black salt",
|
||||
bowlId: 2,
|
||||
});
|
||||
testMethodOp("Combine black salt into mixing bowl", {
|
||||
code: "MULTIPLY",
|
||||
ing: "black salt",
|
||||
bowlId: 1,
|
||||
});
|
||||
testMethodOp("Combine black salt into 2nd mixing bowl", {
|
||||
code: "MULTIPLY",
|
||||
ing: "black salt",
|
||||
bowlId: 2,
|
||||
});
|
||||
});
|
||||
|
||||
test("Divide `ing` [into [the] [`nth`] mixing bowl]", () => {
|
||||
testMethodOp("Divide black salt", {
|
||||
code: "DIVIDE",
|
||||
ing: "black salt",
|
||||
bowlId: 1,
|
||||
});
|
||||
testMethodOp("Divide black salt into the mixing bowl", {
|
||||
code: "DIVIDE",
|
||||
ing: "black salt",
|
||||
bowlId: 1,
|
||||
});
|
||||
testMethodOp("Divide black salt into the 23rd mixing bowl", {
|
||||
code: "DIVIDE",
|
||||
ing: "black salt",
|
||||
bowlId: 23,
|
||||
});
|
||||
testMethodOp("Divide black salt into mixing bowl", {
|
||||
code: "DIVIDE",
|
||||
ing: "black salt",
|
||||
bowlId: 1,
|
||||
});
|
||||
testMethodOp("Divide black salt into 23rd mixing bowl", {
|
||||
code: "DIVIDE",
|
||||
ing: "black salt",
|
||||
bowlId: 23,
|
||||
});
|
||||
});
|
||||
|
||||
test("Add dry ingredients [to [the] [`nth`] mixing bowl]", () => {
|
||||
testMethodOp("Add dry ingredients", {
|
||||
code: "ADD-DRY",
|
||||
bowlId: 1,
|
||||
});
|
||||
testMethodOp("Add dry ingredients to mixing bowl", {
|
||||
code: "ADD-DRY",
|
||||
bowlId: 1,
|
||||
});
|
||||
testMethodOp("Add dry ingredients to 100th mixing bowl", {
|
||||
code: "ADD-DRY",
|
||||
bowlId: 100,
|
||||
});
|
||||
testMethodOp("Add dry ingredients to mixing bowl", {
|
||||
code: "ADD-DRY",
|
||||
bowlId: 1,
|
||||
});
|
||||
testMethodOp("Add dry ingredients to 100th mixing bowl", {
|
||||
code: "ADD-DRY",
|
||||
bowlId: 100,
|
||||
});
|
||||
});
|
||||
|
||||
test("Liquefy `ingredient`", () => {
|
||||
testMethodOp("Liquefy nitrogen gas", {
|
||||
code: "LIQ-ING",
|
||||
ing: "nitrogen gas",
|
||||
});
|
||||
testMethodOp("Liquefy the nitrogen gas", {
|
||||
code: "LIQ-ING",
|
||||
ing: "nitrogen gas",
|
||||
});
|
||||
testMethodOp("Liquefy themed leaves", {
|
||||
code: "LIQ-ING",
|
||||
ing: "themed leaves",
|
||||
});
|
||||
});
|
||||
|
||||
test("Liquefy [the] contents of the [`nth`] mixing bowl", () => {
|
||||
testMethodOp("Liquefy the contents of the mixing bowl", {
|
||||
code: "LIQ-BOWL",
|
||||
bowlId: 1,
|
||||
});
|
||||
testMethodOp("Liquefy the contents of the 22nd mixing bowl", {
|
||||
code: "LIQ-BOWL",
|
||||
bowlId: 22,
|
||||
});
|
||||
testMethodOp("Liquefy contents of the mixing bowl", {
|
||||
code: "LIQ-BOWL",
|
||||
bowlId: 1,
|
||||
});
|
||||
testMethodOp("Liquefy contents of the 22nd mixing bowl", {
|
||||
code: "LIQ-BOWL",
|
||||
bowlId: 22,
|
||||
});
|
||||
});
|
||||
|
||||
test("Stir [the [`nth`] mixing bowl] for `num` minutes", () => {
|
||||
testMethodOp("Stir for 5 minutes", {
|
||||
code: "ROLL-BOWL",
|
||||
bowlId: 1,
|
||||
num: 5,
|
||||
});
|
||||
testMethodOp("Stir the mixing bowl for 22 minutes", {
|
||||
code: "ROLL-BOWL",
|
||||
bowlId: 1,
|
||||
num: 22,
|
||||
});
|
||||
testMethodOp("Stir the 3rd mixing bowl for 0 minutes", {
|
||||
code: "ROLL-BOWL",
|
||||
bowlId: 3,
|
||||
num: 0,
|
||||
});
|
||||
});
|
||||
|
||||
test("Stir `ing` into the [`nth`] mixing bowl", () => {
|
||||
testMethodOp("Stir dry ice into the mixing bowl", {
|
||||
code: "ROLL-ING",
|
||||
bowlId: 1,
|
||||
ing: "dry ice",
|
||||
});
|
||||
testMethodOp("Stir dry ice into the 2nd mixing bowl", {
|
||||
code: "ROLL-ING",
|
||||
bowlId: 2,
|
||||
ing: "dry ice",
|
||||
});
|
||||
});
|
||||
|
||||
test("Mix [the [`nth`] mixing bowl] well", () => {
|
||||
testMethodOp("Mix well", { code: "RANDOM", bowlId: 1 });
|
||||
testMethodOp("Mix the mixing bowl well", { code: "RANDOM", bowlId: 1 });
|
||||
testMethodOp("Mix the 21st mixing bowl well", {
|
||||
code: "RANDOM",
|
||||
bowlId: 21,
|
||||
});
|
||||
});
|
||||
|
||||
test("Clean [the] [`nth`] mixing bowl", () => {
|
||||
testMethodOp("Clean the mixing bowl", { code: "CLEAR", bowlId: 1 });
|
||||
testMethodOp("Clean the 21st mixing bowl", { code: "CLEAR", bowlId: 21 });
|
||||
testMethodOp("Clean mixing bowl", { code: "CLEAR", bowlId: 1 });
|
||||
testMethodOp("Clean 21st mixing bowl", { code: "CLEAR", bowlId: 21 });
|
||||
});
|
||||
|
||||
test("Pour contents of the [`nth`] mixing bowl into the [`pth`] baking dish", () => {
|
||||
testMethodOp("Pour contents of the mixing bowl into the baking dish", {
|
||||
code: "COPY",
|
||||
bowlId: 1,
|
||||
dishId: 1,
|
||||
});
|
||||
testMethodOp(
|
||||
"Pour contents of the 2nd mixing bowl into the 100th baking dish",
|
||||
{
|
||||
code: "COPY",
|
||||
bowlId: 2,
|
||||
dishId: 100,
|
||||
}
|
||||
);
|
||||
testMethodOp(
|
||||
"Pour contents of the mixing bowl into the 100th baking dish",
|
||||
{
|
||||
code: "COPY",
|
||||
bowlId: 1,
|
||||
dishId: 100,
|
||||
}
|
||||
);
|
||||
testMethodOp("Pour contents of the 2nd mixing bowl into the baking dish", {
|
||||
code: "COPY",
|
||||
bowlId: 2,
|
||||
dishId: 1,
|
||||
});
|
||||
});
|
||||
|
||||
test("`Verb` the `ingredient`", () => {
|
||||
testMethodOp("Bake the dough", {
|
||||
code: "LOOP-OPEN",
|
||||
verb: "bake",
|
||||
ing: "dough",
|
||||
closer: JumpAddressPlaceholder,
|
||||
});
|
||||
});
|
||||
|
||||
test("`Verb` [the `ingredient`] until `verbed`", () => {
|
||||
testMethodOp("Destroy until bake", {
|
||||
code: "LOOP-CLOSE",
|
||||
verb: "bake",
|
||||
opener: JumpAddressPlaceholder,
|
||||
});
|
||||
testMethodOp("Destroy the tomato ketchup until bake", {
|
||||
code: "LOOP-CLOSE",
|
||||
verb: "bake",
|
||||
ing: "tomato ketchup",
|
||||
opener: JumpAddressPlaceholder,
|
||||
});
|
||||
});
|
||||
|
||||
test("Set aside", () => {
|
||||
testMethodOp("Set aside", {
|
||||
code: "LOOP-BREAK",
|
||||
closer: JumpAddressPlaceholder,
|
||||
});
|
||||
});
|
||||
|
||||
test("Serve with `auxiliary-recipe`", () => {
|
||||
testMethodOp("Serve with chocolate sauce", {
|
||||
code: "FNCALL",
|
||||
recipe: "chocolate sauce",
|
||||
});
|
||||
});
|
||||
|
||||
test("Refrigerate [for `num` hours]", () => {
|
||||
testMethodOp("Refrigerate", { code: "END" });
|
||||
testMethodOp("Refrigerate for 2 hours", { code: "END", num: 2 });
|
||||
});
|
||||
});
|
159
languages/chef/tests/parser-index.test.ts
Normal file
159
languages/chef/tests/parser-index.test.ts
Normal file
@ -0,0 +1,159 @@
|
||||
import { readTestProgram } from "../../test-utils";
|
||||
import { parseProgram } from "../parser";
|
||||
import { LoopCloseOp, LoopOpenOp } from "../types";
|
||||
|
||||
/** Absolute path to directory of sample programs */
|
||||
const DIRNAME = __dirname + "/samples";
|
||||
|
||||
describe("Parsing entire programs", () => {
|
||||
test("Hello World Souffle", () => {
|
||||
const code = readTestProgram(DIRNAME, "hello-world-souffle");
|
||||
const program = parseProgram(code);
|
||||
expect(program.auxes).toEqual({});
|
||||
expect(program.main.name).toBe("Hello World Souffle");
|
||||
expect(program.main.serves).toEqual({ line: 19, num: 1 });
|
||||
|
||||
// Lightly check list of ingredients
|
||||
const ingredients = program.main.ingredients;
|
||||
expect(Object.keys(ingredients).length).toBe(9);
|
||||
expect(ingredients["haricot beans"].type).toBe("dry");
|
||||
expect(ingredients["haricot beans"].value).toBe(72);
|
||||
expect(ingredients["eggs"].type).toBe("unknown");
|
||||
expect(ingredients["eggs"].value).toBe(101);
|
||||
expect(ingredients["oil"].type).toBe("unknown");
|
||||
expect(ingredients["oil"].value).toBe(111);
|
||||
expect(ingredients["water"].type).toBe("liquid");
|
||||
expect(ingredients["water"].value).toBe(119);
|
||||
|
||||
// Check method operations
|
||||
const method = program.main.method;
|
||||
expect(method.length).toBe(14);
|
||||
expect(method.slice(0, 12).every((m) => m.op.code === "PUSH")).toBe(true);
|
||||
expect(method[12].op.code).toBe("LIQ-BOWL");
|
||||
expect(method[12].location.line).toBe(17);
|
||||
expect([403, 404]).toContain(method[12].location.charRange?.start);
|
||||
expect([439, 440]).toContain(method[12].location.charRange?.end);
|
||||
expect(method[13].op.code).toBe("COPY");
|
||||
expect(method[13].location.line).toBe(17);
|
||||
});
|
||||
|
||||
test("Fibonacci Du Fromage", () => {
|
||||
const code = readTestProgram(DIRNAME, "fibonacci-fromage");
|
||||
const program = parseProgram(code);
|
||||
expect(program.main.name).toBe("Fibonacci Du Fromage");
|
||||
expect(program.main.serves).toEqual({ line: 30, num: 1 });
|
||||
|
||||
// ====== MAIN RECIPE =======
|
||||
// Check the list of ingredients
|
||||
const mainIngredients = program.main.ingredients;
|
||||
expect(Object.keys(mainIngredients).length).toBe(2);
|
||||
expect(mainIngredients["numbers"]).toEqual({ type: "dry", value: 5 });
|
||||
expect(mainIngredients["cheese"]).toEqual({ type: "dry", value: 1 });
|
||||
|
||||
// Check the method instructions
|
||||
const mainMethod = program.main.method;
|
||||
expect(mainMethod.length).toBe(19);
|
||||
expect(mainMethod[0].op.code).toBe("STDIN");
|
||||
expect(mainMethod[0].location.line).toBe(10);
|
||||
expect(mainMethod[0].location.charRange?.start).toBe(0);
|
||||
expect(mainMethod[0].location.charRange?.end).toBe(30);
|
||||
expect(mainMethod[18].op.code).toBe("COPY");
|
||||
expect(mainMethod[18].location.line).toBe(28);
|
||||
expect(mainMethod[18].location.charRange?.start).toBe(0);
|
||||
expect(mainMethod[18].location.charRange?.end).toBe(57);
|
||||
|
||||
// Check loop jump addresses in method
|
||||
const mainOpener1 = mainMethod[8].op as LoopOpenOp;
|
||||
const mainCloser1 = mainMethod[10].op as LoopCloseOp;
|
||||
expect(mainOpener1.closer).toBe(10);
|
||||
expect(mainCloser1.opener).toBe(8);
|
||||
const mainOpener2 = mainMethod[14].op as LoopOpenOp;
|
||||
const mainCloser2 = mainMethod[17].op as LoopCloseOp;
|
||||
expect(mainOpener2.closer).toBe(17);
|
||||
expect(mainCloser2.opener).toBe(14);
|
||||
|
||||
// ====== AUXILIARY RECIPE =========
|
||||
expect(Object.keys(program.auxes)).toEqual(["salt and pepper"]);
|
||||
const auxIngredients = program.auxes["salt and pepper"].ingredients;
|
||||
|
||||
// Check the list of ingredients
|
||||
expect(Object.keys(auxIngredients).length).toBe(2);
|
||||
expect(auxIngredients["salt"]).toEqual({ type: "dry", value: 1 });
|
||||
expect(auxIngredients["pepper"]).toEqual({ type: "dry", value: 1 });
|
||||
|
||||
// Check the method instructions
|
||||
const auxMethod = program.auxes["salt and pepper"].method;
|
||||
expect(auxMethod.length).toBe(5);
|
||||
expect(auxMethod[0].op.code).toBe("POP");
|
||||
expect(auxMethod[0].location.line).toBe(39);
|
||||
expect(auxMethod[0].location.charRange?.start).toBe(0);
|
||||
expect(auxMethod[0].location.charRange?.end).toBe(26);
|
||||
expect(auxMethod[4].op.code).toBe("ADD");
|
||||
expect(auxMethod[4].location.line).toBe(43);
|
||||
expect(auxMethod[4].location.charRange?.start).toBe(0);
|
||||
expect(auxMethod[4].location.charRange?.end).toBe(10);
|
||||
});
|
||||
|
||||
test("Hello World Cake with Chocolate Sauce", () => {
|
||||
const code = readTestProgram(DIRNAME, "hello-world-cake");
|
||||
const program = parseProgram(code);
|
||||
expect(program.main.name).toBe("Hello World Cake with Chocolate sauce");
|
||||
expect(program.main.serves).toBeUndefined();
|
||||
|
||||
// ====== MAIN RECIPE =======
|
||||
// Lightly check the list of ingredients
|
||||
const mainIngredients = program.main.ingredients;
|
||||
expect(Object.keys(mainIngredients).length).toBe(9);
|
||||
expect(mainIngredients["butter"]).toEqual({ type: "dry", value: 100 });
|
||||
expect(mainIngredients["baking powder"]).toEqual({ type: "dry", value: 2 });
|
||||
expect(mainIngredients["cake mixture"]).toEqual({ type: "dry", value: 0 });
|
||||
|
||||
// Check the method instructions
|
||||
const mainMethod = program.main.method;
|
||||
expect(mainMethod.length).toBe(15);
|
||||
expect(mainMethod[0].op.code).toBe("PUSH");
|
||||
expect(mainMethod[0].location.line).toBe(27);
|
||||
expect(mainMethod[0].location.charRange?.start).toBe(0);
|
||||
expect(mainMethod[0].location.charRange?.end).toBe(40);
|
||||
expect(mainMethod[14].op.code).toBe("FNCALL");
|
||||
expect(mainMethod[14].location.line).toBe(41);
|
||||
expect(mainMethod[14].location.charRange?.start).toBe(0);
|
||||
expect(mainMethod[14].location.charRange?.end).toBe(26);
|
||||
|
||||
// Check loop jump addresses in method
|
||||
const mainOpener = mainMethod[12].op as LoopOpenOp;
|
||||
const mainCloser = mainMethod[13].op as LoopCloseOp;
|
||||
expect(mainOpener.closer).toBe(13);
|
||||
expect(mainCloser.opener).toBe(12);
|
||||
|
||||
// ====== AUXILIARY RECIPE =========
|
||||
expect(Object.keys(program.auxes)).toEqual(["chocolate sauce"]);
|
||||
const auxIngredients = program.auxes["chocolate sauce"].ingredients;
|
||||
|
||||
// Check the list of ingredients
|
||||
expect(Object.keys(auxIngredients).length).toBe(5);
|
||||
expect(auxIngredients["sugar"]).toEqual({ type: "dry", value: 111 });
|
||||
expect(auxIngredients["heated double cream"]).toEqual({
|
||||
type: "liquid",
|
||||
value: 108,
|
||||
});
|
||||
|
||||
// Check the method instructions
|
||||
const auxMethod = program.auxes["chocolate sauce"].method;
|
||||
expect(auxMethod.length).toBe(13);
|
||||
expect(auxMethod[0].op.code).toBe("CLEAR");
|
||||
expect(auxMethod[0].location.line).toBe(53);
|
||||
expect(auxMethod[0].location.charRange?.start).toBe(0);
|
||||
expect(auxMethod[0].location.charRange?.end).toBe(21);
|
||||
expect(auxMethod[12].op.code).toBe("END");
|
||||
expect(auxMethod[12].location.line).toBe(65);
|
||||
expect(auxMethod[12].location.charRange?.start).toBe(0);
|
||||
expect(auxMethod[12].location.charRange?.end).toBe(22);
|
||||
|
||||
// Check loop jump addresses in method
|
||||
const auxOpener = auxMethod[4].op as LoopOpenOp;
|
||||
const auxCloser = auxMethod[5].op as LoopCloseOp;
|
||||
expect(auxOpener.closer).toBe(5);
|
||||
expect(auxCloser.opener).toBe(4);
|
||||
});
|
||||
});
|
44
languages/chef/tests/samples/fibonacci-fromage.txt
Normal file
44
languages/chef/tests/samples/fibonacci-fromage.txt
Normal file
@ -0,0 +1,44 @@
|
||||
Fibonacci Du Fromage.
|
||||
|
||||
==== Source: https://github.com/joostrijneveld/Chef-Interpreter/blob/master/ChefInterpreter/FibonacciDuFromage ====
|
||||
An improvement on the Fibonacci with Caramel Sauce recipe. Much less for the sweettooths, much more correct.
|
||||
|
||||
Ingredients.
|
||||
5 g numbers
|
||||
1 g cheese
|
||||
|
||||
Method.
|
||||
Take numbers from refrigerator.
|
||||
Put cheese into mixing bowl.
|
||||
Put cheese into mixing bowl.
|
||||
Put numbers into 2nd mixing bowl.
|
||||
Remove cheese from 2nd mixing bowl.
|
||||
Remove cheese from 2nd mixing bowl.
|
||||
Fold numbers into 2nd mixing bowl.
|
||||
Put numbers into 2nd mixing bowl.
|
||||
Calculate the numbers.
|
||||
Serve with salt and pepper.
|
||||
Ponder the numbers until calculate.
|
||||
Add cheese to 2nd mixing bowl.
|
||||
Add cheese to 2nd mixing bowl.
|
||||
Fold numbers into 2nd mixing bowl.
|
||||
Move the numbers.
|
||||
Fold cheese into mixing bowl.
|
||||
Put cheese into 2nd mixing bowl.
|
||||
Transfer the numbers until move.
|
||||
Pour contents of the 2nd mixing bowl into the baking dish.
|
||||
|
||||
Serves 1.
|
||||
|
||||
salt and pepper.
|
||||
|
||||
Ingredients.
|
||||
1 g salt
|
||||
1 g pepper
|
||||
|
||||
Method.
|
||||
Fold salt into mixing bowl.
|
||||
Fold pepper into mixing bowl.
|
||||
Clean mixing bowl.
|
||||
Put salt into mixing bowl.
|
||||
Add pepper.
|
66
languages/chef/tests/samples/hello-world-cake.txt
Normal file
66
languages/chef/tests/samples/hello-world-cake.txt
Normal file
@ -0,0 +1,66 @@
|
||||
Hello World Cake with Chocolate sauce.
|
||||
|
||||
==== Source: Mike Worth, http://www.mike-worth.com/2013/03/31/baking-a-hello-world-cake/ ====
|
||||
This prints hello world, while being tastier than Hello World Souffle. The main
|
||||
chef makes a " world!" cake, which he puts in the baking dish. When he gets the
|
||||
sous chef to make the "Hello" chocolate sauce, it gets put into the baking dish
|
||||
and then the whole thing is printed when he refrigerates the sauce. When
|
||||
actually cooking, I'm interpreting the chocolate sauce baking dish to be
|
||||
separate from the cake one and Liquify to mean either melt or blend depending on
|
||||
context.
|
||||
|
||||
Ingredients.
|
||||
33 g chocolate chips
|
||||
100 g butter
|
||||
54 ml double cream
|
||||
2 pinches baking powder
|
||||
114 g sugar
|
||||
111 ml beaten eggs
|
||||
119 g flour
|
||||
32 g cocoa powder
|
||||
0 g cake mixture
|
||||
|
||||
Cooking time: 25 minutes.
|
||||
|
||||
Pre-heat oven to 180 degrees Celsius.
|
||||
|
||||
Method.
|
||||
Put chocolate chips into the mixing bowl.
|
||||
Put butter into the mixing bowl.
|
||||
Put sugar into the mixing bowl.
|
||||
Put beaten eggs into the mixing bowl.
|
||||
Put flour into the mixing bowl.
|
||||
Put baking powder into the mixing bowl.
|
||||
Put cocoa powder into the mixing bowl.
|
||||
Stir the mixing bowl for 1 minute.
|
||||
Combine double cream into the mixing bowl.
|
||||
Stir the mixing bowl for 4 minutes.
|
||||
Liquefy the contents of the mixing bowl.
|
||||
Pour contents of the mixing bowl into the baking dish.
|
||||
bake the cake mixture.
|
||||
Wait until bake.
|
||||
Serve with chocolate sauce.
|
||||
|
||||
chocolate sauce.
|
||||
|
||||
Ingredients.
|
||||
111 g sugar
|
||||
108 ml hot water
|
||||
108 ml heated double cream
|
||||
101 g dark chocolate
|
||||
72 g milk chocolate
|
||||
|
||||
Method.
|
||||
Clean the mixing bowl.
|
||||
Put sugar into the mixing bowl.
|
||||
Put hot water into the mixing bowl.
|
||||
Put heated double cream into the mixing bowl.
|
||||
dissolve the sugar.
|
||||
agitate the sugar until dissolve.
|
||||
Liquefy the dark chocolate.
|
||||
Put dark chocolate into the mixing bowl.
|
||||
Liquefy the milk chocolate.
|
||||
Put milk chocolate into the mixing bowl.
|
||||
Liquefy contents of the mixing bowl.
|
||||
Pour contents of the mixing bowl into the baking dish.
|
||||
Refrigerate for 1 hour.
|
20
languages/chef/tests/samples/hello-world-souffle.txt
Normal file
20
languages/chef/tests/samples/hello-world-souffle.txt
Normal file
@ -0,0 +1,20 @@
|
||||
Hello World Souffle.
|
||||
|
||||
==== Source: David Morgan-Mar, https://www.dangermouse.net/esoteric/chef_hello.html ====
|
||||
This recipe prints the immortal words "Hello world!", in a basically brute force way. It also makes a lot of food for one person.
|
||||
|
||||
Ingredients.
|
||||
72 g haricot beans
|
||||
101 eggs
|
||||
108 g lard
|
||||
111 cups oil
|
||||
32 zucchinis
|
||||
119 ml water
|
||||
114 g red salmon
|
||||
100 g dijon mustard
|
||||
33 potatoes
|
||||
|
||||
Method.
|
||||
Put potatoes into the mixing bowl. Put dijon mustard into the mixing bowl. Put lard into the mixing bowl. Put red salmon into the mixing bowl. Put oil into the mixing bowl. Put water into the mixing bowl. Put zucchinis into the mixing bowl. Put oil into the mixing bowl. Put lard into the mixing bowl. Put lard into the mixing bowl. Put eggs into the mixing bowl. Put haricot beans into the mixing bowl. Liquefy contents of the mixing bowl. Pour contents of the mixing bowl into the baking dish.
|
||||
|
||||
Serves 1.
|
Reference in New Issue
Block a user