bahasa-simpl 1.0.11 → 1.0.13

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.
@@ -0,0 +1,8 @@
1
+ declare module "simpl-interpreter" {
2
+ export class Simpl {
3
+ constructor(opts: {
4
+ keepMemory?: boolean,
5
+ });
6
+ runCode(code: string): string;
7
+ }
8
+ }
@@ -84,6 +84,7 @@ class Stipe extends Variable {
84
84
  super(stipeSymbol, true, data);
85
85
  this.symbol = type;
86
86
  this.member = new Environment();
87
+ this.member.define("buat", new Variable(mesinSymbol, true, data));
87
88
  }
88
89
 
89
90
  }
@@ -92,9 +93,9 @@ function kePetik(v, thing) {
92
93
  if (thing.type === logisSymbol) {
93
94
  return thing.data ? "benar" : "salah";
94
95
  } else if (thing.type === barisSymbol) {
95
- return '[' + thing.data.reduce((str, val) => str+", "+kePetik(v, val), "").slice(1) + ' ]';
96
+ return '[' + thing.data.reduce((str, val) => str + ", " + kePetik(v, val), "").slice(1) + ' ]';
96
97
  } else if (thing.type === stipeSymbol) {
97
- return `Model<${thing.symbol.description}>`;
98
+ return `Model<${thing.symbol?.description ? thing.symbol.description : ""}>`;
98
99
  } else if (thing.type === mesinSymbol) {
99
100
  let underlying = thing.data.returnType?.description;
100
101
  return `Mesin<${underlying ? underlying : 'datum'}>`;
@@ -112,304 +113,6 @@ function kePetik(v, thing) {
112
113
  return `${thing.type.description}<>`;
113
114
  }
114
115
  }
115
-
116
- class PetikTipe extends Stipe {
117
- constructor() {
118
- super(petikSymbol, new Callable(null, (v, args) => new Value(petikSymbol, kePetik(v, args[0])),
119
- [[null]], petikSymbol, true));
120
- this.init();
121
- }
122
-
123
- init() {
124
- // BINARY / UNARY OPERATORS
125
- this.member.define("PLUS",
126
- makeBuiltInFunc([petikSymbol, petikSymbol], petikSymbol, (_, [r, l]) => new Value(petikSymbol, l.data + r.data)));
127
- this.member.define("LEBIH",
128
- makeBuiltInFunc([petikSymbol, petikSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data > r.data)));
129
- this.member.define("KURANG",
130
- makeBuiltInFunc([petikSymbol, petikSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data < r.data)));
131
- this.member.define("SAMA_SAMA",
132
- makeBuiltInFunc([petikSymbol, petikSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data === r.data)));
133
- this.member.define("LEBIH_SAMA",
134
- makeBuiltInFunc([petikSymbol, petikSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data >= r.data)));
135
- this.member.define("KURANG_SAMA",
136
- makeBuiltInFunc([petikSymbol, petikSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data <= r.data)));
137
- this.member.define("SERU_SAMA",
138
- makeBuiltInFunc([petikSymbol, petikSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data !== r.data)));
139
- this.member.define("AMPERSAN",
140
- makeBuiltInFunc([petikSymbol, petikSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data && r.data)));
141
- this.member.define("PIPA",
142
- makeBuiltInFunc([petikSymbol, petikSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data || r.data)));
143
-
144
- this.member.define("SERU_UNER",
145
- makeBuiltInFunc([petikSymbol], logisSymbol, (_, [r]) => new Value(logisSymbol, !Boolean(r.data))));
146
-
147
- this.member.define("kePetik",
148
- makeBuiltInFunc([petikSymbol], petikSymbol, (v, [p]) => new Value(petikSymbol, kePetik(v, p))));
149
-
150
- this.member.define("pisah", makeBuiltInFunc([petikSymbol, petikSymbol], barisSymbol, (_, [d, sep]) => {
151
- return new Value(barisSymbol, d.data.split(sep.data).map(val => new Value(petikSymbol, val)));
152
- }));
153
- this.member.define("bersih", makeBuiltInFunc([petikSymbol], petikSymbol, (_, [d]) => {
154
- return new Value(petikSymbol, d.data.trim())
155
- }));
156
- this.member.define("ganti", makeBuiltInFunc([petikSymbol, petikSymbol, petikSymbol], petikSymbol,
157
- (_, [d, what, rep]) => new Value(petikSymbol, d.data.replaceAll(what.data, rep.data))
158
- ));
159
- this.member.define("besar", makeBuiltInFunc([petikSymbol], petikSymbol, (_, [p]) => {
160
- return new Value(petikSymbol, p.data.toUpperCase())
161
- }));
162
- this.member.define("kecil", makeBuiltInFunc([petikSymbol], petikSymbol, (_, [p]) => {
163
- return new Value(petikSymbol, p.data.toLowerCase())
164
- }));
165
- }
166
- }
167
-
168
- class AngkaTipe extends Stipe {
169
- constructor() {
170
- super(angkaSymbol, new Callable(null, (v, args) => {
171
- if (typeof args[0].data === "number") {
172
- return new Value(angkaSymbol, args[0].data);
173
- }
174
-
175
- switch (args[0].type) {
176
- case petikSymbol:
177
- if (isNaN(Number(args[0].data))) {
178
- v.error("Nilai dari petik bukanlah sebuah angka, konversi gagal.");
179
- }
180
- return new Value(angkaSymbol, Number(args[0].data));
181
- case angkaSymbol:
182
- return new Value(angkaSymbol, args[0].data);
183
- case logisSymbol:
184
- return new Value(angkaSymbol, Number(args[0].data));
185
- default:
186
- v.error(`Tipe yang dapat diterima hanyalah petik, angka, logis, dan jenis. Mendapatkan ${args[0].type.description}.`);
187
- return;
188
- }
189
- }, [[null]], angkaSymbol, true)
190
- );
191
- this.init();
192
- }
193
-
194
- init() {
195
- this.member.define("PLUS",
196
- makeBuiltInFunc([angkaSymbol, angkaSymbol], angkaSymbol, (_, [r, l]) => new Value(angkaSymbol, l.data + r.data)));
197
- this.member.define("MINUS",
198
- makeBuiltInFunc([angkaSymbol, angkaSymbol], angkaSymbol, (_, [r, l]) => new Value(angkaSymbol, l.data - r.data)));
199
- this.member.define("BINTANG",
200
- makeBuiltInFunc([angkaSymbol, angkaSymbol], angkaSymbol, (_, [r, l]) => new Value(angkaSymbol, l.data * r.data)));
201
- this.member.define("GARIS_MIRING",
202
- makeBuiltInFunc([angkaSymbol, angkaSymbol], angkaSymbol, (_, [r, l]) => new Value(angkaSymbol, l.data / r.data)));
203
- this.member.define("MODULUS",
204
- makeBuiltInFunc([angkaSymbol, angkaSymbol], angkaSymbol, (_, [r, l]) => new Value(angkaSymbol, l.data % r.data)));
205
-
206
- this.member.define("LEBIH",
207
- makeBuiltInFunc([angkaSymbol, angkaSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data > r.data)));
208
- this.member.define("KURANG",
209
- makeBuiltInFunc([angkaSymbol, angkaSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data < r.data)));
210
- this.member.define("SAMA_SAMA",
211
- makeBuiltInFunc([angkaSymbol, angkaSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data === r.data)));
212
- this.member.define("LEBIH_SAMA",
213
- makeBuiltInFunc([angkaSymbol, angkaSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data >= r.data)));
214
- this.member.define("KURANG_SAMA",
215
- makeBuiltInFunc([angkaSymbol, angkaSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data <= r.data)));
216
- this.member.define("SERU_SAMA",
217
- makeBuiltInFunc([angkaSymbol, angkaSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data !== r.data)));
218
- this.member.define("AMPERSAN",
219
- makeBuiltInFunc([angkaSymbol, angkaSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data && r.data)));
220
- this.member.define("PIPA",
221
- makeBuiltInFunc([angkaSymbol, angkaSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data || r.data)));
222
- this.member.define("SERU_UNER",
223
- makeBuiltInFunc([angkaSymbol], logisSymbol, (_, [r]) => new Value(logisSymbol, !Boolean(r.data))));
224
- this.member.define("PLUS_UNER",
225
- makeBuiltInFunc([angkaSymbol], angkaSymbol, (_, [r]) => new Value(angkaSymbol, +r.data)));
226
- this.member.define("MINUS_UNER",
227
- makeBuiltInFunc([angkaSymbol], angkaSymbol, (_, [r]) => new Value(angkaSymbol, -r.data)));
228
-
229
- this.member.define("kePetik",
230
- makeBuiltInFunc([angkaSymbol], petikSymbol, (v, [a]) => new Value(petikSymbol, kePetik(v, a))));
231
-
232
- this.member.define("bulat", makeBuiltInFunc([angkaSymbol], angkaSymbol, (_, [a]) => {
233
- return new Value(angkaSymbol, Math.round(a.data));
234
- }));
235
- this.member.define("bulatAtas", makeBuiltInFunc([angkaSymbol], angkaSymbol, (_, [a]) => {
236
- return new Value(angkaSymbol, Math.ceil(a.data))
237
- }));
238
- this.member.define("bulatBawah", makeBuiltInFunc([angkaSymbol], angkaSymbol, (_, [a]) => {
239
- return new Value(angkaSymbol, Math.floor(a.data))
240
- }));
241
- }
242
- }
243
-
244
- class LogisTipe extends Stipe {
245
- constructor() {
246
- super(logisSymbol, new Callable(null, (_, args) => {
247
- if (args[0].type === barisSymbol && args[0].data.length === 0) {
248
- return new Value(logisSymbol, false);
249
- }
250
- return new Value(logisSymbol, Boolean(args[0].data) || Boolean(args[0].data?.member?.size));
251
- }, [[null]], logisSymbol, true)
252
- );
253
- this.init();
254
- }
255
-
256
- init() {
257
- this.member.define("SAMA_SAMA",
258
- makeBuiltInFunc([logisSymbol, logisSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data === r.data)));
259
- this.member.define("SERU_SAMA",
260
- makeBuiltInFunc([logisSymbol, logisSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data !== r.data)));
261
- this.member.define("AMPERSAN",
262
- makeBuiltInFunc([logisSymbol, logisSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data && r.data)));
263
- this.member.define("PIPA",
264
- makeBuiltInFunc([logisSymbol, logisSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data || r.data)));
265
- this.member.define("SERU_UNER",
266
- makeBuiltInFunc([logisSymbol], logisSymbol, (_, [r]) => new Value(logisSymbol, !Boolean(r.data))));
267
-
268
- this.member.define("kePetik",
269
- makeBuiltInFunc([logisSymbol], petikSymbol, (v, [l]) => new Value(petikSymbol, kePetik(v, l))));
270
- }
271
- }
272
-
273
- class BarisTipe extends Stipe {
274
- constructor() {
275
- super(barisSymbol);
276
- this.init();
277
- }
278
-
279
- init() {
280
- const valueToVariableDatum = (d) => {
281
- let input = new Variable(d.type, false, d.data);
282
- input.member = d.member;
283
- input.isDatum = true;
284
- return input;
285
- };
286
-
287
- this.member.define("PLUS",
288
- makeBuiltInFunc([barisSymbol, barisSymbol], barisSymbol, (_, [r, l]) =>
289
- new Value(barisSymbol, Array(...l.data, ...r.data))
290
- ));
291
-
292
- this.member.define("MINUS_UNER",
293
- makeBuiltInFunc([barisSymbol], barisSymbol, (_, [r]) =>
294
- new Value(barisSymbol, r.data.slice(0, r.length))
295
- ));
296
-
297
- this.member.define("SAMA_SAMA",
298
- makeBuiltInFunc([barisSymbol, barisSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, ((a, b) => {
299
- if (a.length !== b.length) return false;
300
- for (let i = 0; i < a.length; i++) {
301
- if (a[i].data !== b[i].data) return false;
302
- }
303
- return true;
304
- })(l.data, r.data)))
305
- );
306
-
307
- this.member.define("SERU_SAMA",
308
- makeBuiltInFunc([barisSymbol, barisSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, ((a, b) => {
309
- if (a.length !== b.length) return true;
310
- for (let i = 0; i < a.length; i++) {
311
- if (a[i].data !== b[i].data) return true;
312
- }
313
- return false;
314
- })(l.data, r.data)))
315
- );
316
-
317
- this.member.define("AMPERSAN",
318
- makeBuiltInFunc([barisSymbol, barisSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data && r.data)));
319
- this.member.define("PIPA",
320
- makeBuiltInFunc([barisSymbol, barisSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data || r.data)));
321
- this.member.define("SERU_UNER",
322
- makeBuiltInFunc([barisSymbol], logisSymbol, (_, [r]) => new Value(logisSymbol, !Boolean(r.data))));
323
-
324
- this.member.define("kePetik",
325
- makeBuiltInFunc([barisSymbol], petikSymbol, (v, [p]) => new Value(petikSymbol, kePetik(v, p))));
326
-
327
- this.member.define("hapus", makeBuiltInFunc([barisSymbol, angkaSymbol], barisSymbol, (v, [b, i]) => {
328
- if (b.data.length <= i.data) {
329
- v.error(`Indeks tidak boleh lebih besar atau sama dengan ukuran baris, ${i.data} >= ${b.data.length}`);
330
- }
331
-
332
- while (i.data < 0) i.data += b.data.length;
333
- b.data = b.data.filter((_, idx) => idx !== i.data);
334
- return b;
335
- }));
336
-
337
- this.member.define("potongan", makeBuiltInFunc([barisSymbol, angkaSymbol, angkaSymbol], barisSymbol, (v, [b, fr, to]) => {
338
- if (fr.data >= b.data.length || fr.data < 0 || to.data <= fr.data || to.data > b.data.length) {
339
- v.error(`Indeks tidak valid, ${fr.data} sampai ${to.data}, dengan ukuran baris ${b.data.length}`);
340
- }
341
- return new Value(barisSymbol, b.data.slice(fr.data, to.data));
342
- }));
343
- this.member.define("tumpuk", makeBuiltInFunc([barisSymbol, null], null, (_, [b, d]) => {
344
- b.data.push(valueToVariableDatum(d));
345
- return b;
346
- }));
347
- this.member.define("tumpah", makeBuiltInFunc([barisSymbol], null, (_, [b]) => {
348
- b.data.pop();
349
- return b;
350
- }));
351
- this.member.define("masuk", makeBuiltInFunc([barisSymbol, null, angkaSymbol], null, (v, [b, d, idx]) => {
352
- if (idx.data > b.data.length) {
353
- v.error(`Indeks tidak valid, ${idx.data}, dengan ukuran baris ${b.data.length}`);
354
- }
355
- b.data.splice(idx.data, 0, valueToVariableDatum(d));
356
- return b;
357
- }));
358
- this.member.define("petakan", makeBuiltInFunc([barisSymbol, mesinSymbol], barisSymbol, (v, [b, m]) => {
359
- let newBaris = new Value(barisSymbol, []);
360
- for (let datum of b.data) {
361
- let result = v.callFunc(m.data, [datum]);
362
- newBaris.data.push(valueToVariableDatum(result));
363
- }
364
- return newBaris;
365
- }));
366
- this.member.define("saring", makeBuiltInFunc([barisSymbol, mesinSymbol], barisSymbol, (v, [b, m]) => {
367
- let newBaris = new Value(barisSymbol, []);
368
- for (let datum of b.data) {
369
- let result = v.callFunc(m.data, [datum]);
370
- if (result.data === true) {
371
- newBaris.data.push(valueToVariableDatum(datum));
372
- }
373
- }
374
- return newBaris;
375
- }));
376
- this.member.define("reduksi", makeBuiltInFunc([barisSymbol, mesinSymbol, null], null, (v, [b, m, d]) => {
377
- for (let datum of b.data) {
378
- let result = v.callFunc(m.data, [d, datum]);
379
- d = result;
380
- }
381
- return d;
382
- }));
383
-
384
- this.member.define("punya?", makeBuiltInFunc([barisSymbol, null], logisSymbol, (v, [b, d]) => {
385
- let type = v.environment.get(d.type?.description);
386
- if (!type)
387
- v.error(`Tipe tidak ditemukan atau tidak valid`);
388
- let equalFunc;
389
- if (type.member?.has("SAMA_SAMA")) {
390
- equalFunc = type.member.get("SAMA_SAMA");
391
- } else {
392
- v.error(`model ${d.type.description} tidak mempunyai mesin SAMA_SAMA di dalam modulnya.`);
393
- }
394
- for (let datum of b.data) {
395
- if (datum.type !== d.type) continue;
396
- let isEqual = v.callFunc(equalFunc.data, [datum, d]);
397
- if (isEqual.data) return new Value(logisSymbol, true);
398
- }
399
- return new Value(logisSymbol, false);
400
- }));
401
- }
402
- }
403
-
404
- class MesinTipe extends Stipe {
405
- constructor() {
406
- super(mesinSymbol);
407
-
408
- this.member.define("kePetik",
409
- makeBuiltInFunc([mesinSymbol], petikSymbol, (v, [m]) => new Value(petikSymbol, kePetik(v, m))));
410
- }
411
- }
412
-
413
116
  let Model$1 = class Model extends Stipe {
414
117
  constructor(name, params) {
415
118
  let sym = Symbol(name);
@@ -453,10 +156,7 @@ let Jenis$1 = class Jenis extends Stipe {
453
156
  this.member.define("kePetik", makeBuiltInFunc([sym], petikSymbol, (_, [j]) => {
454
157
  return new Value(petikSymbol, `${name}<${j.data}>`);
455
158
  }));
456
- this.init(sym);
457
- }
458
159
 
459
- init(sym) {
460
160
  this.member.define("SAMA_SAMA",
461
161
  makeBuiltInFunc([sym, sym], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data === r.data)));
462
162
  this.member.define("SERU_SAMA",
@@ -515,13 +215,302 @@ function copier(thing) {
515
215
  }
516
216
 
517
217
 
218
+ const PetikTipe = (() => {
219
+ let tipe = new Stipe(petikSymbol, new Callable(null, (v, args) => new Value(petikSymbol, kePetik(v, args[0])),
220
+ [[null]], petikSymbol, true));
221
+
222
+ tipe.member.define("PLUS",
223
+ makeBuiltInFunc([petikSymbol, petikSymbol], petikSymbol, (_, [r, l]) => new Value(petikSymbol, l.data + r.data)));
224
+ tipe.member.define("LEBIH",
225
+ makeBuiltInFunc([petikSymbol, petikSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data > r.data)));
226
+ tipe.member.define("KURANG",
227
+ makeBuiltInFunc([petikSymbol, petikSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data < r.data)));
228
+ tipe.member.define("SAMA_SAMA",
229
+ makeBuiltInFunc([petikSymbol, petikSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data === r.data)));
230
+ tipe.member.define("LEBIH_SAMA",
231
+ makeBuiltInFunc([petikSymbol, petikSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data >= r.data)));
232
+ tipe.member.define("KURANG_SAMA",
233
+ makeBuiltInFunc([petikSymbol, petikSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data <= r.data)));
234
+ tipe.member.define("SERU_SAMA",
235
+ makeBuiltInFunc([petikSymbol, petikSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data !== r.data)));
236
+ tipe.member.define("AMPERSAN",
237
+ makeBuiltInFunc([petikSymbol, petikSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data && r.data)));
238
+ tipe.member.define("PIPA",
239
+ makeBuiltInFunc([petikSymbol, petikSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data || r.data)));
240
+
241
+ tipe.member.define("SERU_UNER",
242
+ makeBuiltInFunc([petikSymbol], logisSymbol, (_, [r]) => new Value(logisSymbol, !Boolean(r.data))));
243
+
244
+ tipe.member.define("kePetik",
245
+ makeBuiltInFunc([petikSymbol], petikSymbol, (v, [p]) => new Value(petikSymbol, kePetik(v, p))));
246
+
247
+ tipe.member.define("pisah", makeBuiltInFunc([petikSymbol, petikSymbol], barisSymbol, (_, [d, sep]) => {
248
+ return new Value(barisSymbol, d.data.split(sep.data).map(val => new Value(petikSymbol, val)));
249
+ }));
250
+ tipe.member.define("bersih", makeBuiltInFunc([petikSymbol], petikSymbol, (_, [d]) => {
251
+ return new Value(petikSymbol, d.data.trim())
252
+ }));
253
+ tipe.member.define("ganti", makeBuiltInFunc([petikSymbol, petikSymbol, petikSymbol], petikSymbol,
254
+ (_, [d, what, rep]) => new Value(petikSymbol, d.data.replaceAll(what.data, rep.data))
255
+ ));
256
+ tipe.member.define("besar", makeBuiltInFunc([petikSymbol], petikSymbol, (_, [p]) => {
257
+ return new Value(petikSymbol, p.data.toUpperCase())
258
+ }));
259
+ tipe.member.define("kecil", makeBuiltInFunc([petikSymbol], petikSymbol, (_, [p]) => {
260
+ return new Value(petikSymbol, p.data.toLowerCase())
261
+ }));
262
+
263
+ return tipe;
264
+ })();
265
+
266
+
267
+ const AngkaTipe = (() => {
268
+ let tipe = new Stipe(angkaSymbol, new Callable(null, (v, args) => {
269
+ if (typeof args[0].data === "number") {
270
+ return new Value(angkaSymbol, args[0].data);
271
+ }
272
+
273
+ switch (args[0].type) {
274
+ case petikSymbol:
275
+ if (isNaN(Number(args[0].data))) {
276
+ v.error("Nilai dari petik bukanlah sebuah angka, konversi gagal.");
277
+ }
278
+ return new Value(angkaSymbol, Number(args[0].data));
279
+ case angkaSymbol:
280
+ return new Value(angkaSymbol, args[0].data);
281
+ case logisSymbol:
282
+ return new Value(angkaSymbol, Number(args[0].data));
283
+ default:
284
+ v.error(`Tipe yang dapat diterima hanyalah petik, angka, logis, dan jenis. Mendapatkan ${args[0].type.description}.`);
285
+ return;
286
+ }
287
+ }, [[null]], angkaSymbol, true)
288
+ );
289
+
290
+ tipe.member.define("PLUS",
291
+ makeBuiltInFunc([angkaSymbol, angkaSymbol], angkaSymbol, (_, [r, l]) => new Value(angkaSymbol, l.data + r.data)));
292
+ tipe.member.define("MINUS",
293
+ makeBuiltInFunc([angkaSymbol, angkaSymbol], angkaSymbol, (_, [r, l]) => new Value(angkaSymbol, l.data - r.data)));
294
+ tipe.member.define("BINTANG",
295
+ makeBuiltInFunc([angkaSymbol, angkaSymbol], angkaSymbol, (_, [r, l]) => new Value(angkaSymbol, l.data * r.data)));
296
+ tipe.member.define("GARIS_MIRING",
297
+ makeBuiltInFunc([angkaSymbol, angkaSymbol], angkaSymbol, (_, [r, l]) => new Value(angkaSymbol, l.data / r.data)));
298
+ tipe.member.define("MODULUS",
299
+ makeBuiltInFunc([angkaSymbol, angkaSymbol], angkaSymbol, (_, [r, l]) => new Value(angkaSymbol, l.data % r.data)));
300
+
301
+ tipe.member.define("LEBIH",
302
+ makeBuiltInFunc([angkaSymbol, angkaSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data > r.data)));
303
+ tipe.member.define("KURANG",
304
+ makeBuiltInFunc([angkaSymbol, angkaSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data < r.data)));
305
+ tipe.member.define("SAMA_SAMA",
306
+ makeBuiltInFunc([angkaSymbol, angkaSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data === r.data)));
307
+ tipe.member.define("LEBIH_SAMA",
308
+ makeBuiltInFunc([angkaSymbol, angkaSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data >= r.data)));
309
+ tipe.member.define("KURANG_SAMA",
310
+ makeBuiltInFunc([angkaSymbol, angkaSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data <= r.data)));
311
+ tipe.member.define("SERU_SAMA",
312
+ makeBuiltInFunc([angkaSymbol, angkaSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data !== r.data)));
313
+ tipe.member.define("AMPERSAN",
314
+ makeBuiltInFunc([angkaSymbol, angkaSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data && r.data)));
315
+ tipe.member.define("PIPA",
316
+ makeBuiltInFunc([angkaSymbol, angkaSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data || r.data)));
317
+ tipe.member.define("SERU_UNER",
318
+ makeBuiltInFunc([angkaSymbol], logisSymbol, (_, [r]) => new Value(logisSymbol, !Boolean(r.data))));
319
+ tipe.member.define("PLUS_UNER",
320
+ makeBuiltInFunc([angkaSymbol], angkaSymbol, (_, [r]) => new Value(angkaSymbol, +r.data)));
321
+ tipe.member.define("MINUS_UNER",
322
+ makeBuiltInFunc([angkaSymbol], angkaSymbol, (_, [r]) => new Value(angkaSymbol, -r.data)));
323
+
324
+ tipe.member.define("kePetik",
325
+ makeBuiltInFunc([angkaSymbol], petikSymbol, (v, [a]) => new Value(petikSymbol, kePetik(v, a))));
326
+
327
+ tipe.member.define("bulat", makeBuiltInFunc([angkaSymbol], angkaSymbol, (_, [a]) => {
328
+ return new Value(angkaSymbol, Math.round(a.data));
329
+ }));
330
+ tipe.member.define("bulatAtas", makeBuiltInFunc([angkaSymbol], angkaSymbol, (_, [a]) => {
331
+ return new Value(angkaSymbol, Math.ceil(a.data))
332
+ }));
333
+ tipe.member.define("bulatBawah", makeBuiltInFunc([angkaSymbol], angkaSymbol, (_, [a]) => {
334
+ return new Value(angkaSymbol, Math.floor(a.data))
335
+ }));
336
+
337
+ return tipe;
338
+ })();
339
+
340
+
341
+ const LogisTipe = (() => {
342
+ let tipe = new Stipe(logisSymbol, new Callable(null, (_, args) => {
343
+ if (args[0].type === barisSymbol && args[0].data.length === 0) {
344
+ return new Value(logisSymbol, false);
345
+ }
346
+ return new Value(logisSymbol, Boolean(args[0].data) || Boolean(args[0].data?.member?.size));
347
+ }, [[null]], logisSymbol, true)
348
+ );
349
+
350
+ tipe.member.define("SAMA_SAMA",
351
+ makeBuiltInFunc([logisSymbol, logisSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data === r.data)));
352
+ tipe.member.define("SERU_SAMA",
353
+ makeBuiltInFunc([logisSymbol, logisSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data !== r.data)));
354
+ tipe.member.define("AMPERSAN",
355
+ makeBuiltInFunc([logisSymbol, logisSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data && r.data)));
356
+ tipe.member.define("PIPA",
357
+ makeBuiltInFunc([logisSymbol, logisSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data || r.data)));
358
+ tipe.member.define("SERU_UNER",
359
+ makeBuiltInFunc([logisSymbol], logisSymbol, (_, [r]) => new Value(logisSymbol, !Boolean(r.data))));
360
+
361
+ tipe.member.define("kePetik",
362
+ makeBuiltInFunc([logisSymbol], petikSymbol, (v, [l]) => new Value(petikSymbol, kePetik(v, l))));
363
+
364
+ return tipe;
365
+ })();
366
+
367
+
368
+ const BarisTipe = (() => {
369
+ let tipe = new Stipe(barisSymbol);
370
+
371
+ const valueToVariableDatum = (d) => {
372
+ let input = new Variable(d.type, false, d.data);
373
+ input.member = d.member;
374
+ input.isDatum = true;
375
+ return input;
376
+ };
377
+
378
+ tipe.member.define("PLUS",
379
+ makeBuiltInFunc([barisSymbol, barisSymbol], barisSymbol, (_, [r, l]) =>
380
+ new Value(barisSymbol, Array(...l.data, ...r.data))
381
+ ));
382
+
383
+ tipe.member.define("MINUS_UNER",
384
+ makeBuiltInFunc([barisSymbol], barisSymbol, (_, [r]) =>
385
+ new Value(barisSymbol, r.data.slice(0, r.length))
386
+ ));
387
+
388
+ tipe.member.define("SAMA_SAMA",
389
+ makeBuiltInFunc([barisSymbol, barisSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, ((a, b) => {
390
+ if (a.length !== b.length) return false;
391
+ for (let i = 0; i < a.length; i++) {
392
+ if (a[i].data !== b[i].data) return false;
393
+ }
394
+ return true;
395
+ })(l.data, r.data)))
396
+ );
397
+
398
+ tipe.member.define("SERU_SAMA",
399
+ makeBuiltInFunc([barisSymbol, barisSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, ((a, b) => {
400
+ if (a.length !== b.length) return true;
401
+ for (let i = 0; i < a.length; i++) {
402
+ if (a[i].data !== b[i].data) return true;
403
+ }
404
+ return false;
405
+ })(l.data, r.data)))
406
+ );
407
+
408
+ tipe.member.define("AMPERSAN",
409
+ makeBuiltInFunc([barisSymbol, barisSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data && r.data)));
410
+ tipe.member.define("PIPA",
411
+ makeBuiltInFunc([barisSymbol, barisSymbol], logisSymbol, (_, [r, l]) => new Value(logisSymbol, l.data || r.data)));
412
+ tipe.member.define("SERU_UNER",
413
+ makeBuiltInFunc([barisSymbol], logisSymbol, (_, [r]) => new Value(logisSymbol, !Boolean(r.data))));
414
+
415
+ tipe.member.define("kePetik",
416
+ makeBuiltInFunc([barisSymbol], petikSymbol, (v, [p]) => new Value(petikSymbol, kePetik(v, p))));
417
+
418
+ tipe.member.define("hapus", makeBuiltInFunc([barisSymbol, angkaSymbol], barisSymbol, (v, [b, i]) => {
419
+ if (b.data.length <= i.data) {
420
+ v.error(`Indeks tidak boleh lebih besar atau sama dengan ukuran baris, ${i.data} >= ${b.data.length}`);
421
+ }
422
+
423
+ while (i.data < 0) i.data += b.data.length;
424
+ b.data = b.data.filter((_, idx) => idx !== i.data);
425
+ return b;
426
+ }));
427
+
428
+ tipe.member.define("potongan", makeBuiltInFunc([barisSymbol, angkaSymbol, angkaSymbol], barisSymbol, (v, [b, fr, to]) => {
429
+ if (fr.data >= b.data.length || fr.data < 0 || to.data <= fr.data || to.data > b.data.length) {
430
+ v.error(`Indeks tidak valid, ${fr.data} sampai ${to.data}, dengan ukuran baris ${b.data.length}`);
431
+ }
432
+ return new Value(barisSymbol, b.data.slice(fr.data, to.data));
433
+ }));
434
+ tipe.member.define("tumpuk", makeBuiltInFunc([barisSymbol, null], null, (_, [b, d]) => {
435
+ b.data.push(valueToVariableDatum(d));
436
+ return b;
437
+ }));
438
+ tipe.member.define("tumpah", makeBuiltInFunc([barisSymbol], null, (_, [b]) => {
439
+ b.data.pop();
440
+ return b;
441
+ }));
442
+ tipe.member.define("masuk", makeBuiltInFunc([barisSymbol, null, angkaSymbol], null, (v, [b, d, idx]) => {
443
+ if (idx.data > b.data.length) {
444
+ v.error(`Indeks tidak valid, ${idx.data}, dengan ukuran baris ${b.data.length}`);
445
+ }
446
+ b.data.splice(idx.data, 0, valueToVariableDatum(d));
447
+ return b;
448
+ }));
449
+ tipe.member.define("petakan", makeBuiltInFunc([barisSymbol, mesinSymbol], barisSymbol, (v, [b, m]) => {
450
+ let newBaris = new Value(barisSymbol, []);
451
+ for (let datum of b.data) {
452
+ let result = v.callFunc(m.data, [datum]);
453
+ newBaris.data.push(valueToVariableDatum(result));
454
+ }
455
+ return newBaris;
456
+ }));
457
+ tipe.member.define("saring", makeBuiltInFunc([barisSymbol, mesinSymbol], barisSymbol, (v, [b, m]) => {
458
+ let newBaris = new Value(barisSymbol, []);
459
+ for (let datum of b.data) {
460
+ let result = v.callFunc(m.data, [datum]);
461
+ if (result.data === true) {
462
+ newBaris.data.push(valueToVariableDatum(datum));
463
+ }
464
+ }
465
+ return newBaris;
466
+ }));
467
+ tipe.member.define("reduksi", makeBuiltInFunc([barisSymbol, mesinSymbol, null], null, (v, [b, m, d]) => {
468
+ for (let datum of b.data) {
469
+ let result = v.callFunc(m.data, [d, datum]);
470
+ d = result;
471
+ }
472
+ return d;
473
+ }));
474
+
475
+ tipe.member.define("punya?", makeBuiltInFunc([barisSymbol, null], logisSymbol, (v, [b, d]) => {
476
+ let type = v.environment.get(d.type?.description);
477
+ if (!type)
478
+ v.error(`Tipe tidak ditemukan atau tidak valid`);
479
+ let equalFunc;
480
+ if (type.member?.has("SAMA_SAMA")) {
481
+ equalFunc = type.member.get("SAMA_SAMA");
482
+ } else {
483
+ v.error(`model ${d.type.description} tidak mempunyai mesin SAMA_SAMA di dalam modulnya.`);
484
+ }
485
+ for (let datum of b.data) {
486
+ if (datum.type !== d.type) continue;
487
+ let isEqual = v.callFunc(equalFunc.data, [datum, d]);
488
+ if (isEqual.data) return new Value(logisSymbol, true);
489
+ }
490
+ return new Value(logisSymbol, false);
491
+ }));
492
+
493
+ return tipe;
494
+ })();
495
+
496
+
497
+ const MesinTipe = (() => {
498
+ let tipe = new Stipe(mesinSymbol);
499
+
500
+ tipe.member.define("kePetik",
501
+ makeBuiltInFunc([mesinSymbol], petikSymbol, (v, [m]) => new Value(petikSymbol, kePetik(v, m))));
502
+
503
+ return tipe;
504
+ })();
505
+
506
+
518
507
  const GLOBAL_ENV = (() => {
519
508
  let env = new Environment();
520
- env.define("petik", new PetikTipe());
521
- env.define("angka", new AngkaTipe());
522
- env.define("logis", new LogisTipe());
523
- env.define("baris", new BarisTipe());
524
- env.define("mesin", new MesinTipe());
509
+ env.define("petik", PetikTipe);
510
+ env.define("angka", AngkaTipe);
511
+ env.define("logis", LogisTipe);
512
+ env.define("baris", BarisTipe);
513
+ env.define("mesin", MesinTipe);
525
514
 
526
515
  env.define("jarak", makeBuiltInFunc([angkaSymbol, angkaSymbol], barisSymbol,
527
516
  (_, [from, to]) => new Value(barisSymbol,
@@ -716,23 +705,26 @@ let Hasil$1 = class Hasil {
716
705
  }
717
706
  };
718
707
 
719
- const location = {
720
- GLOBAL: 1,
721
- SLAGI: 2,
722
- UNTUK: 3,
723
- MESIN: 4,
724
- LIHAT: 5,
725
- };
726
- const MAX_STACK_SIZE = 500;
727
-
728
708
  // Implements all Expressions and Statements Visitor
729
709
  class Interpreter {
730
710
  constructor() {
731
711
  this.globalEnvironment = GLOBAL_ENV;
712
+ this.location = {
713
+ GLOBAL: 1,
714
+ SLAGI: 2,
715
+ UNTUK: 3,
716
+ MESIN: 4,
717
+ LIHAT: 5,
718
+ };
719
+ this.MAX_STACK_SIZE = 500;
720
+ this.init();
721
+ }
722
+
723
+ init() {
732
724
  this.line = 0;
733
725
  this.environment = new Environment(this.globalEnvironment);
734
726
  this.tree = null;
735
- this.state = location.GLOBAL;
727
+ this.state = this.location.GLOBAL;
736
728
  this.stack = [];
737
729
  this.output = [];
738
730
  this.objectStack = null;
@@ -740,6 +732,14 @@ class Interpreter {
740
732
  this.pipeStack = [];
741
733
  }
742
734
 
735
+ interpret(tree) {
736
+ this.line = 0;
737
+ this.output = [];
738
+ this.tree = tree;
739
+ tree.accept(this);
740
+ return this.output;
741
+ }
742
+
743
743
  // EXPRESSION VISITORS
744
744
 
745
745
  visitLiteralExpr(literalExpr) {
@@ -761,7 +761,7 @@ class Interpreter {
761
761
  let value = new Value(barisSymbol, []);
762
762
 
763
763
  for (let expr of arrayExpr.contents) {
764
- let v = this.validValue(expr.accept(this));
764
+ let v = expr.accept(this);
765
765
  let newVar = new Variable(v.type, false, v.data);
766
766
  newVar.member = v.member;
767
767
  newVar.isDatum = true;
@@ -829,7 +829,7 @@ class Interpreter {
829
829
  this.error(`Hanya bisa 'memanggil' mesin atau model, malah menemukan ${callable.type.description}. `);
830
830
  }
831
831
 
832
- if (!callable.data?.block) {
832
+ if (!callable?.data?.block) {
833
833
  this.error(`Mesin tidak terdefinisi, tidak bisa dipanggil.`);
834
834
  }
835
835
 
@@ -840,7 +840,7 @@ class Interpreter {
840
840
  this.objectStack = null;
841
841
  }
842
842
 
843
- args = [...args, ...callExpr.args.map(val => this.validValue(val.accept(this)))];
843
+ args = [...args, ...callExpr.args.map(val => val.accept(this))];
844
844
 
845
845
  let result = this.callFunc(callable.data, args);
846
846
  return result;
@@ -850,13 +850,16 @@ class Interpreter {
850
850
  // args.forEach((val,idx)=>{
851
851
  // console.log(idx, val);
852
852
  // });
853
+ if (!callable) {
854
+ this.error(`Mesin tidak terdefinisi, tidak bisa dipanggil.`);
855
+ }
853
856
  this.stack.push(this.line);
854
- if (this.stack.length > MAX_STACK_SIZE)
855
- this.error(`Rekursi melebihi batas: Lebih dari ${MAX_STACK_SIZE}`);
857
+ if (this.stack.length > this.MAX_STACK_SIZE)
858
+ this.error(`Rekursi melebihi batas: Lebih dari ${this.MAX_STACK_SIZE}`);
856
859
 
857
860
  let prevState = this.state;
858
861
  this.line = this.stack[this.stack.length - 1];
859
- this.state = location.MESIN;
862
+ this.state = this.location.MESIN;
860
863
 
861
864
  if (args.length !== callable.parameters.length) {
862
865
  this.error(`Jumlah argumen tidak sama dengan parameter mesin. Menemukan ${args.length}, harusnya ${callable.parameters.length}.`);
@@ -917,8 +920,8 @@ class Interpreter {
917
920
 
918
921
 
919
922
  visitBinaryExpr(binaryExpr) {
920
- let leftValue = this.validValue(binaryExpr.left.accept(this));
921
- let rightValue = this.validValue(binaryExpr.right.accept(this));
923
+ let leftValue = binaryExpr.left.accept(this);
924
+ let rightValue = binaryExpr.right.accept(this);
922
925
 
923
926
  this.line = binaryExpr.op.line;
924
927
 
@@ -935,7 +938,7 @@ class Interpreter {
935
938
  }
936
939
 
937
940
  visitUnaryExpr(unaryExpr) {
938
- let rightValue = this.validValue(unaryExpr.right.accept(this));
941
+ let rightValue = unaryExpr.right.accept(this);
939
942
 
940
943
  this.line = unaryExpr.op.line;
941
944
 
@@ -966,7 +969,7 @@ class Interpreter {
966
969
  }
967
970
 
968
971
  visitGroupingExpr(groupingExpr) {
969
- return this.validValue(groupingExpr.expr.accept(this));
972
+ return groupingExpr.expr.accept(this);
970
973
  }
971
974
 
972
975
  visitIdentifierExpr(identifierExpr) {
@@ -1009,11 +1012,11 @@ class Interpreter {
1009
1012
  }
1010
1013
 
1011
1014
  visitPipeLineExpr (pipeLineExpr) {
1012
- let expr = this.validValue(pipeLineExpr.expr.accept(this));
1015
+ let expr = pipeLineExpr.expr.accept(this);
1013
1016
 
1014
1017
  this.pipeStack.push(expr);
1015
1018
 
1016
- let pipeValue = this.validValue(pipeLineExpr.pipeTo.accept(this));
1019
+ let pipeValue = pipeLineExpr.pipeTo.accept(this);
1017
1020
 
1018
1021
  this.pipeStack.pop();
1019
1022
 
@@ -1026,7 +1029,8 @@ class Interpreter {
1026
1029
  visitTypeStmt(typeStmt) {
1027
1030
  if (typeStmt.type === null) return null;
1028
1031
  let type = typeStmt.type.accept(this);
1029
- if (type.type !== stipeSymbol) this.error(`'${type.type.description}' bukan sebuah Model/Tipe Valid.`);
1032
+ if (type.type !== stipeSymbol || !(type.symbol))
1033
+ this.error(`'${type.type.description}' bukan sebuah Model/Tipe Valid.`);
1030
1034
  return type.symbol;
1031
1035
  }
1032
1036
 
@@ -1047,7 +1051,7 @@ class Interpreter {
1047
1051
 
1048
1052
  let variable = new Variable(type, datumStmt.type.tetap);
1049
1053
 
1050
- let value = this.validValue(datumStmt.expr.accept(this));
1054
+ let value = datumStmt.expr.accept(this);
1051
1055
 
1052
1056
  if (value.data === null) value.type = variable.type; // if nihil, ok
1053
1057
 
@@ -1070,7 +1074,7 @@ class Interpreter {
1070
1074
  if (variable.tetap) {
1071
1075
  this.error(`Variabel tetap tidak dapat di-rubah.`);
1072
1076
  }
1073
- let value = this.validValue(rubahStmt.value.accept(this));
1077
+ let value = rubahStmt.value.accept(this);
1074
1078
  if (value.data === null) value.type = variable.type; // if nihil, ok
1075
1079
 
1076
1080
  if (variable.isDatum)
@@ -1109,20 +1113,20 @@ class Interpreter {
1109
1113
  }
1110
1114
 
1111
1115
  visitHentiStmt() {
1112
- if (this.state === location.UNTUK || this.state === location.SLAGI)
1116
+ if (this.state === this.location.UNTUK || this.state === this.location.SLAGI)
1113
1117
  throw new Henti$1(); // throws exception to escape from deep recursion
1114
1118
  else this.error("Tidak ada pengulangan untuk dihentikan.");
1115
1119
  }
1116
1120
 
1117
1121
 
1118
1122
  visitLewatStmt() {
1119
- if (this.state === location.UNTUK || this.state === location.SLAGI)
1123
+ if (this.state === this.location.UNTUK || this.state === this.location.SLAGI)
1120
1124
  throw new Lewat$1(); // throws exception to escape from deep recursion
1121
1125
  else this.error("Tidak ada pengulangan untuk dilewatkan.");
1122
1126
  }
1123
1127
 
1124
1128
  visitJatuhStmt() {
1125
- if (this.state === location.LIHAT)
1129
+ if (this.state === this.location.LIHAT)
1126
1130
  throw new Jatuh$1();
1127
1131
  else this.error("Tidak bisa jatuh di luar blok kasus.");
1128
1132
  }
@@ -1146,9 +1150,9 @@ class Interpreter {
1146
1150
  this.environment = new Environment(lastEnv);
1147
1151
  try {
1148
1152
  for (let stmt of slagiStmt.block.statements) {
1149
- this.state = location.SLAGI;
1153
+ this.state = this.location.SLAGI;
1150
1154
  stmt.accept(this);
1151
- this.state = location.SLAGI;
1155
+ this.state = this.location.SLAGI;
1152
1156
  }
1153
1157
  } catch (err) {
1154
1158
  if (err instanceof Henti$1) {
@@ -1159,15 +1163,15 @@ class Interpreter {
1159
1163
  }
1160
1164
  }
1161
1165
  this.environment = lastEnv;
1162
- if (this.stackNum !== 0) this.state = location.MESIN;
1163
- else this.state = location.GLOBAL;
1166
+ if (this.stackNum !== 0) this.state = this.location.MESIN;
1167
+ else this.state = this.location.GLOBAL;
1164
1168
  }
1165
1169
 
1166
1170
  visitUntukStmt(untukStmt) {
1167
1171
  let name = this.validName(untukStmt.varName.lexeme, false);
1168
1172
  let type = untukStmt.varType.accept(this);
1169
1173
 
1170
- let iter = this.validValue(untukStmt.iterable.accept(this));
1174
+ let iter = untukStmt.iterable.accept(this);
1171
1175
  if (iter.type === petikSymbol) {
1172
1176
  iter = new Value(barisSymbol, iter.data.split("").map(str => new Value(petikSymbol, str)));
1173
1177
  }
@@ -1188,9 +1192,9 @@ class Interpreter {
1188
1192
  try {
1189
1193
  // didn't 'accept' the block, just uses it directly
1190
1194
  for (let stmt of untukStmt.block.statements) {
1191
- this.state = location.UNTUK;
1195
+ this.state = this.location.UNTUK;
1192
1196
  stmt.accept(this);
1193
- this.state = location.UNTUK;
1197
+ this.state = this.location.UNTUK;
1194
1198
  }
1195
1199
  } catch (err) {
1196
1200
  this.environment = untukEnv.enclosing;
@@ -1204,8 +1208,8 @@ class Interpreter {
1204
1208
  }
1205
1209
  this.environment = untukEnv.enclosing;
1206
1210
  }
1207
- if (this.stackNum !== 0) this.state = location.MESIN;
1208
- else this.state = location.GLOBAL;
1211
+ if (this.stackNum !== 0) this.state = this.location.MESIN;
1212
+ else this.state = this.location.GLOBAL;
1209
1213
  }
1210
1214
 
1211
1215
  visitJenisStmt(jenisStmt) {
@@ -1215,7 +1219,7 @@ class Interpreter {
1215
1219
  }
1216
1220
 
1217
1221
  visitLihatStmt(lihatStmt) {
1218
- let match = this.validValue(lihatStmt.expr.accept(this));
1222
+ let match = lihatStmt.expr.accept(this);
1219
1223
  let matchType = this.environment.get(match?.type?.description);
1220
1224
  if (!matchType?.member?.has("SAMA_SAMA")) {
1221
1225
  this.error(`tipe ${matchType ? match.type.description : "nihil"} tidak mempunyai mesin SAMA_SAMA.`);
@@ -1225,9 +1229,9 @@ class Interpreter {
1225
1229
  const handleBlock = (index) => {
1226
1230
  while (index < lihatStmt.cases.length) {
1227
1231
  try {
1228
- this.state = location.LIHAT;
1232
+ this.state = this.location.LIHAT;
1229
1233
  lihatStmt.cases[index][1].accept(this);
1230
- this.state = location.LIHAT;
1234
+ this.state = this.location.LIHAT;
1231
1235
  } catch (err) {
1232
1236
  if (err instanceof Jatuh$1) {
1233
1237
  index++; continue;
@@ -1235,8 +1239,8 @@ class Interpreter {
1235
1239
  }
1236
1240
  break;
1237
1241
  }
1238
- if (this.stackNum !== 0) this.state = location.MESIN;
1239
- else this.state = location.GLOBAL;
1242
+ if (this.stackNum !== 0) this.state = this.location.MESIN;
1243
+ else this.state = this.location.GLOBAL;
1240
1244
  };
1241
1245
 
1242
1246
  for (let i = 0; i < lihatStmt.cases.length; i++) {
@@ -1270,7 +1274,7 @@ class Interpreter {
1270
1274
  if (variable.type !== stipeSymbol) {
1271
1275
  this.error(`Modul hanya bisa _ditambahkan_ pada tipe. '${name}' bukan merupakan tipe.`);
1272
1276
  }
1273
- if (variable.member.memory.size > 0) {
1277
+ if (variable.member.memory.size > 1) {
1274
1278
  this.error(`Tipe '${name}' sudah memiliki modul sendiri, tidak bisa definisi ulang.`);
1275
1279
  }
1276
1280
  } else {
@@ -1294,6 +1298,7 @@ class Interpreter {
1294
1298
 
1295
1299
  typeCheck(a, b, message) {
1296
1300
  if (a.type !== b.type) {
1301
+ console.log(a, b);
1297
1302
  this.error(`Tipe data tidak sama: ${a.type.description} != ${b.type.description}. ` + message);
1298
1303
  }
1299
1304
  }
@@ -1305,11 +1310,6 @@ class Interpreter {
1305
1310
  return false;
1306
1311
  }
1307
1312
 
1308
- validValue(v) {
1309
- if (v.type !== stipeSymbol) return v;
1310
- this.error("stipe tidak dapat menjadi nilai.");
1311
- }
1312
-
1313
1313
  validName(n, checkExisted = true) {
1314
1314
  if (RESERVED_NAMES.some(v => v === n)) {
1315
1315
  this.error(`Nama sistem (${n}) tidak boleh didefinisi ulang.`);
@@ -1323,13 +1323,7 @@ class Interpreter {
1323
1323
  throw new SimplErrorEksekusi(`Error Eksekusi => ${message}`, this.line, this.output.join('\n'));
1324
1324
  }
1325
1325
 
1326
- interpret(tree) {
1327
- this.line = 0;
1328
- this.output = [];
1329
- this.tree = tree;
1330
- tree.accept(this);
1331
- return this.output;
1332
- }
1326
+
1333
1327
  }
1334
1328
 
1335
1329
  class Token {
@@ -1359,6 +1353,23 @@ class Lexer {
1359
1353
  this.errors = [];
1360
1354
  }
1361
1355
 
1356
+ scanTokens(text) {
1357
+ this.init();
1358
+ this.text = text;
1359
+ let tokens = [];
1360
+
1361
+ while (!this.isAtEnd()) {
1362
+ let token = this.scan();
1363
+ this.charStart = this.charIndex;
1364
+ if (token) tokens.push(token);
1365
+ }
1366
+
1367
+ tokens.push(new Token(EOF, "Akhir dokumen", null, this.lineIndex));
1368
+
1369
+ this.tokens = tokens;
1370
+ return this.tokens;
1371
+ }
1372
+
1362
1373
  isAtEnd() {
1363
1374
  return this.charIndex >= this.text.length;
1364
1375
  }
@@ -1401,23 +1412,6 @@ class Lexer {
1401
1412
  return this.text.slice(this.charStart, this.charIndex);
1402
1413
  }
1403
1414
 
1404
- scanTokens(text) {
1405
- this.init();
1406
- this.text = text;
1407
- let tokens = [];
1408
-
1409
- while (!this.isAtEnd()) {
1410
- let token = this.scan();
1411
- this.charStart = this.charIndex;
1412
- if (token) tokens.push(token);
1413
- }
1414
-
1415
- tokens.push(new Token(EOF, "Akhir dokumen", null, this.lineIndex));
1416
-
1417
- this.tokens = tokens;
1418
- return this.tokens;
1419
- }
1420
-
1421
1415
  id() {
1422
1416
  while (!this.isAtEnd() && this.isAlphaNumeric(this.see())) this.advance();
1423
1417
 
@@ -1967,6 +1961,17 @@ class Parser {
1967
1961
  this.tree = null;
1968
1962
  }
1969
1963
 
1964
+ parse(tokens) {
1965
+ this.init();
1966
+ this.tokens = tokens;
1967
+ let treeList = [];
1968
+ while (!this.match(EOF)) {
1969
+ treeList.push(this.statement());
1970
+ }
1971
+ this.tree = new Simpl$1(treeList);
1972
+ return this.tree;
1973
+ }
1974
+
1970
1975
  see() {
1971
1976
  return this.tokens[this.tokenIndex];
1972
1977
  }
@@ -2445,28 +2450,23 @@ class Parser {
2445
2450
  throw new SimplErrorStruktur(`Error Struktur => ` + errmsg + ((found) ? ` Menemukan '${this.see().lexeme}'.` : ""), this.see().line);
2446
2451
  }
2447
2452
 
2448
- parse(tokens) {
2449
- this.init();
2450
- this.tokens = tokens;
2451
- let treeList = [];
2452
- while (!this.match(EOF)) {
2453
- treeList.push(this.statement());
2454
- }
2455
- this.tree = new Simpl$1(treeList);
2456
- return this.tree;
2457
- }
2458
2453
  }
2459
2454
 
2460
2455
  // Simpl: Indonesian Mini Programming Language !!
2461
2456
 
2462
2457
  class Simpl {
2463
- constructor() {
2458
+ constructor(opts = {
2459
+ keepMemory: false
2460
+ }) {
2464
2461
  this.lexer = new Lexer();
2465
2462
  this.parser = new Parser();
2466
2463
  this.interpreter = new Interpreter();
2464
+ this.keepMemory = opts?.keepMemory ? opts.keepMemory : false;
2467
2465
  }
2468
2466
 
2469
2467
  runCode(text) {
2468
+ if (!this.keepMemory) this.interpreter.init();
2469
+
2470
2470
  // console.log(text.split("\n").reduce((codeStr, line, idx) => codeStr + `${idx + 1}.\t${line}\n`, ''));
2471
2471
  const textLines = text.split("\n");
2472
2472
  try {
@@ -2475,7 +2475,6 @@ class Simpl {
2475
2475
  let output = this.interpreter.interpret(pohon);
2476
2476
  return output.join("\n");
2477
2477
  } catch (err) {
2478
- // throw err
2479
2478
  if (err instanceof SimplError) {
2480
2479
  const errorCode = textLines[err.line - 1];
2481
2480
  let errorText = (errorCode ? `ERROR! Pada baris ke-${err.line}\n>> ` + errorCode + '\n' : "") + err.message;
@@ -2489,10 +2488,6 @@ class Simpl {
2489
2488
  }
2490
2489
 
2491
2490
  }
2492
- }
2493
-
2494
- function run(code) {
2495
- return new Simpl().runCode(code);
2496
2491
  }
2497
2492
 
2498
- export { run as default };
2493
+ export { Simpl };
@@ -0,0 +1 @@
1
+ class e extends Error{constructor(e,t){super(e),this.line=t}}class t extends e{constructor(e,t,i){super(e,t),this.output=i}}class i extends e{}class a extends e{}class s{constructor(e){this.enclosing=e,this.memory=new Map}define(e,t){this.memory.set(e,t)}assign(e,t){return this.has(e)?this.memory.set(e,t):this.enclosing&&this.enclosing.assign(e,t),null}get(e){return this.has(e)?this.memory.get(e):this.enclosing?this.enclosing.get(e):null}has(e){return this.memory.has(e)}}const n=["petik","angka","logis","mesin","baris","stipe","modul"],r=Symbol("petik"),h=Symbol("angka"),l=Symbol("logis"),m=Symbol("mesin"),o=Symbol("baris"),d=Symbol("stipe"),u=Symbol("modul");class c{constructor(e,t){this.type=e,this.data=t,this.member=null}}const p=new c(null,null);class k extends c{constructor(e,t,i){super(e,i),this.tetap=t,this.isDatum=!1}}class b extends k{constructor(e,t){super(d,!0,t),this.symbol=e,this.member=new s,this.member.define("buat",new k(m,!0,t))}}function f(e,t){if(t.type===l)return t.data?"benar":"salah";if(t.type===o)return"["+t.data.reduce((t,i)=>t+", "+f(e,i),"").slice(1)+" ]";if(t.type===d)return`Model<${t.symbol?.description?t.symbol.description:""}>`;if(t.type===m){let e=t.data.returnType?.description;return`Mesin<${e||"datum"}>`}if(t.type===h)return t.data.toString();if(t.type===r)return t.data;{if(!t?.type)return"nihil";let i=e.environment.get(t.type.description);if(i?.member.has("kePetik")){return e.callFunc(i.member.get("kePetik").data,[t]).data}return`${t.type.description}<>`}}let w=class extends b{constructor(e,t){let i=Symbol(e);super(i,new g(null,(e,a)=>{let n=new c(i,!0);n.member=new s;let r=e.line;for(let i=0;i<a.length;i++){let s=t[i][0],h=s.accept(e),l=t[i][1].lexeme,m=new k(h,s.tetap,a[i].data);null===h?(m.isDatum=!0,m.type=a[i].type):a[i].type!==h&&(e.line=r,e.error(`Argumen pembuatan objek tidak sama dengan argumen model, menemukan ${a[i].type?.description}, mengharapkan ${h?h.description:"nihil"}`)),m.member=a[i].member,n.member.define(l,m)}return n},t.map(e=>[null]),i,!0))}},S=class extends b{constructor(e,t){let i=Symbol(e);super(i,null),t.forEach((e,t)=>{this.member.define(e.lexeme,new c(i,t))}),this.member.define("kePetik",y([i],r,(t,[i])=>new c(r,`${e}<${i.data}>`))),this.member.define("SAMA_SAMA",y([i,i],l,(e,[t,i])=>new c(l,i.data===t.data))),this.member.define("SERU_SAMA",y([i,i],l,(e,[t,i])=>new c(l,i.data!==t.data)))}};class g{constructor(e,t,i,a,s=!1){this.closure=e,this.block=t,this.parameters=i,this.returnType=a,this.isBuiltIn=s}}function y(e,t,i){let a=new g(null,i,e.map(e=>[e]),t,!0);return new k(m,!0,a)}function A(e){switch(e.type){case r:return new c(r,e.data);case h:return new c(h,e.data);case l:return new c(l,e.data);case m:return new c(m,e.data);case o:return new c(o,e.data.map(e=>{let t=A(e),i=new k(t.type,!1,t.data);return i.member=t.member,i}));case d:case u:return p;default:if(e.member&&e.member instanceof s){let t=e.member.memory.keys(),i=new c(e.type,null),a=new s;for(let i of t){let t=e.member.get(i),s=A(t),n=new k(t.type,t.tetap,s.data);n.member=s.member,a.define(i,n)}return i.member=a,i.data=e.data,i}return new c(e.type,e.data)}}const x=(()=>{let e=new b(r,new g(null,(e,t)=>new c(r,f(e,t[0])),[[null]],r,!0));return e.member.define("PLUS",y([r,r],r,(e,[t,i])=>new c(r,i.data+t.data))),e.member.define("LEBIH",y([r,r],l,(e,[t,i])=>new c(l,i.data>t.data))),e.member.define("KURANG",y([r,r],l,(e,[t,i])=>new c(l,i.data<t.data))),e.member.define("SAMA_SAMA",y([r,r],l,(e,[t,i])=>new c(l,i.data===t.data))),e.member.define("LEBIH_SAMA",y([r,r],l,(e,[t,i])=>new c(l,i.data>=t.data))),e.member.define("KURANG_SAMA",y([r,r],l,(e,[t,i])=>new c(l,i.data<=t.data))),e.member.define("SERU_SAMA",y([r,r],l,(e,[t,i])=>new c(l,i.data!==t.data))),e.member.define("AMPERSAN",y([r,r],l,(e,[t,i])=>new c(l,i.data&&t.data))),e.member.define("PIPA",y([r,r],l,(e,[t,i])=>new c(l,i.data||t.data))),e.member.define("SERU_UNER",y([r],l,(e,[t])=>new c(l,!Boolean(t.data)))),e.member.define("kePetik",y([r],r,(e,[t])=>new c(r,f(e,t)))),e.member.define("pisah",y([r,r],o,(e,[t,i])=>new c(o,t.data.split(i.data).map(e=>new c(r,e))))),e.member.define("bersih",y([r],r,(e,[t])=>new c(r,t.data.trim()))),e.member.define("ganti",y([r,r,r],r,(e,[t,i,a])=>new c(r,t.data.replaceAll(i.data,a.data)))),e.member.define("besar",y([r],r,(e,[t])=>new c(r,t.data.toUpperCase()))),e.member.define("kecil",y([r],r,(e,[t])=>new c(r,t.data.toLowerCase()))),e})(),M=(()=>{let e=new b(h,new g(null,(e,t)=>{if("number"==typeof t[0].data)return new c(h,t[0].data);switch(t[0].type){case r:return isNaN(Number(t[0].data))&&e.error("Nilai dari petik bukanlah sebuah angka, konversi gagal."),new c(h,Number(t[0].data));case h:return new c(h,t[0].data);case l:return new c(h,Number(t[0].data));default:return void e.error(`Tipe yang dapat diterima hanyalah petik, angka, logis, dan jenis. Mendapatkan ${t[0].type.description}.`)}},[[null]],h,!0));return e.member.define("PLUS",y([h,h],h,(e,[t,i])=>new c(h,i.data+t.data))),e.member.define("MINUS",y([h,h],h,(e,[t,i])=>new c(h,i.data-t.data))),e.member.define("BINTANG",y([h,h],h,(e,[t,i])=>new c(h,i.data*t.data))),e.member.define("GARIS_MIRING",y([h,h],h,(e,[t,i])=>new c(h,i.data/t.data))),e.member.define("MODULUS",y([h,h],h,(e,[t,i])=>new c(h,i.data%t.data))),e.member.define("LEBIH",y([h,h],l,(e,[t,i])=>new c(l,i.data>t.data))),e.member.define("KURANG",y([h,h],l,(e,[t,i])=>new c(l,i.data<t.data))),e.member.define("SAMA_SAMA",y([h,h],l,(e,[t,i])=>new c(l,i.data===t.data))),e.member.define("LEBIH_SAMA",y([h,h],l,(e,[t,i])=>new c(l,i.data>=t.data))),e.member.define("KURANG_SAMA",y([h,h],l,(e,[t,i])=>new c(l,i.data<=t.data))),e.member.define("SERU_SAMA",y([h,h],l,(e,[t,i])=>new c(l,i.data!==t.data))),e.member.define("AMPERSAN",y([h,h],l,(e,[t,i])=>new c(l,i.data&&t.data))),e.member.define("PIPA",y([h,h],l,(e,[t,i])=>new c(l,i.data||t.data))),e.member.define("SERU_UNER",y([h],l,(e,[t])=>new c(l,!Boolean(t.data)))),e.member.define("PLUS_UNER",y([h],h,(e,[t])=>new c(h,+t.data))),e.member.define("MINUS_UNER",y([h],h,(e,[t])=>new c(h,-t.data))),e.member.define("kePetik",y([h],r,(e,[t])=>new c(r,f(e,t)))),e.member.define("bulat",y([h],h,(e,[t])=>new c(h,Math.round(t.data)))),e.member.define("bulatAtas",y([h],h,(e,[t])=>new c(h,Math.ceil(t.data)))),e.member.define("bulatBawah",y([h],h,(e,[t])=>new c(h,Math.floor(t.data)))),e})(),E=(()=>{let e=new b(l,new g(null,(e,t)=>t[0].type===o&&0===t[0].data.length?new c(l,!1):new c(l,Boolean(t[0].data)||Boolean(t[0].data?.member?.size)),[[null]],l,!0));return e.member.define("SAMA_SAMA",y([l,l],l,(e,[t,i])=>new c(l,i.data===t.data))),e.member.define("SERU_SAMA",y([l,l],l,(e,[t,i])=>new c(l,i.data!==t.data))),e.member.define("AMPERSAN",y([l,l],l,(e,[t,i])=>new c(l,i.data&&t.data))),e.member.define("PIPA",y([l,l],l,(e,[t,i])=>new c(l,i.data||t.data))),e.member.define("SERU_UNER",y([l],l,(e,[t])=>new c(l,!Boolean(t.data)))),e.member.define("kePetik",y([l],r,(e,[t])=>new c(r,f(e,t)))),e})(),T=(()=>{let e=new b(o);const t=e=>{let t=new k(e.type,!1,e.data);return t.member=e.member,t.isDatum=!0,t};return e.member.define("PLUS",y([o,o],o,(e,[t,i])=>new c(o,Array(...i.data,...t.data)))),e.member.define("MINUS_UNER",y([o],o,(e,[t])=>new c(o,t.data.slice(0,t.length)))),e.member.define("SAMA_SAMA",y([o,o],l,(e,[t,i])=>new c(l,((e,t)=>{if(e.length!==t.length)return!1;for(let i=0;i<e.length;i++)if(e[i].data!==t[i].data)return!1;return!0})(i.data,t.data)))),e.member.define("SERU_SAMA",y([o,o],l,(e,[t,i])=>new c(l,((e,t)=>{if(e.length!==t.length)return!0;for(let i=0;i<e.length;i++)if(e[i].data!==t[i].data)return!0;return!1})(i.data,t.data)))),e.member.define("AMPERSAN",y([o,o],l,(e,[t,i])=>new c(l,i.data&&t.data))),e.member.define("PIPA",y([o,o],l,(e,[t,i])=>new c(l,i.data||t.data))),e.member.define("SERU_UNER",y([o],l,(e,[t])=>new c(l,!Boolean(t.data)))),e.member.define("kePetik",y([o],r,(e,[t])=>new c(r,f(e,t)))),e.member.define("hapus",y([o,h],o,(e,[t,i])=>{for(t.data.length<=i.data&&e.error(`Indeks tidak boleh lebih besar atau sama dengan ukuran baris, ${i.data} >= ${t.data.length}`);i.data<0;)i.data+=t.data.length;return t.data=t.data.filter((e,t)=>t!==i.data),t})),e.member.define("potongan",y([o,h,h],o,(e,[t,i,a])=>((i.data>=t.data.length||i.data<0||a.data<=i.data||a.data>t.data.length)&&e.error(`Indeks tidak valid, ${i.data} sampai ${a.data}, dengan ukuran baris ${t.data.length}`),new c(o,t.data.slice(i.data,a.data))))),e.member.define("tumpuk",y([o,null],null,(e,[i,a])=>(i.data.push(t(a)),i))),e.member.define("tumpah",y([o],null,(e,[t])=>(t.data.pop(),t))),e.member.define("masuk",y([o,null,h],null,(e,[i,a,s])=>(s.data>i.data.length&&e.error(`Indeks tidak valid, ${s.data}, dengan ukuran baris ${i.data.length}`),i.data.splice(s.data,0,t(a)),i))),e.member.define("petakan",y([o,m],o,(e,[i,a])=>{let s=new c(o,[]);for(let n of i.data){let i=e.callFunc(a.data,[n]);s.data.push(t(i))}return s})),e.member.define("saring",y([o,m],o,(e,[i,a])=>{let s=new c(o,[]);for(let n of i.data){!0===e.callFunc(a.data,[n]).data&&s.data.push(t(n))}return s})),e.member.define("reduksi",y([o,m,null],null,(e,[t,i,a])=>{for(let s of t.data){a=e.callFunc(i.data,[a,s])}return a})),e.member.define("punya?",y([o,null],l,(e,[t,i])=>{let a,s=e.environment.get(i.type?.description);s||e.error("Tipe tidak ditemukan atau tidak valid"),s.member?.has("SAMA_SAMA")?a=s.member.get("SAMA_SAMA"):e.error(`model ${i.type.description} tidak mempunyai mesin SAMA_SAMA di dalam modulnya.`);for(let s of t.data){if(s.type!==i.type)continue;if(e.callFunc(a.data,[s,i]).data)return new c(l,!0)}return new c(l,!1)})),e})(),I=(()=>{let e=new b(m);return e.member.define("kePetik",y([m],r,(e,[t])=>new c(r,f(e,t)))),e})(),N=(()=>{let e=new s;e.define("petik",x),e.define("angka",M),e.define("logis",E),e.define("baris",T),e.define("mesin",I),e.define("jarak",y([h,h],o,(e,[t,i])=>new c(o,Array(Math.abs(Math.floor(i.data-t.data))).fill(0).map((e,a)=>new c(h,t.data+(i.data>t.data?1:-1)*a))))),e.define("nihil?",y([null],l,(e,[t])=>new c(l,null===t.data))),e.define("ukuran",y([null],h,(e,[t])=>t.type===o||t.type===r?new c(h,t.data.length):v.error(`Ukuran hanya terdapat untuk tipe petik atau baris. Menemukan tipe ${t.type.description}.`))),e.define("salin",y([null],null,(e,[t])=>A(t))),e.define("tipe",y([null],r,(e,[t])=>t.type?.description?new c(r,t.type.description):new c(r,"datum")));let t=new k(u,!0,null);t.member=new s,t.member.define("acak",y([h,h],h,(e,[t,i])=>{let a=Math.abs(t.data-i.data),s=Math.random()*a+Math.min(t.data,i.data);return new c(h,s)})),t.member.define("akar2",y([h],h,(e,[t])=>new c(h,Math.sqrt(t.data)))),t.member.define("min",y([h,h],h,(e,[t,i])=>new c(h,Math.min(t.data,i.data)))),t.member.define("maks",y([h,h],h,(e,[t,i])=>new c(h,Math.max(t.data,i.data))));const i=(e,t)=>{for([e,t]=[Math.max(e,t),Math.min(e,t)];t>0;)[e,t]=[t,e%t];return e};return t.member.define("fpb",y([h,h],h,(e,[t,a])=>{let s=i(t.data,a.data);return new c(h,s)})),t.member.define("kpk",y([h,h],h,(e,[t,a])=>{let s=i(t.data,a.data);return new c(h,t.data*a*data/s)})),e.define("mtk",t),e})(),L=["rubah","kalau","namun","slagi","untuk","cetak","henti","lewat","dalam","hasil","kerja","datum","jenis","model","tetap","modul","lihat","kasus","jatuh"],U=11,$=20,R=21,P=26,_=27,B=37,C=["RUBAH","KALAU","NAMUN","SLAGI","UNTUK","CETAK","HENTI","LEWAT","DALAM","HASIL","KERJA","DATUM","JENIS","MODEL","TETAP","MODUL","LIHAT","KASUS","JATUH","EOF","ID","LITERAL","PLUS","MINUS","BINTANG","GARIS_MIRING","LPAREN","RPAREN","LEBIH","LEBIH_SAMA","KURANG","KURANG_SAMA","SAMA","SAMA_SAMA","DOT","LCURLY","RCURLY","COMMA","LSQUARE","RSQUARE","PIPA","AMPERSAN","SERU","ARROW","SERU_SAMA","MODULUS","PIPELINE","COLON","DOLLAR"];let j=class{},G=class{},K=class{},H=class{constructor(e){this.value=e}};class O{constructor(){this.globalEnvironment=N,this.location={GLOBAL:1,SLAGI:2,UNTUK:3,MESIN:4,LIHAT:5},this.MAX_STACK_SIZE=500,this.init()}init(){this.line=0,this.environment=new s(this.globalEnvironment),this.tree=null,this.state=this.location.GLOBAL,this.stack=[],this.output=[],this.objectStack=null,this.exprWillBeCalled=!1,this.pipeStack=[]}interpret(e){return this.line=0,this.output=[],this.tree=e,e.accept(this),this.output}visitLiteralExpr(e){let t=e.token;switch(this.line=t.line,typeof t.value){case"string":return new c(r,t.value);case"number":return new c(h,t.value);case"boolean":return new c(l,t.value);default:return p}}visitArrayExpr(e){let t=new c(o,[]);for(let i of e.contents){let e=i.accept(this),a=new k(e.type,!1,e.data);a.member=e.member,a.isDatum=!0,t.data.push(a)}return t}visitIndexExpr(e){let t=e.iterable.accept(this);t.type===r&&(t=new c(o,t.data.split("").map(e=>new c(r,e)))),t.type!==o&&this.error(`'${t.type.description}' bukan baris/petik, tidak bisa di-indeks`);let i=e.index.accept(this);for(i.type!==h&&this.error(`Ekspresi di dalam indeks harus bertipe angka. Menemukan ${i.type.description}`),i.data>=t.data.length&&this.error(`Indeks tidak boleh lebih besar atau sama dengan ukuran baris: ${i.data} >= ${t.data.length}`);i.data<0;)i.data+=t.data.length;return t.data[i.data]}visitLambdaExpr(e){let t=e.params.map(e=>[e[0].accept(this),e[0].tetap,e[1].lexeme]);t.length>1&&(e=>{let t=new Map;for(let i of e){if(t.has(i))return!0;t.set(i,!0)}return!1})(t.map(e=>e[2]))&&this.error("Parameter mesin tidak boleh mempunyai nama yang sama.");let i=null;e.returnType&&(i=e.returnType.accept(this));let a=new g(this.environment,e.block,t,i);return new c(m,a)}visitCallExpr(e){this.exprWillBeCalled=!0;let t=e.callable.accept(this);this.exprWillBeCalled=!1,t.type!==m&&t.type!==d&&this.error(`Hanya bisa 'memanggil' mesin atau model, malah menemukan ${t.type.description}. `),t?.data?.block||this.error("Mesin tidak terdefinisi, tidak bisa dipanggil.");let i=[];return this.objectStack&&(i=[this.objectStack],this.objectStack=null),i=[...i,...e.args.map(e=>e.accept(this))],this.callFunc(t.data,i)}callFunc(e,t){e||this.error("Mesin tidak terdefinisi, tidak bisa dipanggil."),this.stack.push(this.line),this.stack.length>this.MAX_STACK_SIZE&&this.error(`Rekursi melebihi batas: Lebih dari ${this.MAX_STACK_SIZE}`);let i=this.state;this.line=this.stack[this.stack.length-1],this.state=this.location.MESIN,t.length!==e.parameters.length&&this.error(`Jumlah argumen tidak sama dengan parameter mesin. Menemukan ${t.length}, harusnya ${e.parameters.length}.`);let a=this.line;for(let i=0;i<t.length;i++){let s=e.parameters[i][0];null!==s&&(t[i].type!==s&&(this.line=a,this.error(`Tipe argumen tidak sama dengan parameter. Menemukan ${t[i].type.description}, harusnya ${s.description}`)))}if(e.isBuiltIn)return this.stack.pop(),this.state=i,e.block(this,t);let n=this.environment,r=new s(e.closure);this.environment=r;for(let i=0;i<t.length;i++){let[a,s,n]=e.parameters[i];null===a&&(a=t[i].type);let r=new k(a,s,t[i].data);r.member=t[i].member,this.environment.define(n,r)}let h=p;for(let t of e.block.statements)try{t.accept(this)}catch(e){if(e instanceof H){h=e.value;break}if(!(e instanceof j||e instanceof K))throw e;this.error("Tidak bisa menghentikan atau melewatkan mesin. ")}return this.stack.pop(),this.state=i,this.environment=n,h}visitBinaryExpr(e){let t=e.left.accept(this),i=e.right.accept(this);this.line=e.op.line,this.nullCheck(t,i)&&this.error("Tidak bisa mengoperasikan nilai Nihil."),this.typeCheck(t,i,`Pada operasi biner ${e.op.lexeme}`);let a=this.environment.get(t.type.description);return this.operate(a,e.op.type,i,t)}visitUnaryExpr(e){let t=e.right.accept(this);this.line=e.op.line,this.nullCheck(t)&&this.error("Tidak bisa mengoperasikan nilai Nihil.");let i=this.environment.get(t.type.description);return this.operate(i,e.op.type,t)}operate(e,t,i,a){let s=C[t]+(a?"":"_UNER"),n=e.member.get(s);n||this.error(`operator ${s} tidak terdefinisi untuk Model ${i.type.description}.`);let r=null;return r=a?this.callFunc(n.data,[i,a]):this.callFunc(n.data,[i]),r}visitGroupingExpr(e){return e.expr.accept(this)}visitIdentifierExpr(e){if("$"===e.token.lexeme){if(this.line=e.token.line,!(this.pipeStack.length<=0))return this.pipeStack[this.pipeStack.length-1];this.error("$ hanya ada dalam ekspresi saluran.")}let t=this.environment.get(e.token.lexeme);return this.line=e.token.line,t||this.error(`'${e.token.lexeme}' tidak dapat ditemukan.`),t}visitMemberExpr(e){let t=this.exprWillBeCalled;this.exprWillBeCalled=!1;let i=e.main.accept(this),a=e.member.token.lexeme;if(this.line=e.member.token.line,i?.member&&i.member.has(a))return i.member.get(a);{const e=this.environment.get(i.type.description);if(e||this.error(`nama .${a} tidak ditemukan.`),e.member?.has(a)){if(t)return this.objectStack=i,e.member.get(a);this.error("akses titik . dari objek ke model harus berupa panggilan/penggunaaan mesin.")}this.error(`nama .${a} tidak ditemukan dalam tipe ${i.type.description}`)}}visitPipeLineExpr(e){let t=e.expr.accept(this);this.pipeStack.push(t);let i=e.pipeTo.accept(this);return this.pipeStack.pop(),i}visitTypeStmt(e){if(null===e.type)return null;let t=e.type.accept(this);return t.type===d&&t.symbol||this.error(`'${t.type.description}' bukan sebuah Model/Tipe Valid.`),t.symbol}visitCetakStmt(e){let t=e.expr.accept(this);this.output.push(f(this,t))}visitKerjaStmt(e){e.expr.accept(this)}visitDatumStmt(e){let t=e.type.accept(this),i=this.validName(e.name.lexeme);this.line=e.name.line;let a=new k(t,e.type.tetap),s=e.expr.accept(this);null===s.data&&(s.type=a.type),null===t?(a.isDatum=!0,a.type=s.type):this.typeCheck(a,s,`Pada pembuatan variabel '${i}'`),a.data=s.data,a.member=s.member,this.environment.define(i,a)}visitRubahStmt(e){let t=e.variable.accept(this);void 0===t.tetap&&this.error("Pe-rubah-an hanya dapat dilakukan kepada Variabel!"),t.tetap&&this.error("Variabel tetap tidak dapat di-rubah.");let i=e.value.accept(this);null===i.data&&(i.type=t.type),t.isDatum?t.type=i.type:this.typeCheck(t,i,"Pada perubahan variabel."),t.data=i.data,t.member=i.member}visitBlockStmt(e){let t=new s(this.environment);this.environment=t;try{for(let t of e.statements)t.accept(this)}catch(e){throw this.environment=t.enclosing,e}this.environment=t.enclosing}visitKalauStmt(e){let t=e.condition?.accept(this);t?.type&&t?.type!==l&&this.error(`Ekspresi dalam 'kalau' harus bertipe logis, menemukan ${t.type?t.type.description:"nihil"}`),null==t||t.data?e.thenBlock.accept(this):e.elseKalau?.accept(this)}visitHentiStmt(){if(this.state===this.location.UNTUK||this.state===this.location.SLAGI)throw new j;this.error("Tidak ada pengulangan untuk dihentikan.")}visitLewatStmt(){if(this.state===this.location.UNTUK||this.state===this.location.SLAGI)throw new K;this.error("Tidak ada pengulangan untuk dilewatkan.")}visitJatuhStmt(){if(this.state===this.location.LIHAT)throw new G;this.error("Tidak bisa jatuh di luar blok kasus.")}visitHasilStmt(e){throw 0==this.stack.length&&this.error("Tidak bisa menghasilkan diluar blok mesin."),new H(e.expr.accept(this))}visitSlagiStmt(e){const t=e=>(e.type!==l&&this.error(`Ekspresi dalam 'slagi' harus bertipe 'logis', menemukan ${e.type?e.type.description:"nihil"}`),e.data);let i=this.environment;for(;t(e.condition.accept(this));){this.environment=new s(i);try{for(let t of e.block.statements)this.state=this.location.SLAGI,t.accept(this),this.state=this.location.SLAGI}catch(e){if(e instanceof j)break;if(e instanceof K)continue;throw e}}this.environment=i,0!==this.stackNum?this.state=this.location.MESIN:this.state=this.location.GLOBAL}visitUntukStmt(e){let t=this.validName(e.varName.lexeme,!1),i=e.varType.accept(this),a=e.iterable.accept(this);a.type===r&&(a=new c(o,a.data.split("").map(e=>new c(r,e)))),a.type!==o&&this.error(`Pernyataan 'untuk' harus mengiterasi sebuah baris atau petik, bukan ${a.type.description}`);for(let n=0;n<a.data.length;n++){let r=a.data[n],h=new k(r.type,!!e.type?.tetap,r.data);null===i?h.isDatum=!0:r.type!==i&&this.error(`Tipe data tidak sama pada indeks ke-${n}: ${r.type.description} != ${i.description}.`);let l=new s(this.environment);l.define(t,h),this.environment=l;try{for(let t of e.block.statements)this.state=this.location.UNTUK,t.accept(this),this.state=this.location.UNTUK}catch(e){if(this.environment=l.enclosing,e instanceof K)continue;if(e instanceof j)break;throw e}this.environment=l.enclosing}0!==this.stackNum?this.state=this.location.MESIN:this.state=this.location.GLOBAL}visitJenisStmt(e){let t=this.validName(e.name.lexeme);this.line=e.name.line,this.environment.define(t,new S(t,e.enums))}visitLihatStmt(e){let t=e.expr.accept(this),i=this.environment.get(t?.type?.description);i?.member?.has("SAMA_SAMA")||this.error(`tipe ${i?t.type.description:"nihil"} tidak mempunyai mesin SAMA_SAMA.`);let a=i.member.get("SAMA_SAMA");const s=t=>{for(;t<e.cases.length;){try{this.state=this.location.LIHAT,e.cases[t][1].accept(this),this.state=this.location.LIHAT}catch(e){if(e instanceof G){t++;continue}throw e}break}0!==this.stackNum?this.state=this.location.MESIN:this.state=this.location.GLOBAL};for(let i=0;i<e.cases.length;i++){let n=e.cases[i];if(!n[0])return s(i);let r=n[0].accept(this);if(this.callFunc(a.data,[t,r]).data)return s(i)}}visitSimplStmt(e){for(let t of e.statements)t.accept(this)}visitModelStmt(e){let t=this.validName(e.name.lexeme);this.line=e.name.line,this.environment.define(t,new w(t,e.contents))}visitModulStmt(e){let t=this.validName(e.name.lexeme,!1);this.line=e.name.line;let i=this.environment.get(t);i?(i.type!==d&&this.error(`Modul hanya bisa _ditambahkan_ pada tipe. '${t}' bukan merupakan tipe.`),i.member.memory.size>1&&this.error(`Tipe '${t}' sudah memiliki modul sendiri, tidak bisa definisi ulang.`)):(i=new k(u,!0,null),i.member=new s,this.environment.define(t,i));let a=this.environment;i.member.enclosing=this.environment,this.environment=i.member;for(let t of e.statements)t.accept(this);[this.environment,i.member]=[a,this.environment]}typeCheck(e,t,i){e.type!==t.type&&(console.log(e,t),this.error(`Tipe data tidak sama: ${e.type.description} != ${t.type.description}. `+i))}nullCheck(...e){for(let t of e)if(null===t.data||null===t.type)return t;return!1}validName(e,t=!0){return n.some(t=>t===e)?this.error(`Nama sistem (${e}) tidak boleh didefinisi ulang.`):t&&this.environment.has(e)&&this.error(`Variabel dengan nama '${e}' sudah ada. Tidak bisa didefinisi ulang.`),e}error(e){throw new t(`Error Eksekusi => ${e}`,this.line,this.output.join("\n"))}}class D{constructor(e,t,i,a){this.type=e,this.lexeme=t,this.value=i,this.line=a}toString(){return`< [${this.line}] ${C[this.type]}, ${this.lexeme} >`}}class F{constructor(){this.init()}init(){this.text=null,this.charStart=0,this.charIndex=0,this.lineIndex=1,this.tokens=[],this.errors=[]}scanTokens(e){this.init(),this.text=e;let t=[];for(;!this.isAtEnd();){let e=this.scan();this.charStart=this.charIndex,e&&t.push(e)}return t.push(new D(19,"Akhir dokumen",null,this.lineIndex)),this.tokens=t,this.tokens}isAtEnd(){return this.charIndex>=this.text.length}advance(){this.isAtEnd()||("\n"===this.see()&&this.lineIndex++,this.charIndex++)}see(){return this.isAtEnd()?"EOF":this.text[this.charIndex]}peek(e=1){return this.isAtEnd()?null:this.text[this.charIndex+e]}isAlpha(e){return/^[a-zA-Z_]$/.test(e)}isNumeric(e){return/^[0-9]$/.test(e)}isAlphaNumeric(e){return this.isAlpha(e)||this.isNumeric(e)||"?"===e}skipWhitespaces(){for(;!this.isAtEnd()&&/\s/.test(this.see());)this.advance(),this.charStart++}parseLexeme(){return this.text.slice(this.charStart,this.charIndex)}id(){for(;!this.isAtEnd()&&this.isAlphaNumeric(this.see());)this.advance();let e=this.parseLexeme(),t=L.findIndex(t=>t===e);return-1!=t?new D(t,e,null,this.lineIndex):["benar","salah"].some(t=>t===e)?new D(R,e,"benar"===e,this.lineIndex):new D("nihil"===e?R:$,e,null,this.lineIndex)}number(){let e=!1;for(;!this.isAtEnd()&&this.isNumeric(this.see());)if(this.advance(),"."===this.see()){if(e)break;e=!0,this.advance()}let t=parseFloat(e?this.parseLexeme():this.parseLexeme()+".");return new D(R,this.parseLexeme(),t,this.lineIndex)}string(){for(this.advance();!this.isAtEnd()&&'"'!==this.see();)this.advance();this.isAtEnd()&&this.error("Petik tidak tertutup."),this.advance();let e=this.parseLexeme();return new D(R,e,e.slice(1,e.length-1),this.lineIndex)}comment(){for(;!this.isAtEnd()&&"\n"!==this.see();)this.advance(),this.charStart++;this.advance(),this.charStart++}multilineComment(){for(this.advance(),this.advance(),this.charStart=this.charStart+2;!this.isAtEnd()&&("*"!==this.see()||"/"!==this.peek());)this.advance(),this.charStart++;this.advance(),this.advance(),this.charStart=this.charStart+2}makeToken(e){return this.advance(),new D(e,this.parseLexeme(),null,this.lineIndex)}scan(){for(this.skipWhitespaces();"#"===this.see()||"/"===this.see()&&"*"===this.peek();)"#"===this.see()?this.comment():this.multilineComment(),this.skipWhitespaces();if(this.isAlpha(this.see()))return this.id();if(this.isNumeric(this.see()))return this.number();switch(this.see()){case"$":return this.makeToken(48);case":":return this.makeToken(47);case"+":return this.makeToken(22);case"-":return this.makeToken(23);case"/":return this.makeToken(25);case"*":return this.makeToken(24);case"(":return this.makeToken(P);case")":return this.makeToken(_);case".":return this.makeToken(34);case",":return this.makeToken(B);case"{":return this.makeToken(35);case"}":return this.makeToken(36);case"[":return this.makeToken(38);case"]":return this.makeToken(39);case"|":return">"===this.peek()?(this.advance(),this.makeToken(46)):this.makeToken(40);case"&":return this.makeToken(41);case"%":return this.makeToken(45);case"!":return"="===this.peek()?(this.advance(),this.makeToken(44)):this.makeToken(42);case">":return"="===this.peek()?(this.advance(),this.makeToken(29)):this.makeToken(28);case"<":return"="===this.peek()?(this.advance(),this.makeToken(31)):this.makeToken(30);case"=":return"="===this.peek()&&">"===this.peek(2)?this.makeToken(32):"="===this.peek()?(this.advance(),this.makeToken(33)):">"===this.peek()?(this.advance(),this.makeToken(43)):this.makeToken(32);case'"':return this.string()}this.isAtEnd()||this.error(`karakter tidak valid: Menemukan '${this.see()}'.`)}error(e){throw new a("Error Tulisan => "+e,this.see().line)}debugPrintTokens(e){for(let t of e)console.log(t.toString())}}class J{accept(e){return this.visit(e)}}class W extends J{constructor(e,t,i){super(),this.left=e,this.op=t,this.right=i}visit(e){return e.visitBinaryExpr(this)}}class q extends J{constructor(e,t){super(),this.op=e,this.right=t}visit(e){return e.visitUnaryExpr(this)}}class V extends J{constructor(e){super(),this.token=e}visit(e){return e.visitLiteralExpr(this)}}class Z extends J{constructor(e){super(),this.expr=e}visit(e){return e.visitGroupingExpr(this)}}class z extends J{constructor(e,t){super(),this.main=e,this.member=t}visit(e){return e.visitMemberExpr(this)}}class X extends J{constructor(e){super(),this.token=e}visit(e){return e.visitIdentifierExpr(this)}}class Q extends J{constructor(e,t,i){super(),this.params=e,this.returnType=t,this.block=i}visit(e){return e.visitLambdaExpr(this)}}class Y extends J{constructor(e,t){super(),this.callable=e,this.args=t}visit(e){return e.visitCallExpr(this)}}let ee=class extends J{constructor(e){super(),this.contents=e}visit(e){return e.visitArrayExpr(this)}};class te extends J{constructor(e,t){super(),this.iterable=e,this.index=t}visit(e){return e.visitIndexExpr(this)}}class ie extends J{constructor(e,t){super(),this.expr=e,this.pipeTo=t}visit(e){return e.visitPipeLineExpr(this)}}class ae{accept(e){return this.visit(e)}}class se extends ae{constructor(e){super(),this.expr=e}visit(e){return e.visitCetakStmt(this)}}class ne extends ae{constructor(e,t,i){super(),this.type=e,this.name=t,this.expr=i}visit(e){return e.visitDatumStmt(this)}}class re extends ae{constructor(e,t,i){super(),this.type=e,this.tetap=t,this.contents=i}visit(e){return e.visitTypeStmt(this)}}class he extends ae{constructor(e){super(),this.expr=e}visit(e){return e.visitKerjaStmt(this)}}class le extends ae{constructor(e){super(),this.statements=e}visit(e){return e.visitBlockStmt(this)}}class me extends ae{constructor(e,t,i){super(),this.condition=e,this.thenBlock=t,this.elseKalau=i}visit(e){return e.visitKalauStmt(this)}}class oe extends ae{constructor(e,t,i,a){super(),this.varType=e,this.varName=t,this.iterable=i,this.block=a}visit(e){return e.visitUntukStmt(this)}}class de extends ae{constructor(e,t){super(),this.condition=e,this.block=t}visit(e){return e.visitSlagiStmt(this)}}class ue extends ae{constructor(){super()}visit(e){return e.visitHentiStmt(this)}}class ce extends ae{constructor(){super()}visit(e){return e.visitLewatStmt(this)}}class pe extends ae{constructor(){super()}visit(e){return e.visitJatuhStmt(this)}}class ke extends ae{constructor(e,t){super(),this.variable=e,this.value=t}visit(e){return e.visitRubahStmt(this)}}class be extends ae{constructor(e){super(),this.expr=e}visit(e){return e.visitHasilStmt(this)}}class fe extends ae{constructor(e,t){super(),this.name=e,this.enums=t}visit(e){return e.visitJenisStmt(this)}}class we extends ae{constructor(e,t){super(),this.expr=e,this.cases=t}visit(e){return e.visitLihatStmt(this)}}class ve extends ae{constructor(e,t){super(),this.name=e,this.contents=t}visit(e){return e.visitModelStmt(this)}}let Se=class extends ae{constructor(e){super(),this.statements=e}visit(e){return e.visitSimplStmt(this)}};class ge extends ae{constructor(e,t){super(),this.name=e,this.statements=t}visit(e){return e.visitModulStmt(this)}}class ye{constructor(){this.init()}init(){this.tokens=[],this.tokenIndex=0,this.tree=null}parse(e){this.init(),this.tokens=e;let t=[];for(;!this.match(19);)t.push(this.statement());return this.tree=new Se(t),this.tree}see(){return this.tokens[this.tokenIndex]}peek(){return this.tokenIndex+1>=this.tokens.length?null:this.tokens[this.tokenIndex+1]}check(e){return this.tokens[this.tokenIndex].type===e}isAtEnd(){return this.tokenIndex>=this.tokens.length}match(...e){if(this.isAtEnd())return!1;for(let t of e)if(this.check(t))return this.tokenIndex++,!0;return!1}eat(e,t){this.match(e)||this.error(t)}previous(){return this.tokens[this.tokenIndex-1]}blockStmt(){if(this.match(47))return new le([this.statement()]);this.eat(35,"Mengharapkan sebuah blok.");let e=[];for(;!this.match(36);)e.push(this.statement());return new le(e)}functionCallExpr(e){let t=[];if(this.check(_));else do{let e=this.expression();t.push(e)}while(this.match(B));return this.eat(_,"Mengharapkan ')' setelah penggunaan mesin."),new Y(e,t)}lambda(){let e=[];if(this.eat(P,"Mengharapkan '(' setelah '=>' untuk deklarasi objek `mesin`."),this.match($,U)){let t=this.typeStmt();this.eat($,"Mengharapkan Nama parameter setelah deklarasi Tipe parameter dalam objek `mesin`.");let i=this.previous();for(e.push([t,i]);this.match(B);){this.match($,U)||this.error("Mengharapkan Tipe parameter setelah koma dalam objek `mesin`.");let t=this.typeStmt();this.eat($,"Mengharapkan Nama parameter setelah deklarasi Tipe parameter dalam objek `mesin`.");let i=this.previous();e.push([t,i])}}this.eat(_,"Mengharapkan ')' setelah deklarasi parameter objek `mesin`.");let t=null;this.match($,U)&&(t=this.typeStmt()),this.match(R)&&(null!==this.previous().value&&this.error("Mengharapkan Tipe Hasil yang valid."),t=null);let i=this.blockStmt();return new Q(e,t,i)}arrayExpr(){if(this.match(39))return new ee([]);let e=[];do{if(this.check(39))break;let t=this.expression();e.push(t)}while(this.match(B));return this.eat(39,"Mengharapkan ']' untuk menutup 'baris'."),new ee(e)}arrayIndex(e){let t=this.expression();return this.eat(39,"Mengharapkan ']' untuk menutup indeks."),new te(e,t)}primary(){if(this.match(P)){let e=this.expression();return this.eat(_,"Mengharapkan ')' untuk mengakhiri ekspresi kurung"),new Z(e)}return this.match(R)?new V(this.previous()):this.match($,48)?this.identifier():this.match(43)?this.lambda():this.match(38)?this.arrayExpr():void this.error("Mengharapkan Ekspresi valid.")}valuable(){let e=this.primary();for(;;)if(this.match(P))e=this.functionCallExpr(e);else if(this.match(38))e=this.arrayIndex(e);else{if(!this.match(34))break;e=this.member(e)}return e}unary(){if(this.match(22,23,42)){let e=this.previous(),t=this.unary();return new q(e,t)}return this.valuable()}identifier(){return new X(this.previous())}member(e){this.eat($,"Mengharapkan Nama variabel setelah '.'.");let t=this.identifier();return new z(e,t)}factor(){let e=this.unary();for(;this.match(45,24,25);){let t=this.previous(),i=this.unary();e=new W(e,t,i)}return e}term(){let e=this.factor();for(;this.match(22,23);){let t=this.previous(),i=this.factor();e=new W(e,t,i)}return e}equality(){let e=this.term();if(this.match(28,29,30,31,33,44)){let t=this.previous(),i=this.term();e=new W(e,t,i)}return e}andTerm(){let e=this.equality();for(;this.match(41);){let t=this.previous(),i=this.equality();e=new W(e,t,i)}return e}orTerm(){let e=this.andTerm();for(;this.match(40);){let t=this.previous(),i=this.andTerm();e=new W(e,t,i)}return e}pipeLine(){let e=this.orTerm();for(;this.match(46);){let t=this.orTerm();e=new ie(e,t)}return e}expression(){return this.pipeLine()}cetakStmt(){let e=this.expression();return new se(e)}typeStmt(){if(this.previous().type===U){let e=!1;return this.match(14)&&(e=!0),new re(null,e,null)}let e=this.identifier(),t=!1;return this.match(14)&&(t=!0),new re(e,t,null)}datumStmt(){let e=this.typeStmt();this.eat($,"Mengharapkan Nama setelah Tipe pada deklarasi variabel.");let t=this.previous();this.eat(32,"Mengharapkan '=' setelah Nama variabel.");let i=this.expression();return new ne(e,t,i)}kalauStmt(){this.check(35)&&this.error("Mengharapkan ekspresi setelah 'kalau'.");let e=this.expression(),t=this.blockStmt(),i=null;if(this.match(2))if(this.match(1))i=this.kalauStmt();else{let e=null,t=this.blockStmt();i=new me(e,t)}return new me(e,t,i)}untukStmt(){this.match($,U)||this.error("Mengharapkan Tipe variabel untuk diinisialisasi setelah 'untuk'.");let e=this.typeStmt();this.eat($,"Mengharapkan Nama variabel setelah Tipe dalam pernyataan 'untuk'.");let t=this.previous();this.eat(8,"Mengharapkan 'dalam' setelah deklarasi variabel pada pernyataan 'untuk'.");let i=this.expression(),a=this.blockStmt();return new oe(e,t,i,a)}slagiStmt(){let e=this.expression(),t=this.blockStmt();return new de(e,t)}rubahStmt(){let e=this.valuable(),t=null;this.match(22,23,24,25,41,40,45)&&(t=new W(e,this.previous(),null)),this.eat(32,"Mengharapkan '=' setelah variable yang ingin di-'rubah'.");let i=this.expression();return t&&(t.right=i,i=t),new ke(e,i)}jenisStmt(){this.eat($,"Mengharapkan Nama Jenis setelah 'jenis'.");let e=this.previous();this.eat(P,"Mengharapkan '(' setelah deklarasi Nama Jenis."),this.check(_)&&this.error("Isian Jenis tidak boleh kosong.",!1);let t=[];do{this.eat($,"Mengharapkan macam jenis dalam 'jenis'.");let e=this.previous();t.push(e)}while(this.match(B));return this.eat(_,"Mengharapkan ')' untuk mengakhiri deklarasi 'jenis'."),new fe(e,t)}lihatStmt(){let e=this.expression(),t=[];for(this.check(17)||this.error("Mengharapkan `kasus` setelah ekspresi dalam `lihat`.");this.match(17);)t.push([this.expression(),this.blockStmt()]);return this.match(2)&&t.push([null,this.blockStmt()]),new we(e,t)}modelStmt(){this.eat($,"Mengharapkan Nama Model setelah 'model'.");let e=this.previous();this.eat(P,"Mengharapkan '(' setelah Nama Model dalam 'model'."),this.check(_)&&this.error("Model tidak boleh tanpa isian.",!1);let t=[];do{this.match($,U)||this.error("Mengharapkan Tipe variabel dalam deklarasi 'Model'.");let e=this.typeStmt();this.eat($,"Mengharapkan Nama variabel dalam deklarasi 'model'.");let i=this.previous();t.push([e,i])}while(this.match(B));return this.eat(_,"Mengharapkan ')' untuk mengakhiri deklarasi 'model'."),new ve(e,t)}modulStmt(){this.eat($,"Mengharapkan Nama modul setelah deklarasi.");let e=this.previous(),t=this.blockStmt();return new ge(e,t.statements)}statement(){return this.match(5)?this.cetakStmt():this.match($,U)?this.datumStmt():this.match(10)?new he(this.expression()):this.match(1)?this.kalauStmt():this.check(35)?this.blockStmt():this.match(4)?this.untukStmt():this.match(3)?this.slagiStmt():this.match(6)?new ue:this.match(7)?new ce:this.match(18)?new pe:this.match(0)?this.rubahStmt():this.match(9)?new be(this.expression()):this.match(12)?this.jenisStmt():this.match(16)?this.lihatStmt():this.match(13)?this.modelStmt():this.match(15)?this.modulStmt():void this.error(`Pernyataan tidak bisa diawali '${this.see().lexeme}'.`,!1)}error(e,t=!0){throw new i("Error Struktur => "+e+(t?` Menemukan '${this.see().lexeme}'.`:""),this.see().line)}}class Ae{constructor(e={keepMemory:!1}){this.lexer=new F,this.parser=new ye,this.interpreter=new O,this.keepMemory=!!e?.keepMemory&&e.keepMemory}runCode(i){this.keepMemory||this.interpreter.init();const a=i.split("\n");try{let e=this.lexer.scanTokens(i),t=this.parser.parse(e);return this.interpreter.interpret(t).join("\n")}catch(i){if(i instanceof e){const e=a[i.line-1];let s=(e?`ERROR! Pada baris ke-${i.line}\n>> `+e+"\n":"")+i.message;return i instanceof t&&(s+=(i.output?"\nOutput dari kode:\n":"")+i.output),s}return`[Pada baris ke-${this.interpreter.line}] Uh Oh, ini error sistem. Mohon laporkan agar diperbaiki. [ ${i} ]`}}}export{Ae as Simpl};
package/package.json CHANGED
@@ -1,8 +1,19 @@
1
1
  {
2
2
  "name": "bahasa-simpl",
3
- "version": "1.0.11",
3
+ "version": "1.0.13",
4
4
  "description": "Simpl: Indonesian Mini Programming Language interpreter",
5
- "main": "./dist/simpl-interpreter.js",
5
+ "exports": {
6
+ ".": {
7
+ "types": "./dist/simpl.d.ts",
8
+ "import": "./dist/simpl.js"
9
+ }
10
+ },
11
+ "main": "./dist/simpl.js",
12
+ "module": "./dist/simpl.js",
13
+ "types": "./dist/simpl.js",
14
+ "files": [
15
+ "dist"
16
+ ],
6
17
  "scripts": {
7
18
  "build": "rollup -c"
8
19
  },
@@ -19,7 +30,8 @@
19
30
  },
20
31
  "homepage": "https://github.com/faeiz-ff/simpl#readme",
21
32
  "devDependencies": {
22
- "rollup": "^4.53.3"
33
+ "@rollup/plugin-terser": "^0.4.4",
34
+ "rollup": "^4.55.1"
23
35
  },
24
36
  "dependencies": {
25
37
  "bahasa-simpl": "^1.0.3"
package/rollup.config.js DELETED
@@ -1,8 +0,0 @@
1
- export default {
2
- input: "src/simpl.js",
3
- output: {
4
- file: "dist/simpl-interpreter.js",
5
- format: "es",
6
- name: "Simpl",
7
- },
8
- };