merge Field/Extract; prog.Tuple/Zero; TypeAssert refactor
This commit is contained in:
59
ssa/expr.go
59
ssa/expr.go
@@ -93,6 +93,40 @@ func phisExpr(t Type, phis []llvm.Value) Expr {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
func (p Program) Zero(t Type) Expr {
|
||||
var ret llvm.Value
|
||||
switch u := t.raw.Type.Underlying().(type) {
|
||||
case *types.Basic:
|
||||
kind := u.Kind()
|
||||
switch {
|
||||
case kind >= types.Bool && kind <= types.Uintptr:
|
||||
ret = llvm.ConstInt(p.rawType(u).ll, 0, false)
|
||||
case kind == types.String:
|
||||
ret = p.Zero(p.rtType("String")).impl
|
||||
case kind == types.UnsafePointer:
|
||||
ret = llvm.ConstPointerNull(p.tyVoidPtr())
|
||||
case kind <= types.Float64:
|
||||
ret = llvm.ConstFloat(p.Float64().ll, 0)
|
||||
case kind == types.Float32:
|
||||
ret = llvm.ConstFloat(p.Float32().ll, 0)
|
||||
default:
|
||||
panic("todo")
|
||||
}
|
||||
case *types.Pointer:
|
||||
return Expr{llvm.ConstNull(t.ll), t}
|
||||
case *types.Struct:
|
||||
n := u.NumFields()
|
||||
flds := make([]llvm.Value, n)
|
||||
for i := 0; i < n; i++ {
|
||||
flds[i] = p.Zero(p.rawType(u.Field(i).Type())).impl
|
||||
}
|
||||
ret = llvm.ConstStruct(flds, false)
|
||||
default:
|
||||
log.Panicln("todo:", u)
|
||||
}
|
||||
return Expr{ret, t}
|
||||
}
|
||||
|
||||
// Null returns a null constant expression.
|
||||
func (p Program) Null(t Type) Expr {
|
||||
return Expr{llvm.ConstNull(t.ll), t}
|
||||
@@ -125,12 +159,6 @@ func (p Program) FloatVal(v float64, t Type) Expr {
|
||||
return Expr{ret, t}
|
||||
}
|
||||
|
||||
func (p Program) ByteVal(v byte) Expr {
|
||||
t := p.Byte()
|
||||
ret := llvm.ConstInt(t.ll, uint64(v), false)
|
||||
return Expr{ret, t}
|
||||
}
|
||||
|
||||
// Val returns a constant expression.
|
||||
func (p Program) Val(v interface{}) Expr {
|
||||
switch v := v.(type) {
|
||||
@@ -941,21 +969,6 @@ func (b Builder) Call(fn Expr, args ...Expr) (ret Expr) {
|
||||
return
|
||||
}
|
||||
|
||||
// The Extract instruction yields component Index of Tuple.
|
||||
//
|
||||
// This is used to access the results of instructions with multiple
|
||||
// return values, such as Call, TypeAssert, Next, UnOp(ARROW) and
|
||||
// IndexExpr(Map).
|
||||
//
|
||||
// Example printed form:
|
||||
//
|
||||
// t1 = extract t0 #1
|
||||
func (b Builder) Extract(x Expr, index int) (ret Expr) {
|
||||
ret.Type = b.Prog.toType(x.Type.raw.Type.(*types.Tuple).At(index).Type())
|
||||
ret.impl = llvm.CreateExtractValue(b.impl, x.impl, index)
|
||||
return
|
||||
}
|
||||
|
||||
// A Builtin represents a specific use of a built-in function, e.g. len.
|
||||
//
|
||||
// Builtins are immutable values. Builtins do not have addresses.
|
||||
@@ -1009,7 +1022,7 @@ func (b Builder) BuiltinCall(fn string, args ...Expr) (ret Expr) {
|
||||
ret.Type = prog.Void()
|
||||
for i, arg := range args {
|
||||
if ln && i > 0 {
|
||||
b.InlineCall(b.Pkg.rtFunc("PrintByte"), prog.ByteVal(' '))
|
||||
b.InlineCall(b.Pkg.rtFunc("PrintByte"), prog.IntVal(' ', prog.Byte()))
|
||||
}
|
||||
var fn string
|
||||
typ := arg.Type
|
||||
@@ -1049,7 +1062,7 @@ func (b Builder) BuiltinCall(fn string, args ...Expr) (ret Expr) {
|
||||
b.InlineCall(b.Pkg.rtFunc(fn), arg)
|
||||
}
|
||||
if ln {
|
||||
b.InlineCall(b.Pkg.rtFunc("PrintByte"), prog.ByteVal('\n'))
|
||||
b.InlineCall(b.Pkg.rtFunc("PrintByte"), prog.IntVal('\n', prog.Byte()))
|
||||
}
|
||||
return
|
||||
case "copy":
|
||||
|
||||
Reference in New Issue
Block a user