kimchilang 1.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.
Files changed (90) hide show
  1. package/.github/workflows/ci.yml +66 -0
  2. package/README.md +1547 -0
  3. package/create-kimchi-app/README.md +44 -0
  4. package/create-kimchi-app/index.js +214 -0
  5. package/create-kimchi-app/package.json +22 -0
  6. package/editors/README.md +121 -0
  7. package/editors/sublime/KimchiLang.sublime-syntax +138 -0
  8. package/editors/vscode/README.md +90 -0
  9. package/editors/vscode/kimchilang-1.1.0.vsix +0 -0
  10. package/editors/vscode/language-configuration.json +37 -0
  11. package/editors/vscode/package.json +55 -0
  12. package/editors/vscode/src/extension.js +354 -0
  13. package/editors/vscode/syntaxes/kimchi.tmLanguage.json +215 -0
  14. package/examples/api/client.km +36 -0
  15. package/examples/async_pipe.km +58 -0
  16. package/examples/basic.kimchi +109 -0
  17. package/examples/cli_framework/README.md +92 -0
  18. package/examples/cli_framework/calculator.km +61 -0
  19. package/examples/cli_framework/deploy.km +126 -0
  20. package/examples/cli_framework/greeter.km +26 -0
  21. package/examples/config.static +27 -0
  22. package/examples/config.static.js +10 -0
  23. package/examples/env_test.km +37 -0
  24. package/examples/fibonacci.kimchi +17 -0
  25. package/examples/greeter.km +15 -0
  26. package/examples/hello.js +1 -0
  27. package/examples/hello.kimchi +3 -0
  28. package/examples/js_interop.km +42 -0
  29. package/examples/logger_example.km +34 -0
  30. package/examples/memo_fibonacci.km +17 -0
  31. package/examples/myapp/lib/http.js +14 -0
  32. package/examples/myapp/lib/http.km +16 -0
  33. package/examples/myapp/main.km +16 -0
  34. package/examples/myapp/main_with_mock.km +42 -0
  35. package/examples/myapp/services/api.js +18 -0
  36. package/examples/myapp/services/api.km +18 -0
  37. package/examples/new_features.kimchi +52 -0
  38. package/examples/project_example.static +20 -0
  39. package/examples/readme_examples.km +240 -0
  40. package/examples/reduce_pattern_match.km +85 -0
  41. package/examples/regex_match.km +46 -0
  42. package/examples/sample.js +45 -0
  43. package/examples/sample.km +39 -0
  44. package/examples/secrets.static +35 -0
  45. package/examples/secrets.static.js +30 -0
  46. package/examples/shell-example.mjs +144 -0
  47. package/examples/shell_example.km +19 -0
  48. package/examples/stdlib_test.km +22 -0
  49. package/examples/test_example.km +69 -0
  50. package/examples/testing/README.md +88 -0
  51. package/examples/testing/http_client.km +18 -0
  52. package/examples/testing/math.km +48 -0
  53. package/examples/testing/math.test.km +93 -0
  54. package/examples/testing/user_service.km +29 -0
  55. package/examples/testing/user_service.test.km +72 -0
  56. package/examples/use-config.mjs +141 -0
  57. package/examples/use_config.km +13 -0
  58. package/install.sh +59 -0
  59. package/package.json +29 -0
  60. package/pantry/acorn/index.km +1 -0
  61. package/pantry/is_number/index.km +1 -0
  62. package/pantry/is_odd/index.km +2 -0
  63. package/project.static +6 -0
  64. package/src/cli.js +1245 -0
  65. package/src/generator.js +1241 -0
  66. package/src/index.js +141 -0
  67. package/src/js2km.js +568 -0
  68. package/src/lexer.js +822 -0
  69. package/src/linter.js +810 -0
  70. package/src/package-manager.js +307 -0
  71. package/src/parser.js +1876 -0
  72. package/src/static-parser.js +500 -0
  73. package/src/typechecker.js +950 -0
  74. package/stdlib/array.km +0 -0
  75. package/stdlib/bitwise.km +38 -0
  76. package/stdlib/console.km +49 -0
  77. package/stdlib/date.km +97 -0
  78. package/stdlib/function.km +44 -0
  79. package/stdlib/http.km +197 -0
  80. package/stdlib/http.md +333 -0
  81. package/stdlib/index.km +26 -0
  82. package/stdlib/json.km +17 -0
  83. package/stdlib/logger.js +114 -0
  84. package/stdlib/logger.km +104 -0
  85. package/stdlib/math.km +120 -0
  86. package/stdlib/object.km +41 -0
  87. package/stdlib/promise.km +33 -0
  88. package/stdlib/string.km +93 -0
  89. package/stdlib/testing.md +265 -0
  90. package/test/test.js +599 -0
@@ -0,0 +1,141 @@
1
+ import * as _dep_config from './examples/config.static.js';
2
+
3
+ // KimchiLang stdlib extensions
4
+ if (!Array.prototype._kmExtended) {
5
+ Array.prototype._kmExtended = true;
6
+ Array.prototype.first = function() { return this[0]; };
7
+ Array.prototype.last = function() { return this[this.length - 1]; };
8
+ Array.prototype.isEmpty = function() { return this.length === 0; };
9
+ Array.prototype.sum = function() { return this.reduce((a, b) => a + b, 0); };
10
+ Array.prototype.product = function() { return this.reduce((a, b) => a * b, 1); };
11
+ Array.prototype.average = function() { return this.reduce((a, b) => a + b, 0) / this.length; };
12
+ Array.prototype.max = function() { return Math.max(...this); };
13
+ Array.prototype.min = function() { return Math.min(...this); };
14
+ Array.prototype.take = function(n) { return this.slice(0, n); };
15
+ Array.prototype.drop = function(n) { return this.slice(n); };
16
+ Array.prototype.flatten = function() { return this.flat(Infinity); };
17
+ Array.prototype.unique = function() { return [...new Set(this)]; };
18
+ }
19
+ if (!String.prototype._kmExtended) {
20
+ String.prototype._kmExtended = true;
21
+ String.prototype.isEmpty = function() { return this.length === 0; };
22
+ String.prototype.isBlank = function() { return this.trim().length === 0; };
23
+ String.prototype.toChars = function() { return this.split(""); };
24
+ String.prototype.toLines = function() { return this.split("\n"); };
25
+ String.prototype.capitalize = function() { return this.length === 0 ? this : this[0].toUpperCase() + this.slice(1); };
26
+ }
27
+ const _obj = {
28
+ keys: (o) => Object.keys(o),
29
+ values: (o) => Object.values(o),
30
+ entries: (o) => Object.entries(o),
31
+ fromEntries: (arr) => Object.fromEntries(arr),
32
+ has: (o, k) => Object.hasOwn(o, k),
33
+ freeze: (o) => Object.freeze(o),
34
+ isEmpty: (o) => Object.keys(o).length === 0,
35
+ size: (o) => Object.keys(o).length,
36
+ };
37
+
38
+ function error(message, name = "Error") {
39
+ const e = new Error(message);
40
+ e.name = name;
41
+ return e;
42
+ }
43
+ error.create = (name) => {
44
+ const fn = (message) => error(message, name);
45
+ Object.defineProperty(fn, "name", { value: name, writable: false });
46
+ return fn;
47
+ };
48
+
49
+ class _Secret {
50
+ constructor(value) { this._value = value; }
51
+ toString() { return "********"; }
52
+ valueOf() { return this._value; }
53
+ get value() { return this._value; }
54
+ [Symbol.toPrimitive](hint) { return hint === "string" ? "********" : this._value; }
55
+ }
56
+ function _secret(value) { return new _Secret(value); }
57
+
58
+ function _deepFreeze(obj) {
59
+ if (obj === null || typeof obj !== "object") return obj;
60
+ Object.keys(obj).forEach(key => _deepFreeze(obj[key]));
61
+ return Object.freeze(obj);
62
+ }
63
+
64
+ async function _shell(command, inputs = {}) {
65
+ const { exec } = await import("child_process");
66
+ const { promisify } = await import("util");
67
+ const execAsync = promisify(exec);
68
+ // Interpolate inputs into command
69
+ let cmd = command;
70
+ for (const [key, value] of Object.entries(inputs)) {
71
+ cmd = cmd.replace(new RegExp("\\$" + key + "\\b", "g"), String(value));
72
+ }
73
+ try {
74
+ const { stdout, stderr } = await execAsync(cmd);
75
+ return { stdout: stdout.trim(), stderr: stderr.trim(), exitCode: 0 };
76
+ } catch (error) {
77
+ return { stdout: error.stdout?.trim() || "", stderr: error.stderr?.trim() || error.message, exitCode: error.code || 1 };
78
+ }
79
+ }
80
+
81
+ // Testing framework
82
+ const _tests = [];
83
+ let _currentDescribe = null;
84
+ function _describe(name, fn) {
85
+ const prev = _currentDescribe;
86
+ _currentDescribe = { name, tests: [], parent: prev };
87
+ fn();
88
+ if (prev) { prev.tests.push(_currentDescribe); }
89
+ else { _tests.push(_currentDescribe); }
90
+ _currentDescribe = prev;
91
+ }
92
+ function _test(name, fn) {
93
+ const test = { name, fn, describe: _currentDescribe };
94
+ if (_currentDescribe) { _currentDescribe.tests.push(test); }
95
+ else { _tests.push(test); }
96
+ }
97
+ function _expect(actual) {
98
+ return {
99
+ toBe(expected) { if (actual !== expected) throw new Error(`Expected ${JSON.stringify(expected)} but got ${JSON.stringify(actual)}`); },
100
+ toEqual(expected) { if (JSON.stringify(actual) !== JSON.stringify(expected)) throw new Error(`Expected ${JSON.stringify(expected)} to equal ${JSON.stringify(actual)}`); },
101
+ toContain(item) { if (!actual.includes(item)) throw new Error(`Expected ${JSON.stringify(actual)} to contain ${JSON.stringify(item)}`); },
102
+ toBeNull() { if (actual !== null) throw new Error(`Expected null but got ${JSON.stringify(actual)}`); },
103
+ toBeTruthy() { if (!actual) throw new Error(`Expected truthy but got ${JSON.stringify(actual)}`); },
104
+ toBeFalsy() { if (actual) throw new Error(`Expected falsy but got ${JSON.stringify(actual)}`); },
105
+ toBeGreaterThan(n) { if (actual <= n) throw new Error(`Expected ${actual} > ${n}`); },
106
+ toBeLessThan(n) { if (actual >= n) throw new Error(`Expected ${actual} < ${n}`); },
107
+ toHaveLength(n) { if (actual.length !== n) throw new Error(`Expected length ${n} but got ${actual.length}`); },
108
+ toMatch(pattern) { if (!pattern.test(actual)) throw new Error(`Expected ${JSON.stringify(actual)} to match ${pattern}`); },
109
+ toThrow(msg) { try { actual(); throw new Error("Expected to throw"); } catch(e) { if (msg && !e.message.includes(msg)) throw new Error(`Expected error containing "${msg}" but got "${e.message}"`); } },
110
+ };
111
+ }
112
+ function _assert(condition, message) { if (!condition) throw new Error(message); }
113
+ async function _runTests() {
114
+ let passed = 0, failed = 0;
115
+ async function runItem(item, indent = "") {
116
+ if (item.fn) {
117
+ try { await item.fn(); console.log(indent + "✓ " + item.name); passed++; }
118
+ catch (e) { console.log(indent + "✗ " + item.name); console.log(indent + " " + e.message); failed++; }
119
+ } else {
120
+ console.log(indent + item.name);
121
+ for (const t of item.tests) await runItem(t, indent + " ");
122
+ }
123
+ }
124
+ for (const item of _tests) await runItem(item);
125
+ console.log(`\n${passed + failed} tests, ${passed} passed, ${failed} failed`);
126
+ return { passed, failed };
127
+ }
128
+
129
+ export default function(_opts = {}) {
130
+ const config = _dep_config;
131
+
132
+ function main() {
133
+ console.log(`App Name: ${config?.AppConfig?.name}`);
134
+ console.log(`Version: ${config?.AppConfig?.version}`);
135
+ console.log(`Colors: ${config?.Colors}`);
136
+ console.log(`HTTP OK Status: ${config?.HttpStatus?.STATUS_OK}`);
137
+ console.log(`API Endpoint: ${config?.Endpoints?.api}`);
138
+ }
139
+
140
+ main();
141
+ }
@@ -0,0 +1,13 @@
1
+ // Example of using a static file in KimchiLang
2
+
3
+ as config dep examples.config
4
+
5
+ fn main() {
6
+ print "App Name: ${config.AppConfig.name}"
7
+ print "Version: ${config.AppConfig.version}"
8
+ print "Colors: ${config.Colors}"
9
+ print "HTTP OK Status: ${config.HttpStatus.STATUS_OK}"
10
+ print "API Endpoint: ${config.Endpoints.api}"
11
+ }
12
+
13
+ main()
package/install.sh ADDED
@@ -0,0 +1,59 @@
1
+ #!/bin/bash
2
+
3
+ # KimchiLang Installer Script
4
+ # This script installs KimchiLang and makes the 'kimchi' command available globally
5
+
6
+ set -e
7
+
8
+ echo "🌶️ KimchiLang Installer"
9
+ echo "========================"
10
+ echo ""
11
+
12
+ # Check for Node.js
13
+ if ! command -v node &> /dev/null; then
14
+ echo "❌ Node.js is required but not installed."
15
+ echo " Please install Node.js from https://nodejs.org/"
16
+ exit 1
17
+ fi
18
+
19
+ NODE_VERSION=$(node -v | cut -d'v' -f2 | cut -d'.' -f1)
20
+ if [ "$NODE_VERSION" -lt 18 ]; then
21
+ echo "⚠️ Warning: Node.js 18+ is recommended. You have $(node -v)"
22
+ fi
23
+
24
+ # Check for npm
25
+ if ! command -v npm &> /dev/null; then
26
+ echo "❌ npm is required but not installed."
27
+ exit 1
28
+ fi
29
+
30
+ echo "✓ Node.js $(node -v) detected"
31
+ echo "✓ npm $(npm -v) detected"
32
+ echo ""
33
+
34
+ # Get the directory where this script is located
35
+ SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
36
+
37
+ # Install dependencies
38
+ echo "📦 Installing dependencies..."
39
+ cd "$SCRIPT_DIR"
40
+ npm install
41
+
42
+ echo ""
43
+ echo "🔗 Linking kimchi command globally..."
44
+
45
+ # Link the package globally
46
+ npm link
47
+
48
+ echo ""
49
+ echo "✅ Installation complete!"
50
+ echo ""
51
+ echo "You can now use the 'kimchi' command from anywhere:"
52
+ echo ""
53
+ echo " kimchi run hello.kimchi # Run a KimchiLang file"
54
+ echo " kimchi compile app.kimchi # Compile to JavaScript"
55
+ echo " kimchi convert input.js # Convert JS to KimchiLang"
56
+ echo " kimchi repl # Start interactive REPL"
57
+ echo " kimchi help # Show all commands"
58
+ echo ""
59
+ echo "🌶️ Happy coding with KimchiLang!"
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "kimchilang",
3
+ "version": "1.0.1",
4
+ "description": "A modern programming language that transpiles to JavaScript",
5
+ "main": "src/index.js",
6
+ "bin": {
7
+ "kimchi": "./src/cli.js"
8
+ },
9
+ "scripts": {
10
+ "build": "node src/cli.js build",
11
+ "test": "node test/test.js",
12
+ "example": "node src/cli.js run examples/basic.kimchi"
13
+ },
14
+ "keywords": [
15
+ "programming-language",
16
+ "transpiler",
17
+ "javascript",
18
+ "compiler"
19
+ ],
20
+ "author": "KimchiLang Team",
21
+ "license": "MIT",
22
+ "type": "module",
23
+ "dependencies": {
24
+ "acorn": "^8.15.0"
25
+ },
26
+ "devDependencies": {
27
+ "is-odd": "^3.0.1"
28
+ }
29
+ }
@@ -0,0 +1 @@
1
+ fn(global, factory) { }(/* this */, fn(exports) { })
@@ -0,0 +1 @@
1
+ expose dec exports = fn(num) { return false }
@@ -0,0 +1,2 @@
1
+ as isNumber dep is-number
2
+ expose dec exports = fn(value) { return n % 2 === 1 }
package/project.static ADDED
@@ -0,0 +1,6 @@
1
+ // KimchiLang project configuration
2
+ name "kimchilang"
3
+ version "1.0.0"
4
+
5
+ // No external dependencies for the main project
6
+ // This file demonstrates the format