origin-or 1.7.9__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.
- origin_or-1.7.9/MANIFEST.in +4 -0
- origin_or-1.7.9/PKG-INFO +203 -0
- origin_or-1.7.9/README.md +175 -0
- origin_or-1.7.9/origin/__init__.py +3 -0
- origin_or-1.7.9/origin/__main__.py +16 -0
- origin_or-1.7.9/origin/bc/JavaImplement/BoundMethod.java +11 -0
- origin_or-1.7.9/origin/bc/JavaImplement/Builtins.java +224 -0
- origin_or-1.7.9/origin/bc/JavaImplement/HardwareSim.java +93 -0
- origin_or-1.7.9/origin/bc/JavaImplement/Loader.java +103 -0
- origin_or-1.7.9/origin/bc/JavaImplement/Main.java +34 -0
- origin_or-1.7.9/origin/bc/JavaImplement/OpCode.java +79 -0
- origin_or-1.7.9/origin/bc/JavaImplement/OriginClass.java +16 -0
- origin_or-1.7.9/origin/bc/JavaImplement/OriginInstance.java +19 -0
- origin_or-1.7.9/origin/bc/JavaImplement/svm.java +699 -0
- origin_or-1.7.9/origin/bc/__init__.py +1 -0
- origin_or-1.7.9/origin/bc/byte_key.py +74 -0
- origin_or-1.7.9/origin/bc/dump_obc.py +134 -0
- origin_or-1.7.9/origin/bc/helpers.py +18 -0
- origin_or-1.7.9/origin/bc/svm.py +509 -0
- origin_or-1.7.9/origin/bc/to_byte.py +616 -0
- origin_or-1.7.9/origin/classes.py +525 -0
- origin_or-1.7.9/origin/errors.py +372 -0
- origin_or-1.7.9/origin/interpreter.py +446 -0
- origin_or-1.7.9/origin/lexer.py +96 -0
- origin_or-1.7.9/origin/lib/__init__.py +1 -0
- origin_or-1.7.9/origin/lib/calc.or +45 -0
- origin_or-1.7.9/origin/lib/graph.or +55 -0
- origin_or-1.7.9/origin/parser.py +968 -0
- origin_or-1.7.9/origin/runner.py +91 -0
- origin_or-1.7.9/origin_or.egg-info/PKG-INFO +203 -0
- origin_or-1.7.9/origin_or.egg-info/SOURCES.txt +35 -0
- origin_or-1.7.9/origin_or.egg-info/dependency_links.txt +1 -0
- origin_or-1.7.9/origin_or.egg-info/entry_points.txt +2 -0
- origin_or-1.7.9/origin_or.egg-info/requires.txt +8 -0
- origin_or-1.7.9/origin_or.egg-info/top_level.txt +1 -0
- origin_or-1.7.9/setup.cfg +4 -0
- origin_or-1.7.9/setup.py +32 -0
origin_or-1.7.9/PKG-INFO
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: origin-or
|
|
3
|
+
Version: 1.7.9
|
|
4
|
+
Summary: The Origin programming language — compiled bytecode VM for Raspberry Pi
|
|
5
|
+
Author: Nikhil Mahankali
|
|
6
|
+
Classifier: Development Status :: 4 - Beta
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
9
|
+
Classifier: Topic :: Software Development :: Interpreters
|
|
10
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
11
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
12
|
+
Classifier: Operating System :: MacOS
|
|
13
|
+
Requires-Python: >=3.10
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
Provides-Extra: pi
|
|
16
|
+
Requires-Dist: RPi.GPIO; extra == "pi"
|
|
17
|
+
Requires-Dist: adafruit-circuitpython-servokit; extra == "pi"
|
|
18
|
+
Requires-Dist: smbus2; extra == "pi"
|
|
19
|
+
Provides-Extra: build
|
|
20
|
+
Requires-Dist: pyinstaller; extra == "build"
|
|
21
|
+
Dynamic: author
|
|
22
|
+
Dynamic: classifier
|
|
23
|
+
Dynamic: description
|
|
24
|
+
Dynamic: description-content-type
|
|
25
|
+
Dynamic: provides-extra
|
|
26
|
+
Dynamic: requires-python
|
|
27
|
+
Dynamic: summary
|
|
28
|
+
|
|
29
|
+
# Origin Programming Language · v1.7.9
|
|
30
|
+
|
|
31
|
+
[](https://docs-origin.onrender.com)
|
|
32
|
+
[](https://docs-origin.onrender.com)
|
|
33
|
+
[](https://docs-origin.onrender.com)
|
|
34
|
+
|
|
35
|
+
**Origin** is a Python-based programming language with a syntax designed to be expressive, English-like, and hardware-first. It enables AI models and developers to produce scalable code with high readability while retaining the full power of the Python ecosystem.
|
|
36
|
+
|
|
37
|
+
> **Visit the official documentation:** [docs-origin.onrender.com](https://docs-origin.onrender.com)
|
|
38
|
+
|
|
39
|
+
> **June 2026 re-issue:** The standalone `origin.exe` has been rebuilt from the v1.7.5 reference sources with the flat-layout imports normalized, and `secure_install.ps1` now hard-codes the SHA-256 of the new binary. The language surface is unchanged from the prior v1.7.9 release. The bytecode VM migration continues on the [`origin-dev`](https://github.com/boblio-max/origin-dev) branch and will ship as v1.8.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Key Features
|
|
44
|
+
|
|
45
|
+
* **English-Like Syntax**: Write code that reads like natural language.
|
|
46
|
+
* **Built-in Library System**: Import `.or` library files with `import calc`, including a math library (`calc.or`) and graph plotting library (`graph.or`).
|
|
47
|
+
* **Hardware Primitives**: Native, intuitive commands for Raspberry Pi GPIO and ServoKit (PCA9685).
|
|
48
|
+
* **Strict Typing**: Mandatory type annotations (`let x: int = 10`) for predictable state and AI-native safety.
|
|
49
|
+
* **Safe Hardware I/O**: Automatic angle clamping (0-180 degrees) for servos to prevent physical damage.
|
|
50
|
+
* **Formal Module System**: Professional namespacing and module support (`import math as m`, `from lib import x`).
|
|
51
|
+
* **Binary Builder**: Compile your Origin scripts into standalone, zero-dependency `.exe` files.
|
|
52
|
+
* **Modern Logic**: Support for Object-Oriented Programming (classes), `try/except/else`, `parallel` thread blocks, and robust scope management.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Installation
|
|
57
|
+
|
|
58
|
+
### Standalone (Recommended)
|
|
59
|
+
You can now download Origin as a standalone installer for Windows. This is the fastest way to get started.
|
|
60
|
+
|
|
61
|
+
1. **Download**: [Origin v1.7.9 Stable](https://docs-origin.onrender.com/download.html)
|
|
62
|
+
2. **Install**: Run `secure_install.ps1` with PowerShell.
|
|
63
|
+
3. **Usage**: Open a new terminal and type `origin`.
|
|
64
|
+
|
|
65
|
+
### Developer / Source
|
|
66
|
+
1. **Clone the repository**:
|
|
67
|
+
```powershell
|
|
68
|
+
git clone https://github.com/boblio-max/origin.git
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
2. **Install Dependencies**:
|
|
72
|
+
```powershell
|
|
73
|
+
pip install -r requirements.txt
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Language Reference
|
|
79
|
+
|
|
80
|
+
### 1. Variables & Types
|
|
81
|
+
Origin uses `let` for variables and `const` for immutable references. Types are mandatory.
|
|
82
|
+
|
|
83
|
+
```origin
|
|
84
|
+
let x: int = 10 # Scalar integer
|
|
85
|
+
let name: str = "Origin" # String literal
|
|
86
|
+
let flag: bool = true # Boolean (lowercase)
|
|
87
|
+
const pi: float = 3.14159 # Immutable constant
|
|
88
|
+
let data: none = none # None literal
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### 2. Built-in Libraries
|
|
92
|
+
Origin includes a standard library system under `lib/`. Use `import` to load them:
|
|
93
|
+
|
|
94
|
+
```origin
|
|
95
|
+
import calc
|
|
96
|
+
import graph
|
|
97
|
+
|
|
98
|
+
# Math utilities
|
|
99
|
+
calc = calc()
|
|
100
|
+
print calc.sqrt(25)
|
|
101
|
+
print calc.pi
|
|
102
|
+
|
|
103
|
+
# Graph plotting
|
|
104
|
+
graph "My Plot" with {
|
|
105
|
+
X: color(1,0,0) as "Line A",
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### 3. Hardware Control
|
|
110
|
+
Control hardware directly with the `set` namespace and native protocol primitives.
|
|
111
|
+
|
|
112
|
+
```origin
|
|
113
|
+
# Set Servo 1 to 90 degrees (clamped 0-180)
|
|
114
|
+
set servo.angle 1, 90
|
|
115
|
+
|
|
116
|
+
# Drive BCM Pin 12 HIGH
|
|
117
|
+
set pin 12, 1
|
|
118
|
+
|
|
119
|
+
# Parentheseless I2C, SPI, and UART calls
|
|
120
|
+
i2c.read 0x40, 4
|
|
121
|
+
spi.write 0x01
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### 4. Data Structures
|
|
125
|
+
```origin
|
|
126
|
+
# Lists
|
|
127
|
+
let tools: list = ["Servo", "GPIO", "I2C"]
|
|
128
|
+
print tools[0]
|
|
129
|
+
|
|
130
|
+
# Dictionaries (Access via { })
|
|
131
|
+
let config: dict = {"speed": 100, "active": true}
|
|
132
|
+
print config{"speed"}
|
|
133
|
+
|
|
134
|
+
# Tuples
|
|
135
|
+
let coord: tuple = (10, 20)
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### 5. Raw Python Blocks
|
|
139
|
+
Seamlessly bridge the gap between Origin and Python.
|
|
140
|
+
|
|
141
|
+
```origin
|
|
142
|
+
py {
|
|
143
|
+
import math
|
|
144
|
+
import os
|
|
145
|
+
print("Python process ID:", os.getpid())
|
|
146
|
+
print("Sine of 90 degrees:", math.sin(math.pi/2))
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### 6. Module System
|
|
151
|
+
Origin supports a formal module system for clean namespacing.
|
|
152
|
+
|
|
153
|
+
```origin
|
|
154
|
+
import math_utils as mu # Import with alias
|
|
155
|
+
from robotics import drive # Selective import
|
|
156
|
+
|
|
157
|
+
print mu.square(10)
|
|
158
|
+
drive(1.0)
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### 7. Object-Oriented Programming
|
|
162
|
+
Define classes with fields and methods natively for structured development.
|
|
163
|
+
|
|
164
|
+
```origin
|
|
165
|
+
class Sensor (pin type) {
|
|
166
|
+
def read() {
|
|
167
|
+
return pin
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
Origin scripts use the `.or` extension.
|
|
175
|
+
|
|
176
|
+
### Running a script:
|
|
177
|
+
```powershell
|
|
178
|
+
origin main.or
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Building a standalone binary:
|
|
182
|
+
```powershell
|
|
183
|
+
origin build main.or
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Roadmap
|
|
189
|
+
|
|
190
|
+
The following features are currently in development:
|
|
191
|
+
- [ ] **Pattern Matching**: `match` and `case` constructs.
|
|
192
|
+
- [ ] **Advanced Structures**: `struct` and `enum` types.
|
|
193
|
+
- [ ] **Asynchronous I/O**: Native `async` and `await` support.
|
|
194
|
+
- [ ] **Metaprogramming**: `macro` and `inline` definitions.
|
|
195
|
+
- [ ] **Unified IDE**: A dedicated cross-platform IDE for Origin development.
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## License & Contact
|
|
200
|
+
|
|
201
|
+
Distributed under the **MIT License**.
|
|
202
|
+
**Author**: Nikhil Mahankali
|
|
203
|
+
**Contact**: [nikhilmahankali56@gmail.com](mailto:nikhilmahankali56@gmail.com)
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# Origin Programming Language · v1.7.9
|
|
2
|
+
|
|
3
|
+
[](https://docs-origin.onrender.com)
|
|
4
|
+
[](https://docs-origin.onrender.com)
|
|
5
|
+
[](https://docs-origin.onrender.com)
|
|
6
|
+
|
|
7
|
+
**Origin** is a Python-based programming language with a syntax designed to be expressive, English-like, and hardware-first. It enables AI models and developers to produce scalable code with high readability while retaining the full power of the Python ecosystem.
|
|
8
|
+
|
|
9
|
+
> **Visit the official documentation:** [docs-origin.onrender.com](https://docs-origin.onrender.com)
|
|
10
|
+
|
|
11
|
+
> **June 2026 re-issue:** The standalone `origin.exe` has been rebuilt from the v1.7.5 reference sources with the flat-layout imports normalized, and `secure_install.ps1` now hard-codes the SHA-256 of the new binary. The language surface is unchanged from the prior v1.7.9 release. The bytecode VM migration continues on the [`origin-dev`](https://github.com/boblio-max/origin-dev) branch and will ship as v1.8.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Key Features
|
|
16
|
+
|
|
17
|
+
* **English-Like Syntax**: Write code that reads like natural language.
|
|
18
|
+
* **Built-in Library System**: Import `.or` library files with `import calc`, including a math library (`calc.or`) and graph plotting library (`graph.or`).
|
|
19
|
+
* **Hardware Primitives**: Native, intuitive commands for Raspberry Pi GPIO and ServoKit (PCA9685).
|
|
20
|
+
* **Strict Typing**: Mandatory type annotations (`let x: int = 10`) for predictable state and AI-native safety.
|
|
21
|
+
* **Safe Hardware I/O**: Automatic angle clamping (0-180 degrees) for servos to prevent physical damage.
|
|
22
|
+
* **Formal Module System**: Professional namespacing and module support (`import math as m`, `from lib import x`).
|
|
23
|
+
* **Binary Builder**: Compile your Origin scripts into standalone, zero-dependency `.exe` files.
|
|
24
|
+
* **Modern Logic**: Support for Object-Oriented Programming (classes), `try/except/else`, `parallel` thread blocks, and robust scope management.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
### Standalone (Recommended)
|
|
31
|
+
You can now download Origin as a standalone installer for Windows. This is the fastest way to get started.
|
|
32
|
+
|
|
33
|
+
1. **Download**: [Origin v1.7.9 Stable](https://docs-origin.onrender.com/download.html)
|
|
34
|
+
2. **Install**: Run `secure_install.ps1` with PowerShell.
|
|
35
|
+
3. **Usage**: Open a new terminal and type `origin`.
|
|
36
|
+
|
|
37
|
+
### Developer / Source
|
|
38
|
+
1. **Clone the repository**:
|
|
39
|
+
```powershell
|
|
40
|
+
git clone https://github.com/boblio-max/origin.git
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
2. **Install Dependencies**:
|
|
44
|
+
```powershell
|
|
45
|
+
pip install -r requirements.txt
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Language Reference
|
|
51
|
+
|
|
52
|
+
### 1. Variables & Types
|
|
53
|
+
Origin uses `let` for variables and `const` for immutable references. Types are mandatory.
|
|
54
|
+
|
|
55
|
+
```origin
|
|
56
|
+
let x: int = 10 # Scalar integer
|
|
57
|
+
let name: str = "Origin" # String literal
|
|
58
|
+
let flag: bool = true # Boolean (lowercase)
|
|
59
|
+
const pi: float = 3.14159 # Immutable constant
|
|
60
|
+
let data: none = none # None literal
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### 2. Built-in Libraries
|
|
64
|
+
Origin includes a standard library system under `lib/`. Use `import` to load them:
|
|
65
|
+
|
|
66
|
+
```origin
|
|
67
|
+
import calc
|
|
68
|
+
import graph
|
|
69
|
+
|
|
70
|
+
# Math utilities
|
|
71
|
+
calc = calc()
|
|
72
|
+
print calc.sqrt(25)
|
|
73
|
+
print calc.pi
|
|
74
|
+
|
|
75
|
+
# Graph plotting
|
|
76
|
+
graph "My Plot" with {
|
|
77
|
+
X: color(1,0,0) as "Line A",
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### 3. Hardware Control
|
|
82
|
+
Control hardware directly with the `set` namespace and native protocol primitives.
|
|
83
|
+
|
|
84
|
+
```origin
|
|
85
|
+
# Set Servo 1 to 90 degrees (clamped 0-180)
|
|
86
|
+
set servo.angle 1, 90
|
|
87
|
+
|
|
88
|
+
# Drive BCM Pin 12 HIGH
|
|
89
|
+
set pin 12, 1
|
|
90
|
+
|
|
91
|
+
# Parentheseless I2C, SPI, and UART calls
|
|
92
|
+
i2c.read 0x40, 4
|
|
93
|
+
spi.write 0x01
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### 4. Data Structures
|
|
97
|
+
```origin
|
|
98
|
+
# Lists
|
|
99
|
+
let tools: list = ["Servo", "GPIO", "I2C"]
|
|
100
|
+
print tools[0]
|
|
101
|
+
|
|
102
|
+
# Dictionaries (Access via { })
|
|
103
|
+
let config: dict = {"speed": 100, "active": true}
|
|
104
|
+
print config{"speed"}
|
|
105
|
+
|
|
106
|
+
# Tuples
|
|
107
|
+
let coord: tuple = (10, 20)
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### 5. Raw Python Blocks
|
|
111
|
+
Seamlessly bridge the gap between Origin and Python.
|
|
112
|
+
|
|
113
|
+
```origin
|
|
114
|
+
py {
|
|
115
|
+
import math
|
|
116
|
+
import os
|
|
117
|
+
print("Python process ID:", os.getpid())
|
|
118
|
+
print("Sine of 90 degrees:", math.sin(math.pi/2))
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### 6. Module System
|
|
123
|
+
Origin supports a formal module system for clean namespacing.
|
|
124
|
+
|
|
125
|
+
```origin
|
|
126
|
+
import math_utils as mu # Import with alias
|
|
127
|
+
from robotics import drive # Selective import
|
|
128
|
+
|
|
129
|
+
print mu.square(10)
|
|
130
|
+
drive(1.0)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 7. Object-Oriented Programming
|
|
134
|
+
Define classes with fields and methods natively for structured development.
|
|
135
|
+
|
|
136
|
+
```origin
|
|
137
|
+
class Sensor (pin type) {
|
|
138
|
+
def read() {
|
|
139
|
+
return pin
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
Origin scripts use the `.or` extension.
|
|
147
|
+
|
|
148
|
+
### Running a script:
|
|
149
|
+
```powershell
|
|
150
|
+
origin main.or
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Building a standalone binary:
|
|
154
|
+
```powershell
|
|
155
|
+
origin build main.or
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Roadmap
|
|
161
|
+
|
|
162
|
+
The following features are currently in development:
|
|
163
|
+
- [ ] **Pattern Matching**: `match` and `case` constructs.
|
|
164
|
+
- [ ] **Advanced Structures**: `struct` and `enum` types.
|
|
165
|
+
- [ ] **Asynchronous I/O**: Native `async` and `await` support.
|
|
166
|
+
- [ ] **Metaprogramming**: `macro` and `inline` definitions.
|
|
167
|
+
- [ ] **Unified IDE**: A dedicated cross-platform IDE for Origin development.
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## License & Contact
|
|
172
|
+
|
|
173
|
+
Distributed under the **MIT License**.
|
|
174
|
+
**Author**: Nikhil Mahankali
|
|
175
|
+
**Contact**: [nikhilmahankali56@gmail.com](mailto:nikhilmahankali56@gmail.com)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Entry point for `python -m origin` and the `origin` CLI command."""
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
from .runner import run_origin
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def main():
|
|
8
|
+
if len(sys.argv) < 2:
|
|
9
|
+
print("Origin Programming Language v1.7.9")
|
|
10
|
+
print("Usage: origin <file.or>")
|
|
11
|
+
sys.exit(1)
|
|
12
|
+
run_origin(sys.argv[1])
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
if __name__ == "__main__":
|
|
16
|
+
main()
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
package ORIGIN_CODE.bc.JavaImplement;
|
|
2
|
+
|
|
3
|
+
public final class BoundMethod {
|
|
4
|
+
public final OriginInstance instance;
|
|
5
|
+
public final int funcPc;
|
|
6
|
+
|
|
7
|
+
public BoundMethod(OriginInstance instance, int funcPc) {
|
|
8
|
+
this.instance = instance;
|
|
9
|
+
this.funcPc = funcPc;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
package ORIGIN_CODE.bc.JavaImplement;
|
|
2
|
+
|
|
3
|
+
import java.util.ArrayList;
|
|
4
|
+
import java.util.HashMap;
|
|
5
|
+
import java.util.List;
|
|
6
|
+
import java.util.Map;
|
|
7
|
+
import java.util.Scanner;
|
|
8
|
+
import java.util.concurrent.ThreadLocalRandom;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Registry of built-in callables that the VM exposes to bytecode via CALL.
|
|
12
|
+
* Mirrors the {open, read, write, append, range, ...} dictionary in
|
|
13
|
+
* to_byte.py:18 plus the implicit built-ins handled by the Python branch
|
|
14
|
+
* of CALL at svm.py:333-339.
|
|
15
|
+
*/
|
|
16
|
+
public final class Builtins {
|
|
17
|
+
|
|
18
|
+
@FunctionalInterface
|
|
19
|
+
public interface BuiltinFn {
|
|
20
|
+
Object call(List<Object> args);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
private final Map<String, BuiltinFn> registry;
|
|
24
|
+
|
|
25
|
+
public Builtins() {
|
|
26
|
+
this.registry = new HashMap<>();
|
|
27
|
+
registerDefaults();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public BuiltinFn get(String name) {
|
|
31
|
+
return registry.get(name);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public boolean contains(String name) {
|
|
35
|
+
return registry.containsKey(name);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
private void registerDefaults() {
|
|
39
|
+
// Compiler builtins (to_byte.py:18-24)
|
|
40
|
+
registry.put("open", args -> new OpenFile(asStr(args, 0), "r"));
|
|
41
|
+
registry.put("read", args -> {
|
|
42
|
+
OpenFile f = asOpenFile(args, 0);
|
|
43
|
+
return f.readAll();
|
|
44
|
+
});
|
|
45
|
+
registry.put("write", args -> {
|
|
46
|
+
Object pathOrFile = args.get(0);
|
|
47
|
+
Object content = args.get(1);
|
|
48
|
+
String contentStr = String.valueOf(content);
|
|
49
|
+
if (pathOrFile instanceof OpenFile) {
|
|
50
|
+
((OpenFile) pathOrFile).writeAll(contentStr);
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
try (java.io.FileWriter w = new java.io.FileWriter(asStr(args, 0))) {
|
|
54
|
+
w.write(contentStr);
|
|
55
|
+
} catch (java.io.IOException e) {
|
|
56
|
+
throw new RuntimeException(e);
|
|
57
|
+
}
|
|
58
|
+
return null;
|
|
59
|
+
});
|
|
60
|
+
registry.put("append", args -> {
|
|
61
|
+
Object pathOrFile = args.get(0);
|
|
62
|
+
Object content = args.get(1);
|
|
63
|
+
String contentStr = String.valueOf(content);
|
|
64
|
+
if (pathOrFile instanceof OpenFile) {
|
|
65
|
+
((OpenFile) pathOrFile).appendAll(contentStr);
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
try (java.io.FileWriter w = new java.io.FileWriter(asStr(args, 0), true)) {
|
|
69
|
+
w.write(contentStr);
|
|
70
|
+
} catch (java.io.IOException e) {
|
|
71
|
+
throw new RuntimeException(e);
|
|
72
|
+
}
|
|
73
|
+
return null;
|
|
74
|
+
});
|
|
75
|
+
registry.put("range", args -> {
|
|
76
|
+
int n = args.size();
|
|
77
|
+
int start, end;
|
|
78
|
+
if (n == 1) { start = 0; end = asInt(args, 0); }
|
|
79
|
+
else { start = asInt(args, 0); end = asInt(args, 1); }
|
|
80
|
+
List<Object> out = new ArrayList<>();
|
|
81
|
+
for (int i = start; i < end; i++) out.add((long) i);
|
|
82
|
+
return out;
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
// Implied built-ins called from bytecode (svm.py CALL branch)
|
|
86
|
+
registry.put("str", args -> toStr(args.isEmpty() ? null : args.get(0)));
|
|
87
|
+
registry.put("int", args -> {
|
|
88
|
+
if (args.isEmpty()) return 0L;
|
|
89
|
+
Object v = args.get(0);
|
|
90
|
+
if (v instanceof Long) return v;
|
|
91
|
+
if (v instanceof Double) return ((Double) v).longValue();
|
|
92
|
+
if (v instanceof Boolean) return ((Boolean) v) ? 1L : 0L;
|
|
93
|
+
return Long.parseLong(String.valueOf(v));
|
|
94
|
+
});
|
|
95
|
+
registry.put("float", args -> {
|
|
96
|
+
if (args.isEmpty()) return 0.0;
|
|
97
|
+
Object v = args.get(0);
|
|
98
|
+
if (v instanceof Double) return v;
|
|
99
|
+
if (v instanceof Long) return ((Long) v).doubleValue();
|
|
100
|
+
return Double.parseDouble(String.valueOf(v));
|
|
101
|
+
});
|
|
102
|
+
registry.put("bool", args -> toBool(args.isEmpty() ? null : args.get(0)));
|
|
103
|
+
registry.put("len", args -> (long) lengthOf(args.get(0)));
|
|
104
|
+
registry.put("input", args -> {
|
|
105
|
+
if (args.isEmpty()) return new Scanner(System.in).nextLine();
|
|
106
|
+
System.out.print(args.get(0));
|
|
107
|
+
return new Scanner(System.in).nextLine();
|
|
108
|
+
});
|
|
109
|
+
registry.put("random", args -> {
|
|
110
|
+
// Placeholder; VM handles RAND_NUM directly via ThreadLocalRandom.
|
|
111
|
+
return null;
|
|
112
|
+
});
|
|
113
|
+
registry.put("math", args -> null); // VM handles SQRT directly
|
|
114
|
+
registry.put("print", args -> {
|
|
115
|
+
StringBuilder sb = new StringBuilder();
|
|
116
|
+
for (Object a : args) sb.append(toStr(a));
|
|
117
|
+
System.out.println(sb.toString());
|
|
118
|
+
return null;
|
|
119
|
+
});
|
|
120
|
+
registry.put("list", args -> {
|
|
121
|
+
if (args.isEmpty()) return new ArrayList<>();
|
|
122
|
+
Object v = args.get(0);
|
|
123
|
+
if (v instanceof List) return new ArrayList<>((List<?>) v);
|
|
124
|
+
if (v instanceof String) {
|
|
125
|
+
List<Object> out = new ArrayList<>();
|
|
126
|
+
String s = (String) v;
|
|
127
|
+
for (int i = 0; i < s.length(); i++) out.add(String.valueOf(s.charAt(i)));
|
|
128
|
+
return out;
|
|
129
|
+
}
|
|
130
|
+
throw new RuntimeException("object is not iterable");
|
|
131
|
+
});
|
|
132
|
+
registry.put("dict", args -> new HashMap<>());
|
|
133
|
+
registry.put("tuple", args -> new ArrayList<>(args));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// --- helpers used by Builtins and by VM opcode handlers ---
|
|
137
|
+
|
|
138
|
+
public static String toStr(Object v) {
|
|
139
|
+
if (v == null) return "null";
|
|
140
|
+
if (v instanceof OriginInstance) return v.toString();
|
|
141
|
+
return String.valueOf(v);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
public static boolean toBool(Object v) {
|
|
145
|
+
if (v == null) return false;
|
|
146
|
+
if (v instanceof Boolean) return (Boolean) v;
|
|
147
|
+
if (v instanceof Long) return ((Long) v) != 0;
|
|
148
|
+
if (v instanceof Double) return ((Double) v) != 0.0;
|
|
149
|
+
if (v instanceof String) return !((String) v).isEmpty();
|
|
150
|
+
if (v instanceof List) return !((List<?>) v).isEmpty();
|
|
151
|
+
if (v instanceof Map) return !((Map<?, ?>) v).isEmpty();
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
public static int asInt(List<Object> args, int i) {
|
|
156
|
+
Object v = args.get(i);
|
|
157
|
+
if (v instanceof Long) return ((Long) v).intValue();
|
|
158
|
+
if (v instanceof Double) return ((Double) v).intValue();
|
|
159
|
+
if (v instanceof Boolean) return ((Boolean) v) ? 1 : 0;
|
|
160
|
+
return Integer.parseInt(String.valueOf(v));
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
public static String asStr(List<Object> args, int i) {
|
|
164
|
+
Object v = args.get(i);
|
|
165
|
+
if (v == null) return "null";
|
|
166
|
+
return String.valueOf(v);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
public static long asLong(Object v) {
|
|
170
|
+
if (v instanceof Long) return (Long) v;
|
|
171
|
+
if (v instanceof Double) return ((Double) v).longValue();
|
|
172
|
+
if (v instanceof Boolean) return ((Boolean) v) ? 1L : 0L;
|
|
173
|
+
return Long.parseLong(String.valueOf(v));
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
public static double asDouble(Object v) {
|
|
177
|
+
if (v instanceof Double) return (Double) v;
|
|
178
|
+
if (v instanceof Long) return ((Long) v).doubleValue();
|
|
179
|
+
if (v instanceof Boolean) return ((Boolean) v) ? 1.0 : 0.0;
|
|
180
|
+
return Double.parseDouble(String.valueOf(v));
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
public static long lengthOf(Object v) {
|
|
184
|
+
if (v instanceof String) return ((String) v).length();
|
|
185
|
+
if (v instanceof List) return ((List<?>) v).size();
|
|
186
|
+
if (v instanceof Map) return ((Map<?, ?>) v).size();
|
|
187
|
+
throw new RuntimeException("object has no len(): " + (v == null ? "null" : v.getClass().getName()));
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
public static int randInt(long start, long end) {
|
|
191
|
+
return ThreadLocalRandom.current().nextInt((int) start, (int) end + 1);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/** Wrapper for a file handle returned by built-in open(). */
|
|
195
|
+
public static final class OpenFile {
|
|
196
|
+
public final String path;
|
|
197
|
+
public final String mode;
|
|
198
|
+
public OpenFile(String path, String mode) { this.path = path; this.mode = mode; }
|
|
199
|
+
public String readAll() {
|
|
200
|
+
try {
|
|
201
|
+
return new String(java.nio.file.Files.readAllBytes(java.nio.file.Paths.get(path)));
|
|
202
|
+
} catch (java.io.IOException e) {
|
|
203
|
+
throw new RuntimeException(e);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
public void writeAll(String content) {
|
|
207
|
+
try (java.io.FileWriter w = new java.io.FileWriter(path)) {
|
|
208
|
+
w.write(content);
|
|
209
|
+
} catch (java.io.IOException e) { throw new RuntimeException(e); }
|
|
210
|
+
}
|
|
211
|
+
public void appendAll(String content) {
|
|
212
|
+
try (java.io.FileWriter w = new java.io.FileWriter(path, true)) {
|
|
213
|
+
w.write(content);
|
|
214
|
+
} catch (java.io.IOException e) { throw new RuntimeException(e); }
|
|
215
|
+
}
|
|
216
|
+
@Override public String toString() { return "<open file '" + path + "' mode='" + mode + "'>"; }
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
private static OpenFile asOpenFile(List<Object> args, int i) {
|
|
220
|
+
Object v = args.get(i);
|
|
221
|
+
if (v instanceof OpenFile) return (OpenFile) v;
|
|
222
|
+
return new OpenFile(asStr(args, i), "r");
|
|
223
|
+
}
|
|
224
|
+
}
|