easypy-lang 2.0.2__py3-none-any.whl → 2.1.0__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.
@@ -120,3 +120,144 @@ class _DiscordImpl:
120
120
  return {"token": token}
121
121
 
122
122
  discord_bot = _DiscordImpl()
123
+
124
+ # ==================== ML (Machine Learning - Sklearn Wrapper) ====================
125
+ class _MLImpl:
126
+ def model(self, type="classifier"):
127
+ try:
128
+ from sklearn.neighbors import KNeighborsClassifier
129
+ from sklearn.linear_model import LinearRegression
130
+
131
+ if type == "classifier":
132
+ print("🔹 Created KNN Classifier")
133
+ return _SimpleModel(KNeighborsClassifier(n_neighbors=3))
134
+ elif type == "regression":
135
+ print("🔹 Created Linear Regression Model")
136
+ return _SimpleModel(LinearRegression())
137
+ except ImportError:
138
+ print("❌ Error: 'scikit-learn' not installed.")
139
+ return None
140
+
141
+ class _SimpleModel:
142
+ def __init__(self, internal):
143
+ self.model = internal
144
+ self.trained = False
145
+
146
+ def train(self, inputs, outputs):
147
+ try:
148
+ self.model.fit(inputs, outputs)
149
+ self.trained = True
150
+ print("✅ Model trained!")
151
+ except Exception as e:
152
+ print(f"❌ Training Failed: {e}")
153
+
154
+ def predict(self, input_data):
155
+ if not self.trained:
156
+ print("⚠️ Model not trained yet!")
157
+ return None
158
+ return self.model.predict([input_data])[0]
159
+
160
+ ml = _MLImpl()
161
+
162
+ # ==================== AI (Simple NLP/Chat) ====================
163
+ class _AIImpl:
164
+ def ask(self, prompt):
165
+ # Placeholder for actual LLM or API
166
+ responses = {
167
+ "hello": "Hello there! How can I help?",
168
+ "easypy": "Easypy is the easiest language ever!",
169
+ "time": f"The time is {time.strftime('%H:%M')}"
170
+ }
171
+ for k, v in responses.items():
172
+ if k in prompt.lower():
173
+ return v
174
+ return f"User asked: '{prompt}' (AI Backend not connected)"
175
+
176
+ ai = _AIImpl()
177
+
178
+ # ==================== GAME (Turtle Graphics) ====================
179
+ class _GameImpl:
180
+ def window(self, width=600, height=600, title="Easypy Game"):
181
+ import turtle
182
+ s = turtle.Screen()
183
+ s.setup(width, height)
184
+ s.title(title)
185
+ s.bgcolor("black")
186
+ return s
187
+
188
+ def player(self, shape="turtle", color="lime"):
189
+ import turtle
190
+ p = turtle.Turtle()
191
+ p.shape(shape)
192
+ p.color(color)
193
+ p.speed(0)
194
+ return p
195
+
196
+ game = _GameImpl()
197
+
198
+ # Helper for implicit 'ml_classifier' in examples often seen
199
+ def ml_classifier(): return ml.model("classifier")
200
+
201
+ # ==================== DATA (Database & Storage) ====================
202
+ class _DBImpl:
203
+ def sqlite(self, path="database.db"):
204
+ import sqlite3
205
+ try:
206
+ conn = sqlite3.connect(path)
207
+ print(f"✓ Connected to SQLite: {path}")
208
+ return _SQLiteConn(conn)
209
+ except Exception as e:
210
+ print(f"❌ Connection Failed: {e}")
211
+ return None
212
+
213
+ def save_json(self, path, data):
214
+ try:
215
+ with open(path, 'w') as f:
216
+ json.dump(data, f, indent=4)
217
+ print(f"✓ Data saved to {path}")
218
+ except Exception as e:
219
+ print(f"❌ Save JSON Failed: {e}")
220
+
221
+ def load_json(self, path):
222
+ try:
223
+ if not os.path.exists(path):
224
+ return {}
225
+ with open(path, 'r') as f:
226
+ return json.load(f)
227
+ except Exception as e:
228
+ print(f"❌ Load JSON Failed: {e}")
229
+ return None
230
+
231
+ class _SQLiteConn:
232
+ def __init__(self, conn):
233
+ self.conn = conn
234
+ self.cursor = conn.cursor()
235
+
236
+ def execute(self, query, params=()):
237
+ try:
238
+ self.cursor.execute(query, params)
239
+ self.conn.commit()
240
+ return self.cursor.fetchall()
241
+ except Exception as e:
242
+ print(f"❌ SQL Error: {e}")
243
+ return []
244
+
245
+ def close(self):
246
+ self.conn.close()
247
+
248
+ db = _DBImpl()
249
+
250
+ # ==================== DATE & TIME ====================
251
+ class _DateImpl:
252
+ def now(self):
253
+ return time.strftime("%Y-%m-%d %H:%M:%S")
254
+
255
+ def today(self):
256
+ return time.strftime("%Y-%m-%d")
257
+
258
+ def timestamp(self):
259
+ return time.time()
260
+
261
+ datetime = _DateImpl()
262
+
263
+
easypy_lang/transpiler.py CHANGED
@@ -157,17 +157,32 @@ class EasypyTranspiler:
157
157
 
158
158
  def _clean_expression(self, text):
159
159
  """Helper to convert C-style syntax to Python"""
160
+ # Protect strings from replacement
161
+ # placeholders mapping: string_content -> placeholder
162
+ placeholders = {}
163
+ def replace_str(match):
164
+ key = f"__STR_{len(placeholders)}__"
165
+ placeholders[key] = match.group(0)
166
+ return key
167
+
168
+ # Temporarily replace strings with placeholders
169
+ # Regex for double and single quotes
170
+ text_safe = re.sub(r'("[^"]*"|\'[^\']*\')', replace_str, text)
171
+
160
172
  # Operators
161
- text = text.replace("===", "==")
162
- text = text.replace("&&", " and ")
163
- text = text.replace("||", " or ")
173
+ text_safe = text_safe.replace("===", "==")
174
+ text_safe = text_safe.replace("&&", " and ")
175
+ text_safe = text_safe.replace("||", " or ")
164
176
 
165
177
  # '!' but not '!='
166
178
  # Only replace if preceded by start-of-line, space, '(', '[', or '='
167
- # This prevents replacing '!' inside strings like "Hello!"
168
- text = re.sub(r'(?:^|(?<=[=\s(\[]))!(?!=)', 'not ', text)
179
+ text_safe = re.sub(r'(?:^|(?<=[=\s(\[]))!(?!=)', 'not ', text_safe)
180
+
181
+ # Restore strings
182
+ for key, val in placeholders.items():
183
+ text_safe = text_safe.replace(key, val)
169
184
 
170
- # 'true'/'false'/'null' are handled by modules_real.py aliases at runtime,
185
+ return text_safe
171
186
  # but replacing them here can be safer for some edge cases.
172
187
  # But let's stick to the aliases to avoid accidental string replacement.
173
188
 
@@ -255,7 +270,7 @@ class EasypyTranspiler:
255
270
  if len(parts) >= 2:
256
271
  mod = parts[1]
257
272
  # These are actually pre-loaded objects in modules_real.py
258
- preloaded_objects = ["gui", "file", "web", "system", "discord_bot", "api"]
273
+ preloaded_objects = ["gui", "file", "web", "system", "discord_bot", "api", "ml", "ai", "game", "db", "datetime"]
259
274
 
260
275
  if mod in preloaded_objects:
261
276
  return f"{indent}# Module '{mod}' is pre-loaded"
@@ -305,6 +320,18 @@ class EasypyTranspiler:
305
320
  # 3b. Async Functions
306
321
  if raw_line.startswith("async func ") and raw_line.endswith("{"):
307
322
  defn = raw_line[11:-1].strip()
323
+
324
+ # Auto-inject 'self' if inside a class
325
+ if self.context_stack and self.context_stack[-1] == 'class':
326
+ parts = defn.split("(", 1)
327
+ name = parts[0]
328
+ args = parts[1][:-1] if len(parts) > 1 else ""
329
+
330
+ if args.strip():
331
+ defn = f"{name}(self, {args})"
332
+ else:
333
+ defn = f"{name}(self)"
334
+
308
335
  self.indent_level += 1
309
336
  self.context_stack.append('func')
310
337
  return f"{indent}async def {defn}:"
@@ -369,11 +396,18 @@ class EasypyTranspiler:
369
396
  # If it is an assignment (x = {), keep the brace, do strict Python dict open.
370
397
  # Regex checks for "var =" or "word =" pattern at end of line
371
398
  # But NOT "if x == {" (comparison)
372
- # Simple heuristic: If it has "=" and not " if " or " while ", it's likely data.
399
+
400
+ # Also check for nested dictionary structure: "key": {
401
+ is_dict_entry = bool(re.search(r'[\w"\']+\s*:\s*$', clean_line)) # Ends with colon
402
+
373
403
  is_assignment = re.search(r'[^=!<>]=[^=]', clean_line) or clean_line.endswith("=")
374
404
 
405
+ # Check if current context is 'dict' (nested)
406
+ in_dict_context = self.context_stack and self.context_stack[-1] == 'dict'
407
+
375
408
  self.indent_level += 1
376
- if is_assignment:
409
+
410
+ if is_assignment or (in_dict_context and is_dict_entry):
377
411
  # It's a dict! Keep the brace.
378
412
  self.context_stack.append('dict')
379
413
  return f"{indent}{clean_line} {{"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: easypy-lang
3
- Version: 2.0.2
3
+ Version: 2.1.0
4
4
  Summary: A simple, powerful language for AI, ML, and apps - No coding experience needed!
5
5
  Home-page: https://github.com/VadikGoel/easypy-lang
6
6
  Author: Vadik Goel
@@ -66,7 +66,21 @@ docker run -it vadikgoel/easypy-lang
66
66
  - **Python Compatible**: Runs on top of the robust Python ecosystem.
67
67
  - **Zero Configuration**: No complex build tools or compilers needed.
68
68
 
69
- ## 🚀 Quick Start
69
+ ## Modules (Batteries Included)
70
+
71
+ | Module | Purpose | Example |
72
+ |--------|---------|---------|
73
+ | `gui` | Desktop Apps | `gui.create_app("My App")` |
74
+ | `ml` | Machine Learning | `ml.model("classifier")` |
75
+ | `ai` | AI Helpers | `ai.ask("Hello")` |
76
+ | `db` | Database | `db.sqlite("my.db")` |
77
+ | `game` | 2D Games | `game.window()` |
78
+ | `web` | Internet | `web.get("https://google.com")` |
79
+ | `file` | File I/O | `file.write("test.txt", "Hi")` |
80
+ | `datetime`| Date & Time | `datetime.now()` |
81
+ | `discord` | Bots | `class MyBot(discord.Client)` |
82
+
83
+ ## �🚀 Quick Start
70
84
 
71
85
  Create a file named `hello.easy` and write your first program:
72
86
 
@@ -0,0 +1,12 @@
1
+ easypy_lang/__init__.py,sha256=8RyTILsaMBOfR1mgK9hRKOvYz8lkwAUdX9HQILNR5LU,218
2
+ easypy_lang/cli.py,sha256=THGJ23wEK4sG0R-fSVGesNa0wsYp0-WIj4NK_-uWBBA,15490
3
+ easypy_lang/engine.py,sha256=mEvSKb_gcGvlb4iBtrQFFc6Pns73-Gb3HiGKWqLLTes,26608
4
+ easypy_lang/epi.py,sha256=W3FQtq__GujGofQDwBAqsbPGS-1bCyFSnriqnaP_V4A,1683
5
+ easypy_lang/modules.py,sha256=uuyrx7_GY8V64rgBPrLTksjUAB3q0V_PI3aGZySVGwQ,14403
6
+ easypy_lang/modules_real.py,sha256=hpecfv95fzr9sGaFXBn9pE4TP9qQUsbBJC2xus9htII,7909
7
+ easypy_lang/transpiler.py,sha256=UoRMVTdch4HROORP1I3DMnSdxSV3MO8kNUhhDeqTNqQ,17722
8
+ easypy_lang-2.1.0.dist-info/METADATA,sha256=x1lHmttq-DTS_LYW1IaMtXB2iyI_4w7vdQ37nXC1Qjg,3741
9
+ easypy_lang-2.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
10
+ easypy_lang-2.1.0.dist-info/entry_points.txt,sha256=mKKDQahcErG53etDO_npP9h4Oxvw4s7buWdl9R6BMX4,76
11
+ easypy_lang-2.1.0.dist-info/top_level.txt,sha256=MEflM_hPiCkdi0AemcYPHUMvUOoFQhNylmfb92x_FZw,12
12
+ easypy_lang-2.1.0.dist-info/RECORD,,
@@ -1,12 +0,0 @@
1
- easypy_lang/__init__.py,sha256=8RyTILsaMBOfR1mgK9hRKOvYz8lkwAUdX9HQILNR5LU,218
2
- easypy_lang/cli.py,sha256=THGJ23wEK4sG0R-fSVGesNa0wsYp0-WIj4NK_-uWBBA,15490
3
- easypy_lang/engine.py,sha256=mEvSKb_gcGvlb4iBtrQFFc6Pns73-Gb3HiGKWqLLTes,26608
4
- easypy_lang/epi.py,sha256=W3FQtq__GujGofQDwBAqsbPGS-1bCyFSnriqnaP_V4A,1683
5
- easypy_lang/modules.py,sha256=uuyrx7_GY8V64rgBPrLTksjUAB3q0V_PI3aGZySVGwQ,14403
6
- easypy_lang/modules_real.py,sha256=IcZMcVafF3aozmPZYp5YXPoIJzh6oV-BX-28G6TDAQA,3588
7
- easypy_lang/transpiler.py,sha256=0WJYN5PxML0y2yg7TUjDswKJ7-vvcKirxR_0Jwjj8UY,16393
8
- easypy_lang-2.0.2.dist-info/METADATA,sha256=hfNPY9gCQe5aJyZe8X-IdCi7Uk8-ZBzI-DSRMPlANuM,3180
9
- easypy_lang-2.0.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
10
- easypy_lang-2.0.2.dist-info/entry_points.txt,sha256=mKKDQahcErG53etDO_npP9h4Oxvw4s7buWdl9R6BMX4,76
11
- easypy_lang-2.0.2.dist-info/top_level.txt,sha256=MEflM_hPiCkdi0AemcYPHUMvUOoFQhNylmfb92x_FZw,12
12
- easypy_lang-2.0.2.dist-info/RECORD,,