Initial commit

This commit is contained in:
Jeff 2024-02-07 23:29:29 -05:00
commit 83193bb8ba
8 changed files with 221 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
node_modules/

22
bit.ts Normal file
View File

@ -0,0 +1,22 @@
type BinaryDigit = 0 | 1
export interface Bit {
value: BinaryDigit
add: (other: Bit) => { ones: Bit, carry: Bit }
}
export default function bit(value: BinaryDigit): Bit {
function add(other: Bit) {
const result = (value + other.value)
const ones = result % 2 as BinaryDigit
const carry = result === 2 ? 1 : 0
return { bit: bit(ones), carry: bit(carry) }
}
return {
add,
value
}
}

3
index.ts Normal file
View File

@ -0,0 +1,3 @@
function memory(bits: number) {
}

12
memory.ts Normal file
View File

@ -0,0 +1,12 @@
import { Bit } from "./bit";
import { emptyWord, wordFromBits } from "./word";
function memory(initialValue: Bit[])
function memory(width: number)
function memory(valueOrWidth: number | Bit[]) {
let word = typeof valueOrWidth === 'number' ? emptyWord(valueOrWidth) : wordFromBits(valueOrWidth)
function set(word: Word) {
}
}

67
package-lock.json generated Normal file
View File

@ -0,0 +1,67 @@
{
"name": "grit",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "grit",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"@types/lodash": "^4.14.202",
"lodash": "^4.17.21"
},
"devDependencies": {
"@rimbu/typical": "^0.8.0",
"@types/node": "^20.11.16"
}
},
"node_modules/@rimbu/typical": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/@rimbu/typical/-/typical-0.8.0.tgz",
"integrity": "sha512-quQ3OFICxy4ZEU+BRFibi8TkxdML3+RrjK2CNh8lkF02mLifSLn41/RMFQKCgV/CofhX2d/53kZE9V1ptCNRmw==",
"dev": true,
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/vitoke"
}
],
"dependencies": {
"tslib": "^2.6.2"
}
},
"node_modules/@types/lodash": {
"version": "4.14.202",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.202.tgz",
"integrity": "sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ=="
},
"node_modules/@types/node": {
"version": "20.11.16",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.16.tgz",
"integrity": "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ==",
"dev": true,
"dependencies": {
"undici-types": "~5.26.4"
}
},
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"node_modules/tslib": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
"dev": true
},
"node_modules/undici-types": {
"version": "5.26.5",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
"dev": true
}
}
}

19
package.json Normal file
View File

@ -0,0 +1,19 @@
{
"name": "grit",
"version": "1.0.0",
"description": "Tiny computer",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"@types/lodash": "^4.14.202",
"lodash": "^4.17.21"
},
"devDependencies": {
"@rimbu/typical": "^0.8.0",
"@types/node": "^20.11.16"
}
}

0
types.ts Normal file
View File

97
word.ts Normal file
View File

@ -0,0 +1,97 @@
import bit, { Bit } from "./bit"
import { range, zip } from "lodash"
type GreaterThan<Threshold extends number> = number
type LessOrEqual<Threshold extends number> = number
export interface Word<Width extends number> {
plus: <OtherWidth extends number, ResultWidth = >(other: Word<OtherWidth>) => Word<GreaterOf<Width, OtherWidth>>
bits: Bit[]
length: Width
}
// function greaterOf<Value extends number, Other extends number>(value: Value, other: Other){
// return value > other ? value as Value : other as Other
// }
type LessThan = number
type GreaterOrEqual = number
function isLessThan(value: number, other: number): value is LessThan {
return value < other
}
function isGreaterThanOrEqual(value: number, other: number): value is GreaterOrEqual {
return value >= other
}
function greaterOf<A extends LessThan, B>(value: LessThan, other: B): LessThan
function greaterOf<A extends GreaterOrEqual, B>(value: GreaterOrEqual, other: B): GreaterOrEqual
function greaterOf<A extends number, B extends number>(value: A, other: B): LessThan | GreaterOrEqual {
const result = Math.max(value, other)
return isLessThan(value, other) ? value as GreaterThan : other as LessThan
}
const duh = wordFromBits([bit(0)] as const).plus(wordFromBits([bit(0), bit(0)]))
type FixedLengthArray<T, Length extends number> = Readonly<Array<T> & { length: Length}>
export function wordFromBits<Width extends Readonly<number>>(bits: readonly FixedLengthArray<Bit, Width>) {
function plus<OtherWidth extends GreaterThan<Width>>(other: Word<OtherWidth>): Word<OtherWidth>
function plus<OtherWidth extends LessOrEqual<Width>>(other: Word<OtherWidth>): Word<Width> {
const newBits = addBits(bits, other.bits)
return wordFromBits(newBits.bits)
}
function subword(start: number, length?: number) {
return wordFromBits(bits.slice(start, length !== undefined ? start + length : undefined))
}
return {
plus,
subword,
bits,
length: bits.length
}
}
function addBits(bits: Bit[], otherBits: Bit[]) {
const bigEndianBits = [...bits].reverse()
const bigEndianOtherBits = [...otherBits].reverse()
const pairedBits = zip(bigEndianBits, bigEndianOtherBits).reverse()
const denulledBits = pairedBits.map(([a, b]) => [a ?? bit(0), b ?? bit(0)] as const)
const sumResults = denulledBits.reduce<SumResult>(({bits, carry}, [a, b]) => {
const aPlusB = a.add(b)
const aPlusBPlusCarry = aPlusB.ones.add(carry)
const thisCarry = aPlusB.carry.add(aPlusBPlusCarry.carry).ones
bits.push(aPlusBPlusCarry.ones)
return sumResult(bits, thisCarry)
}, sumResult([], bit(0)))
return sumResults
}
interface SumResult {
bits: Bit[]
carry: Bit
}
function sumResult(bits: Bit[], carry: Bit) {
return {
bits,
carry}
}
}
export function emptyWord<Width extends number>(width: Width): Word<Width> {
const bits = range(0, width).map(() => bit(0))
return wordFromBits(bits)
}