Rename directory "engines" to "languages"
This commit is contained in:
215
languages/chef/types.ts
Normal file
215
languages/chef/types.ts
Normal file
@@ -0,0 +1,215 @@
|
||||
import { DocumentRange } from "../types";
|
||||
|
||||
/** Type alias for renderer state */
|
||||
export type ChefRS = {
|
||||
stack: string[];
|
||||
currentKitchen: {
|
||||
ingredients: IngredientBox;
|
||||
bowls: { [k: number]: MixingBowl };
|
||||
dishes: { [k: number]: BakingDish };
|
||||
};
|
||||
};
|
||||
|
||||
/********************************
|
||||
******** UTILITY ALIASES *******
|
||||
********************************/
|
||||
|
||||
/** The name of an ingredient */
|
||||
export type IngredientName = string;
|
||||
|
||||
/** Identifier of a mixing bowl */
|
||||
export type BowlId = number;
|
||||
|
||||
/** Indentifier of a baking dish */
|
||||
export type DishId = number;
|
||||
|
||||
/********************************
|
||||
****** RUNTIME CONSTRUCTS ******
|
||||
********************************/
|
||||
|
||||
/** Type of an element in a Chef stack */
|
||||
export type StackItemType = "dry" | "liquid" | "unknown";
|
||||
|
||||
/** An element of Chef's stack constructs */
|
||||
export type StackItem = { value: number; type: StackItemType };
|
||||
|
||||
/** Details of an ingredient - kind and value */
|
||||
export type IngredientItem = {
|
||||
type: StackItemType;
|
||||
value?: number;
|
||||
};
|
||||
|
||||
/** Set of ingredients (global variables) in a Chef program */
|
||||
export type IngredientBox = { [k: IngredientName]: IngredientItem };
|
||||
|
||||
/** A mixing bowl (stack construct) in Chef */
|
||||
export type MixingBowl = StackItem[];
|
||||
|
||||
/** A baking dish (stack construct) in Chef */
|
||||
export type BakingDish = StackItem[];
|
||||
|
||||
/********************************
|
||||
***** PROGRAM INSTRUCTIONS *****
|
||||
********************************/
|
||||
|
||||
/** TAKE: Take numeric input from STDIN and write in ingredient `ing` */
|
||||
export type StdinOp = { code: "STDIN"; ing: IngredientName };
|
||||
|
||||
/** PUT: Push value of ingredient `ing` into `bowlId`'th mixing bowl */
|
||||
export type PushOp = { code: "PUSH"; ing: IngredientName; bowlId: BowlId };
|
||||
|
||||
/** FOLD: Pop value from top of `bowlId`'th mixing bowl and put in ingredient `ing` */
|
||||
export type PopOp = { code: "POP"; ing: IngredientName; bowlId: BowlId };
|
||||
|
||||
/** ADD: Add value of `ing` to top value of bowl `bowlId` and push result onto same bowl */
|
||||
export type AddOp = { code: "ADD"; ing: IngredientName; bowlId: BowlId };
|
||||
|
||||
/** REMOVE: Subtract value of `ing` from top value of bowl `bowlId` and push result onto same bowl */
|
||||
export type SubtractOp = {
|
||||
code: "SUBTRACT";
|
||||
ing: IngredientName;
|
||||
bowlId: BowlId;
|
||||
};
|
||||
|
||||
/** COMBINE: Multiply value of `ing` with top value of bowl `bowlId` and push result onto same bowl */
|
||||
export type MultiplyOp = {
|
||||
code: "MULTIPLY";
|
||||
ing: IngredientName;
|
||||
bowlId: BowlId;
|
||||
};
|
||||
|
||||
/** DIVIDE: Divide top value of bowl `bowlId` by value of `ing` and push result onto same bowl */
|
||||
export type DivideOp = { code: "DIVIDE"; ing: IngredientName; bowlId: BowlId };
|
||||
|
||||
/** ADD DRY: Add values of all dry ingredients and push result on bowl `bowlId` */
|
||||
export type AddDryOp = { code: "ADD-DRY"; bowlId: BowlId };
|
||||
|
||||
/** LIQUEFY: Convert ingredient `ing` to a liquid */
|
||||
export type LiquefyIngOp = { code: "LIQ-ING"; ing: IngredientName };
|
||||
|
||||
/** LIQUEFY CONTENTS: Convert each item in bowl `bowlId` to liquid */
|
||||
export type LiquefyBowlOp = { code: "LIQ-BOWL"; bowlId: BowlId };
|
||||
|
||||
/** STIR BOWL: Rotates top `num` items of bowl `bowlId` topwards (top ingredient goes to ~`num` position) */
|
||||
export type RollStackOp = { code: "ROLL-BOWL"; bowlId: BowlId; num: number };
|
||||
|
||||
/** STIR ING: Rotates top [value of `ing`] items of bowl `bowlId` topwards */
|
||||
export type RollIngOp = {
|
||||
code: "ROLL-ING";
|
||||
bowlId: BowlId;
|
||||
ing: IngredientName;
|
||||
};
|
||||
|
||||
/** MIX: Randomizes the order of items in the bowl `bowlId` */
|
||||
export type RandomizeOp = { code: "RANDOM"; bowlId: BowlId };
|
||||
|
||||
/** CLEAN: Remove all items from the bowl `bowlId` */
|
||||
export type ClearOp = { code: "CLEAR"; bowlId: BowlId };
|
||||
|
||||
/** POUR: Copies all items from `bowlId`'th bowl onto `dishId`'th baking dish, in the same order */
|
||||
export type CopyToDishOp = { code: "COPY"; bowlId: BowlId; dishId: DishId };
|
||||
|
||||
/** VERB: Loop-opener, execute inner steps until `ing` is zero - then continues past loop-closer. */
|
||||
export type LoopOpenOp = {
|
||||
code: "LOOP-OPEN";
|
||||
verb: string;
|
||||
ing: IngredientName;
|
||||
/** Index of corresponding loop-closing op in current method */
|
||||
closer: number;
|
||||
};
|
||||
|
||||
/** VERB: Loop-closer - also decrement value of `ing` by 1 on execution, if provided */
|
||||
export type LoopCloseOp = {
|
||||
code: "LOOP-CLOSE";
|
||||
verb: string;
|
||||
ing?: IngredientName;
|
||||
/** Index of corresponding loop-opener op in current method */
|
||||
opener: number;
|
||||
};
|
||||
|
||||
/** SET ASIDE: Break out of innermost loop and continue past loop-closer */
|
||||
export type LoopBreakOp = {
|
||||
code: "LOOP-BREAK";
|
||||
/** Index of closing op of innermost loop in current method */
|
||||
closer: number;
|
||||
};
|
||||
|
||||
/** SERVE: Run auxiliary recipe and wait until completion */
|
||||
export type FnCallOp = { code: "FNCALL"; recipe: string };
|
||||
|
||||
/** REFRIGERATE: End recipe execution. If provided, print first `num` baking dishes */
|
||||
export type EndOp = { code: "END"; num?: number };
|
||||
|
||||
/** Four main arithmetic operations in Chef */
|
||||
export type ChefArithmeticOp = AddOp | SubtractOp | MultiplyOp | DivideOp;
|
||||
|
||||
/** Kitchen manipulation operations in Chef */
|
||||
export type ChefKitchenOp =
|
||||
| StdinOp
|
||||
| PushOp
|
||||
| PopOp
|
||||
| ChefArithmeticOp
|
||||
| AddDryOp
|
||||
| LiquefyIngOp
|
||||
| RollStackOp
|
||||
| RollIngOp
|
||||
| RandomizeOp
|
||||
| ClearOp
|
||||
| CopyToDishOp
|
||||
| LiquefyIngOp
|
||||
| LiquefyBowlOp;
|
||||
|
||||
/** Flow control operations in Chef */
|
||||
export type ChefFlowControlOp =
|
||||
| LoopOpenOp
|
||||
| LoopCloseOp
|
||||
| LoopBreakOp
|
||||
| FnCallOp
|
||||
| EndOp;
|
||||
|
||||
/** A single operation of a Chef recipe */
|
||||
export type ChefOperation = ChefKitchenOp | ChefFlowControlOp;
|
||||
|
||||
/** List of codes for flow control operations in Chef */
|
||||
const flowControlOpTypes: ChefFlowControlOp["code"][] = [
|
||||
"LOOP-OPEN",
|
||||
"LOOP-CLOSE",
|
||||
"LOOP-BREAK",
|
||||
"FNCALL",
|
||||
"END",
|
||||
];
|
||||
|
||||
/** Check if a Chef op is a flow control operation */
|
||||
export const isFlowControlOp = (op: ChefOperation): op is ChefFlowControlOp => {
|
||||
return flowControlOpTypes.includes(op.code as any);
|
||||
};
|
||||
|
||||
/********************************
|
||||
******* PROGRAM SEMANTICS ******
|
||||
********************************/
|
||||
|
||||
/** Details about serving of recipe */
|
||||
export type ChefRecipeServes = {
|
||||
line: number; // Line number of the "Serves" line
|
||||
num: number; // Number of servings
|
||||
};
|
||||
|
||||
/** Chef operation with its location in code */
|
||||
export type ChefOpWithLocation = {
|
||||
location: DocumentRange;
|
||||
op: ChefOperation;
|
||||
};
|
||||
|
||||
/** A single Chef recipe */
|
||||
export type ChefRecipe = {
|
||||
name: string;
|
||||
ingredients: IngredientBox;
|
||||
method: ChefOpWithLocation[];
|
||||
serves?: ChefRecipeServes;
|
||||
};
|
||||
|
||||
/** A parsed Chef program */
|
||||
export type ChefProgram = {
|
||||
main: ChefRecipe;
|
||||
auxes: { [name: string]: ChefRecipe };
|
||||
};
|
||||
Reference in New Issue
Block a user