jpsx 0.1.16

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 (45) hide show
  1. package/README.md +242 -0
  2. package/dist/api/__tests__/compile.test.d.ts +2 -0
  3. package/dist/api/__tests__/compile.test.d.ts.map +1 -0
  4. package/dist/api/__tests__/compile.test.js +336 -0
  5. package/dist/api/__tests__/runtime.test.d.ts +2 -0
  6. package/dist/api/__tests__/runtime.test.d.ts.map +1 -0
  7. package/dist/api/__tests__/runtime.test.js +275 -0
  8. package/dist/api/advanced.d.ts +100 -0
  9. package/dist/api/advanced.d.ts.map +1 -0
  10. package/dist/api/advanced.js +192 -0
  11. package/dist/api/benchmark.d.ts +87 -0
  12. package/dist/api/benchmark.d.ts.map +1 -0
  13. package/dist/api/benchmark.js +147 -0
  14. package/dist/api/index.d.ts +88 -0
  15. package/dist/api/index.d.ts.map +1 -0
  16. package/dist/api/index.js +304 -0
  17. package/dist/ast/types.d.ts +141 -0
  18. package/dist/ast/types.d.ts.map +1 -0
  19. package/dist/ast/types.js +1 -0
  20. package/dist/cli/index.d.ts +3 -0
  21. package/dist/cli/index.d.ts.map +1 -0
  22. package/dist/cli/index.js +155 -0
  23. package/dist/cli.js +30 -0
  24. package/dist/generator/generator.d.ts +3 -0
  25. package/dist/generator/generator.d.ts.map +1 -0
  26. package/dist/generator/generator.js +175 -0
  27. package/dist/lexer/lexer.d.ts +3 -0
  28. package/dist/lexer/lexer.d.ts.map +1 -0
  29. package/dist/lexer/lexer.js +23 -0
  30. package/dist/lexer/tokenizer.d.ts +9 -0
  31. package/dist/lexer/tokenizer.d.ts.map +1 -0
  32. package/dist/lexer/tokenizer.js +240 -0
  33. package/dist/parser/grammar.d.ts +29 -0
  34. package/dist/parser/grammar.d.ts.map +1 -0
  35. package/dist/parser/grammar.js +312 -0
  36. package/dist/parser/parser.d.ts +4 -0
  37. package/dist/parser/parser.d.ts.map +1 -0
  38. package/dist/parser/parser.js +47 -0
  39. package/dist/runtime/index.d.ts +24 -0
  40. package/dist/runtime/index.d.ts.map +1 -0
  41. package/dist/runtime/index.js +108 -0
  42. package/dist/transformer/transformer.d.ts +3 -0
  43. package/dist/transformer/transformer.d.ts.map +1 -0
  44. package/dist/transformer/transformer.js +318 -0
  45. package/package.json +54 -0
@@ -0,0 +1,318 @@
1
+ export function transform(program) {
2
+ const body = program.body.map(transformStatement);
3
+ return { type: "Program", body };
4
+ }
5
+ function transformStatement(statement) {
6
+ if (statement.type === "ExpressionStatement") {
7
+ return { ...statement, expression: transformExpression(statement.expression) };
8
+ }
9
+ if (statement.type === "FunctionDeclaration") {
10
+ let name = statement.name;
11
+ let params = statement.params;
12
+ if (name === "__init__") {
13
+ name = "constructor";
14
+ params = params.filter(p => p !== "self"); // Remove self
15
+ }
16
+ else {
17
+ // Remove self from normal methods too if present
18
+ params = params.filter(p => p !== "self");
19
+ }
20
+ return {
21
+ ...statement,
22
+ name,
23
+ params,
24
+ body: statement.body.map(transformStatement),
25
+ };
26
+ }
27
+ if (statement.type === "ForStatement") {
28
+ if (statement.collection) {
29
+ return {
30
+ ...statement,
31
+ collection: transformExpression(statement.collection),
32
+ body: statement.body.map(transformStatement)
33
+ };
34
+ }
35
+ return {
36
+ ...statement,
37
+ start: transformExpression(statement.start),
38
+ end: transformExpression(statement.end),
39
+ body: statement.body.map(transformStatement),
40
+ };
41
+ }
42
+ if (statement.type === "IfStatement") {
43
+ return {
44
+ ...statement,
45
+ test: transformExpression(statement.test),
46
+ consequent: statement.consequent.map(transformStatement),
47
+ alternate: statement.alternate ? statement.alternate.map(transformStatement) : null,
48
+ };
49
+ }
50
+ if (statement.type === "WhileStatement") {
51
+ return {
52
+ ...statement,
53
+ test: transformExpression(statement.test),
54
+ body: statement.body.map(transformStatement),
55
+ };
56
+ }
57
+ if (statement.type === "ClassDeclaration") {
58
+ return {
59
+ ...statement,
60
+ body: statement.body.map(transformStatement)
61
+ };
62
+ }
63
+ if (statement.type === "TryStatement") {
64
+ return {
65
+ ...statement,
66
+ block: statement.block.map(transformStatement),
67
+ handler: statement.handler.map(transformStatement)
68
+ };
69
+ }
70
+ if (statement.type === "ReturnStatement") {
71
+ return {
72
+ ...statement,
73
+ argument: statement.argument ? transformExpression(statement.argument) : null
74
+ };
75
+ }
76
+ if (statement.type === "ExportDeclaration") {
77
+ return {
78
+ ...statement,
79
+ declaration: transformStatement(statement.declaration)
80
+ };
81
+ }
82
+ // ImportDeclaration passes through IDENTITY
83
+ return statement;
84
+ }
85
+ function isSuperCall(expr) {
86
+ return expr.type === "CallExpression" && expr.callee.type === "Identifier" && expr.callee.name === "super";
87
+ }
88
+ function transformExpression(expression) {
89
+ if (!expression)
90
+ return expression;
91
+ if (expression.type === "CallExpression") {
92
+ const { callee, args } = expression;
93
+ // Handle obj.method(...) transformations
94
+ if (callee.type === "MemberExpression") {
95
+ const obj = callee.object;
96
+ const prop = callee.property;
97
+ // Handle super().__init__(...) -> super(...)
98
+ if (isSuperCall(obj) && prop.type === "Identifier" && prop.name === "__init__") {
99
+ return {
100
+ type: "CallExpression",
101
+ callee: { type: "Identifier", name: "super" },
102
+ args: args.map(transformExpression)
103
+ };
104
+ }
105
+ // Handle dictionary methods mappings
106
+ if (!callee.computed && prop.type === "Identifier") {
107
+ if (prop.name === "get") {
108
+ const keyArg = args[0];
109
+ const defaultArg = args[1] || { type: "Identifier", name: "undefined" };
110
+ return {
111
+ type: "ConditionalExpression",
112
+ test: {
113
+ type: "BinaryExpression",
114
+ operator: "in",
115
+ left: transformExpression(keyArg),
116
+ right: transformExpression(obj)
117
+ },
118
+ consequent: {
119
+ type: "MemberExpression",
120
+ object: transformExpression(obj),
121
+ property: transformExpression(keyArg),
122
+ computed: true
123
+ },
124
+ alternate: transformExpression(defaultArg)
125
+ };
126
+ }
127
+ if (prop.name === "items") {
128
+ return {
129
+ type: "CallExpression",
130
+ callee: {
131
+ type: "MemberExpression",
132
+ object: { type: "Identifier", name: "Object" },
133
+ property: { type: "Identifier", name: "entries" },
134
+ computed: false
135
+ },
136
+ args: [transformExpression(obj)]
137
+ };
138
+ }
139
+ if (prop.name === "keys") {
140
+ return {
141
+ type: "CallExpression",
142
+ callee: {
143
+ type: "MemberExpression",
144
+ object: { type: "Identifier", name: "Object" },
145
+ property: { type: "Identifier", name: "keys" },
146
+ computed: false
147
+ },
148
+ args: [transformExpression(obj)]
149
+ };
150
+ }
151
+ if (prop.name === "values") {
152
+ return {
153
+ type: "CallExpression",
154
+ callee: {
155
+ type: "MemberExpression",
156
+ object: { type: "Identifier", name: "Object" },
157
+ property: { type: "Identifier", name: "values" },
158
+ computed: false
159
+ },
160
+ args: [transformExpression(obj)]
161
+ };
162
+ }
163
+ }
164
+ }
165
+ // Handle sorted(iterable, key=..., reverse=...) -> sorted(iterable, key, reverse)
166
+ if (callee.type === "Identifier" && callee.name === "sorted") {
167
+ const iterable = args[0] ? transformExpression(args[0]) : { type: "Identifier", name: "undefined" };
168
+ let key = { type: "Identifier", name: "undefined" };
169
+ let reverse = { type: "BooleanLiteral", value: false };
170
+ // Process arguments to find named args
171
+ for (let i = 1; i < args.length; i++) {
172
+ const arg = args[i];
173
+ if (arg.type === "BinaryExpression" && arg.operator === "=" && arg.left.type === "Identifier") {
174
+ const name = arg.left.name;
175
+ if (name === "key") {
176
+ key = transformExpression(arg.right);
177
+ }
178
+ else if (name === "reverse") {
179
+ reverse = transformExpression(arg.right);
180
+ }
181
+ }
182
+ else {
183
+ // Assume positional mappings if not named: 2nd is key, 3rd is reverse
184
+ if (i === 1)
185
+ key = transformExpression(arg);
186
+ if (i === 2)
187
+ reverse = transformExpression(arg);
188
+ }
189
+ }
190
+ return {
191
+ type: "CallExpression",
192
+ callee: { type: "Identifier", name: "sorted" },
193
+ args: [iterable, key, reverse]
194
+ };
195
+ }
196
+ if (callee.type === "Identifier") {
197
+ // Heuristic for new Class(...)
198
+ if (/^[A-Z]/.test(callee.name)) {
199
+ const exceptions = ["String", "Number", "Boolean", "Object", "Array", "Error"];
200
+ if (!exceptions.includes(callee.name)) {
201
+ return {
202
+ type: "NewExpression",
203
+ callee: { type: "Identifier", name: callee.name },
204
+ args: args.map(transformExpression)
205
+ };
206
+ }
207
+ }
208
+ }
209
+ const transformedCallee = transformExpression(callee);
210
+ return { ...expression, callee: transformedCallee, args: args.map(transformExpression) };
211
+ }
212
+ if (expression.type === "MemberExpression") {
213
+ if (isSuperCall(expression.object)) {
214
+ return {
215
+ ...expression,
216
+ object: { type: "Identifier", name: "super" },
217
+ property: transformExpression(expression.property)
218
+ };
219
+ }
220
+ const prop = expression.property;
221
+ if (!expression.computed && prop.type === "Identifier") {
222
+ if (prop.name === "upper") {
223
+ return {
224
+ ...expression,
225
+ object: transformExpression(expression.object),
226
+ property: { type: "Identifier", name: "toUpperCase" },
227
+ computed: false
228
+ };
229
+ }
230
+ if (prop.name === "lower") {
231
+ return {
232
+ ...expression,
233
+ object: transformExpression(expression.object),
234
+ property: { type: "Identifier", name: "toLowerCase" },
235
+ computed: false
236
+ };
237
+ }
238
+ if (prop.name === "strip") {
239
+ return {
240
+ ...expression,
241
+ object: transformExpression(expression.object),
242
+ property: { type: "Identifier", name: "trim" },
243
+ computed: false
244
+ };
245
+ }
246
+ if (prop.name === "append") {
247
+ return {
248
+ ...expression,
249
+ object: transformExpression(expression.object),
250
+ property: { type: "Identifier", name: "push" },
251
+ computed: false
252
+ };
253
+ }
254
+ }
255
+ return {
256
+ ...expression,
257
+ object: transformExpression(expression.object),
258
+ property: expression.computed ? transformExpression(expression.property) : expression.property
259
+ };
260
+ }
261
+ if (expression.type === "Identifier") {
262
+ if (expression.name === "self") {
263
+ return { type: "Identifier", name: "this" };
264
+ }
265
+ if (expression.name === "None") {
266
+ return { type: "Identifier", name: "null" };
267
+ }
268
+ }
269
+ if (expression.type === "LambdaExpression") {
270
+ return {
271
+ ...expression,
272
+ body: transformExpression(expression.body)
273
+ };
274
+ }
275
+ if (expression.type === "BinaryExpression") {
276
+ if (expression.operator === "in") {
277
+ return {
278
+ type: "CallExpression",
279
+ callee: { type: "Identifier", name: "__in__" },
280
+ args: [transformExpression(expression.left), transformExpression(expression.right)]
281
+ };
282
+ }
283
+ return {
284
+ ...expression,
285
+ left: transformExpression(expression.left),
286
+ right: transformExpression(expression.right),
287
+ };
288
+ }
289
+ if (expression.type === "ListComprehension") {
290
+ return {
291
+ ...expression,
292
+ expression: transformExpression(expression.expression),
293
+ start: expression.start ? transformExpression(expression.start) : undefined,
294
+ end: expression.end ? transformExpression(expression.end) : undefined,
295
+ collection: expression.collection ? transformExpression(expression.collection) : undefined,
296
+ test: expression.test ? transformExpression(expression.test) : undefined,
297
+ };
298
+ }
299
+ if (expression.type === "UnaryExpression") {
300
+ return {
301
+ ...expression,
302
+ argument: transformExpression(expression.argument)
303
+ };
304
+ }
305
+ if (expression.type === "ArrayLiteral") {
306
+ return {
307
+ type: "ArrayLiteral",
308
+ elements: expression.elements.map(transformExpression),
309
+ };
310
+ }
311
+ if (expression.type === "ObjectLiteral") {
312
+ return {
313
+ type: "ObjectLiteral",
314
+ properties: expression.properties.map((p) => ({ ...p, value: transformExpression(p.value) })),
315
+ };
316
+ }
317
+ return expression;
318
+ }
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "jpsx",
3
+ "version": "0.1.16",
4
+ "description": "Just Python Script (JPS) - A Python-like language that compiles to JavaScript",
5
+ "keywords": [
6
+ "compiler",
7
+ "python",
8
+ "javascript",
9
+ "jps"
10
+ ],
11
+ "author": "Loaii abdalslam",
12
+ "license": "ISC",
13
+ "files": [
14
+ "dist"
15
+ ],
16
+ "bin": {
17
+ "jps": "./dist/cli/index.js"
18
+ },
19
+ "main": "./dist/api/index.js",
20
+ "types": "./dist/api/index.d.ts",
21
+ "exports": {
22
+ ".": {
23
+ "types": "./dist/api/index.d.ts",
24
+ "import": "./dist/api/index.js",
25
+ "require": "./dist/api/index.cjs"
26
+ },
27
+ "./cli": "./dist/cli/index.js",
28
+ "./runtime": "./dist/runtime/index.js",
29
+ "./package.json": "./package.json"
30
+ },
31
+ "private": false,
32
+ "type": "module",
33
+ "scripts": {
34
+ "build": "tsc -p tsconfig.json",
35
+ "start": "node dist/cli/index.js",
36
+ "test": "jest"
37
+ },
38
+ "dependencies": {
39
+ "chalk": "^5.6.2",
40
+ "commander": "^14.0.2",
41
+ "moo": "^0.5.2",
42
+ "nearley": "^2.20.1"
43
+ },
44
+ "devDependencies": {
45
+ "@types/jest": "^29.5.12",
46
+ "@types/moo": "^0.5.10",
47
+ "@types/nearley": "^2.11.5",
48
+ "@types/node": "^22.19.7",
49
+ "jest": "^29.7.0",
50
+ "ts-jest": "^29.1.2",
51
+ "ts-node": "^10.9.2",
52
+ "typescript": "^5.3.3"
53
+ }
54
+ }