kimchilang 1.0.1 → 1.0.2
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 +14 -0
- package/create-kimchi-app/package.json +2 -2
- package/install-kimchilang/index.js +60 -0
- package/install-kimchilang/package.json +21 -0
- package/package.json +4 -10
- package/src/generator.js +24 -0
- package/src/parser.js +22 -0
- package/src/typechecker.js +17 -0
package/README.md
CHANGED
|
@@ -334,6 +334,20 @@ sum(1, 2, 3, 4, 5) // 15
|
|
|
334
334
|
fn log(prefix, separator = ": ", ...messages) {
|
|
335
335
|
return prefix + separator + messages.join(", ")
|
|
336
336
|
}
|
|
337
|
+
|
|
338
|
+
// Parameter destructuring - objects
|
|
339
|
+
fn greetPerson({ name, age }) {
|
|
340
|
+
print "Hello, " + name + "! You are " + age
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
greetPerson({ name: "Alice", age: 30 })
|
|
344
|
+
|
|
345
|
+
// Parameter destructuring - arrays
|
|
346
|
+
fn swap([a, b]) {
|
|
347
|
+
return [b, a]
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
swap([1, 2]) // [2, 1]
|
|
337
351
|
```
|
|
338
352
|
|
|
339
353
|
### Enums
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"version": "1.0.0",
|
|
4
4
|
"description": "Create a new KimchiLang application",
|
|
5
5
|
"bin": {
|
|
6
|
-
"create-kimchi-app": "
|
|
6
|
+
"create-kimchi-app": "index.js"
|
|
7
7
|
},
|
|
8
8
|
"type": "module",
|
|
9
9
|
"keywords": [
|
|
@@ -17,6 +17,6 @@
|
|
|
17
17
|
"license": "MIT",
|
|
18
18
|
"repository": {
|
|
19
19
|
"type": "git",
|
|
20
|
-
"url": "https://github.com/kimchilang/kimchilang"
|
|
20
|
+
"url": "git+https://github.com/kimchilang/kimchilang.git"
|
|
21
21
|
}
|
|
22
22
|
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { execSync } from 'child_process';
|
|
4
|
+
|
|
5
|
+
const COLORS = {
|
|
6
|
+
reset: '\x1b[0m',
|
|
7
|
+
bright: '\x1b[1m',
|
|
8
|
+
green: '\x1b[32m',
|
|
9
|
+
cyan: '\x1b[36m',
|
|
10
|
+
yellow: '\x1b[33m',
|
|
11
|
+
red: '\x1b[31m',
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
function log(message, color = '') {
|
|
15
|
+
console.log(color + message + COLORS.reset);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function run(command, options = {}) {
|
|
19
|
+
try {
|
|
20
|
+
execSync(command, { stdio: 'inherit', ...options });
|
|
21
|
+
return true;
|
|
22
|
+
} catch (error) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function showHelp() {
|
|
28
|
+
log('\n🌶️ install-kimchilang\n', COLORS.bright + COLORS.cyan);
|
|
29
|
+
log('Install KimchiLang globally on your system.\n');
|
|
30
|
+
log('Usage:');
|
|
31
|
+
log(' npx install-kimchilang');
|
|
32
|
+
log(' npx install-kimchilang --help\n');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Main
|
|
36
|
+
const args = process.argv.slice(2);
|
|
37
|
+
|
|
38
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
39
|
+
showHelp();
|
|
40
|
+
process.exit(0);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
log('\n🌶️ Installing KimchiLang...\n', COLORS.bright + COLORS.cyan);
|
|
44
|
+
|
|
45
|
+
// Install kimchilang globally
|
|
46
|
+
log('Installing kimchilang globally...', COLORS.yellow);
|
|
47
|
+
|
|
48
|
+
if (run('npm install -g kimchilang')) {
|
|
49
|
+
log('\n✨ KimchiLang installed successfully!\n', COLORS.bright + COLORS.green);
|
|
50
|
+
log('You can now use:', COLORS.cyan);
|
|
51
|
+
log(' kimchi --help Show help');
|
|
52
|
+
log(' kimchi src.main Run a module');
|
|
53
|
+
log(' kimchi compile app.km Compile a file');
|
|
54
|
+
log(' npx create-kimchi-app Create a new project\n');
|
|
55
|
+
} else {
|
|
56
|
+
log('\n❌ Installation failed.\n', COLORS.red);
|
|
57
|
+
log('Try running with sudo:', COLORS.yellow);
|
|
58
|
+
log(' sudo npm install -g kimchilang\n');
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "install-kimchilang",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Install KimchiLang globally",
|
|
5
|
+
"bin": {
|
|
6
|
+
"install-kimchilang": "index.js"
|
|
7
|
+
},
|
|
8
|
+
"type": "module",
|
|
9
|
+
"keywords": [
|
|
10
|
+
"kimchi",
|
|
11
|
+
"kimchilang",
|
|
12
|
+
"install",
|
|
13
|
+
"cli"
|
|
14
|
+
],
|
|
15
|
+
"author": "",
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/danajanezic/kimchilang.git"
|
|
20
|
+
}
|
|
21
|
+
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kimchilang",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "A modern programming language that transpiles to JavaScript",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
|
7
|
-
"kimchi": "
|
|
7
|
+
"kimchi": "src/cli.js"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"build": "node src/cli.js build",
|
|
@@ -17,13 +17,7 @@
|
|
|
17
17
|
"javascript",
|
|
18
18
|
"compiler"
|
|
19
19
|
],
|
|
20
|
-
"author": "
|
|
20
|
+
"author": "Dana Janezic",
|
|
21
21
|
"license": "MIT",
|
|
22
|
-
"type": "module"
|
|
23
|
-
"dependencies": {
|
|
24
|
-
"acorn": "^8.15.0"
|
|
25
|
-
},
|
|
26
|
-
"devDependencies": {
|
|
27
|
-
"is-odd": "^3.0.1"
|
|
28
|
-
}
|
|
22
|
+
"type": "module"
|
|
29
23
|
}
|
package/src/generator.js
CHANGED
|
@@ -700,6 +700,30 @@ export class CodeGenerator {
|
|
|
700
700
|
if (p.type === 'RestElement') {
|
|
701
701
|
return `...${p.argument}`;
|
|
702
702
|
}
|
|
703
|
+
|
|
704
|
+
// Handle destructuring patterns
|
|
705
|
+
if (p.destructuring === 'object') {
|
|
706
|
+
const props = p.pattern.properties.map(prop => prop.key).join(', ');
|
|
707
|
+
const pattern = `{ ${props} }`;
|
|
708
|
+
if (p.defaultValue) {
|
|
709
|
+
return `${pattern} = ${this.visitExpression(p.defaultValue)}`;
|
|
710
|
+
}
|
|
711
|
+
return pattern;
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
if (p.destructuring === 'array') {
|
|
715
|
+
const elems = p.pattern.elements.map(elem => {
|
|
716
|
+
if (elem === null) return '';
|
|
717
|
+
if (elem.type === 'Identifier') return elem.name;
|
|
718
|
+
return this.visitExpression(elem);
|
|
719
|
+
}).join(', ');
|
|
720
|
+
const pattern = `[${elems}]`;
|
|
721
|
+
if (p.defaultValue) {
|
|
722
|
+
return `${pattern} = ${this.visitExpression(p.defaultValue)}`;
|
|
723
|
+
}
|
|
724
|
+
return pattern;
|
|
725
|
+
}
|
|
726
|
+
|
|
703
727
|
if (p.defaultValue) {
|
|
704
728
|
return `${p.name} = ${this.visitExpression(p.defaultValue)}`;
|
|
705
729
|
}
|
package/src/parser.js
CHANGED
|
@@ -544,6 +544,28 @@ export class Parser {
|
|
|
544
544
|
break;
|
|
545
545
|
}
|
|
546
546
|
|
|
547
|
+
// Check for object destructuring pattern: { a, b }
|
|
548
|
+
if (this.check(TokenType.LBRACE)) {
|
|
549
|
+
const pattern = this.parseObjectPattern();
|
|
550
|
+
let defaultValue = null;
|
|
551
|
+
if (this.match(TokenType.ASSIGN)) {
|
|
552
|
+
defaultValue = this.parseExpression();
|
|
553
|
+
}
|
|
554
|
+
params.push({ pattern, defaultValue, destructuring: 'object' });
|
|
555
|
+
continue;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
// Check for array destructuring pattern: [a, b]
|
|
559
|
+
if (this.check(TokenType.LBRACKET)) {
|
|
560
|
+
const pattern = this.parseArrayPattern();
|
|
561
|
+
let defaultValue = null;
|
|
562
|
+
if (this.match(TokenType.ASSIGN)) {
|
|
563
|
+
defaultValue = this.parseExpression();
|
|
564
|
+
}
|
|
565
|
+
params.push({ pattern, defaultValue, destructuring: 'array' });
|
|
566
|
+
continue;
|
|
567
|
+
}
|
|
568
|
+
|
|
547
569
|
const name = this.expect(TokenType.IDENTIFIER, 'Expected parameter name').value;
|
|
548
570
|
let defaultValue = null;
|
|
549
571
|
|
package/src/typechecker.js
CHANGED
|
@@ -398,6 +398,23 @@ export class TypeChecker {
|
|
|
398
398
|
|
|
399
399
|
// Define parameters in scope
|
|
400
400
|
for (const param of node.params) {
|
|
401
|
+
// Handle destructuring patterns
|
|
402
|
+
if (param.destructuring === 'object' && param.pattern) {
|
|
403
|
+
for (const prop of param.pattern.properties) {
|
|
404
|
+
this.defineVariable(prop.key, this.createType(Type.Any));
|
|
405
|
+
}
|
|
406
|
+
continue;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
if (param.destructuring === 'array' && param.pattern) {
|
|
410
|
+
for (const elem of param.pattern.elements) {
|
|
411
|
+
if (elem && elem.type === 'Identifier') {
|
|
412
|
+
this.defineVariable(elem.name, this.createType(Type.Any));
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
continue;
|
|
416
|
+
}
|
|
417
|
+
|
|
401
418
|
const name = param.name || param.argument;
|
|
402
419
|
let paramType = this.createType(Type.Any);
|
|
403
420
|
|