浏览代码

More mx2cc tweaks and fixes.

* Struct extensions can write to 'self' members.

* Major tweakages of type dependancy code.

* Lots of cleanups.
Mark Sibly 9 年之前
父节点
当前提交
fef3312923

+ 11 - 8
README.TXT

@@ -1,23 +1,26 @@
 
-
 ***** Welcome to Monkey2! *****
 
-WARNING: The master branch is super-volatile. Grabbing the most recently tagged branch is recommended if you just want to monkey2 a try.
+W A R N I N G ! The master branch is super-volatile. Grabbing the most recently tagged version is
+recommended if you just want to give monkey2 a try.
+
+Only tagged releases include synced binaries of the compiler. If you pull from master,
+you may or may not have to 'updatemx2cc' before (or after) building everything else.
 
 
 ***** Building monkey2 on Windows *****
 
-1) Install the mingw-64 compiler. Mingw-64 is available here: 
+1) Install the mingw-64 compiler. There is a self-extracting archive of mingw-64 that has been tested with monkey2 here:
 
-https://sourceforge.net/projects/mingw-w64/
+http://www.monkey-x.com/mak/devtools/i686-5.3.0-posix-dwarf-rt_v4-rev0.exe
 
-When installing, you should select 'i686' for 'architecture', 'posix' for 'threads' and 'dwarf' for 'exception'.
+If you install this to the monkey2 'devtools' directory, the following steps should 'just work'.
 
-There is also a self-extracting archive of mingw-64 that has been tested with monkey2 here:
+The general release of mingw-64 is available here: 
 
-http://www.monkey-x.com/mak/devtools/i686-5.3.0-posix-dwarf-rt_v4-rev0.exe
+https://sourceforge.net/projects/mingw-w64/
 
-If you install this to the monkey2 'devtools' directory, the following steps should 'just work'.
+When installing, you should select 'i686' for 'architecture', 'posix' for 'threads' and 'dwarf' for 'exception'.
 
 2) Open a command prompt and change to the 'monkey2\scripts' directory.
 

+ 5 - 0
modules/libc/native/libc.cpp

@@ -40,6 +40,11 @@ int system_( const char *cmd ){
 		si.hStdError=GetStdHandle( STD_ERROR_HANDLE );
 	}
 	
+	if( GetConsoleWindow() ){
+
+		flags=0;
+	}
+	
 	if( !CreateProcessA( 0,(LPSTR)tmp.c_str(),0,0,inherit,flags,0,0,&si,&pi ) ) return -1;
 
 	WaitForSingleObject( pi.hProcess,INFINITE );

+ 1 - 1
modules/monkey/native/bbarray.h

@@ -53,7 +53,7 @@ template<class T,int D> class bbArray : public bbGCNode{
 		return r;
 	}
 	
-	template<class C,class...Args> static bbArray *create( std::initializer_list<C> init,Args...args ){
+	template<class...Args> static bbArray *create( std::initializer_list<T> init,Args...args ){
 	
 		int sizes[]{ args... };
 		for( int i=1;i<D;++i ) sizes[i]*=sizes[i-1];

+ 1 - 2
products/android/README.TXT

@@ -9,8 +9,7 @@ Setting up for Android development:
 
 2) Install the 'NDK' (native development kit) using android studio via 'SDK Manager->SDK Tools'.
 
-3) Edit your monkey2 bin/env_windows.txt file and change the ndk-bundle 'PATH' setting so it points to the NDK. Or, you can just add the
-ndk-bundle dir to your system PATH.
+3) Edit your monkey2 bin/env_windows.txt file and change the ndk-bundle 'PATH' setting so it points to the NDK. Or, you can just add the ndk-bundle dir to your system PATH.
 
 4) Fire up Ted2 and select 'Build->Rebuild Modules->Android'. Wait...
 

+ 8 - 20
src/mx2cc/class.monkey2

@@ -455,20 +455,6 @@ Class ClassType Extends Type
 		If Not flist Return Null
 		
 		Return overload.FindOverload( flist.funcs,type,Null )
-		
-		#rem		
-		
-		If flist
-			Local func:=overload.FindOverload( flist.funcs,type,Null )
-			If func Return func
-		Endif
-		
-		flist=Cast<FuncList>( FileScope.FindExtension( "to",False,Self ) )
-		If Not flist Return Null
-		
-		Return overload.FindOverload( flist.funcs,type,Null )
-		#end
-		
 	End
 	
 	Method DistanceToBase:Int( type:Type )
@@ -505,7 +491,7 @@ Class ClassType Extends Type
 		If dist>=0 Return dist
 		
 		'Cast to bool
-		If type=BoolType 
+		If type=BoolType
 			If IsClass Or IsInterface Return MAX_DISTANCE
 			Return -1
 		Endif
@@ -533,11 +519,13 @@ Class ClassType Extends Type
 		If dist>=0 Return New UpCastValue( type,rvalue )
 		
 		'Cast to bool
-		If type=BoolType Return New UpCastValue( type,rvalue )
-		
-		'Operator To:
-		Local func:=FindToFunc( type )
-		If func Return func.ToValue( rvalue ).Invoke( Null )
+		If type=BoolType
+			If IsClass Or IsInterface Return New UpCastValue( type,rvalue )
+		Else
+			'Operator To:
+			Local func:=FindToFunc( type )
+			If func Return func.ToValue( rvalue ).Invoke( Null )
+		Endif
 
 		Throw New SemantEx( "Unable to convert value from type '"+rvalue.type.ToString()+"' to type '"+type.ToString()+"'" )
 		Return Null

+ 1 - 1
src/mx2cc/enum.monkey2

@@ -64,7 +64,7 @@ Class EnumType Extends Type
 					End
 				Endif
 				
-				Local value:=New LiteralValue( Self,String( nextInit  ) )
+				Local value:=New LiteralValue( Self,String( nextInit ) )
 				
 				scope.Insert( decl.ident,value )
 				

+ 1 - 0
src/mx2cc/errors.monkey2

@@ -124,6 +124,7 @@ End
 
 Function SemantError( func:String )
 	Print "~n".Join( GetDebugStack() )
+	DebugStop()
 	Throw New SemantEx( func+" Internal Error" )
 End
 

+ 1 - 1
src/mx2cc/filescope.monkey2

@@ -143,7 +143,7 @@ Class FileScope Extends Scope
 	End
 	
 	Method FindExtensions:SNode( finder:NodeFinder,ctype:ClassType )
-
+	
 		'Search nmspace hierarchy
 		'		
 		nmspace.FindExtensions( finder,ctype )

+ 28 - 55
src/mx2cc/func.monkey2

@@ -48,8 +48,8 @@ Class FuncValue Extends Value
 	
 	Field params:VarValue[]
 	
-	Field selfType:ClassType
 	Field selfValue:Value
+	Field selfType:ClassType
 	
 	Field instances:Stack<FuncValue>
 	
@@ -133,6 +133,14 @@ Class FuncValue Extends Value
 		Return fdecl.kind="function"
 	End
 	
+	Property IsStatic:Bool()
+		Return fdecl.kind<>"method" Or types Or fdecl.IsExtension
+	End
+	
+	Property IsMember:Bool()
+		Return Not IsStatic
+	End
+	
 	Property IsExtension:Bool()
 		Return (fdecl.kind="method" And types) Or fdecl.IsExtension
 	End
@@ -170,24 +178,12 @@ Class FuncValue Extends Value
 		'Semant selfType and selfValue
 		'
 		If IsCtor Or IsMethod
-	
-			If IsExtension
-			
-				selfType=cscope.ctype
-				
-				If selfType.cdecl.IsExtension selfType=selfType.superType
-				
-'				If fdecl.IsExtension selfType=selfType.superType
-			
-				selfValue=New VarValue( "capture","self",New LiteralValue( selfType,"" ),scope )
-				
-			Else
-			
-				selfType=cscope.ctype
+		
+			selfType=cscope.ctype
+
+			If selfType.cdecl.IsExtension selfType=selfType.superType
 			
-				selfValue=New SelfValue( selfType )
-				
-			Endif
+			selfValue=New SelfValue( selfType,Self )
 			
 		Else If IsLambda
 		
@@ -195,16 +191,20 @@ Class FuncValue Extends Value
 			
 			If selfValue
 			
-				selfValue=New VarValue( "capture","self",selfValue,block )
+				Local selfVar:=New VarValue( "capture","self",selfValue,block )
+				captures.Push( selfVar )
+				
+				selfValue=selfVar
+				selfType=Cast<ClassType>( selfValue.type )
 				
-				captures.Push( Cast<VarValue>( selfValue ) )
 			Endif
 		
 		Endif
 		
 		'That's it for generic funcs
 		'
-		If block.IsGeneric 
+		If block.IsGeneric
+			used=True
 			Return Self
 		Endif
 		
@@ -287,13 +287,19 @@ Class FuncValue Extends Value
 		Endif
 		
 		If IsLambda
+		
 			used=True
 			semanted=Self
 			SemantStmts()
-		Else If fdecl.IsExtern
+			
+		Else If fdecl.IsExtern 
+		
 			used=True
+			
 		Else If Not types
+		
 			Used()
+
 		Endif
 		
 		Return Self
@@ -375,39 +381,6 @@ Class FuncValue Extends Value
 			End
 		Next
 		
-		#rem
-		
-		If IsCtor Or IsMethod
-	
-			If IsExtension
-			
-				Local ctype:=cscope.ctype
-				
-				If fdecl.IsExtension ctype=ctype.superType
-			
-				selfValue=New VarValue( "capture","self",New LiteralValue( ctype,"" ),scope )
-				
-			Else
-			
-				selfValue=New SelfValue( cscope.ctype )
-				
-			Endif
-			
-		Else If IsLambda
-		
-			selfValue=Cast<Block>( scope ).func.selfValue
-			
-			If selfValue
-			
-				selfValue=New VarValue( "capture","self",selfValue,block )
-				
-				captures.Push( Cast<VarValue>( selfValue ) )
-			Endif
-		
-		Endif
-		
-		#end
-		
 	End
 	
 	Method SemantStmts()

+ 2 - 2
src/mx2cc/mx2cc.monkey2

@@ -21,9 +21,9 @@ Global StartDir:String
 
 'Const TestArgs:="mx2cc makedocs mojo"
 
-Const TestArgs:="mx2cc makemods"
+'Const TestArgs:="mx2cc makemods"
 
-'Const TestArgs:="mx2cc makeapp -clean -config=debug -target=desktop src/mx2cc/test.monkey2"
+Const TestArgs:="mx2cc makeapp -clean -config=debug -target=desktop src/mx2cc/test.monkey2"
 
 'Const TestArgs:="mx2cc makeapp -clean -config=debug -target=desktop -product=D:/test_app/test.exe -assets=D:/test_app/assets -dlls=D:/test_app/ src/mx2cc/test.monkey2"
 

+ 0 - 1
src/mx2cc/namespace.monkey2

@@ -98,7 +98,6 @@ Class NamespaceScope Extends Scope
 		For Local ext:=Eachin classexts
 		
 			If ext.IsGeneric
-				continue
 				Local etype:=ctype
 				While etype
 					If etype.instanceOf And etype.instanceOf.Equals( ext.superType.instanceOf )

+ 91 - 7
src/mx2cc/test.monkey2

@@ -1,17 +1,101 @@
 
-Class List<T>
+#import "<std>"
 
-	Struct Node
-		Field data:T
+Using std..
+
+Class UniformBuffer
+
+	Method Id<T>( name:String )
+	
+		Return Values<T>.Get( Self ).Id( name )
+	End
+
+	Method Set<T>( name:String,value:T )
+	
+		Values<T>.Get( Self ).Set( name,value )
+	End
+	
+	Method Clear<T>( name:String )
+	
+		Values<T>.Get( Self ).Clear( name )
 	End
 	
-	Field head:=New Node
+	Method Exists<T>:Bool( name:String )
+	
+		Return Values<T>.Get( Self ).Exists( name )
+	End
+	
+	Method Get<T>:T( name:String )
+	
+		Return Values<T>.Get( Self ).Get( name )
+	End
+	
+	Private
+	
+	Struct Values<T>
+	
+		Global _valuesMap:=New Map<UniformBuffer,Values>
+
+		Function Get:Values( ubuffer:UniformBuffer )
+
+			Local values:=_valuesMap[ubuffer]
+			If values Return values
+
+			values=New Values
+			_valuesMap[ubuffer]=values
+			Return values
+		End
+	
+		Method Id:Int( name:String )
+		
+			Local id:=_ids[name]
+			If id Return id-1
+			
+			_values.Push( Null )
+			_exists.Push( False )
+			
+			_ids[name]=_values.Length
+			Return _values.Length-1
+
+		End
+		
+		Method Set( name:String,value:T )
+			Local id:=Id( name )
+			_values[id]=value
+			_exists[id]=True
+		End
+		
+		Method Clear( name:String )
+			Local id:=Id( name )
+			_exists[ id ]=False
+		End
+		
+		Method Get:T( name:String )
+			Local id:=Id( name )
+			Return _values[id]
+		End
+		
+		Method Exists:Bool( name:String )
+			Local id:=Id( name )
+			Return _exists[id]
+		End
+		
+		Private
+		
+		Field _ids:=New StringMap<Int>
+		
+		Field _values:=New Stack<T>
+		Field _exists:=New Stack<Bool>
+
+	End
+
 End
 
 Function Main()
 
-	Local list:=New List<Int>
-	
-	list.head.data=10
+	Local ubuffer:=New UniformBuffer
 	
+	ubuffer.Set( "TestInt",1 )
+	Print ubuffer.Get<Int>( "TestInt" )
+
 End

+ 7 - 13
src/mx2cc/test2.monkey2

@@ -1,14 +1,8 @@
 
-#Import "<std>"
-
-Using std..
-
-Const TestDoc:="
-Hello World!
-"
- 
-Function Main()
-
-	Print "TestDoc="+TestDoc+"END"
-	
-End
+Enum EntityState
+	ENTERING
+	UPDATING
+	EXPLODING
+	ENDING
+	DONE
+End Enum

+ 21 - 25
src/mx2cc/translator.monkey2

@@ -389,38 +389,25 @@ Class Translator
 	Method Refs( vvar:VarValue )
 	
 		If vvar.vdecl.IsExtern Uses( vvar.transFile ) ; Return
-	
-		Select vvar.vdecl.kind
-		Case "field"
-			Refs( vvar.type )
-			Uses( vvar.scope.FindClass() )
-		Case "const","global"
+		
+		If vvar.IsStatic
 			If AddRef( vvar ) Return
 			_refsVars.Push( vvar )
-			Refs( vvar.type )
-		Case "local","param","capture"
-		Default
-			Throw New TransEx( "Trans.Refs() VarValue '"+String.FromCString( vvar.typeName() )+"' not recognized" )
 		End
+		
+		Refs( vvar.type )
 	End
 	
 	Method Refs( func:FuncValue )
-
-		Local fdecl:=func.fdecl
-			
-		If fdecl.IsExtern Uses( func.transFile ) ; Return
+	
+		If func.fdecl.IsExtern Uses( func.transFile ) ; Return
 		
-		If fdecl.kind="function" Or func.IsExtension
+		If func.IsStatic
 			If AddRef( func ) Return
 			_refsFuncs.Push( func )
-			Refs( func.ftype )
-		Else If fdecl.kind="method"
-			Uses( func.scope.FindClass() )
-			Refs( func.ftype )
-		Else If fdecl.kind="lambda"
-		Else
-			Throw New TransEx( "Trans.Refs() FuncValue '"+String.FromCString( func.typeName() )+"' not recognized" )
-		End
+		Endif
+		
+		Refs( func.ftype )
 	End
 	
 	Method Refs( type:Type )
@@ -464,11 +451,20 @@ Class Translator
 	End
 	
 	Method Uses( type:Type )
+
 		Local ctype:=TCast<ClassType>( type )
-		If ctype Uses( ctype )
+		If ctype 
+			Uses( ctype )
+			Return
+		Endif
 		
 		Local atype:=TCast<ArrayType>( type )
-		If atype Uses( atype.elemType )
+		If atype
+			Uses( atype.elemType )
+			Return
+		Endif
+		
+		Refs( type )
 	End
 	
 	Method Uses( ctype:ClassType )

+ 76 - 70
src/mx2cc/translator_cpp.monkey2

@@ -104,7 +104,6 @@ Class Translator_CPP Extends Translator
 		For Local vvar:=Eachin fdecl.globals
 			Uses( vvar.type )
 			Local proto:=VarProto( vvar )
-'			If IsStruct( vvar.type ) proto+="( bbNullCtor )"
 			Emit( proto+";" )
 		Next
 		
@@ -144,20 +143,6 @@ Class Translator_CPP Extends Translator
 		If Not name Return TransType( type )
 		
 		Return "bbGCVar<"+name+">"
-	
-		#rem
-		Local ctype:=TCast<ClassType>( type )
-		If ctype And (ctype.cdecl.kind="class" Or ctype.cdecl.kind="interface")
-			Return "bbGCVar<"+ClassName( ctype )+">"
-		Endif
-		
-		Local atype:=TCast<ArrayType>( type )
-		If atype
-			Return "bbGCVar<"+ArrayName( atype )+">"
-		Endif
-		
-		Return TransType( type )
-		#end
 	End
 	
 	Method VarType:String( vvar:VarValue )
@@ -176,7 +161,7 @@ Class Translator_CPP Extends Translator
 			Return "bbGCRootVar<"+name+">"
 		End
 		
-		TransError( "Translator.VarType (2)" )
+		TransError( "Translator.VarType()" )
 		Return ""
 	End
 
@@ -200,7 +185,10 @@ Class Translator_CPP Extends Translator
 		If Not func.IsCtor retType=TransType( ftype.retType )+" "
 
 		Local params:=""
-		If func.IsExtension params=TransType( func.selfType )+" l_self"
+		If func.IsExtension
+			Local tself:=func.selfType.IsStruct ? "&l_self" Else "l_self"
+			params=TransType( func.selfType )+" "+tself
+		Endif
 
 		For Local p:=Eachin func.params
 			If params params+=","
@@ -215,11 +203,11 @@ Class Translator_CPP Extends Translator
 		Endif
 		
 		Local ident:=FuncName( func )
-		If Not header And fdecl.kind="method" And Not func.IsExtension ident=ClassName( ctype )+"::"+ident
+		If Not header And func.IsMember ident=ClassName( ctype )+"::"+ident
 		
 		Local proto:=retType+ident+"("+params+")"
 		
-		If header And func.IsMethod And Not func.IsExtension
+		If header And func.IsMember
 			If fdecl.IsAbstract Or fdecl.IsVirtual Or ctype.IsVirtual
 				proto="virtual "+proto
 				If fdecl.IsAbstract proto+="=0"
@@ -354,16 +342,7 @@ Class Translator_CPP Extends Translator
 		EmitBr()		
 		For Local vvar:=Eachin ctype.fields
 
-			#rem			
-			If cdecl.kind="struct"
-				Uses( vvar.type )
-			Else
-				Refs( vvar.type )
-			Endif
-			#end
-			
 			Refs( vvar.type )
-
 			If IsGCType( vvar.type ) needsMark=True
 			
 			Local proto:=VarProto( vvar )
@@ -418,6 +397,7 @@ Class Translator_CPP Extends Translator
 			
 			Refs( func.ftype )
 			Emit( FuncProto( func,true )+";" )
+
 		Next
 		
 		'Emit non-ctor methods
@@ -431,6 +411,7 @@ Class Translator_CPP Extends Translator
 			
 			Refs( func.ftype )
 			Emit( FuncProto( func,True )+";" )
+
 		Next
 		
 		If cdecl.kind="struct"
@@ -945,17 +926,17 @@ Class Translator_CPP Extends Translator
 		
 		Refs( vvar.type )
 		
-		Local dbvar:=""
+		Local tvar:=""
 		
 		If vdecl.kind="local" And IsGCType( vvar.type )
 		
-			dbvar=InsertGCTmp( vvar )
+			tvar=InsertGCTmp( vvar )
 
-			If vvar.init Emit( dbvar+"="+Trans( vvar.init )+";" )
+			If vvar.init Emit( tvar+"="+Trans( vvar.init )+";" )
 
 		Else
 		
-			dbvar=VarName( vvar )
+			tvar=VarName( vvar )
 			
 			Local type:=VarType( vvar )
 			If vdecl.kind="global" Or vdecl.kind="const" type="static "+type
@@ -963,11 +944,11 @@ Class Translator_CPP Extends Translator
 			Local init:="{}"
 			If vvar.init init="="+Trans( vvar.init )
 			
-			Emit( type+" "+dbvar+init+";" )
+			Emit( type+" "+tvar+init+";" )
 			
 		Endif
 		
-		If debug And vdecl.kind="local" Emit( "bbDBLocal(~q"+vvar.vdecl.ident+"~q,&"+dbvar+");" )
+		If debug And vdecl.kind="local" Emit( "bbDBLocal(~q"+vvar.vdecl.ident+"~q,&"+tvar+");" )
 
 	End
 	
@@ -993,6 +974,7 @@ Class Translator_CPP Extends Translator
 	End
 
 	Method EmitStmt( stmt:EvalStmt )
+	
 		Emit( Trans( stmt.value )+";" )
 	End
 	
@@ -1216,9 +1198,11 @@ Class Translator_CPP Extends Translator
 	
 	Method Trans:String( value:UpCastValue )
 	
-		Local ctype:=TCast<ClassType>( value.value.type )
-		If ctype Uses( ctype )
-		
+		Uses( value.type )
+	
+'		Local ctype:=TCast<ClassType>( value.value.type )
+'		If ctype Uses( ctype )
+
 		Local t:="("+Trans( value.value )+")"
 		
 		If IsValue( value.type ) Return TransType( value.type )+t
@@ -1228,9 +1212,11 @@ Class Translator_CPP Extends Translator
 	
 	Method Trans:String( value:ExplicitCastValue )
 	
+		Uses( value.type )
+	
 		Local ctype:=TCast<ClassType>( value.type )
 		If ctype 
-			Uses( ctype )
+'			Uses( ctype )
 			Return "bb_object_cast<"+ClassName( ctype )+"*>("+Trans( value.value )+")"
 		Endif
 		
@@ -1250,6 +1236,8 @@ Class Translator_CPP Extends Translator
 			If ptype=Type.DoubleType Return "0.0f"
 			If ptype=Type.BoolType Return "false"
 		Endif
+		
+		Refs( type )
 
 		Local etype:=TCast<EnumType>( type )
 		If etype Return EnumName( etype )+"(0)"
@@ -1274,6 +1262,8 @@ Class Translator_CPP Extends Translator
 			Return "BB_T("+EnquoteCppString( value.value )+")"
 		End
 		
+		Refs( value.type )
+		
 		Local etype:=TCast<EnumType>( value.type )
 		If etype Return EnumValueName( etype,value.value )
 		
@@ -1283,23 +1273,31 @@ Class Translator_CPP Extends Translator
 	End
 	
 	Method Trans:String( value:SelfValue )
-		If IsStruct( value.ctype ) Return "(*this)"
+	
+		If value.func.IsExtension Return "l_self"
+		
+		If value.ctype.IsStruct Return "(*this)"
+		
 		Return "this"
 	End
 	
 	Method Trans:String( value:SuperValue )
-		Local type:=ClassName( value.ctype )
-		If IsStruct( value.ctype ) Return "(*static_cast<"+type+"*>(this))"
-		Return "static_cast<"+type+"*>(this)"
+	
+		Uses( value.ctype )
+		
+		Local cname:=ClassName( value.ctype )
+		
+		If IsStruct( value.ctype ) Return "(*static_cast<"+cname+"*>(this))"
+		
+		Return "static_cast<"+cname+"*>(this)"
 	End
 	
 	Method TransMember:String( instance:Value,member:Value )
 	
-		Local ctype:=TCast<ClassType>( instance.type )
-		If ctype Uses( ctype )
-
+		Uses( instance.type )
+		
 		Local supr:=Cast<SuperValue>( instance )
-		If supr Return ClassName( TCast<ClassType>( supr.type ) )+"::"+Trans( member )
+		If supr Return ClassName( supr.ctype )+"::"+Trans( member )
 		
 		Local tinst:=Trans( instance )
 		Local tmember:=Trans( member )
@@ -1311,28 +1309,33 @@ Class Translator_CPP Extends Translator
 		Return tinst+"->"+tmember
 	End
 	
-	Method Trans:String( value:InvokeValue )
+	Method TransInvokeMember:String( instance:Value,member:FuncValue,args:Value[] )
+
+		Uses( instance.type )
 	
-		Local mfunc:=Cast<MemberFuncValue>( value.value )
-		
-		If mfunc
-		
-			Local instance:=mfunc.instance
-			Local member:=mfunc.member
+		If member.IsExtension
 			
-			If member.IsExtension
+			Local tinst:=Trans( instance )
 			
-				Refs( member )
-
-				Local tinst:=Trans( instance )
+			If member.selfType.IsStruct
+				If Not instance.IsLValue tinst="("+AllocGCTmp( instance.type )+"="+tinst+")"
+			Else
 				If IsVolatile( instance ) tinst="("+AllocGCTmp( instance.type )+"="+tinst+")"
-				If value.args tinst+=","
-				
-				Return Trans( member )+"("+tinst+TransArgs( value.args )+")"
 			Endif
 			
-			Return TransMember( instance,member )+"("+TransArgs( value.args )+")"
+			If args tinst+=","
+				
+			Return Trans( member )+"("+tinst+TransArgs( args )+")"
 		Endif
+			
+		Return TransMember( instance,member )+"("+TransArgs( args )+")"
+	End
+	
+	Method Trans:String( value:InvokeValue )
+	
+		Local mfunc:=Cast<MemberFuncValue>( value.value )
+		
+		If mfunc Return TransInvokeMember( mfunc.instance,mfunc.member,value.args )
 		
 		Return Trans( value.value )+"("+TransArgs( value.args )+")"
 	End
@@ -1344,7 +1347,8 @@ Class Translator_CPP Extends Translator
 
 	Method Trans:String( value:MemberFuncValue )
 
-		Local ctype:=value.member.scope.FindClass()
+		Local ctype:=value.member.cscope.ctype
+		
 		Uses( ctype )
 
 		Local cname:=ClassName( ctype )
@@ -1355,19 +1359,21 @@ Class Translator_CPP Extends Translator
 	Method Trans:String( value:NewObjectValue )
 	
 		Local ctype:=value.ctype
+		
+		Local cname:=ClassName( ctype )
 		Uses( ctype )
 	
 		If ctype.ExtendsVoid
-			Return "new "+ClassName( ctype )+"("+TransArgs( value.args )+")"
+			Return "new "+cname+"("+TransArgs( value.args )+")"
 		Endif
 		
 		If IsStruct( ctype )
-			If Not value.args Return ClassName( ctype )+"(bbNullCtor)"
-			If value.args[0].type.Equals( ctype ) Return ClassName( ctype )+"("+TransArgs( value.args )+",bbNullCtor)"
-			Return ClassName( ctype )+"("+TransArgs( value.args )+")"
+			If Not value.args Return cname+"(bbNullCtor)"
+			If value.args[0].type.Equals( ctype ) Return cname+"("+TransArgs( value.args )+",bbNullCtor)"
+			Return cname+"("+TransArgs( value.args )+")"
 		Endif
 		
-		Return "bbGCNew<"+ClassName( ctype )+">("+TransArgs( value.args )+")"
+		Return "bbGCNew<"+cname+">("+TransArgs( value.args )+")"
 	End
 	
 	Method Trans:String( value:NewArrayValue )
@@ -1464,13 +1470,12 @@ Class Translator_CPP Extends Translator
 	
 	Method Trans:String( value:FuncValue )
 	
+		Refs( value )
+	
 		If value.fdecl.kind="lambda" 
-			Refs( value.ftype )
 			Return EmitLambda( value )
 		Endif
 		
-		Refs( value )
-		
 		Return FuncName( value )
 	End
 	
@@ -1578,6 +1583,7 @@ Class Translator_CPP Extends Translator
 	End
 	
 	Method ArrayName:String( type:ArrayType )
+		Refs( type )
 		If type.rank=1 Return "bbArray<"+ElementType( type.elemType )+">"
 		Return "bbArray<"+ElementType( type.elemType )+","+type.rank+">"
 	End

+ 5 - 2
src/mx2cc/value.monkey2

@@ -188,12 +188,15 @@ End
 Class SelfValue Extends Value
 
 	Field ctype:ClassType
+	Field func:FuncValue
 	
-	Method New( ctype:ClassType )
+	Method New( ctype:ClassType,func:FuncValue )
 		Self.type=ctype
 		Self.ctype=ctype
+		Self.func=func
 		
-		If ctype.IsStruct flags|=VALUE_LVALUE|VALUE_ASSIGNABLE
+		If ctype.IsStruct flags|=VALUE_LVALUE
+'		If ctype.IsStruct And Not func.IsExtension flags|=VALUE_LVALUE
 	End
 	
 	Method ToString:String() Override

+ 15 - 5
src/mx2cc/var.monkey2

@@ -37,7 +37,10 @@ Class VarValue Extends Value
 		Self.transFile=scope.FindFile().fdecl
 		Self.cscope=Cast<ClassScope>( scope )
 		
-		If vdecl.kind="global" Or vdecl.kind="local" Or vdecl.kind="param" flags|=VALUE_LVALUE|VALUE_ASSIGNABLE
+		Select vdecl.kind
+		Case "global","local","param"
+			flags|=VALUE_LVALUE|VALUE_ASSIGNABLE
+		End
 	End
 	
 	Method New( kind:String,ident:String,init:Value,scope:Scope )
@@ -52,7 +55,10 @@ Class VarValue Extends Value
 		Self.cscope=Cast<ClassScope>( scope )
 		Self.init=init
 		
-		If vdecl.kind="global" Or vdecl.kind="local" Or vdecl.kind="param" flags|=VALUE_LVALUE|VALUE_ASSIGNABLE
+		Select vdecl.kind
+		Case "global","local","param"
+			flags|=VALUE_LVALUE|VALUE_ASSIGNABLE
+		End
 		
 		semanted=Self
 	End
@@ -61,6 +67,10 @@ Class VarValue Extends Value
 		Return vdecl.kind="field"
 	End
 	
+	Property IsStatic:Bool()
+		Return vdecl.kind="const" Or vdecl.kind="global"
+	End
+	
 	Method OnSemant:SNode() Override
 	
 		Scope.semanting.Push( scope )
@@ -134,8 +144,8 @@ Class MemberVarValue Extends Value
 		
 		If member.vdecl.kind="field"
 			If member.cscope.ctype.IsStruct
-				If instance.IsLValue flags|=VALUE_LVALUE
-				If instance.IsAssignable flags|=VALUE_ASSIGNABLE
+				If instance.IsLValue flags|=VALUE_LVALUE|VALUE_ASSIGNABLE
+'				If instance.IsAssignable flags|=VALUE_ASSIGNABLE
 			Else
 				flags|=VALUE_LVALUE|VALUE_ASSIGNABLE
 			Endif
@@ -143,7 +153,7 @@ Class MemberVarValue Extends Value
 	End
 	
 	Method ToString:String() Override
-		Return instance.ToString()+"."+type.ToString()
+		Return instance.ToString()+"."+member.vdecl.ident
 	End
 	
 	Property HasSideEffects:Bool() Override