From fba91bde103a6e1c1b8abbfb8edec37fff966636 Mon Sep 17 00:00:00 2001 From: "Timothy J. Warren" Date: Fri, 27 Oct 2023 16:02:54 -0400 Subject: [PATCH] Rough start to Deno runtime implemenation --- .editorconfig | 10 ++++++++ deno.jsonc | 20 +++++++++++++++ justfile | 14 +++++++++++ src/bun/ffi.ts | 1 + src/deno/ffi.ts | 64 +++++++++++++++++++++++++++++++++++++++++++++++ src/deno/index.ts | 15 +++++++++++ src/scroll.ts | 22 ++++++++++++++-- 7 files changed, 144 insertions(+), 2 deletions(-) create mode 100644 .editorconfig create mode 100644 deno.jsonc create mode 100644 justfile create mode 100644 src/bun/ffi.ts create mode 100644 src/deno/ffi.ts create mode 100644 src/deno/index.ts diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..af4a664 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,10 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 2 +indent_style = tab +insert_final_newline = false +max_line_length = 120 +tab_width = 2 diff --git a/deno.jsonc b/deno.jsonc new file mode 100644 index 0000000..19a82d2 --- /dev/null +++ b/deno.jsonc @@ -0,0 +1,20 @@ +{ + "imports": { + "std": "https://deno.land/std@0.204.0/", + // "/": "./src/", + }, + "lint": { + "include": ["src/"], + "rules": { + "tags": ["recommended"], + } + }, + "fmt": { + "useTabs": true, + "lineWidth": 80, + "indentWidth": 2, + "semiColons": true, + "singleQuote": true, + }, + "nodeModulesDir": true, +} \ No newline at end of file diff --git a/justfile b/justfile new file mode 100644 index 0000000..095ab32 --- /dev/null +++ b/justfile @@ -0,0 +1,14 @@ +# Lists the available actions +default: + @just --list + +# Code linting with deno +deno-lint: + deno lint + +# Code linting with bun +bun-lint: + +# Run with deno +deno-run: + deno run --allow-all --allow-ffi --deny-net --deny-hrtime --unstable ./src/scroll.ts \ No newline at end of file diff --git a/src/bun/ffi.ts b/src/bun/ffi.ts new file mode 100644 index 0000000..11a1fcb --- /dev/null +++ b/src/bun/ffi.ts @@ -0,0 +1 @@ +// Bun-specific ffi code diff --git a/src/deno/ffi.ts b/src/deno/ffi.ts new file mode 100644 index 0000000..2799387 --- /dev/null +++ b/src/deno/ffi.ts @@ -0,0 +1,64 @@ +// Deno-specific ffi code + +// Determine library extension based on +// your OS. +let libSuffix = ''; +switch (Deno.build.os) { + case 'windows': + libSuffix = 'dll'; + break; + case 'darwin': + libSuffix = 'dylib'; + break; + default: + libSuffix = 'so'; + break; +} + +const cSharedLib = `./libc.${libSuffix}`; +const cStdLib = Deno.dlopen( + cSharedLib, + { + termios: { + type: { + struct: [ + // c_iflag + 'u32', + // c_oflag + 'u32', + // c_cflag + 'u32', + // c_lflag + 'u32', + // c_cc[20] + 'u8', 'u8', 'u8', 'u8', 'u8', + 'u8', 'u8', 'u8', 'u8', 'u8', + 'u8', 'u8', 'u8', 'u8', 'u8', + 'u8', 'u8', 'u8', 'u8', 'u8', + // __ispeed + 'i32', + // __ospeed + 'i32', + ] + } + }, + tcgetattr: { + parameters: ['i32', 'pointer'], + result: 'i32', + }, + tcsetattr: { + parameters: ['i32', 'i32', 'pointer'], + result: 'i32', + }, + cfmakeraw: { + parameters: ['pointer'], + result: 'void', + }, +} as const, +); + +export default cStdLib.symbols; +export const termios = cStdLib.symbols.termios; +export const tcgetattr = cStdLib.symbols.tcgetattr; +export const tcsetattr = cStdLib.symbols.tcsetattr; +export const cfmakeraw = cStdLib.symbols.cfmakeraw; diff --git a/src/deno/index.ts b/src/deno/index.ts new file mode 100644 index 0000000..f29d9bc --- /dev/null +++ b/src/deno/index.ts @@ -0,0 +1,15 @@ +/** + * The main entrypoint when using Deno as the runtime + */ +export async function main(): Promise { + const decoder = new TextDecoder(); + for await (const chunk of Deno.stdin.readable) { + const char = String(decoder.decode(chunk)).trim(); + + if (char === 'q') { + return 0; + } + } + + return -1; +} \ No newline at end of file diff --git a/src/scroll.ts b/src/scroll.ts index ad612a7..806a26a 100644 --- a/src/scroll.ts +++ b/src/scroll.ts @@ -1,6 +1,24 @@ /** * The starting point for running scroll */ -(() => { - // Now, to do stuff + +export enum RunTime { + Bun = 'bun', + Deno = 'deno', + Unknown = 'common', +} + +/** + * Determine the runtime strategy, and go! + */ +(async () => { + let RUNTIME = RunTime.Unknown; + if ('Deno' in globalThis) { + RUNTIME = RunTime.Deno; + const { main } = await import('./deno/index.ts'); + await main(); + } + if ('Bun' in globalThis) { + RUNTIME = RunTime.Bun; + } })();