Added a trie based Definelist for the coming preprocessor.
This commit is contained in:
parent
54f252298c
commit
67703597b2
5 changed files with 126 additions and 0 deletions
31
.gitignore
vendored
Normal file
31
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
# Binaries
|
||||||
|
*.exe
|
||||||
|
*.exe~
|
||||||
|
*.dll
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
*.test
|
||||||
|
|
||||||
|
# Build output
|
||||||
|
bin/
|
||||||
|
build/
|
||||||
|
dist/
|
||||||
|
|
||||||
|
# Go workspace
|
||||||
|
*.out
|
||||||
|
|
||||||
|
# Dependency directories (if any)
|
||||||
|
vendor/
|
||||||
|
|
||||||
|
# Go coverage files
|
||||||
|
coverage.out
|
||||||
|
|
||||||
|
# IDE: GoLand / IntelliJ IDEA
|
||||||
|
.idea/
|
||||||
|
*.iml
|
||||||
|
out/
|
||||||
|
|
||||||
|
# Logs and temp files
|
||||||
|
*.log
|
||||||
|
*.tmp
|
||||||
|
.DS_Store
|
||||||
5
go.mod
Normal file
5
go.mod
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
module c65gm
|
||||||
|
|
||||||
|
go 1.25.1
|
||||||
|
|
||||||
|
require github.com/armon/go-radix v1.0.0 // indirect
|
||||||
2
go.sum
Normal file
2
go.sum
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=
|
||||||
|
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||||
57
internal/preproc/definelist.go
Normal file
57
internal/preproc/definelist.go
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
package preproc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"unicode/utf8"
|
||||||
|
|
||||||
|
"github.com/armon/go-radix"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DefineList struct {
|
||||||
|
tree *radix.Tree
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDefineList() *DefineList { return &DefineList{tree: radix.New()} }
|
||||||
|
|
||||||
|
// Add inserts or updates a define->value mapping.
|
||||||
|
func (d *DefineList) Add(define, value string) { d.tree.Insert(define, value) }
|
||||||
|
|
||||||
|
// Delete removes a define. Returns true if it existed.
|
||||||
|
func (d *DefineList) Delete(define string) bool {
|
||||||
|
_, ok := d.tree.Delete(define)
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// Defined reports whether a define exists.
|
||||||
|
func (d *DefineList) Defined(s string) bool {
|
||||||
|
_, ok := d.tree.Get(s)
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// typed wrapper to avoid type assertions sprinkled in hot code
|
||||||
|
func (d *DefineList) longestPrefixString(s string) (key string, val string, ok bool) {
|
||||||
|
k, v, ok := d.tree.LongestPrefix(s)
|
||||||
|
if !ok {
|
||||||
|
return "", "", false
|
||||||
|
}
|
||||||
|
return k, v.(string), true
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReplaceDefines performs a single-pass, longest-prefix replacement.
|
||||||
|
// Case-sensitive. Matches anywhere. No recursive re-expansion.
|
||||||
|
func (d *DefineList) ReplaceDefines(s string) string {
|
||||||
|
var b strings.Builder
|
||||||
|
b.Grow(len(s)) // baseline; grows if expansions occur
|
||||||
|
|
||||||
|
for i := 0; i < len(s); {
|
||||||
|
if key, val, ok := d.longestPrefixString(s[i:]); ok && key != "" {
|
||||||
|
b.WriteString(val)
|
||||||
|
i += len(key) // advance by matched bytes (UTF-8-safe)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
_, size := utf8.DecodeRuneInString(s[i:])
|
||||||
|
b.WriteString(s[i : i+size])
|
||||||
|
i += size
|
||||||
|
}
|
||||||
|
return b.String()
|
||||||
|
}
|
||||||
31
main.go
Normal file
31
main.go
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"c65gm/internal/preproc"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// put the DefineList type in another file (same package) or import it;
|
||||||
|
// here I assume definelist.go is in its own package "definelist".
|
||||||
|
// If it's in the same package main, just call New() directly.
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
defs := preproc.NewDefineList() // <-- important
|
||||||
|
|
||||||
|
defs.Add("ARRAY_MIN", "0")
|
||||||
|
defs.Add("ARRAY_MAX", "100")
|
||||||
|
defs.Add("ARRAY_MAX_PAX", "1000")
|
||||||
|
defs.Add("VERSION", "1.0")
|
||||||
|
defs.Add("π", "3.14159")
|
||||||
|
|
||||||
|
src := `for i := ARRAY_MIN to ARRAY_MAX_PAX do
|
||||||
|
writeln(VERSION);
|
||||||
|
writeln(ARRAY_MAX);
|
||||||
|
const PI = π;`
|
||||||
|
|
||||||
|
fmt.Println("Original:\n" + src)
|
||||||
|
fmt.Println("\nReplaced:\n" + defs.ReplaceDefines(src))
|
||||||
|
defs.Delete("ARRAY_MAX_PAX")
|
||||||
|
fmt.Println("\nReplaced (after .Delete):\n" + defs.ReplaceDefines(src))
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue