@turing-machine-js/builder 6.0.0 → 6.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -12,31 +12,30 @@ Constructs a Turing machine from a declarative state-table object. Every transit
12
12
  import { Tape } from '@turing-machine-js/machine';
13
13
  import buildMachine from '@turing-machine-js/builder';
14
14
 
15
+ // Flip every bit on the tape; halt when the head reaches a blank.
15
16
  const [machine, initialState] = buildMachine({
16
- alphabetString: '_01XY#',
17
- initialState: 'Q8',
18
- finalStateList: ['Q5'],
17
+ alphabetString: ' 01',
18
+ initialState: 'flip',
19
+ finalStateList: ['DONE'],
19
20
  states: {
20
- Q8: { '#': { state: 'Q6', symbol: '#', movement: 'R' } },
21
- Q6: {
22
- '0': { state: 'Q0', symbol: 'X', movement: 'R' },
23
- '1': { state: 'Q1', symbol: 'Y', movement: 'R' },
24
- '#': { state: 'Q2', symbol: '#', movement: 'R' },
21
+ flip: {
22
+ '0': { state: 'flip', symbol: '1', movement: 'R' },
23
+ '1': { state: 'flip', symbol: '0', movement: 'R' },
24
+ ' ': { state: 'DONE', symbol: ' ', movement: 'S' },
25
25
  },
26
- // ... more states ...
27
26
  },
28
27
  });
29
28
 
30
29
  machine.tapeBlock.replaceTape(new Tape({
31
30
  alphabet: machine.tapeBlock.alphabets[0],
32
- symbols: '#011#'.split(''),
31
+ symbols: '0101'.split(''),
33
32
  }));
34
33
 
35
34
  await machine.run({ initialState, stepsLimit: 100 });
36
- // tape now contains: #011#011# (the input duplicated)
35
+ console.log(machine.tapeBlock.tapes[0].symbols.join('').trim()); // "1010"
37
36
  ```
38
37
 
39
- See [`builder.spec.ts`](src/builder.spec.ts) for a complete worked example, including a small parser that reads the `(state,symbol)→(state,symbol,movement);` textual notation often used in textbooks.
38
+ See [`builder.spec.ts`](src/builder.spec.ts) for a longer worked example — a 27-state binary-string-duplicator (input `#011#` → output `#011#011#`) — including a small parser that reads the textbook `(state,symbol)→(state,symbol,movement);` notation.
40
39
 
41
40
  ## Limitations
42
41
 
package/dist/index.cjs CHANGED
@@ -9,7 +9,7 @@ const movementsMap = {
9
9
  };
10
10
  const referenceKey = Symbol('reference');
11
11
  const stateKey = Symbol('state');
12
- function buildMachine({ alphabetString, initialState, finalStateList, states: stateNameToStateDeclarationMap, }) {
12
+ function buildMachine({ alphabetString, initialState, finalStateList, states: stateNameToStateDeclarationMap, debug, }) {
13
13
  const alphabet = new machine.Alphabet(alphabetString.split(''));
14
14
  const machine$1 = new machine.TuringMachine({
15
15
  tapeBlock: machine.TapeBlock.fromAlphabets([alphabet]),
@@ -66,6 +66,40 @@ function buildMachine({ alphabetString, initialState, finalStateList, states: st
66
66
  ...result,
67
67
  [stateName]: stateOrReference[stateKey],
68
68
  }), {});
69
+ // #101: apply per-state debug config. Filter values are raw alphabet
70
+ // characters; translate each via tapeBlock.symbol([char]) so they match
71
+ // the same interned Symbol used in transitions. `true` passes through
72
+ // as-is (wildcard). final-state names are rejected — they alias to
73
+ // haltState which is out of scope per the issue spec.
74
+ if (debug) {
75
+ Object.entries(debug).forEach(([stateName, config]) => {
76
+ if (finalStateList.includes(stateName)) {
77
+ throw new Error(`debug cannot be set on final state '${stateName}': finalStateList `
78
+ + 'entries map to haltState, which is out of scope for the builder. '
79
+ + 'Set haltState.debug directly on the imported singleton if needed.');
80
+ }
81
+ const state = resultStates[stateName];
82
+ if (!state) {
83
+ throw new Error(`debug references unknown state '${stateName}'`);
84
+ }
85
+ const translateFilter = (f) => {
86
+ if (f === undefined)
87
+ return undefined;
88
+ if (f === true)
89
+ return true;
90
+ return f.map((c) => {
91
+ if (!alphabet.has(c)) {
92
+ throw new Error(`debug filter symbol '${c}' for state '${stateName}' is not in the alphabet`);
93
+ }
94
+ return getSymbol([c]);
95
+ });
96
+ };
97
+ state.debug = {
98
+ before: translateFilter(config.before),
99
+ after: translateFilter(config.after),
100
+ };
101
+ });
102
+ }
69
103
  return [
70
104
  machine$1,
71
105
  resultStates[initialState],
package/dist/index.mjs CHANGED
@@ -7,7 +7,7 @@ const movementsMap = {
7
7
  };
8
8
  const referenceKey = Symbol('reference');
9
9
  const stateKey = Symbol('state');
10
- function buildMachine({ alphabetString, initialState, finalStateList, states: stateNameToStateDeclarationMap, }) {
10
+ function buildMachine({ alphabetString, initialState, finalStateList, states: stateNameToStateDeclarationMap, debug, }) {
11
11
  const alphabet = new Alphabet(alphabetString.split(''));
12
12
  const machine = new TuringMachine({
13
13
  tapeBlock: TapeBlock.fromAlphabets([alphabet]),
@@ -64,6 +64,40 @@ function buildMachine({ alphabetString, initialState, finalStateList, states: st
64
64
  ...result,
65
65
  [stateName]: stateOrReference[stateKey],
66
66
  }), {});
67
+ // #101: apply per-state debug config. Filter values are raw alphabet
68
+ // characters; translate each via tapeBlock.symbol([char]) so they match
69
+ // the same interned Symbol used in transitions. `true` passes through
70
+ // as-is (wildcard). final-state names are rejected — they alias to
71
+ // haltState which is out of scope per the issue spec.
72
+ if (debug) {
73
+ Object.entries(debug).forEach(([stateName, config]) => {
74
+ if (finalStateList.includes(stateName)) {
75
+ throw new Error(`debug cannot be set on final state '${stateName}': finalStateList `
76
+ + 'entries map to haltState, which is out of scope for the builder. '
77
+ + 'Set haltState.debug directly on the imported singleton if needed.');
78
+ }
79
+ const state = resultStates[stateName];
80
+ if (!state) {
81
+ throw new Error(`debug references unknown state '${stateName}'`);
82
+ }
83
+ const translateFilter = (f) => {
84
+ if (f === undefined)
85
+ return undefined;
86
+ if (f === true)
87
+ return true;
88
+ return f.map((c) => {
89
+ if (!alphabet.has(c)) {
90
+ throw new Error(`debug filter symbol '${c}' for state '${stateName}' is not in the alphabet`);
91
+ }
92
+ return getSymbol([c]);
93
+ });
94
+ };
95
+ state.debug = {
96
+ before: translateFilter(config.before),
97
+ after: translateFilter(config.after),
98
+ };
99
+ });
100
+ }
67
101
  return [
68
102
  machine,
69
103
  resultStates[initialState],
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@turing-machine-js/builder",
3
- "version": "6.0.0",
3
+ "version": "6.0.1",
4
4
  "description": "A turing machine builder — declarative state-table construction. Not actively developed by the author; the same state-table pattern is also shown as an inline example in @turing-machine-js/machine's README. Contributions welcome.",
5
5
  "engines": {
6
6
  "npm": ">=7.0.0"
7
7
  },
8
- "author": "Ruslan Gilmullin <mellonis14@gmain.com>",
8
+ "author": "Ruslan Gilmullin <mellonis@yandex.ru>",
9
9
  "homepage": "https://github.com/mellonis/turing-machine-js#readme",
10
10
  "license": "GPL-3.0-or-later",
11
11
  "publishConfig": {
@@ -38,5 +38,5 @@
38
38
  "default": "./dist/index.mjs"
39
39
  }
40
40
  },
41
- "gitHead": "6c7b2ac3055470b56c6882471767c746f5a9d7fb"
41
+ "gitHead": "d7ebca4e8379a548e3ca97eb83e96387de2cda32"
42
42
  }