olcabasic 0.1.0__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.
- olcabasic-0.1.0/PKG-INFO +142 -0
- olcabasic-0.1.0/README.md +123 -0
- olcabasic-0.1.0/olcabasic/__init__.py +3 -0
- olcabasic-0.1.0/olcabasic/__main__.py +109 -0
- olcabasic-0.1.0/olcabasic/ast_nodes.py +455 -0
- olcabasic-0.1.0/olcabasic/bridge.py +271 -0
- olcabasic-0.1.0/olcabasic/formatting.py +358 -0
- olcabasic-0.1.0/olcabasic/interpreter.py +1064 -0
- olcabasic-0.1.0/olcabasic/parser.py +1441 -0
- olcabasic-0.1.0/olcabasic/repl.py +103 -0
- olcabasic-0.1.0/olcabasic/runtime.py +140 -0
- olcabasic-0.1.0/olcabasic/tokeniser.py +326 -0
- olcabasic-0.1.0/olcabasic.egg-info/PKG-INFO +142 -0
- olcabasic-0.1.0/olcabasic.egg-info/SOURCES.txt +18 -0
- olcabasic-0.1.0/olcabasic.egg-info/dependency_links.txt +1 -0
- olcabasic-0.1.0/olcabasic.egg-info/entry_points.txt +2 -0
- olcabasic-0.1.0/olcabasic.egg-info/requires.txt +1 -0
- olcabasic-0.1.0/olcabasic.egg-info/top_level.txt +1 -0
- olcabasic-0.1.0/pyproject.toml +31 -0
- olcabasic-0.1.0/setup.cfg +4 -0
olcabasic-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: olcabasic
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A BASIC-like language for controlling openLCA
|
|
5
|
+
Author-email: Below280 <info@below280.com>
|
|
6
|
+
License: MPL-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/Below280/olcaBASIC
|
|
8
|
+
Project-URL: Repository, https://github.com/Below280/olcaBASIC
|
|
9
|
+
Project-URL: Issues, https://github.com/Below280/olcaBASIC/issues
|
|
10
|
+
Keywords: lca,openlca,basic,dsl,life-cycle-assessment
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: Topic :: Scientific/Engineering
|
|
14
|
+
Classifier: License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Requires-Python: >=3.10
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
Requires-Dist: b280-olca-mcp>=1.11
|
|
19
|
+
|
|
20
|
+
# olcaBASIC
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
___ _ ____ _ ____ _ ____ _ ____
|
|
24
|
+
/ _ \| | / ___| / \ | __ ) / \ / ___|| |/ ___|
|
|
25
|
+
| | | | | | | / _ \ | _ \ / _ \ \___ \| | |
|
|
26
|
+
| |_| | |__| |___ / ___ \| |_) / ___ \ ___) | | |___
|
|
27
|
+
\___/|_____\____/_/ \_\____/_/ \_\____/|_|\____|
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**A simplified language to control openLCA, borrowing heavily from
|
|
31
|
+
the BASIC programming language (1964)**
|
|
32
|
+
|
|
33
|
+
olcaBASIC lets LCA practitioners build models, run calculations, and
|
|
34
|
+
analyse results without writing Python. It connects to openLCA via the
|
|
35
|
+
IPC server and translates simple, readable commands into the full power
|
|
36
|
+
of the openLCA calculation engine.
|
|
37
|
+
|
|
38
|
+
## Quick start
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
pip install olcabasic
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Start the IPC server in openLCA (Tools > Developer Tools > IPC Server),
|
|
45
|
+
then:
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
olcabasic
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
olcaBASIC v0.1.0
|
|
53
|
+
Connected to openLCA on port 8080 (ecoinvent 3.10)
|
|
54
|
+
Ready.
|
|
55
|
+
|
|
56
|
+
> PRINT PROCESSES("electricity", "", "GB")
|
|
57
|
+
electricity production, wind, 1-3MW | GB
|
|
58
|
+
electricity production, natural gas | GB
|
|
59
|
+
...
|
|
60
|
+
|
|
61
|
+
> PRINT METHODS("ReCiPe")
|
|
62
|
+
ReCiPe 2016 Midpoint (H)
|
|
63
|
+
ReCiPe 2016 Endpoint (H)
|
|
64
|
+
|
|
65
|
+
> CALCULATE "My System" USING "ReCiPe 2016 Midpoint (H)"
|
|
66
|
+
Climate change: 247.3 kg CO2-eq
|
|
67
|
+
Ozone depletion: 3.21e-6 kg CFC-11-eq
|
|
68
|
+
...
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Write programs
|
|
72
|
+
|
|
73
|
+
Save as `mymodel.baslca` and run with `olcabasic run mymodel.baslca`:
|
|
74
|
+
|
|
75
|
+
```basic
|
|
76
|
+
REM Concrete block EPD model
|
|
77
|
+
|
|
78
|
+
LET cement_mass = 300
|
|
79
|
+
LET water_cement_ratio = 0.45
|
|
80
|
+
LET mixing_energy = 12
|
|
81
|
+
|
|
82
|
+
FLOW "Concrete block", m3, PRODUCT
|
|
83
|
+
|
|
84
|
+
BRIDGE "BRIDGE | Cement | kg", kg
|
|
85
|
+
FOLDER "00: Concrete/Bridges"
|
|
86
|
+
PROVIDER "cement production, Portland | GB"
|
|
87
|
+
END BRIDGE
|
|
88
|
+
|
|
89
|
+
PROCESS "A1: Raw materials" LOCATION "GB"
|
|
90
|
+
FOLDER "00: Concrete/A1"
|
|
91
|
+
OUTPUT "Concrete block", 1, m3, PRODUCT
|
|
92
|
+
INPUT "BRIDGE | Cement | kg", cement_mass, kg
|
|
93
|
+
INPUT "BRIDGE | Sand | kg", 800, kg
|
|
94
|
+
INPUT "BRIDGE | UK grid | kWh", mixing_energy, kWh
|
|
95
|
+
END PROCESS
|
|
96
|
+
|
|
97
|
+
SYSTEM "A1: Raw materials"
|
|
98
|
+
CALCULATE "A1: Raw materials" USING "EN15804+A2 (EF 3.1)"
|
|
99
|
+
PRINT RESULTS
|
|
100
|
+
|
|
101
|
+
SENSITIVITY ON "A1: Raw materials" USING "EN15804+A2 (EF 3.1)" BY 20%
|
|
102
|
+
VARY cement_mass
|
|
103
|
+
VARY mixing_energy
|
|
104
|
+
END SENSITIVITY
|
|
105
|
+
|
|
106
|
+
SCENARIO "Baseline"
|
|
107
|
+
END SCENARIO
|
|
108
|
+
|
|
109
|
+
SCENARIO "Low cement"
|
|
110
|
+
LET cement_mass = 240
|
|
111
|
+
END SCENARIO
|
|
112
|
+
|
|
113
|
+
RUN SCENARIOS ON "A1: Raw materials" USING "EN15804+A2 (EF 3.1)"
|
|
114
|
+
SAVE RESULTS "scenarios.csv"
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Why?
|
|
118
|
+
|
|
119
|
+
Brightway is powerful but requires Python fluency. SimaPro is
|
|
120
|
+
point-and-click but not scriptable. olcaBASIC sits in between:
|
|
121
|
+
programmatic, reproducible LCA work that any environmental scientist
|
|
122
|
+
can read and write on day one.
|
|
123
|
+
|
|
124
|
+
## Requirements
|
|
125
|
+
|
|
126
|
+
- openLCA 2.x with IPC server running (port 8080)
|
|
127
|
+
- Python 3.10+
|
|
128
|
+
- `b280-olca-mcp` (installed automatically)
|
|
129
|
+
|
|
130
|
+
## Licence
|
|
131
|
+
|
|
132
|
+
MPL-2.0
|
|
133
|
+
|
|
134
|
+
## Links
|
|
135
|
+
|
|
136
|
+
- [Language specification](./olcaBASIC_Language_Specification_v1.md)
|
|
137
|
+
- [B280 openLCA MCP](https://github.com/Below280/B280-olca-MCP)
|
|
138
|
+
- [B280 Python IPC tools](https://github.com/Below280/openLCA-IPC-tools-python)
|
|
139
|
+
- [Below280](https://below280.com)
|
|
140
|
+
|
|
141
|
+
*Built by Below280. openLCA is developed by GreenDelta.*
|
|
142
|
+
*BASIC was created by Kemeny and Kurtz at Dartmouth College, 1964.*
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# olcaBASIC
|
|
2
|
+
|
|
3
|
+
```
|
|
4
|
+
___ _ ____ _ ____ _ ____ _ ____
|
|
5
|
+
/ _ \| | / ___| / \ | __ ) / \ / ___|| |/ ___|
|
|
6
|
+
| | | | | | | / _ \ | _ \ / _ \ \___ \| | |
|
|
7
|
+
| |_| | |__| |___ / ___ \| |_) / ___ \ ___) | | |___
|
|
8
|
+
\___/|_____\____/_/ \_\____/_/ \_\____/|_|\____|
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
**A simplified language to control openLCA, borrowing heavily from
|
|
12
|
+
the BASIC programming language (1964)**
|
|
13
|
+
|
|
14
|
+
olcaBASIC lets LCA practitioners build models, run calculations, and
|
|
15
|
+
analyse results without writing Python. It connects to openLCA via the
|
|
16
|
+
IPC server and translates simple, readable commands into the full power
|
|
17
|
+
of the openLCA calculation engine.
|
|
18
|
+
|
|
19
|
+
## Quick start
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
pip install olcabasic
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Start the IPC server in openLCA (Tools > Developer Tools > IPC Server),
|
|
26
|
+
then:
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
olcabasic
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
olcaBASIC v0.1.0
|
|
34
|
+
Connected to openLCA on port 8080 (ecoinvent 3.10)
|
|
35
|
+
Ready.
|
|
36
|
+
|
|
37
|
+
> PRINT PROCESSES("electricity", "", "GB")
|
|
38
|
+
electricity production, wind, 1-3MW | GB
|
|
39
|
+
electricity production, natural gas | GB
|
|
40
|
+
...
|
|
41
|
+
|
|
42
|
+
> PRINT METHODS("ReCiPe")
|
|
43
|
+
ReCiPe 2016 Midpoint (H)
|
|
44
|
+
ReCiPe 2016 Endpoint (H)
|
|
45
|
+
|
|
46
|
+
> CALCULATE "My System" USING "ReCiPe 2016 Midpoint (H)"
|
|
47
|
+
Climate change: 247.3 kg CO2-eq
|
|
48
|
+
Ozone depletion: 3.21e-6 kg CFC-11-eq
|
|
49
|
+
...
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Write programs
|
|
53
|
+
|
|
54
|
+
Save as `mymodel.baslca` and run with `olcabasic run mymodel.baslca`:
|
|
55
|
+
|
|
56
|
+
```basic
|
|
57
|
+
REM Concrete block EPD model
|
|
58
|
+
|
|
59
|
+
LET cement_mass = 300
|
|
60
|
+
LET water_cement_ratio = 0.45
|
|
61
|
+
LET mixing_energy = 12
|
|
62
|
+
|
|
63
|
+
FLOW "Concrete block", m3, PRODUCT
|
|
64
|
+
|
|
65
|
+
BRIDGE "BRIDGE | Cement | kg", kg
|
|
66
|
+
FOLDER "00: Concrete/Bridges"
|
|
67
|
+
PROVIDER "cement production, Portland | GB"
|
|
68
|
+
END BRIDGE
|
|
69
|
+
|
|
70
|
+
PROCESS "A1: Raw materials" LOCATION "GB"
|
|
71
|
+
FOLDER "00: Concrete/A1"
|
|
72
|
+
OUTPUT "Concrete block", 1, m3, PRODUCT
|
|
73
|
+
INPUT "BRIDGE | Cement | kg", cement_mass, kg
|
|
74
|
+
INPUT "BRIDGE | Sand | kg", 800, kg
|
|
75
|
+
INPUT "BRIDGE | UK grid | kWh", mixing_energy, kWh
|
|
76
|
+
END PROCESS
|
|
77
|
+
|
|
78
|
+
SYSTEM "A1: Raw materials"
|
|
79
|
+
CALCULATE "A1: Raw materials" USING "EN15804+A2 (EF 3.1)"
|
|
80
|
+
PRINT RESULTS
|
|
81
|
+
|
|
82
|
+
SENSITIVITY ON "A1: Raw materials" USING "EN15804+A2 (EF 3.1)" BY 20%
|
|
83
|
+
VARY cement_mass
|
|
84
|
+
VARY mixing_energy
|
|
85
|
+
END SENSITIVITY
|
|
86
|
+
|
|
87
|
+
SCENARIO "Baseline"
|
|
88
|
+
END SCENARIO
|
|
89
|
+
|
|
90
|
+
SCENARIO "Low cement"
|
|
91
|
+
LET cement_mass = 240
|
|
92
|
+
END SCENARIO
|
|
93
|
+
|
|
94
|
+
RUN SCENARIOS ON "A1: Raw materials" USING "EN15804+A2 (EF 3.1)"
|
|
95
|
+
SAVE RESULTS "scenarios.csv"
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Why?
|
|
99
|
+
|
|
100
|
+
Brightway is powerful but requires Python fluency. SimaPro is
|
|
101
|
+
point-and-click but not scriptable. olcaBASIC sits in between:
|
|
102
|
+
programmatic, reproducible LCA work that any environmental scientist
|
|
103
|
+
can read and write on day one.
|
|
104
|
+
|
|
105
|
+
## Requirements
|
|
106
|
+
|
|
107
|
+
- openLCA 2.x with IPC server running (port 8080)
|
|
108
|
+
- Python 3.10+
|
|
109
|
+
- `b280-olca-mcp` (installed automatically)
|
|
110
|
+
|
|
111
|
+
## Licence
|
|
112
|
+
|
|
113
|
+
MPL-2.0
|
|
114
|
+
|
|
115
|
+
## Links
|
|
116
|
+
|
|
117
|
+
- [Language specification](./olcaBASIC_Language_Specification_v1.md)
|
|
118
|
+
- [B280 openLCA MCP](https://github.com/Below280/B280-olca-MCP)
|
|
119
|
+
- [B280 Python IPC tools](https://github.com/Below280/openLCA-IPC-tools-python)
|
|
120
|
+
- [Below280](https://below280.com)
|
|
121
|
+
|
|
122
|
+
*Built by Below280. openLCA is developed by GreenDelta.*
|
|
123
|
+
*BASIC was created by Kemeny and Kurtz at Dartmouth College, 1964.*
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"""
|
|
2
|
+
olcaBASIC — entry point.
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
python -m olcabasic Interactive REPL
|
|
6
|
+
python -m olcabasic run file.baslca Run a program
|
|
7
|
+
python -m olcabasic --port 8090 Connect on a different port
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import argparse
|
|
11
|
+
import sys
|
|
12
|
+
|
|
13
|
+
BANNER = r"""
|
|
14
|
+
___ _ ____ _ ____ _ ____ _ ____
|
|
15
|
+
/ _ \| | / ___| / \ | __ ) / \ / ___|| |/ ___|
|
|
16
|
+
| | | | | | | / _ \ | _ \ / _ \ \___ \| | |
|
|
17
|
+
| |_| | |__| |___ / ___ \| |_) / ___ \ ___) | | |___
|
|
18
|
+
\___/|_____\____/_/ \_\____/_/ \_\____/|_|\____|
|
|
19
|
+
|
|
20
|
+
A simplified language to control openLCA, borrowing heavily
|
|
21
|
+
from the BASIC programming language (1964)
|
|
22
|
+
|
|
23
|
+
by Below280
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
VERSION = "0.1.0"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def main():
|
|
30
|
+
parser = argparse.ArgumentParser(
|
|
31
|
+
description="olcaBASIC — BASIC-like language for openLCA",
|
|
32
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
33
|
+
)
|
|
34
|
+
parser.add_argument(
|
|
35
|
+
"command", nargs="?", default=None,
|
|
36
|
+
help="'run' to execute a .baslca file",
|
|
37
|
+
)
|
|
38
|
+
parser.add_argument(
|
|
39
|
+
"file", nargs="?", default=None,
|
|
40
|
+
help="Path to .baslca file (used with 'run')",
|
|
41
|
+
)
|
|
42
|
+
parser.add_argument(
|
|
43
|
+
"--port", type=int, default=8080,
|
|
44
|
+
help="openLCA IPC port (default: 8080)",
|
|
45
|
+
)
|
|
46
|
+
parser.add_argument(
|
|
47
|
+
"--no-connect", action="store_true",
|
|
48
|
+
help="Start without connecting to openLCA (offline mode)",
|
|
49
|
+
)
|
|
50
|
+
parser.add_argument(
|
|
51
|
+
"--version", action="version",
|
|
52
|
+
version=f"olcaBASIC {VERSION}",
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
args = parser.parse_args()
|
|
56
|
+
|
|
57
|
+
print(BANNER)
|
|
58
|
+
print(f" olcaBASIC v{VERSION}")
|
|
59
|
+
|
|
60
|
+
# Import here so startup errors are caught cleanly
|
|
61
|
+
from .repl import REPL
|
|
62
|
+
from .interpreter import Interpreter
|
|
63
|
+
from .bridge import LCABridge
|
|
64
|
+
|
|
65
|
+
# Connect to openLCA
|
|
66
|
+
bridge = None
|
|
67
|
+
if not args.no_connect:
|
|
68
|
+
bridge = LCABridge(port=args.port)
|
|
69
|
+
if bridge.connect():
|
|
70
|
+
info = bridge.database_info()
|
|
71
|
+
family = info.get("database_family", "unknown")
|
|
72
|
+
procs = info.get("processes", "?")
|
|
73
|
+
methods = info.get("impact_methods", "?")
|
|
74
|
+
print(f" Connected to openLCA on port {args.port}")
|
|
75
|
+
print(f" Database: {procs} processes, {methods} methods")
|
|
76
|
+
print(f" Family: {family} (auto-detected)")
|
|
77
|
+
else:
|
|
78
|
+
print(f"\n WARNING: Cannot connect to openLCA on port {args.port}")
|
|
79
|
+
print(" Start the IPC server in openLCA:")
|
|
80
|
+
print(" Tools > Developer Tools > IPC Server > play button")
|
|
81
|
+
print(" Running in offline mode (search/build/calculate disabled)\n")
|
|
82
|
+
bridge = None
|
|
83
|
+
else:
|
|
84
|
+
print(" Offline mode (no openLCA connection)")
|
|
85
|
+
|
|
86
|
+
print(" Ready.\n")
|
|
87
|
+
|
|
88
|
+
interpreter = Interpreter(bridge)
|
|
89
|
+
|
|
90
|
+
if args.command == "run" and args.file:
|
|
91
|
+
# Program mode: run a .baslca file
|
|
92
|
+
try:
|
|
93
|
+
with open(args.file, "r") as f:
|
|
94
|
+
source = f.read()
|
|
95
|
+
interpreter.run_program(source, filename=args.file)
|
|
96
|
+
except FileNotFoundError:
|
|
97
|
+
print(f"File not found: {args.file}")
|
|
98
|
+
sys.exit(1)
|
|
99
|
+
except Exception as e:
|
|
100
|
+
print(f"Error: {e}")
|
|
101
|
+
sys.exit(1)
|
|
102
|
+
else:
|
|
103
|
+
# Interactive REPL
|
|
104
|
+
repl = REPL(interpreter)
|
|
105
|
+
repl.run()
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
if __name__ == "__main__":
|
|
109
|
+
main()
|