indonesian_script 0.1.10__py3-none-any.whl

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,2 @@
1
+ # AST Node module
2
+ from .ast_nodes import *
@@ -0,0 +1,267 @@
1
+ # ast_nodes.py
2
+ from dataclasses import dataclass, field
3
+ from typing import Any, Dict, Tuple, List, Optional, Union
4
+
5
+ class Node:
6
+ """Base class for all AST nodes."""
7
+ pass
8
+
9
+ # --- Program & Blocks ---
10
+ @dataclass
11
+ class Program(Node):
12
+ statements: Optional[List['Statement']]
13
+
14
+ @dataclass
15
+ class Block(Node):
16
+ statements: Optional[List['Statement']]
17
+
18
+ # --- Statements ---
19
+ class Statement(Node):
20
+ pass
21
+
22
+ @dataclass
23
+ class VarDecl(Statement):
24
+ type_ann: 'Type'
25
+ name: str
26
+ value: Optional['Expression']
27
+
28
+ @dataclass
29
+ class FinalDecl(Statement):
30
+ type_ann: 'Type'
31
+ name: str
32
+ value: 'Expression'
33
+
34
+ @dataclass
35
+ class DefDecl(Statement):
36
+ type_ann: 'Type'
37
+ name: str
38
+
39
+ @dataclass
40
+ class AliasDecl(Statement):
41
+ alias: str
42
+ target: str
43
+
44
+ @dataclass
45
+ class Redecl(Statement):
46
+ name: str
47
+ value: 'Expression'
48
+
49
+ @dataclass
50
+ class PointerDecl(Statement):
51
+ name: str
52
+ target: str
53
+
54
+ @dataclass
55
+ class UnpointerDecl(Statement):
56
+ name: str
57
+ target: str
58
+
59
+ @dataclass
60
+ class WriteStmt(Statement):
61
+ target: str
62
+
63
+ @dataclass
64
+ class ReadStmt(Statement):
65
+ expr: 'Expression'
66
+
67
+ @dataclass
68
+ class CtrlFlow(Statement):
69
+ pass
70
+
71
+ @dataclass
72
+ class IfCtrl(CtrlFlow):
73
+ if_stmt: 'IfStmt'
74
+ elif_stmt: Optional[List['ElifStmt']]
75
+ else_stmt: Optional['ElseStmt']
76
+
77
+ @dataclass
78
+ class IfStmt(CtrlFlow):
79
+ condition: 'Expression'
80
+ body: Block
81
+
82
+ @dataclass
83
+ class ElifStmt(CtrlFlow):
84
+ condition: 'Expression'
85
+ body: Block
86
+
87
+ @dataclass
88
+ class ElseStmt(CtrlFlow):
89
+ body: Block
90
+
91
+ @dataclass
92
+ class WhileStmt(CtrlFlow):
93
+ condition: 'Expression'
94
+ body: Block
95
+
96
+ @dataclass
97
+ class ForStmt(CtrlFlow):
98
+ expr: 'ForExpr'
99
+ body: Block
100
+
101
+ @dataclass
102
+ class ForExpr(CtrlFlow):
103
+ name: str
104
+ target: List[Any]
105
+
106
+ @dataclass
107
+ class TryCtrl(CtrlFlow):
108
+ try_stmt: 'TryStmt'
109
+ catch_stmt: 'CatchStmt'
110
+ finnaly_stmt: Optional['FinnalyStmt']
111
+
112
+ @dataclass
113
+ class TryStmt(CtrlFlow):
114
+ body: Block
115
+
116
+ @dataclass
117
+ class CatchStmt(CtrlFlow):
118
+ name: str
119
+ body: Block
120
+
121
+ @dataclass
122
+ class FinallyStmt(CtrlFlow):
123
+ body: Block
124
+
125
+ # --- Expressions ---
126
+ class Expression(Node):
127
+ pass
128
+
129
+ @dataclass
130
+ class BinaryOp(Expression):
131
+ op: str # '+', '-', '*', '/', '%', '==', '!=', '>=', '>', '<=', '<', 'dan', 'atau', 'dalam', 'tidak dalam'
132
+ left: Expression
133
+ right: Expression
134
+
135
+ @dataclass
136
+ class UnaryOp(Expression):
137
+ op: str # 'tidak'
138
+ expr: Expression
139
+
140
+ @dataclass
141
+ class Literal(Expression):
142
+ value: Any
143
+
144
+ @dataclass
145
+ class Variable(Expression):
146
+ name: str
147
+ value: Any = None
148
+
149
+ @dataclass
150
+ class GetAttr(Expression):
151
+ obj: Expression
152
+ attr: str
153
+
154
+ @dataclass
155
+ class GetIndex(Expression):
156
+ obj: Expression
157
+ index: Expression
158
+
159
+ @dataclass
160
+ class CallFunc(Expression):
161
+ func: Expression
162
+ params: 'CallParameter'
163
+
164
+ @dataclass
165
+ class CallParameter(Expression):
166
+ args: List['CallArgument']
167
+
168
+ @dataclass
169
+ class CallArgument(Expression):
170
+ name: Optional[str]
171
+ value: Expression
172
+
173
+ @dataclass
174
+ class LambdaFunc(Expression):
175
+ params: 'Parameter'
176
+ expr: Expression
177
+
178
+ @dataclass
179
+ class TypeOf(Expression):
180
+ var: Variable
181
+
182
+ @dataclass
183
+ class IsStmt(Expression): # sebenarnya ini expression boolean
184
+ left: str
185
+ right: str
186
+ negated: bool = False
187
+
188
+
189
+ # --- Functions ---
190
+ class FunctionNode(Node):
191
+ "Untuk attribute dan kerangka function"
192
+ pass
193
+
194
+ @dataclass
195
+ class Function(FunctionNode):
196
+ type_ann: 'Type'
197
+ name: str
198
+ params: 'Parameter'
199
+ inner: 'Block'
200
+
201
+ @dataclass
202
+ class Parameter(FunctionNode):
203
+ args: List['Argument']
204
+
205
+ @dataclass
206
+ class Generic(FunctionNode):
207
+ args: Optional[List['Argument']]
208
+
209
+ @dataclass
210
+ class Argument(FunctionNode):
211
+ type_ann: 'Type'
212
+ name: str
213
+ value: Optional[Expression] = None
214
+
215
+ @dataclass
216
+ class Return(Expression):
217
+ expr: Expression
218
+
219
+ @dataclass
220
+ class Throw(Expression):
221
+ name: str
222
+ expr: Expression
223
+
224
+ # --- Module ---
225
+ class Module(Node):
226
+ """Dataclass terkait module"""
227
+ pass
228
+
229
+ @dataclass
230
+ class Export(Module):
231
+ exports: List['ExportArgument']
232
+
233
+ @dataclass
234
+ class ExportArgument(Module):
235
+ name: Variable
236
+ alias: Optional[str]
237
+
238
+ @dataclass
239
+ class Import(Module):
240
+ imports: List['ImportArgument']
241
+ from_path: 'PathID'
242
+
243
+ @dataclass
244
+ class ImportArgument(Module):
245
+ name: str
246
+ alias: Optional[str]
247
+
248
+ @dataclass
249
+ class PathID(Module):
250
+ path: List['PathArg']
251
+
252
+ @dataclass
253
+ class PathArg(Module):
254
+ arg: str
255
+
256
+ # --- Types ---
257
+ class Type(Node):
258
+ pass
259
+
260
+ @dataclass
261
+ class BasicType(Type):
262
+ name: str # 'teks', 'angka', dll.
263
+
264
+ @dataclass
265
+ class ArrayType(Type):
266
+ length: int # 0 untuk dinamis
267
+ element_type: Type
@@ -0,0 +1,96 @@
1
+ from decimal import Decimal
2
+
3
+ class kekosongan(object):
4
+ def __call__(cls, isi=''):
5
+ return not bool(isi)
6
+ def __repr__(self):
7
+ return '<tipe \'kekosongan\'>'
8
+
9
+ @staticmethod
10
+ def __instancecheck__(instance, /):
11
+ return isinstance(instance, kekosongan)
12
+
13
+ class kosong(kekosongan):
14
+ def __init__(self):
15
+ pass
16
+ def __repr__(self):
17
+ return 'kosong'
18
+ def __str__(self):
19
+ return ''
20
+ def __int__(self):
21
+ return 0
22
+ def __float__(self):
23
+ return 0.0
24
+ def __bool__(self):
25
+ return False
26
+ def __eq__(self, value, /):
27
+ return bool(kosong == value) or bool(None == value)
28
+ def __ne__(self, value, /):
29
+ return not self.__eq__(value)
30
+
31
+ class tipe(type):
32
+ "tipe utama"
33
+ pass
34
+
35
+ class teks(tipe, str):
36
+ "string"
37
+ pass
38
+
39
+ class desimal(tipe, Decimal):
40
+ pass
41
+
42
+ class angka(tipe, int):
43
+ pass
44
+
45
+ class kondisi(tipe):
46
+ "boolean"
47
+ __value__ = benar
48
+ def __call__(cls, value=benar):
49
+ if value:
50
+ return benar
51
+ else:
52
+ return salah
53
+
54
+ @staticmethod
55
+ def __instancecheck__(instance, /):
56
+ return isinstance(kondisi, instance)
57
+
58
+ def __repr__(self):
59
+ return "<tipe 'kondisi'>"
60
+
61
+ class salah:
62
+ def __init__(self):
63
+ pass
64
+ def __repr__(self):
65
+ return 'salah'
66
+ def __str__(self):
67
+ return 'benar'
68
+ def __int__(self):
69
+ return 0
70
+ def __float__(self):
71
+ return 0.0
72
+ def __bool__(self):
73
+ return False
74
+ def __eq__(self, value, /):
75
+ return bool(salah == value) or bool(False == value)
76
+ def __ne__(self, value, /):
77
+ return not self.__eq__(value)
78
+
79
+ class benar:
80
+ def __init__(self):
81
+ pass
82
+ def __repr__(self):
83
+ return 'benar'
84
+ def __str__(self):
85
+ return 'benar'
86
+ def __int__(self):
87
+ return 1
88
+ def __float__(self):
89
+ return 1.0
90
+ def __bool__(self):
91
+ return True
92
+ def __eq__(self, value, /):
93
+ return bool(benar == value) or bool(True == value)
94
+ def __ne__(self, value, /):
95
+ return not self.__eq__(value)
96
+
@@ -0,0 +1,28 @@
1
+
2
+ class teks(str):
3
+ def __init__(self, chrs='', /):
4
+ self._chrs = str(chrs)
5
+
6
+ def kapitalkan(self, /):
7
+ return self._chrs.capitalize()
8
+
9
+ def simpul(self, /):
10
+ return self._chrs.casefold()
11
+
12
+ def ditengah(self, panjang, pengisi=' ', /):
13
+ return self._chrs.center(panjang, pengisi)
14
+
15
+ def hitung(self, args, /):
16
+ if isinstance(args, str):
17
+ return self._chrs.count(args)
18
+ elif isinstance(args, (list, set, tuple)):
19
+ result = []
20
+ for arg in args:
21
+ if not isinstance(arg, str):
22
+ raise TypeError(f"must be str, not {type(arg).__name__}")
23
+ result.append(self._chrs(arg))
24
+ return result
25
+ else:
26
+ raise TypeError(f"must be str, not {type(arg).__name__}")
27
+
28
+ def diakhiri(self, )
@@ -0,0 +1,2 @@
1
+ # Builtins module
2
+ from .builtins import BUILTINS, TYPES, get_builtin_type
@@ -0,0 +1,140 @@
1
+ # builtins.py
2
+ from ..Exceptions.Exceptions import VariabelGalat, FinalGalat, TipeGalat
3
+ from ..AST_node.ast_nodes import BasicType
4
+ from decimal import Decimal
5
+ TYPES = {
6
+ 'teks': str,
7
+ 'angka': int,
8
+ 'desimal': Decimal,
9
+ 'boolean': bool,
10
+ 'kekosongan': type(None),
11
+ 'apapun': object,
12
+ 'daftar': list,
13
+ 'kamus': dict,
14
+ 'fungsi': callable,
15
+ 'pointer': str,
16
+ 'tipe': type,
17
+ }
18
+
19
+ BUILTINS = {
20
+ 'benar': True,
21
+ 'salah': False,
22
+ 'kosong': None,
23
+ 'enter': '\n',
24
+ 'tab': '\t',
25
+ 'format': lambda val, **kwargs: str(val).format(**kwargs),
26
+ 'tampilkan': print,
27
+ **TYPES
28
+ }
29
+
30
+ def get_builtin_type(name):
31
+ return TYPES.get(name, object)
32
+
33
+ def builtins_fungsi(self, function_name=None, /, *, type_ann=None, body=None):
34
+ """
35
+ builtins_fungsi: untuk manipulasi fungsi
36
+ - Jika hanya function_name: return apakah itu fungsi
37
+ - Jika dengan type_ann dan body: buat fungsi baru
38
+ """
39
+ if function_name is None:
40
+ # Return semua fungsi yang ada
41
+ return {name: info for name, info in self.current_scope.vars.items()
42
+ if info['type'].name == 'fungsi'}
43
+
44
+ try:
45
+ obj = self.current_scope.get(function_name)
46
+ is_func = callable(obj['value'])
47
+
48
+ if type_ann is not None and body is not None:
49
+ # Buat fungsi baru
50
+ def new_func(*args, **kwargs):
51
+ result = body(*args, **kwargs)
52
+ if type_ann != 'apapun':
53
+ expected = TYPES.get(type_ann, object)
54
+ if not isinstance(result, expected):
55
+ raise TipeGalat(f"Fungsi harus mengembalikan tipe {type_ann}")
56
+ return result
57
+
58
+ self.current_scope.declare(
59
+ function_name,
60
+ new_func,
61
+ BasicType('fungsi'),
62
+ hex(id(new_func)),
63
+ True
64
+ )
65
+ return True
66
+
67
+ return is_func
68
+
69
+ except VariabelGalat:
70
+ return False
71
+
72
+ def builtins_vars(self, name=None, /, *, value=None, type_ann=None, constant=False):
73
+ """
74
+ builtins_vars: untuk manipulasi variabel
75
+ - Tanpa argumen: return semua variabel
76
+ - Dengan name saja: return apakah variabel ada
77
+ - Dengan name dan value: buat/ubah variabel
78
+ """
79
+ if name is None:
80
+ # Return semua variabel
81
+ return {n: {
82
+ 'value': info['value'],
83
+ 'type': info['type'].name if isinstance(info['type'], BasicType) else str(info['type']),
84
+ 'constant': info['constant']
85
+ } for n, info in self.current_scope.vars.items()}
86
+
87
+ if value is None:
88
+ # Cek apakah variabel ada
89
+ ada = self.current_scope.has(name)
90
+ return ada
91
+
92
+ # Buat atau ubah variabel
93
+ try:
94
+ # Cek apakah sudah ada
95
+ obj = self.current_scope.get(name)
96
+
97
+ # Validasi konstanta
98
+ if obj['constant'] and not constant:
99
+ raise FinalGalat(f"Variabel '{name}' adalah final")
100
+
101
+ # Validasi tipe
102
+ if type_ann:
103
+ expected = TYPES.get(type_ann, object)
104
+ if not isinstance(value, expected):
105
+ raise TipeGalat(f"Nilai tidak sesuai tipe {type_ann}")
106
+ else:
107
+ type_ann = obj['type'].name if isinstance(obj['type'], BasicType) else 'apapun'
108
+
109
+ # Update
110
+ self.current_scope.set(
111
+ name,
112
+ value,
113
+ BasicType(type_ann),
114
+ hex(id(value)),
115
+ constant or obj['constant']
116
+ )
117
+
118
+ except VariabelGalat:
119
+ # Buat baru
120
+ if type_ann is None:
121
+ type_ann = 'apapun'
122
+ else:
123
+ expected = TYPES.get(type_ann, object)
124
+ if not isinstance(value, expected):
125
+ raise TipeGalat(f"Nilai tidak sesuai tipe {type_ann}")
126
+
127
+ self.current_scope.declare(
128
+ name,
129
+ value,
130
+ BasicType(type_ann),
131
+ hex(id(value)),
132
+ constant
133
+ )
134
+
135
+ return True
136
+
137
+ BUILTINS_FUNCTIONS = {
138
+ 'Fungsi': builtins_fungsi,
139
+ 'Variabel': builtins_vars
140
+ }
@@ -0,0 +1,4 @@
1
+ # Interpreter module
2
+ from .interpreter import Interpreter
3
+ from .transformer import ASTBuilder as Loader
4
+ from .AST_node import ast_nodes as AST