shell-lite 0.4.3__tar.gz → 0.4.4__tar.gz

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.
Files changed (34) hide show
  1. {shell_lite-0.4.3/shell_lite.egg-info → shell_lite-0.4.4}/PKG-INFO +1 -1
  2. {shell_lite-0.4.3 → shell_lite-0.4.4}/pyproject.toml +1 -1
  3. shell_lite-0.4.3/shell_lite/interpreter_final.py → shell_lite-0.4.4/shell_lite/interpreter.py +10 -4
  4. shell_lite-0.4.3/shell_lite/lexer_new.py → shell_lite-0.4.4/shell_lite/lexer.py +2 -1
  5. {shell_lite-0.4.3 → shell_lite-0.4.4}/shell_lite/main.py +5 -5
  6. shell_lite-0.4.3/shell_lite/parser_new.py → shell_lite-0.4.4/shell_lite/parser.py +17 -3
  7. {shell_lite-0.4.3 → shell_lite-0.4.4/shell_lite.egg-info}/PKG-INFO +1 -1
  8. {shell_lite-0.4.3 → shell_lite-0.4.4}/shell_lite.egg-info/SOURCES.txt +0 -10
  9. shell_lite-0.4.3/shell_lite/fix_nulls.py +0 -29
  10. shell_lite-0.4.3/shell_lite/formatter.py +0 -75
  11. shell_lite-0.4.3/shell_lite/interpreter.py +0 -1779
  12. shell_lite-0.4.3/shell_lite/interpreter_backup.py +0 -1781
  13. shell_lite-0.4.3/shell_lite/interpreter_new.py +0 -1773
  14. shell_lite-0.4.3/shell_lite/js_compiler.py +0 -220
  15. shell_lite-0.4.3/shell_lite/lexer.py +0 -245
  16. shell_lite-0.4.3/shell_lite/minimal_interpreter.py +0 -25
  17. shell_lite-0.4.3/shell_lite/parser.py +0 -2093
  18. shell_lite-0.4.3/shell_lite/patch_parser.py +0 -41
  19. {shell_lite-0.4.3 → shell_lite-0.4.4}/LICENSE +0 -0
  20. {shell_lite-0.4.3 → shell_lite-0.4.4}/README.md +0 -0
  21. {shell_lite-0.4.3 → shell_lite-0.4.4}/setup.cfg +0 -0
  22. {shell_lite-0.4.3 → shell_lite-0.4.4}/shell_lite/__init__.py +0 -0
  23. {shell_lite-0.4.3 → shell_lite-0.4.4}/shell_lite/ast_nodes.py +0 -0
  24. {shell_lite-0.4.3 → shell_lite-0.4.4}/shell_lite/cli.py +0 -0
  25. {shell_lite-0.4.3 → shell_lite-0.4.4}/shell_lite/compiler.py +0 -0
  26. {shell_lite-0.4.3 → shell_lite-0.4.4}/shell_lite/runtime.py +0 -0
  27. {shell_lite-0.4.3 → shell_lite-0.4.4}/shell_lite.egg-info/dependency_links.txt +0 -0
  28. {shell_lite-0.4.3 → shell_lite-0.4.4}/shell_lite.egg-info/entry_points.txt +0 -0
  29. {shell_lite-0.4.3 → shell_lite-0.4.4}/shell_lite.egg-info/requires.txt +0 -0
  30. {shell_lite-0.4.3 → shell_lite-0.4.4}/shell_lite.egg-info/top_level.txt +0 -0
  31. {shell_lite-0.4.3 → shell_lite-0.4.4}/tests/test_interpreter.py +0 -0
  32. {shell_lite-0.4.3 → shell_lite-0.4.4}/tests/test_lexer.py +0 -0
  33. {shell_lite-0.4.3 → shell_lite-0.4.4}/tests/test_parser.py +0 -0
  34. {shell_lite-0.4.3 → shell_lite-0.4.4}/tests/test_stdlib.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: shell-lite
3
- Version: 0.4.3
3
+ Version: 0.4.4
4
4
  Summary: A lightweight, English-like scripting language.
5
5
  Author-email: Shrey Naithani <contact@shelllite.tech>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "shell-lite"
7
- version = "0.04.3"
7
+ version = "0.04.4"
8
8
  description = "A lightweight, English-like scripting language."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
@@ -1,7 +1,7 @@
1
1
  from typing import Any, Dict, List, Callable
2
2
  from .ast_nodes import *
3
- from .lexer_new import Token, Lexer
4
- from .parser_new import Parser
3
+ from .lexer import Token, Lexer
4
+ from .parser import Parser
5
5
  import importlib
6
6
  import operator
7
7
  import re
@@ -128,7 +128,7 @@ class WebBuilder:
128
128
  pass
129
129
  class Interpreter:
130
130
  def __init__(self):
131
- print('DEBUG: VERSION 2 LOADED')
131
+ print('DEBUG: ShellLite v0.04.4')
132
132
  self.global_env = Environment()
133
133
  self.global_env.set('str', str)
134
134
  self.global_env.set('int', int)
@@ -278,6 +278,12 @@ class Interpreter:
278
278
  def _builtin_push(self, lst, item):
279
279
  lst.append(item)
280
280
  return None
281
+ def _builtin_upper(self, s):
282
+ return str(s).upper()
283
+ def _builtin_sum_range(self, start, end):
284
+ return sum(range(int(start), int(end)))
285
+ def _builtin_range_list(self, start, end):
286
+ return list(range(int(start), int(end)))
281
287
  def _init_std_modules(self):
282
288
  self.std_modules = {
283
289
  'math': {
@@ -1534,7 +1540,7 @@ class Interpreter:
1534
1540
  self.wfile.write(str(e).encode())
1535
1541
  except: pass
1536
1542
  server = HTTPServer(('0.0.0.0', port_val), ShellLiteHandler)
1537
- print(f"\n ShellLite Server v0.04.3 is running!")
1543
+ print(f"\n ShellLite Server v0.04.4 is running!")
1538
1544
  print(f" \u001b[1;36m➜\u001b[0m Local: \u001b[1;4;36mhttp://localhost:{port_val}/\u001b[0m\n")
1539
1545
  try: server.serve_forever()
1540
1546
  except KeyboardInterrupt:
@@ -165,7 +165,8 @@ class Lexer:
165
165
  'while': 'WHILE', 'until': 'UNTIL',
166
166
  'repeat': 'REPEAT', 'forever': 'FOREVER',
167
167
  'stop': 'STOP', 'skip': 'SKIP', 'exit': 'EXIT',
168
- 'each': 'FOR',
168
+ 'each': 'EACH',
169
+ 'check': 'CHECK',
169
170
  'unless': 'UNLESS', 'when': 'WHEN', 'otherwise': 'OTHERWISE',
170
171
  'then': 'THEN', 'do': 'DO',
171
172
  'print': 'PRINT', 'say': 'SAY', 'show': 'SAY',
@@ -5,9 +5,9 @@ import urllib.request
5
5
  import zipfile
6
6
  import io
7
7
  import subprocess
8
- from .lexer_new import Lexer
9
- from .parser_new import Parser
10
- from .interpreter_new import Interpreter
8
+ from .lexer import Lexer
9
+ from .parser import Parser
10
+ from .interpreter import Interpreter
11
11
  from .ast_nodes import *
12
12
  import json
13
13
  def execute_source(source: str, interpreter: Interpreter):
@@ -72,7 +72,7 @@ def run_repl():
72
72
  print("\n" + "="*40)
73
73
  print(" ShellLite REPL - English Syntax")
74
74
  print("="*40)
75
- print("Version: v0.04.3 | Made by Shrey Naithani")
75
+ print("Version: v0.04.4 | Made by Shrey Naithani")
76
76
  print("Commands: Type 'exit' to quit, 'help' for examples.")
77
77
  print("Note: Terminal commands (like 'shl install') must be run in CMD/PowerShell, not here.")
78
78
 
@@ -203,7 +203,7 @@ def install_globally():
203
203
  ps_cmd = f'$oldPath = [Environment]::GetEnvironmentVariable("Path", "User"); if ($oldPath -notlike "*ShellLite*") {{ [Environment]::SetEnvironmentVariable("Path", "$oldPath;{install_dir}", "User") }}'
204
204
  subprocess.run(["powershell", "-Command", ps_cmd], capture_output=True)
205
205
 
206
- print(f"\n[SUCCESS] ShellLite (v0.04.3) is installed!")
206
+ print(f"\n[SUCCESS] ShellLite (v0.04.4) is installed!")
207
207
  print(f"Location: {install_dir}")
208
208
  print("\nIMPORTANT STEP REQUIRED:")
209
209
  print("1. Close ALL open terminal windows (CMD, PowerShell, VS Code).")
@@ -1,5 +1,5 @@
1
1
  from typing import List, Optional
2
- from .lexer_new import Token, Lexer
2
+ from .lexer import Token, Lexer
3
3
  from .ast_nodes import *
4
4
  import re
5
5
  class Parser:
@@ -84,6 +84,16 @@ class Parser:
84
84
  input_token = self.consume()
85
85
  return self.parse_id_start_statement(passed_name_token=input_token)
86
86
  return self.parse_expression_stmt()
87
+ elif self.check('BUTTON'):
88
+ return self.parse_id_start_statement(passed_name_token=self.consume('BUTTON'))
89
+ elif self.check('COLUMN'):
90
+ return self.parse_id_start_statement(passed_name_token=self.consume('COLUMN'))
91
+ elif self.check('ROW'):
92
+ return self.parse_id_start_statement(passed_name_token=self.consume('ROW'))
93
+ elif self.check('IMAGE'):
94
+ return self.parse_id_start_statement(passed_name_token=self.consume('IMAGE'))
95
+ elif self.check('SIZE'):
96
+ return self.parse_id_start_statement(passed_name_token=self.consume('SIZE'))
87
97
  elif self.check('ID'):
88
98
  return self.parse_id_start_statement()
89
99
  elif self.check('SPAWN'):
@@ -173,6 +183,9 @@ class Parser:
173
183
  # Standalone ask statement? e.g. ask "Questions?"
174
184
  # Or ask is expression. If statement, maybe just expression statement.
175
185
  return self.parse_expression_statement()
186
+ elif self.check('CHECK'):
187
+ self.consume('CHECK')
188
+ return self.parse_if()
176
189
  elif self.check('SET'):
177
190
  return self.parse_set()
178
191
  else:
@@ -940,8 +953,8 @@ class Parser:
940
953
  return node
941
954
  def parse_start_server(self) -> Node:
942
955
  token = self.consume('START')
943
- if self.check('SERVER'):
944
- self.consume('SERVER')
956
+ if self.check('SERVER') or self.check('WEBSITE') or (self.check('ID') and self.peek().value == 'website'):
957
+ self.consume()
945
958
  port = Number(8080)
946
959
  if self.check('ON'):
947
960
  self.consume('ON')
@@ -1667,6 +1680,7 @@ class Parser:
1667
1680
  node.line = start_token.line
1668
1681
  return node
1669
1682
  start_token = self.consume('FOR')
1683
+ if self.check('EACH'): self.consume('EACH')
1670
1684
  if self.check('ID') and self.peek(1).type == 'IN':
1671
1685
  var_name = self.consume('ID').value
1672
1686
  self.consume('IN')
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: shell-lite
3
- Version: 0.4.3
3
+ Version: 0.4.4
4
4
  Summary: A lightweight, English-like scripting language.
5
5
  Author-email: Shrey Naithani <contact@shelllite.tech>
6
6
  License: MIT
@@ -5,20 +5,10 @@ shell_lite/__init__.py
5
5
  shell_lite/ast_nodes.py
6
6
  shell_lite/cli.py
7
7
  shell_lite/compiler.py
8
- shell_lite/fix_nulls.py
9
- shell_lite/formatter.py
10
8
  shell_lite/interpreter.py
11
- shell_lite/interpreter_backup.py
12
- shell_lite/interpreter_final.py
13
- shell_lite/interpreter_new.py
14
- shell_lite/js_compiler.py
15
9
  shell_lite/lexer.py
16
- shell_lite/lexer_new.py
17
10
  shell_lite/main.py
18
- shell_lite/minimal_interpreter.py
19
11
  shell_lite/parser.py
20
- shell_lite/parser_new.py
21
- shell_lite/patch_parser.py
22
12
  shell_lite/runtime.py
23
13
  shell_lite.egg-info/PKG-INFO
24
14
  shell_lite.egg-info/SOURCES.txt
@@ -1,29 +0,0 @@
1
-
2
- import sys
3
- import glob
4
- import os
5
-
6
- files = [
7
- r'c:\Users\shrey\OneDrive\Desktop\oka\shell-lite\shell_lite\parser.py',
8
- r'c:\Users\shrey\OneDrive\Desktop\oka\shell-lite\shell_lite\lexer.py',
9
- r'c:\Users\shrey\OneDrive\Desktop\oka\shell-lite\shell_lite\interpreter.py',
10
- r'c:\Users\shrey\OneDrive\Desktop\oka\shell-lite\shell_lite\main.py',
11
- r'c:\Users\shrey\OneDrive\Desktop\oka\shell-lite\shell_lite\ast_nodes.py',
12
- r'c:\Users\shrey\OneDrive\Desktop\oka\tests_suite\repro_issues.shl'
13
- ]
14
-
15
- for path in files:
16
- try:
17
- with open(path, 'rb') as f:
18
- content = f.read()
19
-
20
- if b'\x00' in content:
21
- print(f"Null bytes found in {path}! Fixing...")
22
- new_content = content.replace(b'\x00', b'')
23
- with open(path, 'wb') as f:
24
- f.write(new_content)
25
- print(f"Fixed {path}.")
26
- else:
27
- print(f"No null bytes in {path}.")
28
- except Exception as e:
29
- print(f"Error checking {path}: {e}")
@@ -1,75 +0,0 @@
1
- from typing import List
2
- from .lexer import Lexer, Token
3
- class Formatter:
4
- def __init__(self, source_code: str):
5
- self.source_code = source_code
6
- self.indent_size = 4
7
- def format(self) -> str:
8
- lexer = Lexer(self.source_code)
9
- try:
10
- tokens = lexer.tokenize()
11
- except Exception:
12
- raise
13
- formatted_lines = []
14
- current_indent = 0
15
- current_line_tokens: List[Token] = []
16
- def flush_line():
17
- nonlocal current_line_tokens
18
- if not current_line_tokens:
19
- pass
20
- line_str = self._format_line_tokens(current_line_tokens, current_indent)
21
- formatted_lines.append(line_str)
22
- current_line_tokens.clear()
23
- for token in tokens:
24
- if token.type == 'EOF':
25
- if current_line_tokens:
26
- flush_line()
27
- break
28
- elif token.type == 'INDENT':
29
- current_indent += 1
30
- elif token.type == 'DEDENT':
31
- current_indent -= 1
32
- if current_indent < 0: current_indent = 0
33
- elif token.type == 'NEWLINE':
34
- flush_line()
35
- pass
36
- else:
37
- current_line_tokens.append(token)
38
- return '\n'.join(formatted_lines)
39
- def _format_line_tokens(self, tokens: List[Token], indent_level: int) -> str:
40
- if not tokens:
41
- return ''
42
- line_parts = []
43
- line_parts.append(' ' * (indent_level * self.indent_size))
44
- for i, token in enumerate(tokens):
45
- val = token.value
46
- type = token.type
47
- if type == 'STRING':
48
- if '"' in val and "'" not in val:
49
- val = f"'{val}'"
50
- else:
51
- val = val.replace('"', '\\"')
52
- val = f'"{val}"'
53
- elif type == 'REGEX':
54
- val = f"/{val}/"
55
- if i > 0:
56
- prev = tokens[i-1]
57
- need_space = True
58
- if prev.type in ('LPAREN', 'LBRACKET', 'LBRACE', 'DOT', 'AT'):
59
- need_space = False
60
- if type in ('RPAREN', 'RBRACKET', 'RBRACE', 'DOT', 'COMMA', 'COLON'):
61
- need_space = False
62
- if type == 'LPAREN':
63
- if prev.type == 'ID':
64
- need_space = False
65
- elif prev.type in ('RPAREN', 'RBRACKET', 'STRING'):
66
- need_space = False
67
- else:
68
- pass
69
- if type == 'LBRACKET':
70
- if prev.type in ('ID', 'STRING', 'RPAREN', 'RBRACKET'):
71
- need_space = False
72
- if need_space:
73
- line_parts.append(' ')
74
- line_parts.append(val)
75
- return "".join(line_parts).rstrip()