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,
|
llvm.Value,
|
||||||
error,
|
error,
|
||||||
) {
|
) {
|
||||||
source, err := this.generateExpression(from)
|
|
||||||
if err != nil { return nil, err }
|
|
||||||
toBase := analyzer.ReduceToBase(to)
|
toBase := analyzer.ReduceToBase(to)
|
||||||
|
|
||||||
switch toBase := toBase.(type) {
|
switch toBase := toBase.(type) {
|
||||||
@ -48,6 +46,8 @@ func (this *generator) generateAssignmentSource (
|
|||||||
// conversion from interface to interface
|
// conversion from interface to interface
|
||||||
case *entity.TypeInterface:
|
case *entity.TypeInterface:
|
||||||
// re-assign data
|
// re-assign data
|
||||||
|
source, err := this.generateExpressionLoc(from)
|
||||||
|
if err != nil { return nil, err }
|
||||||
irFromType, err := this.generateType(fromType)
|
irFromType, err := this.generateType(fromType)
|
||||||
if err != nil { return nil, err }
|
if err != nil { return nil, err }
|
||||||
fromDataField := this.getInterfaceData(source, irFromType)
|
fromDataField := this.getInterfaceData(source, irFromType)
|
||||||
@ -69,6 +69,8 @@ func (this *generator) generateAssignmentSource (
|
|||||||
// conversion from pointer to interface
|
// conversion from pointer to interface
|
||||||
case *entity.TypePointer:
|
case *entity.TypePointer:
|
||||||
// assign data
|
// assign data
|
||||||
|
source, err := this.generateExpression(from)
|
||||||
|
if err != nil { return nil, err }
|
||||||
fromData := this.blockManager.NewLoad(new(llvm.TypePointer), source)
|
fromData := this.blockManager.NewLoad(new(llvm.TypePointer), source)
|
||||||
this.blockManager.NewStore(fromData, toDataField)
|
this.blockManager.NewStore(fromData, toDataField)
|
||||||
|
|
||||||
@ -91,6 +93,8 @@ func (this *generator) generateAssignmentSource (
|
|||||||
// conversion from other type to interface
|
// conversion from other type to interface
|
||||||
default:
|
default:
|
||||||
// assign data
|
// assign data
|
||||||
|
source, err := this.generateExpressionLoc(from)
|
||||||
|
if err != nil { return nil, err }
|
||||||
this.blockManager.NewStore(source, toDataField)
|
this.blockManager.NewStore(source, toDataField)
|
||||||
|
|
||||||
fromType, ok := fromType.(*entity.TypeNamed)
|
fromType, ok := fromType.(*entity.TypeNamed)
|
||||||
@ -109,13 +113,19 @@ func (this *generator) generateAssignmentSource (
|
|||||||
this.blockManager.NewStore(fromBehavior, toBehaviorField)
|
this.blockManager.NewStore(fromBehavior, toBehaviorField)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return this.blockManager.NewLoad(irToType, destination), nil
|
||||||
|
|
||||||
// conversion from array to slice
|
// conversion from array to slice
|
||||||
case *entity.TypeSlice:
|
case *entity.TypeSlice:
|
||||||
switch fromBase := analyzer.ReduceToBase(from.Type()).(type) {
|
switch fromBase := analyzer.ReduceToBase(from.Type()).(type) {
|
||||||
case *entity.TypeArray:
|
case *entity.TypeArray:
|
||||||
|
source, err := this.generateExpression(from)
|
||||||
|
if err != nil { return nil, err }
|
||||||
return this.generateSlice(to, source, int64(fromBase.Length))
|
return this.generateSlice(to, source, int64(fromBase.Length))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
source, err := this.generateExpression(from)
|
||||||
|
if err != nil { return nil, err }
|
||||||
return source, nil
|
return source, nil
|
||||||
}
|
}
|
||||||
|
@ -58,10 +58,12 @@ func (this *generator) generateMethodCall (call *entity.MethodCall) (llvm.Value,
|
|||||||
method, err := this.method(sourceType.Name, call.Name)
|
method, err := this.method(sourceType.Name, call.Name)
|
||||||
if err != nil { return nil, err }
|
if err != nil { return nil, err }
|
||||||
|
|
||||||
source, err := this.generateExpressionLoc(call.Source)
|
if method != nil {
|
||||||
if err != nil { return nil, err }
|
source, err := this.generateExpressionLoc(call.Source)
|
||||||
args[0] = source
|
if err != nil { return nil, err }
|
||||||
return this.blockManager.NewCall(method, method.Signature, args...), nil
|
args[0] = source
|
||||||
|
return this.blockManager.NewCall(method, method.Signature, args...), nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for methods on pointer to named type
|
// 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)
|
method, err := this.method(sourceType.Name, call.Name)
|
||||||
if err != nil { return nil, err }
|
if err != nil { return nil, err }
|
||||||
|
|
||||||
source, err := this.generateExpression(call.Source)
|
if method != nil {
|
||||||
if err != nil { return nil, err }
|
source, err := this.generateExpression(call.Source)
|
||||||
args[0] = source
|
if err != nil { return nil, err }
|
||||||
return this.blockManager.NewCall(method, method.Signature, args...), nil
|
args[0] = source
|
||||||
|
return this.blockManager.NewCall(method, method.Signature, args...), nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for interface behaviors
|
// check for interface behaviors
|
||||||
if sourceType := getInterface(call.Source.Type()); sourceType != nil {
|
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 }
|
if err != nil { return nil, err }
|
||||||
source, err := this.generateExpression(call.Source)
|
source, err := this.generateExpressionLoc(call.Source)
|
||||||
if err != nil { return nil, err }
|
if err != nil { return nil, err }
|
||||||
irBehavior := this.getInterfaceBehavior(sourceType, source, irSourceType, call.Name)
|
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"))
|
errors.New(fmt.Sprintln("type", typeName, "not found"))
|
||||||
}
|
}
|
||||||
method, exists := ty.Methods[name]
|
method, exists := ty.Methods[name]
|
||||||
if !exists {
|
if !exists { return nil, nil }
|
||||||
return nil, errors.New(fmt.Sprintln (
|
|
||||||
"method", typeName + "." + name, "not found"))
|
|
||||||
}
|
|
||||||
return this.generateMethod(method)
|
return this.generateMethod(method)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,10 +96,7 @@ func (this *generator) function (name string) (*llvm.Function, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
function, exists := this.tree.Functions[name]
|
function, exists := this.tree.Functions[name]
|
||||||
if !exists {
|
if !exists { return nil, nil }
|
||||||
return nil, errors.New(fmt.Sprintln (
|
|
||||||
"function", name, "not found"))
|
|
||||||
}
|
|
||||||
return this.generateFunction(function)
|
return this.generateFunction(function)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,31 @@ import "testing"
|
|||||||
|
|
||||||
func TestInterfaceBasic (test *testing.T) {
|
func TestInterfaceBasic (test *testing.T) {
|
||||||
testString (test,
|
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)
|
Numbered: ([number]: Int)
|
||||||
|
Loading…
Reference in New Issue
Block a user