浏览代码

Properly handle different for loop types. Fixes #62.

woollybah 10 年之前
父节点
当前提交
e884d17c28
共有 3 个文件被更改,包括 48 次插入13 次删除
  1. 28 7
      expr.bmx
  2. 6 5
      parser.bmx
  3. 14 1
      stmt.bmx

+ 28 - 7
expr.bmx

@@ -146,7 +146,7 @@ Type TExpr
 		'End If
 
 		If TStringType( lhs ) Or TStringType( rhs ) Return New TStringType
-		If TDoubleType( lhs ) Or TDoubleType( rhs ) Return New TFloatType
+		If TDoubleType( lhs ) Or TDoubleType( rhs ) Return New TDoubleType
 		If TFloatType( lhs ) Or TFloatType( rhs ) Return New TFloatType
 		If IsPointerType( lhs, 0, TType.T_POINTER ) Or IsPointerType( rhs, 0, TType.T_POINTER ) Then
 			If IsPointerType( lhs, 0, TType.T_POINTER ) Return lhs
@@ -282,7 +282,7 @@ Type TConstExpr Extends TExpr
 	Field value$
 
 	Method Create:TConstExpr( ty:TType,value$ )
-		If TIntType( ty )
+		If TIntType( ty ) Or TShortType( ty ) Or TByteType( ty ) Or TLongType( ty )
 			Local radix:Int
 			If value.StartsWith( "%" )
 				radix=1
@@ -301,16 +301,28 @@ Type TConstExpr Extends TExpr
 						val=val Shl radix | ((ch & 15)+9)
 					EndIf
 				Next
-				If val >= 2147483648:Long Then
+				If TIntType(ty) And val >= 2147483648:Long Then
 					value = String( -2147483648:Long + (val - 2147483648:Long))
 				Else
-					value=String( val )
+					If TShortType( ty ) Then
+						value=String( Short(val) )
+					Else If TByteType( ty ) Then
+						value=String( Byte(val) )
+					Else
+						value=String( val )
+					End If
 				End If
 			Else
-				value = String.FromLong(value.ToLong())
+				If TShortType( ty ) Then
+					value = String.FromLong(Short(value.ToLong()))
+				Else If TByteType( ty ) Then
+					value = String.FromLong(Byte(value.ToLong()))
+				Else
+					value = String.FromLong(value.ToLong())
+				End If
 			EndIf
 
-		Else If TFloatType( ty )
+		Else If TDecimalType( ty )
 			If Not (value.Contains("e") Or value.Contains("E") Or value.Contains("."))
 				value:+".0"
 			EndIf
@@ -1082,7 +1094,16 @@ Type TCastExpr Extends TExpr
 			Err "Unable to convert from "+src.ToString()+" to "+ty.ToString()+"."
 		EndIf
 
-		If TConstExpr( expr ) Return EvalConst()
+		If TConstExpr( expr ) Then
+
+			Local ex:TExpr = EvalConst()
+			If flags & CAST_EXPLICIT Then
+				Return New TCastExpr.Create(exprType, ex, 1).Semant()
+			Else
+				Return ex
+			End If
+		End If
+		
 		Return Self
 	End Method
 

+ 6 - 5
parser.bmx

@@ -1593,14 +1593,15 @@ End Rem
 		Local init:TStmt,expr:TExpr,incr:TStmt
 
 		If varlocal
-			Local indexVar:TLocalDecl=New TLocalDecl.Create( varid,varty,from,0 )
+			Local indexVar:TLocalDecl=New TLocalDecl.Create( varid,varty,New TCastExpr.Create( varty,from,1 ),0 )
 			init=New TDeclStmt.Create( indexVar )
-			expr=New TBinaryCompareExpr.Create( op,New TVarExpr.Create( indexVar ),term )
-			incr=New TAssignStmt.Create( "=",New TVarExpr.Create( indexVar ),New TBinaryMathExpr.Create( "+",New TVarExpr.Create( indexVar ),stp ) )
+			expr=New TBinaryCompareExpr.Create( op,New TVarExpr.Create( indexVar ),New TCastExpr.Create( varty,term,1 ) )
+			incr=New TAssignStmt.Create( "=",New TVarExpr.Create( indexVar ),New TBinaryMathExpr.Create( "+",New TVarExpr.Create( indexVar ),New TCastExpr.Create( varty,stp,1 ) ) )
 		Else
+			' varty is NULL here for the casts. We will back-populate it later.
 			init=New TAssignStmt.Create( "=",New TIdentExpr.Create( varid ),from )
-			expr=New TBinaryCompareExpr.Create( op,New TIdentExpr.Create( varid ),term )
-			incr=New TAssignStmt.Create( "=",New TIdentExpr.Create( varid ),New TBinaryMathExpr.Create( "+",New TIdentExpr.Create( varid ),stp ) )
+			expr=New TBinaryCompareExpr.Create( op,New TIdentExpr.Create( varid ),New TCastExpr.Create( varty,term,1 ) )
+			incr=New TAssignStmt.Create( "=",New TIdentExpr.Create( varid ),New TBinaryMathExpr.Create( "+",New TIdentExpr.Create( varid ),New TCastExpr.Create( varty,stp,1 ) ) )
 		EndIf
 
 		Local block:TBlockDecl=New TBlockDecl.Create( _block )

+ 14 - 1
stmt.bmx

@@ -452,8 +452,21 @@ Type TForStmt Extends TLoopStmt
 	Method OnSemant()
 
 		PushEnv block
+
+		Local updateCastTypes:Int
+		If TAssignStmt(init) And TIdentExpr(TAssignStmt(init).lhs) Then
+			updateCastTypes = True
+		End If
 		init.Semant
+
 		PopEnv
+
+		If updateCastTypes Then
+			' ty in the casts are currently Null - we didn't know at the time of creating the statement, what the variable type was.
+			' Now we do, so we'll fill in the gaps.
+			TCastExpr(TBinaryCompareExpr(expr).rhs).ty = TVarExpr(TAssignStmt(init).lhs).exprType.Copy()
+			TCastExpr(TBinaryMathExpr(TAssignStmt(incr).rhs).rhs).ty = TVarExpr(TAssignStmt(init).lhs).exprType.Copy()
+		End If
 		
 		expr=expr.Semant()
 		
@@ -462,7 +475,7 @@ Type TForStmt Extends TLoopStmt
 		_loopnest:-1
 
 		incr.Semant
-		
+
 		'dodgy as hell! Reverse comparison for backward loops!
 		Local assop:TAssignStmt=TAssignStmt( incr )
 		Local addop:TBinaryExpr=TBinaryExpr( assop.rhs )