classes/InputFileContext.ps1
|
class InputFileContext { [string]$FilePath [string]$Content [int] $Index = 0 [int] $Length = 0 [int] $Line = 1 [int] $Column = 1 [System.Collections.Generic.List[string]]$IncludeDirs = [System.Collections.Generic.List[string]]::new() [bool]$IncludeOnce = $false InputFileContext([string]$resolvedPath) { $this.FilePath = $resolvedPath $this.Content = (Get-Content -Path $resolvedPath -Raw) # -replace "`r`n", "`n" ` # -replace "`r", "`n" ` # -replace ([char]0x2028), "`n" ` # -replace ([char]0x2029), "`n" ` # -split("`n") $this.Length = $this.Content.Length $this.IncludeDirs.Add((Split-Path $resolvedPath -Parent)) } InputFileContext([string]$filename, [string]$content) { $this.FilePath = $filename $this.Content = $content $this.Length = $content.Length $this.IncludeDirs.Add((Get-Location).Path) } hidden [bool] IsEOF() { return $this.Index -ge $this.Length } [char] PeekChar() { if ($this.IsEOF()) { return 0 } return $this.Content[$this.Index] } [char] ReadChar() { if ($this.IsEOF()) { return 0 } $ch = $this.Content[$this.Index] $this.Index++ $code = [int][char]$ch # newline family if ($code -in 10,8232,8233) { $this.Line++ $this.Column = 1 return "`n" } # normal char, incl CR $this.Column++ return $ch } [void] UnReadChar() { if ($this.Index -le 0) { return } # Step back one char $this.Index-- $ch = $this.Content[$this.Index] $code = [int][char]$ch if ($this.Column -eq 1) { if ($this.Line -gt 1) { $this.Line-- # ---- Recompute column ---- $i = $this.Index - 1 $col = 1 while ($i -ge 0) { $c2 = [int][char]$this.Content[$i] if ($c2 -in 10,8232,8233) { break } $col++ $i-- } $this.Column = $col return } } $this.Column-- } [void] AddIncludeDir([string]$path) { $full = (Resolve-Path $path).Path $this.IncludeDirs.Add($full) } [void] Close() { # nothing to close, file already loaded } } |