Attempt to further fix interface assignment
This commit is contained in:
parent
f72bf533e0
commit
c4df65d189
|
@ -27,8 +27,6 @@ func (this *generator) generateAssignmentSource (
|
|||
llvm.Value,
|
||||
error,
|
||||
) {
|
||||
source, err := this.generateExpression(from)
|
||||
if err != nil { return nil, err }
|
||||
toBase := analyzer.ReduceToBase(to)
|
||||
|
||||
switch toBase := toBase.(type) {
|
||||
|
@ -48,6 +46,8 @@ func (this *generator) generateAssignmentSource (
|
|||
// conversion from interface to interface
|
||||
case *entity.TypeInterface:
|
||||
// re-assign data
|
||||
source, err := this.generateExpressionLoc(from)
|
||||
if err != nil { return nil, err }
|
||||
irFromType, err := this.generateType(fromType)
|
||||
if err != nil { return nil, err }
|
||||
fromDataField := this.getInterfaceData(source, irFromType)
|
||||
|
@ -69,6 +69,8 @@ func (this *generator) generateAssignmentSource (
|
|||
// conversion from pointer to interface
|
||||
case *entity.TypePointer:
|
||||
// assign data
|
||||
source, err := this.generateExpression(from)
|
||||
if err != nil { return nil, err }
|
||||
fromData := this.blockManager.NewLoad(new(llvm.TypePointer), source)
|
||||
this.blockManager.NewStore(fromData, toDataField)
|
||||
|
||||
|
@ -91,6 +93,8 @@ func (this *generator) generateAssignmentSource (
|
|||
// conversion from other type to interface
|
||||
default:
|
||||
// assign data
|
||||
source, err := this.generateExpressionLoc(from)
|
||||
if err != nil { return nil, err }
|
||||
this.blockManager.NewStore(source, toDataField)
|
||||
|
||||
fromType, ok := fromType.(*entity.TypeNamed)
|
||||
|
@ -109,13 +113,19 @@ func (this *generator) generateAssignmentSource (
|
|||
this.blockManager.NewStore(fromBehavior, toBehaviorField)
|
||||
}
|
||||
}
|
||||
return this.blockManager.NewLoad(irToType, destination), nil
|
||||
|
||||
// conversion from array to slice
|
||||
case *entity.TypeSlice:
|
||||
switch fromBase := analyzer.ReduceToBase(from.Type()).(type) {
|
||||
case *entity.TypeArray:
|
||||
source, err := this.generateExpression(from)
|
||||
if err != nil { return nil, err }
|
||||
return this.generateSlice(to, source, int64(fromBase.Length))
|
||||
}
|
||||
}
|
||||
|
||||
source, err := this.generateExpression(from)
|
||||
if err != nil { return nil, err }
|
||||
return source, nil
|
||||
}
|
||||
|
|
|
@ -58,10 +58,12 @@ func (this *generator) generateMethodCall (call *entity.MethodCall) (llvm.Value,
|
|||
method, err := this.method(sourceType.Name, call.Name)
|
||||
if err != nil { return nil, err }
|
||||
|
||||
source, err := this.generateExpressionLoc(call.Source)
|
||||
if err != nil { return nil, err }
|
||||
args[0] = source
|
||||
return this.blockManager.NewCall(method, method.Signature, args...), nil
|
||||
if method != nil {
|
||||
source, err := this.generateExpressionLoc(call.Source)
|
||||
if err != nil { return nil, err }
|
||||
args[0] = source
|
||||
return this.blockManager.NewCall(method, method.Signature, args...), nil
|
||||
}
|
||||
}
|
||||
|
||||
// check for methods on pointer to named type
|
||||
|
@ -70,18 +72,20 @@ func (this *generator) generateMethodCall (call *entity.MethodCall) (llvm.Value,
|
|||
method, err := this.method(sourceType.Name, call.Name)
|
||||
if err != nil { return nil, err }
|
||||
|
||||
source, err := this.generateExpression(call.Source)
|
||||
if err != nil { return nil, err }
|
||||
args[0] = source
|
||||
return this.blockManager.NewCall(method, method.Signature, args...), nil
|
||||
if method != nil {
|
||||
source, err := this.generateExpression(call.Source)
|
||||
if err != nil { return nil, err }
|
||||
args[0] = source
|
||||
return this.blockManager.NewCall(method, method.Signature, args...), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check for interface behaviors
|
||||
if sourceType := getInterface(call.Source.Type()); sourceType != nil {
|
||||
irSourceType, err := this.generateType(sourceType)
|
||||
irSourceType, err := this.generateType(call.Source.Type())
|
||||
if err != nil { return nil, err }
|
||||
source, err := this.generateExpression(call.Source)
|
||||
source, err := this.generateExpressionLoc(call.Source)
|
||||
if err != nil { return nil, err }
|
||||
irBehavior := this.getInterfaceBehavior(sourceType, source, irSourceType, call.Name)
|
||||
|
||||
|
|
|
@ -85,10 +85,7 @@ func (this *generator) method (typeName string, name string) (*llvm.Function, er
|
|||
errors.New(fmt.Sprintln("type", typeName, "not found"))
|
||||
}
|
||||
method, exists := ty.Methods[name]
|
||||
if !exists {
|
||||
return nil, errors.New(fmt.Sprintln (
|
||||
"method", typeName + "." + name, "not found"))
|
||||
}
|
||||
if !exists { return nil, nil }
|
||||
return this.generateMethod(method)
|
||||
}
|
||||
|
||||
|
@ -99,10 +96,7 @@ func (this *generator) function (name string) (*llvm.Function, error) {
|
|||
}
|
||||
}
|
||||
function, exists := this.tree.Functions[name]
|
||||
if !exists {
|
||||
return nil, errors.New(fmt.Sprintln (
|
||||
"function", name, "not found"))
|
||||
}
|
||||
if !exists { return nil, nil }
|
||||
return this.generateFunction(function)
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,31 @@ import "testing"
|
|||
|
||||
func TestInterfaceBasic (test *testing.T) {
|
||||
testString (test,
|
||||
`
|
||||
`%Number = type i64
|
||||
%Numbered = type { ptr, ptr }
|
||||
define i64 @main() {
|
||||
0:
|
||||
%1 = alloca %Number
|
||||
store i64 5, ptr %1
|
||||
%2 = alloca %Numbered
|
||||
%3 = getelementptr %Numbered, ptr %2, i32 0, i32 0
|
||||
store ptr %1, ptr %3
|
||||
%4 = getelementptr %Numbered, ptr %2, i32 0, i32 1
|
||||
store ptr @Number.number, ptr %4
|
||||
%6 = getelementptr { ptr, ptr }, ptr %2, i32 0, i32 1
|
||||
%7 = getelementptr { ptr, ptr }, ptr %2, i32 0, i32 0
|
||||
%8 = load ptr, ptr %7
|
||||
%9 = call i64 %7(ptr %6)
|
||||
ret i64 %9
|
||||
}
|
||||
define i64 @Number.number(ptr %this) {
|
||||
0:
|
||||
%1 = alloca ptr
|
||||
store ptr %this, ptr %1
|
||||
%2 = load ptr, ptr %1
|
||||
%3 = load i64, ptr %2
|
||||
ret i64 %3
|
||||
}
|
||||
`,
|
||||
`
|
||||
Numbered: ([number]: Int)
|
||||
|
|
Loading…
Reference in New Issue