1 Star 1 Fork 1

U语言组织/U语言

forked from 秋来冬风/U语言 
Create your Gitee Account
Explore and code with more than 13.5 million developers,Free private repositories !:)
Sign up
文件
Clone or Download
sbt.go 9.33 KB
Copy Edit Raw Blame History
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()
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/u-language/u-language.git
git@gitee.com:u-language/u-language.git
u-language
u-language
U语言
df767d8a61bb

Search