1
0
mirror of https://github.com/fumiama/gozel.git synced 2026-06-05 08:20:24 +08:00

feat(gen): add symbolTable

This commit is contained in:
源文雨
2026-03-15 00:34:33 +08:00
parent e852e0e4d5
commit bddf993ebf
3 changed files with 139 additions and 17 deletions

View File

@@ -22,7 +22,7 @@ func infh(name string) string {
func scanheader(name string, scan *bufio.Scanner) {
ln := 0
var regionfile *os.File
symtab := map[string]symbol{
symtab := symbolTable{
"ZE_APICALL": symbol{symbolTypeConst, "ZE_APICALL", []string{""}},
"ZE_APIEXPORT": symbol{symbolTypeConst, "ZE_APIEXPORT", []string{""}},
"ZE_DLLEXPORT": symbol{symbolTypeConst, "ZE_DLLEXPORT", []string{""}},
@@ -67,23 +67,28 @@ func scanheader(name string, scan *bufio.Scanner) {
func scanblocks(
name string, scan *bufio.Scanner, f *os.File,
ln int, symtab map[string]symbol,
ln int, symtab symbolTable,
) int {
sb := strings.Builder{}
skip2nextblk := false
isinifndef := false
skip2nextblk := false //TODO: check logic
ifdepth := 0
isparsing := func() bool {
//TODO: more condition
return ifdepth > 0
}
for scan.Scan() {
ln++
t := scan.Text()
switch {
// block barrier
case strings.HasPrefix(t, "///////////////////////////////////////////////////////////////////////////////"):
// block end
case t == "":
if isparsing() {
continue
}
if sb.Len() != 0 {
panic(fmt.Sprintf("%s L%d: unexpected non-0 sb at block end: %s", name, ln, &sb))
}
f.WriteString(t)
f.WriteString("\n")
skip2nextblk = false
return ln
case skip2nextblk:
continue
// is definition's comment
@@ -101,12 +106,20 @@ func scanblocks(
if t[:8] != "#ifndef " {
panic(fmt.Sprintf("%s L%d: unexpected #if type %s", name, ln, t))
}
isinifndef = true
sname := strings.TrimSpace(t[8:])
tab, ok := symtab[sname]
_, ok := symtab[sname]
if ok {
//TODO: skip2 endif
ln = skip2endif(scan, ln)
continue
}
ifdepth++
case strings.HasPrefix(t, "#endif"):
ifdepth--
if ifdepth < 0 {
panic(fmt.Sprintf("%s L%d: unexpected unpaired #endif", name, ln))
}
case strings.HasPrefix(t, "#define"):
}
}
return ln

46
gen/skip.go Normal file
View File

@@ -0,0 +1,46 @@
package main
import (
"bufio"
"errors"
"strings"
)
func skip2endif(scan *bufio.Scanner, ln int) int {
depth := 1
for scan.Scan() {
ln++
t := scan.Text()
switch {
case strings.HasPrefix(t, "#endif"):
depth--
case strings.HasPrefix(t, "#if"):
depth++
default:
}
if depth <= 0 {
break
}
}
return ln
}
func getinside0brakets(txt string) (string, int, error) {
depth := 0
a := 0
for i, t := range txt {
switch t {
case '(':
if depth == 0 {
a = i + 1
}
depth++
case ')':
depth--
if depth <= 0 {
return txt[a:i], i, nil
}
}
}
return "", 0, errors.New("no round brakets pair in " + txt)
}

View File

@@ -6,6 +6,20 @@ import (
"strings"
)
var (
errIsConstReplace = errors.New("is const replace")
errNoSuchSymbol = errors.New("no such sybmol")
)
type symbolTable map[string]symbol
func (st symbolTable) apply(t string) string {
for _, s := range st {
t = s.replace(t)
}
return t
}
type symbolType uintptr
const (
@@ -26,13 +40,62 @@ type symbol struct {
fields []string
}
func (s *symbol) replace(txt string, args ...string) (string, error) {
func newsymbolconst(name, val string) symbol {
return symbol{
stype: symbolTypeConst,
name: name,
fields: []string{val},
}
}
func newsymbolfunc(name, paras, evals string) symbol {
return symbol{
stype: symbolTypeConst,
name: name,
fields: []string{paras, evals},
}
}
func (s *symbol) extractfirstfunc(txt string) (args []string, a, b int, err error) {
if s.stype == symbolTypeConst {
return nil, 0, 0, errIsConstReplace
}
a = strings.Index(txt, s.name)
if a < 0 {
return nil, 0, 0, errNoSuchSymbol
}
str, off, err := getinside0brakets(txt[a:])
if err != nil {
return nil, 0, 0, err
}
args = strings.Split(str, ",")
for i, arg := range args {
args[i] = strings.TrimSpace(arg)
}
return args, a, a + off, nil
}
func (s *symbol) replace(txt string) string {
switch s.stype {
case symbolTypeConst:
return strings.ReplaceAll(txt, s.name, s.fields[0]), nil
return strings.ReplaceAll(txt, s.name, s.fields[0])
case symbolTypeFunc:
//TODO: finish
return "", nil
paras := strings.Split(s.fields[0], ",")
for {
args, a, b, err := s.extractfirstfunc(txt)
if err == errNoSuchSymbol {
return txt
}
if len(paras) != len(args) {
panic("args " + strings.Join(args, ", ") + " count " + strconv.Itoa(len(args)) + " is different from recorded " + s.fields[0])
}
txts := []string{txt[:a], txt[a:b], txt[b:]}
for i, p := range paras {
txts[1] = strings.ReplaceAll(txts[1], strings.TrimSpace(p), args[i])
}
txts[1] = strings.ReplaceAll(txts[1], s.name, "")
txt = strings.Join(txts, "")
}
}
return "", errors.New("unsupported symbol type " + strconv.Itoa(int(s.stype)))
panic("unsupported symbol type " + strconv.Itoa(int(s.stype)))
}