maliklang 1.0.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.
- malik_lang/__init__.py +24 -0
- malik_lang/cli/__init__.py +7 -0
- malik_lang/cli/cli.py +196 -0
- malik_lang/cli/formatter.py +40 -0
- malik_lang/interpreter/__init__.py +7 -0
- malik_lang/interpreter/interpreter.py +718 -0
- malik_lang/lexer/__init__.py +8 -0
- malik_lang/lexer/lexer.py +376 -0
- malik_lang/lexer/token.py +121 -0
- malik_lang/parser/__init__.py +69 -0
- malik_lang/parser/ast_nodes.py +232 -0
- malik_lang/parser/parser.py +545 -0
- malik_lang/repl/__init__.py +7 -0
- malik_lang/repl/repl.py +168 -0
- malik_lang/runtime/__init__.py +47 -0
- malik_lang/runtime/environment.py +75 -0
- malik_lang/runtime/errors.py +113 -0
- malik_lang/runtime/formatter.py +25 -0
- malik_lang/runtime/values.py +118 -0
- malik_lang/stdlib/__init__.py +64 -0
- malik_lang/stdlib/builtins.py +204 -0
- malik_lang/stdlib/crypto_mod.py +108 -0
- malik_lang/stdlib/file_mod.py +112 -0
- malik_lang/stdlib/http_mod.py +163 -0
- malik_lang/stdlib/json_mod.py +30 -0
- malik_lang/stdlib/log_mod.py +103 -0
- malik_lang/stdlib/math_mod.py +109 -0
- malik_lang/stdlib/network_mod.py +133 -0
- malik_lang/stdlib/process_mod.py +78 -0
- malik_lang/stdlib/random_mod.py +47 -0
- malik_lang/stdlib/regex_mod.py +64 -0
- malik_lang/stdlib/system_mod.py +63 -0
- malik_lang/stdlib/text_mod.py +95 -0
- malik_lang/stdlib/time_mod.py +48 -0
- maliklang/__init__.py +22 -0
- maliklang-1.0.0.dist-info/METADATA +297 -0
- maliklang-1.0.0.dist-info/RECORD +41 -0
- maliklang-1.0.0.dist-info/WHEEL +5 -0
- maliklang-1.0.0.dist-info/entry_points.txt +2 -0
- maliklang-1.0.0.dist-info/licenses/LICENSE +21 -0
- maliklang-1.0.0.dist-info/top_level.txt +2 -0
malik_lang/__init__.py
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""
|
|
2
|
+
MalikLang Programming Language
|
|
3
|
+
A beginner-friendly, English-like programming language built from scratch.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
__version__ = "1.0.0"
|
|
7
|
+
__author__ = "MalikLang Contributors"
|
|
8
|
+
|
|
9
|
+
from malik_lang.lexer.lexer import Lexer
|
|
10
|
+
from malik_lang.parser.parser import Parser
|
|
11
|
+
from malik_lang.interpreter.interpreter import Interpreter
|
|
12
|
+
from malik_lang.runtime.environment import Environment
|
|
13
|
+
from malik_lang.runtime.errors import MalikError, MalikSyntaxError, MalikRuntimeError
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"Lexer",
|
|
17
|
+
"Parser",
|
|
18
|
+
"Interpreter",
|
|
19
|
+
"Environment",
|
|
20
|
+
"MalikError",
|
|
21
|
+
"MalikSyntaxError",
|
|
22
|
+
"MalikRuntimeError",
|
|
23
|
+
"__version__",
|
|
24
|
+
]
|
malik_lang/cli/cli.py
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Command-Line Interface (CLI) for MalikLang.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import sys
|
|
6
|
+
import os
|
|
7
|
+
import unittest
|
|
8
|
+
from malik_lang import __version__
|
|
9
|
+
from malik_lang.lexer import Lexer
|
|
10
|
+
from malik_lang.parser import Parser
|
|
11
|
+
from malik_lang.interpreter import Interpreter
|
|
12
|
+
from malik_lang.runtime.errors import MalikError
|
|
13
|
+
from malik_lang.cli.formatter import format_source_code
|
|
14
|
+
from malik_lang.repl import start_repl
|
|
15
|
+
|
|
16
|
+
HELP_TEXT = f"""MalikLang CLI v{__version__}
|
|
17
|
+
A beginner-friendly programming language designed for natural readability and defensive security scripting.
|
|
18
|
+
|
|
19
|
+
Usage:
|
|
20
|
+
malik run <filename.malik> [args...] Execute a MalikLang source file
|
|
21
|
+
malik <filename.malik> Execute a MalikLang source file (shortcut)
|
|
22
|
+
malik check <filename.malik> Check source file syntax without executing
|
|
23
|
+
malik repl Launch interactive REPL shell
|
|
24
|
+
malik format <filename.malik> Format and beautify source code indentation
|
|
25
|
+
malik test Run all built-in automated test suites
|
|
26
|
+
malik version Show language version and platform info
|
|
27
|
+
malik examples List available built-in example programs
|
|
28
|
+
malik help Display this help manual
|
|
29
|
+
|
|
30
|
+
Examples:
|
|
31
|
+
malik run examples/hello.malik
|
|
32
|
+
malik run examples/calculator.malik
|
|
33
|
+
malik check my_script.malik
|
|
34
|
+
malik format my_script.malik
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def run_file(filepath: str) -> int:
|
|
39
|
+
"""Executes a MalikLang source file."""
|
|
40
|
+
if not os.path.exists(filepath):
|
|
41
|
+
print(f"Error: File '{filepath}' not found.", file=sys.stderr)
|
|
42
|
+
return 1
|
|
43
|
+
|
|
44
|
+
try:
|
|
45
|
+
with open(filepath, "r", encoding="utf-8") as f:
|
|
46
|
+
source = f.read()
|
|
47
|
+
|
|
48
|
+
lexer = Lexer(source, filename=filepath)
|
|
49
|
+
tokens = lexer.tokenize()
|
|
50
|
+
parser = Parser(tokens, source_code=source, filename=filepath)
|
|
51
|
+
program = parser.parse()
|
|
52
|
+
|
|
53
|
+
interpreter = Interpreter(source_code=source, filename=filepath)
|
|
54
|
+
interpreter.interpret(program)
|
|
55
|
+
return 0
|
|
56
|
+
|
|
57
|
+
except MalikError as me:
|
|
58
|
+
print(me.format_friendly(), file=sys.stderr)
|
|
59
|
+
return 1
|
|
60
|
+
except Exception as e:
|
|
61
|
+
print(f"Internal Runtime Error: {e}", file=sys.stderr)
|
|
62
|
+
return 1
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def check_file(filepath: str) -> int:
|
|
66
|
+
"""Validates the syntax and AST structure of a MalikLang file."""
|
|
67
|
+
if not os.path.exists(filepath):
|
|
68
|
+
print(f"Error: File '{filepath}' not found.", file=sys.stderr)
|
|
69
|
+
return 1
|
|
70
|
+
|
|
71
|
+
try:
|
|
72
|
+
with open(filepath, "r", encoding="utf-8") as f:
|
|
73
|
+
source = f.read()
|
|
74
|
+
|
|
75
|
+
lexer = Lexer(source, filename=filepath)
|
|
76
|
+
tokens = lexer.tokenize()
|
|
77
|
+
parser = Parser(tokens, source_code=source, filename=filepath)
|
|
78
|
+
parser.parse()
|
|
79
|
+
print(f"Syntax check passed successfully for '{filepath}'.")
|
|
80
|
+
return 0
|
|
81
|
+
|
|
82
|
+
except MalikError as me:
|
|
83
|
+
print(me.format_friendly(), file=sys.stderr)
|
|
84
|
+
return 1
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def format_file(filepath: str) -> int:
|
|
88
|
+
"""Auto-formats a MalikLang file with standard indentation."""
|
|
89
|
+
if not os.path.exists(filepath):
|
|
90
|
+
print(f"Error: File '{filepath}' not found.", file=sys.stderr)
|
|
91
|
+
return 1
|
|
92
|
+
|
|
93
|
+
try:
|
|
94
|
+
with open(filepath, "r", encoding="utf-8") as f:
|
|
95
|
+
source = f.read()
|
|
96
|
+
|
|
97
|
+
formatted = format_source_code(source)
|
|
98
|
+
with open(filepath, "w", encoding="utf-8") as f:
|
|
99
|
+
f.write(formatted)
|
|
100
|
+
|
|
101
|
+
print(f"Successfully formatted '{filepath}'.")
|
|
102
|
+
return 0
|
|
103
|
+
except Exception as e:
|
|
104
|
+
print(f"Error formatting file: {e}", file=sys.stderr)
|
|
105
|
+
return 1
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def run_tests() -> int:
|
|
109
|
+
"""Runs the test suite."""
|
|
110
|
+
print("Running MalikLang automated test suite...\n")
|
|
111
|
+
loader = unittest.TestLoader()
|
|
112
|
+
suite = loader.discover("tests", pattern="test_*.py")
|
|
113
|
+
runner = unittest.TextTestRunner(verbosity=2)
|
|
114
|
+
result = runner.run(suite)
|
|
115
|
+
return 0 if result.wasSuccessful() else 1
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def show_examples() -> None:
|
|
119
|
+
"""Lists built-in example programs."""
|
|
120
|
+
print("\n--- Available MalikLang Example Programs ---")
|
|
121
|
+
examples = [
|
|
122
|
+
("examples/hello.malik", "Variables, input/output, and basic English commands"),
|
|
123
|
+
("examples/calculator.malik", "Interactive arithmetic calculator with loops and functions"),
|
|
124
|
+
("examples/guessing_game.malik", "Number guessing game with conditions and user interaction"),
|
|
125
|
+
("examples/todo.malik", "To-do manager demonstrating lists and dictionaries"),
|
|
126
|
+
("examples/file_reader.malik", "File I/O, writing, reading, and line processing"),
|
|
127
|
+
("examples/json_example.malik", "JSON parsing and structured serialization"),
|
|
128
|
+
("examples/network_example.malik", "Safe DNS lookup, IP verification, and port checks"),
|
|
129
|
+
("examples/http_example.malik", "Safe HTTP requests and REST API consumption"),
|
|
130
|
+
("examples/cybersecurity_defensive_example.malik", "Defensive multi-point security audit"),
|
|
131
|
+
("examples/security_log_analyzer.malik", "Web server log forensics & brute force detector"),
|
|
132
|
+
("examples/file_integrity_checker.malik", "SHA-256 baseline security monitor"),
|
|
133
|
+
]
|
|
134
|
+
for path, desc in examples:
|
|
135
|
+
print(f" {path:45} - {desc}")
|
|
136
|
+
print("\nRun any example using: malik run <example_path>\n")
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def main(args: list = None) -> int:
|
|
140
|
+
if args is None:
|
|
141
|
+
args = sys.argv[1:]
|
|
142
|
+
|
|
143
|
+
if not args:
|
|
144
|
+
start_repl()
|
|
145
|
+
return 0
|
|
146
|
+
|
|
147
|
+
command = args[0].lower()
|
|
148
|
+
|
|
149
|
+
if command in ("-v", "--version", "version"):
|
|
150
|
+
print(f"MalikLang version {__version__} (Python runtime: {sys.version.split()[0]})")
|
|
151
|
+
return 0
|
|
152
|
+
|
|
153
|
+
elif command in ("-h", "--help", "help"):
|
|
154
|
+
print(HELP_TEXT)
|
|
155
|
+
return 0
|
|
156
|
+
|
|
157
|
+
elif command in ("repl", "shell"):
|
|
158
|
+
start_repl()
|
|
159
|
+
return 0
|
|
160
|
+
|
|
161
|
+
elif command == "test":
|
|
162
|
+
return run_tests()
|
|
163
|
+
|
|
164
|
+
elif command == "examples":
|
|
165
|
+
show_examples()
|
|
166
|
+
return 0
|
|
167
|
+
|
|
168
|
+
elif command == "run":
|
|
169
|
+
if len(args) < 2:
|
|
170
|
+
print("Error: 'run' requires a target .malik file.\nUsage: malik run <file.malik>", file=sys.stderr)
|
|
171
|
+
return 1
|
|
172
|
+
return run_file(args[1])
|
|
173
|
+
|
|
174
|
+
elif command == "check":
|
|
175
|
+
if len(args) < 2:
|
|
176
|
+
print("Error: 'check' requires a target .malik file.\nUsage: malik check <file.malik>", file=sys.stderr)
|
|
177
|
+
return 1
|
|
178
|
+
return check_file(args[1])
|
|
179
|
+
|
|
180
|
+
elif command in ("format", "fmt"):
|
|
181
|
+
if len(args) < 2:
|
|
182
|
+
print("Error: 'format' requires a target .malik file.\nUsage: malik format <file.malik>", file=sys.stderr)
|
|
183
|
+
return 1
|
|
184
|
+
return format_file(args[1])
|
|
185
|
+
|
|
186
|
+
# Direct filename shortcut: `malik script.malik`
|
|
187
|
+
elif command.endswith(".malik") or command.endswith(".mlk") or os.path.exists(command):
|
|
188
|
+
return run_file(command)
|
|
189
|
+
|
|
190
|
+
else:
|
|
191
|
+
print(f"Unknown command or file '{command}'. Run 'malik help' for usage.", file=sys.stderr)
|
|
192
|
+
return 1
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
if __name__ == "__main__":
|
|
196
|
+
sys.exit(main())
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Source code formatter for MalikLang.
|
|
3
|
+
Automatically formats indentation, removes trailing whitespace, and normalizes block structures.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import List
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def format_source_code(source: str, indent_size: int = 4) -> str:
|
|
10
|
+
"""Formats MalikLang source code with consistent indentation."""
|
|
11
|
+
lines = source.strip().splitlines()
|
|
12
|
+
formatted_lines: List[str] = []
|
|
13
|
+
indent_level = 0
|
|
14
|
+
indent_str = " " * indent_size
|
|
15
|
+
|
|
16
|
+
for raw_line in lines:
|
|
17
|
+
line = raw_line.strip()
|
|
18
|
+
|
|
19
|
+
# Preserve internal empty lines
|
|
20
|
+
if not line:
|
|
21
|
+
formatted_lines.append("")
|
|
22
|
+
continue
|
|
23
|
+
|
|
24
|
+
# Check for dedenting keywords
|
|
25
|
+
# Dedent if the line starts with 'end', 'else', or 'catch'
|
|
26
|
+
if line.startswith("end") or line.startswith("else") or line.startswith("catch"):
|
|
27
|
+
indent_level = max(0, indent_level - 1)
|
|
28
|
+
|
|
29
|
+
# Apply current indentation
|
|
30
|
+
formatted_lines.append((indent_str * indent_level) + line)
|
|
31
|
+
|
|
32
|
+
# Check for indenting keywords
|
|
33
|
+
# Indent after lines starting with 'if', 'else', 'repeat', 'while', 'for', 'function', 'try', 'catch'
|
|
34
|
+
# unless it is a single-line statement with 'end'
|
|
35
|
+
if not line.endswith("end"):
|
|
36
|
+
first_word = line.split()[0] if line.split() else ""
|
|
37
|
+
if first_word in ("if", "repeat", "while", "for", "function", "try", "catch", "else"):
|
|
38
|
+
indent_level += 1
|
|
39
|
+
|
|
40
|
+
return "\n".join(formatted_lines) + "\n"
|