bahasa-simpl 1.0.7 → 1.0.9

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
@@ -16,7 +16,6 @@ Berikut fitur yang _sekarang_ sudah diimplementasikan:
16
16
  - **Semua** kata kunci berjumlah 5 huruf dan dalam bahasa Indonesia
17
17
 
18
18
  Fitur yang akan datang:
19
- - Website untuk menjalankan `simpl`
20
19
  - dokumentasi penuh
21
20
  - Pembersihan dan perapihan kode sumber :')
22
21
  - Pengecekan sebelum eksekusi (Analisa semantik)
@@ -114,7 +113,7 @@ Pengguna lain = Pengguna.baru("Hengker Anongnimus")
114
113
  cetak Pengguna.kepetik(admin)
115
114
  # "{ nama: zie, id: 0, status: online }"
116
115
 
117
- cetak Pengguna.kePetik(lain)
116
+ cetak lain.kePetik()
118
117
  # "{ nama: Hengker Anongnimus, id: 1, status: online }"
119
118
  ```
120
119
 
@@ -124,4 +123,4 @@ cetak Pengguna.kePetik(lain)
124
123
  - [https://ruslanspivak.com/lsbasi-part1/](https://ruslanspivak.com/lsbasi-part1/)
125
124
  - [https://craftinginterpreters.com/](https://craftinginterpreters.com/)
126
125
 
127
- (No AI was used while making this, the proof is apparent in the spaghetti codebase)
126
+
@@ -88,36 +88,38 @@ class Stipe extends Variable {
88
88
 
89
89
  }
90
90
 
91
+ function kePetik(v, thing) {
92
+ if (thing.type === logisSymbol) {
93
+ return thing.data ? "benar" : "salah";
94
+ } else if (thing.type === barisSymbol) {
95
+ return '[' + thing.data.reduce((str, val) => {
96
+ let item = kePetik(v, val);
97
+ return str + ", " + (val.type === Value.petikSymbol ? `"${item}"` : item);
98
+ }, "").slice(1) + ' ]';
99
+ } else if (thing.type === stipeSymbol) {
100
+ return `Model<${thing.symbol.description}>`;
101
+ } else if (thing.type === mesinSymbol) {
102
+ let underlying = thing.data.returnType?.description;
103
+ return `Mesin<${underlying ? underlying : 'datum'}>`;
104
+ } else if (thing.type === angkaSymbol) {
105
+ return thing.data.toString();
106
+ } else if (thing.type === petikSymbol) {
107
+ return '"' + thing.data + '"';
108
+ } else {
109
+ if (!thing?.type) return `nihil`;
110
+ let type = v.environment.get(thing.type.description);
111
+ if (type?.member.has("kePetik")) {
112
+ let res = v.callFunc(type.member.get("kePetik").data, [thing]).data;
113
+ return res;
114
+ }
115
+ return `${thing.type.description}<>`;
116
+ }
117
+ }
118
+
91
119
  class PetikTipe extends Stipe {
92
120
  constructor() {
93
- super(petikSymbol, new Callable(null, (v, args) => {
94
- const kePetik = (thing) => {
95
- if (thing.type === logisSymbol) {
96
- return thing.data ? "benar" : "salah";
97
- } else if (thing.type === barisSymbol) {
98
- return '[' + thing.data.reduce((str, val) => str + ", " + kePetik(val), "").slice(1) + ' ]';
99
- } else if (thing.type === stipeSymbol) {
100
- return `Model<${thing.symbol.description}>`;
101
- } else if (thing.type === mesinSymbol) {
102
- let underlying = thing.data.returnType?.description;
103
- return `Mesin<${underlying ? underlying : 'datum'}>`;
104
- } else if (thing.type === angkaSymbol) {
105
- return thing.data.toString();
106
- } else if (thing.type === petikSymbol) {
107
- return '"' + thing.data + '"';
108
- } else {
109
- if (!thing?.type) return `nihil`;
110
- let type = v.environment.get(thing.type.description);
111
- if (type?.member.has("kePetik")) {
112
- let res = v.callFunc(type.member.get("kePetik").data, [thing]).data;
113
- return res;
114
- }
115
- return `${thing.type.description}<>`;
116
- }
117
- };
118
- return new Value(petikSymbol, kePetik(args[0]));
119
- }, [[null]], petikSymbol, true)
120
- );
121
+ super(petikSymbol, new Callable(null, (v, args) => new Value(petikSymbol, kePetik(v, args[0])),
122
+ [[null]], petikSymbol, true) );
121
123
  this.init();
122
124
  }
123
125
 
@@ -145,6 +147,9 @@ class PetikTipe extends Stipe {
145
147
  this.member.define("SERU_UNER",
146
148
  makeBuiltInFunc([petikSymbol], logisSymbol, (_, [r]) => new Value(logisSymbol, !Boolean(r.data))));
147
149
 
150
+ this.member.define("kePetik",
151
+ makeBuiltInFunc([petikSymbol], petikSymbol, (v, [p]) => new Value(petikSymbol, kePetik(v, p))));
152
+
148
153
  this.member.define("pisah", makeBuiltInFunc([petikSymbol, petikSymbol], barisSymbol, (_, [d, sep]) => {
149
154
  return new Value(barisSymbol, d.data.split(sep.data).map(val => new Value(petikSymbol, val)));
150
155
  }));
@@ -224,6 +229,9 @@ class AngkaTipe extends Stipe {
224
229
  this.member.define("MINUS_UNER",
225
230
  makeBuiltInFunc([angkaSymbol], angkaSymbol, (_, [r]) => new Value(angkaSymbol, -r.data)));
226
231
 
232
+ this.member.define("kePetik",
233
+ makeBuiltInFunc([angkaSymbol], petikSymbol, (v, [a]) => new Value(petikSymbol, kePetik(v, a))));
234
+
227
235
  this.member.define("bulat", makeBuiltInFunc([angkaSymbol], angkaSymbol, (_, [a]) => {
228
236
  return new Value(angkaSymbol, Math.round(a.data));
229
237
  }));
@@ -259,6 +267,9 @@ class LogisTipe extends Stipe {
259
267
  makeBuiltInFunc([logisSymbol, logisSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data || r.data)));
260
268
  this.member.define("SERU_UNER",
261
269
  makeBuiltInFunc([logisSymbol], logisSymbol, (_, [r]) => new Value(logisSymbol, !Boolean(r.data))));
270
+
271
+ this.member.define("kePetik",
272
+ makeBuiltInFunc([logisSymbol], petikSymbol, (v, [l]) => new Value(petikSymbol, kePetik(v, l))));
262
273
  }
263
274
  }
264
275
 
@@ -269,6 +280,13 @@ class BarisTipe extends Stipe {
269
280
  }
270
281
 
271
282
  init() {
283
+ const valueToVariableDatum = (d) => {
284
+ let input = new Variable(d.type, false, d.data);
285
+ input.member = d.member;
286
+ input.isDatum = true;
287
+ return input;
288
+ };
289
+
272
290
  this.member.define("PLUS",
273
291
  makeBuiltInFunc([barisSymbol, barisSymbol], barisSymbol, (_, [r, l]) =>
274
292
  new Value(barisSymbol, Array(...l.data, ...r.data))
@@ -306,6 +324,9 @@ class BarisTipe extends Stipe {
306
324
  this.member.define("SERU_UNER",
307
325
  makeBuiltInFunc([barisSymbol], logisSymbol, (_, [r]) => new Value(logisSymbol, !Boolean(r.data))));
308
326
 
327
+ this.member.define("kePetik",
328
+ makeBuiltInFunc([barisSymbol], petikSymbol, (v, [p]) => new Value(petikSymbol, kePetik(v, p))));
329
+
309
330
  this.member.define("hapus", makeBuiltInFunc([barisSymbol, angkaSymbol], barisSymbol, (v, [b, i]) => {
310
331
  if (b.data.length <= i.data) {
311
332
  v.error(`Indeks tidak boleh lebih besar atau sama dengan ukuran baris, ${i.data} >= ${b.data.length}`);
@@ -318,12 +339,12 @@ class BarisTipe extends Stipe {
318
339
 
319
340
  this.member.define("potongan", makeBuiltInFunc([barisSymbol, angkaSymbol, angkaSymbol], barisSymbol, (v, [b, fr, to]) => {
320
341
  if (fr.data >= b.data.length || fr.data < 0 || to.data <= fr.data || to.data > b.data.length) {
321
- v.error(`Indeks tidak valid, ${fr.data}:${to.data}, dengan ukuran baris ${b.data.length}`);
342
+ v.error(`Indeks tidak valid, ${fr.data} sampai ${to.data}, dengan ukuran baris ${b.data.length}`);
322
343
  }
323
344
  return new Value(barisSymbol, b.data.slice(fr.data, to.data));
324
345
  }));
325
346
  this.member.define("tumpuk", makeBuiltInFunc([barisSymbol, null], null, (_, [b, d]) => {
326
- b.data.push(d);
347
+ b.data.push(valueToVariableDatum(d));
327
348
  return b;
328
349
  }));
329
350
  this.member.define("tumpah", makeBuiltInFunc([barisSymbol], null, (_, [b]) => {
@@ -334,14 +355,14 @@ class BarisTipe extends Stipe {
334
355
  if (idx.data > b.data.length) {
335
356
  v.error(`Indeks tidak valid, ${idx.data}, dengan ukuran baris ${b.data.length}`);
336
357
  }
337
- b.data.splice(idx.data, 0, d);
358
+ b.data.splice(idx.data, 0, valueToVariableDatum(d));
338
359
  return b;
339
360
  }));
340
361
  this.member.define("petakan", makeBuiltInFunc([barisSymbol, mesinSymbol], barisSymbol, (v, [b, m]) => {
341
362
  let newBaris = new Value(barisSymbol, []);
342
363
  for (let datum of b.data) {
343
364
  let result = v.callFunc(m.data, [datum]);
344
- newBaris.data.push(result);
365
+ newBaris.data.push(valueToVariableDatum(result));
345
366
  }
346
367
  return newBaris;
347
368
  }));
@@ -350,7 +371,7 @@ class BarisTipe extends Stipe {
350
371
  for (let datum of b.data) {
351
372
  let result = v.callFunc(m.data, [datum]);
352
373
  if (result.data === true) {
353
- newBaris.data.push(datum);
374
+ newBaris.data.push(valueToVariableDatum(datum));
354
375
  }
355
376
  }
356
377
  return newBaris;
@@ -362,13 +383,33 @@ class BarisTipe extends Stipe {
362
383
  }
363
384
  return d;
364
385
  }));
386
+
387
+ this.member.define("punya?", makeBuiltInFunc([barisSymbol, null], logisSymbol, (v, [b, d]) => {
388
+ let type = v.environment.get(d.type?.description);
389
+ if (!type)
390
+ v.error(`Tipe tidak ditemukan atau tidak valid`);
391
+ let equalFunc;
392
+ if (type.member?.has("SAMA_SAMA")) {
393
+ equalFunc = type.member.get("SAMA_SAMA");
394
+ } else {
395
+ v.error(`model ${d.type.description} tidak mempunyai mesin SAMA_SAMA di dalam modulnya.`);
396
+ }
397
+ for (let datum of b.data) {
398
+ if (datum.type !== d.type) continue;
399
+ let isEqual = v.callFunc(equalFunc.data, [datum, d]);
400
+ if (isEqual.data) return new Value(logisSymbol, true);
401
+ }
402
+ return new Value(logisSymbol, false);
403
+ }));
365
404
  }
366
405
  }
367
406
 
368
407
  class MesinTipe extends Stipe {
369
408
  constructor() {
370
409
  super(mesinSymbol);
371
- this.member.define("$", null);
410
+
411
+ this.member.define("kePetik",
412
+ makeBuiltInFunc([mesinSymbol], petikSymbol, (v, [m]) => new Value(petikSymbol, kePetik(v, m))));
372
413
  }
373
414
  }
374
415
 
@@ -413,8 +454,7 @@ let Jenis$1 = class Jenis extends Stipe {
413
454
  this.member.define(thing.lexeme, new Value(sym, idx));
414
455
  });
415
456
  this.member.define("kePetik", makeBuiltInFunc([sym], petikSymbol, (_, [j]) => {
416
- let enumName = enums.map(thing=>thing.lexeme)[j.data];
417
- return new Value(petikSymbol, `${name}.${enumName}`);
457
+ return new Value(petikSymbol, `${name}<${j.data}>`);
418
458
  }));
419
459
  this.init(sym);
420
460
  }
@@ -449,7 +489,12 @@ function copier(thing) {
449
489
  case angkaSymbol: return new Value(angkaSymbol, thing.data);
450
490
  case logisSymbol: return new Value(logisSymbol, thing.data);
451
491
  case mesinSymbol: return new Value(mesinSymbol, thing.data);
452
- case barisSymbol: return new Value(barisSymbol, thing.data.map((val) => copier(val)));
492
+ case barisSymbol: return new Value(barisSymbol, thing.data.map((val) => {
493
+ let copy = copier(val);
494
+ let varCopy = new Variable(copy.type, false, copy.data);
495
+ varCopy.member = copy.member;
496
+ return varCopy
497
+ }));
453
498
  case stipeSymbol: return NIHIL;
454
499
  case modulSymbol: return NIHIL;
455
500
  default:
@@ -458,13 +503,17 @@ function copier(thing) {
458
503
  let valCopy = new Value(thing.type, null);
459
504
  let newMember = new Environment();
460
505
  for (let i of keys) {
461
- newMember.define(i, copier(thing.member.get(i)));
506
+ let varPrev = thing.member.get(i);
507
+ let tempCopy = copier(varPrev);
508
+ let varCopy = new Variable(varPrev.type, varPrev.tetap, tempCopy.data);
509
+ varCopy.member = tempCopy.member;
510
+ newMember.define(i, varCopy);
462
511
  }
463
512
  valCopy.member = newMember;
464
-
513
+ valCopy.data = thing.data;
465
514
  return valCopy;
466
515
  }
467
- return NIHIL;
516
+ return new Value(thing.type, thing.data);
468
517
  }
469
518
  }
470
519
 
@@ -949,35 +998,7 @@ class Interpreter {
949
998
 
950
999
  visitCetakStmt(cetakStmt) {
951
1000
  let result = cetakStmt.expr.accept(this);
952
- const kePetik = (thing) => {
953
- if (thing.type === logisSymbol) {
954
- return thing.data ? "benar" : "salah";
955
- } else if (thing.type === barisSymbol) {
956
- return '[' + thing.data.reduce((str, val) => {
957
- let item = kePetik(val);
958
- return str + ", " + (val.type === petikSymbol ? `"${item}"` : item);
959
- }, "").slice(1) + ' ]';
960
- } else if (thing.type === stipeSymbol) {
961
- return `Model<${thing.symbol.description}>`;
962
- } else if (thing.type === mesinSymbol) {
963
- let underlying = thing.data.returnType?.description;
964
- return `Mesin<${underlying ? underlying : 'datum'}>`;
965
- } else if (thing.type === angkaSymbol) {
966
- return thing.data.toString();
967
- } else if (thing.type === petikSymbol) {
968
- return thing.data;
969
- } else {
970
- if (!thing?.type) return `nihil`;
971
- let type = this.environment.get(thing.type.description);
972
- if (type?.member?.has("kePetik")) {
973
- let res = this.callFunc(type.member.get("kePetik").data, [thing]).data;
974
- return res;
975
- }
976
- return `${thing.type.description}<>`;
977
- }
978
- };
979
-
980
- this.output.push(kePetik(result));
1001
+ this.output.push(kePetik(this, result));
981
1002
 
982
1003
  }
983
1004
 
@@ -1009,6 +1030,9 @@ class Interpreter {
1009
1030
 
1010
1031
  visitRubahStmt(rubahStmt) {
1011
1032
  let variable = rubahStmt.variable.accept(this); // is a reference to the variable data
1033
+ if (variable.tetap === undefined) {
1034
+ this.error(`Pe-rubah-an hanya dapat dilakukan kepada Variabel!`);
1035
+ }
1012
1036
  if (variable.tetap) {
1013
1037
  this.error(`Variabel tetap tidak dapat di-rubah.`);
1014
1038
  }
@@ -1379,6 +1403,17 @@ class Lexer {
1379
1403
  this.charStart++;
1380
1404
  }
1381
1405
 
1406
+ multilineComment() {
1407
+ this.advance(); this.advance();
1408
+ this.charStart = this.charStart + 2;
1409
+ while (!this.isAtEnd() && (this.see() !== '*' || this.peek() !== '/')) {
1410
+ this.advance();
1411
+ this.charStart++;
1412
+ }
1413
+ this.advance(); this.advance();
1414
+ this.charStart = this.charStart + 2;
1415
+ }
1416
+
1382
1417
  makeToken(type) {
1383
1418
  this.advance();
1384
1419
  return new Token(type, this.parseLexeme(), null, this.lineIndex);
@@ -1386,8 +1421,9 @@ class Lexer {
1386
1421
 
1387
1422
  scan() {
1388
1423
  this.skipWhitespaces();
1389
- while (this.see() === '#') {
1390
- this.comment();
1424
+ while (this.see() === '#' || (this.see() === '/' && this.peek() === '*')) {
1425
+ if (this.see() === '#') this.comment();
1426
+ else this.multilineComment();
1391
1427
  this.skipWhitespaces();
1392
1428
  }
1393
1429
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bahasa-simpl",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
4
4
  "description": "Simpl: Indonesian Mini Programming Language interpreter",
5
5
  "main": "./dist/simpl-interpreter.js",
6
6
  "scripts": {