vladx 1.0.0

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 (42) hide show
  1. package/README.md +256 -0
  2. package/bin/cli.js +486 -0
  3. package/bin/vlad.js +539 -0
  4. package/bin/vladpm.js +710 -0
  5. package/bin/vladx.js +491 -0
  6. package/package.json +57 -0
  7. package/src/engine/jit-compiler.js +285 -0
  8. package/src/engine/vladx-engine.js +941 -0
  9. package/src/index.js +44 -0
  10. package/src/interpreter/interpreter.js +2114 -0
  11. package/src/lexer/lexer.js +658 -0
  12. package/src/lexer/optimized-lexer.js +106 -0
  13. package/src/lexer/regex-cache.js +83 -0
  14. package/src/parser/ast-nodes.js +472 -0
  15. package/src/parser/parser.js +1408 -0
  16. package/src/runtime/advanced-type-system.js +209 -0
  17. package/src/runtime/async-manager.js +252 -0
  18. package/src/runtime/builtins.js +143 -0
  19. package/src/runtime/bundler.js +422 -0
  20. package/src/runtime/cache-manager.js +126 -0
  21. package/src/runtime/data-structures.js +612 -0
  22. package/src/runtime/debugger.js +260 -0
  23. package/src/runtime/enhanced-module-system.js +196 -0
  24. package/src/runtime/environment-enhanced.js +272 -0
  25. package/src/runtime/environment.js +140 -0
  26. package/src/runtime/event-emitter.js +232 -0
  27. package/src/runtime/formatter.js +280 -0
  28. package/src/runtime/functional.js +359 -0
  29. package/src/runtime/io-operations.js +390 -0
  30. package/src/runtime/linter.js +374 -0
  31. package/src/runtime/logging.js +314 -0
  32. package/src/runtime/minifier.js +242 -0
  33. package/src/runtime/module-system.js +377 -0
  34. package/src/runtime/network-operations.js +373 -0
  35. package/src/runtime/profiler.js +295 -0
  36. package/src/runtime/repl.js +336 -0
  37. package/src/runtime/security-manager.js +244 -0
  38. package/src/runtime/source-map-generator.js +208 -0
  39. package/src/runtime/test-runner.js +394 -0
  40. package/src/runtime/transformer.js +277 -0
  41. package/src/runtime/type-system.js +244 -0
  42. package/src/runtime/vladx-object.js +250 -0
@@ -0,0 +1,277 @@
1
+ /**
2
+ * Transformer — AST трансформации
3
+ */
4
+
5
+ export class Transformer {
6
+ constructor() {
7
+ this.plugins = [];
8
+ }
9
+
10
+ /**
11
+ * Добавить плагин
12
+ */
13
+ use(plugin) {
14
+ this.plugins.push(plugin);
15
+ return this;
16
+ }
17
+
18
+ /**
19
+ * Применить трансформации к AST
20
+ */
21
+ transform(ast) {
22
+ let transformed = ast;
23
+
24
+ for (const plugin of this.plugins) {
25
+ transformed = plugin(transformed, this.traverse);
26
+ }
27
+
28
+ return transformed;
29
+ }
30
+
31
+ /**
32
+ * Траверс AST
33
+ */
34
+ traverse(node, visitor) {
35
+ if (!node || typeof node !== 'object') {
36
+ return;
37
+ }
38
+
39
+ // Enter
40
+ if (visitor.enter) {
41
+ const result = visitor.enter(node);
42
+ if (result === false) return;
43
+ if (result !== undefined) node = result;
44
+ }
45
+
46
+ // Traverse children
47
+ const traverseNode = (child) => {
48
+ if (Array.isArray(child)) {
49
+ child.forEach(c => this.traverse(c, visitor));
50
+ } else if (typeof child === 'object' && child !== null) {
51
+ this.traverse(child, visitor);
52
+ }
53
+ };
54
+
55
+ for (const key in node) {
56
+ if (key === 'parent') continue;
57
+
58
+ const child = node[key];
59
+ if (child === node) continue;
60
+
61
+ traverseNode(child);
62
+ }
63
+
64
+ // Exit
65
+ if (visitor.exit) {
66
+ const result = visitor.exit(node);
67
+ if (result !== undefined) node = result;
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Найти узлы по типу
73
+ */
74
+ find(ast, type) {
75
+ const results = [];
76
+
77
+ this.traverse(ast, {
78
+ enter: (node) => {
79
+ if (node.type === type) {
80
+ results.push(node);
81
+ }
82
+ }
83
+ });
84
+
85
+ return results;
86
+ }
87
+
88
+ /**
89
+ * Заменить узлы по типу
90
+ */
91
+ replace(ast, type, replacer) {
92
+ this.traverse(ast, {
93
+ enter: (node, parent) => {
94
+ if (node.type === type) {
95
+ const replacement = replacer(node);
96
+ if (parent) {
97
+ for (const key in parent) {
98
+ if (parent[key] === node) {
99
+ parent[key] = replacement;
100
+ break;
101
+ }
102
+ if (Array.isArray(parent[key])) {
103
+ const index = parent[key].indexOf(node);
104
+ if (index !== -1) {
105
+ parent[key][index] = replacement;
106
+ }
107
+ }
108
+ }
109
+ }
110
+ }
111
+ }
112
+ });
113
+
114
+ return ast;
115
+ }
116
+
117
+ /**
118
+ * Встроенные плагины
119
+ */
120
+
121
+ /**
122
+ * Плагин: hoisting - поднятие объявлений
123
+ */
124
+ static hoisting() {
125
+ return (ast, traverse) => {
126
+ const declarations = [];
127
+
128
+ traverse(ast, {
129
+ enter: (node) => {
130
+ if (node.type === 'LetStatement' || node.type === 'ConstStatement') {
131
+ declarations.push(node);
132
+ }
133
+ }
134
+ });
135
+
136
+ // Переместить объявления в начало
137
+ for (const decl of declarations) {
138
+ // Логика hoisting...
139
+ }
140
+
141
+ return ast;
142
+ };
143
+ }
144
+
145
+ /**
146
+ * Плагин: constant folding - вычисление констант во время компиляции
147
+ */
148
+ static constantFolding() {
149
+ return (ast, traverse) => {
150
+ traverse(ast, {
151
+ enter: (node) => {
152
+ if (node.type === 'BinaryExpression') {
153
+ if (node.left.type === 'Literal' && node.right.type === 'Literal') {
154
+ if (typeof node.left.value === 'number' && typeof node.right.value === 'number') {
155
+ let result;
156
+ switch (node.operator) {
157
+ case '+': result = node.left.value + node.right.value; break;
158
+ case '-': result = node.left.value - node.right.value; break;
159
+ case '*': result = node.left.value * node.right.value; break;
160
+ case '/': result = node.left.value / node.right.value; break;
161
+ case '%': result = node.left.value % node.right.value; break;
162
+ case '**': result = Math.pow(node.left.value, node.right.value); break;
163
+ default: return;
164
+ }
165
+
166
+ node.type = 'Literal';
167
+ node.value = result;
168
+ delete node.left;
169
+ delete node.right;
170
+ delete node.operator;
171
+ }
172
+ }
173
+ }
174
+ }
175
+ });
176
+
177
+ return ast;
178
+ };
179
+ }
180
+
181
+ /**
182
+ * Плагин: dead code elimination - удаление мертвого кода
183
+ */
184
+ static deadCodeElimination() {
185
+ return (ast, traverse) => {
186
+ let unreachable = false;
187
+
188
+ traverse(ast, {
189
+ enter: (node) => {
190
+ if (node.type === 'ReturnStatement' || node.type === 'ThrowStatement') {
191
+ unreachable = true;
192
+ } else if (unreachable && node.type !== 'FunctionDeclaration') {
193
+ node.removed = true;
194
+ } else {
195
+ unreachable = false;
196
+ }
197
+ }
198
+ });
199
+
200
+ return ast;
201
+ };
202
+ }
203
+
204
+ /**
205
+ * Плагин: inline small functions - inline маленьких функций
206
+ */
207
+ static inlineFunctions() {
208
+ return (ast, traverse) => {
209
+ const functions = new Map();
210
+
211
+ // Найти маленькие функции
212
+ traverse(ast, {
213
+ enter: (node) => {
214
+ if (node.type === 'FunctionDeclaration') {
215
+ const bodySize = node.thenBranch?.body?.length || 0;
216
+ if (bodySize <= 3) {
217
+ functions.set(node.name, node);
218
+ }
219
+ }
220
+ }
221
+ });
222
+
223
+ // Inline функции
224
+ traverse(ast, {
225
+ enter: (node) => {
226
+ if (node.type === 'CallExpression' && node.callee.type === 'Identifier') {
227
+ const func = functions.get(node.callee.name);
228
+ if (func) {
229
+ node.type = 'BlockStatement';
230
+ node.body = func.thenBranch?.body || [];
231
+ }
232
+ }
233
+ }
234
+ });
235
+
236
+ return ast;
237
+ };
238
+ }
239
+
240
+ /**
241
+ * Плагин: simplify conditionals - упрощение условий
242
+ */
243
+ static simplifyConditionals() {
244
+ return (ast, traverse) => {
245
+ traverse(ast, {
246
+ enter: (node) => {
247
+ if (node.type === 'IfStatement') {
248
+ const condition = node.condition;
249
+
250
+ // if (true) { ... }
251
+ if (condition.type === 'Literal' && condition.value === true) {
252
+ node.type = 'BlockStatement';
253
+ node.body = node.thenBranch?.body || [];
254
+ delete node.condition;
255
+ delete node.thenBranch;
256
+ delete node.elseBranch;
257
+ }
258
+
259
+ // if (false) { ... } else { ... }
260
+ if (condition.type === 'Literal' && condition.value === false) {
261
+ if (node.elseBranch) {
262
+ node.type = 'BlockStatement';
263
+ node.body = node.elseBranch.thenBranch?.body || [];
264
+ } else {
265
+ node.removed = true;
266
+ }
267
+ }
268
+ }
269
+ }
270
+ });
271
+
272
+ return ast;
273
+ };
274
+ }
275
+ }
276
+
277
+ export default Transformer;
@@ -0,0 +1,244 @@
1
+ /**
2
+ * VladX Type System — Система типов для статической типизации
3
+ */
4
+
5
+ import { VladXObject } from './vladx-object.js';
6
+
7
+ export class TypeSystem {
8
+ constructor() {
9
+ this.types = new Map();
10
+ this.initializeBuiltInTypes();
11
+ }
12
+
13
+ /**
14
+ * Инициализация встроенных типов
15
+ */
16
+ initializeBuiltInTypes() {
17
+ // Базовые типы
18
+ this.types.set('число', {
19
+ name: 'число',
20
+ check: (value) => {
21
+ if (value && typeof value === 'object' && 'value' in value) {
22
+ return typeof value.value === 'number' && !isNaN(value.value);
23
+ }
24
+ return typeof value === 'number' && !isNaN(value);
25
+ },
26
+ defaultValue: 0
27
+ });
28
+
29
+ this.types.set('строка', {
30
+ name: 'строка',
31
+ check: (value) => {
32
+ if (value && typeof value === 'object' && 'value' in value) {
33
+ return typeof value.value === 'string';
34
+ }
35
+ return typeof value === 'string';
36
+ },
37
+ defaultValue: ''
38
+ });
39
+
40
+ this.types.set('логический', {
41
+ name: 'логический',
42
+ check: (value) => {
43
+ if (value && typeof value === 'object' && 'value' in value) {
44
+ return typeof value.value === 'boolean';
45
+ }
46
+ return typeof value === 'boolean';
47
+ },
48
+ defaultValue: false
49
+ });
50
+
51
+ this.types.set('ничто', {
52
+ name: 'ничто',
53
+ check: (value) => {
54
+ if (value && typeof value === 'object' && 'value' in value) {
55
+ return value.value === null || value.value === undefined;
56
+ }
57
+ return value === null || value === undefined;
58
+ },
59
+ defaultValue: null
60
+ });
61
+
62
+ this.types.set('любой', {
63
+ name: 'любой',
64
+ check: (value) => true, // Принимает любое значение
65
+ defaultValue: null
66
+ });
67
+ }
68
+
69
+ /**
70
+ * Проверка соответствия значения типу
71
+ */
72
+ checkType(value, typeAnnotation) {
73
+ if (!typeAnnotation) return true; // Без аннотации типа - всегда ок
74
+
75
+ switch (typeAnnotation.type) {
76
+ case 'SimpleType':
77
+ const typeDef = this.types.get(typeAnnotation.name);
78
+ if (!typeDef) {
79
+ throw new Error(`Неизвестный тип: ${typeAnnotation.name}`);
80
+ }
81
+ return typeDef.check(value);
82
+
83
+ case 'ArrayType':
84
+ if (!Array.isArray(value)) return false;
85
+ // Для массивов проверяем тип элементов если нужно
86
+ return true; // Пока без строгой проверки элементов
87
+
88
+ case 'FunctionType':
89
+ return typeof value === 'function';
90
+
91
+ case 'ObjectType':
92
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
93
+
94
+ default:
95
+ return true; // Неизвестный тип - пропускаем
96
+ }
97
+ }
98
+
99
+ /**
100
+ * Инференс типа из значения
101
+ */
102
+ inferType(value) {
103
+ if (value === null || value === undefined) return 'ничто';
104
+
105
+ // Если это VladXObject
106
+ if (value && typeof value === 'object' && 'type' in value) {
107
+ switch (value.type) {
108
+ case 'number': return 'число';
109
+ case 'string': return 'строка';
110
+ case 'boolean': return 'логический';
111
+ case 'array': return 'массив';
112
+ case 'object': return 'объект';
113
+ case 'function':
114
+ case 'closure': return 'функция';
115
+ case 'null': return 'ничто';
116
+ default: return 'любой';
117
+ }
118
+ }
119
+
120
+ if (typeof value === 'number') return 'число';
121
+ if (typeof value === 'string') return 'строка';
122
+ if (typeof value === 'boolean') return 'логический';
123
+ if (Array.isArray(value)) return 'массив';
124
+ if (typeof value === 'function') return 'функция';
125
+ if (typeof value === 'object') return 'объект';
126
+ return 'любой';
127
+ }
128
+
129
+ /**
130
+ * Преобразование значения к типу
131
+ */
132
+ coerceValue(value, typeAnnotation) {
133
+ if (!typeAnnotation) return value;
134
+
135
+ switch (typeAnnotation.type) {
136
+ case 'SimpleType':
137
+ const typeName = typeAnnotation.name;
138
+ const typeDef = this.types.get(typeName);
139
+ if (!typeDef) return value;
140
+
141
+ // Если значение уже правильного типа
142
+ if (typeDef.check(value)) return value;
143
+
144
+ // Попытка преобразования
145
+ switch (typeName) {
146
+ case 'число':
147
+ const num = Number(value);
148
+ return isNaN(num) ? typeDef.defaultValue : num;
149
+ case 'строка':
150
+ return String(value);
151
+ case 'логический':
152
+ return Boolean(value);
153
+ default:
154
+ return typeDef.defaultValue;
155
+ }
156
+
157
+ default:
158
+ return value;
159
+ }
160
+ }
161
+
162
+ /**
163
+ * Проверка типов в AST
164
+ */
165
+ checkAST(ast, environment) {
166
+ // Простая проверка типов - можно расширить
167
+ this.checkNode(ast, environment);
168
+ }
169
+
170
+ checkNode(node, environment) {
171
+ switch (node.type) {
172
+ case 'LetStatement':
173
+ case 'ConstStatement':
174
+ if (node.typeAnnotation) {
175
+ const value = this.evaluateForTypeCheck(node.initializer, environment);
176
+ if (!this.checkType(value, node.typeAnnotation)) {
177
+ console.warn(`Предупреждение типа: переменная ${node.name} имеет тип, не соответствующий аннотации`);
178
+ }
179
+ }
180
+ break;
181
+
182
+ case 'FunctionDeclaration':
183
+ // Проверка типов параметров и возвращаемого значения
184
+ if (node.returnType) {
185
+ // Можно добавить проверку возвращаемых значений
186
+ }
187
+ break;
188
+
189
+ case 'BinaryExpression':
190
+ // Проверка типов операндов
191
+ const left = this.evaluateForTypeCheck(node.left, environment);
192
+ const right = this.evaluateForTypeCheck(node.right, environment);
193
+
194
+ // Для арифметических операций оба операнда должны быть числами
195
+ if (['+', '-', '*', '/', '%', '**'].includes(node.operator)) {
196
+ if (typeof left !== 'number' || typeof right !== 'number') {
197
+ console.warn(`Предупреждение типа: операция ${node.operator} требует числовые операнды`);
198
+ }
199
+ }
200
+ break;
201
+ }
202
+
203
+ // Рекурсивная проверка дочерних узлов
204
+ for (const key in node) {
205
+ if (node[key] && typeof node[key] === 'object' && node[key].type) {
206
+ this.checkNode(node[key], environment);
207
+ } else if (Array.isArray(node[key])) {
208
+ node[key].forEach(item => {
209
+ if (item && typeof item === 'object' && item.type) {
210
+ this.checkNode(item, environment);
211
+ }
212
+ });
213
+ }
214
+ }
215
+ }
216
+
217
+ /**
218
+ * Оценка выражения для проверки типов (упрощенная версия)
219
+ */
220
+ evaluateForTypeCheck(expr, environment) {
221
+ if (!expr) return null;
222
+
223
+ switch (expr.type) {
224
+ case 'Literal':
225
+ return expr.value;
226
+ case 'Identifier':
227
+ return environment.get(expr.name)?.value || null;
228
+ case 'BinaryExpression':
229
+ const left = this.evaluateForTypeCheck(expr.left, environment);
230
+ const right = this.evaluateForTypeCheck(expr.right, environment);
231
+ if (typeof left === 'number' && typeof right === 'number') {
232
+ switch (expr.operator) {
233
+ case '+': return left + right;
234
+ case '-': return left - right;
235
+ case '*': return left * right;
236
+ case '/': return right !== 0 ? left / right : 0;
237
+ }
238
+ }
239
+ return null;
240
+ default:
241
+ return null;
242
+ }
243
+ }
244
+ }