瀏覽代碼

Added mx2cc geninfo support for local vars in for loops.

Mark Sibly 7 年之前
父節點
當前提交
a0de035af3

+ 0 - 38
src/mx2cc/.mx2/test.monkey2

@@ -1,38 +0,0 @@
-
-Function Main:Void()
-	
-	Local x:=0,y:=50,z:=100
-	
-	If x<10
-		Local t:=100
-	Else
-		Local t:=20
-	Endif
-	
-	While True
-		Local a:=10
-	Wend
-	
-	Repeat
-		Local q:=70
-	Until True
-	
-	For Local b:=0 Until 10
-		Local c:=20
-	Next
-	
-	Select x
-	Case 10
-		Local d:=30
-	Default
-		Local e:=40
-	End
-	
-	Try
-		Local f:=50
-	Catch ex:Throwable
-		Local g:=60
-	End
-
-End
-

+ 4 - 4
src/mx2cc/block.monkey2

@@ -103,21 +103,21 @@ Class Block Extends Scope
 		Scope.semanting.Pop()
 	End
 	
-	Method AllocLocal:VarValue( init:Value )
+	Method AllocLocal:VarValue( init:Value,srcpos:Int=0,endpos:Int=0 )
 
 		Local ident:=""+func.nextLocalId
 		func.nextLocalId+=1
 
-		Local varValue:=New VarValue( "local",ident,init,Self )
+		Local varValue:=New VarValue( "local",ident,init,Self,srcpos,endpos )
 		
 		stmts.Push( New VarDeclStmt( Null,varValue ) )
 
 		Return varValue
 	End
 
-	Method AllocLocal:VarValue( ident:String,init:Value )
+	Method AllocLocal:VarValue( ident:String,init:Value,srcpos:Int=0,endpos:Int=0 )
 
-		Local varValue:=New VarValue( "local",ident,init,Self )
+		Local varValue:=New VarValue( "local",ident,init,Self,srcpos,endpos,DECL_PUBLIC )
 		
 		stmts.Push( New VarDeclStmt( Null,varValue ) )
 

+ 8 - 1
src/mx2cc/geninfo/geninfo.monkey2

@@ -272,7 +272,14 @@ Class GeninfoGenerator
 	Method GenNode:JsonValue( forStmt:ForStmtExpr )
 		
 		Local jobj:=MakeNode( forStmt,"block" )
-		jobj.SetValue( "stmts",GenNode( forStmt.stmts ) )
+'		jobj.SetValue( "stmts",GenNode( forStmt.stmts ) )
+		Local jarr:=New JsonArray
+		If forStmt.semVar jarr.Add( GenNode( forStmt.semVar.vdecl ) )
+		For Local stmt:=Eachin forStmt.stmts
+			Local jobj:=GenNode( stmt )
+			If jobj jarr.Add( GenNode( stmt ) )
+		Next
+		jobj.SetValue( "stmts",jarr )
 		Return jobj
 	End
 	

+ 9 - 3
src/mx2cc/parser.monkey2

@@ -972,8 +972,6 @@ Class Parser
 	
 	Method ParseFor:ForStmtExpr()
 	
-		Local srcpos:=SrcPos
-		
 		Local varIdent:String
 		Local varType:Expr
 		Local varExpr:Expr
@@ -982,10 +980,16 @@ Class Parser
 		Local cond:Expr
 		Local incr:Expr
 		
+		Local srcpos:=SrcPos
+		
+		Local vsrcpos:=srcpos
+		
 		Try
 			Parse( "for" )
 			
 			If CParse( "local" )
+				
+				vsrcpos=SrcPos
 			
 				varIdent=ParseIdent()
 				
@@ -1033,6 +1037,8 @@ Class Parser
 			
 		End
 		
+		Local vendpos:=SrcPos
+		
 		Local stmts:=ParseStmts( True )
 		
 		Try
@@ -1042,7 +1048,7 @@ Class Parser
 			SkipToNextLine()
 		End
 		
-		Return New ForStmtExpr( varIdent,varType,varExpr,kind,init,cond,incr,stmts,srcpos,EndPos )
+		Return New ForStmtExpr( varIdent,varType,varExpr,kind,init,cond,incr,stmts,srcpos,EndPos,vsrcpos,vendpos )
 	
 	End
 	

+ 10 - 5
src/mx2cc/stmtexpr.monkey2

@@ -577,10 +577,13 @@ Class ForStmtExpr Extends StmtExpr
 	Field init:Expr
 	Field cond:Expr
 	Field incr:Expr
-	
 	Field stmts:StmtExpr[]
+	Field vsrcpos:Int
+	Field vendpos:Int
 	
-	Method New( varIdent:String,varType:Expr,varExpr:Expr,kind:String,init:Expr,cond:Expr,incr:Expr,stmts:StmtExpr[],srcpos:Int,endpos:Int )
+	Field semVar:VarValue
+
+	Method New( varIdent:String,varType:Expr,varExpr:Expr,kind:String,init:Expr,cond:Expr,incr:Expr,stmts:StmtExpr[],srcpos:Int,endpos:Int,vsrcpos:Int,vendpos:Int )
 		Super.New( srcpos,endpos )
 		
 		Self.varIdent=varIdent
@@ -590,8 +593,9 @@ Class ForStmtExpr Extends StmtExpr
 		Self.init=init
 		Self.cond=cond
 		Self.incr=incr
-		
 		Self.stmts=stmts
+		Self.vsrcpos=vsrcpos
+		Self.vendpos=vendpos
 	End
 	
 	Method ToString:String() Override
@@ -699,7 +703,7 @@ Class ForStmtExpr Extends StmtExpr
 		
 		If varIdent
 			If varType curr=curr.UpCast( varType.SemantType( block ) )
-			block.AllocLocal( varIdent,curr )
+			semVar=block.AllocLocal( varIdent,curr,vsrcpos,vendpos )
 		Else
 			Local iter:=varExpr.Semant( block ).RemoveSideEffects( block )
 			If Not iter.IsAssignable Throw New SemantEx( "For loop index '"+iter.ToString()+"' is not assignable" )
@@ -724,7 +728,8 @@ Class ForStmtExpr Extends StmtExpr
 		
 		If varIdent
 			If varType init=init.UpCast( varType.SemantType( iblock ) )
-			iter=iblock.AllocLocal( varIdent,init )
+			semVar=iblock.AllocLocal( varIdent,init,vsrcpos,vendpos )
+			iter=semVar
 		Else
 			iter=varExpr.Semant( iblock ).RemoveSideEffects( iblock )
 			If Not iter.IsAssignable Throw New SemantEx( "For loop index '"+iter.ToString()+"' is not assignable" )

+ 9 - 20
src/mx2cc/test.monkey2

@@ -1,27 +1,16 @@
 
-Global weakRef:WeakRef
-
-Class C
-End
-
-Function Test()
-	
-	weakRef=New WeakRef( New C )
-End
-
 Function Main()
 	
-	Test()
-	
-'	Local tmp:=weakRef.Target
+	Local x:=10
 	
-	Print "weakRef valid="+(weakRef.Target<>Null)
-	
-	GCCollect()
-	GCCollect()
-
-	Print "weakRef valid="+(weakRef.Target<>Null)
+	For Local c:=Eachin "Hello World"
+		Local t:=c
+		Print c
+	Next
 	
-	Print "Hello World"
+	For Local i:=0 Until 10
+		Local y:=20
+		Print i
+	Next
 	
 End

+ 25 - 0
src/mx2cc/tests/weakref.monkey2

@@ -0,0 +1,25 @@
+
+Global weakRef:WeakRef
+
+Class C
+End
+
+Function Test()
+	
+	weakRef=New WeakRef( New C )
+End
+
+Function Main()
+	
+	Test()
+	
+'	Local tmp:=weakRef.Target	'should keep weakref alive
+	
+	Print "weakRef valid="+(weakRef.Target<>Null)	'true
+	
+	GCCollect()
+	GCCollect()
+
+	Print "weakRef valid="+(weakRef.Target<>Null)	'false
+	
+End

+ 4 - 1
src/mx2cc/var.monkey2

@@ -45,11 +45,14 @@ Class VarValue Extends Value
 		End
 	End
 	
-	Method New( kind:String,ident:String,init:Value,scope:Scope )
+	Method New( kind:String,ident:String,init:Value,scope:Scope,srcpos:Int=0,endpos:Int=0,declflags:Int=0 )
 
 		vdecl=New VarDecl
 		vdecl.kind=kind
 		vdecl.ident=ident
+		vdecl.srcpos=srcpos
+		vdecl.endpos=endpos
+		vdecl.flags=declflags
 		
 		Self.pnode=vdecl
 		Self.type=init.type