hindicode 1.3.0 → 1.4.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.
package/README.md CHANGED
@@ -1,97 +1,90 @@
1
- # HindiCode - हिंदी में जावास्क्रिप्ट लिखें! 🚀
2
- > Write JavaScript in Hindi with Industrial-Grade Robustness.
1
+ # HindiCode - हिंदी में जावास्क्रिप्ट लिखें!
3
2
 
4
- ---
3
+ Hindicode is evolving from a runtime keyword translator into a Hindi-first JavaScript compiler pipeline.
5
4
 
6
- ## 🌍 [HI] परिचय (Introduction)
7
- **HindiCode** एक आधुनिक NPM पैकेज है जो आपको **हिंदी में जावास्क्रिप्ट** लिखने की सुविधा देता है। यह कोड को रन-टाइम पर पार्स करता है और हिंदी के कीवर्ड्स को जावास्क्रिप्ट में बदल देता है।
5
+ ## What Hindicode Supports Today
8
6
 
9
- **HindiCode** is a modern NPM package that lets you **write JavaScript in Hindi**. It transpiles Hindi keywords into JavaScript at runtime, enabling a seamless native coding experience.
7
+ - `.hindi.js` runtime execution in Node
8
+ - `hindicode run`, `hindicode check`, and `hindicode transpile`
9
+ - multi-file CommonJS-style Hindicode programs
10
+ - browser-targeted transpilation experiments
11
+ - structured diagnostics for compile-time syntax failures
10
12
 
11
- ### 🔹 Example (उदाहरण)
12
- ```javascript
13
- स्थिर x = 10;
14
- अगर (x > 5) {
15
- दिखाओ("x बड़ा है!");
16
- } अन्यथा {
17
- दिखाओ("x छोटा है!");
18
- }
19
- ```
20
-
21
- ---
22
-
23
- ## 🌟 Features (विशेषताएँ)
24
- - **Industrial-Grade Protection**:
25
- - **🛡️ Comment Protection**: Keywords inside `//` or `/* */` are never translated.
26
- - **🛡️ String Protection**: Your text inside `" "` or `' '` stays exactly as written.
27
- - **🛡️ Regex Protection**: Search patterns like `/अगर/g` are preserved perfectly.
28
- - **Smart Template Literals**: Supports full `${}` interpolation with recursive translation.
29
- - **Unicode Boundaries**: Professional word boundaries ensure `नम` doesn't break `नमस्ते`.
30
- - **Zero Configuration**: Just register the hook and run `.hindi.js` files.
31
-
32
- ---
33
-
34
- ## 🔧 Installation (स्थापना)
35
- ```sh
36
- npm install hindicode
37
- ```
38
-
39
- ---
40
-
41
- ## 🚀 Usage (उपयोग)
13
+ ## Quick Example
42
14
 
43
- ### 1. Register the Transpiler
44
- Add this to your entry point (e.g., `index.js`):
45
15
  ```javascript
46
- require('hindicode');
47
- require('./your-file.hindi.js');
48
- ```
49
-
50
- ### 2. Write in Hindi (`.hindi.js`)
51
- ```javascript
52
- // app.hindi.js
53
- नया नाम = "अर्जुन";
54
- दिखाओ(`नमस्ते ${नाम}!`);
16
+ स्थिर नाम = "अर्जुन";
55
17
 
56
- कार्य जोड़(अ, ब) {
57
- लौटाओ + ब;
18
+ कार्य स्वागत(व्यक्ति) {
19
+ लौटाओ `नमस्ते ${व्यक्ति}`;
58
20
  }
59
21
 
60
- दिखाओ("योग:", जोड़(10, 20));
22
+ दिखाओ(स्वागत(नाम));
61
23
  ```
62
24
 
63
- ---
64
-
65
- ## 📖 Keyword Mapping (कीवर्ड्स)
66
- | Hindi | JavaScript | Hindi | JavaScript |
67
- | :--- | :--- | :--- | :--- |
68
- | अगर | if | अन्य | else |
69
- | दिखाओ | console.log | कार्य | function |
70
- | लौटाओ | return | चलाओ | for |
71
- | जबतक | while | नया | let |
72
- | स्थिर | const | सही | true |
73
- | गलत | false | असांयकालिक | async |
74
- | प्रतीक्षा | await | त्रुटि | Error |
75
-
76
- *(Check `index.js` for the full dictionary of over 90+ terms!)*
77
-
78
- ---
25
+ ## Install
79
26
 
80
- ## 🗺️ Roadmap (भविष्य की योजना)
81
- - [ ] **Hindi Variables**: Support for non-keyword Hindi tokens as identifiers.
82
- - [ ] **Hindi CLI**: A dedicated runner (`hindicode my-file.hindi.js`).
83
- - [ ] **VS Code Extension**: Syntax highlighting and snippets for `.hindi.js`.
84
- - [ ] **Hindi Error Messages**: Localized compiler errors.
85
- - [ ] **Hindi-DOM**: Support for `दस्तावेज़` (document) and `खिड़की` (window).
86
-
87
- ---
88
-
89
- ## 💖 Contribute (योगदान)
90
- We welcome contributions! Star the repo and join the movement to make coding accessible in every language.
27
+ ```powershell
28
+ npm install hindicode
29
+ ```
91
30
 
92
- 👉 **Support Us**: [Patreon](https://www.patreon.com/c/BABU_ISHU)
31
+ ## CLI
93
32
 
94
- ---
33
+ ```powershell
34
+ hindicode run app.hindi.js
35
+ hindicode check app.hindi.js
36
+ hindicode transpile app.hindi.js
37
+ ```
95
38
 
96
- ## 📜 License
97
- Released under the **MIT License**. 😊
39
+ ## Compiler Direction
40
+
41
+ Phase 1 now includes:
42
+ - keyword inventory module
43
+ - tokenizer
44
+ - parser-strategy layer
45
+ - compiler contract
46
+ - runtime registration module
47
+ - CLI entrypoints
48
+ - parser, CLI, integration, and scenario coverage
49
+
50
+ ## Best-Supported Phase 1 Use Cases
51
+
52
+ - learning JavaScript in Hindi
53
+ - Node scripts and utilities
54
+ - multi-file CommonJS projects
55
+ - browser-oriented transpilation with mocked or real browser globals
56
+
57
+ ## Current Limits
58
+
59
+ Not yet fully promised in Phase 1:
60
+ - full ESM runtime execution
61
+ - React/Angular integrations
62
+ - source maps
63
+ - framework loaders
64
+ - full AST parser behavior
65
+
66
+ ## Important Docs
67
+
68
+ - `PHASE_ONE_PLAN.md`
69
+ - `PHASE_ONE_CHECKLIST.md`
70
+ - `PHASE_TWO_PLAN.md`
71
+ - `PHASE_TWO_CHECKLIST.md`
72
+ - `VISION.md`
73
+ - `ROADMAP.md`
74
+ - `docs/getting-started.md`
75
+ - `docs/cli-usage.md`
76
+ - `docs/cli-quick-reference.md`
77
+ - `docs/language-spec-v1.md`
78
+ - `docs/compiler-contract.md`
79
+ - `docs/runtime-support.md`
80
+ - `docs/source-map-design.md`
81
+ - `docs/contributor-guide.md`
82
+ - `docs/how-to-add-keyword.md`
83
+
84
+ ## Contributing
85
+
86
+ If you add language features, please update tests and docs together. Phase 1 is focused on correctness, diagnostics, and compiler structure.
87
+
88
+ ## License
89
+
90
+ MIT
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { runCli } = require("../src/cli/main");
4
+
5
+ process.exitCode = runCli(process.argv, console);
package/index.js CHANGED
@@ -1,239 +1,14 @@
1
- const fs = require("fs");
2
- const Module = require("module");
3
- const path = require("path");
4
-
5
- const hindiToJS = {
6
- // ── Multi-word phrases FIRST (longest → shortest to avoid partial matches) ──
7
- "नहीं तो": "else",
8
- "के रूप में": "as",
9
- "का प्रकार": "typeof",
10
- "नया बनाओ": "new",
11
- "कम या बराबर": "<=",
12
- "ज्यादा या बराबर": ">=",
13
- "बराबर नहीं": "!==",
14
-
15
- // ── Control Flow ─────────────────────────────────
16
- "अगर": "if",
17
- "वरना": "else",
18
- "करो": "do",
19
- "जबतक": "while",
20
- "केलिए": "for",
21
- "स्विच": "switch",
22
- "मामला": "case",
23
- "रोकें": "break",
24
- "जारी": "continue",
25
- "लौटाओ": "return",
26
- "फेंको": "throw",
27
-
28
- // ── Declarations ─────────────────────────────────
29
- "नया": "let",
30
- "स्थिर": "const",
31
- "पुराना": "var",
32
- "कार्य": "function",
33
- "वर्ग": "class",
34
-
35
- // ── Async ─────────────────────────────────────────
36
- "असिंक": "async",
37
- "इंतज़ार": "await",
38
-
39
- // ── Literals ─────────────────────────────────────
40
- "सच": "true",
41
- "झूठ": "false",
42
- "खाली": "null",
43
- "अपरिभाषित": "undefined",
44
-
45
- // ── OOP ──────────────────────────────────────────
46
- "विस्तार": "extends",
47
- "सुपर": "super",
48
- "यह": "this",
49
- "हटाओ": "delete",
50
- "प्रोटो": "prototype",
51
- "में": "in",
52
- "सत्यापित": "instanceof",
53
- "वापसी": "yield",
54
-
55
- // ── Modules ──────────────────────────────────────
56
- "आयात": "import",
57
- "निर्यात": "export",
58
- "डिफ़ॉल्ट": "default",
59
- "से": "from",
60
- "मांगो": "require",
61
- "मॉड्यूल": "module",
62
-
63
- // ── Operators ────────────────────────────────────
64
- "और": "&&",
65
- "या": "||",
66
- "नहीं": "!",
67
- "बराबर": "===",
68
- "छोटा": "<",
69
- "बड़ा": ">",
70
-
71
- // ── Error Handling ────────────────────────────────
72
- "कोशिश": "try",
73
- "पकड़ो": "catch",
74
- "पकड़": "catch",
75
- "अंततः": "finally",
76
- "त्रुटि": "Error",
77
-
78
- // ── Console ──────────────────────────────────────
79
- "दिखाओ": "console.log",
80
- "गलती": "console.error",
81
- "चेतावनी": "console.warn",
82
- "जानकारी": "console.info",
83
- "कंसोल": "console",
84
-
85
- // ── Array Methods ────────────────────────────────
86
- "पुश": "push",
87
- "पॉप": "pop",
88
- "शिफ्ट": "shift",
89
- "अनशिफ्ट": "unshift",
90
- "स्लाइस": "slice",
91
- "जोड़ो": "concat",
92
- "शामिल": "includes",
93
- "ढूँढो": "find",
94
- "मानचित्र": "map",
95
- "फ़िल्टर": "filter",
96
- "कमकरो": "reduce",
97
- "हरएक": "forEach",
98
- "लंबाई": "length",
99
- "इंडेक्स": "indexOf",
100
- "उलटाओ": "reverse",
101
- "क्रमित": "sort",
102
-
103
- // ── Object Methods ────────────────────────────────
104
- "कुंजियाँ": "keys",
105
- "मूल्य": "values",
106
- "प्रविष्टियाँ": "entries",
107
- "बनाएँ": "create",
108
- "मिलाओ": "assign",
109
- "जमाओ": "freeze",
110
-
111
- // ── Map / Set ─────────────────────────────────────
112
- "नक्शा": "Map",
113
- "है": "has",
114
- "प्राप्त": "get",
115
- "रखो": "set",
116
- "साफ़": "clear",
117
- "आकार": "size",
118
- "डालो": "add",
119
-
120
- // ── Promise ───────────────────────────────────────
121
- "फिर": "then",
122
- "सभी": "all",
123
- "हल": "resolve",
124
- "अस्वीकार": "reject",
125
- "प्रॉमिस": "Promise",
126
-
127
- // ── Browser APIs ──────────────────────────────────
128
- "विंडो": "window",
129
- "दस्तावेज": "document",
130
- "ब्राउज़र": "navigator",
131
- "स्थान": "location",
132
- "इतिहास": "history",
133
- "संग्रह": "localStorage",
134
- "सत्र_संग्रह": "sessionStorage",
135
- "चेतावनी_डिब्बा": "alert",
136
- "पूछो": "prompt",
137
- "पक्का_करो": "confirm",
138
- "लाओ": "fetch",
139
- "समय_बाद": "setTimeout",
140
- "बार_बार": "setInterval",
141
- "समय_रोकें": "clearTimeout",
142
- "बार_रोकें": "clearInterval",
143
-
144
- // ── Node.js ───────────────────────────────────────
145
- "प्रक्रिया": "process",
146
- "__नाम": "__filename",
147
- "__डायरेक्टरी": "__dirname",
148
- "बफर": "Buffer",
149
-
150
- // ── Built-ins ─────────────────────────────────────
151
- "ऑब्जेक्ट": "Object",
152
- "ऐरे": "Array",
153
- "सेट": "Set",
154
- "स्ट्रिंग": "String",
155
- "टेक्स्ट": "String",
156
- "नंबर": "Number",
157
- "बूलियन": "Boolean",
158
- "डेट": "Date",
159
- "तारीख": "Date",
160
- "गणित": "Math",
161
- "जेसन": "JSON",
162
- "रेगएक्स": "RegExp",
163
- "अनंत": "Infinity",
164
- "त्रुटि": "Error",
165
- "प्रॉमिस": "Promise",
166
-
167
- // ── Math Shortcuts ────────────────────────────────
168
- "गोलाई": "Math.round",
169
- "ऊपर": "Math.ceil",
170
- "नीचे": "Math.floor",
171
- "अधिकतम": "Math.max",
172
- "न्यूनतम": "Math.min",
173
- "यादृच्छ": "Math.random",
174
- "वर्गमूल": "Math.sqrt",
175
- "पाई": "Math.PI",
176
-
177
- // ── JSON Shortcuts ────────────────────────────────
178
- "पार्स": "JSON.parse",
179
- "तार_बनाओ": "JSON.stringify",
180
-
181
- // ── String Methods ────────────────────────────────
182
- "बड़े_अक्षर": "toUpperCase",
183
- "छोटे_अक्षर": "toLowerCase",
184
- "काटो": "trim",
185
- "विभाजन": "split",
186
- "बदलो": "replace",
187
- "खोजो": "search",
188
- "शुरू_से": "startsWith",
189
- "खत्म_से": "endsWith",
190
- "दोहराओ": "repeat",
191
- "हिस्सा": "substring",
1
+ const { compileHindiJS, tokenizeSource, translateHindiJS } = require("./src/compiler/compile");
2
+ const { registerHindiExtension } = require("./src/runtime/register");
3
+ const { hindiToJS, sortedKeywords } = require("./src/language/keywords");
4
+
5
+ registerHindiExtension();
6
+
7
+ module.exports = {
8
+ compileHindiJS,
9
+ hindiToJS,
10
+ registerHindiExtension,
11
+ sortedKeywords,
12
+ tokenizeSource,
13
+ translateHindiJS,
192
14
  };
193
-
194
- function translateHindiJS(code) {
195
- const sortedKeywords = Object.keys(hindiToJS).sort((a, b) => b.length - a.length);
196
-
197
- const parts = [
198
- /(?<BLOCK>\/\*[\s\S]*?\*\/)/.source,
199
- /(?<LINE>\/\/.*)/.source,
200
- /(?<STRING_DBL>"(?:[^"\\]|\\.)*")/.source,
201
- /(?<STRING_SGL>'(?:[^'\\]|\\.)*')/.source,
202
- /(?<BACKTICK>`[\s\S]*?`)/.source,
203
- /(?<REGEX>\/(?![*\/])(?:[^\/\\\n]|\\.)*?\/[gimuy]*)/.source,
204
- `(?<KEYWORD>(?<![\\u0900-\\u097F\\w$])(?:${sortedKeywords.join("|")})(?![\\u0900-\\u097F\\w$]))`
205
- ];
206
-
207
- const masterRegex = new RegExp(parts.join("|"), "g");
208
-
209
- return code.replace(masterRegex, (...args) => {
210
- const groups = args[args.length - 1];
211
- const { BACKTICK, KEYWORD } = groups;
212
-
213
- if (KEYWORD && hindiToJS[KEYWORD]) {
214
- return hindiToJS[KEYWORD];
215
- }
216
-
217
- if (BACKTICK) {
218
- return BACKTICK.replace(/\${([\s\S]*?)}/g, (m, inner) => {
219
- return `${"$"}{${translateHindiJS(inner)}}`;
220
- });
221
- }
222
-
223
- return args[0];
224
- });
225
- }
226
-
227
- // Custom require hook for `.hindi.js` files
228
- require.extensions[".hindi.js"] = function (module, filename) {
229
- try {
230
- let content = fs.readFileSync(filename, "utf8").trim();
231
- content = translateHindiJS(content);
232
- module._compile(content, filename);
233
- } catch (error) {
234
- console.error("❌ Hindi Transpiler Error:", error);
235
- throw error; // Re-throw to allow runners to detect failure
236
- }
237
- };
238
-
239
- module.exports = { translateHindiJS };
package/package.json CHANGED
@@ -1,11 +1,14 @@
1
1
  {
2
2
  "name": "hindicode",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "Run JavaScript with Hindi keywords",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
7
+ "bin": {
8
+ "hindicode": "./bin/hindicode.js"
9
+ },
7
10
  "scripts": {
8
- "test": "echo \"Error: no test specified\" && exit 1"
11
+ "test": "node tests/tokenizer_runner.js && node tests/parser_runner.js && node tests/public_api_runner.js && node tests/cli_runner.js && node tests/integration_runner.js && node tests/spec_runner.js && node runner.js"
9
12
  },
10
13
  "keywords": [
11
14
  "hindi",
@@ -27,8 +30,10 @@
27
30
  },
28
31
  "homepage": "https://github.com/Ujjwal-08/hindicode#readme",
29
32
  "files": [
33
+ "bin",
30
34
  "index.js",
31
35
  "index.d.ts",
36
+ "src",
32
37
  "README.md",
33
38
  "LICENSE"
34
39
  ],
@@ -0,0 +1,77 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+
4
+ const { compileHindiJS } = require("../compiler/compile");
5
+ const { createDiagnostic, formatDiagnostic } = require("../diagnostics");
6
+ const { registerHindiExtension } = require("../runtime/register");
7
+
8
+ function printHelp() {
9
+ console.log(`hindicode <command> <file>
10
+
11
+ Commands:
12
+ run <file> Run a Hindicode file
13
+ transpile <file> Print transpiled JavaScript
14
+ check <file> Validate a Hindicode file compiles
15
+ `);
16
+ }
17
+
18
+ function resolveInputFile(filePath) {
19
+ if (!filePath) {
20
+ throw createDiagnostic({
21
+ code: "HC_CLI_NO_INPUT",
22
+ message: "No input file provided.",
23
+ hint: "Use hindicode <command> <file>.",
24
+ });
25
+ }
26
+
27
+ const resolved = path.resolve(process.cwd(), filePath);
28
+ if (!fs.existsSync(resolved)) {
29
+ throw createDiagnostic({
30
+ code: "HC_CLI_FILE_NOT_FOUND",
31
+ file: resolved,
32
+ message: "Input file does not exist.",
33
+ hint: "Check the path or run the command from the project root.",
34
+ });
35
+ }
36
+
37
+ return resolved;
38
+ }
39
+
40
+ function runCommand(command, filePath) {
41
+ if (!command || command === "--help" || command === "-h") {
42
+ printHelp();
43
+ return 0;
44
+ }
45
+
46
+ const resolved = resolveInputFile(filePath);
47
+
48
+ if (command === "run") {
49
+ registerHindiExtension();
50
+ require(resolved);
51
+ return 0;
52
+ }
53
+
54
+ const source = fs.readFileSync(resolved, "utf8");
55
+ const result = compileHindiJS(source, { filename: resolved, mode: command });
56
+
57
+ if (command === "transpile") {
58
+ process.stdout.write(result.code);
59
+ return 0;
60
+ }
61
+
62
+ if (command === "check") {
63
+ console.log(`OK: ${path.basename(resolved)}`);
64
+ return 0;
65
+ }
66
+
67
+ throw createDiagnostic({
68
+ code: "HC_CLI_UNKNOWN_COMMAND",
69
+ message: `Unknown command: ${command}`,
70
+ hint: "Use --help to see supported commands.",
71
+ });
72
+ }
73
+
74
+ module.exports = {
75
+ formatDiagnostic,
76
+ runCommand,
77
+ };
@@ -0,0 +1,20 @@
1
+ const { formatDiagnostic, runCommand } = require("./index");
2
+
3
+ function runCli(argv = process.argv, io = console) {
4
+ try {
5
+ const [, , command, filePath] = argv;
6
+ const exitCode = runCommand(command, filePath);
7
+ return typeof exitCode === "number" ? exitCode : 0;
8
+ } catch (error) {
9
+ if (error && error.code && error.message) {
10
+ io.error(formatDiagnostic(error));
11
+ } else {
12
+ io.error(error.message);
13
+ }
14
+ return 1;
15
+ }
16
+ }
17
+
18
+ module.exports = {
19
+ runCli,
20
+ };
@@ -0,0 +1,108 @@
1
+ const vm = require("vm");
2
+ const { createDiagnostic } = require("../diagnostics");
3
+ const { tokenizeSource } = require("./tokenizer");
4
+ const { parseSource } = require("../parser");
5
+
6
+ function translateHindiJS(source, options = {}) {
7
+ const tokens = tokenizeSource(source);
8
+ const parseResult = parseSource({
9
+ source,
10
+ tokens,
11
+ filename: options.filename || null,
12
+ recursiveTransform: (innerSource) => translateHindiJS(innerSource, options),
13
+ });
14
+
15
+ return parseResult.transformedCode;
16
+ }
17
+
18
+ function extractLocationFromSyntaxError(stackText, filename) {
19
+ const lines = String(stackText || "").split(/\r?\n/);
20
+ const header = lines.find((line) => line.startsWith(`${filename}:`)) || "";
21
+ const match = header.match(/:(\d+)$/);
22
+ const line = match ? Number(match[1]) : 1;
23
+
24
+ const caretLine = lines.find((lineText) => /\^/.test(lineText)) || "^";
25
+ const column = Math.max(caretLine.indexOf("^") + 1, 1);
26
+
27
+ return {
28
+ line,
29
+ column,
30
+ };
31
+ }
32
+
33
+ function validateGeneratedJavaScript(code, filename) {
34
+ try {
35
+ new vm.Script(code, { filename });
36
+ return [];
37
+ } catch (error) {
38
+ const location = extractLocationFromSyntaxError(error.stack, filename || "inline.hindi.js");
39
+ return [
40
+ createDiagnostic({
41
+ code: "HC_JS_SYNTAX_ERROR",
42
+ file: filename || null,
43
+ message: error.message,
44
+ start: {
45
+ line: location.line,
46
+ column: location.column,
47
+ index: 0,
48
+ },
49
+ end: {
50
+ line: location.line,
51
+ column: location.column,
52
+ index: 0,
53
+ },
54
+ hint: "Run hindicode transpile to inspect generated JavaScript around this location.",
55
+ }),
56
+ ];
57
+ }
58
+ }
59
+
60
+ function compileHindiJS(source, options = {}) {
61
+ let parseResult;
62
+
63
+ try {
64
+ const tokens = tokenizeSource(source);
65
+ parseResult = parseSource({
66
+ source,
67
+ tokens,
68
+ filename: options.filename || null,
69
+ recursiveTransform: (innerSource) => translateHindiJS(innerSource, options),
70
+ });
71
+ } catch (error) {
72
+ const diagnostic = createDiagnostic({
73
+ code: "HC_COMPILE_FAILURE",
74
+ file: options.filename || null,
75
+ message: error.message,
76
+ hint: "Inspect the source near the reported location or use hindicode transpile for debugging.",
77
+ });
78
+ throw diagnostic;
79
+ }
80
+
81
+ const diagnostics = [
82
+ ...parseResult.diagnostics,
83
+ ...validateGeneratedJavaScript(parseResult.transformedCode, options.filename || "inline.hindi.js"),
84
+ ];
85
+
86
+ if (diagnostics.length > 0) {
87
+ throw diagnostics[0];
88
+ }
89
+
90
+ return {
91
+ code: parseResult.transformedCode,
92
+ map: null,
93
+ diagnostics,
94
+ meta: {
95
+ filename: options.filename || null,
96
+ mode: options.mode || "runtime",
97
+ parserStrategy: parseResult.strategy,
98
+ parserStage: parseResult.meta.parserStage,
99
+ },
100
+ parseResult,
101
+ };
102
+ }
103
+
104
+ module.exports = {
105
+ compileHindiJS,
106
+ tokenizeSource,
107
+ translateHindiJS,
108
+ };
@@ -0,0 +1,219 @@
1
+ const TOKEN_TYPES = {
2
+ CODE: "code",
3
+ LINE_COMMENT: "line_comment",
4
+ BLOCK_COMMENT: "block_comment",
5
+ STRING_SINGLE: "string_single",
6
+ STRING_DOUBLE: "string_double",
7
+ TEMPLATE: "template",
8
+ REGEX: "regex",
9
+ };
10
+
11
+ function isEscaped(source, index) {
12
+ let backslashes = 0;
13
+ for (let i = index - 1; i >= 0 && source[i] === "\\"; i--) {
14
+ backslashes++;
15
+ }
16
+ return backslashes % 2 === 1;
17
+ }
18
+
19
+ function isRegexAllowedAfter(previousNonWhitespace) {
20
+ if (!previousNonWhitespace) {
21
+ return true;
22
+ }
23
+
24
+ return /[=([{:,;!?&|+\-*/%^<>~]/.test(previousNonWhitespace);
25
+ }
26
+
27
+ function readQuoted(source, start, quote) {
28
+ let index = start + 1;
29
+
30
+ while (index < source.length) {
31
+ if (source[index] === quote && !isEscaped(source, index)) {
32
+ return index + 1;
33
+ }
34
+ index++;
35
+ }
36
+
37
+ return source.length;
38
+ }
39
+
40
+ function readLineComment(source, start) {
41
+ let index = start + 2;
42
+ while (index < source.length && source[index] !== "\n") {
43
+ index++;
44
+ }
45
+ return index;
46
+ }
47
+
48
+ function readBlockComment(source, start) {
49
+ let index = start + 2;
50
+ while (index < source.length) {
51
+ if (source[index] === "*" && source[index + 1] === "/") {
52
+ return index + 2;
53
+ }
54
+ index++;
55
+ }
56
+ return source.length;
57
+ }
58
+
59
+ function readRegex(source, start) {
60
+ let index = start + 1;
61
+ let inCharClass = false;
62
+
63
+ while (index < source.length) {
64
+ const char = source[index];
65
+
66
+ if (char === "[" && !isEscaped(source, index)) {
67
+ inCharClass = true;
68
+ } else if (char === "]" && !isEscaped(source, index)) {
69
+ inCharClass = false;
70
+ } else if (char === "/" && !inCharClass && !isEscaped(source, index)) {
71
+ index++;
72
+ while (/[a-z]/i.test(source[index] || "")) {
73
+ index++;
74
+ }
75
+ return index;
76
+ }
77
+
78
+ index++;
79
+ }
80
+
81
+ return source.length;
82
+ }
83
+
84
+ function readTemplate(source, start) {
85
+ let index = start + 1;
86
+
87
+ while (index < source.length) {
88
+ const char = source[index];
89
+
90
+ if (char === "`" && !isEscaped(source, index)) {
91
+ return index + 1;
92
+ }
93
+
94
+ if (char === "$" && source[index + 1] === "{" && !isEscaped(source, index)) {
95
+ index += 2;
96
+ let depth = 1;
97
+
98
+ while (index < source.length && depth > 0) {
99
+ const inner = source[index];
100
+
101
+ if ((inner === "'" || inner === '"') && !isEscaped(source, index)) {
102
+ index = readQuoted(source, index, inner);
103
+ continue;
104
+ }
105
+
106
+ if (inner === "`" && !isEscaped(source, index)) {
107
+ index = readTemplate(source, index);
108
+ continue;
109
+ }
110
+
111
+ if (inner === "{" && !isEscaped(source, index)) {
112
+ depth++;
113
+ } else if (inner === "}" && !isEscaped(source, index)) {
114
+ depth--;
115
+ }
116
+
117
+ index++;
118
+ }
119
+
120
+ continue;
121
+ }
122
+
123
+ index++;
124
+ }
125
+
126
+ return source.length;
127
+ }
128
+
129
+ function getLocation(source, index) {
130
+ let line = 1;
131
+ let column = 1;
132
+
133
+ for (let i = 0; i < index; i++) {
134
+ if (source[i] === "\n") {
135
+ line++;
136
+ column = 1;
137
+ } else {
138
+ column++;
139
+ }
140
+ }
141
+
142
+ return { line, column, index };
143
+ }
144
+
145
+ function createToken(source, type, start, end) {
146
+ return {
147
+ type,
148
+ value: source.slice(start, end),
149
+ start,
150
+ end,
151
+ startLoc: getLocation(source, start),
152
+ endLoc: getLocation(source, end),
153
+ };
154
+ }
155
+
156
+ function tokenizeSource(source) {
157
+ const tokens = [];
158
+ let codeStart = 0;
159
+ let index = 0;
160
+ let previousNonWhitespace = "";
161
+
162
+ const pushCode = (end) => {
163
+ if (end > codeStart) {
164
+ tokens.push(createToken(source, TOKEN_TYPES.CODE, codeStart, end));
165
+ }
166
+ };
167
+
168
+ const pushProtected = (type, start, end) => {
169
+ pushCode(start);
170
+ tokens.push(createToken(source, type, start, end));
171
+ codeStart = end;
172
+ index = end;
173
+ };
174
+
175
+ while (index < source.length) {
176
+ const char = source[index];
177
+ const next = source[index + 1];
178
+
179
+ if (char === "/" && next === "/") {
180
+ pushProtected(TOKEN_TYPES.LINE_COMMENT, index, readLineComment(source, index));
181
+ continue;
182
+ }
183
+
184
+ if (char === "/" && next === "*") {
185
+ pushProtected(TOKEN_TYPES.BLOCK_COMMENT, index, readBlockComment(source, index));
186
+ continue;
187
+ }
188
+
189
+ if (char === "'" || char === '"') {
190
+ const type = char === "'" ? TOKEN_TYPES.STRING_SINGLE : TOKEN_TYPES.STRING_DOUBLE;
191
+ pushProtected(type, index, readQuoted(source, index, char));
192
+ continue;
193
+ }
194
+
195
+ if (char === "`") {
196
+ pushProtected(TOKEN_TYPES.TEMPLATE, index, readTemplate(source, index));
197
+ continue;
198
+ }
199
+
200
+ if (char === "/" && isRegexAllowedAfter(previousNonWhitespace)) {
201
+ pushProtected(TOKEN_TYPES.REGEX, index, readRegex(source, index));
202
+ continue;
203
+ }
204
+
205
+ if (!/\s/.test(char)) {
206
+ previousNonWhitespace = char;
207
+ }
208
+
209
+ index++;
210
+ }
211
+
212
+ pushCode(source.length);
213
+ return tokens;
214
+ }
215
+
216
+ module.exports = {
217
+ TOKEN_TYPES,
218
+ tokenizeSource,
219
+ };
@@ -0,0 +1,45 @@
1
+ const DiagnosticSeverity = {
2
+ INFO: "info",
3
+ WARNING: "warning",
4
+ ERROR: "error",
5
+ };
6
+
7
+ function createSourceLocation(line = 1, column = 1, index = 0) {
8
+ return { line, column, index };
9
+ }
10
+
11
+ function createDiagnostic({
12
+ code,
13
+ message,
14
+ severity = DiagnosticSeverity.ERROR,
15
+ file = null,
16
+ start = createSourceLocation(),
17
+ end = start,
18
+ hint = null,
19
+ }) {
20
+ return {
21
+ code,
22
+ message,
23
+ severity,
24
+ file,
25
+ start,
26
+ end,
27
+ hint,
28
+ };
29
+ }
30
+
31
+ function formatDiagnostic(diagnostic) {
32
+ const location = diagnostic.file
33
+ ? `${diagnostic.file}:${diagnostic.start.line}:${diagnostic.start.column}`
34
+ : `line ${diagnostic.start.line}, column ${diagnostic.start.column}`;
35
+
36
+ const hint = diagnostic.hint ? `\nHint: ${diagnostic.hint}` : "";
37
+ return `[${diagnostic.severity}] ${diagnostic.code} at ${location}: ${diagnostic.message}${hint}`;
38
+ }
39
+
40
+ module.exports = {
41
+ createDiagnostic,
42
+ createSourceLocation,
43
+ DiagnosticSeverity,
44
+ formatDiagnostic,
45
+ };
@@ -0,0 +1,209 @@
1
+ const hindiToJS = {
2
+ // Multi-word phrases FIRST (longest -> shortest to avoid partial matches)
3
+ "नहीं तो": "else",
4
+ "अन्यथा": "else",
5
+ "के रूप में": "as",
6
+ "का प्रकार": "typeof",
7
+ "नया बनाओ": "new",
8
+ "कम या बराबर": "<=",
9
+ "ज्यादा या बराबर": ">=",
10
+ "बराबर नहीं": "!==",
11
+
12
+ // Control flow
13
+ "अगर": "if",
14
+ "वरना": "else",
15
+ "करो": "do",
16
+ "जबतक": "while",
17
+ "केलिए": "for",
18
+ "स्विच": "switch",
19
+ "मामला": "case",
20
+ "रोकें": "break",
21
+ "जारी": "continue",
22
+ "लौटाओ": "return",
23
+ "फेंको": "throw",
24
+
25
+ // Declarations
26
+ "नया": "let",
27
+ "स्थिर": "const",
28
+ "पुराना": "var",
29
+ "कार्य": "function",
30
+ "वर्ग": "class",
31
+
32
+ // Async
33
+ "असिंक": "async",
34
+ "इंतज़ार": "await",
35
+
36
+ // Literals
37
+ "सच": "true",
38
+ "सत्य": "true",
39
+ "झूठ": "false",
40
+ "असत्य": "false",
41
+ "खाली": "null",
42
+ "अपरिभाषित": "undefined",
43
+
44
+ // OOP
45
+ "विस्तार": "extends",
46
+ "सुपर": "super",
47
+ "यह": "this",
48
+ "हटाओ": "delete",
49
+ "प्रोटो": "prototype",
50
+ "में": "in",
51
+ "सत्यापित": "instanceof",
52
+ "वापसी": "yield",
53
+
54
+ // Modules
55
+ "आयात": "import",
56
+ "निर्यात": "export",
57
+ "डिफ़ॉल्ट": "default",
58
+ "डिफॉल्ट": "default",
59
+ "से": "from",
60
+ "मांगो": "require",
61
+ "अनुरोध": "require",
62
+ "मॉड्यूल": "module",
63
+
64
+ // Operators
65
+ "और": "&&",
66
+ "या": "||",
67
+ "नहीं": "!",
68
+ "बराबर": "===",
69
+ "छोटा": "<",
70
+ "बड़ा": ">",
71
+
72
+ // Error handling
73
+ "कोशिश": "try",
74
+ "पकड़ो": "catch",
75
+ "पकड़": "catch",
76
+ "अंततः": "finally",
77
+ "त्रुटि": "Error",
78
+
79
+ // Console
80
+ "दिखाओ": "console.log",
81
+ "गलती": "console.error",
82
+ "चेतावनी": "console.warn",
83
+ "जानकारी": "console.info",
84
+ "कंसोल": "console",
85
+
86
+ // Array methods
87
+ "पुश": "push",
88
+ "पॉप": "pop",
89
+ "शिफ्ट": "shift",
90
+ "अनशिफ्ट": "unshift",
91
+ "स्लाइस": "slice",
92
+ "जोड़ो": "concat",
93
+ "शामिल": "includes",
94
+ "ढूँढो": "find",
95
+ "मानचित्र": "map",
96
+ "फ़िल्टर": "filter",
97
+ "कमकरो": "reduce",
98
+ "हरएक": "forEach",
99
+ "लंबाई": "length",
100
+ "लम्बाई": "length",
101
+ "इंडेक्स": "indexOf",
102
+ "उलटाओ": "reverse",
103
+ "क्रमित": "sort",
104
+
105
+ // Object methods
106
+ "कुंजियाँ": "keys",
107
+ "मूल्य": "values",
108
+ "प्रविष्टियाँ": "entries",
109
+ "बनाएँ": "create",
110
+ "मिलाओ": "assign",
111
+ "जमाओ": "freeze",
112
+
113
+ // Map / Set
114
+ "नक्शा": "Map",
115
+ "है": "has",
116
+ "प्राप्त": "get",
117
+ "रखो": "set",
118
+ "साफ़": "clear",
119
+ "आकार": "size",
120
+ "डालो": "add",
121
+
122
+ // Promise
123
+ "फिर": "then",
124
+ "सभी": "all",
125
+ "हल": "resolve",
126
+ "अस्वीकार": "reject",
127
+ "प्रॉमिस": "Promise",
128
+
129
+ // Browser APIs
130
+ "विंडो": "window",
131
+ "दस्तावेज": "document",
132
+ "दस्तावेज़": "document",
133
+ "ब्राउज़र": "navigator",
134
+ "स्थान": "location",
135
+ "इतिहास": "history",
136
+ "संग्रह": "localStorage",
137
+ "सत्र_संग्रह": "sessionStorage",
138
+ "चेतावनी_डिब्बा": "alert",
139
+ "पूछो": "prompt",
140
+ "पक्का_करो": "confirm",
141
+ "लाओ": "fetch",
142
+ "समय_बाद": "setTimeout",
143
+ "बार_बार": "setInterval",
144
+ "समय_रोकें": "clearTimeout",
145
+ "बार_रोकें": "clearInterval",
146
+ "तत्व_ढूँढो_आईडी_से": "getElementById",
147
+ "तत्व_ढूँढो": "querySelector",
148
+ "सभी_तत्व_ढूँढो": "querySelectorAll",
149
+ "घटना_सुनो": "addEventListener",
150
+ "तत्व_बनाओ": "createElement",
151
+ "बच्चा_जोड़ो": "appendChild",
152
+
153
+ // Node.js
154
+ "प्रक्रिया": "process",
155
+ "__नाम": "__filename",
156
+ "__डायरेक्टरी": "__dirname",
157
+ "बफर": "Buffer",
158
+
159
+ // Built-ins
160
+ "ऑब्जेक्ट": "Object",
161
+ "ऐरे": "Array",
162
+ "सेट": "Set",
163
+ "स्ट्रिंग": "String",
164
+ "टेक्स्ट": "String",
165
+ "नंबर": "Number",
166
+ "बूलियन": "Boolean",
167
+ "डेट": "Date",
168
+ "तारीख": "Date",
169
+ "गणित": "Math",
170
+ "जेसन": "JSON",
171
+ "जेसन_डेटा": "json",
172
+ "जीसन": "JSON",
173
+ "जोड़ें": "join",
174
+ "रेगएक्स": "RegExp",
175
+ "अनंत": "Infinity",
176
+
177
+ // Math shortcuts
178
+ "गोलाई": "Math.round",
179
+ "ऊपर": "Math.ceil",
180
+ "नीचे": "Math.floor",
181
+ "अधिकतम": "Math.max",
182
+ "न्यूनतम": "Math.min",
183
+ "यादृच्छ": "Math.random",
184
+ "वर्गमूल": "Math.sqrt",
185
+ "पाई": "Math.PI",
186
+
187
+ // JSON shortcuts
188
+ "पार्स": "JSON.parse",
189
+ "तार_बनाओ": "JSON.stringify",
190
+
191
+ // String methods
192
+ "बड़े_अक्षर": "toUpperCase",
193
+ "छोटे_अक्षर": "toLowerCase",
194
+ "काटो": "trim",
195
+ "विभाजन": "split",
196
+ "बदलो": "replace",
197
+ "खोजो": "search",
198
+ "शुरू_से": "startsWith",
199
+ "खत्म_से": "endsWith",
200
+ "दोहराओ": "repeat",
201
+ "हिस्सा": "substring",
202
+ };
203
+
204
+ const sortedKeywords = Object.keys(hindiToJS).sort((a, b) => b.length - a.length);
205
+
206
+ module.exports = {
207
+ hindiToJS,
208
+ sortedKeywords,
209
+ };
@@ -0,0 +1,66 @@
1
+ const { TOKEN_TYPES } = require("../compiler/tokenizer");
2
+ const { sortedKeywords, hindiToJS } = require("../language/keywords");
3
+
4
+ function escapeForRegex(value) {
5
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
6
+ }
7
+
8
+ const keywordRegex = new RegExp(
9
+ `(?<![\\u0900-\\u097F\\w$])(?:${sortedKeywords.map(escapeForRegex).join("|")})(?![\\u0900-\\u097F\\w$])`,
10
+ "g"
11
+ );
12
+
13
+ function transformCodeSegment(code) {
14
+ return code.replace(keywordRegex, (match) => hindiToJS[match] || match);
15
+ }
16
+
17
+ function transformTokens(tokens, recursiveTransform) {
18
+ return tokens
19
+ .map((token) => {
20
+ if (token.type === TOKEN_TYPES.CODE) {
21
+ return transformCodeSegment(token.value);
22
+ }
23
+
24
+ if (token.type === TOKEN_TYPES.TEMPLATE) {
25
+ return token.value.replace(/\${([\s\S]*?)}/g, (fullMatch, expression) => {
26
+ return `${"$"}{${recursiveTransform(expression)}}`;
27
+ });
28
+ }
29
+
30
+ return token.value;
31
+ })
32
+ .join("");
33
+ }
34
+
35
+ function createParseResult({ source, tokens, transformedCode, filename = null }) {
36
+ return {
37
+ source,
38
+ tokens,
39
+ transformedCode,
40
+ ast: null,
41
+ diagnostics: [],
42
+ strategy: "token-transform",
43
+ meta: {
44
+ filename,
45
+ parserStage: "phase-one-token-transform",
46
+ },
47
+ };
48
+ }
49
+
50
+ function parseSource({ source, tokens, recursiveTransform, filename = null }) {
51
+ const transformedCode = transformTokens(tokens, recursiveTransform);
52
+
53
+ return createParseResult({
54
+ source,
55
+ tokens,
56
+ transformedCode,
57
+ filename,
58
+ });
59
+ }
60
+
61
+ module.exports = {
62
+ createParseResult,
63
+ parseSource,
64
+ transformCodeSegment,
65
+ transformTokens,
66
+ };
@@ -0,0 +1,24 @@
1
+ const fs = require("fs");
2
+ const { compileHindiJS } = require("../compiler/compile");
3
+ const { formatDiagnostic } = require("../diagnostics");
4
+
5
+ function registerHindiExtension() {
6
+ require.extensions[".hindi.js"] = function loadHindiModule(module, filename) {
7
+ try {
8
+ const content = fs.readFileSync(filename, "utf8").trim();
9
+ const compiled = compileHindiJS(content, { filename, mode: "runtime" });
10
+ module._compile(compiled.code, filename);
11
+ } catch (error) {
12
+ if (error && error.code && error.message) {
13
+ console.error("❌ Hindi Transpiler Error:", formatDiagnostic(error));
14
+ } else {
15
+ console.error("❌ Hindi Transpiler Error:", error);
16
+ }
17
+ throw error;
18
+ }
19
+ };
20
+ }
21
+
22
+ module.exports = {
23
+ registerHindiExtension,
24
+ };