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:
37
gen/scan.go
37
gen/scan.go
@@ -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
46
gen/skip.go
Normal 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)
|
||||
}
|
||||
73
gen/symb.go
73
gen/symb.go
@@ -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)))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user