bahasa-simpl 1.0.0 → 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.
@@ -4,7 +4,12 @@ class SimplError extends Error {
4
4
  super(message);
5
5
  this.line = line;
6
6
  }
7
- }class SimplErrorEksekusi extends SimplError {}class SimplErrorStruktur extends SimplError {}class SimplErrorTulisan extends SimplError {}
7
+ }class SimplErrorEksekusi extends SimplError {
8
+ constructor(message, line, output) {
9
+ super(message, line);
10
+ this.output = output;
11
+ }
12
+ }class SimplErrorStruktur extends SimplError {}class SimplErrorTulisan extends SimplError {}
8
13
 
9
14
  // Environment defines a scope for all data to live in
10
15
  class Environment {
@@ -174,6 +179,8 @@ class Value {
174
179
  }
175
180
  }
176
181
 
182
+ const NIHIL = new Value(null, null);
183
+
177
184
  class Variable extends Value {
178
185
  constructor(type, tetap, data) {
179
186
  super(type, data);
@@ -198,9 +205,9 @@ class Stipe extends Variable {
198
205
 
199
206
  let result = null;
200
207
  if (left) { // Binary
201
- result = operatorFunc.data.callFunc(visitor, [right, left]);
208
+ result = visitor.callFunc(operatorFunc.data, [right, left]);
202
209
  } else { // Unary, safe because valid unary op is just + - ! in the parser
203
- result = operatorFunc.data.callFunc(visitor, [right]);
210
+ result = visitor.callFunc(operatorFunc.data, [right]);
204
211
  }
205
212
  return result;
206
213
  }
@@ -208,168 +215,180 @@ class Stipe extends Variable {
208
215
 
209
216
  class PetikTipe extends Stipe {
210
217
  constructor() {
211
- super(petikSymbol,
212
- {
213
- callFunc: (v,args) => {
214
- if (args.length !== 1) {
215
- v.error(`Jumlah argumen tidak sama dengan parameter mesin: ${args.length} != 1.`);
216
- }
217
-
218
- const kePetik = (thing) => {
219
- if (thing.type === logisSymbol) {
220
- return thing.data ? "benar" : "salah";
221
- } else if (thing.type === barisSymbol) {
222
- return '[' + thing.data.reduce((str, val)=>str+" "+kePetik(val)+",", "") + ' ]'
223
- } else if (thing.type === stipeSymbol) {
224
- return `Model:${thing.symbol.description}`;
225
- } else if (thing.type === mesinSymbol) {
226
- return `Mesin<>`;
227
- } else if (thing.type === angkaSymbol || thing.type === petikSymbol) {
228
- return thing.data !== null ? thing.data.toString() : "nihil";
229
- } else {
230
- return `Objek<${thing.symbol.description}>` + thing;
231
- }
232
- };
233
-
234
- return new Value(petikSymbol, kePetik(args[0]));
218
+ super(petikSymbol, new Callable(null, (v,args) => {
219
+ const kePetik = (thing) => {
220
+ if (thing.type === logisSymbol) {
221
+ return thing.data ? "benar" : "salah";
222
+ } else if (thing.type === barisSymbol) {
223
+ return '[' + thing.data.reduce((str, val)=>str+", "+kePetik(val), "").slice(1) + ' ]';
224
+ } else if (thing.type === stipeSymbol) {
225
+ return `Model<${thing.symbol.description}>`;
226
+ } else if (thing.type === mesinSymbol) {
227
+ let underlying = thing.data.returnType?.description;
228
+ return `Mesin<${underlying? underlying : 'datum'}>`;
229
+ } else if (thing.type === angkaSymbol) {
230
+ return thing.data.toString();
231
+ } else if (thing.type === petikSymbol) {
232
+ return '"' + thing.data + '"';
233
+ } else {
234
+ if (!thing?.type) return `nihil`;
235
+ let type = v.environment.get(thing.type.description);
236
+ if (type?.member.has("kePetik")) {
237
+ v.stack.push(v.line);
238
+ let res = v.callFunc(type.member.get("kePetik").data, [thing]).data;
239
+ v.stack.pop();
240
+ return res;
235
241
  }
236
-
237
- });
242
+ return `${thing.type.description}<>`;
243
+ }
244
+ };
245
+ return new Value(petikSymbol, kePetik(args[0]));
246
+ }, [[null]], petikSymbol, true)
247
+ );
238
248
  this.init();
239
249
  }
240
250
 
241
251
  init() {
242
252
  // BINARY / UNARY OPERATORS
243
253
  this.operators.define("PLUS",
244
- makeBuiltInFunc([petikSymbol, petikSymbol], petikSymbol, (v, [r, l]) => new Value(petikSymbol, l.data+r.data)));
254
+ makeBuiltInFunc([petikSymbol, petikSymbol], petikSymbol, (_, [r, l]) => new Value(petikSymbol, l.data+r.data)));
245
255
  this.operators.define("LEBIH",
246
- makeBuiltInFunc([petikSymbol, petikSymbol], logisSymbol, (v, [r, l]) => new Value(logisSymbol, l.data>r.data)));
256
+ makeBuiltInFunc([petikSymbol, petikSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data>r.data)));
247
257
  this.operators.define("KURANG",
248
- makeBuiltInFunc([petikSymbol, petikSymbol], logisSymbol, (v, [r, l]) => new Value(logisSymbol, l.data<r.data)));
258
+ makeBuiltInFunc([petikSymbol, petikSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data<r.data)));
249
259
  this.operators.define("SAMA_SAMA",
250
- makeBuiltInFunc([petikSymbol, petikSymbol], logisSymbol, (v, [r, l]) => new Value(logisSymbol, l.data===r.data)));
260
+ makeBuiltInFunc([petikSymbol, petikSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data===r.data)));
251
261
  this.operators.define("LEBIH_SAMA",
252
- makeBuiltInFunc([petikSymbol, petikSymbol], logisSymbol, (v, [r, l]) => new Value(logisSymbol, l.data>=r.data)));
262
+ makeBuiltInFunc([petikSymbol, petikSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data>=r.data)));
253
263
  this.operators.define("KURANG_SAMA",
254
- makeBuiltInFunc([petikSymbol, petikSymbol], logisSymbol, (v, [r, l]) => new Value(logisSymbol, l.data<=r.data)));
264
+ makeBuiltInFunc([petikSymbol, petikSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data<=r.data)));
255
265
  this.operators.define("SERU_SAMA",
256
- makeBuiltInFunc([petikSymbol, petikSymbol], logisSymbol, (v, [r, l]) => new Value(logisSymbol, l.data!==r.data)));
266
+ makeBuiltInFunc([petikSymbol, petikSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data!==r.data)));
257
267
  this.operators.define("AMPERSAN",
258
- makeBuiltInFunc([petikSymbol, petikSymbol], logisSymbol, (v, [r, l]) => new Value(logisSymbol, l.data&&r.data)));
268
+ makeBuiltInFunc([petikSymbol, petikSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data&&r.data)));
259
269
  this.operators.define("PIPA",
260
- makeBuiltInFunc([petikSymbol, petikSymbol], logisSymbol, (v, [r, l]) => new Value(logisSymbol, l.data||r.data)));
270
+ makeBuiltInFunc([petikSymbol, petikSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data||r.data)));
261
271
 
262
272
  this.operators.define("SERU_UNARY",
263
- makeBuiltInFunc([petikSymbol], logisSymbol, (v, [r]) => new Value(logisSymbol, !Boolean(r.data))));
273
+ makeBuiltInFunc([petikSymbol], logisSymbol, (_, [r]) => new Value(logisSymbol, !Boolean(r.data))));
264
274
 
265
275
  this.member = new Environment();
266
276
 
267
- this.member.define("pisah", makeBuiltInFunc([petikSymbol, petikSymbol], barisSymbol, (v, [d, sep])=>{
277
+ this.member.define("pisah", makeBuiltInFunc([petikSymbol, petikSymbol], barisSymbol, (_, [d, sep])=>{
268
278
  return new Value(barisSymbol, d.data.split(sep.data).map(val=>new Value(petikSymbol, val)));
269
279
  }));
270
- this.member.define("bersih", makeBuiltInFunc([petikSymbol], petikSymbol, (v, [d])=> {
280
+ this.member.define("bersih", makeBuiltInFunc([petikSymbol], petikSymbol, (_, [d])=> {
271
281
  return new Value(petikSymbol, d.data.trim())
272
282
  }));
273
283
  this.member.define("ganti", makeBuiltInFunc([petikSymbol, petikSymbol, petikSymbol], petikSymbol,
274
- (v, [d, what, rep]) => new Value(petikSymbol, d.data.replaceAll(what.data, rep.data))
284
+ (_, [d, what, rep]) => new Value(petikSymbol, d.data.replaceAll(what.data, rep.data))
275
285
  ));
286
+ this.member.define("besar", makeBuiltInFunc([petikSymbol], petikSymbol, (_, [p]) => {
287
+ return new Value(petikSymbol, p.data.toUpperCase())
288
+ }));
289
+ this.member.define("kecil", makeBuiltInFunc([petikSymbol], petikSymbol, (_, [p]) => {
290
+ return new Value(petikSymbol, p.data.toLowerCase())
291
+ }));
276
292
  }
277
293
  }
278
294
 
279
295
  class AngkaTipe extends Stipe {
280
296
  constructor() {
281
- super(angkaSymbol, {
282
- callFunc: (v, args) => {
283
- if (args.length !== 1) {
284
- v.error(`Jumlah argumen tidak sama dengan parameter mesin: ${args.length} != 1.`);
285
- }
286
-
287
- switch (args[0].type) {
288
- case petikSymbol:
289
- if (isNaN(Number(args[0].data))) {
290
- v.error("Nilai dari petik bukanlah sebuah angka, konversi gagal.");
291
- }
292
- return new Value(angkaSymbol, Number(args[0].data));
293
- case angkaSymbol:
294
- return new Value(angkaSymbol, args[0].data);
295
- case logisSymbol:
296
- return new Value(angkaSymbol, Number(args[0].data));
297
- default:
298
- v.error(`Tipe yang dapat diterima hanyalah petik, angka, dan logis. Mendapatkan ${args[0].type.description}.`);
299
- return;
300
- }
301
- }
302
- });
297
+ super(angkaSymbol, new Callable(null, (v, args) => {
298
+ if (typeof args[0].data === "number") {
299
+ return new Value(angkaSymbol, args[0].data);
300
+ }
301
+
302
+ switch (args[0].type) {
303
+ case petikSymbol:
304
+ if (isNaN(Number(args[0].data))) {
305
+ v.error("Nilai dari petik bukanlah sebuah angka, konversi gagal.");
306
+ }
307
+ return new Value(angkaSymbol, Number(args[0].data));
308
+ case angkaSymbol:
309
+ return new Value(angkaSymbol, args[0].data);
310
+ case logisSymbol:
311
+ return new Value(angkaSymbol, Number(args[0].data));
312
+ default:
313
+ v.error(`Tipe yang dapat diterima hanyalah petik, angka, logis, dan jenis. Mendapatkan ${args[0].type.description}.`);
314
+ return;
315
+ }
316
+ }, [[null]], angkaSymbol, true)
317
+ );
303
318
  this.init();
304
319
  }
305
320
 
306
321
  init() {
307
322
  this.operators.define("PLUS",
308
- makeBuiltInFunc([angkaSymbol, angkaSymbol], angkaSymbol, (v, [r, l]) => new Value(angkaSymbol, l.data+r.data)));
323
+ makeBuiltInFunc([angkaSymbol, angkaSymbol], angkaSymbol, (_, [r, l]) => new Value(angkaSymbol, l.data+r.data)));
309
324
  this.operators.define("MINUS",
310
- makeBuiltInFunc([angkaSymbol, angkaSymbol], angkaSymbol, (v, [r, l]) => new Value(angkaSymbol, l.data-r.data)));
325
+ makeBuiltInFunc([angkaSymbol, angkaSymbol], angkaSymbol, (_, [r, l]) => new Value(angkaSymbol, l.data-r.data)));
311
326
  this.operators.define("BINTANG",
312
- makeBuiltInFunc([angkaSymbol, angkaSymbol], angkaSymbol, (v, [r, l]) => new Value(angkaSymbol, l.data*r.data)));
327
+ makeBuiltInFunc([angkaSymbol, angkaSymbol], angkaSymbol, (_, [r, l]) => new Value(angkaSymbol, l.data*r.data)));
313
328
  this.operators.define("GARIS_MIRING",
314
- makeBuiltInFunc([angkaSymbol, angkaSymbol], angkaSymbol, (v, [r, l]) => new Value(angkaSymbol, l.data/r.data)));
329
+ makeBuiltInFunc([angkaSymbol, angkaSymbol], angkaSymbol, (_, [r, l]) => new Value(angkaSymbol, l.data/r.data)));
315
330
  this.operators.define("MODULUS",
316
- makeBuiltInFunc([angkaSymbol, angkaSymbol], angkaSymbol, (v, [r, l]) => new Value(angkaSymbol, l.data%r.data)));
331
+ makeBuiltInFunc([angkaSymbol, angkaSymbol], angkaSymbol, (_, [r, l]) => new Value(angkaSymbol, l.data%r.data)));
317
332
 
318
333
  this.operators.define("LEBIH",
319
- makeBuiltInFunc([angkaSymbol, angkaSymbol], logisSymbol, (v, [r, l]) => new Value(logisSymbol, l.data>r.data)));
334
+ makeBuiltInFunc([angkaSymbol, angkaSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data>r.data)));
320
335
  this.operators.define("KURANG",
321
- makeBuiltInFunc([angkaSymbol, angkaSymbol], logisSymbol, (v, [r, l]) => new Value(logisSymbol, l.data<r.data)));
336
+ makeBuiltInFunc([angkaSymbol, angkaSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data<r.data)));
322
337
  this.operators.define("SAMA_SAMA",
323
- makeBuiltInFunc([angkaSymbol, angkaSymbol], logisSymbol, (v, [r, l]) => new Value(logisSymbol, l.data===r.data)));
338
+ makeBuiltInFunc([angkaSymbol, angkaSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data===r.data)));
324
339
  this.operators.define("LEBIH_SAMA",
325
- makeBuiltInFunc([angkaSymbol, angkaSymbol], logisSymbol, (v, [r, l]) => new Value(logisSymbol, l.data>=r.data)));
340
+ makeBuiltInFunc([angkaSymbol, angkaSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data>=r.data)));
326
341
  this.operators.define("KURANG_SAMA",
327
- makeBuiltInFunc([angkaSymbol, angkaSymbol], logisSymbol, (v, [r, l]) => new Value(logisSymbol, l.data<=r.data)));
342
+ makeBuiltInFunc([angkaSymbol, angkaSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data<=r.data)));
328
343
  this.operators.define("SERU_SAMA",
329
- makeBuiltInFunc([angkaSymbol, angkaSymbol], logisSymbol, (v, [r, l]) => new Value(logisSymbol, l.data!==r.data)));
344
+ makeBuiltInFunc([angkaSymbol, angkaSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data!==r.data)));
330
345
  this.operators.define("AMPERSAN",
331
- makeBuiltInFunc([angkaSymbol, angkaSymbol], logisSymbol, (v, [r, l]) => new Value(logisSymbol, l.data&&r.data)));
346
+ makeBuiltInFunc([angkaSymbol, angkaSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data&&r.data)));
332
347
  this.operators.define("PIPA",
333
- makeBuiltInFunc([angkaSymbol, angkaSymbol], logisSymbol, (v, [r, l]) => new Value(logisSymbol, l.data||r.data)));
348
+ makeBuiltInFunc([angkaSymbol, angkaSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data||r.data)));
334
349
  this.operators.define("SERU_UNARY",
335
- makeBuiltInFunc([angkaSymbol], logisSymbol, (v, [r]) => new Value(logisSymbol, !Boolean(r.data))));
350
+ makeBuiltInFunc([angkaSymbol], logisSymbol, (_, [r]) => new Value(logisSymbol, !Boolean(r.data))));
336
351
  this.operators.define("PLUS_UNARY",
337
- makeBuiltInFunc([angkaSymbol], angkaSymbol, (v, [r]) => new Value(angkaSymbol, +r.data)));
352
+ makeBuiltInFunc([angkaSymbol], angkaSymbol, (_, [r]) => new Value(angkaSymbol, +r.data)));
338
353
  this.operators.define("MINUS_UNARY",
339
- makeBuiltInFunc([angkaSymbol], angkaSymbol, (v, [r]) => new Value(angkaSymbol, -r.data)));
354
+ makeBuiltInFunc([angkaSymbol], angkaSymbol, (_, [r]) => new Value(angkaSymbol, -r.data)));
340
355
 
341
356
  this.member = new Environment();
357
+
358
+ this.member.define("bulat", makeBuiltInFunc([angkaSymbol], angkaSymbol, (_, [a]) => {
359
+ return new Value(angkaSymbol, Math.round(a.data));
360
+ }));
361
+ this.member.define("bulatAtas", makeBuiltInFunc([angkaSymbol], angkaSymbol, (_, [a]) => {
362
+ return new Value(angkaSymbol, Math.ceil(a.data))
363
+ }));
364
+ this.member.define("bulatBawah", makeBuiltInFunc([angkaSymbol], angkaSymbol, (_, [a]) => {
365
+ return new Value(angkaSymbol, Math.floor(a.data))
366
+ }));
342
367
  }
343
368
  }
344
369
 
345
370
  class LogisTipe extends Stipe {
346
371
  constructor() {
347
- super(logisSymbol, {
348
- callFunc: (v, args) => {
349
- if (args.length !== 1) {
350
- v.error(`Jumlah argumen tidak sama dengan parameter mesin: ${args.length} != 1.`);
351
- }
352
-
372
+ super(logisSymbol, new Callable(null, (_, args) => {
353
373
  return new Value(logisSymbol, Boolean(args[0].data) || Boolean(args[0].data.member));
354
- }
355
- });
374
+ }, [[null]], logisSymbol, true)
375
+ );
356
376
  this.init();
357
377
  }
358
378
 
359
379
  init() {
360
380
  this.operators.define("SAMA_SAMA",
361
- makeBuiltInFunc([logisSymbol, logisSymbol], logisSymbol, (v, [r, l]) => new Value(logisSymbol, l.data===r.data)));
381
+ makeBuiltInFunc([logisSymbol, logisSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data===r.data)));
362
382
  this.operators.define("SERU_SAMA",
363
- makeBuiltInFunc([logisSymbol, logisSymbol], logisSymbol, (v, [r, l]) => new Value(logisSymbol, l.data!==r.data)));
364
-
383
+ makeBuiltInFunc([logisSymbol, logisSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data!==r.data)));
365
384
  this.operators.define("AMPERSAN",
366
- makeBuiltInFunc([logisSymbol, logisSymbol], logisSymbol, (v, [r, l]) => new Value(logisSymbol, l.data&&r.data)));
385
+ makeBuiltInFunc([logisSymbol, logisSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data&&r.data)));
367
386
  this.operators.define("PIPA",
368
- makeBuiltInFunc([logisSymbol, logisSymbol], logisSymbol, (v, [r, l]) => new Value(logisSymbol, l.data||r.data)));
387
+ makeBuiltInFunc([logisSymbol, logisSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data||r.data)));
369
388
  this.operators.define("SERU_UNARY",
370
- makeBuiltInFunc([logisSymbol], logisSymbol, (v, [r]) => new Value(logisSymbol, !Boolean(r.data))));
389
+ makeBuiltInFunc([logisSymbol], logisSymbol, (_, [r]) => new Value(logisSymbol, !Boolean(r.data))));
371
390
 
372
- this.member = true;
391
+ this.member = new Environment();
373
392
  }
374
393
  }
375
394
 
@@ -381,17 +400,17 @@ class BarisTipe extends Stipe {
381
400
 
382
401
  init () {
383
402
  this.operators.define("PLUS",
384
- makeBuiltInFunc([barisSymbol, barisSymbol], barisSymbol, (v, [r,l]) => new Value(barisSymbol, Array(...l.data, ...r.data))));
403
+ makeBuiltInFunc([barisSymbol, barisSymbol], barisSymbol, (_, [r,l]) =>
404
+ new Value(barisSymbol, Array(...l.data, ...r.data))
405
+ ));
385
406
 
386
407
  this.operators.define("MINUS_UNARY",
387
- makeBuiltInFunc([barisSymbol], barisSymbol, (v, [r]) => {
388
- let newBaris = copier(r);
389
- newBaris.data.pop();
390
- return newBaris;
391
- }));
408
+ makeBuiltInFunc([barisSymbol], barisSymbol, (_, [r]) =>
409
+ new Value(barisSymbol, r.data.slice(0,r.length))
410
+ ));
392
411
 
393
412
  this.operators.define("SAMA_SAMA",
394
- makeBuiltInFunc([barisSymbol, barisSymbol], logisSymbol, (v, [r, l]) => new Value(logisSymbol, ((a,b)=>{
413
+ makeBuiltInFunc([barisSymbol, barisSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, ((a,b)=>{
395
414
  if (a.length !== b.length) return false;
396
415
  for (let i = 0; i < a.length; i++) {
397
416
  if (a[i].data !== b[i].data) return false;
@@ -401,7 +420,7 @@ class BarisTipe extends Stipe {
401
420
  );
402
421
 
403
422
  this.operators.define("SERU_SAMA",
404
- makeBuiltInFunc([barisSymbol, barisSymbol], logisSymbol, (v, [r, l]) => new Value(logisSymbol, ((a,b)=>{
423
+ makeBuiltInFunc([barisSymbol, barisSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, ((a,b)=>{
405
424
  if (a.length !== b.length) return true;
406
425
  for (let i = 0; i < a.length; i++) {
407
426
  if (a[i].data !== b[i].data) return true;
@@ -411,11 +430,11 @@ class BarisTipe extends Stipe {
411
430
  );
412
431
 
413
432
  this.operators.define("AMPERSAN",
414
- makeBuiltInFunc([barisSymbol, barisSymbol], logisSymbol, (v, [r, l]) => new Value(logisSymbol, l.data&&r.data)));
433
+ makeBuiltInFunc([barisSymbol, barisSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data&&r.data)));
415
434
  this.operators.define("PIPA",
416
- makeBuiltInFunc([barisSymbol, barisSymbol], logisSymbol, (v, [r, l]) => new Value(logisSymbol, l.data||r.data)));
435
+ makeBuiltInFunc([barisSymbol, barisSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data||r.data)));
417
436
  this.operators.define("SERU_UNARY",
418
- makeBuiltInFunc([barisSymbol], logisSymbol, (v, [r]) => new Value(logisSymbol, !Boolean(r.data))));
437
+ makeBuiltInFunc([barisSymbol], logisSymbol, (_, [r]) => new Value(logisSymbol, !Boolean(r.data))));
419
438
 
420
439
  this.member = new Environment();
421
440
 
@@ -425,7 +444,55 @@ class BarisTipe extends Stipe {
425
444
  }
426
445
 
427
446
  while (i.data < 0) i.data += b.data.length;
428
- return new Value(barisSymbol, b.data.filter((val, idx)=>idx!==i.data));
447
+ b.data = b.data.filter((_, idx) => idx !== i.data);
448
+ return b;
449
+ }));
450
+
451
+ this.member.define("potongan", makeBuiltInFunc([barisSymbol, angkaSymbol, angkaSymbol], barisSymbol, (v, [b, fr, to]) => {
452
+ if (fr.data >= b.data.length || fr.data < 0 || to.data <= fr.data || to.data > b.data.length) {
453
+ v.error(`Indeks tidak valid, ${fr.data}:${to.data}, dengan ukuran baris ${b.data.length}`);
454
+ }
455
+ return new Value(barisSymbol, b.data.slice(fr.data, to.data));
456
+ }));
457
+ this.member.define("tumpuk", makeBuiltInFunc([barisSymbol, null], null, (_, [b, d])=>{
458
+ b.data.push(d);
459
+ return b;
460
+ }));
461
+ this.member.define("tumpah", makeBuiltInFunc([barisSymbol], null, (_, [b])=>{
462
+ b.data.pop();
463
+ return b;
464
+ }));
465
+ this.member.define("masuk", makeBuiltInFunc([barisSymbol, null, angkaSymbol], null, (v, [b, d, idx]) => {
466
+ if (idx.data > b.data.length) {
467
+ v.error(`Indeks tidak valid, ${idx.data}, dengan ukuran baris ${b.data.length}`);
468
+ }
469
+ b.data.splice(idx.data, 0, d);
470
+ return b;
471
+ }));
472
+ this.member.define("petakan", makeBuiltInFunc([barisSymbol, mesinSymbol], barisSymbol, (v, [b, m]) => {
473
+ let newBaris = new Value(barisSymbol, []);
474
+ for (let datum of b.data) {
475
+ let result = v.callFunc(m.data, [datum]);
476
+ newBaris.data.push(result);
477
+ }
478
+ return newBaris;
479
+ }));
480
+ this.member.define("saring", makeBuiltInFunc([barisSymbol, mesinSymbol], barisSymbol, (v, [b, m]) => {
481
+ let newBaris = new Value(barisSymbol, []);
482
+ for (let datum of b.data) {
483
+ let result = v.callFunc(m.data, [datum]);
484
+ if (result.data === true) {
485
+ newBaris.data.push(datum);
486
+ }
487
+ }
488
+ return newBaris;
489
+ }));
490
+ this.member.define("reduksi", makeBuiltInFunc([barisSymbol, mesinSymbol, null], null, (v, [b, m, d]) => {
491
+ for (let datum of b.data) {
492
+ let result = v.callFunc(m.data, [d, datum]);
493
+ d = result;
494
+ }
495
+ return d;
429
496
  }));
430
497
  }
431
498
  }
@@ -433,20 +500,14 @@ class BarisTipe extends Stipe {
433
500
  class MesinTipe extends Stipe {
434
501
  constructor() {
435
502
  super(mesinSymbol);
436
- this.member = true;
503
+ this.member = new Environment();
437
504
  }
438
505
  }
439
-
506
+
440
507
  let Model$1 = class Model extends Stipe {
441
508
  constructor(name, params) {
442
509
  let sym = Symbol(name);
443
- super(sym, {
444
- callFunc: (v, args) => {
445
- if (args.length !== params.length) {
446
- v.error("Jumlah argumen tidak sama dengan parameter mesin:" + ` ${args.length} != ${params.length}.`);
447
- }
448
- // for call error info
449
- let callLineNum = v.line;
510
+ super(sym, new Callable(null, (v, args) => {
450
511
 
451
512
  let obj = new Value(sym, true);
452
513
  obj.member = new Environment();
@@ -460,18 +521,14 @@ let Model$1 = class Model extends Stipe {
460
521
  if (args[i].data === null) ; else if (symbol === null) {
461
522
  val.isDatum = true;
462
523
  val.type = args[i].type;
463
- } else if (symbol !== args[i].type) {
464
- v.line = callLineNum;
465
- v.error(`Tipe member tidak sama dengan argumen. ${symbol.description} != ${args[i].type.description}`);
466
524
  }
467
525
  val.member = args[i].member;
468
526
  obj.member.define(name, val);
469
527
  }
470
528
 
471
- obj.member.define("objek", obj);
472
529
  return obj;
473
- }
474
- });
530
+ }, params.map(_=>[null]), sym, true)
531
+ );
475
532
  }
476
533
  };
477
534
 
@@ -488,81 +545,24 @@ let Jenis$1 = class Jenis extends Stipe {
488
545
 
489
546
  init(sym) {
490
547
  this.operators.define("SAMA_SAMA",
491
- makeBuiltInFunc([sym, sym], logisSymbol, (v, [r, l]) => new Value(logisSymbol, l.data===r.data)));
548
+ makeBuiltInFunc([sym, sym], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data===r.data)));
492
549
  this.operators.define("SERU_SAMA",
493
- makeBuiltInFunc([sym, sym], logisSymbol, (v, [r, l]) => new Value(logisSymbol, l.data!==r.data)));
550
+ makeBuiltInFunc([sym, sym], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data!==r.data)));
494
551
  }
495
552
  };
496
553
 
497
554
  class Callable {
498
- constructor(enclosing, block, parameters, returnType) {
555
+ constructor(enclosing, block, parameters, returnType, isBuiltIn=false) {
499
556
  this.closure = enclosing;
500
557
  this.block = block;
501
558
  this.parameters = parameters;
502
559
  this.returnType = returnType;
503
- }
504
-
505
- // call with arguments (of value)
506
- callFunc (visitor, args) {
507
- // this function may go into the interpreter idk
508
- if (args.length !== this.parameters.length) {
509
- visitor.error("Jumlah argumen tidak sama dengan parameter mesin:" + ` ${args.length} != ${this.parameters.length}.`);
510
- }
511
-
512
- // for asserting _call_ error.
513
- let callLineNum = visitor.line;
514
-
515
- let visitorEnv = visitor.environment;
516
- let funcEnv = new Environment(this.closure);
517
- visitor.environment = funcEnv;
518
- for(let i = 0; i < args.length; i++) {
519
- let [type, tetap, name] = this.parameters[i];
520
- let val = new Variable(type, tetap, args[i].data);
521
-
522
- if (type === null) {
523
- val.isDatum = true;
524
- val.type = args[i].type;
525
- } else if (args[i].data === null) ; else if (args[i].type !== type) {
526
- visitor.line = callLineNum;
527
- visitor.error(`Tipe argumen tidak sama dengan parameter. ${args[i].type} != ${type.description}`);
528
- }
529
- val.member = args[i].member;
530
- funcEnv.define(name, val);
531
- }
532
- let result = new Value(null, null);
533
- for(let stmt of this.block.statements) {
534
- try {
535
- stmt.accept(visitor);
536
- } catch (err) {
537
- if (err instanceof Hasil$1) {
538
- result = err.value;
539
- break;
540
- } else if (err instanceof Henti$1 || err instanceof Lewat$1) {
541
- visitor.error("Tidak bisa menghentikan atau melewatkan mesin. ");
542
- } else throw err;
543
- }
544
- }
545
- visitor.environment = visitorEnv;
546
- return result;
560
+ this.isBuiltIn = isBuiltIn;
547
561
  }
548
562
  }
549
563
 
550
- // this approach is too slow. Will fix later...
551
-
552
564
  function makeBuiltInFunc(parameters, returnType, funcBody) {
553
- let lambda = new Callable(null, null, parameters.map((val)=>[val]), returnType);
554
- lambda.callFunc = (v, args) => {
555
- if (args.length != parameters.length) {
556
- v.error("Jumlah Argumen tidak sama dengan parameter:" + ` Seharusnya ${parameters.length} dan bukan ${args.length}.`);
557
- }
558
- for (let i = 0; i < args.length; i++) {
559
- if (parameters[i] === null) continue;
560
- if (args[i].type !== parameters[i]) {
561
- v.error("Tipe argumen tidak sama dengan tipe parameter." + ` Seharusnya ${parameters[i].type.description} dan bukan ${args[i].description}`);
562
- }
563
- }
564
- return funcBody(v, args);
565
- };
565
+ let lambda = new Callable(null, funcBody, parameters.map((val)=>[val]), returnType, true);
566
566
  let variable = new Variable(mesinSymbol, true, lambda);
567
567
  return variable;
568
568
  }
@@ -574,23 +574,21 @@ function copier(thing) {
574
574
  case logisSymbol: return new Value(logisSymbol, thing.data);
575
575
  case mesinSymbol: return new Value(mesinSymbol, thing.data);
576
576
  case barisSymbol: return new Value(barisSymbol, thing.data.map((val)=>copier(val)));
577
- case stipeSymbol: return new Value(null, null);
578
- case modulSymbol: return new Value(null, null);
577
+ case stipeSymbol: return NIHIL;
578
+ case modulSymbol: return NIHIL;
579
579
  default:
580
580
  if (thing.member && thing.member instanceof Environment) {
581
581
  let keys = thing.member.memory.keys();
582
582
  let valCopy = new Value(thing.type, null);
583
583
  let newMember = new Environment();
584
584
  for (let i of keys) {
585
- if (i === "objek") continue;
586
585
  newMember.define(i, copier(thing.member.get(i)));
587
586
  }
588
- newMember.define("objek", valCopy);
589
587
  valCopy.member = newMember;
590
588
 
591
589
  return valCopy;
592
590
  }
593
- return new Value(null, null);
591
+ return NIHIL;
594
592
  }
595
593
  }
596
594
 
@@ -604,23 +602,37 @@ const GLOBAL_ENV = (() => {
604
602
  env.define("mesin", new MesinTipe());
605
603
 
606
604
  env.define("jarak", makeBuiltInFunc([angkaSymbol, angkaSymbol], barisSymbol,
607
- (v, [from, to])=>new Value(barisSymbol,
605
+ (_, [from, to])=>new Value(barisSymbol,
608
606
  Array(Math.abs(Math.floor(to.data-from.data)))
609
607
  .fill(0)
610
- .map((val, idx)=>new Value(angkaSymbol, from.data+((to.data>from.data)?1:-1)*idx))))
608
+ .map((_, idx)=>new Value(angkaSymbol, from.data+((to.data>from.data)?1:-1)*idx))))
611
609
  );
612
610
 
613
- env.define("nihil?", makeBuiltInFunc([null], logisSymbol, (v, [d]) => new Value(logisSymbol, d.data === null)));
614
- env.define("ukuran", makeBuiltInFunc([null], angkaSymbol,(v, [d]) => d.type === barisSymbol || d.type === petikSymbol
611
+ env.define("nihil?", makeBuiltInFunc([null], logisSymbol, (_, [d]) => new Value(logisSymbol, d.data === null)));
612
+ env.define("ukuran", makeBuiltInFunc([null], angkaSymbol,(_, [d]) => d.type === barisSymbol || d.type === petikSymbol
615
613
  ? new Value(angkaSymbol, d.data.length)
616
614
  : v.error(`Ukuran hanya terdapat untuk tipe petik atau baris. Menemukan tipe ${d.type.description}.`)
617
615
  ));
618
616
 
619
- env.define("salin", makeBuiltInFunc([null], null, (v, [d]) => copier(d)));
620
- env.define("tipe", makeBuiltInFunc([null], petikSymbol, (v, [d]) => (d.type?.description)
617
+ env.define("salin", makeBuiltInFunc([null], null, (_, [d]) => copier(d)));
618
+ env.define("tipe", makeBuiltInFunc([null], petikSymbol, (_, [d]) => (d.type?.description)
621
619
  ? new Value(petikSymbol, d.type.description)
622
620
  : new Value(petikSymbol, "datum")
623
621
  ));
622
+
623
+ let mtkModul = new Variable(modulSymbol, true, null);
624
+ mtkModul.member = new Environment();
625
+ mtkModul.member.define("acak", makeBuiltInFunc([angkaSymbol, angkaSymbol], angkaSymbol, (_, [a,b]) => {
626
+ let width = Math.abs(a.data-b.data);
627
+ let range = Math.random() * width;
628
+ let final = range + Math.min(a.data,b.data);
629
+ return new Value(angkaSymbol, final);
630
+ }));
631
+ mtkModul.member.define("akar2", makeBuiltInFunc([angkaSymbol], angkaSymbol, (_, [a]) => {
632
+ return new Value(angkaSymbol, Math.sqrt(a.data));
633
+ }));
634
+
635
+ env.define("mtk", mtkModul);
624
636
  return env;
625
637
  })();
626
638
 
@@ -651,6 +663,8 @@ class Interpreter {
651
663
  this.state = location.GLOBAL;
652
664
  this.stack = [];
653
665
  this.output = [];
666
+ this.objectStack = null;
667
+ this.exprWillBeCalled = false;
654
668
  }
655
669
 
656
670
  // EXPRESSION VISITORS
@@ -666,7 +680,7 @@ class Interpreter {
666
680
  case "boolean":
667
681
  return new Value(logisSymbol, lit.value);
668
682
  default:
669
- return new Value(null, null);
683
+ return new NIHIL;
670
684
  }
671
685
  }
672
686
 
@@ -675,10 +689,7 @@ class Interpreter {
675
689
 
676
690
  for (let expr of arrayExpr.contents) {
677
691
  let v = this.validvalue(expr.accept(this));
678
- // value.data.push(v);
679
- let result = new Value(v.type, v.data);
680
- result.member = v.member;
681
- value.data.push(new Value(v.type, v.data));
692
+ value.data.push(v);
682
693
  }
683
694
 
684
695
  return value;
@@ -710,8 +721,18 @@ class Interpreter {
710
721
  visitLambdaExpr(lambdaExpr) {
711
722
  // let type = lambdaExpr.returnValue.accept(this);
712
723
  let params = lambdaExpr.params.map(val=>[val[0].accept(this), val[0].tetap, val[1].lexeme]);
713
- if (params.length > 1
714
- && params.some(param=>params.reduce((count, anotherParam)=>param[2]===anotherParam[2] ? count+1:count, 0) > 1 ? true : false)) {
724
+
725
+ const check_duplicate_name = (p) => {
726
+ let mapped = new Map();
727
+ for (let name of p) {
728
+ if (mapped.has(name)) return true;
729
+ mapped.set(name, true);
730
+ }
731
+ return false;
732
+ };
733
+
734
+ if (params.length > 1
735
+ && check_duplicate_name(params.map(p=>p[2])) ){
715
736
  this.error("Parameter mesin tidak boleh mempunyai nama yang sama.");
716
737
  }
717
738
  let retType = null;
@@ -723,26 +744,101 @@ class Interpreter {
723
744
  }
724
745
 
725
746
  visitCallExpr(callExpr) {
726
- this.stack.push(this.line);
727
- if (this.stack.length > MAX_STACK_SIZE)
728
- this.error(`Rekursi melebihi batas: Lebih dari ${MAX_STACK_SIZE}`);
729
- this.state = location.MESIN;
730
- let callable = callExpr.callable.accept(this);
731
747
 
748
+ this.exprWillBeCalled = true;
749
+ let callable = callExpr.callable.accept(this);
750
+ this.exprWillBeCalled = false;
751
+
732
752
  if (callable.type !== mesinSymbol && callable.type !== stipeSymbol) {
733
753
  this.error(`Hanya bisa 'memanggil' mesin atau model, malah menemukan ${callable.type.description}. `);
734
754
  }
735
755
 
736
- if (!callable.data?.callFunc) {
756
+ if (!callable.data?.block) {
737
757
  this.error(`Mesin tidak terdefinisi, tidak bisa dipanggil.`);
738
758
  }
759
+
760
+ let args = [];
761
+
762
+ if (this.objectStack) {
763
+ args = [this.objectStack];
764
+ this.objectStack = null;
765
+ }
766
+
767
+ args = [...args, ...callExpr.args.map(val=>this.validvalue(val.accept(this)))];
768
+
769
+ let result = this.callFunc(callable.data, args);
770
+ return result;
771
+ }
772
+
773
+ callFunc(callable, args) {
774
+ // args.forEach((val,idx)=>{
775
+ // console.log(idx, val);
776
+ // });
777
+ this.stack.push(this.line);
778
+ if (this.stack.length > MAX_STACK_SIZE)
779
+ this.error(`Rekursi melebihi batas: Lebih dari ${MAX_STACK_SIZE}`);
780
+
739
781
  this.line = this.stack[this.stack.length-1];
740
- let result = callable.data.callFunc(this, callExpr.args.map(val=>this.validvalue(val.accept(this))));
782
+ this.state = location.MESIN;
783
+
784
+ if (args.length !== callable.parameters.length) {
785
+ this.error(`Jumlah argumen tidak sama dengan parameter mesin. Menemukan ${args.length}, harusnya ${callable.parameters.length}.`);
786
+ }
787
+
788
+ // for asserting _call_ error.
789
+ let callLineNum = this.line;
790
+
791
+ for(let i = 0; i < args.length; i++) {
792
+ let type = callable.parameters[i][0];
793
+
794
+ if (type === null) continue;
795
+ if (args[i].type !== type) {
796
+ this.line = callLineNum;
797
+ this.error(`Tipe argumen tidak sama dengan parameter. Menemukan ${args[i].type.description}, harusnya ${type.description}`);
798
+ }
799
+ }
800
+
801
+ if (callable.isBuiltIn) {
802
+ this.stack.pop();
803
+ if (this.stack.length == 0) this.state = location.GLOBAL;
804
+ return callable.block(this, args);
805
+ }
806
+
807
+ let visitorEnv = this.environment;
808
+ let funcEnv = new Environment(callable.closure);
809
+ this.environment = funcEnv;
810
+
811
+ for(let i = 0; i < args.length; i++) {
812
+ let [type, tetap, name] = callable.parameters[i];
813
+ if (type === null) {
814
+ type = args[i].type;
815
+ }
816
+ let variable = new Variable(type, tetap, args[i].data);
817
+ variable.member = args[i].member;
818
+
819
+ this.environment.define(name, variable);
820
+ }
821
+
822
+ let result = NIHIL;
823
+ for(let stmt of callable.block.statements) {
824
+ try {
825
+ stmt.accept(this);
826
+ } catch (err) {
827
+ if (err instanceof Hasil$1) {
828
+ result = err.value;
829
+ break;
830
+ } else if (err instanceof Henti$1 || err instanceof Lewat$1) {
831
+ this.error("Tidak bisa menghentikan atau melewatkan mesin. ");
832
+ } else throw err;
833
+ }
834
+ }
741
835
  this.stack.pop();
742
836
  if (this.stack.length == 0) this.state = location.GLOBAL;
837
+ this.environment = visitorEnv;
743
838
  return result;
744
839
  }
745
840
 
841
+
746
842
  visitBinaryExpr(binaryExpr) {
747
843
  let leftValue = this.validvalue(binaryExpr.left.accept(this));
748
844
  let rightValue = this.validvalue(binaryExpr.right.accept(this));
@@ -789,15 +885,23 @@ class Interpreter {
789
885
  }
790
886
 
791
887
  visitMemberExpr(memberExpr) {
888
+ let willBeCalled = this.exprWillBeCalled;
889
+ this.exprWillBeCalled = false;
792
890
  let main = memberExpr.main.accept(this);
793
891
  let name = memberExpr.member.token.lexeme;
794
892
  this.line = memberExpr.member.token.line;
795
- if (!main.member) {
796
- this.error(`Nilai tidak mempunyai atribut sama sekali.`);
797
- } else if (!main.member.has(name)) {
798
- this.error(`atribut .${name} tidak dapat ditemukan.`);
893
+ if (!main.member || !main.member.has(name)) {
894
+ const type = this.environment.get(main.type.description);
895
+ if (type.member?.has(name)) {
896
+ if (willBeCalled) {
897
+ this.objectStack = main;
898
+ }
899
+ return type.member.get(name);
900
+ }
901
+ this.error(`nama .${name} tidak ditemukan dalam tipe ${main.type.description}`);
902
+ } else {
903
+ return main.member.get(name);
799
904
  }
800
- return main.member.get(name);
801
905
  }
802
906
 
803
907
  // STATEMENT VISITORS
@@ -816,7 +920,10 @@ class Interpreter {
816
920
  if (thing.type === logisSymbol) {
817
921
  return thing.data ? "benar" : "salah";
818
922
  } else if (thing.type === barisSymbol) {
819
- return '[' + thing.data.reduce((str, val)=>str+", "+kePetik(val), "").slice(1) + ' ]';
923
+ return '[' + thing.data.reduce((str, val)=>{
924
+ let item = kePetik(val);
925
+ return str + ", " + (val.type === petikSymbol ? `"${item}"` : item);
926
+ }, "").slice(1) + ' ]';
820
927
  } else if (thing.type === stipeSymbol) {
821
928
  return `Model<${thing.symbol.description}>`;
822
929
  } else if (thing.type === mesinSymbol) {
@@ -825,9 +932,18 @@ class Interpreter {
825
932
  } else if (thing.type === angkaSymbol) {
826
933
  return thing.data.toString();
827
934
  } else if (thing.type === petikSymbol) {
828
- return '"' + thing.data + '"';
935
+ return thing.data;
829
936
  } else {
830
937
  if (!thing?.type) return `nihil`;
938
+ let type = this.environment.get(thing.type.description);
939
+ if (type?.member?.has("kePetik")) {
940
+ this.state = location.MESIN;
941
+ this.stack.push(this.line);
942
+ let res = this.callFunc(type.member.get("kePetik").data, [thing]).data;
943
+ this.stack.pop();
944
+ this.state = this.stack > 0 ? location.MESIN : location.GLOBAL;
945
+ return res;
946
+ }
831
947
  return `${thing.type.description}<>`;
832
948
  }
833
949
  };
@@ -1029,8 +1145,7 @@ class Interpreter {
1029
1145
  }
1030
1146
 
1031
1147
  let lastEnv = this.environment;
1032
- this.environment = new Environment(this.globalEnvironment);
1033
- if (variable) this.environment.define(name, variable);
1148
+ this.environment = new Environment(this.environment);
1034
1149
  for (let stmt of modulStmt.statements) {
1035
1150
  stmt.accept(this);
1036
1151
  }
@@ -1076,7 +1191,7 @@ class Interpreter {
1076
1191
  }
1077
1192
 
1078
1193
  error(message) {
1079
- throw new SimplErrorEksekusi(`Error Eksekusi => ${message}`, this.line);
1194
+ throw new SimplErrorEksekusi(`Error Eksekusi => ${message}`, this.line, this.output.join('\n'));
1080
1195
  }
1081
1196
 
1082
1197
  interpret(tree) {
@@ -1240,7 +1355,7 @@ class Lexer {
1240
1355
 
1241
1356
  scan() {
1242
1357
  this.skipWhitespaces();
1243
- if(this.see() === '#') {
1358
+ while (this.see() === '#') {
1244
1359
  this.comment();
1245
1360
  this.skipWhitespaces();
1246
1361
  }
@@ -2011,8 +2126,19 @@ class Parser {
2011
2126
 
2012
2127
  rubahStmt() {
2013
2128
  let id = this.valuable();
2129
+ let shorthand = null;
2130
+ if (this.match(
2131
+ PLUS, MINUS, STAR, SLASH,
2132
+ AMPERSAND, PIPE, MODULUS
2133
+ )) {
2134
+ shorthand = new Binary(id, this.previous(), null);
2135
+ }
2014
2136
  this.eat(EQUAL, "Mengharapkan '=' setelah variable yang ingin di-'rubah'.");
2015
2137
  let expr = this.expression();
2138
+ if (shorthand) {
2139
+ shorthand.right = expr;
2140
+ expr = shorthand;
2141
+ }
2016
2142
  return new Rubah(id, expr);
2017
2143
  }
2018
2144
 
@@ -2140,8 +2266,12 @@ class Simpl {
2140
2266
  return output.join("\n");
2141
2267
  } catch (err) {
2142
2268
  if (err instanceof SimplError) {
2143
- const errorText = textLines[err.line-1];
2144
- return (errorText ? `ERROR! Pada baris ke-${err.line}\n>> ` + errorText + '\n': "") + err.message;
2269
+ const errorCode = textLines[err.line-1];
2270
+ let errorText = (errorCode ? `ERROR! Pada baris ke-${err.line}\n>> ` + errorCode + '\n': "") + err.message;
2271
+ if (err instanceof SimplErrorEksekusi) {
2272
+ errorText += (err.output ? "\nOutput dari kode:\n" : "") + err.output;
2273
+ }
2274
+ return errorText;
2145
2275
  } else {
2146
2276
  return `[Pada baris ke-${this.interpreter.line}] Uh Oh, ini error sistem. Mohon laporkan agar diperbaiki. [ ${err} ]`;
2147
2277
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bahasa-simpl",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Simpl: Indonesian Mini Programming Language interpreter",
5
5
  "main": "./dist/simpl-interpreter.js",
6
6
  "scripts": {