Fetch the repository succeeded.
This action will force synchronization from 秋来冬风/U语言, which will overwrite any changes that you have made since you forked the repository, and can not be recovered!!!
Synchronous operation will process in the background and will refresh the page when finishing processing. Please be patient.
package ast2
import (
"fmt"
"strings"
"sync"
"gitee.com/u-language/u-language/ucom/astdata"
"gitee.com/u-language/u-language/ucom/enum"
"gitee.com/u-language/u-language/ucom/errcode"
"gitee.com/u-language/u-language/ucom/internal/errutil"
"gitee.com/u-language/u-language/ucom/internal/utils"
)
// Sbt 符号表 symbolTable
type Sbt struct {
//单线程符号表
vmap map[string]fmt.Stringer
//多线程符号表 key string value Node
syncmap *sync.Map
//上级符号表
sbt *Sbt
//是否并发
Thread bool
}
// NewSbt 创建符号表
// - Thread控制是否可以并发
func NewSbt(Thread bool) *Sbt {
ret := new(Sbt)
if Thread {
ret.syncmap = new(sync.Map)
} else {
ret.vmap = make(map[string]fmt.Stringer)
}
ret.Thread = Thread
return ret
}
// seniorSbt 设置上级符号表
// - sbt是上级符号表
func (v *Sbt) seniorSbt(sbt *Sbt) {
v.sbt = sbt
}
// add 添加一个符号信息
func (s *Sbt) add(name string, info fmt.Stringer) errcode.ErrCode {
if s.Thread { //多线程
_, ok := s.syncmap.LoadOrStore(name, info) //记录到哈希表
if ok { //如果已经同名符号
return errcode.SymbolRepeat
}
} else { //单线程
_, ok := s.vmap[name]
if ok { //如果已经同名符号
return errcode.SymbolRepeat
} else {
s.vmap[name] = info //记录到哈希表
}
}
return errcode.NoErr
}
// store 设置一个符号信息
func (s *Sbt) store(name string, info Node) {
if s.Thread { //多线程
s.syncmap.Store(name, info) //记录到哈希表
} else { //单线程
s.vmap[name] = info //记录到哈希表
}
}
// AddVar 记录变量 有错返回错误码
func (s *Sbt) AddVar(n *VarNode) errcode.ErrCode {
err := s.add(n.Name, n)
return err
}
// AddConst 记录常量 有错返回错误码
// - n 是被记录的常量节点
func (s *Sbt) AddConst(n *ConstNode) errcode.ErrCode {
return s.add(n.Name, n)
}
// AddFunc 记录函数
func (s *Sbt) AddFunc(info *FuncNode) errcode.ErrCode {
return s.add(info.Name, info)
}
// AddStruct 记录结构体 有错返回错误码
// - decl是语法节点
func (s *Sbt) AddStruct(decl *StructDecl) errcode.ErrCode {
return s.add(decl.Name, decl)
}
// AddPackage 记录被导入的包 有错返回错误码
// - p是被导入的包
func (s *Sbt) AddPackage(p *Package) errcode.ErrCode {
return s.add(p.PackageName, p)
}
// AddMethod 记录方法 有错返回错误码
// - method是语法节点
func (s *Sbt) AddMethod(method *MethodNode) errcode.ErrCode {
Type := utils.Ret_no_lea(method.Parame[0].Type.Typ())
table_name := Type + enum.Method
info, ok := s.have(table_name)
if !ok { //如果没有方法表
table := NewMethodTableInfo(s.Thread)
s := s
for s.sbt != nil {
s = s.sbt
}
if s.add(table_name, table) != errcode.NoErr { //并发时万一其他goroutine先添加
info, _ = s.have(table_name)
} else {
info = table
}
}
name := astdata.Generate_method_symbol(Type, method.FuncInfo.Name)
s.add(name, method)
v := info.(MethodTableInfo)
return v.Infos.add(name, method)
}
// AddEnum 记录枚举 有错返回错误码
// - n 是被记录的枚举节点
func (s *Sbt) AddEnum(n *EnumDecl) errcode.ErrCode {
for s.sbt != nil { //确保记录到全局符号表
s = s.sbt
}
return s.add(n.Name, n)
}
// AddGenInst 记录泛型实例化信息
// - node是泛型实例化节点
func (s *Sbt) AddGenInst(node *GenericInstantiation) {
typ := node.Typ()
if typ == "" {
return
}
name := utils.Ret_no_lea(typ)
s.add(name, node)
}
// HaveMethod 查询是否记录了方法
// - Type是类型名
// - Name是函数的名字
//
// 如果符号不存在,返回空信息
func (s *Sbt) HaveMethod(Type string, Name string) fmt.Stringer {
defer func() {
if err := recover(); err != nil {
if _, ok := err.(errutil.Err2); ok {
return
}
panic(err)
}
}()
Type = utils.Ret_no_lea(Type)
info, err := s.Have(Type + enum.Method)
if err != errcode.NoErr {
return nil
}
info, _ = info.(MethodTableInfo).Infos.Have(astdata.Generate_method_symbol(Type, Name))
return info
}
func (v *Sbt) String() string {
var buf strings.Builder
buf.WriteString("*ast2.Sbt{")
v.Range(func(key string, value fmt.Stringer) bool {
buf.WriteString("\n")
buf.WriteString(key)
buf.WriteString(" : ")
if _, ok := value.(*Package); !ok {
buf.WriteString(value.String())
}
return true
})
buf.WriteString("\t}")
return buf.String()
}
// Range 循环遍历所有表中记录的符号信息
func (v *Sbt) Range(f func(key string, value fmt.Stringer) bool) {
if v.Thread {
v.syncmap.Range(func(key, value interface{}) bool {
return f(key.(string), value.(fmt.Stringer))
})
} else {
for key, value := range v.vmap {
if !f(key, value) {
return
}
}
}
return
}
func (v *Sbt) Copy() *Sbt {
ret := NewSbt(v.Thread)
v.Range(func(key string, value fmt.Stringer) bool {
ret.add(key, value)
return true
})
ret.sbt = v.sbt
return ret
}
// Have 查询是否记录了符号
// - name是符号名
func (v *Sbt) Have(name string) (fmt.Stringer, errcode.ErrCode) {
value, _, err := v.Have2(name)
return value, err
}
// Have2 查询是否记录了符号
// - name是符号名
func (v *Sbt) Have2(name string) (n fmt.Stringer, inlocal bool, err errcode.ErrCode) {
// if utils.Is_In_AutoFree(name) {
// name = name[:len(name)-len(enum.AutoFreeInFunc)]
// }
info, ok := v.have(name)
if ok {
return info, true, errcode.NoErr
}
info, ok = Builtin_func_info[name]
if ok {
return info, true, errcode.NoErr
}
if v.sbt != nil { //如果存在上级符号表
n, err = v.sbt.Have(name)
return n, false, err
}
return nil, false, errcode.UnknownSymbol
}
// 预定义的函数或视为函数调用的类型转换
var Builtin_func_info = map[string]Node{
enum.Printf: NewFuncNode(&FuncInfo{Name: enum.Printf, Parame: []astdata.Parame{astdata.NewNameAndType("format", NewObject(TypeObj, enum.String))}}),
enum.Float: NewFuncNode(&FuncInfo{Name: enum.Float, RetValue: []astdata.RetValue{astdata.NewNameAndType("", NewObject(TypeObj, enum.Float))}}),
enum.Int: NewFuncNode(&FuncInfo{Name: enum.Int, RetValue: []astdata.RetValue{astdata.NewNameAndType("", NewObject(TypeObj, enum.Int))}}),
enum.Malloc: NewFuncNode(&FuncInfo{Name: enum.Malloc, Parame: []astdata.Parame{astdata.NewNameAndType("type", NewObject(TypeObj, "T"))}, RetValue: []astdata.RetValue{astdata.NewNameAndType("ptr", NewObject(TypeObj, "&T"))}}),
enum.Free: NewFuncNode(&FuncInfo{Name: enum.Free, Parame: []astdata.Parame{astdata.NewNameAndType("ptr", NewObject(TypeObj, "&T"))}}),
enum.UnsafeAdd: NewFuncNode(&FuncInfo{Name: enum.UnsafeAdd, Parame: []astdata.Parame{astdata.NewNameAndType("ptr", NewObject(TypeObj, "&T")), astdata.NewNameAndType("offset", NewObject(TypeObj, enum.Int))}, RetValue: []astdata.RetValue{astdata.NewNameAndType("ptr", NewObject(TypeObj, "&T"))}}),
enum.UnsafeConvert: NewFuncNode(&FuncInfo{Name: enum.UnsafeConvert, Parame: []astdata.Parame{astdata.NewNameAndType("ptr", NewObject(TypeObj, enum.UnsafePointer)), astdata.NewNameAndType("type", NewObject(TypeObj, "T"))}, RetValue: []astdata.RetValue{astdata.NewNameAndType("ptr", NewObject(TypeObj, "&T"))}}),
enum.UnsafeSizeof: NewFuncNode(&FuncInfo{Name: enum.UnsafeSizeof, Parame: []astdata.Parame{astdata.NewNameAndType("type", NewObject(TypeObj, "T"))}, RetValue: []astdata.RetValue{astdata.NewNameAndType("size", NewObject(TypeObj, enum.Int))}}),
enum.MallocSize: NewFuncNode(&FuncInfo{Name: enum.MallocSize, Parame: []astdata.Parame{astdata.NewNameAndType("size", NewObject(TypeObj, enum.Int))}, RetValue: []astdata.RetValue{astdata.NewNameAndType("ptr", NewObject(TypeObj, enum.UnsafePointer))}}),
enum.MemPoolFree: NewFuncNode(nil),
enum.MemPoolNew: NewFuncNode(nil),
enum.UnsafePointer: NewFuncNode(nil),
}
// have 查询是否记录某个符号
func (s *Sbt) have(name string) (fmt.Stringer, bool) {
if s.Thread { //多线程
ret, ok := s.syncmap.Load(name)
if ok {
return ret.(fmt.Stringer), true
}
} else { //单线程
ret, ok := s.vmap[name]
return ret, ok
}
return nil, false
}
func (s *Sbt) delete(name string) {
if s.Thread {
s.syncmap.Delete(name)
return
}
delete(s.vmap, name)
}
var (
TypeEnumStrMap = map[string]*Object{
"int": NewObject(TypeObj, "int"),
"string": NewObject(TypeObj, "string"),
"bool": NewObject(TypeObj, "bool"),
"float": NewObject(TypeObj, "float"),
enum.UnsafePointer: NewObject(TypeObj, enum.UnsafePointer),
"any": NewObject(TypeObj, "any"),
}
)
// HaveType 查询是否记录了指定类型的符号
// - name是符号名
func (s *Sbt) HaveType(name string) (astdata.Typ, errcode.ErrCode) {
name = utils.Ret_no_lea(name)
if o, ok := TypeEnumStrMap[name]; ok {
return o, errcode.NoErr
}
ret, ok := s.have(name)
if !ok && s.sbt != nil { //如果存在上级符号表
return s.sbt.HaveType(name)
}
if ret, ok := ret.(astdata.Typ); ok {
//TODO:更严格的检查是否是类型符号
return ret, errcode.NoErr
}
return nil, errcode.UnknownType
}
// ImportInfo 导入信息
type ImportInfo struct {
Path string
}
func (info ImportInfo) String() string {
return fmt.Sprintf("*ast2.ImportInfo{Path:%s}", info.Path)
}
type MethodTableInfo struct {
Infos *Sbt
}
func NewMethodTableInfo(Thread bool) MethodTableInfo {
return MethodTableInfo{NewSbt(Thread)}
}
func (info MethodTableInfo) String() string {
return info.Infos.String()
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。