UNPKG

@kipper/target-js

Version:

The JavaScript target for the Kipper compiler 🦊

149 lines (123 loc) • 5.63 kB
/** * The TypeScript target-specific built-ins generator for generating the code that allows for the use of built-in * functions. * @since 0.10.0 */ import type { BuiltInFunction, BuiltInVariable, InternalFunction, KipperProgramContext, TranslatedCodeLine, } from "@kipper/core"; import { KipperTargetBuiltInGenerator } from "@kipper/core"; import { createJSFunctionSignature, getJSFunctionSignature } from "./tools"; import { TargetJS } from "./target"; /** * Generates a JavaScript function from the given signature and body. * @param signature The signature of the function. * @param body The body of the function. * @param ignoreParams Whether or not to ignore the parameters of the function. * @since 0.10.0 */ export function genJSFunction( signature: { identifier: string; params: string[] }, body: string, ignoreParams: boolean = false, ): Array<TranslatedCodeLine> { return [[signature.identifier, ":", " ", createJSFunctionSignature(signature, ignoreParams), " ", body]]; } /** * Generates a JavaScript local or global variable from the given variable and value. * @param varSpec The variable to generate. * @param value The value of the variable. */ export function genJSVariable(varSpec: BuiltInVariable, value: string): TranslatedCodeLine { if (varSpec.local) { return ["const", " ", TargetJS.getBuiltInIdentifier(varSpec), " ", "=", " ", value, ";"]; } return [varSpec.identifier, ":", " ", value]; } /** * The TypeScript target-specific built-ins generator for generating the code that allows for the use of built-in * functions. * @since 0.10.0 */ export class JavaScriptTargetBuiltInGenerator extends KipperTargetBuiltInGenerator { async numToStr(funcSpec: InternalFunction): Promise<Array<TranslatedCodeLine>> { const signature = getJSFunctionSignature(funcSpec); const convArgIdentifier = signature.params[0]; return genJSFunction(signature, `{ return (${convArgIdentifier}).toString(); }`); } async boolToStr(funcSpec: InternalFunction): Promise<Array<TranslatedCodeLine>> { const signature = getJSFunctionSignature(funcSpec); const convArgIdentifier = signature.params[0]; return genJSFunction(signature, `{ return \`\${${convArgIdentifier}}\`; }`); } async voidToStr(funcSpec: InternalFunction): Promise<Array<TranslatedCodeLine>> { const signature = getJSFunctionSignature(funcSpec); return genJSFunction(signature, `{ return "void"; }`, true); } async nullToStr(funcSpec: InternalFunction): Promise<Array<TranslatedCodeLine>> { const signature = getJSFunctionSignature(funcSpec); return genJSFunction(signature, `{ return "null"; }`, true); } async undefinedToStr(funcSpec: InternalFunction): Promise<Array<TranslatedCodeLine>> { const signature = getJSFunctionSignature(funcSpec); return genJSFunction(signature, `{ return "undefined"; }`, true); } async strToNum(funcSpec: InternalFunction): Promise<Array<TranslatedCodeLine>> { const signature = getJSFunctionSignature(funcSpec); const convArgIdentifier = signature.params[0]; return genJSFunction(signature, `{ return parseInt(${convArgIdentifier}); }`); } async boolToNum(funcSpec: InternalFunction): Promise<Array<TranslatedCodeLine>> { const signature = getJSFunctionSignature(funcSpec); const convArgIdentifier = signature.params[0]; return genJSFunction(signature, `{ return ${convArgIdentifier} ? 1 : 0; }`); } async slice(funcSpec: InternalFunction): Promise<Array<TranslatedCodeLine>> { const signature = getJSFunctionSignature(funcSpec); const objLikeIdentifier = signature.params[0]; const startIdentifier = signature.params[1]; const endIdentifier = signature.params[2]; return genJSFunction( signature, `{ return ${objLikeIdentifier} ? ${objLikeIdentifier}.slice(${startIdentifier}, ${endIdentifier}) : ${objLikeIdentifier}; }`, ); } async index(funcSpec: InternalFunction): Promise<Array<TranslatedCodeLine>> { const signature = getJSFunctionSignature(funcSpec); const arrayLikeIdentifier = signature.params[0]; const indexIdentifier = signature.params[1]; return genJSFunction( signature, `{ if (${indexIdentifier} >= ${arrayLikeIdentifier}.length) ` + `throw new __kipper.IndexError(\`Index '\${${indexIdentifier}}' out of bonds of array-like.\`); ` + `return ${arrayLikeIdentifier}[${indexIdentifier}]; }`, ); } async repeatString(funcSpec: InternalFunction): Promise<Array<TranslatedCodeLine>> { const signature = getJSFunctionSignature(funcSpec); const toRepeatIdentifier = signature.params[0]; const timesIdentifier = signature.params[1]; return genJSFunction(signature, `{ return ${toRepeatIdentifier}.repeat(${timesIdentifier}); }`); } async print(funcSpec: BuiltInFunction): Promise<Array<TranslatedCodeLine>> { const signature = getJSFunctionSignature(funcSpec); const printArgIdentifier = signature.params[0]; // Define the function signature and its body. We will simply use 'console.log(msg)' for printing out IO. return genJSFunction(signature, `{ console.log(${printArgIdentifier}); }`); } async len(funcSpec: BuiltInFunction): Promise<Array<TranslatedCodeLine>> { const signature = getJSFunctionSignature(funcSpec); const lenArgIdentifier = signature.params[0]; return genJSFunction(signature, `{ return ${lenArgIdentifier}.length; }`); } async __name__(varSpec: BuiltInVariable, programCtx: KipperProgramContext): Promise<Array<TranslatedCodeLine>> { return [genJSVariable(varSpec, `"${programCtx.fileName}"`)]; } async NaN(varSpec: BuiltInVariable): Promise<Array<TranslatedCodeLine>> { return [genJSVariable(varSpec, "NaN")]; } }