diff --git a/.gitattributes b/.gitattributes
index cf6aa2b..eba1110 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,7 +1,2 @@
# Auto detect text files and perform LF normalization
-* text=auto
-
-docs/** -linguist-documentation
-
-*.rst linguist-detectable
-*.ps1 linguist-detectable
+* text=auto
\ No newline at end of file
diff --git a/.github/workflows/pr-bot.yml b/.github/workflows/pr-bot.yml
new file mode 100644
index 0000000..8166a24
--- /dev/null
+++ b/.github/workflows/pr-bot.yml
@@ -0,0 +1,57 @@
+name: reStructuredPython automated PR Labeling
+on:
+ issue_comment:
+ types: [created]
+
+jobs:
+ update-labels:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Parse comment and update PR labels
+ uses: actions/github-script@v6
+ with:
+ script: |
+ const comment = context.payload.comment.body;
+ const prNumber = context.payload.issue.number;
+ const labelsToAdd = [];
+ const labelsToRemove = [];
+
+ const status = {
+ windows: false,
+ mac: false,
+ ubuntu: false
+ };
+
+ if (comment.includes("!windows-passing")) status.windows = true;
+ if (comment.includes("!windows-failing")) status.windows = false;
+ if (comment.includes("!mac-passing")) status.mac = true;
+ if (comment.includes("!mac-failing")) status.mac = false;
+ if (comment.includes("!ubuntu-passing")) status.ubuntu = true;
+ if (comment.includes("!ubuntu-failing")) status.ubuntu = false;
+
+ const allPassing = status.windows && status.mac && status.ubuntu;
+ const anyFailing = !status.windows || !status.mac || !status.ubuntu;
+
+ if (allPassing) {
+ labelsToAdd.push("awaiting merge");
+ labelsToRemove.push("DO-NOT-MERGE");
+ } else if (anyFailing) {
+ labelsToAdd.push("DO-NOT-MERGE");
+ labelsToRemove.push("awaiting merge");
+ }
+
+ await github.rest.issues.addLabels({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number: prNumber,
+ labels: labelsToAdd
+ });
+
+ for (const label of labelsToRemove) {
+ await github.rest.issues.removeLabel({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number: prNumber,
+ name: label
+ }).catch(() => {});
+ }
diff --git a/compile.bat b/compile.bat
index ae9725e..ff9c181 100644
--- a/compile.bat
+++ b/compile.bat
@@ -15,11 +15,16 @@ xcopy "%SRC_DIR%\*" "%DEST%" /E /H /C /I /exclude:exclude.txt
pushd "C:\TempBuild"
cl /LD restructuredpython/include/io.c
-for %%F in (*.dll) do xcopy "%%F" "%SRC_DIR%/restructuredpython/lib" /Y
+set /p arch="Was this run from an x64 tools prompt (y/n) >"
+if "%arch%"=="y" (
+for %%F in (io.dll) do xcopy "%%F" "%SRC_DIR%/restructuredpython/lib/windows-libs/io64.dll" /Y
+) else (
+for %%F in (io.dll) do xcopy "%%F" "%SRC_DIR%/restructuredpython/lib/windows-libs/io32.dll" /Y
+)
echo Deleting copied files
-del /Q "%DEST%\*.*"
+del /Q C:\TempBuild
popd
diff --git a/docs/source/conf.py b/docs/source/conf.py
index f1cd847..0c74aba 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -10,7 +10,7 @@
copyright = '2025, Rihaan Meher'
author = 'Rihaan Meher'
-release = '2.0.0'
+release = '2.1.0'
html_favicon = "_static/icon.png"
# -- General configuration ---------------------------------------------------
@@ -26,3 +26,84 @@
html_theme = 'furo'
html_static_path = ['_static']
+html_theme_options = {
+ "light_css_variables": {
+ "color-brand-primary": "red",
+ "color-brand-secondary": "blue",
+ "color-brand-content": "#CC3333",
+ "color-admonition-background": "orange",
+ "color-background-primary": "#e3f2fd",
+ },
+ "dark_css_variables": {
+ "color-foreground-primary": "black",
+ "color-brand-secondary": "blue",
+ "color-foreground-secondary": "#5a5c63",
+ "color-foreground-muted": "#6b6f76",
+ "color-foreground-border": "#878787",
+ "color-brand-primary": "red",
+ "color-brand-content": "#CC3333",
+ "color-admonition-background": "orange",
+ "color-background-primary": "#e3f2fd",
+ "color-background-secondary": "#f8f9fb",
+ "color-background-hover": "#efeff4ff",
+ "color-background-border": "#eeebee"
+ },
+ "announcement": '''
+
+
+
+ ''',
+}
\ No newline at end of file
diff --git a/docs/source/index.rst b/docs/source/index.rst
index 5a0c034..3992d18 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -1,7 +1,9 @@
reStructuredPython Documentation
================================
-Welcome to the reStructuredPython documentation! reStructuredPython, also known as 'rePython', is a Python variant that introduces JavaScript-like syntax for a cleaner and more readable coding experience. It compiles seamlessly into standard Python code.
+Welcome to the reStructuredPython documentation! reStructuredPython, also known as 'rePython', is a superset of python with full compatibility with existing python libaries that compiles back into standard python!
+
+https://github.com/sharktide/restructuredpython
Getting Started
---------------
@@ -31,6 +33,7 @@ Features
* **Seamless Compilation:** reStructuredPython code compiles directly into Python, ensuring compatibility with existing Python libraries and frameworks.
* **Enhanced Readability:** The syntax enhancements which include multiline comments aim to improve code readability and reduce verbosity.
* **repyconfig.toml:** Easily control the build of your projects with a repyconfig.toml
+* **Strict Types** Enhance your python projects wil strict types in functions with the builtin strict_types decorator
Documentation
-------------
diff --git a/docs/source/reference/Builtin_Decorators.rst b/docs/source/reference/Builtin_Decorators.rst
deleted file mode 100644
index c151b27..0000000
--- a/docs/source/reference/Builtin_Decorators.rst
+++ /dev/null
@@ -1,198 +0,0 @@
-Builtin Decorators
-==================
-
-This list is a complete list of decorators builtin to the reStructuredPython compiler and how to use them.
-
-How to include a decorator/function
------------------------------------
-
-To include a decorator via the ``include`` keyword, simply add it to the top of your file where you would include ``cdata`` header files.
-
-For example, to include the timer decorator, you can import it and use it like this:
-
-.. code-block:: repy
-
- include 'decorators.timer'
-
- @timer
- def myfunction() {
- time.sleep(1)
- }
-
-Or you could do this:
-
-.. code-block:: repy
-
- include 'decorators'
-
- @decorators.timer
- def myfunction() {
- pass
- }
-
-Decorators
-----------
-
-This is the list of built in decorators avalible in reStructuredPython.
-
-1. **decorators.timer**
-
-Times the execution of the decorated function and prints the output.
-
-Main use: debugging.
-
-Output format:
-
-.. code-block:: python
-
- print(f"{func.__name__} took {end_time - start_time:.2f} seconds.")
-
-How to include:
-
-.. code-block:: repy
-
- include 'decorators.timer'
-
- @timer
- def myfunction() {
- time.sleep(1)
- }
-
-Or you could do this:
-
-.. code-block:: repy
-
- include 'decorators'
-
- @decorators.timer
- def myfunction() {
- pass
- }
-
-2. **decorators.logging**
-
-Logs all arguments passed and returned by a function
-
-Main use: debugging
-
-Output format:
-
-.. code-block:: python
-
- print(f"Calling {func.__name__} with args: {args}, kwargs: {kwargs}")
- result = func(*args, **kwargs)
- print(f"{func.__name__} returned {result}")
-
-How to include:
-
-.. code-block:: repy
-
- include 'decorators.logging'
-
- @logging
- def myfunction(*args, **kwargs) {
- pass
- }
-
-Or you could do this:
-
-.. code-block:: repy
-
- include 'decorators'
-
- @decorators.logging
- def myfunction(*args, **kwargs) {
- pass
- }
-
-3. **decorators.memoization**
-
-If a function is called repeatedly with the same arguments, this decorator will not run the funciton and check in its cache if the result already exists and return that.
-
-Main use: Preformance
-
-How to include:
-
-.. code-block:: repy
-
- include 'decorators.memoization'
-
- @logging
- def myfunction(*args, **kwargs) {
- result = "something"
- return result
- }
-
-Or you could do this:
-
-.. code-block:: repy
-
- include 'decorators'
-
- @decorators.logging
- def myfunction(*args, **kwargs) {
- result = "something"
- return result
- }
-
-4. **decorators.retry**
-
-Retry a function a set amount of times if a error occurs with a set delay.
-
-Arguments:
-.. code-block:: python
- retry(retries=3, delay=1)
-
-*Defaults to 3 retries and 1 second delay.
-
-.. code-block:: repy
-
- include 'decorators.memoization'
-
- @retry(3, 1)
- def myfunction(*args, **kwargs) {
- result = "something"
- return result
- }
-
-Or you could do this:
-
-.. code-block:: repy
-
- include 'decorators'
-
- @decorators.retry(3, 1)
- def myfunction(*args, **kwargs) {
- result = "something"
- return result
- }
-
-5. **decorators.access_control
-
-Allows only certain user roles to use a function
-
-Example:
-
-.. code-block:: repy
-
- include 'decorators.access_control'
-
- @access_control(allowed_roles=['admin', 'moderator'])
- def delete_user_account(user_role, username) {
- print(f"User '{username}' has been deleted by '{user_role}'.")
-
- # Simulated role-based access
- delete_user_account('admin', 'john_doe') # This works.
- delete_user_account('guest', 'john_doe') # This raises an exception.
-
-.. code-block:: repy
-
- include 'decorators'
-
- @decorators.access_control(allowed_roles=['admin', 'moderator'])
- def delete_user_account(user_role, username) {
- print(f"User '{username}' has been deleted by '{user_role}'.")
-
- # Simulated role-based access
- delete_user_account('admin', 'john_doe') # This works.
- delete_user_account('guest', 'john_doe') # This raises an exception.
diff --git a/docs/source/reference/Builtin_Decorators/access_control.rst b/docs/source/reference/Builtin_Decorators/access_control.rst
new file mode 100644
index 0000000..148edaa
--- /dev/null
+++ b/docs/source/reference/Builtin_Decorators/access_control.rst
@@ -0,0 +1,30 @@
+decorators.access_control
+=========================
+
+Allows only certain user roles to use a function
+
+Example:
+
+.. code-block:: repy
+
+ include 'decorators.access_control'
+
+ @access_control(allowed_roles=['admin', 'moderator'])
+ def delete_user_account(user_role, username) {
+ print(f"User '{username}' has been deleted by '{user_role}'.")
+
+ # Simulated role-based access
+ delete_user_account('admin', 'john_doe') # This works.
+ delete_user_account('guest', 'john_doe') # This raises an exception.
+
+.. code-block:: repy
+
+ include 'decorators'
+
+ @decorators.access_control(allowed_roles=['admin', 'moderator'])
+ def delete_user_account(user_role, username) {
+ print(f"User '{username}' has been deleted by '{user_role}'.")
+
+ # Simulated role-based access
+ delete_user_account('admin', 'john_doe') # This works.
+ delete_user_account('guest', 'john_doe') # This raises an exception.
\ No newline at end of file
diff --git a/docs/source/reference/Builtin_Decorators/index.rst b/docs/source/reference/Builtin_Decorators/index.rst
new file mode 100644
index 0000000..ae5da47
--- /dev/null
+++ b/docs/source/reference/Builtin_Decorators/index.rst
@@ -0,0 +1,54 @@
+Builtin Decorators
+==================
+
+This list is a complete list of decorators builtin to the reStructuredPython compiler and how to use them.
+
+How to include a decorator/function
+-----------------------------------
+
+To include a decorator via the ``include`` keyword, simply add it to the top of your file where you would include ``cdata`` header files.
+
+For example, to include the timer decorator, you can import it and use it like this:
+
+.. code-block:: repy
+
+ include 'decorators.timer'
+
+ @timer
+ def myfunction() {
+ time.sleep(1)
+ }
+
+Or you could do this:
+
+.. code-block:: repy
+
+ include 'decorators'
+
+ @decorators.timer
+ def myfunction() {
+ pass
+ }
+
+Decorators
+----------
+
+This is the list of built in decorators avalible in reStructuredPython.
+
+5. **decorators.access_control
+
+Allows only certain user roles to use a function
+
+Example:
+
+
+
+.. toctree::
+ :maxdepth: 2
+
+ access_control
+ logging
+ memoization
+ retry
+ strict_types
+ timer
\ No newline at end of file
diff --git a/docs/source/reference/Builtin_Decorators/logging.rst b/docs/source/reference/Builtin_Decorators/logging.rst
new file mode 100644
index 0000000..975bfc9
--- /dev/null
+++ b/docs/source/reference/Builtin_Decorators/logging.rst
@@ -0,0 +1,36 @@
+decorators.logging
+==================
+
+Logs all arguments passed and returned by a function
+
+Main use: debugging
+
+Output format:
+
+.. code-block:: python
+
+ print(f"Calling {func.__name__} with args: {args}, kwargs: {kwargs}")
+ result = func(*args, **kwargs)
+ print(f"{func.__name__} returned {result}")
+
+How to include:
+
+.. code-block:: repy
+
+ include 'decorators.logging'
+
+ @logging
+ def myfunction(*args, **kwargs) {
+ pass
+ }
+
+Or you could do this:
+
+.. code-block:: repy
+
+ include 'decorators'
+
+ @decorators.logging
+ def myfunction(*args, **kwargs) {
+ pass
+ }
\ No newline at end of file
diff --git a/docs/source/reference/Builtin_Decorators/memoization.rst b/docs/source/reference/Builtin_Decorators/memoization.rst
new file mode 100644
index 0000000..858c999
--- /dev/null
+++ b/docs/source/reference/Builtin_Decorators/memoization.rst
@@ -0,0 +1,30 @@
+decorators.memoization
+======================
+
+If a function is called repeatedly with the same arguments, this decorator will not run the funciton and check in its cache if the result already exists and return that.
+
+Main use: Preformance
+
+How to include:
+
+.. code-block:: repy
+
+ include 'decorators.memoization'
+
+ @logging
+ def myfunction(*args, **kwargs) {
+ result = "something"
+ return result
+ }
+
+Or you could do this:
+
+.. code-block:: repy
+
+ include 'decorators'
+
+ @decorators.logging
+ def myfunction(*args, **kwargs) {
+ result = "something"
+ return result
+ }
\ No newline at end of file
diff --git a/docs/source/reference/Builtin_Decorators/retry.rst b/docs/source/reference/Builtin_Decorators/retry.rst
new file mode 100644
index 0000000..21ec888
--- /dev/null
+++ b/docs/source/reference/Builtin_Decorators/retry.rst
@@ -0,0 +1,37 @@
+decorators.retry
+================
+
+Retry a function a set amount of times if a error occurs with a set delay.
+
+Arguments:
+.. code-block:: python
+
+ retry(retries=3, delay=1)
+
+*Defaults to 3 retries and 1 second delay.
+
+.. code-block:: repy
+
+ include 'decorators.retry'
+
+ @retry(3, 1)
+ def myfunction(*args, **kwargs) {
+ result = "something"
+ if mycondition() {
+ raise SyntaxError('Retry this!')
+ return result
+ }
+
+Or you could do this:
+
+.. code-block:: repy
+
+ include 'decorators'
+
+ @decorators.retry(3, 1)
+ def myfunction(*args, **kwargs) {
+ result = "something"
+ if mycondition() {
+ raise SyntaxError('Retry this!')
+ return result
+ }
\ No newline at end of file
diff --git a/docs/source/reference/Builtin_Decorators/strict_types.rst b/docs/source/reference/Builtin_Decorators/strict_types.rst
new file mode 100644
index 0000000..3845304
--- /dev/null
+++ b/docs/source/reference/Builtin_Decorators/strict_types.rst
@@ -0,0 +1,30 @@
+decorators.strict_types
+=======================
+
+Allows strict type checking for functions
+
+Example:
+
+.. code-block:: repy
+
+ include 'decorators.strict_types'
+ @strict_types
+ def add(a: int, b: int) -> int:
+ return a + b
+
+ print(add(2, 3))
+ print(add(2, 'hi')) # raises an error
+
+Or
+
+.. code-block:: repy
+
+ include 'decorators'
+ @decorators.strict_types
+ def add(a: int, b: int) -> int:
+ return a + b
+
+ print(add(2, 3))
+ print(add(2, 'hi')) # raises an error
+
+Notes: This works with the return value, and with different types of input, even though not displayed in example.
\ No newline at end of file
diff --git a/docs/source/reference/Builtin_Decorators/timer.rst b/docs/source/reference/Builtin_Decorators/timer.rst
new file mode 100644
index 0000000..285b16a
--- /dev/null
+++ b/docs/source/reference/Builtin_Decorators/timer.rst
@@ -0,0 +1,34 @@
+decorators.timer
+================
+
+Times the execution of the decorated function and prints the output.
+
+Main use: debugging.
+
+Output format:
+
+.. code-block:: python
+
+ print(f"{func.__name__} took {end_time - start_time:.2f} seconds.")
+
+How to include:
+
+.. code-block:: repy
+
+ include 'decorators.timer'
+
+ @timer
+ def myfunction() {
+ time.sleep(1)
+ }
+
+Or you could do this:
+
+.. code-block:: repy
+
+ include 'decorators'
+
+ @decorators.timer
+ def myfunction() {
+ pass
+ }
\ No newline at end of file
diff --git a/docs/source/reference/index.rst b/docs/source/reference/index.rst
index f17384e..6ea0e65 100644
--- a/docs/source/reference/index.rst
+++ b/docs/source/reference/index.rst
@@ -4,8 +4,8 @@ Reference
The reference section provides detailed information about the built-in functions and syntax of reStructuredPython.
.. toctree::
- :maxdepth: 1
+ :maxdepth: 2
Syntax_Guide
- Builtin_Decorators
+ Builtin_Decorators/index
repyconfig.toml
diff --git a/docs/source/roadmap.rst b/docs/source/roadmap.rst
index ed94126..ffc2617 100644
--- a/docs/source/roadmap.rst
+++ b/docs/source/roadmap.rst
@@ -1,11 +1,6 @@
Roadmap
=======
-1.2.0
------
+Nothing to see here!
-Possibly add built-in functions, not only decorators. This will definetly happen, we just aren't sure if it will happen in 1.1.1
-
-Expected release dates:
-
-TBD
+The content of releases 2.2.0 2.3.0 and 2.4.0 has not been decided yet
diff --git a/pyproject.toml b/pyproject.toml
index c46b496..a070f18 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
[project]
name = "restructuredpython"
-version = "2.0.0"
-description = "A superset of Python with many new features, including multiline comments, header files, and optional curly brackets around control statements"
+version = "2.1.0"
+description = "A superset of Python with many new features, including full JS integration, multiline comments, header files, and optional curly brackets around control statements"
authors = [{name = "Rihaan Meher", email = "meherrihaan@gmail.com"}]
license = {text = "Apache-2.0"}
classifiers = [
diff --git a/restructuredpython.egg-info/PKG-INFO b/restructuredpython.egg-info/PKG-INFO
index 3497d27..b056c6e 100644
--- a/restructuredpython.egg-info/PKG-INFO
+++ b/restructuredpython.egg-info/PKG-INFO
@@ -1,7 +1,7 @@
Metadata-Version: 2.4
Name: restructuredpython
-Version: 2.0.0
-Summary: A superset of Python with many new features, including multiline comments, header files, and optional curly brackets around control statements
+Version: 2.1.0
+Summary: A superset of Python with many new features, including full JS integration, multiline comments, header files, and optional curly brackets around control statements
Author-email: Rihaan Meher
License: Apache-2.0
Classifier: Programming Language :: Python :: 3
diff --git a/restructuredpython.egg-info/SOURCES.txt b/restructuredpython.egg-info/SOURCES.txt
index cde8563..e381623 100644
--- a/restructuredpython.egg-info/SOURCES.txt
+++ b/restructuredpython.egg-info/SOURCES.txt
@@ -10,11 +10,13 @@ restructuredpython.egg-info/dependency_links.txt
restructuredpython.egg-info/entry_points.txt
restructuredpython.egg-info/top_level.txt
restructuredpython/include/io.c
-restructuredpython/lib/io.dll
+restructuredpython/lib/DO_NOT_MODIFY_THIS_DIR.txt
+restructuredpython/lib/windows-libs/io64.dll
restructuredpython/predefined/__init__.py
restructuredpython/predefined/decorators.py
restructuredpython/predefined/decorators/access_control.py
restructuredpython/predefined/decorators/logging.py
restructuredpython/predefined/decorators/memoization.py
restructuredpython/predefined/decorators/retry.py
+restructuredpython/predefined/decorators/strict_types.py
restructuredpython/predefined/decorators/timer.py
\ No newline at end of file
diff --git a/restructuredpython/predefined/decorators/strict_types.py b/restructuredpython/predefined/decorators/strict_types.py
new file mode 100644
index 0000000..7dddc46
--- /dev/null
+++ b/restructuredpython/predefined/decorators/strict_types.py
@@ -0,0 +1,34 @@
+import inspect
+from functools import wraps
+from typing import get_type_hints
+
+def strict_types(func):
+ sig = inspect.signature(func)
+ type_hints = get_type_hints(func)
+
+ @wraps(func)
+ def wrapper(*args, **kwargs):
+ bound_args = sig.bind(*args, **kwargs)
+ bound_args.apply_defaults()
+
+ # Check argument types
+ for name, value in bound_args.arguments.items():
+ expected_type = type_hints.get(name)
+ if expected_type and not isinstance(value, expected_type):
+ raise TypeError(
+ f"Argument '{name}' expected {expected_type.__name__}, got {type(value).__name__}"
+ )
+
+ # Call the function
+ result = func(*args, **kwargs)
+
+ # Check return type
+ expected_return = type_hints.get('return')
+ if expected_return and not isinstance(result, expected_return):
+ raise TypeError(
+ f"Return value expected {expected_return.__name__}, got {type(result).__name__}"
+ )
+
+ return result
+
+ return wrapper
diff --git a/restructuredpython/restructuredpython.py b/restructuredpython/restructuredpython.py
index c923034..d80f72a 100644
--- a/restructuredpython/restructuredpython.py
+++ b/restructuredpython/restructuredpython.py
@@ -17,11 +17,9 @@
if spec and spec.origin:
package_dir = os.path.dirname(spec.origin)
io_dll = os.path.join(package_dir, "lib", "windows-libs", "io64.dll")
- io32_dll = os.path.join(
- package_dir,
- "lib",
- "windows-lib",
- "io32.dll") # Adjust based on platform
+
+ io32_dll = os.path.join(package_dir, "lib", "windows-lib", "io32.dll")
+
io_so = os.path.join(package_dir, "lib", "linux-libs", "io.so")
io_dylib = os.path.join(package_dir, "lib", "macos-libs", "io.dylib")
@@ -37,7 +35,6 @@
lib = ctypes.CDLL(io_so)
-# Define argument & return types
lib.check_file_exists.argtypes = [ctypes.c_char_p]
lib.check_file_exists.restype = ctypes.c_int
@@ -63,10 +60,26 @@ def load_toml_binary(filename):
raw_data = ctypes.string_at(raw_data_ptr, size.value)
return toml.loads(raw_data.decode())
+def read_file_utf8(filename: str) -> str:
+ size = ctypes.c_size_t()
+ filename_bytes = filename.encode('utf-8')
+
+ ptr = lib.read_binary_file(filename_bytes, ctypes.byref(size))
+ if not ptr:
+ raise FileNotFoundError(f"File not found: {filename}")
+
+ raw_bytes = ctypes.string_at(ptr, size.value)
+
+ try:
+ text = raw_bytes.decode('utf-8')
+ except UnicodeDecodeError as e:
+ raise ValueError(f"File is not valid UTF-8: {e}")
+
+ return text
token_specification = [
- ('COMMENT', r'/\*.*?\*/'), # Multiline comment pattern
+ ('COMMENT', r'/\*.*?\*/'),
('IF', r'if'),
('FOR', r'for'),
('WHILE', r'while'),
@@ -79,8 +92,8 @@ def load_toml_binary(filename):
('WITH', r'with'),
('MATCH', r'match'),
('CASE', r'case'),
- ('PIPE', r'\|>'), # pipeline operator
- ('IDENT', r'[A-Za-z_][A-Za-z0-9_]*'), # variable or function name
+ ('PIPE', r'\|>'),
+ ('IDENT', r'[A-Za-z_][A-Za-z0-9_]*'),
('NUMBER', r'\d+'),
('LBRACE', r'\{'),
('RBRACE', r'\}'),
@@ -226,7 +239,7 @@ def compile_header_file(header_filename):
if lib.check_file_exists(header_filename.encode()) == 0:
raise FileNotFoundError(f"Header file {header_filename} not found.")
try:
- header_code = lib.read_file(header_filename.encode()).decode()
+ header_code = read_file_utf8(header_filename)
if not header_code.strip():
raise ValueError(f"Header file {header_filename} is empty.")
except Exception as e:
@@ -247,15 +260,14 @@ def process_includes(code, input_file):
header_code = ""
for include in includes:
- # Handle predefined headers
+ # predefined
predefined_path = os.path.join(
PREDEFINED_HEADERS_DIR, include.replace(
'.', os.sep) + '.py')
if lib.check_file_exists(predefined_path.encode()):
header_code += compile_header_file(predefined_path) + "\n"
continue
-
- # Handle user-defined headers
+ # userdefined
if not os.path.isabs(include):
include = os.path.join(
os.path.dirname(
@@ -374,7 +386,6 @@ def launch():
final_code = header_code + python_code
- # Execute the compiled code directly
try:
execute_code_temporarily(final_code)
except Exception as e: