tzo 1.0.18 → 1.0.20

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.
Files changed (186) hide show
  1. package/README.md +284 -280
  2. package/bin/package.json +2 -2
  3. package/bin/tzo +3 -3
  4. package/bin/tzo.mjs +3 -3
  5. package/dist/browser/cli.d.ts +1 -1
  6. package/dist/browser/cli.js +34 -34
  7. package/dist/browser/cli.js.map +1 -1
  8. package/dist/browser/concisetext/ConciseTextLexer.d.ts +30 -30
  9. package/dist/browser/concisetext/ConciseTextLexer.js +122 -122
  10. package/dist/browser/concisetext/ConciseTextListener.d.ts +14 -14
  11. package/dist/browser/concisetext/ConciseTextListener.js +35 -35
  12. package/dist/browser/concisetext/ConciseTextParser.d.ts +99 -99
  13. package/dist/browser/concisetext/ConciseTextParser.js +438 -438
  14. package/dist/browser/getStackParams.d.ts +2 -2
  15. package/dist/browser/getStackParams.js +23 -23
  16. package/dist/browser/index.d.ts +5 -5
  17. package/dist/browser/index.js +17 -17
  18. package/dist/browser/interfaces.d.ts +42 -42
  19. package/dist/browser/interfaces.js +2 -2
  20. package/dist/browser/opcodes/and.d.ts +3 -3
  21. package/dist/browser/opcodes/and.js +8 -8
  22. package/dist/browser/opcodes/charCode.d.ts +3 -3
  23. package/dist/browser/opcodes/charCode.js +9 -9
  24. package/dist/browser/opcodes/closeBrace.d.ts +3 -3
  25. package/dist/browser/opcodes/closeBrace.js +6 -6
  26. package/dist/browser/opcodes/closeBrace.js.map +1 -1
  27. package/dist/browser/opcodes/concat.d.ts +3 -3
  28. package/dist/browser/opcodes/concat.js +8 -8
  29. package/dist/browser/opcodes/delContext.d.ts +3 -3
  30. package/dist/browser/opcodes/delContext.js +8 -8
  31. package/dist/browser/opcodes/dup.d.ts +6 -6
  32. package/dist/browser/opcodes/dup.js +12 -12
  33. package/dist/browser/opcodes/eq.d.ts +3 -3
  34. package/dist/browser/opcodes/eq.js +9 -9
  35. package/dist/browser/opcodes/exit.d.ts +3 -3
  36. package/dist/browser/opcodes/exit.js +6 -6
  37. package/dist/browser/opcodes/getContext.d.ts +3 -3
  38. package/dist/browser/opcodes/getContext.js +12 -12
  39. package/dist/browser/opcodes/goto.d.ts +3 -3
  40. package/dist/browser/opcodes/goto.js +19 -19
  41. package/dist/browser/opcodes/gt.d.ts +3 -3
  42. package/dist/browser/opcodes/gt.js +9 -9
  43. package/dist/browser/opcodes/hasContext.d.ts +3 -3
  44. package/dist/browser/opcodes/hasContext.js +13 -13
  45. package/dist/browser/opcodes/jgz.d.ts +3 -3
  46. package/dist/browser/opcodes/jgz.js +10 -10
  47. package/dist/browser/opcodes/jz.d.ts +3 -3
  48. package/dist/browser/opcodes/jz.js +10 -10
  49. package/dist/browser/opcodes/lt.d.ts +3 -3
  50. package/dist/browser/opcodes/lt.js +9 -9
  51. package/dist/browser/opcodes/min.d.ts +3 -3
  52. package/dist/browser/opcodes/min.js +10 -10
  53. package/dist/browser/opcodes/mul.d.ts +3 -3
  54. package/dist/browser/opcodes/mul.js +10 -10
  55. package/dist/browser/opcodes/nop.d.ts +6 -6
  56. package/dist/browser/opcodes/nop.js +9 -9
  57. package/dist/browser/opcodes/not.d.ts +6 -6
  58. package/dist/browser/opcodes/not.js +16 -16
  59. package/dist/browser/opcodes/openBrace.d.ts +3 -3
  60. package/dist/browser/opcodes/openBrace.js +20 -20
  61. package/dist/browser/opcodes/openBrace.js.map +1 -1
  62. package/dist/browser/opcodes/or.d.ts +3 -3
  63. package/dist/browser/opcodes/or.js +8 -8
  64. package/dist/browser/opcodes/pause.d.ts +3 -3
  65. package/dist/browser/opcodes/pause.js +6 -6
  66. package/dist/browser/opcodes/plus.d.ts +3 -3
  67. package/dist/browser/opcodes/plus.js +10 -10
  68. package/dist/browser/opcodes/pop.d.ts +3 -3
  69. package/dist/browser/opcodes/pop.js +6 -6
  70. package/dist/browser/opcodes/ppc.d.ts +6 -6
  71. package/dist/browser/opcodes/ppc.js +9 -9
  72. package/dist/browser/opcodes/randInt.d.ts +3 -3
  73. package/dist/browser/opcodes/randInt.js +9 -9
  74. package/dist/browser/opcodes/rconcat.d.ts +3 -3
  75. package/dist/browser/opcodes/rconcat.js +8 -8
  76. package/dist/browser/opcodes/setContext.d.ts +3 -3
  77. package/dist/browser/opcodes/setContext.js +8 -8
  78. package/dist/browser/opcodes/stacksize.d.ts +3 -3
  79. package/dist/browser/opcodes/stacksize.js +6 -6
  80. package/dist/browser/opcodes/stdout.d.ts +3 -3
  81. package/dist/browser/opcodes/stdout.js +6 -6
  82. package/dist/browser/util/builder.d.ts +12 -12
  83. package/dist/browser/util/builder.js +37 -37
  84. package/dist/browser/util/fix_antlr_grammar_ts.d.ts +1 -1
  85. package/dist/browser/util/fix_antlr_grammar_ts.js +7 -7
  86. package/dist/browser/util/tokenizer.d.ts +20 -20
  87. package/dist/browser/util/tokenizer.js +176 -176
  88. package/dist/browser/util/tokenizer.js.map +1 -1
  89. package/dist/browser/vm.d.ts +26 -26
  90. package/dist/browser/vm.js +201 -201
  91. package/dist/browser/vm.test.d.ts +1 -1
  92. package/dist/browser/vm.test.js +398 -355
  93. package/dist/browser/vm.test.js.map +1 -1
  94. package/dist/node/cli.d.ts +1 -1
  95. package/dist/node/cli.js +34 -34
  96. package/dist/node/cli.js.map +1 -1
  97. package/dist/node/concisetext/ConciseTextLexer.d.ts +30 -30
  98. package/dist/node/concisetext/ConciseTextLexer.js +122 -122
  99. package/dist/node/concisetext/ConciseTextListener.d.ts +14 -14
  100. package/dist/node/concisetext/ConciseTextListener.js +35 -35
  101. package/dist/node/concisetext/ConciseTextParser.d.ts +99 -99
  102. package/dist/node/concisetext/ConciseTextParser.js +438 -438
  103. package/dist/node/getStackParams.d.ts +2 -2
  104. package/dist/node/getStackParams.js +23 -23
  105. package/dist/node/index.d.ts +5 -5
  106. package/dist/node/index.js +17 -17
  107. package/dist/node/interfaces.d.ts +42 -42
  108. package/dist/node/interfaces.js +2 -2
  109. package/dist/node/opcodes/and.d.ts +3 -3
  110. package/dist/node/opcodes/and.js +8 -8
  111. package/dist/node/opcodes/charCode.d.ts +3 -3
  112. package/dist/node/opcodes/charCode.js +9 -9
  113. package/dist/node/opcodes/closeBrace.d.ts +3 -3
  114. package/dist/node/opcodes/closeBrace.js +6 -6
  115. package/dist/node/opcodes/closeBrace.js.map +1 -1
  116. package/dist/node/opcodes/concat.d.ts +3 -3
  117. package/dist/node/opcodes/concat.js +8 -8
  118. package/dist/node/opcodes/delContext.d.ts +3 -3
  119. package/dist/node/opcodes/delContext.js +8 -8
  120. package/dist/node/opcodes/dup.d.ts +6 -6
  121. package/dist/node/opcodes/dup.js +12 -12
  122. package/dist/node/opcodes/eq.d.ts +3 -3
  123. package/dist/node/opcodes/eq.js +9 -9
  124. package/dist/node/opcodes/exit.d.ts +3 -3
  125. package/dist/node/opcodes/exit.js +6 -6
  126. package/dist/node/opcodes/getContext.d.ts +3 -3
  127. package/dist/node/opcodes/getContext.js +12 -12
  128. package/dist/node/opcodes/goto.d.ts +3 -3
  129. package/dist/node/opcodes/goto.js +19 -19
  130. package/dist/node/opcodes/gt.d.ts +3 -3
  131. package/dist/node/opcodes/gt.js +9 -9
  132. package/dist/node/opcodes/hasContext.d.ts +3 -3
  133. package/dist/node/opcodes/hasContext.js +13 -13
  134. package/dist/node/opcodes/jgz.d.ts +3 -3
  135. package/dist/node/opcodes/jgz.js +10 -10
  136. package/dist/node/opcodes/jz.d.ts +3 -3
  137. package/dist/node/opcodes/jz.js +10 -10
  138. package/dist/node/opcodes/lt.d.ts +3 -3
  139. package/dist/node/opcodes/lt.js +9 -9
  140. package/dist/node/opcodes/min.d.ts +3 -3
  141. package/dist/node/opcodes/min.js +10 -10
  142. package/dist/node/opcodes/mul.d.ts +3 -3
  143. package/dist/node/opcodes/mul.js +10 -10
  144. package/dist/node/opcodes/nop.d.ts +6 -6
  145. package/dist/node/opcodes/nop.js +9 -9
  146. package/dist/node/opcodes/not.d.ts +6 -6
  147. package/dist/node/opcodes/not.js +16 -16
  148. package/dist/node/opcodes/openBrace.d.ts +3 -3
  149. package/dist/node/opcodes/openBrace.js +20 -20
  150. package/dist/node/opcodes/openBrace.js.map +1 -1
  151. package/dist/node/opcodes/or.d.ts +3 -3
  152. package/dist/node/opcodes/or.js +8 -8
  153. package/dist/node/opcodes/pause.d.ts +3 -3
  154. package/dist/node/opcodes/pause.js +6 -6
  155. package/dist/node/opcodes/plus.d.ts +3 -3
  156. package/dist/node/opcodes/plus.js +10 -10
  157. package/dist/node/opcodes/pop.d.ts +3 -3
  158. package/dist/node/opcodes/pop.js +6 -6
  159. package/dist/node/opcodes/ppc.d.ts +6 -6
  160. package/dist/node/opcodes/ppc.js +9 -9
  161. package/dist/node/opcodes/randInt.d.ts +3 -3
  162. package/dist/node/opcodes/randInt.js +9 -9
  163. package/dist/node/opcodes/rconcat.d.ts +3 -3
  164. package/dist/node/opcodes/rconcat.js +8 -8
  165. package/dist/node/opcodes/setContext.d.ts +3 -3
  166. package/dist/node/opcodes/setContext.js +8 -8
  167. package/dist/node/opcodes/stacksize.d.ts +3 -3
  168. package/dist/node/opcodes/stacksize.js +6 -6
  169. package/dist/node/opcodes/stdout.d.ts +3 -3
  170. package/dist/node/opcodes/stdout.js +6 -6
  171. package/dist/node/util/builder.d.ts +12 -12
  172. package/dist/node/util/builder.js +37 -37
  173. package/dist/node/util/fix_antlr_grammar_ts.d.ts +1 -1
  174. package/dist/node/util/fix_antlr_grammar_ts.js +7 -7
  175. package/dist/node/util/tokenizer.d.ts +20 -20
  176. package/dist/node/util/tokenizer.js +176 -176
  177. package/dist/node/util/tokenizer.js.map +1 -1
  178. package/dist/node/vm.d.ts +26 -26
  179. package/dist/node/vm.js +201 -201
  180. package/dist/node/vm.test.d.ts +1 -1
  181. package/dist/node/vm.test.js +398 -355
  182. package/dist/node/vm.test.js.map +1 -1
  183. package/jest.config.js +4 -4
  184. package/package.json +50 -50
  185. package/tsconfig-browser.json +8 -8
  186. package/tsconfig.json +28 -28
package/dist/node/vm.js CHANGED
@@ -1,202 +1,202 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.VM = exports.std_functions = void 0;
7
- const debug_1 = __importDefault(require("debug"));
8
- const and_1 = __importDefault(require("./opcodes/and"));
9
- const charCode_1 = __importDefault(require("./opcodes/charCode"));
10
- const closeBrace_1 = __importDefault(require("./opcodes/closeBrace"));
11
- const concat_1 = __importDefault(require("./opcodes/concat"));
12
- const delContext_1 = __importDefault(require("./opcodes/delContext"));
13
- const dup_1 = __importDefault(require("./opcodes/dup"));
14
- const eq_1 = __importDefault(require("./opcodes/eq"));
15
- const exit_1 = __importDefault(require("./opcodes/exit"));
16
- const getContext_1 = __importDefault(require("./opcodes/getContext"));
17
- const hasContext_1 = __importDefault(require("./opcodes/hasContext"));
18
- const goto_1 = __importDefault(require("./opcodes/goto"));
19
- const gt_1 = __importDefault(require("./opcodes/gt"));
20
- const jgz_1 = __importDefault(require("./opcodes/jgz"));
21
- const jz_1 = __importDefault(require("./opcodes/jz"));
22
- const lt_1 = __importDefault(require("./opcodes/lt"));
23
- const min_1 = __importDefault(require("./opcodes/min"));
24
- const mul_1 = __importDefault(require("./opcodes/mul"));
25
- const nop_1 = __importDefault(require("./opcodes/nop"));
26
- const not_1 = __importDefault(require("./opcodes/not"));
27
- const openBrace_1 = __importDefault(require("./opcodes/openBrace"));
28
- const or_1 = __importDefault(require("./opcodes/or"));
29
- const pause_1 = __importDefault(require("./opcodes/pause"));
30
- const plus_1 = __importDefault(require("./opcodes/plus"));
31
- const pop_1 = __importDefault(require("./opcodes/pop"));
32
- const ppc_1 = __importDefault(require("./opcodes/ppc"));
33
- const randInt_1 = __importDefault(require("./opcodes/randInt"));
34
- const rconcat_1 = __importDefault(require("./opcodes/rconcat"));
35
- const setContext_1 = __importDefault(require("./opcodes/setContext"));
36
- const stacksize_1 = __importDefault(require("./opcodes/stacksize"));
37
- const stdout_1 = __importDefault(require("./opcodes/stdout"));
38
- exports.std_functions = {
39
- "randInt": randInt_1.default,
40
- "charCode": charCode_1.default,
41
- "+": plus_1.default,
42
- "plus": plus_1.default,
43
- "-": min_1.default,
44
- "min": min_1.default,
45
- "*": mul_1.default,
46
- "mul": mul_1.default,
47
- "not": not_1.default,
48
- "concat": concat_1.default,
49
- "rconcat": rconcat_1.default,
50
- "getContext": getContext_1.default,
51
- "hasContext": hasContext_1.default,
52
- "setContext": setContext_1.default,
53
- "delContext": delContext_1.default,
54
- "gt": gt_1.default,
55
- "lt": lt_1.default,
56
- "eq": eq_1.default,
57
- "jgz": jgz_1.default,
58
- "jz": jz_1.default,
59
- "exit": exit_1.default,
60
- "pause": pause_1.default,
61
- "goto": goto_1.default,
62
- "{": openBrace_1.default,
63
- "}": closeBrace_1.default,
64
- "ppc": ppc_1.default,
65
- "nop": nop_1.default,
66
- "and": and_1.default,
67
- "or": or_1.default,
68
- "dup": dup_1.default,
69
- "pop": pop_1.default,
70
- "stacksize": stacksize_1.default,
71
- "stdout": stdout_1.default,
72
- };
73
- class VM {
74
- constructor(initialContext, additionalFunctions = {}) {
75
- this.stack = [];
76
- this.context = {};
77
- this.programList = [];
78
- this.labelMap = {};
79
- this.programCounter = 0;
80
- this.exit = false;
81
- this.pause = false;
82
- this.logger = debug_1.default("tzo-vm");
83
- this.context = initialContext;
84
- this.functions = Object.assign(Object.assign({}, exports.std_functions), additionalFunctions);
85
- }
86
- quit() {
87
- this.exit = true;
88
- }
89
- suspend() {
90
- this.pause = true;
91
- }
92
- invoke(instructions) {
93
- this.logger("invoking!");
94
- let retval = undefined;
95
- instructions.forEach(instruction => {
96
- this.logger(`stack (json): ${JSON.stringify(this.stack)}`);
97
- retval = instruction(this.stack, this.context, this);
98
- });
99
- this.logger(`done! return value: ${retval}, final stack: ${JSON.stringify(this.stack)}, final context: ${JSON.stringify(this.context)}`);
100
- return retval;
101
- }
102
- getVMInstructions(instructions, labelMap) {
103
- if (labelMap === undefined) {
104
- labelMap = {};
105
- }
106
- const vmInstructions = instructions.map((instruction, instrIndex) => {
107
- if (instruction.label !== undefined) {
108
- if (labelMap[instruction.label] === undefined) {
109
- labelMap[instruction.label] = instrIndex;
110
- }
111
- else {
112
- throw new Error(`label already defined: ${instruction.label}!`);
113
- }
114
- }
115
- switch (instruction.type) {
116
- case "invoke-function-instruction":
117
- const functionNameToPush = instruction.functionName;
118
- let functionToPush = this.functions[functionNameToPush];
119
- if (functionToPush === undefined) {
120
- if (functionNameToPush.startsWith("_")) { // do not throw errors when function name starts with underscore
121
- const x = () => {
122
- this.logger(`Missing function got invoked: ${functionNameToPush}!`);
123
- };
124
- functionToPush = x;
125
- }
126
- else {
127
- throw new Error(`Cannot find function in function table: ${functionNameToPush}`);
128
- }
129
- }
130
- return functionToPush;
131
- break;
132
- case "push-number-instruction":
133
- return ((stack) => {
134
- const v = instruction.value;
135
- this.logger(`pushNumber: ${v}`);
136
- stack.push(v);
137
- return instruction.value;
138
- });
139
- break;
140
- case "push-string-instruction":
141
- return ((stack) => {
142
- const v = instruction.value;
143
- this.logger(`pushString: ${v}`);
144
- stack.push(v);
145
- return instruction.value;
146
- });
147
- break;
148
- default:
149
- throw new Error(`Unsupported instruction type!`);
150
- }
151
- });
152
- return { vmInstructions, labelMap };
153
- }
154
- loadProgramList(instructions, labelMap) {
155
- const parsed_instructions = this.getVMInstructions(instructions, labelMap);
156
- this.programList = parsed_instructions.vmInstructions;
157
- this.labelMap = parsed_instructions.labelMap;
158
- }
159
- loadVMState(tzoVMState) {
160
- const parsed_instructions = this.getVMInstructions(tzoVMState.programList, tzoVMState.labelMap);
161
- this.programList = parsed_instructions.vmInstructions;
162
- this.labelMap = parsed_instructions.labelMap;
163
- this.stack = tzoVMState.stack;
164
- this.context = tzoVMState.context;
165
- this.programCounter = tzoVMState.programCounter;
166
- this.pause = tzoVMState.pause;
167
- this.exit = tzoVMState.exit;
168
- }
169
- setProgramCounter(c) {
170
- this.programCounter = c;
171
- }
172
- tick() {
173
- /**
174
- * Execute one instruction from program list
175
- */
176
- const instruction = this.programList[this.programCounter];
177
- if (instruction === undefined) {
178
- this.exit = true;
179
- return null;
180
- }
181
- const oldPC = this.programCounter;
182
- instruction(this.stack, this.context, this);
183
- if (this.programCounter === oldPC) { // if the program counter did not change, increment by one!
184
- this.programCounter += 1;
185
- }
186
- }
187
- run() {
188
- this.pause = false;
189
- while (this.exit !== true && this.pause !== true) {
190
- try {
191
- this.tick();
192
- }
193
- catch (e) {
194
- const err = new Error(`An error occurred!\nStack: ${this.stack}\nPC: ${this.programCounter}\nContext: ${JSON.stringify(this.context)}\nerr: ${e}`);
195
- this.logger(err);
196
- throw err;
197
- }
198
- }
199
- }
200
- }
201
- exports.VM = VM;
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.VM = exports.std_functions = void 0;
7
+ const debug_1 = __importDefault(require("debug"));
8
+ const and_1 = __importDefault(require("./opcodes/and"));
9
+ const charCode_1 = __importDefault(require("./opcodes/charCode"));
10
+ const closeBrace_1 = __importDefault(require("./opcodes/closeBrace"));
11
+ const concat_1 = __importDefault(require("./opcodes/concat"));
12
+ const delContext_1 = __importDefault(require("./opcodes/delContext"));
13
+ const dup_1 = __importDefault(require("./opcodes/dup"));
14
+ const eq_1 = __importDefault(require("./opcodes/eq"));
15
+ const exit_1 = __importDefault(require("./opcodes/exit"));
16
+ const getContext_1 = __importDefault(require("./opcodes/getContext"));
17
+ const hasContext_1 = __importDefault(require("./opcodes/hasContext"));
18
+ const goto_1 = __importDefault(require("./opcodes/goto"));
19
+ const gt_1 = __importDefault(require("./opcodes/gt"));
20
+ const jgz_1 = __importDefault(require("./opcodes/jgz"));
21
+ const jz_1 = __importDefault(require("./opcodes/jz"));
22
+ const lt_1 = __importDefault(require("./opcodes/lt"));
23
+ const min_1 = __importDefault(require("./opcodes/min"));
24
+ const mul_1 = __importDefault(require("./opcodes/mul"));
25
+ const nop_1 = __importDefault(require("./opcodes/nop"));
26
+ const not_1 = __importDefault(require("./opcodes/not"));
27
+ const openBrace_1 = __importDefault(require("./opcodes/openBrace"));
28
+ const or_1 = __importDefault(require("./opcodes/or"));
29
+ const pause_1 = __importDefault(require("./opcodes/pause"));
30
+ const plus_1 = __importDefault(require("./opcodes/plus"));
31
+ const pop_1 = __importDefault(require("./opcodes/pop"));
32
+ const ppc_1 = __importDefault(require("./opcodes/ppc"));
33
+ const randInt_1 = __importDefault(require("./opcodes/randInt"));
34
+ const rconcat_1 = __importDefault(require("./opcodes/rconcat"));
35
+ const setContext_1 = __importDefault(require("./opcodes/setContext"));
36
+ const stacksize_1 = __importDefault(require("./opcodes/stacksize"));
37
+ const stdout_1 = __importDefault(require("./opcodes/stdout"));
38
+ exports.std_functions = {
39
+ "randInt": randInt_1.default,
40
+ "charCode": charCode_1.default,
41
+ "+": plus_1.default,
42
+ "plus": plus_1.default,
43
+ "-": min_1.default,
44
+ "min": min_1.default,
45
+ "*": mul_1.default,
46
+ "mul": mul_1.default,
47
+ "not": not_1.default,
48
+ "concat": concat_1.default,
49
+ "rconcat": rconcat_1.default,
50
+ "getContext": getContext_1.default,
51
+ "hasContext": hasContext_1.default,
52
+ "setContext": setContext_1.default,
53
+ "delContext": delContext_1.default,
54
+ "gt": gt_1.default,
55
+ "lt": lt_1.default,
56
+ "eq": eq_1.default,
57
+ "jgz": jgz_1.default,
58
+ "jz": jz_1.default,
59
+ "exit": exit_1.default,
60
+ "pause": pause_1.default,
61
+ "goto": goto_1.default,
62
+ "{": openBrace_1.default,
63
+ "}": closeBrace_1.default,
64
+ "ppc": ppc_1.default,
65
+ "nop": nop_1.default,
66
+ "and": and_1.default,
67
+ "or": or_1.default,
68
+ "dup": dup_1.default,
69
+ "pop": pop_1.default,
70
+ "stacksize": stacksize_1.default,
71
+ "stdout": stdout_1.default,
72
+ };
73
+ class VM {
74
+ constructor(initialContext, additionalFunctions = {}) {
75
+ this.stack = [];
76
+ this.context = {};
77
+ this.programList = [];
78
+ this.labelMap = {};
79
+ this.programCounter = 0;
80
+ this.exit = false;
81
+ this.pause = false;
82
+ this.logger = debug_1.default("tzo-vm");
83
+ this.context = initialContext;
84
+ this.functions = Object.assign(Object.assign({}, exports.std_functions), additionalFunctions);
85
+ }
86
+ quit() {
87
+ this.exit = true;
88
+ }
89
+ suspend() {
90
+ this.pause = true;
91
+ }
92
+ invoke(instructions) {
93
+ this.logger("invoking!");
94
+ let retval = undefined;
95
+ instructions.forEach(instruction => {
96
+ this.logger(`stack (json): ${JSON.stringify(this.stack)}`);
97
+ retval = instruction(this.stack, this.context, this);
98
+ });
99
+ this.logger(`done! return value: ${retval}, final stack: ${JSON.stringify(this.stack)}, final context: ${JSON.stringify(this.context)}`);
100
+ return retval;
101
+ }
102
+ getVMInstructions(instructions, labelMap) {
103
+ if (labelMap === undefined) {
104
+ labelMap = {};
105
+ }
106
+ const vmInstructions = instructions.map((instruction, instrIndex) => {
107
+ if (instruction.label !== undefined) {
108
+ if (labelMap[instruction.label] === undefined) {
109
+ labelMap[instruction.label] = instrIndex;
110
+ }
111
+ else {
112
+ throw new Error(`label already defined: ${instruction.label}!`);
113
+ }
114
+ }
115
+ switch (instruction.type) {
116
+ case "invoke-function-instruction":
117
+ const functionNameToPush = instruction.functionName;
118
+ let functionToPush = this.functions[functionNameToPush];
119
+ if (functionToPush === undefined) {
120
+ if (functionNameToPush.startsWith("_")) { // do not throw errors when function name starts with underscore
121
+ const x = () => {
122
+ this.logger(`Missing function got invoked: ${functionNameToPush}!`);
123
+ };
124
+ functionToPush = x;
125
+ }
126
+ else {
127
+ throw new Error(`Cannot find function in function table: ${functionNameToPush}`);
128
+ }
129
+ }
130
+ return functionToPush;
131
+ break;
132
+ case "push-number-instruction":
133
+ return ((stack) => {
134
+ const v = instruction.value;
135
+ this.logger(`pushNumber: ${v}`);
136
+ stack.push(v);
137
+ return instruction.value;
138
+ });
139
+ break;
140
+ case "push-string-instruction":
141
+ return ((stack) => {
142
+ const v = instruction.value;
143
+ this.logger(`pushString: ${v}`);
144
+ stack.push(v);
145
+ return instruction.value;
146
+ });
147
+ break;
148
+ default:
149
+ throw new Error(`Unsupported instruction type!`);
150
+ }
151
+ });
152
+ return { vmInstructions, labelMap };
153
+ }
154
+ loadProgramList(instructions, labelMap) {
155
+ const parsed_instructions = this.getVMInstructions(instructions, labelMap);
156
+ this.programList = parsed_instructions.vmInstructions;
157
+ this.labelMap = parsed_instructions.labelMap;
158
+ }
159
+ loadVMState(tzoVMState) {
160
+ const parsed_instructions = this.getVMInstructions(tzoVMState.programList, tzoVMState.labelMap);
161
+ this.programList = parsed_instructions.vmInstructions;
162
+ this.labelMap = parsed_instructions.labelMap;
163
+ this.stack = tzoVMState.stack;
164
+ this.context = tzoVMState.context;
165
+ this.programCounter = tzoVMState.programCounter;
166
+ this.pause = tzoVMState.pause;
167
+ this.exit = tzoVMState.exit;
168
+ }
169
+ setProgramCounter(c) {
170
+ this.programCounter = c;
171
+ }
172
+ tick() {
173
+ /**
174
+ * Execute one instruction from program list
175
+ */
176
+ const instruction = this.programList[this.programCounter];
177
+ if (instruction === undefined) {
178
+ this.exit = true;
179
+ return null;
180
+ }
181
+ const oldPC = this.programCounter;
182
+ instruction(this.stack, this.context, this);
183
+ if (this.programCounter === oldPC) { // if the program counter did not change, increment by one!
184
+ this.programCounter += 1;
185
+ }
186
+ }
187
+ run() {
188
+ this.pause = false;
189
+ while (this.exit !== true && this.pause !== true) {
190
+ try {
191
+ this.tick();
192
+ }
193
+ catch (e) {
194
+ const err = new Error(`An error occurred!\nStack: ${this.stack}\nPC: ${this.programCounter}\nContext: ${JSON.stringify(this.context)}\nerr: ${e}`);
195
+ this.logger(err);
196
+ throw err;
197
+ }
198
+ }
199
+ }
200
+ }
201
+ exports.VM = VM;
202
202
  //# sourceMappingURL=vm.js.map
@@ -1 +1 @@
1
- export {};
1
+ export {};