Add TypeScript
This commit is contained in:
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Martin Petr
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
34
README.md
Normal file
34
README.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Lints
|
||||
|
||||
## What the hell is this?
|
||||
|
||||
Lints is an experimental operating system kernel written almost entirely in TypeScript. This is not some in-browser system emulator or WebAssembly hack; Lints actually runs on real hardware (or a hardware emulator like QEMU) by leveraging a JavaScript engine with a small C kernel (just some basic memory management needed by the JS engine) and JS-to-C bindings for purposes like writting data to pointers, etc.
|
||||
|
||||
## Why?
|
||||
|
||||
- I can.
|
||||
- I want to be able to say that I did it.
|
||||
- I am not sane and don't have a life.
|
||||
- TypeScript haters.
|
||||
- "Anything that can be done in JavaScript will eventually be done in JavaScript." - Jeff Atwood
|
||||
|
||||
## How to run it?
|
||||
|
||||
Please don't.
|
||||
|
||||
If you really want to, make sure you have Docker installed, then run:
|
||||
|
||||
```bash
|
||||
./scripts/run-kernel.sh
|
||||
```
|
||||
|
||||
## If you are an employer looking at this...
|
||||
|
||||
I would appreciate if you messaged me and gave me some well-paid job. Also...
|
||||
Please don't judge me based on this project. I swear I can write normal code too.
|
||||
|
||||
## License
|
||||
|
||||
MIT License. See LICENSE file for details.
|
||||
|
||||
TL;DR: Do whatever you want with it, but don't blame me if it blows up in your face. Also I'd appreciate that you give me credit if you use any of my code, ideas or whatever - I mean why would someone even want to be associated with this project (or steal it), right?
|
||||
@@ -10,8 +10,12 @@ RUN dnf install -y \
|
||||
qemu-system-x86 \
|
||||
wget \
|
||||
meson \
|
||||
unzip \
|
||||
&& dnf clean all
|
||||
|
||||
RUN curl -fsSL https://bun.sh/install | bash
|
||||
ENV PATH="/root/.bun/bin:${PATH}"
|
||||
|
||||
WORKDIR /workspace
|
||||
|
||||
CMD ["bash", "-c", "/workspace/scripts/build-picolibc.sh && /workspace/scripts/build-kernel.sh"]
|
||||
@@ -19,8 +19,11 @@ fi
|
||||
mkdir -p "$BUILD_DIR"
|
||||
mkdir -p "$OUT_DIR"
|
||||
|
||||
# Copy JavaScript source to build directory
|
||||
cp src/os/index.js build/
|
||||
# Build TypeScript to JavaScript
|
||||
cd src/os
|
||||
echo "Compiling TypeScript to JavaScript..."
|
||||
bun build --outdir ../../build --target node --bundle kernel/index.ts
|
||||
cd ../../
|
||||
|
||||
# Generate embedded JavaScript header
|
||||
echo "Generating embedded JavaScript..."
|
||||
|
||||
34
src/os/.gitignore
vendored
Normal file
34
src/os/.gitignore
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
# dependencies (bun install)
|
||||
node_modules
|
||||
|
||||
# output
|
||||
out
|
||||
dist
|
||||
*.tgz
|
||||
|
||||
# code coverage
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# logs
|
||||
logs
|
||||
_.log
|
||||
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
|
||||
|
||||
# dotenv environment variable files
|
||||
.env
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env.local
|
||||
|
||||
# caches
|
||||
.eslintcache
|
||||
.cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# IntelliJ based IDEs
|
||||
.idea
|
||||
|
||||
# Finder (MacOS) folder config
|
||||
.DS_Store
|
||||
29
src/os/bun.lock
Normal file
29
src/os/bun.lock
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"lockfileVersion": 1,
|
||||
"workspaces": {
|
||||
"": {
|
||||
"name": "os",
|
||||
"devDependencies": {
|
||||
"@types/bun": "latest",
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5",
|
||||
},
|
||||
},
|
||||
},
|
||||
"packages": {
|
||||
"@types/bun": ["@types/bun@1.3.2", "", { "dependencies": { "bun-types": "1.3.2" } }, "sha512-t15P7k5UIgHKkxwnMNkJbWlh/617rkDGEdSsDbu+qNHTaz9SKf7aC8fiIlUdD5RPpH6GEkP0cK7WlvmrEBRtWg=="],
|
||||
|
||||
"@types/node": ["@types/node@24.10.1", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ=="],
|
||||
|
||||
"@types/react": ["@types/react@19.2.6", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-p/jUvulfgU7oKtj6Xpk8cA2Y1xKTtICGpJYeJXz2YVO2UcvjQgeRMLDGfDeqeRW2Ta+0QNFwcc8X3GH8SxZz6w=="],
|
||||
|
||||
"bun-types": ["bun-types@1.3.2", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-i/Gln4tbzKNuxP70OWhJRZz1MRfvqExowP7U6JKoI8cntFrtxg7RJK3jvz7wQW54UuvNC8tbKHHri5fy74FVqg=="],
|
||||
|
||||
"csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="],
|
||||
|
||||
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
||||
|
||||
"undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
clearScreen();
|
||||
print("Hello, World!");
|
||||
|
||||
function clearScreen() {
|
||||
var i = 0;
|
||||
while (i < 80 * 25 * 2) {
|
||||
writeMemory(0xb8000 + i, 0x00);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
function printChar(char, offset) {
|
||||
writeMemory(0xb8000 + offset * 2, char.charCodeAt(0));
|
||||
writeMemory(0xb8000 + offset * 2 + 1, 0x0f); // White on black
|
||||
}
|
||||
|
||||
function print(str) {
|
||||
for (var i = 0; i < str.length; i++) {
|
||||
printChar(str.charAt(i), i);
|
||||
}
|
||||
}
|
||||
33
src/os/kernel/index.ts
Normal file
33
src/os/kernel/index.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
const SCREEN_WIDTH = 80;
|
||||
const SCREEN_HEIGHT = 25;
|
||||
const VIDEO_MEMORY_START = 0xb8000;
|
||||
|
||||
clearScreen();
|
||||
print("Welcome to Lints OS!", 0, 0, 0x0a); // Light green on black
|
||||
|
||||
function clearScreen(): void {
|
||||
for (var row = 0; row < SCREEN_HEIGHT; row++) {
|
||||
for (var col = 0; col < SCREEN_WIDTH; col++) {
|
||||
const address = VIDEO_MEMORY_START + 2 * (row * SCREEN_WIDTH + col);
|
||||
writeMemory(address, 0x20); // ASCII space
|
||||
writeMemory(address + 1, 0x07); // Light grey on black
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function writeChar(
|
||||
row: number,
|
||||
col: number,
|
||||
char: string,
|
||||
color: number
|
||||
): void {
|
||||
const address = VIDEO_MEMORY_START + 2 * (row * SCREEN_WIDTH + col);
|
||||
writeMemory(address, char.charCodeAt(0));
|
||||
writeMemory(address + 1, color);
|
||||
}
|
||||
|
||||
function print(text: string, row: number, col: number, color: number): void {
|
||||
for (var i = 0; i < text.length; i++) {
|
||||
writeChar(row, col + i, text[i]!, color);
|
||||
}
|
||||
}
|
||||
12
src/os/package.json
Normal file
12
src/os/package.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "os",
|
||||
"module": "index.ts",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"@types/bun": "latest"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5"
|
||||
}
|
||||
}
|
||||
29
src/os/tsconfig.json
Normal file
29
src/os/tsconfig.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
// Environment setup & latest features
|
||||
"lib": ["ESNext"],
|
||||
"target": "ESNext",
|
||||
"module": "Preserve",
|
||||
"moduleDetection": "force",
|
||||
"jsx": "react-jsx",
|
||||
"allowJs": true,
|
||||
|
||||
// Bundler mode
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"noEmit": true,
|
||||
|
||||
// Best practices
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"noImplicitOverride": true,
|
||||
|
||||
// Some stricter flags (disabled by default)
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": false,
|
||||
"noPropertyAccessFromIndexSignature": false
|
||||
}
|
||||
}
|
||||
1
src/os/types/kernel/functions.d.ts
vendored
Normal file
1
src/os/types/kernel/functions.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
declare function writeMemory(address: number, value: number): void;
|
||||
Reference in New Issue
Block a user