1 Star 1 Fork 1

U语言组织 / U语言

forked from 秋来冬风 / U语言 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
ir2.go 8.22 KB
一键复制 编辑 原始数据 按行查看 历史
package cast
import (
"fmt"
"strings"
"gitee.com/u-language/u-language/ucom/ast"
"gitee.com/u-language/u-language/ucom/data"
"gitee.com/u-language/u-language/ucom/enum"
"gitee.com/u-language/u-language/ucom/internal/errutil"
"gitee.com/u-language/u-language/ucom/internal/utils"
"gitee.com/u-language/u-language/ucom/ir2"
)
type Ir2ToC struct {
headerFile data.Slice[ast.CHeaderFile]
Nodes []ast.Node
packageName string
isInitFunc bool
varInit []ast.Node
}
func NewIr2ToC(packageName string, isInitFunc bool) *Ir2ToC {
return &Ir2ToC{packageName: packageName, isInitFunc: isInitFunc}
}
func (c *Ir2ToC) C() string {
defer Deferfunc()
var buf strings.Builder
buf.Grow(len(c.Nodes) * 50)
buf.WriteString(includeStr)
// if c.InAutoFree {
// buf.WriteString("#include \"mempool.h\"\n")
// }
generateHeaderFile(c.headerFile.Data, nil, &buf)
tion := generateInit2(c.packageName, c.isInitFunc, c.varInit, &buf, nil, false)
generateCFileNoLF(c.Nodes, &buf)
buf.WriteString("\n")
buf.WriteString(tion)
return buf.String()
}
// generateInit2 生成隐式调用init函数 返回init函数定义
// - PackageName 是包名
// - isInitFunc是否有自定义init函数
// - node 是变量初始化节点
// - fbuf 写入声明
// - importLocal 是自己导入的包
// - isImported 是否被导入
func generateInit2(PackageName string, isInitFunc bool, node []ast.Node, fbuf *strings.Builder, importLocal []*Package, isImported bool) string {
var buf strings.Builder
vil := len(node)
var decl string = utils.GeneratePackageSymbol(PackageName, "init")
//生成隐式init函数声明
fbuf.WriteString("// --- 隐式init函数声明 ---\n")
fbuf.WriteString("void ")
fbuf.WriteString(decl)
fbuf.WriteString("();\n")
//生成隐式init函数定义
f := ast.FuncNode{}
f.FuncInfo = &ast.FuncInfo{}
f.Name = decl
f.C(&buf)
fbuf.WriteString("\n")
if !isImported { //如果不是被导入的包
generateImportInitCallAll(importLocal, &buf)
}
buf.WriteString("\n")
for i := 0; i < vil; i++ {
node[i].C(&buf)
}
if isInitFunc { //如果有自定义的init函数
buf.WriteString("// --- 调用自定义init函数 ---\n")
decl = utils.GeneratePackageSymbol(PackageName, "init__user")
//调用自定义init函数
ast.NewCallExpr(ast.NewObject(ast.SymbolObj, decl), false).C(&buf)
buf.WriteString(";\n")
}
buf.WriteString("\n}\n")
return buf.String()
}
func PaeserIr2(toc *Ir2ToC, f *ir2.File) {
//处理全局声明
for _, v := range f.GlobalDecl {
toc.headerFile.Add(ast.CHeaderFile{N: v.(ast.CDecl), Line: retNodeLine(v)})
}
//处理变量初始化
for _, v := range f.VarInit {
toc.varInit = append(toc.varInit, OneIr2ToC(v))
}
//处理指令
toc.Nodes = make([]ast.Node, len(f.Ir))
for i, v := range f.Ir {
toc.Nodes[i] = OneIr2ToC(v)
}
}
func retNodeLine(n ast.Node) int {
switch node := n.(type) {
case *ast.VarNode:
return node.LineNum
case *ast.FuncNode:
return node.LineNum
case *ast.MethodNode:
return node.LineNum
case *ast.StructDecl:
return node.LineNum
default:
panic(errutil.NewErr2(errutil.CompileErr, fmt.Sprintf("未知的节点:%+v", n)))
}
}
type OneIr2ToC ir2.IrNode
func (ir OneIr2ToC) C(buf *strings.Builder) {
ir2ToC(ir2.IrNode(ir), buf)
}
func (ir OneIr2ToC) String() string {
var buf strings.Builder
ir2ToC(ir2.IrNode(ir), &buf)
return buf.String()
}
func ir2ToC(ir ir2.IrNode, buf *strings.Builder) {
switch ir.Op {
case ir2.ADDOP, ir2.SUBOP, ir2.MULOP, ir2.DIVOP, ir2.LessOp, ir2.GreaterOp, ir2.EqualOp, ir2.NoEqualOp, ir2.RemainOp:
if ir.ResultObj == enum.StrFalse { //如果指令不包含操作的值
buf.WriteString(ir2opToStr[ir.Op])
return
}
buf.WriteString(ir.Arg1Obj)
buf.WriteString(ir2opToStr[ir.Op])
buf.WriteString(ir.Arg2Obj)
if ir.ResultTyp != enum.StrFalse { //如果不是不换行
buf.WriteString(";\n")
}
case ir2.MOVOP:
buf.WriteString(ir.ResultObj)
buf.WriteString(" = ")
if ir.Arg2Obj != enum.StrFalse { //如果不是不包含源操作数
buf.WriteString(ir.Arg1Obj)
buf.WriteString(";\n")
}
case ir2.RbraceOP:
buf.WriteString("}\n")
case ir2.FuncOP:
n := **ir.Func()
if f, ok := n.(*ast.FuncNode); ok {
cf := f
cf.C(buf)
} else {
f := n.(*ast.MethodNode)
f.C(buf)
}
buf.WriteString("\n")
case ir2.VarOP:
n := *ir.Var()
n.Value = nil
n.C(buf)
buf.WriteString("\n")
case ir2.TmpVarOP:
buf.WriteString(typeToC(ir.Arg2Obj)) //这是类型
buf.WriteString(" ")
buf.WriteString(ir.Arg1Obj) //这是临时变量名
buf.WriteString(";\n")
case ir2.TypeConvertOp:
buf.WriteString("(")
buf.WriteString(typeToC(ir.Arg1Obj))
buf.WriteString(")")
buf.WriteString(ir.Arg2Obj)
case ir2.CallOP:
buf.WriteString(ir.Arg1Obj)
buf.WriteString("(")
noparame := ir.ResultObj == enum.StrFalse
if noparame { //如果没有参数
buf.WriteString(")")
}
if noparame && ir.ResultTyp != enum.StrFalse { //如果没有参数,同时不是不换行
buf.WriteString(";\n")
}
case ir2.EndCallOp:
buf.WriteString(")")
if ir.ResultTyp != enum.StrFalse { //如果不是不换行
buf.WriteString(";\n")
}
case ir2.PaPaOp:
buf.WriteString(ir.Arg2Obj)
if ir.ResultObj != enum.StrFalse { //如果不是最后一个传参
buf.WriteString(",")
}
case ir2.RetOp:
buf.WriteString("return ")
if ir.Arg2Obj == enum.StrFalse { //如果返回值不在后面,也就是直接有返回值
buf.WriteString(ir.Arg1Obj)
buf.WriteString(";\n")
}
case ir2.ForOp:
buf.WriteString("for (")
case ir2.SemicolonOp:
buf.WriteString(" ; ")
case ir2.CommaOp:
buf.WriteString(" , ")
case ir2.ObjOP:
buf.WriteString(ir.ResultObj)
case ir2.LbraceOp:
buf.WriteString(" { ")
case ir2.LineFeedOp:
buf.WriteString("\n")
case ir2.LocalVarOp:
buf.WriteString(typeToC((**ir.Type()).Typ()))
buf.WriteString(" ")
buf.WriteString(ir.Arg1Obj)
buf.WriteString(" =")
case ir2.RPARENOp:
buf.WriteString(" ) ")
case ir2.ElseOp:
buf.WriteString("else {\n")
case ir2.ElseIfOp:
buf.WriteString("else if (")
boolexprToC(ir, buf)
case ir2.IfOp:
buf.WriteString("if (")
boolexprToC(ir, buf)
case ir2.Field:
buf.WriteString(typeToC((**ir.Arg1ObjTyp()).Typ()))
buf.WriteString(" ")
buf.WriteString(ir.Arg1Obj)
buf.WriteString(";\n")
case ir2.Field3:
buf.WriteString(typeToC((**ir.Arg1ObjTyp()).Typ()))
buf.WriteString(" ")
buf.WriteString(ir.Arg1Obj)
buf.WriteString(";\n")
buf.WriteString(typeToC((**ir.Arg2ObjTyp()).Typ()))
buf.WriteString(" ")
buf.WriteString(ir.Arg2Obj)
buf.WriteString(";\n")
buf.WriteString(typeToC((**ir.ResultObjTyp()).Typ()))
buf.WriteString(" ")
buf.WriteString(ir.ResultObj)
buf.WriteString(";\n")
case ir2.StructDeclStart:
buf.WriteString("typedef struct {\n")
case ir2.Struct1Field:
buf.WriteString("typedef struct {\n")
buf.WriteString(typeToC((**ir.Arg1ObjTyp()).Typ()))
buf.WriteString(" ")
buf.WriteString(ir.Arg1Obj)
buf.WriteString(";")
case ir2.Struct2Field:
buf.WriteString("typedef struct {\n")
buf.WriteString(typeToC((**ir.Arg1ObjTyp()).Typ()))
buf.WriteString(" ")
buf.WriteString(ir.Arg1Obj)
buf.WriteString(";\n")
buf.WriteString(typeToC((**ir.Arg2ObjTyp()).Typ()))
buf.WriteString(" ")
buf.WriteString(ir.Arg2Obj)
buf.WriteString(";")
case ir2.StructDeclEnd:
buf.WriteString("\n}")
buf.WriteString(ir.ResultObj)
buf.WriteString(";\n")
case ir2.SelectRight:
buf.WriteString(".")
buf.WriteString(ir.Arg1Obj)
case ir2.LeftSelectRight:
buf.WriteString(ir.Arg1Obj)
buf.WriteString(".")
buf.WriteString(ir.Arg2Obj)
case ir2.AssignOp:
buf.WriteString("=")
case ir2.Malloc:
buf.WriteString("malloc(sizeof(")
n := ir.Arg1ObjExpr()
(**n).(ast.CType).CType(buf)
buf.WriteString("))")
if ir.ResultTyp != enum.StrFalse { //如果不是不换行
buf.WriteString("\n")
}
default:
panic(errutil.NewErr2(errutil.CompileErr, fmt.Sprintf("未知的ir:%+v", ir)))
}
}
func boolexprToC(ir ir2.IrNode, buf *strings.Builder) {
if ir.Arg2Obj == enum.StrFalse { //如果布尔表达式在ir里
buf.WriteString(ir.Arg1Obj)
buf.WriteString(")}")
return
}
}
var ir2opToStr = map[ir2.OPEnum]string{
ir2.ADDOP: " + ",
ir2.SUBOP: " - ",
ir2.MULOP: " * ",
ir2.DIVOP: " / ",
ir2.LessOp: " < ",
ir2.GreaterOp: " > ",
ir2.EqualOp: " == ",
ir2.NoEqualOp: " != ",
ir2.RemainOp: " % ",
}
Go
1
https://gitee.com/u-language/u-language.git
git@gitee.com:u-language/u-language.git
u-language
u-language
U语言
a214d6007862

搜索帮助

53164aa7 5694891 3bd8fe86 5694891