paramath3 3.1.3__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.
- paramath3-3.1.3/LICENSE +21 -0
- paramath3-3.1.3/PKG-INFO +145 -0
- paramath3-3.1.3/README.md +125 -0
- paramath3-3.1.3/cli.py +332 -0
- paramath3-3.1.3/colors.py +76 -0
- paramath3-3.1.3/paramath3.egg-info/PKG-INFO +145 -0
- paramath3-3.1.3/paramath3.egg-info/SOURCES.txt +12 -0
- paramath3-3.1.3/paramath3.egg-info/dependency_links.txt +1 -0
- paramath3-3.1.3/paramath3.egg-info/entry_points.txt +2 -0
- paramath3-3.1.3/paramath3.egg-info/requires.txt +4 -0
- paramath3-3.1.3/paramath3.egg-info/top_level.txt +3 -0
- paramath3-3.1.3/paramath3.py +2395 -0
- paramath3-3.1.3/pyproject.toml +33 -0
- paramath3-3.1.3/setup.cfg +4 -0
paramath3-3.1.3/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Kaemori Yozzan
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
paramath3-3.1.3/PKG-INFO
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: paramath3
|
|
3
|
+
Version: 3.1.3
|
|
4
|
+
Summary: Paramath v3 compiler
|
|
5
|
+
Author: Kaemori Yozzan
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/kaemori/paramath3
|
|
8
|
+
Project-URL: Repository, https://github.com/kaemori/paramath3
|
|
9
|
+
Keywords: dsl,math,compiler,paramath
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Requires-Python: >=3.10
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
License-File: LICENSE
|
|
16
|
+
Provides-Extra: full
|
|
17
|
+
Requires-Dist: tqdm>=4.66; extra == "full"
|
|
18
|
+
Requires-Dist: sympy>=1.12; extra == "full"
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
|
|
21
|
+
# The Paramath Programming Language
|
|
22
|
+
|
|
23
|
+
Paramath is a Domain-Specific Language (DSL) that transforms procedural math code into mathematical expressions. Paramath compiles into math expressions with operations commonly found on standard scientific calculators, allowing evaluation of logical code on mathematical hardware.
|
|
24
|
+
|
|
25
|
+
All this, powered by Python.
|
|
26
|
+
|
|
27
|
+
> **Why the name "Paramath"?**
|
|
28
|
+
> The word "paramath" comes from the portmanteau of "parenthesis" and "mathematics".
|
|
29
|
+
|
|
30
|
+
## Features
|
|
31
|
+
|
|
32
|
+
- **Infix + prefix syntax**: Arithmetic and comparators are infix; other operations are function-style prefix calls
|
|
33
|
+
- **Automatic optimization**: Simplification and duplicate subexpression extraction
|
|
34
|
+
- **Loop unrolling**: Compile-time iteration for performance
|
|
35
|
+
- **Flexible output**: Display and/or write compiled expressions to files
|
|
36
|
+
|
|
37
|
+
## Documentation
|
|
38
|
+
|
|
39
|
+
- Language reference: [paramath_syntax_guide.md](https://github.com/kaemori/paramath3/blob/main/docs/paramath_syntax_guide.md)
|
|
40
|
+
- Developer docs: [paramath_docs_developers.md](https://github.com/kaemori/paramath3/blob/main/docs/paramath_docs_developers.md)
|
|
41
|
+
|
|
42
|
+
## Installation
|
|
43
|
+
|
|
44
|
+
### Method 1 (PyPI)
|
|
45
|
+
|
|
46
|
+
#### Generic PyPI install (virtual environment)
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
python -m venv .venv
|
|
50
|
+
source .venv/bin/activate
|
|
51
|
+
pip install paramath3
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Run the compiler:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
paramath3 --version
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
#### Recommended on Arch Linux: use pipx
|
|
61
|
+
|
|
62
|
+
Arch enforces Python's externally managed environment (PEP 668), so global `pip install` may fail. Use `pipx` instead:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
sudo pacman -S --needed python-pipx
|
|
66
|
+
pipx ensurepath
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Restart your shell, then install Paramath:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
pipx install paramath3
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Method 2 (Direct Git Clone)
|
|
76
|
+
|
|
77
|
+
Clone the repository:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
git clone https://github.com/kaemori/paramath3.git
|
|
81
|
+
cd paramath3
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Run directly from source:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
python cli.py --version
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Install as a local package (recommended):
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
pip install -e .
|
|
94
|
+
paramath3 --version
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Optional dependencies:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
pip install -e .[full]
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Usage
|
|
104
|
+
|
|
105
|
+
The compiler can be run with:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
python cli.py [-h] [-V] [-o FILE] [-d] [-v] [-s] [-S] [-O] [-m] [-t] [-L FILE] [-p] [--no-color] [filepath]
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Options:
|
|
112
|
+
|
|
113
|
+
- `filepath` input Paramath file
|
|
114
|
+
- `-h, --help` show help and exit
|
|
115
|
+
- `-V, --version` print Paramath version and exit
|
|
116
|
+
- `-o, --output FILE` output file (default: `math.txt`)
|
|
117
|
+
- `-d, --debug` enable debug output
|
|
118
|
+
- `-v, --verbose` enable verbose output
|
|
119
|
+
- `-s, --suppress` suppress non-error output
|
|
120
|
+
- `-S, --silent` suppress all output
|
|
121
|
+
- `-O, --print-output` print compiled output
|
|
122
|
+
- `-m, --math-output` format output for calculators (`^`, implicit multiplication, `ANS`)
|
|
123
|
+
- `-t, --trust` allow compile-time Python eval (`:=`)
|
|
124
|
+
- `-L, --logfile FILE` write logs to file
|
|
125
|
+
- `-p, --progress` show parsing/processing progress bars
|
|
126
|
+
- `--no-color` disable colored CLI output
|
|
127
|
+
|
|
128
|
+
## Testing
|
|
129
|
+
|
|
130
|
+
Test layout:
|
|
131
|
+
|
|
132
|
+
- `paramath_test/` contains `.pm3` fixture programs
|
|
133
|
+
- `tests/` contains Python test modules (`.py`)
|
|
134
|
+
|
|
135
|
+
Run the Paramath v3 suite:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
python -m unittest tests/pm_test_suite.py -v
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
The fixture set in `paramath_test/` is a file-for-file (`1:1`) conversion of `_for_ref/paramath/paramath_tests` into Paramath v3 syntax, including `examples/number_test`.
|
|
142
|
+
|
|
143
|
+
## License
|
|
144
|
+
|
|
145
|
+
This project is licensed under the [MIT License](https://github.com/kaemori/paramath3/blob/main/LICENSE).
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# The Paramath Programming Language
|
|
2
|
+
|
|
3
|
+
Paramath is a Domain-Specific Language (DSL) that transforms procedural math code into mathematical expressions. Paramath compiles into math expressions with operations commonly found on standard scientific calculators, allowing evaluation of logical code on mathematical hardware.
|
|
4
|
+
|
|
5
|
+
All this, powered by Python.
|
|
6
|
+
|
|
7
|
+
> **Why the name "Paramath"?**
|
|
8
|
+
> The word "paramath" comes from the portmanteau of "parenthesis" and "mathematics".
|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
|
|
12
|
+
- **Infix + prefix syntax**: Arithmetic and comparators are infix; other operations are function-style prefix calls
|
|
13
|
+
- **Automatic optimization**: Simplification and duplicate subexpression extraction
|
|
14
|
+
- **Loop unrolling**: Compile-time iteration for performance
|
|
15
|
+
- **Flexible output**: Display and/or write compiled expressions to files
|
|
16
|
+
|
|
17
|
+
## Documentation
|
|
18
|
+
|
|
19
|
+
- Language reference: [paramath_syntax_guide.md](https://github.com/kaemori/paramath3/blob/main/docs/paramath_syntax_guide.md)
|
|
20
|
+
- Developer docs: [paramath_docs_developers.md](https://github.com/kaemori/paramath3/blob/main/docs/paramath_docs_developers.md)
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
### Method 1 (PyPI)
|
|
25
|
+
|
|
26
|
+
#### Generic PyPI install (virtual environment)
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
python -m venv .venv
|
|
30
|
+
source .venv/bin/activate
|
|
31
|
+
pip install paramath3
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Run the compiler:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
paramath3 --version
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
#### Recommended on Arch Linux: use pipx
|
|
41
|
+
|
|
42
|
+
Arch enforces Python's externally managed environment (PEP 668), so global `pip install` may fail. Use `pipx` instead:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
sudo pacman -S --needed python-pipx
|
|
46
|
+
pipx ensurepath
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Restart your shell, then install Paramath:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pipx install paramath3
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Method 2 (Direct Git Clone)
|
|
56
|
+
|
|
57
|
+
Clone the repository:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
git clone https://github.com/kaemori/paramath3.git
|
|
61
|
+
cd paramath3
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Run directly from source:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
python cli.py --version
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Install as a local package (recommended):
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
pip install -e .
|
|
74
|
+
paramath3 --version
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Optional dependencies:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
pip install -e .[full]
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Usage
|
|
84
|
+
|
|
85
|
+
The compiler can be run with:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
python cli.py [-h] [-V] [-o FILE] [-d] [-v] [-s] [-S] [-O] [-m] [-t] [-L FILE] [-p] [--no-color] [filepath]
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Options:
|
|
92
|
+
|
|
93
|
+
- `filepath` input Paramath file
|
|
94
|
+
- `-h, --help` show help and exit
|
|
95
|
+
- `-V, --version` print Paramath version and exit
|
|
96
|
+
- `-o, --output FILE` output file (default: `math.txt`)
|
|
97
|
+
- `-d, --debug` enable debug output
|
|
98
|
+
- `-v, --verbose` enable verbose output
|
|
99
|
+
- `-s, --suppress` suppress non-error output
|
|
100
|
+
- `-S, --silent` suppress all output
|
|
101
|
+
- `-O, --print-output` print compiled output
|
|
102
|
+
- `-m, --math-output` format output for calculators (`^`, implicit multiplication, `ANS`)
|
|
103
|
+
- `-t, --trust` allow compile-time Python eval (`:=`)
|
|
104
|
+
- `-L, --logfile FILE` write logs to file
|
|
105
|
+
- `-p, --progress` show parsing/processing progress bars
|
|
106
|
+
- `--no-color` disable colored CLI output
|
|
107
|
+
|
|
108
|
+
## Testing
|
|
109
|
+
|
|
110
|
+
Test layout:
|
|
111
|
+
|
|
112
|
+
- `paramath_test/` contains `.pm3` fixture programs
|
|
113
|
+
- `tests/` contains Python test modules (`.py`)
|
|
114
|
+
|
|
115
|
+
Run the Paramath v3 suite:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
python -m unittest tests/pm_test_suite.py -v
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
The fixture set in `paramath_test/` is a file-for-file (`1:1`) conversion of `_for_ref/paramath/paramath_tests` into Paramath v3 syntax, including `examples/number_test`.
|
|
122
|
+
|
|
123
|
+
## License
|
|
124
|
+
|
|
125
|
+
This project is licensed under the [MIT License](https://github.com/kaemori/paramath3/blob/main/LICENSE).
|
paramath3-3.1.3/cli.py
ADDED
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import time
|
|
3
|
+
|
|
4
|
+
time_start = time.time()
|
|
5
|
+
import os
|
|
6
|
+
|
|
7
|
+
import_os_time = time.time() - time_start
|
|
8
|
+
last_time = time.time()
|
|
9
|
+
import builtins
|
|
10
|
+
|
|
11
|
+
import_builtins_time = time.time() - last_time
|
|
12
|
+
last_time = time.time()
|
|
13
|
+
import argparse
|
|
14
|
+
|
|
15
|
+
import_argparse_time = time.time() - last_time
|
|
16
|
+
last_time = time.time()
|
|
17
|
+
import sys
|
|
18
|
+
|
|
19
|
+
import_sys_time = time.time() - last_time
|
|
20
|
+
last_time = time.time()
|
|
21
|
+
from colors import colors
|
|
22
|
+
|
|
23
|
+
import_colors_time = time.time() - last_time
|
|
24
|
+
last_time = time.time()
|
|
25
|
+
from paramath3 import (
|
|
26
|
+
code_to_lines,
|
|
27
|
+
parse_pm3_to_ast,
|
|
28
|
+
process_asts,
|
|
29
|
+
check_python_eval,
|
|
30
|
+
print_debug,
|
|
31
|
+
print_verbose,
|
|
32
|
+
)
|
|
33
|
+
import paramath3
|
|
34
|
+
|
|
35
|
+
import_paramath_time = time.time() - last_time
|
|
36
|
+
main_time = time.time()
|
|
37
|
+
|
|
38
|
+
PROGRAM_VERSION = "3.1.3"
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _supports_color(stream) -> bool:
|
|
42
|
+
if os.getenv("NO_COLOR") is not None:
|
|
43
|
+
return False
|
|
44
|
+
return hasattr(stream, "isatty") and stream.isatty()
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _cli_color_enabled() -> bool:
|
|
48
|
+
# allow user to force-disable without waiting for argparse
|
|
49
|
+
if "--no-color" in sys.argv:
|
|
50
|
+
return False
|
|
51
|
+
return _supports_color(sys.stdout)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
COLOR_ENABLED = _cli_color_enabled()
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def _c(code: str, text: str) -> str:
|
|
58
|
+
if not COLOR_ENABLED:
|
|
59
|
+
return text
|
|
60
|
+
return f"{code}{text}{colors.Reset.reset}"
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _title(text: str) -> str:
|
|
64
|
+
return _c(colors.BoldHighIntensity.cyan, text)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _ok(text: str) -> str:
|
|
68
|
+
return _c(colors.BoldHighIntensity.green, text)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _warn(text: str) -> str:
|
|
72
|
+
return _c(colors.BoldHighIntensity.yellow, text)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _err(text: str) -> str:
|
|
76
|
+
return _c(colors.BoldHighIntensity.red, text)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def _dim(text: str) -> str:
|
|
80
|
+
return _c(colors.HighIntensity.black, text)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def _path(text: str) -> str:
|
|
84
|
+
return _c(colors.HighIntensity.cyan, text)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def _clear(text: str) -> str:
|
|
88
|
+
return _c(colors.Reset.reset, text)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def main():
|
|
92
|
+
parser = argparse.ArgumentParser(
|
|
93
|
+
description="Paramath Compiler",
|
|
94
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
95
|
+
epilog="""
|
|
96
|
+
examples:
|
|
97
|
+
paramath3 testfile.pm
|
|
98
|
+
paramath3 testfile.pm -dv
|
|
99
|
+
paramath3 testfile.pm -sL output.log
|
|
100
|
+
paramath3 testfile.pm -dvL debug.log
|
|
101
|
+
paramath3 testfile.pm -tmo compiled.txt -O
|
|
102
|
+
paramath3 testfile.pm -mtpo compiled.txt
|
|
103
|
+
""",
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
parser.add_argument(
|
|
107
|
+
"filepath",
|
|
108
|
+
nargs="?",
|
|
109
|
+
help="Input paramath file",
|
|
110
|
+
)
|
|
111
|
+
parser.add_argument(
|
|
112
|
+
"-V",
|
|
113
|
+
"--version",
|
|
114
|
+
action="version",
|
|
115
|
+
version=f"Paramath {PROGRAM_VERSION}",
|
|
116
|
+
help="prints the Paramath version number and exits",
|
|
117
|
+
)
|
|
118
|
+
parser.add_argument(
|
|
119
|
+
"-o",
|
|
120
|
+
"--output",
|
|
121
|
+
default="math.txt",
|
|
122
|
+
metavar="FILE",
|
|
123
|
+
help="output file (default: math.txt)",
|
|
124
|
+
)
|
|
125
|
+
parser.add_argument(
|
|
126
|
+
"-d", "--debug", action="store_true", help="enable debug output"
|
|
127
|
+
)
|
|
128
|
+
parser.add_argument(
|
|
129
|
+
"-v", "--verbose", action="store_true", help="enable verbose output"
|
|
130
|
+
)
|
|
131
|
+
parser.add_argument(
|
|
132
|
+
"-s", "--suppress", action="store_true", help="suppress non-error output"
|
|
133
|
+
)
|
|
134
|
+
parser.add_argument(
|
|
135
|
+
"-S", "--silent", action="store_true", help="suppress ALL output"
|
|
136
|
+
)
|
|
137
|
+
parser.add_argument(
|
|
138
|
+
"-O",
|
|
139
|
+
"--print-output",
|
|
140
|
+
action="store_true",
|
|
141
|
+
help="print out the compiled output",
|
|
142
|
+
)
|
|
143
|
+
parser.add_argument(
|
|
144
|
+
"-m",
|
|
145
|
+
"--math-output",
|
|
146
|
+
action="store_true",
|
|
147
|
+
help="format output for calculators (use ^, implicit multiplication, capital ANS)",
|
|
148
|
+
)
|
|
149
|
+
parser.add_argument(
|
|
150
|
+
"-t",
|
|
151
|
+
"--trust",
|
|
152
|
+
action="store_true",
|
|
153
|
+
help="enable unsafe code execution (default: disabled) (WARNING: may be dangerous! use at your own risk!)",
|
|
154
|
+
)
|
|
155
|
+
parser.add_argument(
|
|
156
|
+
"-L",
|
|
157
|
+
"--logfile",
|
|
158
|
+
required=False,
|
|
159
|
+
metavar="FILE",
|
|
160
|
+
help="write logs from verbose or debug to FILE",
|
|
161
|
+
)
|
|
162
|
+
parser.add_argument(
|
|
163
|
+
"-p",
|
|
164
|
+
"--progress",
|
|
165
|
+
action="store_true",
|
|
166
|
+
help="show parsing progress using tqdm (WARNING: may slow down parsing)",
|
|
167
|
+
)
|
|
168
|
+
parser.add_argument(
|
|
169
|
+
"--no-color",
|
|
170
|
+
action="store_true",
|
|
171
|
+
help="disable colored CLI output",
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
# nts: verbose means human readable logs
|
|
175
|
+
# debug means less-human-readable, debugging-focused logs
|
|
176
|
+
args = parser.parse_args()
|
|
177
|
+
verbose = args.verbose
|
|
178
|
+
debug = args.debug
|
|
179
|
+
logfile = args.logfile
|
|
180
|
+
trust = args.trust
|
|
181
|
+
progress = args.progress
|
|
182
|
+
math_output = args.math_output
|
|
183
|
+
output_file = args.output
|
|
184
|
+
print_output = args.print_output
|
|
185
|
+
input_file = args.filepath
|
|
186
|
+
|
|
187
|
+
old_print = None
|
|
188
|
+
if args.suppress or args.silent:
|
|
189
|
+
# just monkeypatch print to do nothing
|
|
190
|
+
old_print = builtins.print
|
|
191
|
+
if args.silent:
|
|
192
|
+
old_print = lambda *a, **k: None
|
|
193
|
+
builtins.print = lambda *a, **k: None
|
|
194
|
+
|
|
195
|
+
print(_title(f"Paramath v{PROGRAM_VERSION}") + "\n")
|
|
196
|
+
|
|
197
|
+
global COLOR_ENABLED
|
|
198
|
+
if args.no_color:
|
|
199
|
+
COLOR_ENABLED = False
|
|
200
|
+
|
|
201
|
+
if args.filepath is None:
|
|
202
|
+
parser.print_help()
|
|
203
|
+
return
|
|
204
|
+
|
|
205
|
+
if progress and (debug or verbose):
|
|
206
|
+
raise ValueError("Progress bar cannot be used with verbose or debug modes")
|
|
207
|
+
|
|
208
|
+
if verbose:
|
|
209
|
+
paramath3.VERBOSE = True
|
|
210
|
+
print_verbose("verbose logging enabled")
|
|
211
|
+
|
|
212
|
+
if debug:
|
|
213
|
+
paramath3.DEBUG = True
|
|
214
|
+
print_debug("debug logging enabled")
|
|
215
|
+
|
|
216
|
+
if logfile:
|
|
217
|
+
paramath3.LOGFILE = logfile
|
|
218
|
+
print_verbose(f'Logging to file: "{logfile}"')
|
|
219
|
+
with open(logfile, "w") as f:
|
|
220
|
+
f.write(
|
|
221
|
+
f"Paramath v{PROGRAM_VERSION} Logfile (at {time.strftime('%Y-%m-%d %H:%M:%S')})\n\n"
|
|
222
|
+
)
|
|
223
|
+
print_debug(f'Logfile "{logfile}" initialized.')
|
|
224
|
+
|
|
225
|
+
print_debug(
|
|
226
|
+
"argv/options: "
|
|
227
|
+
+ str(
|
|
228
|
+
{
|
|
229
|
+
"input": input_file,
|
|
230
|
+
"output": output_file,
|
|
231
|
+
"progress": progress,
|
|
232
|
+
"trust": trust,
|
|
233
|
+
"math_output": math_output,
|
|
234
|
+
"print_output": print_output,
|
|
235
|
+
"verbose": verbose,
|
|
236
|
+
"debug": debug,
|
|
237
|
+
"logfile": logfile,
|
|
238
|
+
}
|
|
239
|
+
)
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
print_debug(f"Import os time: {import_os_time*1000:.6f}ms")
|
|
243
|
+
print_debug(f"Import builtins time: {import_builtins_time*1000:.6f}ms")
|
|
244
|
+
print_debug(f"Import argparse time: {import_argparse_time*1000:.6f}ms")
|
|
245
|
+
print_debug(f"Import sys time: {import_sys_time*1000:.6f}ms")
|
|
246
|
+
print_debug(f"Import colors time: {import_colors_time*1000:.6f}ms")
|
|
247
|
+
print_debug(f"Import paramath3 time: {import_paramath_time*1000:.6f}ms")
|
|
248
|
+
print_debug(f"Init finished: {(time.time() - time_start)*1000:.6f}ms")
|
|
249
|
+
|
|
250
|
+
try:
|
|
251
|
+
with open(input_file) as f:
|
|
252
|
+
code = code_to_lines(f.readlines())
|
|
253
|
+
print_verbose(f"loaded script: {len(code)} non-empty lines from '{input_file}'")
|
|
254
|
+
print_debug(f"script content: {code}")
|
|
255
|
+
|
|
256
|
+
if not trust:
|
|
257
|
+
print(
|
|
258
|
+
_warn("Running as untrusted.") + " " + _dim("No code will be executed.")
|
|
259
|
+
)
|
|
260
|
+
python_eval = check_python_eval(code)
|
|
261
|
+
if python_eval:
|
|
262
|
+
if old_print is not None:
|
|
263
|
+
builtins.print = old_print
|
|
264
|
+
|
|
265
|
+
print(_err("The following Python code was found in the script:"))
|
|
266
|
+
for line_no, line in python_eval:
|
|
267
|
+
print(_err(f"Line {line_no}:") + f' "{line}"')
|
|
268
|
+
print(
|
|
269
|
+
_err("Aborting due to untrusted code execution.")
|
|
270
|
+
+ " "
|
|
271
|
+
+ _dim("Review the code, THEN run with -t to trust.")
|
|
272
|
+
)
|
|
273
|
+
sys.exit(1)
|
|
274
|
+
|
|
275
|
+
print("")
|
|
276
|
+
|
|
277
|
+
asts = parse_pm3_to_ast(code, progress=progress)
|
|
278
|
+
print_verbose(f"parsed to ASTs: {len(asts)} outputs")
|
|
279
|
+
outputs = process_asts(asts, progress=progress)
|
|
280
|
+
print_verbose(f"compiled outputs: {len(outputs)} expressions")
|
|
281
|
+
|
|
282
|
+
with open(output_file, "w", encoding="utf-8") as f:
|
|
283
|
+
for output, expr in outputs:
|
|
284
|
+
if math_output:
|
|
285
|
+
output = (
|
|
286
|
+
output.replace("**", "^")
|
|
287
|
+
.replace("*", "")
|
|
288
|
+
.replace("ans", "ANS")
|
|
289
|
+
.replace("pi", "π")
|
|
290
|
+
.replace("e", "ℯ")
|
|
291
|
+
)
|
|
292
|
+
|
|
293
|
+
f.write(f"to {output}:\n")
|
|
294
|
+
f.write(expr + "\n")
|
|
295
|
+
if print_output:
|
|
296
|
+
print(f"to {output}:")
|
|
297
|
+
print(expr)
|
|
298
|
+
|
|
299
|
+
print(_ok("=== Compilation successful! ==="))
|
|
300
|
+
print(_dim("Compiled in") + _ok(f" {(time.time() - main_time):.6f}s!"))
|
|
301
|
+
print(_dim("Generated ") + _clear(f"{len(outputs)} outputs"))
|
|
302
|
+
print(_dim("Output written to ") + _path(f'"{output_file}"'))
|
|
303
|
+
|
|
304
|
+
except FileNotFoundError:
|
|
305
|
+
if old_print is not None:
|
|
306
|
+
builtins.print = old_print
|
|
307
|
+
print(_err("=== Compilation failed! ==="))
|
|
308
|
+
print(
|
|
309
|
+
_err("Error:")
|
|
310
|
+
+ " "
|
|
311
|
+
+ _dim("Input file ")
|
|
312
|
+
+ _path(f'"{input_file}"')
|
|
313
|
+
+ _dim(" not found!")
|
|
314
|
+
)
|
|
315
|
+
|
|
316
|
+
except Exception as e:
|
|
317
|
+
import traceback
|
|
318
|
+
|
|
319
|
+
if old_print is not None:
|
|
320
|
+
builtins.print = old_print
|
|
321
|
+
print(_err("=== Compilation failed! ==="))
|
|
322
|
+
print(_err("Error:") + " " + str(e))
|
|
323
|
+
if debug:
|
|
324
|
+
print(
|
|
325
|
+
_dim(
|
|
326
|
+
f"If this is an error in the compiler,\n{"".join(traceback.format_exception(e)[1:])}."
|
|
327
|
+
)
|
|
328
|
+
)
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
if __name__ == "__main__":
|
|
332
|
+
main()
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
class Colors:
|
|
2
|
+
class Regular:
|
|
3
|
+
black = "\033[0;30m"
|
|
4
|
+
red = "\033[0;31m"
|
|
5
|
+
green = "\033[0;32m"
|
|
6
|
+
yellow = "\033[0;33m"
|
|
7
|
+
blue = "\033[0;34m"
|
|
8
|
+
purple = "\033[0;35m"
|
|
9
|
+
cyan = "\033[0;36m"
|
|
10
|
+
white = "\033[0;37m"
|
|
11
|
+
|
|
12
|
+
class Bold:
|
|
13
|
+
black = "\033[1;30m"
|
|
14
|
+
red = "\033[1;31m"
|
|
15
|
+
green = "\033[1;32m"
|
|
16
|
+
yellow = "\033[1;33m"
|
|
17
|
+
blue = "\033[1;34m"
|
|
18
|
+
purple = "\033[1;35m"
|
|
19
|
+
cyan = "\033[1;36m"
|
|
20
|
+
white = "\033[1;37m"
|
|
21
|
+
|
|
22
|
+
class Underline:
|
|
23
|
+
black = "\033[4;30m"
|
|
24
|
+
red = "\033[4;31m"
|
|
25
|
+
green = "\033[4;32m"
|
|
26
|
+
yellow = "\033[4;33m"
|
|
27
|
+
blue = "\033[4;34m"
|
|
28
|
+
purple = "\033[4;35m"
|
|
29
|
+
cyan = "\033[4;36m"
|
|
30
|
+
white = "\033[4;37m"
|
|
31
|
+
|
|
32
|
+
class Background:
|
|
33
|
+
black = "\033[40m"
|
|
34
|
+
red = "\033[41m"
|
|
35
|
+
green = "\033[42m"
|
|
36
|
+
yellow = "\033[43m"
|
|
37
|
+
blue = "\033[44m"
|
|
38
|
+
purple = "\033[45m"
|
|
39
|
+
cyan = "\033[46m"
|
|
40
|
+
white = "\033[47m"
|
|
41
|
+
|
|
42
|
+
class HighIntensity:
|
|
43
|
+
black = "\033[0;90m"
|
|
44
|
+
red = "\033[0;91m"
|
|
45
|
+
green = "\033[0;92m"
|
|
46
|
+
yellow = "\033[0;93m"
|
|
47
|
+
blue = "\033[0;94m"
|
|
48
|
+
purple = "\033[0;95m"
|
|
49
|
+
cyan = "\033[0;96m"
|
|
50
|
+
white = "\033[0;97m"
|
|
51
|
+
|
|
52
|
+
class BoldHighIntensity:
|
|
53
|
+
black = "\033[1;90m"
|
|
54
|
+
red = "\033[1;91m"
|
|
55
|
+
green = "\033[1;92m"
|
|
56
|
+
yellow = "\033[1;93m"
|
|
57
|
+
blue = "\033[1;94m"
|
|
58
|
+
purple = "\033[1;95m"
|
|
59
|
+
cyan = "\033[1;96m"
|
|
60
|
+
white = "\033[1;97m"
|
|
61
|
+
|
|
62
|
+
class HighIntensityBackground:
|
|
63
|
+
black = "\033[0;100m"
|
|
64
|
+
red = "\033[0;101m"
|
|
65
|
+
green = "\033[0;102m"
|
|
66
|
+
yellow = "\033[0;103m"
|
|
67
|
+
blue = "\033[0;104m"
|
|
68
|
+
purple = "\033[0;105m"
|
|
69
|
+
cyan = "\033[0;106m"
|
|
70
|
+
white = "\033[0;107m"
|
|
71
|
+
|
|
72
|
+
class Reset:
|
|
73
|
+
reset = "\033[0m"
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
colors = Colors()
|