Skip to content

Commit e298f64

Browse files
Refactor Lua conversion functions and improve error handling; update examples for ConvertFrom-Lua
1 parent 4fefa8d commit e298f64

9 files changed

Lines changed: 113 additions & 34 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ $luaOutput | Set-Content -Path 'settings.lua'
6969
### Example 6: Convert Lua to PSCustomObject
7070

7171
```powershell
72-
$result = '{ server = "localhost", port = 8080 }' | ConvertFrom-Lua -AsObject
72+
$result = '{ server = "localhost", port = 8080 }' | ConvertFrom-Lua
7373
$result.server # localhost
7474
$result.port # 8080
7575
```

examples/General.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Write-Output "Name: $($result.name)"
3434
Write-Output "Player Width: $($result.unitframes.playerWidth)"
3535

3636
# Convert Lua to PSCustomObject
37-
$obj = '{ server = "localhost", port = 8080 }' | ConvertFrom-Lua -AsObject
37+
$obj = '{ server = "localhost", port = 8080 }' | ConvertFrom-Lua
3838
Write-Output "Server: $($obj.server), Port: $($obj.port)"
3939

4040
# Compressed output

src/functions/private/ConvertFrom-LuaTable.ps1

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@
4848

4949
$result = Read-LuaValue
5050

51+
Skip-LuaWhitespace
52+
if ($script:luaPos -lt $script:luaString.Length) {
53+
$remainingInput = $script:luaString.Substring($script:luaPos)
54+
throw "Unexpected trailing content after Lua value at position $($script:luaPos): $remainingInput"
55+
}
56+
5157
return $result
5258
}
5359

src/functions/private/Read-LuaMultiLineString.ps1

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
function Read-LuaMultiLineString {
22
<#
33
.SYNOPSIS
4-
Reads a multi-line Lua string delimited by [[ and ]].
4+
Reads a multi-line Lua string delimited by long brackets [[ ]], [=[ ]=], [==[ ]==], etc.
55
#>
66
[OutputType([string])]
77
[CmdletBinding()]
@@ -10,10 +10,27 @@
1010
begin {}
1111

1212
process {
13-
$script:luaPos += 2 # skip [[
13+
# Count the number of '=' characters in the opening long bracket
14+
$script:luaPos++ # skip first [
15+
$equalsCount = 0
16+
while ($script:luaPos -lt $script:luaString.Length -and
17+
$script:luaString[$script:luaPos] -eq '=') {
18+
$equalsCount++
19+
$script:luaPos++
20+
}
21+
if ($script:luaPos -ge $script:luaString.Length -or
22+
$script:luaString[$script:luaPos] -ne '[') {
23+
throw 'Invalid long bracket string opening.'
24+
}
25+
$script:luaPos++ # skip second [
26+
27+
# Build the closing pattern: ] + N '=' + ]
28+
$closingBracket = ']' + ('=' * $equalsCount) + ']'
29+
$closeLen = $closingBracket.Length
30+
1431
$result = [System.Text.StringBuilder]::new()
1532

16-
# Per Lua spec, a newline immediately after [[ is ignored
33+
# Per Lua spec, a newline immediately after the opening bracket is ignored
1734
if ($script:luaPos -lt $script:luaString.Length -and
1835
$script:luaString[$script:luaPos] -eq "`n") {
1936
$script:luaPos++
@@ -23,10 +40,10 @@
2340
$script:luaPos += 2
2441
}
2542

26-
while ($script:luaPos + 1 -lt $script:luaString.Length) {
27-
if ($script:luaString[$script:luaPos] -eq ']' -and
28-
$script:luaString[$script:luaPos + 1] -eq ']') {
29-
$script:luaPos += 2
43+
while ($script:luaPos -lt $script:luaString.Length) {
44+
if ($script:luaPos + $closeLen - 1 -lt $script:luaString.Length -and
45+
$script:luaString.Substring($script:luaPos, $closeLen) -eq $closingBracket) {
46+
$script:luaPos += $closeLen
3047
return $result.ToString()
3148
}
3249
$null = $result.Append($script:luaString[$script:luaPos])

src/functions/private/Read-LuaString.ps1

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,35 @@
104104
throw 'Invalid \u escape sequence.'
105105
}
106106
}
107+
"`n" {
108+
$null = $result.Append("`n")
109+
$script:luaPos++
110+
if (
111+
$script:luaPos -lt $script:luaString.Length -and
112+
$script:luaString[$script:luaPos] -eq "`r"
113+
) {
114+
$script:luaPos++
115+
}
116+
}
117+
"`r" {
118+
$null = $result.Append("`n")
119+
$script:luaPos++
120+
if (
121+
$script:luaPos -lt $script:luaString.Length -and
122+
$script:luaString[$script:luaPos] -eq "`n"
123+
) {
124+
$script:luaPos++
125+
}
126+
}
127+
'z' {
128+
$script:luaPos++
129+
while (
130+
$script:luaPos -lt $script:luaString.Length -and
131+
[char]::IsWhiteSpace($script:luaString[$script:luaPos])
132+
) {
133+
$script:luaPos++
134+
}
135+
}
107136
default {
108137
# \ddd - decimal byte sequence (1-3 digits)
109138
if ($nextChar -match '[0-9]') {

src/functions/private/Read-LuaTable.ps1

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,17 @@
4343
Skip-LuaWhitespace
4444
$key = Read-LuaValue
4545
Skip-LuaWhitespace
46-
if ($script:luaPos -lt $script:luaString.Length -and
47-
$script:luaString[$script:luaPos] -eq ']') {
48-
$script:luaPos++ # skip ]
46+
if ($script:luaPos -ge $script:luaString.Length -or
47+
$script:luaString[$script:luaPos] -ne ']') {
48+
throw "Expected ']' after bracket key in Lua table."
4949
}
50+
$script:luaPos++ # skip ]
5051
Skip-LuaWhitespace
51-
if ($script:luaPos -lt $script:luaString.Length -and
52-
$script:luaString[$script:luaPos] -eq '=') {
53-
$script:luaPos++ # skip =
52+
if ($script:luaPos -ge $script:luaString.Length -or
53+
$script:luaString[$script:luaPos] -ne '=') {
54+
throw "Expected '=' after bracket key in Lua table."
5455
}
56+
$script:luaPos++ # skip =
5557
Skip-LuaWhitespace
5658
$value = Read-LuaValue
5759
$entries.Add(@{ Key = [string]$key; Value = $value })
@@ -101,11 +103,14 @@
101103

102104
Skip-LuaWhitespace
103105

104-
# Skip comma or semicolon separator
105-
if ($script:luaPos -lt $script:luaString.Length -and
106-
($script:luaString[$script:luaPos] -eq ',' -or
107-
$script:luaString[$script:luaPos] -eq ';')) {
108-
$script:luaPos++
106+
# Lua requires a comma or semicolon between fields unless the next token is }
107+
if ($script:luaPos -lt $script:luaString.Length) {
108+
if ($script:luaString[$script:luaPos] -eq ',' -or
109+
$script:luaString[$script:luaPos] -eq ';') {
110+
$script:luaPos++
111+
} elseif ($script:luaString[$script:luaPos] -ne '}') {
112+
throw "Expected ',', ';', or '}' in Lua table constructor."
113+
}
109114
}
110115
}
111116

src/functions/private/Read-LuaValue.ps1

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,19 @@
3838
return Read-LuaString -QuoteChar "'"
3939
}
4040

41-
# Multi-line string [[ ... ]]
41+
# Multi-line string [[ ... ]] or [=[ ... ]=]
4242
if ($char -eq '[' -and
4343
$script:luaPos + 1 -lt $script:luaString.Length -and
44-
$script:luaString[$script:luaPos + 1] -eq '[') {
44+
($script:luaString[$script:luaPos + 1] -eq '[' -or
45+
$script:luaString[$script:luaPos + 1] -eq '=')) {
4546
return Read-LuaMultiLineString
4647
}
4748

48-
# Number or negative number
49+
# Number or negative number (including .5 style floats)
4950
if ($char -match '[0-9]' -or
51+
($char -eq '.' -and
52+
$script:luaPos + 1 -lt $script:luaString.Length -and
53+
$script:luaString[$script:luaPos + 1] -match '[0-9]') -or
5054
($char -eq '-' -and
5155
$script:luaPos + 1 -lt $script:luaString.Length -and
5256
$script:luaString[$script:luaPos + 1] -match '[0-9.]')) {

src/functions/private/Skip-LuaWhitespace.ps1

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,35 @@
2424
$script:luaString[$script:luaPos + 1] -eq '-') {
2525
$script:luaPos += 2
2626

27-
# Multi-line comment --[[ ... ]]
28-
if ($script:luaPos + 1 -lt $script:luaString.Length -and
29-
$script:luaString[$script:luaPos] -eq '[' -and
30-
$script:luaString[$script:luaPos + 1] -eq '[') {
31-
$script:luaPos += 2
32-
while ($script:luaPos + 1 -lt $script:luaString.Length) {
33-
if ($script:luaString[$script:luaPos] -eq ']' -and
34-
$script:luaString[$script:luaPos + 1] -eq ']') {
35-
$script:luaPos += 2
36-
break
27+
# Multi-line comment --[[ ... ]] or --[=[ ... ]=] etc.
28+
if ($script:luaPos -lt $script:luaString.Length -and
29+
$script:luaString[$script:luaPos] -eq '[') {
30+
$eqStart = $script:luaPos + 1
31+
$eqCount = 0
32+
while ($eqStart + $eqCount -lt $script:luaString.Length -and
33+
$script:luaString[$eqStart + $eqCount] -eq '=') {
34+
$eqCount++
35+
}
36+
if ($eqStart + $eqCount -lt $script:luaString.Length -and
37+
$script:luaString[$eqStart + $eqCount] -eq '[') {
38+
# Valid long bracket comment opening
39+
$script:luaPos = $eqStart + $eqCount + 1
40+
$closePattern = ']' + ('=' * $eqCount) + ']'
41+
$closeLen = $closePattern.Length
42+
while ($script:luaPos -lt $script:luaString.Length) {
43+
if ($script:luaPos + $closeLen - 1 -lt $script:luaString.Length -and
44+
$script:luaString.Substring($script:luaPos, $closeLen) -eq $closePattern) {
45+
$script:luaPos += $closeLen
46+
break
47+
}
48+
$script:luaPos++
49+
}
50+
} else {
51+
# Not a long bracket - treat as single-line comment
52+
while ($script:luaPos -lt $script:luaString.Length -and
53+
$script:luaString[$script:luaPos] -ne "`n") {
54+
$script:luaPos++
3755
}
38-
$script:luaPos++
3956
}
4057
} else {
4158
# Single-line comment

src/functions/public/Lua/ConvertFrom-Lua.ps1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272

7373
# Max nesting depth allowed in input. Throws a terminating error when exceeded.
7474
[Parameter()]
75+
[ValidateRange(0, 1024)]
7576
[int] $Depth = 1024,
7677

7778
# Output arrays as a single object instead of enumerating elements through the pipeline.

0 commit comments

Comments
 (0)