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"
"strconv"
"strings"
"sync"
"gitee.com/u-language/u-language/ucom/astdata"
"gitee.com/u-language/u-language/ucom/data"
"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"
)
// 节点接口,代表一个抽象语法树节点
type Node interface {
String() string
C(buf *strings.Builder)
}
// 表达式接口,代表一个表达式
type Expr interface {
Node
expr()
}
type node struct {
LineNum int
}
var (
varname = "变量名"
constname = "常量名"
)
var _ Node = (*VarNode)(nil)
var _ Node = (*FuncNode)(nil)
var _ Node = (*ASSIGNNode)(nil)
var _ Node = (*Object)(nil)
var _ Expr = (*OpExpr)(nil)
var _ Node = (*RbraceNode)(nil)
var _ Node = (*IfNode)(nil)
var _ Node = (*ElseNode)(nil)
var _ Node = (*ForNode)(nil)
var _ Node = (*CallNode)(nil)
var _ Node = (*ReturnNode)(nil)
var _ Node = (*GotoStmt)(nil)
var _ Node = (*LabelNode)(nil)
var _ Node = (*BreakStmt)(nil)
var _ Node = (*ContinueStmt)(nil)
var _ Node = (*ConstNode)(nil)
var _ Node = (*StructDecl)(nil)
var _ Node = (*Objects)(nil)
var _ Node = (*SelfOpStmt)(nil)
var _ Node = (*SwitchNode)(nil)
var _ Node = (*CaseNode)(nil)
var _ Node = (*DefaultNode)(nil)
var _ Node = (*MethodNode)(nil)
var _ Node = (*AutoFreeNode)(nil)
var _ Node = (*EnumDecl)(nil)
var _ Node = (*IndexExpr)(nil)
var _ Node = (*GenericInstantiation)(nil)
var _ Node = (*DerefExpr)(nil)
var _ astdata.Typ = (*Object)(nil)
var _ astdata.Typ = (*Objects)(nil)
var _ astdata.Typ = (*StructDecl)(nil)
var _ astdata.Typ = (*Array)(nil)
var _ astdata.Typ = (*GenericInstantiation)(nil)
var _ astdata.Typ = (*EnumDecl)(nil)
var _ Expr = (*Object)(nil)
var _ Expr = (*Objects)(nil)
var _ Expr = (*CallNode)(nil)
var _ Expr = (*OpExpr)(nil)
var _ Expr = (*IndexExpr)(nil)
var _ Expr = (*DerefExpr)(nil)
var _ set_nosemicolon_interface = (*VarNode)(nil)
var _ set_nosemicolon_interface = (*ASSIGNNode)(nil)
var _ set_nosemicolon_interface = (*OpExpr)(nil)
var _ set_nosemicolon_interface = (*SelfOpStmt)(nil)
var _ set_nosemicolon_interface = (*CallNode)(nil)
type CType interface {
CType(buf *strings.Builder)
}
var _ CType = (*Object)(nil)
var _ CType = (*Objects)(nil)
type set_nosemicolon_interface interface {
SetNosemicolon(nosemicolon bool)
}
var _ CDecl = (*VarNode)(nil)
var _ CDecl = (*ConstNode)(nil)
var _ CDecl = (*StructDecl)(nil)
var _ CDecl = (*EnumDecl)(nil)
var _ CDecl = (*FuncNode)(nil)
var _ CDecl = (*MethodNode)(nil)
// CDecl 表示一个支持生成C头文件的一个声明语句的类型
type CDecl interface {
Node
CDecl(buf *strings.Builder)
}
// 变量声明节点
type VarNode struct {
TYPE astdata.Typ //变量类型
Value Expr //值
Name string //变量名
Tmp *VarNode //处理变量遮蔽
CType string
InFunc bool
nosemicolon bool
node
}
// NewVarNode 创建变量声明节点
func NewVarNode(name string, InFunc bool, LineNum int) *VarNode {
ret := &VarNode{Name: name, InFunc: InFunc}
ret.LineNum = LineNum
return ret
}
func (n *VarNode) String() string {
var buf strings.Builder
if handleNil(&buf, n) {
return buf.String()
}
buf.WriteString("*ast2.VarNode")
buf.WriteString(fmt.Sprintf("%+v", *n))
return buf.String()
}
func (v *VarNode) C(buf *strings.Builder) {
if v.CType == "" {
tocVarNode(v)
}
if v.Tmp != nil {
v.Tmp.C(buf)
}
buf.Grow(65)
buf.WriteString(v.CType)
buf.WriteString(" ")
buf.WriteString(v.Name)
if v.InFunc && v.Value != nil { //是局部变量初始化
buf.WriteString(" = ")
v.Value.C(buf)
}
if !v.nosemicolon {
buf.WriteString(" ;")
}
}
func (n *VarNode) SetNosemicolon(nosemicolon bool) {
n.nosemicolon = nosemicolon
}
func (v *VarNode) CDecl(buf *strings.Builder) {
tocVarNode(v)
buf.Grow(65)
buf.WriteString("extern ")
buf.WriteString(v.CType)
buf.WriteString(" ")
buf.WriteString(v.Name)
buf.WriteString(" ;")
}
func tocVarNode(n *VarNode) {
typ := n.TYPE.Typ()
if typ[0] == '[' { //如果是连续类型
elem, Len := new(strings.Builder), new(strings.Builder)
splitElemAndLen(elem, Len, typ)
n.Name, n.CType = n.Name+Len.String(), typeToC(elem.String())
} else {
n.CType = typeToC(typ)
}
}
// splitElemAndLen 分割元素类型与长度
// 对于单维数组 [expr]x elem写入 x Len 写入 [expr]
// 对于多维数组 [expr]x elem写入 x Len 写入 所有的[expr]
func splitElemAndLen(elem, Len *strings.Builder, typ string) {
if typ[0] == '[' {
e, l, _ := utils.Elem(typ)
Len.WriteString(l)
splitElemAndLen(elem, Len, e)
return
}
elem.WriteString(typ)
}
// FuncInfo 函数信息
type FuncInfo struct {
Name string
Parame []astdata.Parame
RetValue []astdata.RetValue
TypeParame []astdata.NameAndType
codeBlock
}
func (f *FuncInfo) String() string {
return fmt.Sprintf("%+v", *f)
}
// 函数节点
type FuncNode struct {
*FuncInfo
}
// NewFuncNode 创建函数节点
func NewFuncNode(info *FuncInfo) *FuncNode {
var ret FuncNode
ret.FuncInfo = info
return &ret
}
func (f *FuncNode) String() string {
var buf strings.Builder
if handleNil(&buf, f) {
return buf.String()
}
buf.WriteString("*ast2.FuncNode{\n")
buf.WriteString(fmt.Sprintf("name=%s\t", f.Name))
buf.WriteString(fmt.Sprintf("Parame=%s\t", f.Parame))
buf.WriteString(fmt.Sprintf("RetValue=%s\t", f.RetValue))
buf.WriteString(fmt.Sprintf("TypeParame=%s\n", f.TypeParame))
buf.WriteString(f.Sbt.String())
return buf.String()
}
func (f *FuncNode) C(buf *strings.Builder) {
buf.Grow(100)
if f.Name == "main" {
buf.WriteString("int main(){\n")
buf.WriteString("main__init();\n")
} else {
if len(f.RetValue) != 0 {
buf.WriteString(typeToC(f.RetValue[0].Type.Typ()))
} else {
buf.WriteString("void")
}
buf.WriteString(" ")
buf.WriteString(f.Name)
buf.WriteString("(")
plen := len(f.Parame)
for i := 0; i < plen; i++ {
buf.WriteString(typeToC(f.Parame[i].Type.Typ()))
buf.WriteString(" ")
buf.WriteString(f.Parame[i].Name)
if i+1 < plen {
buf.WriteString(",")
}
}
buf.WriteString("){")
}
}
func (f *FuncNode) CDecl(buf *strings.Builder) {
if f.TypeParame != nil {
return
}
buf.Grow(100)
if f.Name == "main" {
buf.WriteString("int main();\n")
return
}
if len(f.RetValue) != 0 {
buf.WriteString(typeToC(f.RetValue[0].Type.Typ()))
} else {
buf.WriteString("void")
}
buf.WriteString(" ")
buf.WriteString(f.Name)
buf.WriteString("(")
plen := len(f.Parame)
for i := 0; i < plen; i++ {
buf.WriteString(typeToC(f.Parame[i].Type.Typ()))
buf.WriteString(" ")
buf.WriteString(f.Parame[i].Name)
if i+1 < plen {
buf.WriteString(",")
}
}
buf.WriteString(");")
}
// 赋值节点
type AssignmentNode struct {
//目的操作数,源操作数
Dest Expr
Src Expr
nosemicolon bool
node
}
type ASSIGNNode = AssignmentNode
// NewASSIGNNode 创建赋值节点
func NewASSIGNNode(Dest Expr, Src Expr, LineNum int) *ASSIGNNode {
ret := &ASSIGNNode{
Dest: Dest,
Src: Src,
}
ret.LineNum = LineNum
return ret
}
func (a *ASSIGNNode) String() string {
var buf strings.Builder
if handleNil(&buf, a) {
return buf.String()
}
buf.WriteString("*ast2.ASSIGNode{")
buf.WriteString("\nDest:")
buf.WriteString(a.Dest.String())
buf.WriteString("\nSrc:")
buf.WriteString(a.Src.String())
buf.WriteString("\n\t}")
return buf.String()
}
func (a *ASSIGNNode) C(buf *strings.Builder) {
buf.Grow(50)
a.Dest.C(buf)
buf.WriteString(" = ")
a.Src.C(buf)
if !a.nosemicolon {
buf.WriteString(" ;")
}
}
func (a *ASSIGNNode) SetNosemicolon(nosemicolon bool) {
a.nosemicolon = nosemicolon
}
// 对象类型枚举
type ObjKind int
const (
NoKind ObjKind = 1 << iota
INTOBJ
FLOATOBJ
BoolObj
StringObj
SymbolObj
LeaObj
DerefObj
StructPtr
NilObj
EnumObj
TypeObj
)
var (
ObjKindSrtMap = [...]string{
NoKind: "nokind (未定义的枚举)",
INTOBJ: "intobj (整数)",
FLOATOBJ: "floatobj (浮点数)",
BoolObj: "boolobj (布尔值)",
StringObj: "stringobj(字符串)",
SymbolObj: "SymbolObj (符号)",
LeaObj: "leaObj (取地址)",
DerefObj: "derefObj (解引用)",
StructPtr: "StructPtr (结构体指针)",
NilObj: "NilObj (指针的零值)",
EnumObj: "EnumObj (枚举值)",
TypeObj: "TypeObj(类型)",
}
)
func (o ObjKind) String() string {
var buf strings.Builder
try_equal(o, INTOBJ, &buf)
try_equal(o, FLOATOBJ, &buf)
try_equal(o, BoolObj, &buf)
try_equal(o, StringObj, &buf)
try_equal(o, SymbolObj, &buf)
try_equal(o, LeaObj, &buf)
try_equal(o, DerefObj, &buf)
try_equal(o, StructPtr, &buf)
try_equal(o, NilObj, &buf)
try_equal(o, EnumObj, &buf)
try_equal(o, TypeObj, &buf)
return buf.String()
}
func try_equal(k ObjKind, eq ObjKind, buf *strings.Builder) {
if k&eq != 0 {
buf.WriteString(ObjKindSrtMap[eq])
}
}
// 对象节点
//
// 可能表示
// - 整数
// - 浮点数
// - 布尔值
// - 符号
// - 字符串
type Object struct {
Name string
Kind ObjKind
}
// 创建对象节点
func NewObject(Kind ObjKind, Name string) *Object {
ret := &Object{Name: Name}
ret.Kind = Kind
return ret
}
func (o *Object) String() string {
var buf strings.Builder
if handleNil(&buf, o) {
return buf.String()
}
buf.WriteString("*ast2.Object")
buf.WriteString(fmt.Sprintf("%+v", *o))
return buf.String()
}
func (o *Object) Typ() string {
if o.Kind&LeaObj != 0 {
if o.Kind&TypeObj != 0 {
return "&" + o.Name
}
return o.Name + "*"
}
return o.Name
}
func (o *Object) SetTyp() { o.Kind |= TypeObj }
func (o *Object) Copy() astdata.Typ {
ret := *o
return &ret
}
func (o *Object) SetLea(i int) {
n, leai := utils.Ret_type_no_lea(o.Name)
if leai == i {
return
}
o.Kind |= LeaObj
var buf strings.Builder
buf.Grow(i + len(n))
buf.WriteString(strings.Repeat("&", i))
buf.WriteString(n)
o.Name = buf.String()
}
func (o *Object) C(buf *strings.Builder) {
buf.Grow(len(o.Name))
switch o.Kind {
case INTOBJ, FLOATOBJ, BoolObj, StringObj, SymbolObj, StructPtr, StructPtr | SymbolObj, SymbolObj | EnumObj, TypeObj:
buf.WriteString(o.Name)
case LeaObj, LeaObj | StructPtr:
buf.WriteString("&")
buf.WriteString(o.Name)
case DerefObj, DerefObj | StructPtr:
buf.WriteString("(*")
buf.WriteString(o.Name)
buf.WriteString(")")
case NilObj:
buf.WriteString("NULL")
}
}
func (o *Object) CType(buf *strings.Builder) {
buf.Grow(len(o.Name))
switch o.Kind {
case INTOBJ, FLOATOBJ, BoolObj, StringObj, SymbolObj, StructPtr, StructPtr | SymbolObj, SymbolObj | EnumObj, TypeObj:
buf.WriteString(typeToC(o.Name))
case LeaObj, LeaObj | StructPtr:
buf.WriteString(typeToC(o.Name))
buf.WriteString("*")
case DerefObj, DerefObj | StructPtr:
buf.WriteString("(*")
buf.WriteString(typeToC(o.Name))
buf.WriteString(")")
case NilObj:
buf.WriteString("NULL")
}
}
func (o *Object) expr() {}
// 运算表达式节点
type OperationExpr struct {
Src1 Expr
Src2 Expr
OP enum.OPSymbol
Inparen bool //是否在小括号内
node
}
// 运算表达式节点
type OpExpr = OperationExpr
// NewOpExpr 创建运算表达式节点
func NewOpExpr(OP enum.OPSymbol, Src1, Src2 Expr, LineNum int) *OpExpr {
ret := &OpExpr{
OP: OP,
Src1: Src1,
Src2: Src2,
}
ret.LineNum = LineNum
return ret
}
func (a *OpExpr) String() string {
var buf strings.Builder
buf.Grow(10)
if handleNil(&buf, a) {
return buf.String()
}
buf.WriteString("*ast2.OpExpr{")
buf.WriteString("\nOP:")
buf.WriteString(a.OP.String())
buf.WriteString("\nSrc1:")
buf.WriteString(a.Src1.String())
buf.WriteString("\nSrc2:")
buf.WriteString(a.Src2.String())
buf.WriteString("\nInparen:")
buf.WriteString(strconv.FormatBool(a.Inparen))
buf.WriteString("}")
return buf.String()
}
func (a *OpExpr) expr() {}
func (a *OpExpr) C(buf *strings.Builder) {
buf.Grow(10)
if a.Inparen {
buf.WriteString("(")
defer buf.WriteString(")")
}
a.Src1.C(buf)
str, ok := opToStrMap[a.OP]
if !ok {
panic(errutil.NewErr2(errutil.CompileErr, fmt.Sprintf("未知的 op: %s", a.OP.String())))
}
buf.WriteString(str)
a.Src2.C(buf)
}
func (o *OpExpr) SetNosemicolon(nosemicolon bool) {
if s, ok := o.Src1.(set_nosemicolon_interface); ok {
s.SetNosemicolon(true)
}
if s, ok := o.Src2.(set_nosemicolon_interface); ok {
s.SetNosemicolon(true)
}
}
var opToStrMap = map[enum.OPSymbol]string{
enum.ADDOP: " + ",
enum.SUBOP: " - ",
enum.MULOP: " * ",
enum.DIVOP: " / ",
enum.LessOP: " < ",
enum.GreaterOP: " > ",
enum.EqualOP: " == ",
enum.NoEqualOP: " != ",
enum.RemainOP: " % ",
enum.IncOP: "++",
enum.DecOP: "--",
enum.AndOP: "&",
enum.OrOP: "|",
enum.XorOp: "^",
enum.LogicAndOP: "&&",
enum.LogicOrOP: "||",
}
// 右大括号节点
type RbraceNode struct{}
func NewRbraceNode() RbraceNode {
return RbraceNode{}
}
func (b RbraceNode) String() string {
var buf strings.Builder
buf.WriteString("ast2.RbraceNode{}")
return buf.String()
}
func (b RbraceNode) C(buf *strings.Builder) {
buf.WriteString("}")
}
// if节点
type IfNode struct {
codeBlock
BoolExpr Expr
}
// NewIfNode 创建if节点
func NewIfNode(LineNum int) *IfNode {
ret := &IfNode{}
ret.codeBlock = newCodeBlock(LineNum)
return ret
}
func (l *IfNode) String() string {
var buf strings.Builder
if handleNil(&buf, l) {
return buf.String()
}
buf.WriteString("*ast2.IfNode{\n")
buf.WriteString(l.BoolExpr.String())
buf.WriteString(l.Sbt.String())
buf.WriteString("}")
return buf.String()
}
func (l *IfNode) C(buf *strings.Builder) {
buf.Grow(7)
buf.WriteString("if (")
l.BoolExpr.C(buf)
buf.WriteString("){")
}
// else节点
type ElseNode struct {
codeBlock
BoolExpr Expr
}
// NewElseNode 创建else节点
func NewElseNode(LineNum int) *ElseNode {
ret := &ElseNode{}
ret.codeBlock = newCodeBlock(LineNum)
return ret
}
func (l *ElseNode) String() string {
var buf strings.Builder
if handleNil(&buf, l) {
return buf.String()
}
buf.WriteString("*ast2.ElseNode{\n")
if l.BoolExpr != nil {
buf.WriteString(fmt.Sprintf("boolexpr=%+v\n", l.BoolExpr))
}
buf.WriteString(l.Sbt.String())
buf.WriteString("}")
return buf.String()
}
func (l *ElseNode) C(buf *strings.Builder) {
buf.Grow(13)
buf.WriteString("else ")
if l.BoolExpr != nil {
buf.WriteString("if (")
l.BoolExpr.C(buf)
buf.WriteString(")")
}
buf.WriteString("{\n")
}
// codeBlock 是代码块应该包含的值和方法
type codeBlock struct {
node
Sbt *Sbt //当前作用域符号表
}
func newCodeBlock(LineNum int) codeBlock {
ret := codeBlock{}
ret.LineNum = LineNum
ret.Sbt = NewSbt(false)
return ret
}
func (c *codeBlock) getSbt() *Sbt {
return c.Sbt
}
// CodeBlockIface 是代码块节点接口
type CodeBlockIface interface {
Node
getSbt() *Sbt
}
// for节点
type ForNode struct {
codeBlock
InitStmt Node
BoolExpr Expr
EndStmt Node
}
// NewForNode 创建for节点
func NewForNode(LineNum int) *ForNode {
ret := &ForNode{}
ret.codeBlock = newCodeBlock(LineNum)
return ret
}
func (l *ForNode) String() string {
var buf strings.Builder
if handleNil(&buf, l) {
return buf.String()
}
buf.WriteString("*ast2.ForNode{\n")
if l.InitStmt != nil {
buf.WriteString("\nInitStmt:")
buf.WriteString(l.InitStmt.String())
}
if l.BoolExpr != nil {
buf.WriteString("\nBoolStmt:")
buf.WriteString(l.BoolExpr.String())
}
if l.EndStmt != nil {
buf.WriteString("\nEndStmt:")
buf.WriteString(l.EndStmt.String())
}
buf.WriteString(l.Sbt.String())
buf.WriteString("}")
return buf.String()
}
func (l *ForNode) C(buf *strings.Builder) {
buf.Grow(11)
buf.WriteString("for (")
if l.InitStmt != nil {
l.InitStmt.C(buf)
} else {
buf.WriteString(" ;")
}
if l.BoolExpr != nil {
l.BoolExpr.C(buf)
}
buf.WriteString(";")
if l.EndStmt != nil {
iface := l.EndStmt.(set_nosemicolon_interface)
iface.SetNosemicolon(true)
l.EndStmt.C(buf)
}
buf.WriteString("){")
}
// 函数调用节点
type CallNode struct {
FuncName Expr //调用函数名
Parame []Expr //Parameter
CCallFuncName string
nosemicolon bool
InAutoFree bool
node
}
// NewCallNode 创建函数调用节点
func NewCallExpr(funcname Expr, LineNum int, parame ...Expr) *CallNode {
ret := new(CallNode)
ret.FuncName = funcname
ret.Parame = parame
ret.LineNum = LineNum
return ret
}
func (a *CallNode) String() string {
var buf strings.Builder
if handleNil(&buf, a) {
return buf.String()
}
buf.WriteString("*ast2.CallNode{")
buf.WriteString(fmt.Sprintf("%+v}", *a))
return buf.String()
}
func (c *CallNode) expr() {}
func (c *CallNode) SetNosemicolon(nosemicolon bool) {
c.nosemicolon = nosemicolon
}
func (a *CallNode) C(buf *strings.Builder) {
a = utoCCall(a)
buf.Grow(60)
defer func() {
if !a.nosemicolon {
buf.WriteString(";")
}
}()
pl := len(a.Parame)
switch a.CCallFuncName {
case enum.Malloc:
buf.WriteString("(")
a.Parame[0].(CType).CType(buf)
buf.WriteString("*)malloc(sizeof(")
a.Parame[0].(CType).CType(buf)
buf.WriteString("))")
return
case enum.Int, enum.Float:
buf.WriteString("(")
buf.WriteString(typeToC(a.CCallFuncName))
buf.WriteString(")")
a.Parame[0].C(buf)
return
case enum.UnsafeAdd:
buf.WriteString("(((void*)")
a.Parame[0].C(buf)
buf.WriteString(")+")
a.Parame[1].C(buf)
buf.WriteString(")")
return
case enum.UnsafeConvert:
buf.WriteString("(")
a.Parame[1].(CType).CType(buf)
buf.WriteString(")")
a.Parame[0].C(buf)
return
case enum.MallocSize:
buf.WriteString("malloc(")
a.Parame[0].C(buf)
buf.WriteString(")")
return
case enum.UnsafeSizeof:
buf.WriteString("sizeof(")
a.Parame[0].(CType).CType(buf)
buf.WriteString(")")
return
case enum.MemPoolNew:
buf.WriteString(enum.MemPoolNew)
buf.WriteString("(")
a.Parame[0].C(buf)
buf.WriteString(",")
if o, ok := a.Parame[1].(*Object); ok && o.Kind == TypeObj { //如果是类型
buf.WriteString("sizeof(")
buf.WriteString(typeToC(o.Name))
buf.WriteString(")")
} else {
a.Parame[1].C(buf)
}
buf.WriteString(")")
return
case enum.UnsafePointer:
buf.WriteString("(void *)")
a.Parame[0].C(buf)
return
}
buf.WriteString(a.CCallFuncName)
buf.WriteString("(")
for i := 0; i < pl; i++ {
a.Parame[i].C(buf)
if i+1 < pl { //如果不是最后一个参数
buf.WriteString(",")
}
}
buf.WriteString(")")
}
// utoCCall 将调用节点转换为cast等价的
// - c是被转换的,不能为nil
func utoCCall(c *CallNode) *CallNode {
var funcname string
var parame []Expr
poff := 0
if n, ok := c.FuncName.(*Objects); ok {
if c.InAutoFree {
poff = 1
}
if n.T != "" { //如果是方法
poff++
parame = make([]Expr, len(c.Parame)+1)
funcname = astdata.Generate_method_symbol(n.T, n.Slice[len(n.Slice)-1].Name)
receiver := *n
receiver.Slice = n.Slice[:len(n.Slice)-1]
parame[poff-1] = &receiver
} else {
parame = make([]Expr, len(c.Parame))
var buf strings.Builder
buf.WriteString(n.Slice[0].Name)
for _, v := range n.Slice[1:] {
buf.WriteString(enum.PackageSep)
buf.WriteString(v.Name)
}
funcname = buf.String()
if n.IsImportSymbol {
//TODO:避免不同包同名冲突
funcname = n.Slice[1].Name
}
}
} else {
parame = make([]Expr, len(c.Parame))
//Noto:未来支持a()(),其中a()返回函数类型,这里需要修改
funcname = c.FuncName.(*Object).Name
}
c.CCallFuncName = funcname
for i := 0; i < len(c.Parame); i++ {
if parame[i] != nil {
continue
}
parame[i] = c.Parame[i]
}
c.Parame = parame
return c
}
// return节点
type ReturnNode struct {
RetValue Expr
LineNum int
}
func (l *ReturnNode) String() string {
var buf strings.Builder
if handleNil(&buf, l) {
return buf.String()
}
buf.WriteString("*ast2.ReturnNode{")
buf.WriteString(fmt.Sprint(l.RetValue))
buf.WriteString("}")
return buf.String()
}
func (l *ReturnNode) C(buf *strings.Builder) {
buf.Grow(8)
buf.WriteString("return ")
if l.RetValue != nil {
l.RetValue.C(buf)
}
buf.WriteString(";")
}
// 缩写: statement 缩写成Stmt
// goto语句
type GotoStmt struct {
Label string
node
}
func NewGotoStmt(LineNum int) *GotoStmt {
ret := &GotoStmt{}
ret.LineNum = LineNum
return ret
}
func (g *GotoStmt) String() string {
return fmt.Sprintf("*ast2.GotoStmt{Label:%s}", g.Label)
}
func (g *GotoStmt) C(buf *strings.Builder) {
buf.Grow(len(g.Label) + 6)
buf.WriteString("goto ")
buf.WriteString(g.Label)
buf.WriteString(";")
}
// 标签
type LabelNode struct {
Value string
node
}
func NewLabelNode(value string, LineNum int) *LabelNode {
ret := &LabelNode{Value: value}
ret.LineNum = LineNum
return ret
}
func (b *LabelNode) String() string {
return fmt.Sprintf("*ast2.LabelNode{Value:%s}", b.Value)
}
func (l *LabelNode) C(buf *strings.Builder) {
buf.Grow(len(l.Value) + 1)
buf.WriteString(l.Value)
buf.WriteString(":")
}
// break语句
type BreakStmt struct{}
func NewBreakStmt() BreakStmt {
return BreakStmt{}
}
func (b BreakStmt) String() string {
var buf strings.Builder
buf.WriteString("ast2.BreakStmt{}")
return buf.String()
}
func (b BreakStmt) C(buf *strings.Builder) {
buf.Grow(7)
buf.WriteString("break ;")
}
// continue语句
type ContinueStmt struct{}
func NewContinueStmt() ContinueStmt {
return ContinueStmt{}
}
func (c ContinueStmt) String() string {
var buf strings.Builder
buf.WriteString("ast2.ContinueStmt{}")
return buf.String()
}
func (c ContinueStmt) C(buf *strings.Builder) {
buf.Grow(10)
buf.WriteString("continue ;")
}
// 常量声明节点
type ConstNode struct {
TYPE astdata.Typ
Value Expr
Name string
node
}
// newConstNode 创建常量声明节点
func newConstNode(name string, LineNum int) *ConstNode {
c := &ConstNode{Name: name}
c.LineNum = LineNum
return c
}
func (n *ConstNode) String() string {
var buf strings.Builder
if handleNil(&buf, n) {
return buf.String()
}
buf.WriteString("*ast2.Const{")
buf.WriteString(fmt.Sprintf("%+v}", *n))
return buf.String()
}
func (c *ConstNode) C(buf *strings.Builder) {
var typename string
if o, ok := c.TYPE.(*Object); ok {
typename = typeToC(o.Name)
} else {
typename = c.TYPE.Typ()
}
buf.Grow(60)
buf.WriteString(enum.Const)
buf.WriteString(" ")
buf.WriteString(typename)
buf.WriteString(" ")
buf.WriteString(c.Name)
if c.Value == nil { //没有初始化
buf.WriteString(" ;")
return
}
buf.WriteString(" = ")
c.Value.C(buf)
buf.WriteString(" ;")
}
func (c *ConstNode) CDecl(buf *strings.Builder) {
buf.WriteString("extern ")
var typename string
if o, ok := c.TYPE.(*Object); ok {
typename = typeToC(o.Name)
} else {
typename = c.TYPE.Typ()
}
buf.Grow(60)
buf.WriteString(enum.Const)
buf.WriteString(" ")
buf.WriteString(typename)
buf.WriteString(" ")
buf.WriteString(c.Name)
buf.WriteString(" ;")
}
// StructDecl 结构体声明
//
// 缩写:struct declaration 缩写成:StructDecl
type StructDecl struct {
sbt *Sbt
Name string
FileName string
FieldTable []Field
TypeParame []astdata.NameAndType
InFunc bool
node
}
func (s *StructDecl) String() string {
var buf strings.Builder
if handleNil(&buf, s) {
return buf.String()
}
buf.WriteString("*ast2.StructDecl{")
buf.WriteString(fmt.Sprintf("%+v}", *s))
return buf.String()
}
func (s *StructDecl) C(buf *strings.Builder) {
if !s.InFunc { //全局结构体的C代码由CDecl生产
return
}
s.c(buf)
}
func (s *StructDecl) c(buf *strings.Builder) {
if s.TypeParame != nil { //跳过未实例化泛型
return
}
buf.Grow(20 + len(s.FieldTable)*15)
buf.WriteString("typedef struct ")
buf.WriteString(s.Name)
buf.WriteString("{\n")
for _, v := range s.FieldTable {
buf.WriteString(typeToC(v.Type.Typ()))
buf.WriteString(" ")
buf.WriteString(v.Name)
buf.WriteString(";\n")
}
buf.WriteString("}")
buf.WriteString(s.Name)
buf.WriteString(";")
}
func (s *StructDecl) CDecl(buf *strings.Builder) {
s.c(buf)
}
func (s *StructDecl) Typ() string {
return s.Name
}
func (s *StructDecl) Copy() astdata.Typ { panic("未实现") }
func (s *StructDecl) SetLea(i int) { panic("未实现") }
func (s *StructDecl) SetTyp() { panic("未实现") }
func (s *StructDecl) genName() string {
list := typInfoToStr(s.FieldTable)
return utils.GenerateGenericTypes(s.Name, list)
}
// FindField 寻找结构体字段中是否有Name
// 返回值Field.Name==""表示结构体字段中没有要查询到
func (info *StructDecl) FindField(Name string) Field {
for _, v := range info.FieldTable {
if v.Name == Name {
return v
}
}
return Field{}
}
func (info *StructDecl) My() string {
return info.Name
}
func (info *StructDecl) DepLen() int {
return len(info.FieldTable)
}
func (info *StructDecl) Dep(i int) data.IsItARecursiveType {
iface := fieldInfo{typ: info.FieldTable[i].Type}
iface.dep = findTypeDep(info.sbt, info.FieldTable[i].Type)
return iface
}
// fieldInfo 字段信息
type fieldInfo struct {
typ astdata.Typ
dep data.IsItARecursiveType
}
func (info fieldInfo) My() string {
return info.typ.Typ()
}
func (info fieldInfo) DepLen() int {
return 1
}
func (info fieldInfo) Dep(i int) data.IsItARecursiveType {
if i != 0 {
panic(errutil.NewErr2(errutil.CompileErr, "访问越界"))
}
return info.dep
}
func (info fieldInfo) String() string {
return fmt.Sprintf("typ:%s\tdep:%+v", info.typ, info.dep)
}
// findTypeDep 寻找类型的依赖
func findTypeDep(sbt *Sbt, typ astdata.Typ) data.IsItARecursiveType {
var info astdata.Typ
if o, ok := typ.(*Object); ok {
info, _ = sbt.HaveType(o.Name)
} else {
o := typ.(*Objects)
info, _ = sbt.HaveType(utils.GeneratePackageSymbol(o.Slice[0].Name, o.Slice[1].Name))
}
v, _ := info.(*StructDecl)
return v
}
func typInfoToStr(typ []astdata.NameAndType) []string {
copys := make([]string, len(typ))
for i := 0; i < len(typ); i++ {
copys[i] = typ[i].Type.Typ()
}
return copys
}
func typeToC(typ string) string {
switch typ {
case enum.String:
return "char*"
case enum.Int:
return "int64_t"
case enum.UnsafePointer:
return "void*"
}
switch typ[0] {
case '&':
return typeToC(typ[1:]) + "*"
}
return typ
}
type Field = astdata.NameAndType
type Objects struct {
T string
Slice []Object
IsImportSymbol bool //是否是导入符号,由语义检查填充
}
func NewObjects(slice []Object) *Objects {
return &Objects{Slice: slice}
}
func (o *Objects) String() string {
var buf strings.Builder
if handleNil(&buf, o) {
return buf.String()
}
buf.WriteString("*ast2.Objects{")
for _, v := range o.Slice {
buf.WriteString(v.String())
}
buf.WriteString("}")
return buf.String()
}
func (o *Objects) FuncName() string {
var buf strings.Builder
buf.Grow(50)
for _, v := range o.Slice[:len(o.Slice)-1] {
buf.WriteString(v.Name)
buf.WriteString(".")
}
buf.WriteString(o.Slice[len(o.Slice)-1].Name)
return buf.String()
}
func (o *Objects) Typ() string {
var buf strings.Builder
buf.Grow(50)
if o.Slice[0].Kind&LeaObj != 0 {
buf.WriteString("&")
}
buf.WriteString(o.Slice[0].Name)
buf.WriteString(enum.PackageSep)
buf.WriteString(o.Slice[1].Name)
return buf.String()
}
func (o *Objects) SetTyp() { o.Slice[0].Kind |= TypeObj }
func (o *Objects) Copy() astdata.Typ {
ret := *o
return &ret
}
func (o *Objects) SetLea(i int) {
o.Slice[0].SetLea(i)
}
func (o *Objects) C(buf *strings.Builder) {
if o.IsImportSymbol {
//TODO:删除这个特殊处理
buf.WriteString(o.Slice[1].Name)
return
}
buf.Grow(50)
slen := len(o.Slice)
for i := 0; i < slen; i++ {
o.Slice[i].C(buf)
if i+1 < slen {
if o.Slice[i].Kind&StructPtr != 0 && o.Slice[i].Kind&DerefObj == 0 {
buf.WriteString("->")
} else {
if o.IsImportSymbol || o.Slice[i].Kind&EnumObj != 0 {
buf.WriteString(enum.PackageSep)
} else {
buf.WriteString(".")
}
}
}
}
}
func (o *Objects) CType(buf *strings.Builder) {
buf.Grow(20)
buf.WriteString(o.Slice[0].Name)
buf.WriteString(enum.PackageSep)
buf.WriteString(o.Slice[1].Name)
}
func (o *Objects) expr() {}
// 自操作语句
// 缩写: Self-operating statement 缩写成 SelfOpStmt
// 源操作数只可能是下列类型
// - 对象节点 [ast2.Object]
// - 选择器节点 [ast2.Objects]
type SelfOpStmt struct {
Dest Expr
OP enum.OPSymbol
node
nosemicolon bool
}
func newSelfOpStmt(OP enum.OPSymbol, Dest Expr, LineNum int) *SelfOpStmt {
s := &SelfOpStmt{OP: OP, Dest: Dest}
s.LineNum = LineNum
return s
}
func (o *SelfOpStmt) String() string {
var buf strings.Builder
if handleNil(&buf, o) {
return buf.String()
}
buf.WriteString("*ast2.SelfOpStmt{")
buf.WriteString(fmt.Sprintf("%+v}", *o))
return buf.String()
}
func (o *SelfOpStmt) C(buf *strings.Builder) {
buf.Grow(10)
o.Dest.C(buf)
buf.WriteString(opToStrMap[o.OP])
if !o.nosemicolon {
buf.WriteString(";")
}
}
func (o *SelfOpStmt) SetNosemicolon(nosemicolon bool) {
o.nosemicolon = nosemicolon
}
// switch节点
type SwitchNode struct {
codeBlock
Expr Expr
}
func NewSwitchNode(LineNum int) *SwitchNode {
ret := &SwitchNode{}
ret.codeBlock = newCodeBlock(LineNum)
return ret
}
func (s *SwitchNode) String() string {
var buf strings.Builder
if handleNil(&buf, s) {
return buf.String()
}
buf.WriteString("*ast2.SwitchNode{")
buf.WriteString(fmt.Sprintf("%+v}", *s))
return buf.String()
}
func (s *SwitchNode) C(buf *strings.Builder) {
buf.Grow(10)
buf.WriteString("switch (")
s.Expr.C(buf)
buf.WriteString("){")
}
// case节点
type CaseNode struct {
Expr Expr
codeBlock
}
func NewCaseNode(LineNum int) *CaseNode {
ret := &CaseNode{}
ret.codeBlock = newCodeBlock(LineNum)
return ret
}
func (c *CaseNode) String() string {
var buf strings.Builder
if handleNil(&buf, c) {
return buf.String()
}
buf.WriteString("*ast2.CasehNode{")
buf.WriteString(fmt.Sprintf("%+v}", *c))
return buf.String()
}
func (c *CaseNode) C(buf *strings.Builder) {
buf.Grow(10)
buf.WriteString("case ")
c.Expr.C(buf)
buf.WriteString(":")
}
// default节点
type DefaultNode struct {
codeBlock
}
func NewDefaultNode(LineNum int) *DefaultNode {
ret := &DefaultNode{}
ret.codeBlock = newCodeBlock(LineNum)
return ret
}
func (d *DefaultNode) String() string {
var buf strings.Builder
if handleNil(&buf, d) {
return buf.String()
}
buf.WriteString("*ast2.DefaultNode{")
buf.WriteString(fmt.Sprintf("%+v}", *d))
return buf.String()
}
func (c *DefaultNode) C(buf *strings.Builder) {
buf.Grow(10)
buf.WriteString("default :")
}
// MethodNode 方法节点
type MethodNode struct {
*FuncInfo
}
// NewMethodNode 创建函数节点
func NewMethodNode(info *FuncInfo) *MethodNode {
ret := &MethodNode{FuncInfo: info}
return ret
}
func (m *MethodNode) String() string {
var buf strings.Builder
if handleNil(&buf, m) {
return buf.String()
}
buf.WriteString("&ast.MethodNode{\n")
buf.WriteString(fmt.Sprintf("type=%s\t", m.FuncInfo.Parame[0].Type.Typ()))
buf.WriteString(fmt.Sprintf("funcinfo=%s\t", m.FuncInfo.String()))
buf.WriteString(m.Sbt.String())
buf.WriteString("}")
return buf.String()
}
func (m *MethodNode) C(buf *strings.Builder) {
//Note:依赖CDecl在之前被调用
f := FuncNode{FuncInfo: m.FuncInfo}
f.C(buf)
}
func (m *MethodNode) CDecl(buf *strings.Builder) {
m.Name = astdata.Generate_method_symbol(m.FuncInfo.Parame[0].Type.Typ(), m.FuncInfo.Name)
f := FuncNode{FuncInfo: m.FuncInfo}
f.CDecl(buf)
}
// 自动释放块节点
type AutoFreeNode struct {
codeBlock
Expr Expr
FileName string
}
func NewAutoFreeNode(FileName string, LineNum int) *AutoFreeNode {
ret := &AutoFreeNode{FileName: FileName}
ret.codeBlock = newCodeBlock(LineNum)
return ret
}
func (a *AutoFreeNode) String() string {
var buf strings.Builder
if handleNil(&buf, a) {
return buf.String()
}
buf.WriteString("*ast2.AutoFreeNode{")
buf.WriteString(fmt.Sprintf("%+v}", *a))
return buf.String()
}
func (a *AutoFreeNode) C(buf *strings.Builder) {
tmp := VarNode{Name: utils.Generate_mempool_Name(a.LineNum, a.FileName), TYPE: mempool, CType: enum.MemPool, Value: NewCallExpr(mempoolNew, 0, a.Expr), InFunc: true}
tmp.C(buf)
}
var mempool = NewObject(SymbolObj, enum.MemPool)
var mempoolNew = NewObject(SymbolObj, "mempool__New")
// EnumDecl 枚举声明
type EnumDecl struct {
Name string
Enums []string
InFunc bool
node
}
func NewEnumDecl(Name string, LineNum int, InFunc bool) *EnumDecl {
ret := &EnumDecl{Name: Name, InFunc: InFunc}
ret.LineNum = LineNum
return ret
}
func (s *EnumDecl) String() string {
var buf strings.Builder
if handleNil(&buf, s) {
return buf.String()
}
buf.WriteString("*ast2.EnumDecl{")
buf.WriteString(fmt.Sprintf("%+v}", *s))
return buf.String()
}
func (s *EnumDecl) C(buf *strings.Builder) {
if !s.InFunc { //全局结构体的C代码由CDecl生产
return
}
s.c(buf)
}
func (s *EnumDecl) c(buf *strings.Builder) {
elen := len(s.Enums)
buf.Grow(20 + elen*10)
buf.WriteString("typedef enum {")
for i := 0; i < elen; i++ {
buf.WriteString(s.Enums[i])
if i+1 < elen {
buf.WriteString(",")
}
}
buf.WriteString("} ")
buf.WriteString(s.Name)
buf.WriteString(";")
}
func (s *EnumDecl) CDecl(buf *strings.Builder) {
s.c(buf)
}
func (s *EnumDecl) Typ() string {
return s.Name
}
func (s *EnumDecl) Copy() astdata.Typ { panic("未实现") }
func (s *EnumDecl) SetLea(i int) { panic("未实现") }
func (s *EnumDecl) SetTyp() { panic("未实现") }
// Array 数组类型
type Array struct {
Len Expr
TYPE astdata.Typ
//下列字段用于获取类型名
once sync.Once
UStr string
sbt *Sbt
t *Tree
LineNum int
}
func (c *Array) String() string {
var buf strings.Builder
if handleNil(&buf, c) {
return buf.String()
}
buf.WriteString("*ast2.Array{")
buf.WriteString(fmt.Sprintf("%+v}", *c))
return buf.String()
}
func (c *Array) SetTyp() {}
func (c *Array) Copy() astdata.Typ {
ret := *c
return &ret
}
func (c *Array) SetLea(i int) {
c.TYPE.SetLea(i)
}
func (a *Array) Typ() string {
a.once.Do(func() {
lenstr, ok := sum(a.Len, a.sbt)
if !ok {
a.t.errctx.Panic(a.t.Filename, a.LineNum, nil, errcode.ArrayLenNotCompileTimeConstExpr)
}
var buf strings.Builder
buf.WriteString("[")
buf.WriteString(lenstr)
buf.WriteString("]")
buf.WriteString(a.TYPE.Typ())
a.UStr = buf.String()
})
return a.UStr
}
// IndexExpr 索引表达式
// 缩写index expression 缩写成 IndexExpr
type IndexExpr struct {
X Expr
Index Expr
node
}
func NewIndexExpr(X Expr, LineNum int) *IndexExpr {
ret := &IndexExpr{X: X}
ret.LineNum = LineNum
return ret
}
func (l *IndexExpr) String() string {
var buf strings.Builder
if handleNil(&buf, l) {
return buf.String()
}
buf.WriteString("*ast2.IndexExpr{")
buf.WriteString(fmt.Sprintf("%+v}", *l))
return buf.String()
}
func (l *IndexExpr) C(buf *strings.Builder) {
buf.Grow(5)
l.X.C(buf)
buf.WriteString("[")
l.Index.C(buf)
buf.WriteString("]")
}
func (l *IndexExpr) expr() {}
// GenericInstantiation 泛型实例化
type GenericInstantiation struct {
BaseName astdata.Typ
ActualType []astdata.Typ
FileName string
node
}
func (g *GenericInstantiation) String() string {
var buf strings.Builder
if handleNil(&buf, g) {
return buf.String()
}
buf.WriteString("&ast.GenericInstantiation{BaseName:")
buf.WriteString(g.BaseName.Typ())
fmt.Fprintf(&buf, "\tLineNum:%d\tActualType:", g.LineNum)
for _, v := range g.ActualType {
buf.WriteString(v.Typ())
buf.WriteString(" ")
}
buf.WriteString("}")
return buf.String()
}
func (g *GenericInstantiation) SetTyp() {}
func (g *GenericInstantiation) Typ() string {
list, havenil := typToStr(g.ActualType)
if havenil {
return ""
}
return utils.GenerateGenericTypes(g.BaseName.Typ(), list)
}
func (g *GenericInstantiation) C(buf *strings.Builder) {
panic("不应执行的路径")
}
func typToStr(typ []astdata.Typ) ([]string, bool) {
list := make([]string, len(typ))
for i, v := range typ {
if v == nil {
return nil, true
}
list[i] = v.Typ()
}
return list, false
}
func (g *GenericInstantiation) Copy() astdata.Typ {
ret := *g
ret.BaseName = g.BaseName.Copy()
ret.ActualType = copyTyp(ret.ActualType)
return &ret
}
func copyTyp(typ []astdata.Typ) []astdata.Typ {
copys := make([]astdata.Typ, len(typ))
for i, v := range typ {
copys[i] = v.Copy()
}
return copys
}
func copyNameAndTyp(s []astdata.NameAndType) []astdata.NameAndType {
copys := make([]astdata.NameAndType, len(s))
for i, v := range s {
copys[i].Name = v.Name
copys[i].Type = v.Type.Copy()
}
return copys
}
func (g *GenericInstantiation) SetLea(i int) {
g.BaseName.SetLea(i)
}
func (g *GenericInstantiation) FuncName() string {
return g.Typ()
}
func (g *GenericInstantiation) expr() {}
// DerefExpr 解引用节点
type DerefExpr struct {
Value Expr
node
}
func (d *DerefExpr) String() string {
var buf strings.Builder
if handleNil(&buf, d) {
return buf.String()
}
buf.WriteString("*ast2.Dereference")
buf.WriteString(fmt.Sprintf("%+v}", *d))
return buf.String()
}
func (d *DerefExpr) expr() {}
func (d *DerefExpr) C(buf *strings.Builder) {
buf.Grow(5)
buf.WriteString("*(")
d.Value.C(buf)
buf.WriteString(")")
}
func handleNil[T any](buf *strings.Builder, n *T) bool {
if n == nil {
buf.WriteString(fmt.Sprintf("%T{<nil>}", n))
return true
}
return false
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。