Skip to content
Open
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
17 changes: 17 additions & 0 deletions biome.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
"formatter": {
"enabled": false
},
"javascript": {
"formatter": {
"quoteStyle": "single"
}
},
"linter": {
"enabled": false
},
"organizeImports": {
"enabled": false
}
}
4 changes: 2 additions & 2 deletions src/programs/run-and-interpret.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Effect } from 'effect'
import { runPromiseInDefault } from '../runtimes/default'
import { Evaluator } from '../services/evaluator'
import { createErrorObj } from '@/services/object'
import { errorObjSchema } from '@/schemas/objs/error'

const runAndInterpretProgram = (input: string) =>
Effect.gen(function* () {
Expand All @@ -12,5 +12,5 @@ const runAndInterpretProgram = (input: string) =>
export const runAndInterpret = (input: string) =>
runPromiseInDefault(runAndInterpretProgram(input).pipe(
Effect.catchAll((error) => {
return Effect.succeed(createErrorObj(error.message))
return Effect.succeed(errorObjSchema.make({message: error.message}))
})))
3 changes: 1 addition & 2 deletions src/schemas/nodes/exps/diff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export type DiffExpEncoded = {
readonly _tag: 'DiffExp'
readonly token: DiffToken
readonly exp: ExpEncoded
readonly params: readonly IdentExp[]
readonly params: readonly IdentExpEncoded[]
}

export class DiffExp extends Schema.TaggedClass<DiffExp>()('DiffExp', {
Expand All @@ -16,7 +16,6 @@ export class DiffExp extends Schema.TaggedClass<DiffExp>()('DiffExp', {
params: Schema.Array(
Schema.suspend((): Schema.Schema<IdentExp, IdentExpEncoded> => IdentExp),
),
// x: Schema.suspend((): Schema.Schema<IdentExp, IdentExpEncoded> => IdentExp),
}) {
tokenLiteral() {
return this.token.literal
Expand Down
9 changes: 2 additions & 7 deletions src/schemas/nodes/exps/ident.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,9 @@ export class IdentExp

export const IdentExpEq = Schema.equivalence(IdentExp)

export const expectIdentEquivalence = (a: IdentExp, b: IdentExp) =>
Effect.gen(function* () {
return !IdentExpEq(a, b)
? yield* new KennethParseError({
export const expectIdentEquivalence = (a: IdentExp, b: IdentExp) => Effect.fail(new KennethParseError({
message: 'we expected ident to equal x',
})
: undefined
})
})).pipe(Effect.unless(() => IdentExpEq(a, b)))

export const nativeToIdentExp = (value: string) =>
new IdentExp({
Expand Down
6 changes: 3 additions & 3 deletions src/schemas/objs/bool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ const fields = {
}

export interface BoolObj extends Schema.Struct.Type<typeof fields> {
readonly _tag: 'BoolObj'
readonly _tag: 'BooleanObj'
}

export interface BoolObjEncoded extends Schema.Struct.Type<typeof fields> {
readonly _tag: 'BoolObj'
readonly _tag: 'BooleanObj'
}

export const boolObjSchema = Schema.TaggedStruct('BoolObj', {
export const boolObjSchema = Schema.TaggedStruct('BooleanObj', {
...fields,
})
2 changes: 1 addition & 1 deletion src/schemas/objs/built-in.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Schema } from 'effect'

const fields = {
fn: Schema.Unknown,
fn: Schema.Literal('len', 'diff'),
}

export interface BuiltInObj extends Schema.Struct.Type<typeof fields> {
Expand Down
13 changes: 6 additions & 7 deletions src/schemas/objs/function.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,28 @@
import { Schema } from 'effect'
import { IdentExp, type IdentExpEncoded } from '../nodes/exps/ident'
import { BlockStmt, type BlockStmtEncoded } from '../nodes/stmts/block'
import { Environment, EnvironmentEncoded, environmentSchema } from '@/services/object/environment'

const fields = {
env: Schema.Unknown,
}

export interface FunctionObj extends Schema.Struct.Type<typeof fields> {
export interface FunctionObj {
readonly _tag: 'FunctionObj'
readonly params: readonly IdentExp[]
readonly body: BlockStmt
readonly env: Environment
}

export interface FunctionObjEncoded extends Schema.Struct.Type<typeof fields> {
export interface FunctionObjEncoded {
readonly _tag: 'FunctionObj'
readonly params: readonly IdentExpEncoded[]
readonly body: BlockStmtEncoded
readonly env: EnvironmentEncoded
}

export const functionObjSchema = Schema.TaggedStruct('FunctionObj', {
...fields,
params: Schema.Array(
Schema.suspend((): Schema.Schema<IdentExp, IdentExpEncoded> => IdentExp),
),
body: Schema.suspend(
(): Schema.Schema<BlockStmt, BlockStmtEncoded> => BlockStmt,
),
env: Schema.suspend((): Schema.Schema<Environment, EnvironmentEncoded> => environmentSchema)
})
19 changes: 19 additions & 0 deletions src/schemas/objs/ident.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Schema } from 'effect'
import { IdentExp, IdentExpEncoded } from '../nodes/exps/ident'

export interface IdentObj {
readonly _tag: 'IdentObj'
readonly identExp: IdentExp
}

export interface IdentObjEncoded {
readonly _tag: 'IdentObj'
readonly identExp: IdentExpEncoded
}

export const identObjSchema = Schema.TaggedStruct('IdentObj', {
identExp: Schema.suspend((): Schema.Schema<IdentExp, IdentExpEncoded> => IdentExp)

})

export const identObjEq = Schema.equivalence(identObjSchema)
28 changes: 28 additions & 0 deletions src/schemas/objs/infix.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Schema } from 'effect'
import { infixOperatorSchema } from '../infix-operator'
import { Obj, ObjEncoded, objSchema } from './union'

const fields = {
operator: infixOperatorSchema
}

export interface InfixObj extends Schema.Struct.Type<typeof fields> {
readonly _tag: 'InfixObj'
readonly left: Obj
readonly right: Obj
}

export interface InfixObjEncoded extends Schema.Struct.Type<typeof fields> {
readonly _tag: 'InfixObj'
readonly left: ObjEncoded
readonly right: ObjEncoded
}

export const infixObjSchema = Schema.TaggedStruct('InfixObj', {
...fields,
left: Schema.suspend((): Schema.Schema<Obj, ObjEncoded> => objSchema),
right: Schema.suspend((): Schema.Schema<Obj, ObjEncoded> => objSchema),
operator: infixOperatorSchema
})

export const infixObjEq = Schema.equivalence(infixObjSchema)
11 changes: 4 additions & 7 deletions src/schemas/objs/null.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
import { Schema } from 'effect'

const fields = {
inpect: Schema.String,
}

export interface NullObj extends Schema.Struct.Type<typeof fields> {
export interface NullObj {
readonly _tag: 'NullObj'
}

export interface NullObjEncoded extends Schema.Struct.Type<typeof fields> {
export interface NullObjEncoded {
readonly _tag: 'NullObj'
}

export const nullObjSchema = Schema.TaggedStruct('NullObj', {
...fields,
})

export const NULL = nullObjSchema.make()
2 changes: 1 addition & 1 deletion src/schemas/objs/string.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Schema } from 'effect'

const fields = {
vlue: Schema.String,
value: Schema.String,
}

export interface StringObj extends Schema.Struct.Type<typeof fields> {
Expand Down
37 changes: 36 additions & 1 deletion src/schemas/objs/union.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Schema } from 'effect'
import { Data, Pretty, Schema } from 'effect'
import { type BoolObjEncoded, boolObjSchema, type BoolObj } from './bool'
import {
type BuiltInObjEncoded,
Expand All @@ -23,6 +23,8 @@ import {
stringObjSchema,
type StringObj,
} from './string'
import { IdentObj, IdentObjEncoded, identObjSchema } from './ident'
import { InfixObj, InfixObjEncoded, infixObjSchema } from './infix'

export type Obj =
| BoolObj
Expand All @@ -33,6 +35,8 @@ export type Obj =
| NullObj
| ReturnObj
| StringObj
| IdentObj
| InfixObj

export type ObjEncoded =
| BoolObjEncoded
Expand All @@ -43,6 +47,8 @@ export type ObjEncoded =
| NullObjEncoded
| ReturnObjEncoded
| StringObjEncoded
| IdentObjEncoded
| InfixObjEncoded

export const objSchema = Schema.suspend(
(): Schema.Schema<Obj, ObjEncoded> =>
Expand All @@ -55,5 +61,34 @@ export const objSchema = Schema.suspend(
nullObjSchema,
returnObjSchema,
stringObjSchema,
identObjSchema,
infixObjSchema
),
)

export const prettyObj = Pretty.make(objSchema)

const {
$is,
$match,
} = Data.taggedEnum<Obj>()

export const isIntegerObj = $is('IntegerObj')
export const isBooleanObj = $is('BooleanObj')
export const isNullObj = $is('NullObj')
export const isReturnObj = $is('ReturnObj')
export const isErrorObj = $is('ErrorObj')
export const isFunctionObj = $is('FunctionObj')
export const isStringObj = $is('StringObj')
export const isBuiltInObj = $is('BuiltInObj')
export const isIdentObj = $is('IdentObj')
export const isInfixObj = $is('InfixObj')

export const objMatch = $match

export const isObj = $is

export const FALSE = boolObjSchema.make({value: false})
export const TRUE = boolObjSchema.make({value: true})

export const nativeBoolToObjectBool = (input: boolean) => (input ? TRUE : FALSE)
23 changes: 23 additions & 0 deletions src/schemas/objs/unions/polynomial.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Schema } from "effect"
import { IdentObj, IdentObjEncoded, identObjSchema } from "../ident"
import { InfixObj, InfixObjEncoded, infixObjSchema } from "../infix"
import { IntObj, IntObjEncoded, intObjSchema } from "../int"

export type PolynomialObj =
| IntObj
| IdentObj
| InfixObj

export type PolynomialObjEncoded =
| IntObjEncoded
| IdentObjEncoded
| InfixObjEncoded

export const polynomialObjSchema = Schema.suspend(
(): Schema.Schema<PolynomialObj, PolynomialObjEncoded> =>
Schema.Union(
intObjSchema,
identObjSchema,
infixObjSchema
),
)
12 changes: 12 additions & 0 deletions src/schemas/polynomial-operator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Schema } from 'effect'
import { TokenType } from './token-types/union'

export const polynomialOperatorSchema = Schema.Literal(
TokenType.PLUS,
TokenType.MINUS,
TokenType.ASTERISK,
TokenType.SLASH,
TokenType.EXPONENT,
)

export type PolynomialOperator = typeof polynomialOperatorSchema.Type
7 changes: 4 additions & 3 deletions src/services/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
import { Args, Command } from '@effect/cli'
import { Terminal } from '@effect/platform'
import { BunContext, BunRuntime } from '@effect/platform-bun'
import { Console, Effect, Layer } from 'effect'
import { Console, Effect, Layer, Pretty } from 'effect'
import { PROMPT } from './repl/constants'
import { Parser } from './parser'
import { Eval } from './evaluator'
import { createEnvironment } from './object/environment'
import { objSchema } from '@/schemas/objs/union'

// Define the top-level command
const topLevel = Command.make('hello-world', {}, () =>
Expand Down Expand Up @@ -35,8 +36,8 @@ const replCommand = Command.make(
const parser = yield* Parser
yield* parser.init(input)
const program = yield* parser.parseProgram
const evaluation = yield* Eval(program)(env)
yield* Console.log(evaluation.inspect())
const evaluation = yield* Eval(program)(env, undefined)
yield* Console.log(Pretty.make(objSchema)(evaluation))
}
}),
// Console.log(input),
Expand Down
Loading