Ver código fonte

Improved handling of Self.

woollybah 8 anos atrás
pai
commit
f3e6c3dea9
3 arquivos alterados com 55 adições e 11 exclusões
  1. 4 0
      decl.bmx
  2. 18 5
      expr.bmx
  3. 33 6
      type.bmx

+ 4 - 0
decl.bmx

@@ -1633,6 +1633,10 @@ Type TFuncDecl Extends TBlockDecl
 		Return (attrs & FUNC_METHOD)<>0
 		Return (attrs & FUNC_METHOD)<>0
 	End Method
 	End Method
 	
 	
+	Method IsAnyMethod:Int()
+		Return IsMethod() Or IsCtor() Or IsDtor() 
+	End Method
+	
 	Method IsStatic:Int()
 	Method IsStatic:Int()
 		Return (attrs & (FUNC_METHOD|FUNC_CTOR))=0
 		Return (attrs & (FUNC_METHOD|FUNC_CTOR))=0
 	End Method
 	End Method

+ 18 - 5
expr.bmx

@@ -806,16 +806,21 @@ Type TNewObjectExpr Extends TExpr
 		args=SemantArgs( args )
 		args=SemantArgs( args )
 
 
 		Local objTy:TObjectType=TObjectType( ty )
 		Local objTy:TObjectType=TObjectType( ty )
-		If Not objTy
+		Local clsTy:TClassType=TClassType( ty )
+		If Not objTy And Not clsTy
 			Err "Expression is not a class."
 			Err "Expression is not a class."
 		EndIf
 		EndIf
 		
 		
 		' 
 		' 
-		If objTy.instance Then
+		If clsTy And clsTy.instance Then
 			instanceExpr = New TSelfExpr.Semant()
 			instanceExpr = New TSelfExpr.Semant()
 		End If
 		End If
 
 
-		classDecl=objTy.classDecl
+		If objTy Then
+			classDecl=objTy.classDecl
+		Else
+			classDecl=clsTy.classDecl
+		End If
 
 
 		If Not instanceExpr Then
 		If Not instanceExpr Then
 			If classDecl.IsInterface() Err "Cannot create instance of an interface."
 			If classDecl.IsInterface() Err "Cannot create instance of an interface."
@@ -862,7 +867,7 @@ Type TNewObjectExpr Extends TExpr
 
 
 			Local expr:TExpr = Self
 			Local expr:TExpr = Self
 			Local cdecl:TClassDecl = classDecl
 			Local cdecl:TClassDecl = classDecl
-			Local eType:TType = objTy
+			Local eType:TType = ty
 			
 			
 			Local errorDetails:String
 			Local errorDetails:String
 
 
@@ -1066,7 +1071,15 @@ Type TSelfExpr Extends TExpr
 		If Not scope Then
 		If Not scope Then
 			Err "'Self' can only be used within methods."
 			Err "'Self' can only be used within methods."
 		End If
 		End If
-		exprType=New TObjectType.Create( scope )
+		
+		Local funcScope:TFuncDecl = _env.FuncScope()
+		If funcScope.IsAnyMethod() Then
+			exprType=New TObjectType.Create( scope )
+			TObjectType(exprType).instance = True
+		Else
+			exprType=New TClassType.Create( scope )
+		End If
+
 		Return Self
 		Return Self
 	End Method
 	End Method
 
 

+ 33 - 6
type.bmx

@@ -1466,6 +1466,33 @@ Type TObjectType Extends TType
 
 
 End Type
 End Type
 
 
+Type TClassType Extends TType
+
+	Field classDecl:TClassDecl
+	Field instance:Int
+	
+	Method Create:TClassType( classDecl:TClassDecl )
+		Self.classDecl=classDecl
+		Return Self
+	End Method
+
+	Method GetClass:TClassDecl()
+		Return classDecl
+	End Method
+
+	Method OnCopy:TType()
+		Local ty:TClassType = New TClassType
+		ty.classDecl = classDecl
+		ty.instance = instance
+		Return ty
+	End Method
+
+	Method ToString:String()
+		Return "Type"
+	End Method
+	
+End Type
+
 Type TIdentType Extends TType
 Type TIdentType Extends TType
 	Field ident$
 	Field ident$
 	Field args:TType[]
 	Field args:TType[]
@@ -1531,12 +1558,12 @@ Type TIdentType Extends TType
 				Local scope:TClassDecl = _env.ClassScope()
 				Local scope:TClassDecl = _env.ClassScope()
 				If scope Then
 				If scope Then
 					tyid = scope.ident
 					tyid = scope.ident
-					ty = New TObjectType.Create(scope)
+					ty = New TClassType.Create(scope)
 					
 					
 					' test for method scope - self is already an instance
 					' test for method scope - self is already an instance
 					Local funcScope:TFuncDecl = _env.FuncScope()
 					Local funcScope:TFuncDecl = _env.FuncScope()
-					If funcScope.IsMethod() Then
-						TObjectType(ty).instance = True
+					If funcScope.IsAnyMethod() Then
+						TClassType(ty).instance = True
 					End If
 					End If
 				Else
 				Else
 					Err "'Self' can only be used within methods."
 					Err "'Self' can only be used within methods."
@@ -1566,12 +1593,12 @@ Type TIdentType Extends TType
 				Local scope:TClassDecl = _env.ClassScope()
 				Local scope:TClassDecl = _env.ClassScope()
 				If scope Then
 				If scope Then
 					tyid = scope.ident
 					tyid = scope.ident
-					ty = New TObjectType.Create(scope)
+					ty = New TClassType.Create(scope)
 					
 					
 					' test for method scope - self is already an instance
 					' test for method scope - self is already an instance
 					Local funcScope:TFuncDecl = _env.FuncScope()
 					Local funcScope:TFuncDecl = _env.FuncScope()
-					If funcScope.IsMethod() Then
-						TObjectType(ty).instance = True
+					If funcScope.IsAnyMethod() Then
+						TClassType(ty).instance = True
 					End If
 					End If
 				Else
 				Else
 					Err "'Self' can only be used within methods."
 					Err "'Self' can only be used within methods."