nc-gcode-interpreter 0.1.3__tar.gz → 0.1.5__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.
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/.github/workflows/build-and-release.yml +46 -32
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/Cargo.lock +1 -1
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/Cargo.toml +1 -1
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/PKG-INFO +7 -6
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/README.md +1 -1
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/ggroups/generate_pest.py +13 -1
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/ggroups/ggroups.pest +4 -1
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/pyproject.toml +6 -6
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/src/grammar.pest +6 -64
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/src/interpret_rules.rs +21 -12
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/src/interpreter.rs +39 -54
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/src/lib.rs +10 -4
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/src/main.rs +10 -6
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/src/state.rs +3 -3
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/src/types.rs +1 -3
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/.gitignore +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/CONTRIBUTING.md +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/Development.md +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/Example.MPF +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/LICENSE +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/TODO.md +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/examples/arrays.csv +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/examples/arrays.mpf +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/examples/basic_math.csv +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/examples/basic_math.mpf +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/examples/custom_vars.csv +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/examples/custom_vars.mpf +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/examples/defaults.csv +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/examples/defaults.mpf +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/examples/for_loop.csv +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/examples/for_loop.mpf +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/examples/if_statement.csv +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/examples/if_statement.mpf +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/examples/increment.csv +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/examples/increment.mpf +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/examples/loop.csv +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/examples/loop.mpf +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/examples/multiple_m_codes.csv +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/examples/multiple_m_codes.mpf +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/examples/simple.csv +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/examples/simple.mpf +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/examples/trans.csv +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/examples/trans.mpf +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/examples/variables.csv +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/examples/variables.mpf +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/ggroups/generate_modal_ggroups.py +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/ggroups/ggroups.json +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/ggroups/modal_groups.rs +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/python/example/minimal.py +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/python/nc_gcode_interpreter/__init__.py +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/python/tests/test_expected_output.py +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/rustfmt.toml +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/src/errors.rs +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/src/modal_groups.rs +0 -0
- {nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/uv.lock +0 -0
{nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/.github/workflows/build-and-release.yml
RENAMED
|
@@ -50,7 +50,8 @@ jobs:
|
|
|
50
50
|
uses: PyO3/maturin-action@v1
|
|
51
51
|
with:
|
|
52
52
|
target: ${{ matrix.platform.target }}
|
|
53
|
-
args: --release --out dist --find-interpreter -b bin
|
|
53
|
+
# args: --release --out dist --find-interpreter -b bin
|
|
54
|
+
args: --release --out dist --find-interpreter
|
|
54
55
|
sccache: 'true'
|
|
55
56
|
manylinux: auto
|
|
56
57
|
- name: Upload wheels
|
|
@@ -81,7 +82,8 @@ jobs:
|
|
|
81
82
|
# uses: PyO3/maturin-action@v1
|
|
82
83
|
# with:
|
|
83
84
|
# target: ${{ matrix.platform.target }}
|
|
84
|
-
#
|
|
85
|
+
# # args: --release --out dist --find-interpreter -b bin
|
|
86
|
+
# args: --release --out dist --find-interpreter
|
|
85
87
|
# sccache: 'true'
|
|
86
88
|
# manylinux: musllinux_1_2
|
|
87
89
|
# - name: Upload wheels
|
|
@@ -109,7 +111,8 @@ jobs:
|
|
|
109
111
|
uses: PyO3/maturin-action@v1
|
|
110
112
|
with:
|
|
111
113
|
target: ${{ matrix.platform.target }}
|
|
112
|
-
args: --release --out dist --find-interpreter -b bin
|
|
114
|
+
# args: --release --out dist --find-interpreter -b bin
|
|
115
|
+
args: --release --out dist --find-interpreter
|
|
113
116
|
sccache: 'true'
|
|
114
117
|
- name: Upload wheels
|
|
115
118
|
uses: actions/upload-artifact@v4
|
|
@@ -135,7 +138,8 @@ jobs:
|
|
|
135
138
|
uses: PyO3/maturin-action@v1
|
|
136
139
|
with:
|
|
137
140
|
target: ${{ matrix.platform.target }}
|
|
138
|
-
args: --release --out dist --find-interpreter -b bin
|
|
141
|
+
# args: --release --out dist --find-interpreter -b bin
|
|
142
|
+
args: --release --out dist --find-interpreter
|
|
139
143
|
sccache: 'true'
|
|
140
144
|
- name: Upload wheels
|
|
141
145
|
uses: actions/upload-artifact@v4
|
|
@@ -174,7 +178,8 @@ jobs:
|
|
|
174
178
|
# uses: PyO3/maturin-action@v1
|
|
175
179
|
# with:
|
|
176
180
|
# target: ${{ matrix.platform.target }}
|
|
177
|
-
#
|
|
181
|
+
# # args: --release --out dist -i ${{ env.PYTHON_VERSION }} -b bin
|
|
182
|
+
# args: --release --out dist -i ${{ env.PYTHON_VERSION }}
|
|
178
183
|
# sccache: 'true'
|
|
179
184
|
# rust-toolchain: nightly
|
|
180
185
|
# - name: Upload wheels
|
|
@@ -224,39 +229,48 @@ jobs:
|
|
|
224
229
|
with:
|
|
225
230
|
command: upload
|
|
226
231
|
args: --non-interactive --skip-existing wheels-*/*
|
|
227
|
-
- name: Extract binary and rename
|
|
228
|
-
env:
|
|
229
|
-
PROJECT_NAME: ${{ env.PROJECT_NAME }}
|
|
230
|
-
run: |
|
|
231
|
-
for wheel_dir in wheels-windows-* wheels-linux-* wheels-macos-*; do
|
|
232
|
-
arch=$(echo $wheel_dir | cut -d'-' -f3)
|
|
233
|
-
os=$(echo $wheel_dir | cut -d'-' -f2)
|
|
234
|
-
find ./$wheel_dir -name "*.whl" -exec sh -c '
|
|
235
|
-
wheel_name=$(basename "$1")
|
|
236
|
-
version=$(echo $wheel_name | sed -E "s/.*-([0-9]+\.[0-9]+\.[0-9]+)-.*/\1/")
|
|
237
|
-
unzip -d "$(dirname "$1")" "$1"
|
|
238
|
-
if [ "$2" = "windows" ]; then
|
|
239
|
-
binary_path=$(find "$(dirname "$1")" -name "*.exe")
|
|
240
|
-
if [ -n "$binary_path" ]; then
|
|
241
|
-
mv "$binary_path" "$(dirname "$binary_path")/${PROJECT_NAME}_${version}_${2}_${3}.exe"
|
|
242
|
-
fi
|
|
243
|
-
else
|
|
244
|
-
binary_path=$(find "$(dirname "$1")" -type f -executable)
|
|
245
|
-
if [ -n "$binary_path" ]; then
|
|
246
|
-
mv "$binary_path" "$(dirname "$binary_path")/${PROJECT_NAME}_${version}_${2}_${3}"
|
|
247
|
-
fi
|
|
248
|
-
fi
|
|
249
|
-
' _ {} "$os" "$arch" \;
|
|
250
|
-
done
|
|
251
232
|
- name: Upload to GitHub Release
|
|
252
233
|
uses: softprops/action-gh-release@v2
|
|
253
234
|
with:
|
|
254
235
|
files: |
|
|
255
236
|
wheels-sdist/*.tar.gz
|
|
256
237
|
wheels-windows-*/*.whl
|
|
257
|
-
wheels-windows-*/*.data/scripts/${{ env.PROJECT_NAME }}_*_windows_*.exe
|
|
258
238
|
wheels-linux-*/*.whl
|
|
259
|
-
wheels-linux-*/*.data/scripts/${{ env.PROJECT_NAME }}_*_linux_*
|
|
260
239
|
wheels-macos-*/*.whl
|
|
261
|
-
wheels-macos-*/*.data/scripts/${{ env.PROJECT_NAME }}_*_macos_*
|
|
262
240
|
prerelease: ${{ contains(github.ref, 'alpha') || contains(github.ref, 'beta') }}
|
|
241
|
+
# - name: Extract binary and rename
|
|
242
|
+
# env:
|
|
243
|
+
# PROJECT_NAME: ${{ env.PROJECT_NAME }}
|
|
244
|
+
# run: |
|
|
245
|
+
# for wheel_dir in wheels-windows-* wheels-linux-* wheels-macos-*; do
|
|
246
|
+
# arch=$(echo $wheel_dir | cut -d'-' -f3)
|
|
247
|
+
# os=$(echo $wheel_dir | cut -d'-' -f2)
|
|
248
|
+
# find ./$wheel_dir -name "*.whl" -exec sh -c '
|
|
249
|
+
# wheel_name=$(basename "$1")
|
|
250
|
+
# version=$(echo $wheel_name | sed -E "s/.*-([0-9]+\.[0-9]+\.[0-9]+)-.*/\1/")
|
|
251
|
+
# unzip -d "$(dirname "$1")" "$1"
|
|
252
|
+
# if [ "$2" = "windows" ]; then
|
|
253
|
+
# binary_path=$(find "$(dirname "$1")" -name "*.exe")
|
|
254
|
+
# if [ -n "$binary_path" ]; then
|
|
255
|
+
# mv "$binary_path" "$(dirname "$binary_path")/${PROJECT_NAME}_${version}_${2}_${3}.exe"
|
|
256
|
+
# fi
|
|
257
|
+
# else
|
|
258
|
+
# binary_path=$(find "$(dirname "$1")" -type f -executable)
|
|
259
|
+
# if [ -n "$binary_path" ]; then
|
|
260
|
+
# mv "$binary_path" "$(dirname "$binary_path")/${PROJECT_NAME}_${version}_${2}_${3}"
|
|
261
|
+
# fi
|
|
262
|
+
# fi
|
|
263
|
+
# ' _ {} "$os" "$arch" \;
|
|
264
|
+
# done
|
|
265
|
+
# - name: Upload to GitHub Release
|
|
266
|
+
# uses: softprops/action-gh-release@v2
|
|
267
|
+
# with:
|
|
268
|
+
# files: |
|
|
269
|
+
# wheels-sdist/*.tar.gz
|
|
270
|
+
# wheels-windows-*/*.whl
|
|
271
|
+
# wheels-windows-*/*.data/scripts/${{ env.PROJECT_NAME }}_*_windows_*.exe
|
|
272
|
+
# wheels-linux-*/*.whl
|
|
273
|
+
# wheels-linux-*/*.data/scripts/${{ env.PROJECT_NAME }}_*_linux_*
|
|
274
|
+
# wheels-macos-*/*.whl
|
|
275
|
+
# wheels-macos-*/*.data/scripts/${{ env.PROJECT_NAME }}_*_macos_*
|
|
276
|
+
# prerelease: ${{ contains(github.ref, 'alpha') || contains(github.ref, 'beta') }}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: nc-gcode-interpreter
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.5
|
|
4
4
|
Classifier: Programming Language :: Rust
|
|
5
5
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
6
6
|
Classifier: Programming Language :: Python :: 3.12
|
|
@@ -8,14 +8,15 @@ Classifier: License :: OSI Approved :: MIT License
|
|
|
8
8
|
Classifier: Operating System :: OS Independent
|
|
9
9
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
10
10
|
Requires-Dist: maturin >=1.7.4
|
|
11
|
+
Requires-Dist: polars >=1.9.0
|
|
11
12
|
License-File: LICENSE
|
|
12
13
|
Summary: A interpreter for NC (Numerical Control) code
|
|
13
|
-
Author-email:
|
|
14
|
+
Author-email: CEAD Group <software@ceadgroup.com>
|
|
14
15
|
Requires-Python: >=3.12
|
|
15
16
|
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
16
|
-
Project-URL: Homepage, https://github.com/
|
|
17
|
-
Project-URL: Repository, https://github.com/
|
|
18
|
-
Project-URL: Documentation, https://nc-gcode-interpreter.
|
|
17
|
+
Project-URL: Homepage, https://github.com/CEAD-group/nc-gcode-interpreter
|
|
18
|
+
Project-URL: Repository, https://github.com/CEAD-group/nc-gcode-interpreter.git
|
|
19
|
+
Project-URL: Documentation, https://github.com/CEAD-group/nc-gcode-interpreter/blob/main/README.md
|
|
19
20
|
|
|
20
21
|
# NC-GCode-Interpreter
|
|
21
22
|
|
|
@@ -83,7 +84,7 @@ Options:
|
|
|
83
84
|
-a, --axes <AXIS> Override default axis identifiers (comma-separated, e.g., "X,Y,Z")
|
|
84
85
|
-e, --extra-axes <EXTRA_AXIS> Add extra axis identifiers (comma-separated, e.g., "RA1,RA2")
|
|
85
86
|
-i, --initial_state <INITIAL_STATE> Optional initial_state file to initialize state
|
|
86
|
-
-l, --iteration_limit <LIMIT>
|
|
87
|
+
-l, --iteration_limit <LIMIT> Maximum number of iterations for loops [default: 10000]
|
|
87
88
|
-f, --disable-forward-fill Disable forward-filling of null values in axes columns
|
|
88
89
|
-h, --help Print help
|
|
89
90
|
-V, --version Print version
|
|
@@ -64,7 +64,7 @@ Options:
|
|
|
64
64
|
-a, --axes <AXIS> Override default axis identifiers (comma-separated, e.g., "X,Y,Z")
|
|
65
65
|
-e, --extra-axes <EXTRA_AXIS> Add extra axis identifiers (comma-separated, e.g., "RA1,RA2")
|
|
66
66
|
-i, --initial_state <INITIAL_STATE> Optional initial_state file to initialize state
|
|
67
|
-
-l, --iteration_limit <LIMIT>
|
|
67
|
+
-l, --iteration_limit <LIMIT> Maximum number of iterations for loops [default: 10000]
|
|
68
68
|
-f, --disable-forward-fill Disable forward-filling of null values in axes columns
|
|
69
69
|
-h, --help Print help
|
|
70
70
|
-V, --version Print version
|
|
@@ -18,6 +18,10 @@ def create_pest_grammar(g_groups):
|
|
|
18
18
|
grammar_parts.append(
|
|
19
19
|
"// Due to the way pest works, the sorting of the literals is important."
|
|
20
20
|
)
|
|
21
|
+
all_words = [
|
|
22
|
+
f'^"{entry["id"]}"' for group in g_groups for entry in group["entries"]
|
|
23
|
+
]
|
|
24
|
+
|
|
21
25
|
ggroup_names = []
|
|
22
26
|
for group in g_groups:
|
|
23
27
|
group_rules = []
|
|
@@ -28,7 +32,15 @@ def create_pest_grammar(g_groups):
|
|
|
28
32
|
grammar_parts.append(
|
|
29
33
|
f"{ggroup_name} = @{{({' | '.join(reversed(sorted(group_rules)))}) ~ !(ASCII_ALPHANUMERIC) }}"
|
|
30
34
|
)
|
|
31
|
-
|
|
35
|
+
|
|
36
|
+
grammar_parts.append(
|
|
37
|
+
f"\ngcommand_list = @{{({' | '.join(reversed(sorted(all_words)))}) ~ !(ASCII_ALPHANUMERIC) }}"
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
grammar_parts.append('g_command_numbered = { &("G" ~ ASCII_DIGIT+) ~ g_command }')
|
|
41
|
+
grammar_parts.append(
|
|
42
|
+
f"g_command = {{ &gcommand_list ~ ({' | '.join(ggroup_names)})}}"
|
|
43
|
+
)
|
|
32
44
|
return "\n".join(grammar_parts)
|
|
33
45
|
|
|
34
46
|
|
|
@@ -60,4 +60,7 @@ gg59_area_limit = @{(^"WALCS9" | ^"WALCS8" | ^"WALCS7" | ^"WALCS6" | ^"WALCS5" |
|
|
|
60
60
|
gg61_tool_orient_smooth = @{(^"ORISON" | ^"ORISOF") ~ !(ASCII_ALPHANUMERIC) }
|
|
61
61
|
gg62_repos_non_modal = @{(^"RMNBL" | ^"RMIBL" | ^"RMEBL" | ^"RMBBL") ~ !(ASCII_ALPHANUMERIC) }
|
|
62
62
|
gg64_grinding_frames = @{(^"GFRAME[9]" | ^"GFRAME[99]" | ^"GFRAME[98]" | ^"GFRAME[97]" | ^"GFRAME[96]" | ^"GFRAME[95]" | ^"GFRAME[94]" | ^"GFRAME[93]" | ^"GFRAME[92]" | ^"GFRAME[91]" | ^"GFRAME[90]" | ^"GFRAME[8]" | ^"GFRAME[89]" | ^"GFRAME[88]" | ^"GFRAME[87]" | ^"GFRAME[86]" | ^"GFRAME[85]" | ^"GFRAME[84]" | ^"GFRAME[83]" | ^"GFRAME[82]" | ^"GFRAME[81]" | ^"GFRAME[80]" | ^"GFRAME[7]" | ^"GFRAME[79]" | ^"GFRAME[78]" | ^"GFRAME[77]" | ^"GFRAME[76]" | ^"GFRAME[75]" | ^"GFRAME[74]" | ^"GFRAME[73]" | ^"GFRAME[72]" | ^"GFRAME[71]" | ^"GFRAME[70]" | ^"GFRAME[6]" | ^"GFRAME[69]" | ^"GFRAME[68]" | ^"GFRAME[67]" | ^"GFRAME[66]" | ^"GFRAME[65]" | ^"GFRAME[64]" | ^"GFRAME[63]" | ^"GFRAME[62]" | ^"GFRAME[61]" | ^"GFRAME[60]" | ^"GFRAME[5]" | ^"GFRAME[59]" | ^"GFRAME[58]" | ^"GFRAME[57]" | ^"GFRAME[56]" | ^"GFRAME[55]" | ^"GFRAME[54]" | ^"GFRAME[53]" | ^"GFRAME[52]" | ^"GFRAME[51]" | ^"GFRAME[50]" | ^"GFRAME[4]" | ^"GFRAME[49]" | ^"GFRAME[48]" | ^"GFRAME[47]" | ^"GFRAME[46]" | ^"GFRAME[45]" | ^"GFRAME[44]" | ^"GFRAME[43]" | ^"GFRAME[42]" | ^"GFRAME[41]" | ^"GFRAME[40]" | ^"GFRAME[3]" | ^"GFRAME[39]" | ^"GFRAME[38]" | ^"GFRAME[37]" | ^"GFRAME[36]" | ^"GFRAME[35]" | ^"GFRAME[34]" | ^"GFRAME[33]" | ^"GFRAME[32]" | ^"GFRAME[31]" | ^"GFRAME[30]" | ^"GFRAME[2]" | ^"GFRAME[29]" | ^"GFRAME[28]" | ^"GFRAME[27]" | ^"GFRAME[26]" | ^"GFRAME[25]" | ^"GFRAME[24]" | ^"GFRAME[23]" | ^"GFRAME[22]" | ^"GFRAME[21]" | ^"GFRAME[20]" | ^"GFRAME[1]" | ^"GFRAME[19]" | ^"GFRAME[18]" | ^"GFRAME[17]" | ^"GFRAME[16]" | ^"GFRAME[15]" | ^"GFRAME[14]" | ^"GFRAME[13]" | ^"GFRAME[12]" | ^"GFRAME[11]" | ^"GFRAME[10]" | ^"GFRAME[100]" | ^"GFRAME[0]") ~ !(ASCII_ALPHANUMERIC) }
|
|
63
|
-
|
|
63
|
+
|
|
64
|
+
gcommand_list = @{(^"WALIMON" | ^"WALIMOF" | ^"WALCS9" | ^"WALCS8" | ^"WALCS7" | ^"WALCS6" | ^"WALCS5" | ^"WALCS4" | ^"WALCS3" | ^"WALCS2" | ^"WALCS10" | ^"WALCS1" | ^"WALCS0" | ^"UPATH" | ^"TRANS" | ^"TOWWCS" | ^"TOWTCS" | ^"TOWSTD" | ^"TOWMCS" | ^"TOWKCS" | ^"TOWBCS" | ^"TOROTZ" | ^"TOROTY" | ^"TOROTX" | ^"TOROTOF" | ^"TOROT" | ^"TOFRAMEZ" | ^"TOFRAMEY" | ^"TOFRAMEX" | ^"TOFRAME" | ^"TCOFRZ" | ^"TCOFRY" | ^"TCOFRX" | ^"TCOFR" | ^"TCOABS" | ^"SUPD" | ^"SUPA" | ^"STOPFIFO" | ^"STARTFIFO" | ^"SPOF" | ^"SPATH" | ^"SONS" | ^"SON" | ^"SOFT" | ^"SCALE" | ^"RTLION" | ^"RTLIOF" | ^"ROTS" | ^"ROT" | ^"RMNBL" | ^"RMN" | ^"RMIBL" | ^"RMI" | ^"RMEBL" | ^"RME" | ^"RMBBL" | ^"RMB" | ^"REPOSQA" | ^"REPOSQ" | ^"REPOSL" | ^"REPOSHA" | ^"REPOSH" | ^"REPOSA" | ^"PTPWOC" | ^"PTPG0" | ^"PTP" | ^"PONS" | ^"PON" | ^"POLY" | ^"PDELAYON" | ^"PDELAYOF" | ^"PAROTOF" | ^"PAROT" | ^"OST" | ^"OSSE" | ^"OSS" | ^"OSOF" | ^"OSD" | ^"OSC" | ^"ORIWKS" | ^"ORIVIRT2" | ^"ORIVIRT1" | ^"ORIVECT" | ^"ORISON" | ^"ORISOF" | ^"ORIRPY2" | ^"ORIRPY" | ^"ORIROTT" | ^"ORIROTR" | ^"ORIROTC" | ^"ORIROTA" | ^"ORIPLANE" | ^"ORIPATHS" | ^"ORIPATH" | ^"ORIMKS" | ^"ORIEULER" | ^"ORID" | ^"ORICURVE" | ^"ORICONTO" | ^"ORICONIO" | ^"ORICONCW" | ^"ORICONCCW" | ^"ORIC" | ^"ORIAXPOS" | ^"ORIAXES" | ^"OEMIPO2" | ^"OEMIPO1" | ^"NORM" | ^"MIRROR" | ^"LFWP" | ^"LFTXT" | ^"LFPOS" | ^"LFON" | ^"LFOF" | ^"KONTT" | ^"KONTC" | ^"KONT" | ^"INVCW" | ^"INVCCW" | ^"GFRAME[9]" | ^"GFRAME[99]" | ^"GFRAME[98]" | ^"GFRAME[97]" | ^"GFRAME[96]" | ^"GFRAME[95]" | ^"GFRAME[94]" | ^"GFRAME[93]" | ^"GFRAME[92]" | ^"GFRAME[91]" | ^"GFRAME[90]" | ^"GFRAME[8]" | ^"GFRAME[89]" | ^"GFRAME[88]" | ^"GFRAME[87]" | ^"GFRAME[86]" | ^"GFRAME[85]" | ^"GFRAME[84]" | ^"GFRAME[83]" | ^"GFRAME[82]" | ^"GFRAME[81]" | ^"GFRAME[80]" | ^"GFRAME[7]" | ^"GFRAME[79]" | ^"GFRAME[78]" | ^"GFRAME[77]" | ^"GFRAME[76]" | ^"GFRAME[75]" | ^"GFRAME[74]" | ^"GFRAME[73]" | ^"GFRAME[72]" | ^"GFRAME[71]" | ^"GFRAME[70]" | ^"GFRAME[6]" | ^"GFRAME[69]" | ^"GFRAME[68]" | ^"GFRAME[67]" | ^"GFRAME[66]" | ^"GFRAME[65]" | ^"GFRAME[64]" | ^"GFRAME[63]" | ^"GFRAME[62]" | ^"GFRAME[61]" | ^"GFRAME[60]" | ^"GFRAME[5]" | ^"GFRAME[59]" | ^"GFRAME[58]" | ^"GFRAME[57]" | ^"GFRAME[56]" | ^"GFRAME[55]" | ^"GFRAME[54]" | ^"GFRAME[53]" | ^"GFRAME[52]" | ^"GFRAME[51]" | ^"GFRAME[50]" | ^"GFRAME[4]" | ^"GFRAME[49]" | ^"GFRAME[48]" | ^"GFRAME[47]" | ^"GFRAME[46]" | ^"GFRAME[45]" | ^"GFRAME[44]" | ^"GFRAME[43]" | ^"GFRAME[42]" | ^"GFRAME[41]" | ^"GFRAME[40]" | ^"GFRAME[3]" | ^"GFRAME[39]" | ^"GFRAME[38]" | ^"GFRAME[37]" | ^"GFRAME[36]" | ^"GFRAME[35]" | ^"GFRAME[34]" | ^"GFRAME[33]" | ^"GFRAME[32]" | ^"GFRAME[31]" | ^"GFRAME[30]" | ^"GFRAME[2]" | ^"GFRAME[29]" | ^"GFRAME[28]" | ^"GFRAME[27]" | ^"GFRAME[26]" | ^"GFRAME[25]" | ^"GFRAME[24]" | ^"GFRAME[23]" | ^"GFRAME[22]" | ^"GFRAME[21]" | ^"GFRAME[20]" | ^"GFRAME[1]" | ^"GFRAME[19]" | ^"GFRAME[18]" | ^"GFRAME[17]" | ^"GFRAME[16]" | ^"GFRAME[15]" | ^"GFRAME[14]" | ^"GFRAME[13]" | ^"GFRAME[12]" | ^"GFRAME[11]" | ^"GFRAME[10]" | ^"GFRAME[100]" | ^"GFRAME[0]" | ^"G973" | ^"G972" | ^"G971" | ^"G97" | ^"G962" | ^"G961" | ^"G96" | ^"G952" | ^"G95" | ^"G942" | ^"G94" | ^"G931" | ^"G93" | ^"G91" | ^"G90" | ^"G9" | ^"G829" | ^"G828" | ^"G827" | ^"G826" | ^"G825" | ^"G824" | ^"G823" | ^"G822" | ^"G821" | ^"G820" | ^"G819" | ^"G818" | ^"G817" | ^"G816" | ^"G815" | ^"G814" | ^"G813" | ^"G812" | ^"G811" | ^"G810" | ^"G75" | ^"G74" | ^"G710" | ^"G71" | ^"G700" | ^"G70" | ^"G7" | ^"G645" | ^"G644" | ^"G643" | ^"G642" | ^"G641" | ^"G64" | ^"G63" | ^"G621" | ^"G62" | ^"G603" | ^"G602" | ^"G601" | ^"G60" | ^"G599" | ^"G598" | ^"G597" | ^"G596" | ^"G595" | ^"G594" | ^"G593" | ^"G592" | ^"G591" | ^"G590" | ^"G59" | ^"G589" | ^"G588" | ^"G587" | ^"G586" | ^"G585" | ^"G584" | ^"G583" | ^"G582" | ^"G581" | ^"G580" | ^"G58" | ^"G579" | ^"G578" | ^"G577" | ^"G576" | ^"G575" | ^"G574" | ^"G573" | ^"G572" | ^"G571" | ^"G570" | ^"G57" | ^"G569" | ^"G568" | ^"G567" | ^"G566" | ^"G565" | ^"G564" | ^"G563" | ^"G562" | ^"G561" | ^"G560" | ^"G56" | ^"G559" | ^"G558" | ^"G557" | ^"G556" | ^"G555" | ^"G554" | ^"G553" | ^"G552" | ^"G551" | ^"G550" | ^"G55" | ^"G549" | ^"G548" | ^"G547" | ^"G546" | ^"G545" | ^"G544" | ^"G543" | ^"G542" | ^"G541" | ^"G540" | ^"G54" | ^"G539" | ^"G538" | ^"G537" | ^"G536" | ^"G535" | ^"G534" | ^"G533" | ^"G532" | ^"G531" | ^"G530" | ^"G53" | ^"G529" | ^"G528" | ^"G527" | ^"G526" | ^"G525" | ^"G524" | ^"G523" | ^"G522" | ^"G521" | ^"G520" | ^"G519" | ^"G518" | ^"G517" | ^"G516" | ^"G515" | ^"G514" | ^"G513" | ^"G512" | ^"G511" | ^"G510" | ^"G509" | ^"G508" | ^"G507" | ^"G506" | ^"G505" | ^"G500" | ^"G5" | ^"G462" | ^"G461" | ^"G460" | ^"G451" | ^"G450" | ^"G42" | ^"G41" | ^"G40" | ^"G4" | ^"G35" | ^"G348" | ^"G347" | ^"G341" | ^"G340" | ^"G34" | ^"G336" | ^"G335" | ^"G332" | ^"G331" | ^"G33" | ^"G3" | ^"G291" | ^"G290" | ^"G26" | ^"G25" | ^"G248" | ^"G247" | ^"G2" | ^"G19" | ^"G18" | ^"G17" | ^"G153" | ^"G148" | ^"G147" | ^"G143" | ^"G142" | ^"G141" | ^"G140" | ^"G112" | ^"G111" | ^"G110" | ^"G1" | ^"G0" | ^"FTOCON" | ^"FTOCOF" | ^"FNORM" | ^"FLIN" | ^"FIFOCTRL" | ^"FFWON" | ^"FFWOF" | ^"FENDNORM" | ^"FCUB" | ^"ETAN" | ^"ENAT" | ^"EAUTO" | ^"DYNSEMIFIN" | ^"DYNROUGH" | ^"DYNPREC" | ^"DYNPOS" | ^"DYNNORM" | ^"DYNFINISH" | ^"DRIVE" | ^"DIAMON" | ^"DIAMOF" | ^"DIAMCYCOF" | ^"DIAM90" | ^"CUTCONON" | ^"CUTCONOF" | ^"CUT3DFS" | ^"CUT3DFF" | ^"CUT3DFD" | ^"CUT3DF" | ^"CUT3DCD" | ^"CUT3DCCD" | ^"CUT3DCC" | ^"CUT3DC" | ^"CUT2DFD" | ^"CUT2DF" | ^"CUT2DD" | ^"CUT2D" | ^"CT" | ^"CSPLINE" | ^"CPRECON" | ^"CPRECOF" | ^"CP" | ^"COMPSURF" | ^"COMPON" | ^"COMPOF" | ^"COMPCURV" | ^"COMPCAD" | ^"CIP" | ^"CFTCP" | ^"CFIN" | ^"CFC" | ^"CDON" | ^"CDOF2" | ^"CDOF" | ^"BTAN" | ^"BSPLINE" | ^"BRISK" | ^"BNAT" | ^"BAUTO" | ^"ATRANS" | ^"ASPLINE" | ^"ASCALE" | ^"AROTS" | ^"AROT" | ^"AMIRROR") ~ !(ASCII_ALPHANUMERIC) }
|
|
65
|
+
g_command_numbered = { &("G" ~ ASCII_DIGIT+) ~ g_command }
|
|
66
|
+
g_command = { &gcommand_list ~ (gg01_motion | gg02_wait | gg03_frame_area_limit | gg04_fifo | gg06_plane_select | gg07_tool_radius | gg08_work_offset | gg09_frame_tool_suppress | gg10_exact_stop_mode | gg11_exact_stop_non_modal | gg12_block_change_g60_g9 | gg13_wp_measure | gg14_wp_measure_mode | gg15_feed_type | gg16_feedrate_override | gg17_approach_retract_tool | gg18_corner_behavior | gg19_curve_start_spline | gg20_curve_end_spline | gg21_accel_profile | gg22_tool_offset_type | gg23_collision_monitor | gg24_precontrol | gg25_tool_orient_ref | gg26_repos_mode | gg27_tool_offset_change | gg28_area_limit | gg29_rad_diam_prog | gg30_nc_compress | gg31_oem_g | gg32_oem_g | gg33_fine_tool_offset | gg34_tool_orient_smooth | gg35_punch_nibble | gg36_punch_delay | gg37_feedrate_profile | gg39_contour_acc | gg40_tool_radius_const | gg41_thread_interrupt | gg42_tool_carrier | gg43_sar_approach | gg44_sar_segment | gg45_path_ref_fgroup | gg46_plane_fast_retract | gg47_mode_switchover | gg48_approach_retract_trc | gg49_ptp_motion | gg50_orient_prog | gg51_interp_type_orient | gg52_frame_rot_wp | gg53_tool_wear | gg54_vector_rot_poly | gg55_rapid_traverse | gg56_frame_rot_tool | gg57_corner_decel | gg58_dyn_resp_path | gg59_area_limit | gg61_tool_orient_smooth | gg62_repos_non_modal | gg64_grinding_frames)}
|
|
@@ -4,9 +4,9 @@ build-backend = "maturin"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "nc-gcode-interpreter"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.5"
|
|
8
8
|
description = "A interpreter for NC (Numerical Control) code"
|
|
9
|
-
authors = [{ name = "
|
|
9
|
+
authors = [{ name = "CEAD Group", email = "software@ceadgroup.com" }]
|
|
10
10
|
requires-python = ">=3.12"
|
|
11
11
|
classifiers = [
|
|
12
12
|
"Programming Language :: Rust",
|
|
@@ -16,15 +16,15 @@ classifiers = [
|
|
|
16
16
|
"Operating System :: OS Independent",
|
|
17
17
|
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
18
18
|
]
|
|
19
|
-
|
|
20
19
|
dependencies = [
|
|
21
20
|
"maturin>=1.7.4",
|
|
21
|
+
"polars>=1.9.0"
|
|
22
22
|
]
|
|
23
23
|
|
|
24
24
|
[project.urls]
|
|
25
|
-
Homepage = "https://github.com/
|
|
26
|
-
Repository = "https://github.com/
|
|
27
|
-
Documentation = "https://nc-gcode-interpreter.
|
|
25
|
+
Homepage = "https://github.com/CEAD-group/nc-gcode-interpreter"
|
|
26
|
+
Repository = "https://github.com/CEAD-group/nc-gcode-interpreter.git"
|
|
27
|
+
Documentation = "https://github.com/CEAD-group/nc-gcode-interpreter/blob/main/README.md"
|
|
28
28
|
|
|
29
29
|
[tool.maturin]
|
|
30
30
|
features = ["pyo3/extension-module"]
|
|
@@ -31,10 +31,11 @@ condition = { base_condition | ("(" ~ base_condition ~ ")") }
|
|
|
31
31
|
base_condition = _{ (expression ~ relational_operator ~ expression) | expression }
|
|
32
32
|
relational_operator = { "<=" | ">=" | "<" | ">" | "==" | "<>" }
|
|
33
33
|
statement = {
|
|
34
|
-
|
|
34
|
+
g_command_numbered
|
|
35
35
|
| m_command
|
|
36
36
|
| assignment_multi
|
|
37
37
|
| assignment
|
|
38
|
+
| g_command
|
|
38
39
|
| function_call
|
|
39
40
|
| tool_selection
|
|
40
41
|
}
|
|
@@ -124,7 +125,6 @@ m_command = { "M" ~ ASCII_DIGIT+ }
|
|
|
124
125
|
// G-Code ggroups
|
|
125
126
|
// This Pest grammar file is auto-generated from G-Code definitions.
|
|
126
127
|
// Due to the way pest works, the sorting of the literals is important.
|
|
127
|
-
|
|
128
128
|
gg01_motion = @{ (^"POLY" | ^"OEMIPO2" | ^"OEMIPO1" | ^"INVCW" | ^"INVCCW" | ^"G35" | ^"G34" | ^"G336" | ^"G335" | ^"G332" | ^"G331" | ^"G33" | ^"G3" | ^"G2" | ^"G1" | ^"G0" | ^"CT" | ^"CSPLINE" | ^"CIP" | ^"BSPLINE" | ^"ASPLINE") ~ !(ASCII_ALPHANUMERIC) }
|
|
129
129
|
gg02_wait = @{ (^"REPOSQA" | ^"REPOSQ" | ^"REPOSL" | ^"REPOSHA" | ^"REPOSH" | ^"REPOSA" | ^"G75" | ^"G74" | ^"G7" | ^"G63" | ^"G5" | ^"G4" | ^"G348" | ^"G347" | ^"G248" | ^"G247" | ^"G148" | ^"G147") ~ !(ASCII_ALPHANUMERIC) }
|
|
130
130
|
gg03_frame_area_limit = @{ (^"TRANS" | ^"SCALE" | ^"ROTS" | ^"ROT" | ^"MIRROR" | ^"G59" | ^"G58" | ^"G26" | ^"G25" | ^"G112" | ^"G111" | ^"G110" | ^"ATRANS" | ^"ASCALE" | ^"AROTS" | ^"AROT" | ^"AMIRROR") ~ !(ASCII_ALPHANUMERIC) }
|
|
@@ -185,65 +185,7 @@ gg59_area_limit = @{ (^"WALCS9" | ^"WALCS8" | ^"WALCS7" | ^"WALCS6" |
|
|
|
185
185
|
gg61_tool_orient_smooth = @{ (^"ORISON" | ^"ORISOF") ~ !(ASCII_ALPHANUMERIC) }
|
|
186
186
|
gg62_repos_non_modal = @{ (^"RMNBL" | ^"RMIBL" | ^"RMEBL" | ^"RMBBL") ~ !(ASCII_ALPHANUMERIC) }
|
|
187
187
|
gg64_grinding_frames = @{ (^"GFRAME[9]" | ^"GFRAME[99]" | ^"GFRAME[98]" | ^"GFRAME[97]" | ^"GFRAME[96]" | ^"GFRAME[95]" | ^"GFRAME[94]" | ^"GFRAME[93]" | ^"GFRAME[92]" | ^"GFRAME[91]" | ^"GFRAME[90]" | ^"GFRAME[8]" | ^"GFRAME[89]" | ^"GFRAME[88]" | ^"GFRAME[87]" | ^"GFRAME[86]" | ^"GFRAME[85]" | ^"GFRAME[84]" | ^"GFRAME[83]" | ^"GFRAME[82]" | ^"GFRAME[81]" | ^"GFRAME[80]" | ^"GFRAME[7]" | ^"GFRAME[79]" | ^"GFRAME[78]" | ^"GFRAME[77]" | ^"GFRAME[76]" | ^"GFRAME[75]" | ^"GFRAME[74]" | ^"GFRAME[73]" | ^"GFRAME[72]" | ^"GFRAME[71]" | ^"GFRAME[70]" | ^"GFRAME[6]" | ^"GFRAME[69]" | ^"GFRAME[68]" | ^"GFRAME[67]" | ^"GFRAME[66]" | ^"GFRAME[65]" | ^"GFRAME[64]" | ^"GFRAME[63]" | ^"GFRAME[62]" | ^"GFRAME[61]" | ^"GFRAME[60]" | ^"GFRAME[5]" | ^"GFRAME[59]" | ^"GFRAME[58]" | ^"GFRAME[57]" | ^"GFRAME[56]" | ^"GFRAME[55]" | ^"GFRAME[54]" | ^"GFRAME[53]" | ^"GFRAME[52]" | ^"GFRAME[51]" | ^"GFRAME[50]" | ^"GFRAME[4]" | ^"GFRAME[49]" | ^"GFRAME[48]" | ^"GFRAME[47]" | ^"GFRAME[46]" | ^"GFRAME[45]" | ^"GFRAME[44]" | ^"GFRAME[43]" | ^"GFRAME[42]" | ^"GFRAME[41]" | ^"GFRAME[40]" | ^"GFRAME[3]" | ^"GFRAME[39]" | ^"GFRAME[38]" | ^"GFRAME[37]" | ^"GFRAME[36]" | ^"GFRAME[35]" | ^"GFRAME[34]" | ^"GFRAME[33]" | ^"GFRAME[32]" | ^"GFRAME[31]" | ^"GFRAME[30]" | ^"GFRAME[2]" | ^"GFRAME[29]" | ^"GFRAME[28]" | ^"GFRAME[27]" | ^"GFRAME[26]" | ^"GFRAME[25]" | ^"GFRAME[24]" | ^"GFRAME[23]" | ^"GFRAME[22]" | ^"GFRAME[21]" | ^"GFRAME[20]" | ^"GFRAME[1]" | ^"GFRAME[19]" | ^"GFRAME[18]" | ^"GFRAME[17]" | ^"GFRAME[16]" | ^"GFRAME[15]" | ^"GFRAME[14]" | ^"GFRAME[13]" | ^"GFRAME[12]" | ^"GFRAME[11]" | ^"GFRAME[10]" | ^"GFRAME[100]" | ^"GFRAME[0]") ~ !(ASCII_ALPHANUMERIC) }
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
| gg03_frame_area_limit
|
|
192
|
-
| gg04_fifo
|
|
193
|
-
| gg06_plane_select
|
|
194
|
-
| gg07_tool_radius
|
|
195
|
-
| gg08_work_offset
|
|
196
|
-
| gg09_frame_tool_suppress
|
|
197
|
-
| gg10_exact_stop_mode
|
|
198
|
-
| gg11_exact_stop_non_modal
|
|
199
|
-
| gg12_block_change_g60_g9
|
|
200
|
-
| gg13_wp_measure
|
|
201
|
-
| gg14_wp_measure_mode
|
|
202
|
-
| gg15_feed_type
|
|
203
|
-
| gg16_feedrate_override
|
|
204
|
-
| gg17_approach_retract_tool
|
|
205
|
-
| gg18_corner_behavior
|
|
206
|
-
| gg19_curve_start_spline
|
|
207
|
-
| gg20_curve_end_spline
|
|
208
|
-
| gg21_accel_profile
|
|
209
|
-
| gg22_tool_offset_type
|
|
210
|
-
| gg23_collision_monitor
|
|
211
|
-
| gg24_precontrol
|
|
212
|
-
| gg25_tool_orient_ref
|
|
213
|
-
| gg26_repos_mode
|
|
214
|
-
| gg27_tool_offset_change
|
|
215
|
-
| gg28_area_limit
|
|
216
|
-
| gg29_rad_diam_prog
|
|
217
|
-
| gg30_nc_compress
|
|
218
|
-
| gg31_oem_g
|
|
219
|
-
| gg32_oem_g
|
|
220
|
-
| gg33_fine_tool_offset
|
|
221
|
-
| gg34_tool_orient_smooth
|
|
222
|
-
| gg35_punch_nibble
|
|
223
|
-
| gg36_punch_delay
|
|
224
|
-
| gg37_feedrate_profile
|
|
225
|
-
| gg39_contour_acc
|
|
226
|
-
| gg40_tool_radius_const
|
|
227
|
-
| gg41_thread_interrupt
|
|
228
|
-
| gg42_tool_carrier
|
|
229
|
-
| gg43_sar_approach
|
|
230
|
-
| gg44_sar_segment
|
|
231
|
-
| gg45_path_ref_fgroup
|
|
232
|
-
| gg46_plane_fast_retract
|
|
233
|
-
| gg47_mode_switchover
|
|
234
|
-
| gg48_approach_retract_trc
|
|
235
|
-
| gg49_ptp_motion
|
|
236
|
-
| gg50_orient_prog
|
|
237
|
-
| gg51_interp_type_orient
|
|
238
|
-
| gg52_frame_rot_wp
|
|
239
|
-
| gg53_tool_wear
|
|
240
|
-
| gg54_vector_rot_poly
|
|
241
|
-
| gg55_rapid_traverse
|
|
242
|
-
| gg56_frame_rot_tool
|
|
243
|
-
| gg57_corner_decel
|
|
244
|
-
| gg58_dyn_resp_path
|
|
245
|
-
| gg59_area_limit
|
|
246
|
-
| gg61_tool_orient_smooth
|
|
247
|
-
| gg62_repos_non_modal
|
|
248
|
-
| gg64_grinding_frames
|
|
249
|
-
}
|
|
188
|
+
|
|
189
|
+
gcommand_list = @{ (^"WALIMON" | ^"WALIMOF" | ^"WALCS9" | ^"WALCS8" | ^"WALCS7" | ^"WALCS6" | ^"WALCS5" | ^"WALCS4" | ^"WALCS3" | ^"WALCS2" | ^"WALCS10" | ^"WALCS1" | ^"WALCS0" | ^"UPATH" | ^"TRANS" | ^"TOWWCS" | ^"TOWTCS" | ^"TOWSTD" | ^"TOWMCS" | ^"TOWKCS" | ^"TOWBCS" | ^"TOROTZ" | ^"TOROTY" | ^"TOROTX" | ^"TOROTOF" | ^"TOROT" | ^"TOFRAMEZ" | ^"TOFRAMEY" | ^"TOFRAMEX" | ^"TOFRAME" | ^"TCOFRZ" | ^"TCOFRY" | ^"TCOFRX" | ^"TCOFR" | ^"TCOABS" | ^"SUPD" | ^"SUPA" | ^"STOPFIFO" | ^"STARTFIFO" | ^"SPOF" | ^"SPATH" | ^"SONS" | ^"SON" | ^"SOFT" | ^"SCALE" | ^"RTLION" | ^"RTLIOF" | ^"ROTS" | ^"ROT" | ^"RMNBL" | ^"RMN" | ^"RMIBL" | ^"RMI" | ^"RMEBL" | ^"RME" | ^"RMBBL" | ^"RMB" | ^"REPOSQA" | ^"REPOSQ" | ^"REPOSL" | ^"REPOSHA" | ^"REPOSH" | ^"REPOSA" | ^"PTPWOC" | ^"PTPG0" | ^"PTP" | ^"PONS" | ^"PON" | ^"POLY" | ^"PDELAYON" | ^"PDELAYOF" | ^"PAROTOF" | ^"PAROT" | ^"OST" | ^"OSSE" | ^"OSS" | ^"OSOF" | ^"OSD" | ^"OSC" | ^"ORIWKS" | ^"ORIVIRT2" | ^"ORIVIRT1" | ^"ORIVECT" | ^"ORISON" | ^"ORISOF" | ^"ORIRPY2" | ^"ORIRPY" | ^"ORIROTT" | ^"ORIROTR" | ^"ORIROTC" | ^"ORIROTA" | ^"ORIPLANE" | ^"ORIPATHS" | ^"ORIPATH" | ^"ORIMKS" | ^"ORIEULER" | ^"ORID" | ^"ORICURVE" | ^"ORICONTO" | ^"ORICONIO" | ^"ORICONCW" | ^"ORICONCCW" | ^"ORIC" | ^"ORIAXPOS" | ^"ORIAXES" | ^"OEMIPO2" | ^"OEMIPO1" | ^"NORM" | ^"MIRROR" | ^"LFWP" | ^"LFTXT" | ^"LFPOS" | ^"LFON" | ^"LFOF" | ^"KONTT" | ^"KONTC" | ^"KONT" | ^"INVCW" | ^"INVCCW" | ^"GFRAME[9]" | ^"GFRAME[99]" | ^"GFRAME[98]" | ^"GFRAME[97]" | ^"GFRAME[96]" | ^"GFRAME[95]" | ^"GFRAME[94]" | ^"GFRAME[93]" | ^"GFRAME[92]" | ^"GFRAME[91]" | ^"GFRAME[90]" | ^"GFRAME[8]" | ^"GFRAME[89]" | ^"GFRAME[88]" | ^"GFRAME[87]" | ^"GFRAME[86]" | ^"GFRAME[85]" | ^"GFRAME[84]" | ^"GFRAME[83]" | ^"GFRAME[82]" | ^"GFRAME[81]" | ^"GFRAME[80]" | ^"GFRAME[7]" | ^"GFRAME[79]" | ^"GFRAME[78]" | ^"GFRAME[77]" | ^"GFRAME[76]" | ^"GFRAME[75]" | ^"GFRAME[74]" | ^"GFRAME[73]" | ^"GFRAME[72]" | ^"GFRAME[71]" | ^"GFRAME[70]" | ^"GFRAME[6]" | ^"GFRAME[69]" | ^"GFRAME[68]" | ^"GFRAME[67]" | ^"GFRAME[66]" | ^"GFRAME[65]" | ^"GFRAME[64]" | ^"GFRAME[63]" | ^"GFRAME[62]" | ^"GFRAME[61]" | ^"GFRAME[60]" | ^"GFRAME[5]" | ^"GFRAME[59]" | ^"GFRAME[58]" | ^"GFRAME[57]" | ^"GFRAME[56]" | ^"GFRAME[55]" | ^"GFRAME[54]" | ^"GFRAME[53]" | ^"GFRAME[52]" | ^"GFRAME[51]" | ^"GFRAME[50]" | ^"GFRAME[4]" | ^"GFRAME[49]" | ^"GFRAME[48]" | ^"GFRAME[47]" | ^"GFRAME[46]" | ^"GFRAME[45]" | ^"GFRAME[44]" | ^"GFRAME[43]" | ^"GFRAME[42]" | ^"GFRAME[41]" | ^"GFRAME[40]" | ^"GFRAME[3]" | ^"GFRAME[39]" | ^"GFRAME[38]" | ^"GFRAME[37]" | ^"GFRAME[36]" | ^"GFRAME[35]" | ^"GFRAME[34]" | ^"GFRAME[33]" | ^"GFRAME[32]" | ^"GFRAME[31]" | ^"GFRAME[30]" | ^"GFRAME[2]" | ^"GFRAME[29]" | ^"GFRAME[28]" | ^"GFRAME[27]" | ^"GFRAME[26]" | ^"GFRAME[25]" | ^"GFRAME[24]" | ^"GFRAME[23]" | ^"GFRAME[22]" | ^"GFRAME[21]" | ^"GFRAME[20]" | ^"GFRAME[1]" | ^"GFRAME[19]" | ^"GFRAME[18]" | ^"GFRAME[17]" | ^"GFRAME[16]" | ^"GFRAME[15]" | ^"GFRAME[14]" | ^"GFRAME[13]" | ^"GFRAME[12]" | ^"GFRAME[11]" | ^"GFRAME[10]" | ^"GFRAME[100]" | ^"GFRAME[0]" | ^"G973" | ^"G972" | ^"G971" | ^"G97" | ^"G962" | ^"G961" | ^"G96" | ^"G952" | ^"G95" | ^"G942" | ^"G94" | ^"G931" | ^"G93" | ^"G91" | ^"G90" | ^"G9" | ^"G829" | ^"G828" | ^"G827" | ^"G826" | ^"G825" | ^"G824" | ^"G823" | ^"G822" | ^"G821" | ^"G820" | ^"G819" | ^"G818" | ^"G817" | ^"G816" | ^"G815" | ^"G814" | ^"G813" | ^"G812" | ^"G811" | ^"G810" | ^"G75" | ^"G74" | ^"G710" | ^"G71" | ^"G700" | ^"G70" | ^"G7" | ^"G645" | ^"G644" | ^"G643" | ^"G642" | ^"G641" | ^"G64" | ^"G63" | ^"G621" | ^"G62" | ^"G603" | ^"G602" | ^"G601" | ^"G60" | ^"G599" | ^"G598" | ^"G597" | ^"G596" | ^"G595" | ^"G594" | ^"G593" | ^"G592" | ^"G591" | ^"G590" | ^"G59" | ^"G589" | ^"G588" | ^"G587" | ^"G586" | ^"G585" | ^"G584" | ^"G583" | ^"G582" | ^"G581" | ^"G580" | ^"G58" | ^"G579" | ^"G578" | ^"G577" | ^"G576" | ^"G575" | ^"G574" | ^"G573" | ^"G572" | ^"G571" | ^"G570" | ^"G57" | ^"G569" | ^"G568" | ^"G567" | ^"G566" | ^"G565" | ^"G564" | ^"G563" | ^"G562" | ^"G561" | ^"G560" | ^"G56" | ^"G559" | ^"G558" | ^"G557" | ^"G556" | ^"G555" | ^"G554" | ^"G553" | ^"G552" | ^"G551" | ^"G550" | ^"G55" | ^"G549" | ^"G548" | ^"G547" | ^"G546" | ^"G545" | ^"G544" | ^"G543" | ^"G542" | ^"G541" | ^"G540" | ^"G54" | ^"G539" | ^"G538" | ^"G537" | ^"G536" | ^"G535" | ^"G534" | ^"G533" | ^"G532" | ^"G531" | ^"G530" | ^"G53" | ^"G529" | ^"G528" | ^"G527" | ^"G526" | ^"G525" | ^"G524" | ^"G523" | ^"G522" | ^"G521" | ^"G520" | ^"G519" | ^"G518" | ^"G517" | ^"G516" | ^"G515" | ^"G514" | ^"G513" | ^"G512" | ^"G511" | ^"G510" | ^"G509" | ^"G508" | ^"G507" | ^"G506" | ^"G505" | ^"G500" | ^"G5" | ^"G462" | ^"G461" | ^"G460" | ^"G451" | ^"G450" | ^"G42" | ^"G41" | ^"G40" | ^"G4" | ^"G35" | ^"G348" | ^"G347" | ^"G341" | ^"G340" | ^"G34" | ^"G336" | ^"G335" | ^"G332" | ^"G331" | ^"G33" | ^"G3" | ^"G291" | ^"G290" | ^"G26" | ^"G25" | ^"G248" | ^"G247" | ^"G2" | ^"G19" | ^"G18" | ^"G17" | ^"G153" | ^"G148" | ^"G147" | ^"G143" | ^"G142" | ^"G141" | ^"G140" | ^"G112" | ^"G111" | ^"G110" | ^"G1" | ^"G0" | ^"FTOCON" | ^"FTOCOF" | ^"FNORM" | ^"FLIN" | ^"FIFOCTRL" | ^"FFWON" | ^"FFWOF" | ^"FENDNORM" | ^"FCUB" | ^"ETAN" | ^"ENAT" | ^"EAUTO" | ^"DYNSEMIFIN" | ^"DYNROUGH" | ^"DYNPREC" | ^"DYNPOS" | ^"DYNNORM" | ^"DYNFINISH" | ^"DRIVE" | ^"DIAMON" | ^"DIAMOF" | ^"DIAMCYCOF" | ^"DIAM90" | ^"CUTCONON" | ^"CUTCONOF" | ^"CUT3DFS" | ^"CUT3DFF" | ^"CUT3DFD" | ^"CUT3DF" | ^"CUT3DCD" | ^"CUT3DCCD" | ^"CUT3DCC" | ^"CUT3DC" | ^"CUT2DFD" | ^"CUT2DF" | ^"CUT2DD" | ^"CUT2D" | ^"CT" | ^"CSPLINE" | ^"CPRECON" | ^"CPRECOF" | ^"CP" | ^"COMPSURF" | ^"COMPON" | ^"COMPOF" | ^"COMPCURV" | ^"COMPCAD" | ^"CIP" | ^"CFTCP" | ^"CFIN" | ^"CFC" | ^"CDON" | ^"CDOF2" | ^"CDOF" | ^"BTAN" | ^"BSPLINE" | ^"BRISK" | ^"BNAT" | ^"BAUTO" | ^"ATRANS" | ^"ASPLINE" | ^"ASCALE" | ^"AROTS" | ^"AROT" | ^"AMIRROR") ~ !(ASCII_ALPHANUMERIC) }
|
|
190
|
+
g_command_numbered = { &("G" ~ ASCII_DIGIT+) ~ g_command }
|
|
191
|
+
g_command = { &gcommand_list ~ (gg01_motion | gg02_wait | gg03_frame_area_limit | gg04_fifo | gg06_plane_select | gg07_tool_radius | gg08_work_offset | gg09_frame_tool_suppress | gg10_exact_stop_mode | gg11_exact_stop_non_modal | gg12_block_change_g60_g9 | gg13_wp_measure | gg14_wp_measure_mode | gg15_feed_type | gg16_feedrate_override | gg17_approach_retract_tool | gg18_corner_behavior | gg19_curve_start_spline | gg20_curve_end_spline | gg21_accel_profile | gg22_tool_offset_type | gg23_collision_monitor | gg24_precontrol | gg25_tool_orient_ref | gg26_repos_mode | gg27_tool_offset_change | gg28_area_limit | gg29_rad_diam_prog | gg30_nc_compress | gg31_oem_g | gg32_oem_g | gg33_fine_tool_offset | gg34_tool_orient_smooth | gg35_punch_nibble | gg36_punch_delay | gg37_feedrate_profile | gg39_contour_acc | gg40_tool_radius_const | gg41_thread_interrupt | gg42_tool_carrier | gg43_sar_approach | gg44_sar_segment | gg45_path_ref_fgroup | gg46_plane_fast_retract | gg47_mode_switchover | gg48_approach_retract_trc | gg49_ptp_motion | gg50_orient_prog | gg51_interp_type_orient | gg52_frame_rot_wp | gg53_tool_wear | gg54_vector_rot_poly | gg55_rapid_traverse | gg56_frame_rot_tool | gg57_corner_decel | gg58_dyn_resp_path | gg59_area_limit | gg61_tool_orient_smooth | gg62_repos_non_modal | gg64_grinding_frames) }
|
|
@@ -139,7 +139,10 @@ fn interpret_assignment(element: Pair<Rule>, state: &mut State) -> Result<(Strin
|
|
|
139
139
|
let (key, value, translate) = match (variable_pair.as_rule(), expression_pair.as_rule()) {
|
|
140
140
|
(Rule::variable_single_char, Rule::value) => {
|
|
141
141
|
let key = variable_pair.as_str().to_string();
|
|
142
|
-
let value = expression_pair
|
|
142
|
+
let value = expression_pair
|
|
143
|
+
.as_str()
|
|
144
|
+
.parse::<f32>()
|
|
145
|
+
.expect("Failed to interpret value");
|
|
143
146
|
(key, value, true)
|
|
144
147
|
}
|
|
145
148
|
(Rule::variable, Rule::axis_increment) => {
|
|
@@ -495,28 +498,29 @@ fn insert_m_key(last: &mut HashMap<String, Value>, value: &str) -> Result<(), Pa
|
|
|
495
498
|
if let Value::StrList(ref mut vec) = existing_value {
|
|
496
499
|
if vec.len() < 5 {
|
|
497
500
|
vec.push(value.to_string());
|
|
498
|
-
return Ok(());
|
|
501
|
+
return Ok(()); // Successfully added to the list
|
|
499
502
|
}
|
|
500
503
|
}
|
|
501
504
|
} else {
|
|
502
505
|
// If the key doesn't exist, insert a new StrList with the first value
|
|
503
506
|
last.insert(m_key.to_owned(), Value::StrList(vec![value.to_string()]));
|
|
504
|
-
return Ok(());
|
|
507
|
+
return Ok(()); // Exit early after insertion
|
|
505
508
|
}
|
|
506
509
|
}
|
|
507
|
-
Err(ParsingError::TooManyMCommands)
|
|
510
|
+
Err(ParsingError::TooManyMCommands) // Return error if all keys are full
|
|
508
511
|
}
|
|
509
512
|
|
|
510
513
|
fn interpret_statement(element: Pair<Rule>, output: &mut Output, state: &mut State) -> Result<(), ParsingError> {
|
|
511
514
|
// Grammar:
|
|
512
|
-
// statement
|
|
513
|
-
//
|
|
514
|
-
//
|
|
515
|
-
//
|
|
516
|
-
//
|
|
517
|
-
//
|
|
518
|
-
//
|
|
519
|
-
//
|
|
515
|
+
// statement = {
|
|
516
|
+
// g_command_numbered
|
|
517
|
+
// | m_command
|
|
518
|
+
// | assignment_multi
|
|
519
|
+
// | assignment
|
|
520
|
+
// | g_command
|
|
521
|
+
// | function_call
|
|
522
|
+
// | tool_selection
|
|
523
|
+
// }
|
|
520
524
|
|
|
521
525
|
for statement in element.into_inner() {
|
|
522
526
|
let last = output.last_mut().expect("Output vector should not be empty");
|
|
@@ -529,6 +533,11 @@ fn interpret_statement(element: Pair<Rule>, output: &mut Output, state: &mut Sta
|
|
|
529
533
|
let (key, value) = interpret_g_command(statement);
|
|
530
534
|
last.insert(key, Value::Str(value));
|
|
531
535
|
}
|
|
536
|
+
Rule::g_command_numbered => {
|
|
537
|
+
let (key, value) =
|
|
538
|
+
interpret_g_command(statement.into_inner().next().expect("Error parsing g_command_numbered"));
|
|
539
|
+
last.insert(key, Value::Str(value));
|
|
540
|
+
}
|
|
532
541
|
Rule::m_command => {
|
|
533
542
|
let (_key, value) = interpret_m_command(statement);
|
|
534
543
|
// there are 5 M codes allowed in a block. Store them in separate columns in the output
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
//interpreter.rs
|
|
2
2
|
use pest::Parser;
|
|
3
|
+
use polars::chunked_array::ops::FillNullStrategy;
|
|
3
4
|
use polars::prelude::*;
|
|
4
5
|
use std::collections::HashMap;
|
|
5
6
|
use std::io::{self};
|
|
6
|
-
use polars::chunked_array::ops::FillNullStrategy;
|
|
7
7
|
|
|
8
8
|
use crate::errors::ParsingError;
|
|
9
9
|
use crate::interpret_rules::interpret_blocks;
|
|
10
|
+
use crate::modal_groups::MODAL_GROUPS;
|
|
10
11
|
use crate::state::{self, State};
|
|
11
12
|
use crate::types::{NCParser, Rule, Value};
|
|
12
|
-
use crate::modal_groups::MODAL_GROUPS;
|
|
13
|
-
|
|
14
13
|
|
|
15
14
|
/// Helper function to convert PolarsError to ParsingError
|
|
16
15
|
impl From<PolarsError> for ParsingError {
|
|
@@ -29,7 +28,6 @@ pub fn nc_to_dataframe(
|
|
|
29
28
|
extra_axes: Option<Vec<String>>,
|
|
30
29
|
iteration_limit: usize,
|
|
31
30
|
disable_forward_fill: bool,
|
|
32
|
-
|
|
33
31
|
) -> Result<(DataFrame, state::State), ParsingError> {
|
|
34
32
|
// Default axis identifiers
|
|
35
33
|
const DEFAULT_AXIS_IDENTIFIERS: &[&str] = &[
|
|
@@ -37,9 +35,8 @@ pub fn nc_to_dataframe(
|
|
|
37
35
|
];
|
|
38
36
|
|
|
39
37
|
// Use the override if provided, otherwise use the default identifiers
|
|
40
|
-
let axis_identifiers: Vec<String> =
|
|
41
|
-
DEFAULT_AXIS_IDENTIFIERS.iter().map(|&s| s.to_string()).collect()
|
|
42
|
-
});
|
|
38
|
+
let axis_identifiers: Vec<String> =
|
|
39
|
+
axis_identifiers.unwrap_or_else(|| DEFAULT_AXIS_IDENTIFIERS.iter().map(|&s| s.to_string()).collect());
|
|
43
40
|
|
|
44
41
|
// Add extra axes to the existing list if provided
|
|
45
42
|
let mut axis_identifiers = axis_identifiers;
|
|
@@ -65,44 +62,35 @@ pub fn nc_to_dataframe(
|
|
|
65
62
|
// Get the column names and reorder them
|
|
66
63
|
let ordered_columns = reorder_columns(
|
|
67
64
|
axis_identifiers,
|
|
68
|
-
df.get_column_names().into_iter().map(|s| s.to_string()).collect()
|
|
65
|
+
df.get_column_names().into_iter().map(|s| s.to_string()).collect(),
|
|
69
66
|
);
|
|
70
67
|
|
|
71
68
|
// Select the columns in the specified order and return
|
|
72
69
|
df = df.select(&ordered_columns).map_err(ParsingError::from)?;
|
|
73
70
|
|
|
74
|
-
|
|
75
|
-
|
|
76
71
|
if !disable_forward_fill {
|
|
77
|
-
|
|
78
72
|
let fill_columns: Vec<String> = df
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
.
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
.map_err(|e| io::Error::new(io::ErrorKind::Other, e.to_string()))?;
|
|
96
|
-
}
|
|
73
|
+
.get_column_names()
|
|
74
|
+
.iter()
|
|
75
|
+
.map(|col| col.to_string())
|
|
76
|
+
.filter(|col| state.is_axis(col) || MODAL_GROUPS.contains(&col.as_str()))
|
|
77
|
+
.collect();
|
|
78
|
+
|
|
79
|
+
for col_name in fill_columns {
|
|
80
|
+
let column = df
|
|
81
|
+
.column(&col_name)
|
|
82
|
+
.map_err(|e| io::Error::new(io::ErrorKind::Other, e.to_string()))?;
|
|
83
|
+
let filled_column = column
|
|
84
|
+
.fill_null(FillNullStrategy::Forward(None))
|
|
85
|
+
.map_err(|e| io::Error::new(io::ErrorKind::Other, e.to_string()))?;
|
|
86
|
+
df.with_column(filled_column)
|
|
87
|
+
.map_err(|e| io::Error::new(io::ErrorKind::Other, e.to_string()))?;
|
|
88
|
+
}
|
|
97
89
|
}
|
|
98
90
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
91
|
Ok((df, state))
|
|
103
92
|
}
|
|
104
93
|
|
|
105
|
-
|
|
106
94
|
#[allow(dead_code)] // Only used in main.rs, not in lib.rs
|
|
107
95
|
pub fn dataframe_to_csv(df: &mut DataFrame, path: &str) -> Result<(), PolarsError> {
|
|
108
96
|
// Get all column names that are of List type
|
|
@@ -125,8 +113,7 @@ pub fn dataframe_to_csv(df: &mut DataFrame, path: &str) -> Result<(), PolarsErro
|
|
|
125
113
|
*df = exploded_df;
|
|
126
114
|
}
|
|
127
115
|
|
|
128
|
-
let mut file = std::fs::File::create(path)
|
|
129
|
-
.map_err(|e| PolarsError::ComputeError(format!("{:?}", e).into()))?;
|
|
116
|
+
let mut file = std::fs::File::create(path).map_err(|e| PolarsError::ComputeError(format!("{:?}", e).into()))?;
|
|
130
117
|
|
|
131
118
|
CsvWriter::new(&mut file)
|
|
132
119
|
.with_float_precision(Some(3))
|
|
@@ -135,7 +122,6 @@ pub fn dataframe_to_csv(df: &mut DataFrame, path: &str) -> Result<(), PolarsErro
|
|
|
135
122
|
Ok(())
|
|
136
123
|
}
|
|
137
124
|
|
|
138
|
-
|
|
139
125
|
/// Parse file and return results as a vector of HashMaps
|
|
140
126
|
fn interpret_file(input: &str, state: &mut State) -> Result<Vec<HashMap<String, Value>>, ParsingError> {
|
|
141
127
|
let blocks = NCParser::parse(Rule::file, input)
|
|
@@ -162,21 +148,21 @@ fn interpret_file(input: &str, state: &mut State) -> Result<Vec<HashMap<String,
|
|
|
162
148
|
|
|
163
149
|
fn results_to_dataframe(data: Vec<HashMap<String, Value>>) -> PolarsResult<DataFrame> {
|
|
164
150
|
// Step 1: Collect all unique keys (column names)
|
|
165
|
-
let columns: Vec<String> = data
|
|
151
|
+
let columns: Vec<String> = data
|
|
152
|
+
.iter()
|
|
166
153
|
.flat_map(|row| row.keys().cloned())
|
|
167
|
-
.collect::<std::collections::HashSet<String>>()
|
|
154
|
+
.collect::<std::collections::HashSet<String>>() // Deduplicate keys
|
|
168
155
|
.into_iter()
|
|
169
156
|
.collect();
|
|
170
157
|
|
|
171
158
|
// Step 2: Initialize empty columns (vectors) for each key
|
|
172
|
-
let mut series_map: HashMap<String, Vec<Option<AnyValue>>> =
|
|
173
|
-
.iter()
|
|
174
|
-
.map(|key| (key.clone(), Vec::new()))
|
|
175
|
-
.collect();
|
|
159
|
+
let mut series_map: HashMap<String, Vec<Option<AnyValue>>> =
|
|
160
|
+
columns.iter().map(|key| (key.clone(), Vec::new())).collect();
|
|
176
161
|
|
|
177
162
|
// Step 3: Populate the columns with data, inserting None where keys are missing
|
|
178
163
|
for row in &data {
|
|
179
|
-
if row.is_empty() {
|
|
164
|
+
if row.is_empty() {
|
|
165
|
+
// Skip rows with no values
|
|
180
166
|
continue;
|
|
181
167
|
}
|
|
182
168
|
|
|
@@ -187,12 +173,16 @@ fn results_to_dataframe(data: Vec<HashMap<String, Value>>) -> PolarsResult<DataF
|
|
|
187
173
|
}
|
|
188
174
|
|
|
189
175
|
// Step 4: Convert each column to a Polars Series
|
|
190
|
-
let polars_series: Vec<Series> = columns
|
|
176
|
+
let polars_series: Vec<Series> = columns
|
|
177
|
+
.iter()
|
|
191
178
|
.map(|key| {
|
|
192
179
|
let column_data = series_map.remove(key).unwrap();
|
|
193
180
|
Series::new(
|
|
194
|
-
key.as_str().into(),
|
|
195
|
-
column_data
|
|
181
|
+
key.as_str().into(), // Convert `&String` to `PlSmallStr` using `Into::into`
|
|
182
|
+
column_data
|
|
183
|
+
.into_iter()
|
|
184
|
+
.map(|opt| opt.unwrap_or(AnyValue::Null))
|
|
185
|
+
.collect::<Vec<AnyValue>>(),
|
|
196
186
|
)
|
|
197
187
|
})
|
|
198
188
|
.collect();
|
|
@@ -202,13 +192,10 @@ fn results_to_dataframe(data: Vec<HashMap<String, Value>>) -> PolarsResult<DataF
|
|
|
202
192
|
}
|
|
203
193
|
|
|
204
194
|
/// Helper function to reorder DataFrame columns
|
|
205
|
-
fn reorder_columns(
|
|
206
|
-
axis_identifiers: Vec<String>,
|
|
207
|
-
mut df_columns: Vec<String>
|
|
208
|
-
) -> Vec<String> {
|
|
195
|
+
fn reorder_columns(axis_identifiers: Vec<String>, mut df_columns: Vec<String>) -> Vec<String> {
|
|
209
196
|
let mut ordered_columns = Vec::new();
|
|
210
|
-
df_columns.sort();
|
|
211
|
-
|
|
197
|
+
df_columns.sort(); // Sort columns alphabetically
|
|
198
|
+
// Move axis columns first
|
|
212
199
|
for axis in axis_identifiers {
|
|
213
200
|
if let Some(index) = df_columns.iter().position(|col| col == &axis) {
|
|
214
201
|
ordered_columns.push(df_columns.remove(index));
|
|
@@ -226,5 +213,3 @@ fn reorder_columns(
|
|
|
226
213
|
|
|
227
214
|
ordered_columns
|
|
228
215
|
}
|
|
229
|
-
|
|
230
|
-
|
|
@@ -10,8 +10,8 @@ use std::collections::HashMap;
|
|
|
10
10
|
mod errors;
|
|
11
11
|
mod interpret_rules;
|
|
12
12
|
mod interpreter;
|
|
13
|
-
mod state;
|
|
14
13
|
mod modal_groups;
|
|
14
|
+
mod state;
|
|
15
15
|
|
|
16
16
|
use pyo3::prelude::*;
|
|
17
17
|
use pyo3::wrap_pyfunction;
|
|
@@ -28,13 +28,19 @@ fn nc_to_dataframe(
|
|
|
28
28
|
iteration_limit: usize,
|
|
29
29
|
disable_forward_fill: bool,
|
|
30
30
|
) -> PyResult<(PyDataFrame, HashMap<String, HashMap<String, f32>>)> {
|
|
31
|
-
let (df,state) = nc_to_dataframe_rust(
|
|
32
|
-
|
|
31
|
+
let (df, state) = nc_to_dataframe_rust(
|
|
32
|
+
input,
|
|
33
|
+
initial_state.as_deref(),
|
|
34
|
+
axis_identifiers,
|
|
35
|
+
extra_axes,
|
|
36
|
+
iteration_limit,
|
|
37
|
+
disable_forward_fill,
|
|
38
|
+
)
|
|
39
|
+
.map_err(|e| PyErr::new::<PyValueError, _>(format!("Error creating DataFrame: {:?}", e)))?;
|
|
33
40
|
|
|
34
41
|
Ok((PyDataFrame(df), state.to_python_dict()))
|
|
35
42
|
}
|
|
36
43
|
|
|
37
|
-
|
|
38
44
|
/// Define the Python module
|
|
39
45
|
#[pymodule]
|
|
40
46
|
fn nc_gcode_interpreter(_py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
|
|
@@ -8,9 +8,9 @@ use std::io::{self};
|
|
|
8
8
|
mod errors;
|
|
9
9
|
mod interpret_rules;
|
|
10
10
|
mod interpreter;
|
|
11
|
+
mod modal_groups;
|
|
11
12
|
mod state;
|
|
12
13
|
mod types;
|
|
13
|
-
mod modal_groups;
|
|
14
14
|
|
|
15
15
|
use interpreter::{dataframe_to_csv, nc_to_dataframe};
|
|
16
16
|
use std::path::PathBuf;
|
|
@@ -91,13 +91,17 @@ fn main() -> io::Result<()> {
|
|
|
91
91
|
|
|
92
92
|
let input = std::fs::read_to_string(matches.get_one::<String>("input").unwrap())
|
|
93
93
|
.map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Error reading input file: {:?}", e)))?;
|
|
94
|
-
|
|
95
94
|
|
|
96
|
-
let initial_state = matches
|
|
95
|
+
let initial_state = matches
|
|
96
|
+
.get_one::<String>("initial_state")
|
|
97
97
|
.map(std::fs::read_to_string)
|
|
98
98
|
.transpose()
|
|
99
|
-
.map_err(|e|
|
|
100
|
-
|
|
99
|
+
.map_err(|e| {
|
|
100
|
+
io::Error::new(
|
|
101
|
+
io::ErrorKind::Other,
|
|
102
|
+
format!("Error reading initial state file: {:?}", e),
|
|
103
|
+
)
|
|
104
|
+
})?;
|
|
101
105
|
|
|
102
106
|
let (mut df, _state) = nc_to_dataframe(
|
|
103
107
|
&input,
|
|
@@ -105,7 +109,7 @@ fn main() -> io::Result<()> {
|
|
|
105
109
|
axes_override.clone(),
|
|
106
110
|
extra_axes,
|
|
107
111
|
*iteration_limit,
|
|
108
|
-
disable_forward_fill
|
|
112
|
+
disable_forward_fill,
|
|
109
113
|
)?;
|
|
110
114
|
|
|
111
115
|
let mut output_path = PathBuf::from(input_path.clone());
|
|
@@ -54,12 +54,12 @@ impl State {
|
|
|
54
54
|
*self.translation.get(axis).unwrap_or(&0.0)
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
pub fn update_axis(&mut self, key: &str, value: f32, translate:bool) -> Result<f32, ParsingError> {
|
|
57
|
+
pub fn update_axis(&mut self, key: &str, value: f32, translate: bool) -> Result<f32, ParsingError> {
|
|
58
58
|
let translation_value = self.get_translation(key);
|
|
59
59
|
let mut updated_value = value;
|
|
60
60
|
if translate {
|
|
61
|
-
updated_value+= translation_value;
|
|
62
|
-
}
|
|
61
|
+
updated_value += translation_value;
|
|
62
|
+
}
|
|
63
63
|
self.axes.insert(key.to_string(), updated_value);
|
|
64
64
|
Ok(updated_value)
|
|
65
65
|
}
|
|
@@ -19,9 +19,7 @@ impl Value {
|
|
|
19
19
|
match self {
|
|
20
20
|
Value::Str(s) => AnyValue::String(s),
|
|
21
21
|
Value::Float(f) => AnyValue::Float32(*f),
|
|
22
|
-
Value::StrList(vec) =>
|
|
23
|
-
AnyValue::List(vec.iter().map(|s| s.as_str()).collect())
|
|
24
|
-
}
|
|
22
|
+
Value::StrList(vec) => AnyValue::List(vec.iter().map(|s| s.as_str()).collect()),
|
|
25
23
|
}
|
|
26
24
|
}
|
|
27
25
|
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/python/nc_gcode_interpreter/__init__.py
RENAMED
|
File without changes
|
{nc_gcode_interpreter-0.1.3 → nc_gcode_interpreter-0.1.5}/python/tests/test_expected_output.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|