Skip to content

Commit

Permalink
extract compose
Browse files Browse the repository at this point in the history
- let `Word` be algebraic data type
  • Loading branch information
xieyuheng committed Aug 2, 2023
1 parent 6bb8e2b commit 6753aea
Show file tree
Hide file tree
Showing 11 changed files with 171 additions and 160 deletions.
4 changes: 0 additions & 4 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
# type

extract `compose`

- let `Word` be algebraic data type

extract `cut`

`defrule` -- check type -- cut -- words composition
Expand Down
98 changes: 97 additions & 1 deletion src/lang/compose/compose.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { Node } from "../graph"
import { findPortInNodes } from "../graph/findPortInActiveEdge"
import { Mod } from "../mod"
import { lookupDefinitionOrFail } from "../mod/lookupDefinitionOrFail"
import { Net } from "../net"
import { connect } from "../net/connect"
import { disconnect } from "../net/disconnect"
import { Word } from "../word"

export interface ComposeOptions {
Expand All @@ -13,5 +17,97 @@ export function compose(
word: Word,
options?: ComposeOptions,
): void {
//
switch (word.kind) {
case "Call": {
const found = net.localPorts.get(word.name)
if (found !== undefined) {
net.ports.push(found)
net.localPorts.delete(word.name)
return
} else {
lookupDefinitionOrFail(mod, word.name).compose(net)
return
}
}

case "LocalSet": {
const port = net.ports.pop()
if (port === undefined) {
throw new Error(
`[LocalSet.compose] expect a port on the top of the stack`,
)
}

net.localPorts.set(word.name, port)
return
}

case "PortPush": {
const { current } = options || {}

if (current === undefined) {
throw new Error(`[PortPush.compose] expect current activeEdge`)
}

const found = findPortInNodes(word.nodeName, word.portName, [
current.start,
current.end,
])

if (found === undefined) {
throw new Error(
`[PortPush.compose] can not find port: ${word.portName} in active edge`,
)
}

if (found.connection === undefined) {
throw new Error(
`[PortPush.compose] I expect the found port to have connection`,
)
}

disconnect(net, found.connection.edge)

net.ports.push(found)

return
}

case "PortReconnect": {
const { current } = options || {}

if (current === undefined) {
throw new Error(`[PortReconnect.compose] expect current activeEdge`)
}

const found = findPortInNodes(word.nodeName, word.portName, [
current.start,
current.end,
])

if (found === undefined) {
throw new Error(
`[PortReconnect.compose] can not find port: ${word.portName} in active edge`,
)
}

if (found.connection === undefined) {
throw new Error(
`[PortReconnect.compose] I expect the found port to have connection`,
)
}

disconnect(net, found.connection.edge)

const topPort = net.ports.pop()

if (topPort === undefined) {
throw new Error(`[PortReconnect.compose] expect top port`)
}

connect(net, topPort, found)

return
}
}
}
3 changes: 2 additions & 1 deletion src/lang/compose/composeWords.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import { Mod } from "../mod"
import { Net } from "../net"
import { cleanUpWires } from "../net/cleanUpWires"
import { Word } from "../word"
import { compose } from "./compose"

export function composeWords(mod: Mod, net: Net, words: Array<Word>): void {
for (const word of words) {
word.compose(mod, net)
compose(mod, net, word)
}

cleanUpWires(net)
Expand Down
3 changes: 2 additions & 1 deletion src/lang/run/interact.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { compose } from "../compose/compose"
import { ActiveEdge } from "../graph"
import { Mod } from "../mod"
import { Net } from "../net"
Expand All @@ -8,7 +9,7 @@ export function interact(mod: Mod, net: Net, activeEdge: ActiveEdge): void {
removeNodeAndEdges(net, activeEdge.start.node)

for (const word of activeEdge.rule.words) {
word.compose(mod, net, {
compose(mod, net, word, {
current: {
start: activeEdge.start.node,
end: activeEdge.end.node,
Expand Down
10 changes: 5 additions & 5 deletions src/lang/syntax/matchers/word_matcher.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import * as pt from "@cicada-lang/partech"
import * as Words from "../../word"
import { Word } from "../../word"
import * as Words from "../../words"

export function word_matcher(tree: pt.Tree): Word {
return pt.matcher<Word>({
"word:call": ({ name }, { span }) => new Words.Call(pt.str(name), span),
"word:call": ({ name }, { span }) => Words.Call(pt.str(name), span),
"word:local_set": ({ name }, { span }) =>
new Words.LocalSet(pt.str(name), span),
Words.LocalSet(pt.str(name), span),
"word:port_push": ({ nodeName, portName }, { span }) =>
new Words.PortPush(pt.str(nodeName), pt.str(portName), span),
Words.PortPush(pt.str(nodeName), pt.str(portName), span),
"word:port_reconnect": ({ nodeName, portName }, { span }) =>
new Words.PortReconnect(pt.str(nodeName), pt.str(portName), span),
Words.PortReconnect(pt.str(nodeName), pt.str(portName), span),
})(tree)
}

Expand Down
72 changes: 65 additions & 7 deletions src/lang/word/Word.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,71 @@
import { Node } from "../graph"
import { Mod } from "../mod"
import { Net } from "../net"
import { Span } from "../span"

export interface ComposeOptions {
current?: { start: Node; end: Node }
export type Word = Call | LocalSet | PortPush | PortReconnect

export type Call = {
kind: "Call"
name: string
span: Span
}

export function Call(name: string, span: Span): Call {
return {
kind: "Call",
name,
span,
}
}

export type LocalSet = {
kind: "LocalSet"
name: string
span: Span
}

export function LocalSet(name: string, span: Span): LocalSet {
return {
kind: "LocalSet",
name,
span,
}
}

export type PortPush = {
kind: "PortPush"
nodeName: string
portName: string
span: Span
}

export interface Word {
export function PortPush(
nodeName: string,
portName: string,
span: Span,
): PortPush {
return {
kind: "PortPush",
nodeName,
portName,
span,
}
}

export type PortReconnect = {
kind: "PortReconnect"
nodeName: string
portName: string
span: Span
compose(mod: Mod, net: Net, options?: ComposeOptions): void
}

export function PortReconnect(
nodeName: string,
portName: string,
span: Span,
): PortReconnect {
return {
kind: "PortReconnect",
nodeName,
portName,
span,
}
}
22 changes: 0 additions & 22 deletions src/lang/words/Call.ts

This file was deleted.

22 changes: 0 additions & 22 deletions src/lang/words/LocalSet.ts

This file was deleted.

43 changes: 0 additions & 43 deletions src/lang/words/PortPush.ts

This file was deleted.

50 changes: 0 additions & 50 deletions src/lang/words/PortReconnect.ts

This file was deleted.

4 changes: 0 additions & 4 deletions src/lang/words/index.ts

This file was deleted.

0 comments on commit 6753aea

Please sign in to comment.