UNPKG

delphirtl

Version:
376 lines 20.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Output = exports.TextFile = exports.sLineBreak = exports.TObject = void 0; exports.hasInstanceMethod = hasInstanceMethod; exports.hasPrototypeMethodFromConstructor = hasPrototypeMethodFromConstructor; exports.getParamCount = getParamCount; exports.UNUSED = UNUSED; exports.getLauncher = getLauncher; exports.sleep = sleep; exports.Sleep = sleep; exports.ParamStr = ParamStr; exports.getParamStr = ParamStr; exports.AssignFile = AssignFile; exports.Assign = AssignFile; exports.Append = Append; exports.CloseFile = CloseFile; exports.Close = CloseFile; exports.Rewrite = Rewrite; exports.Write = Write; exports.WriteLn = WriteLn; exports.Halt = Halt; const assert = require("assert"); require("./dateutils"); // Import all the prototypes into delphirtl /** * Implements Delphi TObject semantics where you have to call .Free() to destroy the object. * Has AfterConstruction and BeforeDestruction methods, which can be overridden. * * @category RTL */ class TObject { constructor() { this._isDestroyed = false; } /** * performs cleanup tasks and destroys the object */ destroy() { if (this._isDestroyed) return; this.BeforeDestruction(); // place future destruction code below // end destruction code above this._isDestroyed = true; } Destroy() { this.destroy(); } /** * Calls destroy to perform any cleanup tasks. Call Free() to destroy the object, so as to retain Delphi-style AfterConstruction and BeforeDestruction semantics. */ free() { this.destroy(); } /** * Destroys the object, maintaining Delphi-style AfterConstruction and BeforeDestruction semantics. */ Free() { this.free(); } /** * Creates a new instance of the class. To create a new constructor, declare the constructor(args) method * and call the super constructor. Then, to instantiate the class, call YourClass.Create(args) instead of new YourClass(args), * so as to retain Delphi-style AfterConstruction and BeforeDestruction semantics. * * @param args * @constructor */ static Create(...args) { const instance = new this(...args); if (instance.AfterConstruction && typeof instance.AfterConstruction === 'function') { instance.AfterConstruction(); } return instance; } /** * Responds after the last constructor has executed. * * AfterConstruction is called automatically after the object's last constructor has executed. Do not call it explicitly in your applications. * * The AfterConstruction method implemented in TObject does nothing. Override this method when creating a class that performs an action after the object is created. */ AfterConstruction() { } /** * Responds before the first destructor executes. * * BeforeDestruction is called automatically before the object's first destructor executes. Do not call it explicitly in your applications. * * The BeforeDestruction method implemented in TObject does nothing. Override this method when creating a class that performs an action before the object is destroyed. */ BeforeDestruction() { } } exports.TObject = TObject; const sLineBreak = process.platform === 'win32' ? '\r\n' : '\n'; exports.sLineBreak = sLineBreak; /** * Gets the process arguments * * @returns {string[]} * @category RTL */ function getProcessArgs() { const result = process.argv.slice(1); return result; } /** * Returns true if the named method exists as a function on the constructor's prototype * or on the given instance. * * This helper is useful for checking prototype-augmented methods added at runtime. */ function hasPrototypeMethodFromConstructor(constructorFn, name) { if (!constructorFn || typeof constructorFn !== 'function') return false; return typeof constructorFn.prototype?.[name] === 'function'; } function hasInstanceMethod(instance, name) { if (!instance || typeof instance !== 'object') return false; return typeof instance[name] === 'function'; } /** * Returns the number of parameters passed to the app * * @returns {number} * @category RTL */ function getParamCount() { const processArgs = getProcessArgs(); return processArgs.length - 1; } /** * Returns the index'th argument passed to the app * * @param {number} index * @returns {string} * @category RTL */ function ParamStr(index) { assert(index >= 0); const processArgs = getProcessArgs(); if (index < 0) { return ""; } else { return processArgs[index]; } } /** * * @returns the launcher, ie, node.exe or something that can run Javascript... * @category RTL */ function getLauncher() { const result = process.argv[0]; return result; } /** * Sleeps for the specified number of millisecs. * * @async * @param {number} ms number of ms to sleep * @returns {unknown} * @category RTL */ async function sleep(ms) { // Ensure we do not resolve earlier than requested due to timer rounding const delay = Math.max(0, Math.ceil(ms)); return new Promise(resolve => setTimeout(resolve, delay + 1)); } /** * Used for ignoring any unused types, variables, so that the compiler doesn't complain. * * @param {...*} x any number of parameters to ignore * @category RTL */ function UNUSED(...x) { } const fs = require('fs'); class TextFile { constructor() { this.filename = null; this.stream = null; this.mode = null; } open(mode = "w") { if (!this.filename) throw new Error("Filename not assigned"); this.mode = mode; // Treat Delphi pseudo-filenames for console specially: if (this.filename === 'CONOUT$') { // use process.stdout as the stream this.stream = process.stdout; return; } if (mode === "w") { fs.writeFileSync(this.filename, ""); // truncate/create } else { // mode 'a': create if not exists if (!fs.existsSync(this.filename)) fs.writeFileSync(this.filename, ""); } } write(text) { if (!this.mode) throw new Error("File not opened"); if (this.stream) { // process.stdout (a Writable) accepts strings this.stream.write(text); return; } if (this.mode === "w") { fs.appendFileSync(this.filename, text); } else if (this.mode === "a") { fs.appendFileSync(this.filename, text); } } writelnText(text) { this.write(text + sLineBreak); } close() { if (this.stream) { // Do not end process.stdout, otherwise, future writes in the same process will fail if (this.stream !== process.stdout) { this.stream.end(); } this.stream = null; } this.filename = null; this.mode = null; } } exports.TextFile = TextFile; // Delphi-style functions /** * Associates the name of an external file with a file class * * @param {TextFile} outFile * @param {string} filename * @returns {void} * @category RTL */ function AssignFile(outFile, filename) { if (!(outFile instanceof TextFile)) throw new TypeError('First arg must be TextFile'); outFile.filename = filename; } /** * Creates a new file and opens it. * * @param {TextFile} outFile * @returns {void} * @category RTL */ function Rewrite(outFile) { if (!(outFile instanceof TextFile)) throw new TypeError('RewriteFile expects a TextFile'); outFile.open('w'); } /** * Prepares an existing file for adding text to the end. * * @param {TextFile} outFile * @returns {void} * @category RTL */ function Append(outFile) { if (!(outFile instanceof TextFile)) throw new TypeError('Append expects a TextFile'); outFile.open('a'); } /** * Terminates the association between a file variable and an external disk file. * * @param {TextFile} outFile * @returns {void} * @category RTL */ function CloseFile(outFile) { if (!(outFile instanceof TextFile)) throw new TypeError('CloseFile expects a TextFile'); outFile.close(); } function concatArgs(args, startIndex = 0) { return Array.prototype.slice.call(args, startIndex).map(x => { if (x === null || x === undefined) return ''; return typeof x === 'object' ? JSON.stringify(x) : String(x); }).join(''); } /** * * Writes to a text file. * * Writeln is an extension of the Write procedure, as it is defined for text files. * * The syntax shown here for the Writeln procedure is illustrates that WriteLn can take a variable number of arguments. * * After executing Write, Writeln writes an end-of-line marker (line feed or carriage return/line feed) to the file. * * If F is omitted, the global variable Output is used to access the processed standard input file. * * @param {TextFile} outFile optional output file, otherwise uses standard output * @param {...*} arg any number of arguments to write * @returns {void} * @category RTL */ function Write(outFile, ...arg /* args */) { const args = arguments; if (args.length === 0) return; const first = args[0]; if (first instanceof TextFile) { const text = concatArgs(args, 1); if (text.length) first.write(text); } else { const text = concatArgs(args, 0); process.stdout.write(text); } } /** * * Writes to a text file and adds an end-of-line marker. * * Writeln is an extension of the Write procedure, as it is defined for text files. * * The syntax shown here for the Writeln procedure is illustrates that WriteLn can take a variable number of arguments. * * After executing Write, Writeln writes an end-of-line marker (line feed or carriage return/line feed) to the file. * * If F is omitted, the global variable Output is used to access the processed standard input file. * * @param {TextFile} outFile optional output file, otherwise uses standard output * @param {...*} arg any number of arguments to write * @returns {void} * @category RTL */ function WriteLn(outFile, ...arg /* args */) { const args = arguments; if (args.length > 0 && args[0] instanceof TextFile) { // Pass OutputFile + all args + newline as one string to Write const file = args[0]; const text = concatArgs(args, 1) + sLineBreak; Write(file, text); } else { const text = concatArgs(args, 0) + sLineBreak; Write(text); } } /* * Halts the program with the given code and returns control to the operating system. * * @returns {void} * @category RTL */ function Halt(code) { process.exit(code); } /* * Specifies a write-only text file associated with the process's standard output file. * @category RTL */ const Output = new TextFile(); exports.Output = Output; AssignFile(Output, 'CONOUT$'); Rewrite(Output); // Define ParamCount, and this is a run-time definition Object.defineProperty(exports, 'ParamCount', { get() { const processArgs = getProcessArgs(); return processArgs.length - 1; }, enumerable: true }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnRsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3J0bC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFpWkksOENBQWlCO0FBQUUsOEVBQWlDO0FBQ3BELHNDQUFhO0FBRWIsd0JBQU07QUFBRSxrQ0FBVztBQUduQixzQkFBSztBQUFXLHNCQUFLO0FBQ3JCLDRCQUFRO0FBQWMsK0JBQVc7QUFDdkIsZ0NBQVU7QUFBZ0IsNEJBQU07QUFBRSx3QkFBTTtBQUNsRCw4QkFBUztBQUFlLDBCQUFLO0FBQVUsMEJBQU87QUFDOUMsc0JBQUs7QUFBRSwwQkFBTztBQUFFLG9CQUFJO0FBM1p4QixpQ0FBa0M7QUFDbEMsdUJBQXFCLENBQUMsMkNBQTJDO0FBRWpFOzs7OztHQUtHO0FBQ0gsTUFBTSxPQUFPO0lBQWI7UUFFWSxpQkFBWSxHQUFZLEtBQUssQ0FBQztJQWdFMUMsQ0FBQztJQTlERzs7T0FFRztJQUNJLE9BQU87UUFDVixJQUFJLElBQUksQ0FBQyxZQUFZO1lBQUUsT0FBTztRQUM5QixJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztRQUN6QixzQ0FBc0M7UUFFdEMsNkJBQTZCO1FBQzdCLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO0lBQzdCLENBQUM7SUFDTSxPQUFPLEtBQVcsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQztJQUUxQzs7T0FFRztJQUNJLElBQUk7UUFDUCxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDbkIsQ0FBQztJQUVEOztPQUVHO0lBQ0ksSUFBSTtRQUNQLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUNoQixDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILE1BQU0sQ0FBQyxNQUFNLENBQXFELEdBQUcsSUFBVztRQUM1RSxNQUFNLFFBQVEsR0FBRyxJQUFJLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDO1FBRW5DLElBQUksUUFBUSxDQUFDLGlCQUFpQixJQUFJLE9B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