Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/adts.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import * as eitherUtilities from './adts/either-utilities.js'
import * as eitherADT from './adts/either.js'
import * as eitherAdt from './adts/either.js'
import * as optionUtilities from './adts/option-utilities.js'
import * as optionADT from './adts/option.js'
import * as optionAdt from './adts/option.js'

export type { Either } from './adts/either.js'
export type { Option } from './adts/option.js'
export const either = { ...eitherADT, ...eitherUtilities }
export const option = { ...optionADT, ...optionUtilities }
export const either = { ...eitherAdt, ...eitherUtilities }
export const option = { ...optionAdt, ...optionUtilities }
22 changes: 11 additions & 11 deletions src/language/cli/input.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { parseArgs } from 'util'
import { either, type Either } from '../../adts.js'
import { type JSONValueForbiddingSymbolicKeys } from '../parsing.js'
import { type JsonValueForbiddingSymbolicKeys } from '../parsing.js'

export type InvalidJsonError = {
readonly kind: 'invalidJSON'
readonly kind: 'invalidJson'
readonly message: string
}

export const handleInput = async <Result>(
process: NodeJS.Process,
command: (input: JSONValueForbiddingSymbolicKeys) => Result,
command: (input: JsonValueForbiddingSymbolicKeys) => Result,
): Promise<Result> => {
const args = parseArgs({
args: process.argv.slice(2), // remove `execPath` and `filename`
Expand All @@ -25,7 +25,7 @@ export const handleInput = async <Result>(
`Unsupported input format: "${args.values['input-format']}"`,
)
} else {
const input = await readJSON(process.stdin)
const input = await readJson(process.stdin)
return either.match(input, {
left: error => {
throw new Error(error.message) // TODO: Improve error reporting.
Expand All @@ -35,10 +35,10 @@ export const handleInput = async <Result>(
}
}

export const readJSON = async (
export const readJson = async (
stream: AsyncIterable<string>,
): Promise<Either<InvalidJsonError, JSONValueForbiddingSymbolicKeys>> =>
parseJSON(await readString(stream))
): Promise<Either<InvalidJsonError, JsonValueForbiddingSymbolicKeys>> =>
parseJson(await readString(stream))

export const readString = async (
stream: AsyncIterable<string>,
Expand All @@ -50,13 +50,13 @@ export const readString = async (
return input
}

const parseJSON = (
const parseJson = (
source: string,
): Either<InvalidJsonError, JSONValueForbiddingSymbolicKeys> =>
): Either<InvalidJsonError, JsonValueForbiddingSymbolicKeys> =>
either.mapLeft(
either.tryCatch((): JSONValueForbiddingSymbolicKeys => JSON.parse(source)),
either.tryCatch((): JsonValueForbiddingSymbolicKeys => JSON.parse(source)),
jsonParseError => ({
kind: 'invalidJSON',
kind: 'invalidJson',
message:
jsonParseError instanceof Error
? jsonParseError.message
Expand Down
4 changes: 2 additions & 2 deletions src/language/compiling/compiler.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { either, type Either } from '../../adts.js'
import type { CompilationError } from '../errors.js'
import type { JSONValueForbiddingSymbolicKeys } from '../parsing.js'
import type { JsonValueForbiddingSymbolicKeys } from '../parsing.js'
import { canonicalize } from '../parsing.js'
import { elaborate, serialize, type Output } from '../semantics.js'
import { keywordHandlers } from './semantics/keywords.js'

export const compile = (
input: JSONValueForbiddingSymbolicKeys,
input: JsonValueForbiddingSymbolicKeys,
): Either<CompilationError, Output> => {
const syntaxTree = canonicalize(input)
const semanticGraphResult = elaborate(syntaxTree, keywordHandlers)
Expand Down
2 changes: 1 addition & 1 deletion src/language/parsing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ export type { Atom } from './parsing/atom.js'
export type { Molecule } from './parsing/molecule.js'
export {
canonicalize,
type JSONValueForbiddingSymbolicKeys,
type JsonValueForbiddingSymbolicKeys,
type SyntaxTree,
} from './parsing/syntax-tree.js'
24 changes: 12 additions & 12 deletions src/language/parsing/syntax-tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { option, type Option } from '../../adts.js'
import { parser, type Parser } from '../../parsing.js'
import { withPhantomData, type WithPhantomData } from '../../phantom-data.js'
import type {
JSONArray,
JSONRecord,
JSONValue,
JsonArray,
JsonRecord,
JsonValue,
Writable,
} from '../../utility-types.js'
import type { KeyPath } from '../semantics.js'
Expand Down Expand Up @@ -47,7 +47,7 @@ export const applyKeyPathToSyntaxTree = (
* The JSON value `["a", 1, null]` is canonicalized as `{ "0": "a", "1": "1", "2": "null" }`.
*/
export const canonicalize = (
input: JSONValueForbiddingSymbolicKeys,
input: JsonValueForbiddingSymbolicKeys,
): SyntaxTree => {
let canonicalized: Atom | Writable<Molecule>
if (typeof input === 'object' && input !== null) {
Expand All @@ -66,15 +66,15 @@ export const canonicalize = (
* (because symbolic keys can always be widened away), but will catch simple mistakes like directly
* feeding an `Option<…>` into `canonicalize`.
*/
export type JSONValueForbiddingSymbolicKeys =
| Exclude<JSONValue, JSONArray | JSONRecord>
| JSONArrayForbiddingSymbolicKeys
| JSONRecordForbiddingSymbolicKeys
export type JsonValueForbiddingSymbolicKeys =
| Exclude<JsonValue, JsonArray | JsonRecord>
| JsonArrayForbiddingSymbolicKeys
| JsonRecordForbiddingSymbolicKeys

type JSONArrayForbiddingSymbolicKeys =
readonly JSONValueForbiddingSymbolicKeys[]
type JSONRecordForbiddingSymbolicKeys = {
readonly [key: string]: JSONValueForbiddingSymbolicKeys
type JsonArrayForbiddingSymbolicKeys =
readonly JsonValueForbiddingSymbolicKeys[]
type JsonRecordForbiddingSymbolicKeys = {
readonly [key: string]: JsonValueForbiddingSymbolicKeys
} & Partial<{
readonly [key: symbol]: undefined
}>
Expand Down
4 changes: 2 additions & 2 deletions src/language/runtime/evaluator.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { either, type Either } from '../../adts.js'
import type { RuntimeError } from '../errors.js'
import type { JSONValueForbiddingSymbolicKeys } from '../parsing.js'
import type { JsonValueForbiddingSymbolicKeys } from '../parsing.js'
import { canonicalize } from '../parsing.js'
import { elaborate, serialize, type Output } from '../semantics.js'
import { keywordHandlers } from './keywords.js'

export const evaluate = (
input: JSONValueForbiddingSymbolicKeys,
input: JsonValueForbiddingSymbolicKeys,
): Either<RuntimeError, Output> => {
const syntaxTree = canonicalize(input)
const semanticGraphResult = elaborate(syntaxTree, keywordHandlers)
Expand Down
14 changes: 7 additions & 7 deletions src/language/semantics/type-system/prelude-types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { option as optionADT } from '../../../adts.js'
import { option as optionAdt } from '../../../adts.js'
import {
makeFunctionType,
makeObjectType,
Expand All @@ -23,22 +23,22 @@ export const boolean = makeUnionType('boolean', ['false', 'true'])

export const atom = makeOpaqueAtomType('atom', {
isAssignableFromLiteralType: (_literalType: string) => true,
nearestOpaqueAssignableFrom: () => optionADT.makeSome(integer),
nearestOpaqueAssignableTo: () => optionADT.none,
nearestOpaqueAssignableFrom: () => optionAdt.makeSome(integer),
nearestOpaqueAssignableTo: () => optionAdt.none,
})

export const integer = makeOpaqueAtomType('natural_number', {
isAssignableFromLiteralType: literalType =>
/^(?:0|-?[1-9](?:[0-9])*)+$/.test(literalType),
nearestOpaqueAssignableFrom: () => optionADT.makeSome(naturalNumber),
nearestOpaqueAssignableTo: () => optionADT.makeSome(atom),
nearestOpaqueAssignableFrom: () => optionAdt.makeSome(naturalNumber),
nearestOpaqueAssignableTo: () => optionAdt.makeSome(atom),
})

export const naturalNumber = makeOpaqueAtomType('natural_number', {
isAssignableFromLiteralType: literalType =>
/^(?:0|[1-9](?:[0-9])*)+$/.test(literalType),
nearestOpaqueAssignableFrom: () => optionADT.none,
nearestOpaqueAssignableTo: () => optionADT.makeSome(integer),
nearestOpaqueAssignableFrom: () => optionAdt.none,
nearestOpaqueAssignableTo: () => optionAdt.makeSome(integer),
})

export const object = makeObjectType('object', {})
Expand Down
10 changes: 5 additions & 5 deletions src/utility-types.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
export type JSONArray = readonly JSONValue[]
export type JSONRecord = { readonly [key: string]: JSONValue }
export type JSONValue =
export type JsonArray = readonly JsonValue[]
export type JsonRecord = { readonly [key: string]: JsonValue }
export type JsonValue =
| null
| boolean
| number
| string
| JSONArray
| JSONRecord
| JsonArray
| JsonRecord

export type Writable<T> = { -readonly [P in keyof T]: T[P] }
Loading