Browse Source

Fixed alias
Added generic aliases
Fixed module dependancy build order
Docmaker tweaks.

Mark Sibly 9 years ago
parent
commit
6d153871e0

+ 55 - 12
src/mx2new/alias.monkey2

@@ -3,37 +3,80 @@ Namespace mx2
 
 Class AliasDecl Extends Decl
 
+	Field genArgs:String[]
 	Field type:TypeExpr
 	
 	Method ToNode:SNode( scope:Scope ) Override
-		Return New AliasType( Self,scope )
+	
+		Local types:=New Type[genArgs.Length]
+		For Local i:=0 Until types.Length
+			types[i]=New GenArgType( i,genArgs[i],Null,Null )
+		Next
+		
+		Return New AliasType( Self,scope,types,Null )
 	End
 End
 
-Class AliasType Extends Type
+Class AliasType Extends ProxyType
 
 	Field adecl:AliasDecl
 	Field scope:Scope
+	Field types:Type[]
+	Field instanceOf:AliasType
+	
+	Field instances:Stack<AliasType>
 	
-	Method New( adecl:AliasDecl,scope:Scope )
-		Self.pnode=adecl
+	Method New( adecl:AliasDecl,scope:Scope,types:Type[],instanceOf:AliasType )
 		Self.adecl=adecl
 		Self.scope=scope
+		Self.types=types
+		Self.instanceOf=instanceOf
+		
+		If AnyTypeGeneric( types ) flags|=TYPE_GENERIC
 	End
 	
 	Property Name:String() Override
-		Return "{Alias}"
+
+		Return adecl.ident+":"+_alias.Name
 	End
+
+	Method OnSemant:SNode() Override
 	
-	Property TypeId:String() Override
-		SemantError( "AliasType.TypeId()" )
-		Return ""
+'		If IsGeneric Return Self
+		
+		Local tscope:=scope
+		If types
+			tscope=New Scope( tscope )
+			For Local i:=0 Until types.Length
+				tscope.Insert( adecl.genArgs[i],types[i] )
+			Next
+		Endif
+		
+		_alias=adecl.type.Semant( tscope )
+		
+		flags=_alias.flags
+		
+		Return Self
 	End
 	
-	Method OnSemant:SNode() Override
-		Local node:=adecl.type.Semant( scope )
-		If Not node Throw New SemantEx( "Can't find type '"+adecl.type.ToString()+"'" )
-		Return node
+	Method GenInstance:Type( types:Type[] ) Override
+
+		If Not IsGeneric Return Super.GenInstance( types )
+
+		If types.Length<>Self.types.Length Throw New SemantEx( "Wrong number of generic type parameters" )
+
+		If Not instances instances=New Stack<AliasType>
+	
+		For Local inst:=Eachin instances
+			If TypesEqual( inst.types,types ) Return inst
+		Next
+		
+		Local inst:=New AliasType( adecl,scope,types,Self )
+		instances.Push( inst )
+		
+		inst.Semant()
+		
+		Return inst
 	End
 
 End

+ 133 - 85
src/mx2new/builder.monkey2

@@ -35,6 +35,10 @@ Class Builder
 	
 	Field ppsyms:=New StringMap<String>
 
+	Field mainModule:Module
+	
+	Field parsingModule:Module
+	
 	Field modules:=New Stack<Module>
 	
 	Field modulesMap:=New StringMap<Module>
@@ -58,8 +62,8 @@ Class Builder
 	
 	Field maxObjTime:Long
 
-	Field MX2_FILES:=New StringList
-	Field MX2_LIBS:=New StringList
+	Field MX2_SRCS:=New StringStack
+	Field MX2_LIBS:=New StringStack
 	
 	Field SRC_FILES:=New StringStack
 	Field OBJ_FILES:=New StringStack
@@ -137,53 +141,49 @@ Class Builder
 	Method Parse()
 	
 		If opts.verbose=0 Print "Parsing..."
+		
+		Local name:=StripDir( StripExt( opts.mainSource ) )
 
-		Local module:=New Module( StripDir( StripExt( opts.mainSource ) ),opts.mainSource,opts.productType )
+		Local module:=New Module( name,opts.mainSource,opts.productType,MX2_PRODUCT_VERSION )
+		modulesMap[name]=module
 		modules.Push( module )
 		
-		Local monkeyDone:=(module.name="monkey" And module.productType="module")
+		mainModule=module
+		If name="monkey" And module.productType="module" modulesMap["monkey"]=module
 		
 		If opts.clean 
 			DeleteDir( module.outputDir,True )
 			DeleteDir( module.cacheDir,True )
 		Endif
 		
-		MX2_FILES.AddLast( module.srcPath )
+		parsingModule=module
+		MX2_SRCS.Push( module.srcPath )
 		
 		Repeat
 		
-			If MX2_FILES.Empty
+			If MX2_SRCS.Empty
+			
+				parsingModule=Null
 			
 				If MX2_LIBS.Empty
 				
-					If monkeyDone Exit
-					monkeyDone=True
+					If modulesMap["monkey"] Exit
 					
-					MX2_LIBS.AddLast( "monkey" )
+					MX2_LIBS.Push( "monkey" )
 				Endif
 				
-				Local lib:=MX2_LIBS.RemoveFirst()
-				If lib="monkey" And Not monkeyDone Continue
+				Local name:=MX2_LIBS.Pop()
+				Local srcPath:=modulesDir+name+"/"+name+".monkey2"
 				
-				Local module2:=modulesMap[lib]
-				If module2
-					modules.Remove( module2 )
-					modules.Push( module2 )
-					Continue
-				Endif
-				
-				Local srcPath:=modulesDir+lib+"/"+lib+".monkey2"
-				
-				module=New Module( lib,srcPath,"module" )
-				modulesMap[lib]=module
+				module=New Module( name,srcPath,"module",MX2_MODULES_VERSION )
+				modulesMap[name]=module
 				modules.Push( module )
-
-				LD_LIBS.Push( module.outputDir+lib+".a" )
 				
-				MX2_FILES.AddLast( module.srcPath )
+				parsingModule=module
+				MX2_SRCS.Push( module.srcPath )
 			Endif
 			
-			Local path:=MX2_FILES.RemoveFirst()
+			Local path:=MX2_SRCS.Pop()
 			
 			If opts.verbose>0 Print "Parsing "+path
 			
@@ -214,14 +214,61 @@ Class Builder
 		Forever
 	
 	End
+	
+	Method SortModules( module:Module,done:StringMap<Bool>,deps:Stack<Module> )
+	
+		If done.Contains( module.name ) Return
+		
+		For Local dep:=Eachin module.moduleDeps.Keys
+		
+			Local module2:=modulesMap[dep]
+		
+			SortModules( module2,done,deps )
+		
+		Next
+		
+		If done.Contains( module.name ) Return
+		
+		done[module.name]=True
+		
+		deps.Push( module )
+		
+	End
+	
+	Method SortModules()
+
+		'sort modules into dependency order
+		Local sorted:=New Stack<Module>
+		Local done:=New StringMap<Bool>
+		
+		sorted.Push( modulesMap["monkey"] )
+		done["monkey"]=True
+		
+		For Local i:=0 Until modules.Length
+			SortModules( modules[i],done,sorted )
+		Next
+		
+		modules=sorted
+		
+		For Local i:=0 Until modules.Length
+		
+			Local module:=modules[modules.Length-i-1]
+
+			If module<>mainModule LD_LIBS.Push( module.outputDir+module.name+".a" )
+			
+		Next
+		
+	End
 
 	Method Semant()
 	
 		If opts.verbose=0 Print "Semanting..."
-
+		
+		SortModules()
+		
 		For Local i:=0 Until modules.Length
-
-			Local module:=modules[modules.Length-i-1]
+		
+			Local module:=modules[i]
 			
 '			Print ""		
 '			Print "Semanting module:"+module.srcPath
@@ -246,16 +293,8 @@ Class Builder
 				
 			Next
 			
-			Local count:=0
-			
 			Repeat
 			
-				count+=1
-				If count=1000 
-'					Print "Giving up!"
-'					Exit
-				Endif
-			
 				If Not semantMembers.Empty
 				
 					Local ctype:=semantMembers.RemoveFirst()
@@ -286,19 +325,22 @@ Class Builder
 					PNode.semanting.Pop()
 				
 				Else
-			
 					Exit
 				Endif
 
 			Forever
 			
+			semantingModule=Null
+
+			'Check Main
+			'			
 			Local main:=module.main
 			
-			If opts.productType="app" And module=modules[0]
+			If opts.productType="app" And module=mainModule
 				If main
 					main.fdecl.symbol="bbMain"
 				Else
-					Print "Can't find Main:Void()"
+					New BuildEx( "Can't find Main:Void()" )
 				Endif
 			Else If opts.productType="module"
 				If main
@@ -306,8 +348,8 @@ Class Builder
 				Endif
 			Endif
 			
-			semantingModule=Null
-			
+			'Ugly stuff for generic instances
+			'
 			Local transFiles:=New StringMap<FileDecl>
 			
 			For Local inst:=Eachin module.genInstances
@@ -316,7 +358,7 @@ Class Builder
 				
 				Local vvar:=Cast<VarValue>( inst )
 				Local func:=Cast<FuncValue>( inst )
-				Local ctype:=Cast<ClassType>( inst )
+				Local ctype:=TCast<ClassType>( inst )
 				
 				If vvar
 					transFile=vvar.transFile
@@ -376,7 +418,7 @@ Class Builder
 	
 		If opts.verbose=0 Print "Translating..."
 		
-		Local module:=modules[0]
+		Local module:=mainModule
 		
 		CreateDir( module.buildDir )
 		CreateDir( module.buildDir+"build_cache" )
@@ -403,7 +445,7 @@ Class Builder
 	
 		If opts.verbose=0 Print "Compiling...."
 		
-		Local module:=modules[0]
+		Local module:=mainModule
 	
 		For Local src:=Eachin SRC_FILES
 		
@@ -489,7 +531,7 @@ Class Builder
 	
 	Method CreateApp()
 	
-		Local module:=modules[0]
+		Local module:=mainModule
 		
 		Local outputFile:="",assetsDir:="",dllsDir:=""
 		
@@ -653,7 +695,8 @@ Class Builder
 	
 	Method CreateArchive()
 
-		Local module:=modules[0]
+		Local module:=mainModule
+		
 		Local outputFile:=module.outputDir+module.name+".a"
 		
 		If opts.verbose>=0 Print "Archiving "+outputFile
@@ -689,7 +732,7 @@ Class Builder
 			Local id:=path.Slice( i0,i1 )
 			i0=i1+1
 			
-			Local ntype:=Cast<NamespaceType>( nmspace.GetType( id ) )
+			Local ntype:=TCast<NamespaceType>( nmspace.GetType( id ) )
 			If Not ntype
 				ntype=New NamespaceType( id,nmspace )
 				nmspace.Insert( id,ntype )
@@ -733,28 +776,28 @@ Class Builder
 			Exit
 		Next
 
-		Type.BoolType=New PrimType( Cast<ClassType>( types.nodes["@bool"] ) )
-		Type.ByteType=New PrimType( Cast<ClassType>( types.nodes["@byte"] ) )
-		Type.UByteType=New PrimType( Cast<ClassType>( types.nodes["@ubyte"] ) )
-		Type.ShortType=New PrimType( Cast<ClassType>( types.nodes["@short"] ) )
-		Type.UShortType=New PrimType( Cast<ClassType>( types.nodes["@ushort"] ) )
-		Type.IntType=New PrimType( Cast<ClassType>( types.nodes["@int"] ) )
-		Type.UIntType=New PrimType( Cast<ClassType>( types.nodes["@uint"] ) )
-		Type.LongType=New PrimType( Cast<ClassType>( types.nodes["@long"] ) )
-		Type.ULongType=New PrimType( Cast<ClassType>( types.nodes["@ulong"] ) )
-		Type.FloatType=New PrimType( Cast<ClassType>( types.nodes["@float"] ) )
-		Type.DoubleType=New PrimType( Cast<ClassType>( types.nodes["@double"] ) )
-		Type.StringType=New PrimType( Cast<ClassType>( types.nodes["@string"] ) )
-		
-		Type.ArrayClass=Cast<ClassType>( types.nodes["@Array"] )
-		Type.ObjectClass=Cast<ClassType>( types.nodes["@object"] )
-		Type.ThrowableClass=Cast<ClassType>( types.nodes["@throwable"] )
-		
-		Type.CStringClass=Cast<ClassType>( types.nodes["CString"] )
-		Type.WStringClass=Cast<ClassType>( types.nodes["WString"] )
-		Type.Utf8StringClass=Cast<ClassType>( types.nodes["Utf8String"] )
-
-		Type.ExceptionClass=Cast<ClassType>( types.nodes["@Exception"] )
+		Type.BoolType=New PrimType( TCast<ClassType>( types.nodes["@bool"] ) )
+		Type.ByteType=New PrimType( TCast<ClassType>( types.nodes["@byte"] ) )
+		Type.UByteType=New PrimType( TCast<ClassType>( types.nodes["@ubyte"] ) )
+		Type.ShortType=New PrimType( TCast<ClassType>( types.nodes["@short"] ) )
+		Type.UShortType=New PrimType( TCast<ClassType>( types.nodes["@ushort"] ) )
+		Type.IntType=New PrimType( TCast<ClassType>( types.nodes["@int"] ) )
+		Type.UIntType=New PrimType( TCast<ClassType>( types.nodes["@uint"] ) )
+		Type.LongType=New PrimType( TCast<ClassType>( types.nodes["@long"] ) )
+		Type.ULongType=New PrimType( TCast<ClassType>( types.nodes["@ulong"] ) )
+		Type.FloatType=New PrimType( TCast<ClassType>( types.nodes["@float"] ) )
+		Type.DoubleType=New PrimType( TCast<ClassType>( types.nodes["@double"] ) )
+		Type.StringType=New PrimType( TCast<ClassType>( types.nodes["@string"] ) )
+		
+		Type.ArrayClass=TCast<ClassType>( types.nodes["@Array"] )
+		Type.ObjectClass=TCast<ClassType>( types.nodes["@object"] )
+		Type.ThrowableClass=TCast<ClassType>( types.nodes["@throwable"] )
+		
+		Type.CStringClass=TCast<ClassType>( types.nodes["CString"] )
+		Type.WStringClass=TCast<ClassType>( types.nodes["WString"] )
+		Type.Utf8StringClass=TCast<ClassType>( types.nodes["Utf8String"] )
+
+		Type.ExceptionClass=TCast<ClassType>( types.nodes["@Exception"] )
 
 		rootNamespace.Insert( "void",Type.VoidType )
 		rootNamespace.Insert( "bool",Type.BoolType )
@@ -831,10 +874,14 @@ Class Builder
 	Method ImportSystemFile:Void( path:String )
 	
 		Local ext:=ExtractExt( path )
+
+		Local name:=StripExt( path )
 		
-		If ext<>".monkey2" And imported.Contains( path ) Return
+		If ext=".monkey2" parsingModule.moduleDeps[name]=True
 		
-		Local name:=StripExt( path )
+		If imported.Contains( path ) Return
+		
+		imported[path]=True
 		
 		Select ext.ToLower()
 		Case ".a"
@@ -855,20 +902,14 @@ Class Builder
 '			STD_INCLUDES.Push( "<"+path+">" )
 			
 		Case ".monkey2"
-		
-			If Not imported.Contains( path )
-				modules.Top.moduleDeps.Push( name )
-			Endif
-			
-			MX2_LIBS.AddLast( name )
+
+			MX2_LIBS.Push( name )
 		
 		Default
 
 			New BuildEx( "Unrecognized import file type: '"+path+"'" )
 			
 		End
-		
-		imported[path]=True
 
 	End
 	
@@ -930,7 +971,12 @@ Class Builder
 			
 		Default
 		
-			If GetFileType( path )<>FILETYPE_FILE
+			Local tpath:=path
+		
+			Local i:=tpath.Find( "@/" )
+			If i<>-1 tpath=tpath.Slice( 0,i )
+		
+			If GetFileType( tpath )<>FILETYPE_FILE
 				New BuildEx( "File "+qpath+" not found" )
 				Return
 			Endif
@@ -940,7 +986,7 @@ Class Builder
 		Select ext
 		Case ".mx2",".monkey2"
 		
-			MX2_FILES.AddLast( path )
+			MX2_SRCS.Push( path )
 			
 		Case ".h",".hh",".hpp"
 		
@@ -948,9 +994,11 @@ Class Builder
 			
 		Case ".c",".cc",".cxx",".cpp",".m",".mm"
 		
-			If modules.Length=1
-				SRC_FILES.Push( path )
-			Endif
+			If parsingModule=mainModule SRC_FILES.Push( path )
+		
+'			If modules.Length=1
+'				SRC_FILES.Push( path )
+'			Endif
 			
 		Case ".o"
 		

+ 6 - 6
src/mx2new/class.monkey2

@@ -109,7 +109,7 @@ Class ClassType Extends Type
 		
 			Try
 				Local type:=cdecl.superType.Semant( scope )
-				If type=Type.VoidType
+				If TCast<VoidType>( type )
 				
 					If Not cdecl.IsExtern Or cdecl.kind<>"class" Throw New SemantEx( "Only extern classes can extend 'Void'" )
 					
@@ -117,7 +117,7 @@ Class ClassType Extends Type
 					
 				Else
 				
-					superType=Cast<ClassType>( type )
+					superType=TCast<ClassType>( type )
 					
 					If Not superType Or superType.cdecl.kind<>cdecl.kind Throw New SemantEx( "Type '"+type.ToString()+"' is not a valid super class type" )
 					
@@ -148,7 +148,7 @@ Class ClassType Extends Type
 			
 				Try
 					Local type:=iface.Semant( scope )
-					Local ifaceType:=Cast<ClassType>( type )
+					Local ifaceType:=TCast<ClassType>( type )
 					
 					If Not ifaceType Or (ifaceType.cdecl.kind<>"interface" And ifaceType.cdecl.kind<>"protocol" ) Throw New SemantEx( "Type '"+type.ToString()+"' is not a valid interface type" )
 					
@@ -448,14 +448,14 @@ Class ClassType Extends Type
 
 		#rem
 		'cast native classes to void ptr		
-		Local ptype:=Cast<PointerType>( type )
+		Local ptype:=TCast<PointerType>( type )
 		If ptype 
 			If IsVoid And ptype.elemType=Type.VoidType Return MAX_DISTANCE
 			Return -1
 		Endif
 		#end
 		
-		Local ctype:=Cast<ClassType>( type )
+		Local ctype:=TCast<ClassType>( type )
 		If Not ctype Return -1
 	
 		Local dist:=0
@@ -482,7 +482,7 @@ Class ClassType Extends Type
 	
 		If Not IsGeneric Return Super.InferType( type,infered )
 		
-		Local ctype:=Cast<ClassType>( type )
+		Local ctype:=TCast<ClassType>( type )
 		If Not ctype Return Null
 		
 		If types.Length<>ctype.types.Length Return Null

+ 76 - 50
src/mx2new/docsmaker.monkey2

@@ -165,32 +165,10 @@ Class DocsMaker
 		Return docs
 	End
 	
-	Method MungUrl:String( url:String )
-		url=url.Replace( "_","_0" )
-		url=url.Replace( "<","_1" )
-		url=url.Replace( ">","_2" )
-		url=url.Replace( ",","_3" )
-		url=url.Replace( "?","_4" )
-		url=url.Replace( "&","_5" )
-		url=url.Replace( "@","_6" )
-		url=url.Replace( ".","_" )
-		Return url
-	End
-	
-	Method HtmlEsc:String( str:String )
-		str=str.Replace( "&","&amp;" )
-		str=str.Replace( "<","&lt;" )
-		str=str.Replace( ">","&gt;" )
-		Return str
-	End
-	
-	Method MarkdownEsc:String( str:String )
-		str=str.Replace( "\","\\" )
-		str=str.Replace( "_","\_" )
-		str=str.Replace( "<","\<" )
-		str=str.Replace( ">","\>" )
-		Return str
-	End
+	Method Esc:String( id:String )
+		id=id.Replace( "_","\_" )
+		Return id
+	End	
 	
 	Method DeclSlug:String( decl:Decl,scope:Scope )
 		Local ident:=decl.ident.Replace( "@","" )
@@ -263,10 +241,10 @@ Class DocsMaker
 				Local flist:=Cast<FuncList>( node )
 				If flist Return MakeLink( id,flist.funcs[0].fdecl,flist.funcs[0].scope )
 				
-				Local etype:=Cast<EnumType>( node )
+				Local etype:=TCast<EnumType>( node )
 				If etype Return MakeLink( id,etype.edecl,etype.scope.outer )
 				
-				Local ctype:=Cast<ClassType>( node )
+				Local ctype:=TCast<ClassType>( node )
 				If ctype Return MakeLink( id,ctype.cdecl,ctype.scope.outer )
 				
 				Return ""
@@ -280,19 +258,19 @@ Class DocsMaker
 			Local type:=scope.FindType( id )
 			If Not type Return ""
 			
-			Local ntype:=Cast<NamespaceType>( type )
+			Local ntype:=TCast<NamespaceType>( type )
 			If ntype
 				scope=ntype.scope
 				Continue
 			Endif
 			
-			Local etype:=Cast<EnumType>( type )
+			Local etype:=TCast<EnumType>( type )
 			If etype
 				'stop at enum!
 				Return MakeLink( id+"."+path.Slice( i0 ),etype.edecl,etype.scope.outer )
 			Endif
 			
-			Local ctype:=Cast<ClassType>( type )
+			Local ctype:=TCast<ClassType>( type )
 			If ctype
 				scope=ctype.scope
 				Continue
@@ -318,6 +296,9 @@ Class DocsMaker
 		Endif
 		
 		If gen
+			Local adecl:=Cast<AliasDecl>( decl )
+			If adecl And adecl.genArgs ident+="<"+(",".Join( adecl.genArgs ))+">"
+			
 			Local cdecl:=Cast<ClassDecl>( decl )
 			If cdecl And cdecl.genArgs ident+="<"+(",".Join( cdecl.genArgs ))+">"
 			
@@ -325,10 +306,11 @@ Class DocsMaker
 			If fdecl And fdecl.genArgs ident+="<"+(",".Join( fdecl.genArgs ))+">"
 		Endif
 		
-		Return MarkdownEsc( ident )
+		Return Esc( ident )
 	End
 	
 	Method DeclIdent:String( decl:Decl,scope:Scope,gen:Bool=False )
+
 		Return MakeLink( DeclIdent( decl,gen ),decl,scope )
 	End
 	
@@ -366,28 +348,36 @@ Class DocsMaker
 	
 	Method TypeName:String( type:Type,prefix:String )
 	
-		Local vtype:=Cast<VoidType>( type )
+		Local xtype:=Cast<AliasType>( type )
+		If xtype
+		
+			If xtype.instanceOf xtype=xtype.instanceOf
+			
+			Return MakeLink( Esc( xtype.adecl.ident ),xtype.adecl,xtype.scope )
+		Endif
+	
+		Local vtype:=TCast<VoidType>( type )
 		If vtype
 			Return vtype.Name
 		Endif
 	
-		Local gtype:=Cast<GenArgType>( type )
+		Local gtype:=TCast<GenArgType>( type )
 		If gtype
 			Return gtype.Name.Replace( "?","" )
 		Endif
 	
-		Local ptype:=Cast<PrimType>( type )
+		Local ptype:=TCast<PrimType>( type )
 		If ptype
 			Local ctype:=ptype.ctype
-			Return MakeLink( ptype.Name,ctype.cdecl,ctype.scope.outer )
+			Return MakeLink( Esc( ptype.Name ),ctype.cdecl,ctype.scope.outer )
 		Endif
 		
-		Local ntype:=Cast<NamespaceType>( type )
+		Local ntype:=TCast<NamespaceType>( type )
 		If ntype
-			Return ntype.Name
+			Return Esc( ntype.Name )
 		Endif
 		
-		Local ctype:=Cast<ClassType>( type )
+		Local ctype:=TCast<ClassType>( type )
 		If ctype
 			Local args:=""
 			For Local type:=Eachin ctype.types
@@ -397,28 +387,28 @@ Class DocsMaker
 			
 			If ctype.instanceOf ctype=ctype.instanceOf
 			
-			Return MakeLink( MarkdownEsc( ctype.cdecl.ident ),ctype.cdecl,ctype.scope.outer )+args
+			Return MakeLink( Esc( ctype.cdecl.ident ),ctype.cdecl,ctype.scope.outer )+args
 		Endif
 		
-		Local etype:=Cast<EnumType>( type )
+		Local etype:=TCast<EnumType>( type )
 		If etype
 			Local name:=etype.Name
 			If name.StartsWith( prefix ) name=name.Slice( prefix.Length )
-			Return MakeLink( MarkdownEsc( name ),etype.edecl,etype.scope.outer )
+			Return MakeLink( Esc( name ),etype.edecl,etype.scope.outer )
 		Endif
 		
-		Local qtype:=Cast<PointerType>( type )
+		Local qtype:=TCast<PointerType>( type )
 		If qtype
 			Return TypeName( qtype.elemType,prefix )+" Ptr"
 		Endif
 		
-		Local atype:=Cast<ArrayType>( type )
+		Local atype:=TCast<ArrayType>( type )
 		If atype
 			If atype.rank=1 Return TypeName( atype.elemType,prefix )+"\[ \]"
 			Return TypeName( atype.elemType,prefix )+"\[ ,,,,,,,,,".Slice( 0,atype.rank+2 )+" \]"
 		End
 		
-		Local ftype:=Cast<FuncType>( type )
+		Local ftype:=TCast<FuncType>( type )
 		If ftype
 			Local args:=""
 			For Local arg:=Eachin ftype.argTypes
@@ -458,6 +448,25 @@ Class DocsMaker
 		Local init:=True
 	
 		For Local node:=Eachin scope.nodes
+		
+			Local atype:=Cast<AliasType>( node.Value )
+			If atype
+				If kind<>"alias" Continue
+				Local decl:=atype.adecl
+				If DocsHidden( decl ) Continue
+				If inherited<>(scope<>atype.scope) Continue
+				
+				If init
+					init=False
+					EmitBr()
+					Emit( "| Aliases | |" )
+					Emit( "|:---|:---" )
+				Endif
+				
+				Emit( "| "+DeclIdent( decl,atype.scope )+" | "+DeclDesc( decl )+" |" )
+				Continue
+			Endif
+				
 
 			Local ctype:=Cast<ClassType>( node.Value )
 			If ctype
@@ -476,7 +485,7 @@ Class DocsMaker
 				
 				Emit( "| "+DeclIdent( decl,ctype.scope.outer )+" | "+DeclDesc( decl )+" |" )
 				Continue
-			End
+			Endif
 			
 			Local etype:=Cast<EnumType>( node.Value )
 			If etype
@@ -494,7 +503,7 @@ Class DocsMaker
 
 				Emit( "| "+DeclIdent( decl,etype.scope.outer )+" | "+DeclDesc( decl )+" |" )
 				Continue
-			End
+			Endif
 
 			Local vvar:=Cast<VarValue>( node.Value )
 			If vvar
@@ -517,7 +526,6 @@ Class DocsMaker
 			Local plist:=Cast<PropertyList>( node.Value )
 			If plist
 				If kind<>"property" Continue
-				
 				Local decl:=plist.pdecl
 				If DocsHidden( decl ) Continue
 				If inherited<>(scope<>plist.scope) Continue
@@ -575,6 +583,7 @@ Class DocsMaker
 		Emit( "_Module: &lt;"+_module.name+"&gt;_  " )
 		Emit( "_Namespace: "+nmspace.Name+"_" )
 		
+		EmitMembers( "alias",nmspace,True )
 		EmitMembers( "enum",nmspace,True )
 		EmitMembers( "struct",nmspace,True )
 		EmitMembers( "class",nmspace,True )
@@ -586,6 +595,22 @@ Class DocsMaker
 		Return Flush()
 	End
 	
+	Method MakeAliasDocs:String( atype:AliasType )
+		Local decl:=atype.adecl
+		
+		If DocsHidden( decl ) Return ""
+		
+		_scope=atype.scope
+		
+		EmitHeader( decl,atype.scope )
+		
+		Emit( "##### Alias "+DeclIdent( decl,True )+" : "+TypeName( atype._alias,atype.scope ) )
+		
+		Emit( decl.docs )
+		
+		Return Flush()
+	End
+	
 	Method MakeEnumDocs:String( etype:EnumType )
 		Local decl:=etype.edecl
 		
@@ -645,6 +670,7 @@ Class DocsMaker
 		Emit( decl.docs )
 		
 		For Local inh:=0 Until 1
+			EmitMembers( "alias",ctype.scope,inh )
 			EmitMembers( "enum",ctype.scope,inh )
 			EmitMembers( "struct",ctype.scope,inh )
 			EmitMembers( "class",ctype.scope,inh )
@@ -736,7 +762,7 @@ Class DocsMaker
 			
 			Local params:=""
 			For Local i:=0 Until func.ftype.argTypes.Length
-				Local ident:=MarkdownEsc( func.fdecl.type.params[i].ident )
+				Local ident:=Esc( func.fdecl.type.params[i].ident )
 				Local type:=TypeName( func.ftype.argTypes[i],func.scope )
 				Local init:=""
 				If func.fdecl.type.params[i].init
@@ -746,7 +772,7 @@ Class DocsMaker
 			Next
 			params=params.Slice( 3 )
 			
-			Emit( "##### "+tkind+DeclIdent( decl )+" : "+TypeName( func.ftype.retType,func.scope )+" ( "+params+" ) " )
+			Emit( "##### "+tkind+DeclIdent( decl,True )+" : "+TypeName( func.ftype.retType,func.scope )+" ( "+params+" ) " )
 
 		Next
 		

+ 4 - 5
src/mx2new/enum.monkey2

@@ -42,7 +42,7 @@ Class EnumType Extends Type
 	
 		If edecl.superType
 			Try
-				superType=Cast<EnumType>( edecl.superType.Semant( scope ) )
+				superType=TCast<EnumType>( edecl.superType.Semant( scope ) )
 				
 				If Not superType Or superType.edecl.kind<>"enum"
 					Throw New SemantEx( "Cant find super type "+edecl.superType.ToString(),edecl )
@@ -108,15 +108,14 @@ Class EnumType Extends Type
 	
 		If type=Self Return 0
 		
-		If type=Type.BoolType Return MAX_DISTANCE
-		
-		Local ptype:=Cast<PrimType>( type )
+		Local ptype:=TCast<PrimType>( type )
 		If ptype
+			If ptype=Type.BoolType Return MAX_DISTANCE
 			If ptype.IsIntegral Return MAX_DISTANCE
 			Return -1
 		Endif
 	
-		Local etype:=Cast<EnumType>( type )
+		Local etype:=TCast<EnumType>( type )
 		If Not etype Return -1
 		
 		Local dist:=0

+ 1 - 0
src/mx2new/errors.monkey2

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

+ 1 - 1
src/mx2new/eval.monkey2

@@ -38,7 +38,7 @@ Function EvalBinaryop:LiteralValue( type:Type,op:String,lhs:LiteralValue,rhs:Lit
 		Return New LiteralValue( Type.IntType,String( r ) )
 	End
 	
-	Local etype:=Cast<EnumType>( type )
+	Local etype:=TCast<EnumType>( type )
 	If etype And Not etype.edecl.IsExtern
 		Local r:Int,x:=Int( lhs.value ),y:=Int( rhs.value )
 		Select op

+ 26 - 20
src/mx2new/expr.monkey2

@@ -295,7 +295,7 @@ Class NewObjectExpr Extends Expr
 	
 		Local type:=Self.type.Semant( scope )
 		
-		Local ctype:=Cast<ClassType>( type )
+		Local ctype:=TCast<ClassType>( type )
 		If Not ctype Throw New SemantEx( "Type '"+type.Name+"' is not a class" )
 		
 		'hmmm...
@@ -361,7 +361,7 @@ Class NewArrayExpr Extends Expr
 	
 	Method OnSemant:Value( scope:Scope ) Override
 	
-		Local atype:=Cast<ArrayType>( type.Semant( scope ) )
+		Local atype:=TCast<ArrayType>( type.Semant( scope ) )
 		If Not atype SemantError( "NewArrayExpr.OnSemant()" )
 		
 		If atype.elemType.IsGeneric Throw New SemantEx( "Array element type '"+atype.elemType.Name+"' is generic" )
@@ -425,7 +425,7 @@ Class ExtendsExpr Extends Expr
 	
 	Method OnSemant:Value( scope:Scope ) Override
 	
-		Local ctype:=Cast<ClassType>( Self.type.Semant( scope ) )
+		Local ctype:=TCast<ClassType>( Self.type.Semant( scope ) )
 		If Not ctype Or (ctype.cdecl.kind<>"class" And ctype.cdecl.kind<>"interface" And ctype.cdecl.kind<>"protocol" ) 
 			Throw New SemantEx( "Type '"+type.ToString()+"' is not a class or interface type" )
 		Endif
@@ -435,7 +435,7 @@ Class ExtendsExpr Extends Expr
 		Local tvalue:=Cast<TypeValue>( value )
 		If tvalue
 			If tvalue.ttype.DistanceToType( ctype )>=0 Return LiteralValue.BoolValue( True )
-			Local ptype:=Cast<PrimType>( tvalue.ttype )
+			Local ptype:=TCast<PrimType>( tvalue.ttype )
 			If ptype And ptype.ctype.DistanceToType( ctype )>=0 Return LiteralValue.BoolValue( True )
 			Return LiteralValue.BoolValue( False )
 		Endif
@@ -451,7 +451,8 @@ Class ExtendsExpr Extends Expr
 	
 	Method OnSemantWhere:Bool( scope:Scope ) Override
 	
-		Local ctype:=Cast<ClassType>( Self.type.Semant( scope ) )
+		Local ctype:=TCast<ClassType>( Self.type.Semant( scope ) )
+		
 		If Not ctype Or (ctype.cdecl.kind<>"class" And ctype.cdecl.kind<>"interface" And ctype.cdecl.kind<>"protocol" ) 
 			Throw New SemantEx( "Type '"+type.ToString()+"' is not a class or interface type" )
 		endif
@@ -483,6 +484,9 @@ Class CastExpr Extends Expr
 		Local type:=Self.type.Semant( scope )
 		
 		Local value:=Self.expr.Semant( scope )
+		
+		Local castOp:=value.FindValue( "cast" )
+		If castOp value=castOp.Invoke( Null )
 
 		'simple upcast?		
 		If value.type.DistanceToType( type )>=0 Return value.UpCast( type )
@@ -535,7 +539,7 @@ Class SuperExpr Extends Expr
 		Local block:=Cast<Block>( scope )
 		If block And block.func.selfValue
 		
-			Local ctype:=Cast<ClassType>( block.func.selfValue.type )
+			Local ctype:=TCast<ClassType>( block.func.selfValue.type )
 			If ctype
 
 				Local superType:=ctype.superType
@@ -592,7 +596,7 @@ Class UnaryopExpr Extends Expr
 		Local node:=value.FindValue( op )
 		If node Return node.Invoke( Null )
 		
-		Local ptype:=Cast<PrimType>( type )
+		Local ptype:=TCast<PrimType>( type )
 		
 		Select op
 		Case "+","-"
@@ -603,7 +607,7 @@ Class UnaryopExpr Extends Expr
 				Throw New SemantEx( "Type cannot be unsigned" )
 			Endif
 		Case "~"
-			Local etype:=Cast<EnumType>( type )
+			Local etype:=TCast<EnumType>( type )
 			If etype
 				type=etype
 			Else If Not ptype Or Not ptype.IsIntegral
@@ -680,8 +684,8 @@ Class BinaryopExpr Extends Expr
 	
 	Function BalanceTypes:Type( lhs:Type,rhs:Type )
 	
-		Local plhs:=Cast<PrimType>( lhs )
-		Local prhs:=Cast<PrimType>( rhs )
+		Local plhs:=TCast<PrimType>( lhs )
+		Local prhs:=TCast<PrimType>( rhs )
 		
 		If plhs And prhs Return BalancePrimTypes( plhs,prhs )
 		
@@ -709,6 +713,8 @@ Class BinaryopExpr Extends Expr
 			rhs=rhs.ToRValue()
 		Endif
 		
+		'check for overloaded operator
+		'
 		Local node:=lhs.FindValue( op )
 		If node 
 			Local args:=New Value[1]
@@ -718,8 +724,8 @@ Class BinaryopExpr Extends Expr
 
 		'handle pointer arithmetic
 		'
-		Local lptype:=Cast<PointerType>( lhs.type )
-		Local rptype:=Cast<PointerType>( rhs.type )
+		Local lptype:=TCast<PointerType>( lhs.type )
+		Local rptype:=TCast<PointerType>( rhs.type )
 		If lptype Or rptype
 			If lptype And (op="+" Or op="-")	
 				'pointer=pointer +/- int
@@ -731,8 +737,8 @@ Class BinaryopExpr Extends Expr
 			Throw New SemantEx( "Pointer arithmetic error" )
 		Endif
 		
-		Local plhs:=Cast<PrimType>( lhs.type )
-		Local prhs:=Cast<PrimType>( rhs.type )
+		Local plhs:=TCast<PrimType>( lhs.type )
+		Local prhs:=TCast<PrimType>( rhs.type )
 		
 		Local type:Type,lhsType:Type,rhsType:Type
 		
@@ -747,8 +753,8 @@ Class BinaryopExpr Extends Expr
 			
 		Case "&","|","~"
 		
-			Local elhs:=Cast<EnumType>( lhs.type )
-			Local erhs:=Cast<EnumType>( rhs.type )
+			Local elhs:=TCast<EnumType>( lhs.type )
+			Local erhs:=TCast<EnumType>( rhs.type )
 			If elhs Or erhs
 				If elhs.Equals( erhs ) type=elhs
 			Else
@@ -761,7 +767,7 @@ Class BinaryopExpr Extends Expr
 			rhsType=Type.IntType
 			
 		Case "=","<>","<",">","<=",">="
-		
+
 			Local node:=lhs.FindValue( "<=>" )
 			If node
 			
@@ -772,7 +778,7 @@ Class BinaryopExpr Extends Expr
 				lhsType=lhs.type
 				rhsType=lhsType
 				
-				Local ptype:=Cast<PrimType>( lhsType )
+				Local ptype:=TCast<PrimType>( lhsType )
 				Assert( ptype And ptype.IsNumeric )
 				
 				rhs=New LiteralValue( rhsType,"" )
@@ -907,7 +913,7 @@ Class LiteralExpr Extends Expr
 		 
 			type=typeExpr.Semant( scope )
 
-			Local ptype:=Cast<PrimType>( type )
+			Local ptype:=TCast<PrimType>( type )
 			If Not ptype Throw New SemantEx( "Literal type must be a primitive type" )
 			
 			Select tokeType
@@ -940,7 +946,7 @@ Class LiteralExpr Extends Expr
 		
 		Local t:=toke
 		
-		Local ptype:=Cast<PrimType>( type )
+		Local ptype:=TCast<PrimType>( type )
 		
 		If ptype And ptype.IsIntegral And t And t[0]=CHAR_DOLLAR
 		

+ 27 - 32
src/mx2new/func.monkey2

@@ -114,7 +114,7 @@ Class FuncValue Extends Value
 	Property IsGeneric:Bool()
 		If Not ftype SemantError( "FuncValue.IsGeneric()" )
 		
-		Return ftype.IsGeneric Or (types And Not instanceOf)
+		Return ftype.IsGeneric Or (types And Not instanceOf)	
 	End
 	
 	Property IsCtor:Bool()
@@ -146,18 +146,18 @@ Class FuncValue Extends Value
 		'Checks for generic funcs
 		'
 		If types
-			If fdecl.IsAbstract Or fdecl.IsVirtual Or fdecl.IsOverride Throw New SemantEx( "Virtual methods cannot be generic" )
+			If fdecl.IsAbstract Or fdecl.IsVirtual Or fdecl.IsOverride Throw New SemantEx( "Generic methods cannot be virtual" )
 			If IsCtor Throw New SemantEx( "Constructors cannot be generic" )	'TODO
 		Endif
 
 		'Semant func type
 		'
 		type=fdecl.type.Semant( block )
-		ftype=Cast<FuncType>( type )
+		ftype=TCast<FuncType>( type )
 		
 		'That's it for generic funcs
 		'
-		If block.IsGeneric
+		If block.IsGeneric 
 			Return Self
 		Endif
 		
@@ -177,7 +177,7 @@ Class FuncValue Extends Value
 					If ftype.argTypes.Length<>1 Throw New SemantEx( "Comparison operator '"+op+"' must have 1 parameter" )
 '					If Not ftype.argTypes[0].Equals( ctype ) Throw New SemantEx( "Comparison operator '"+op+"' parameter must be of type '"+ctype.ToString()+"'" )
 				Case "<=>"
-					Local ptype:=Cast<PrimType>( ftype.retType )
+					Local ptype:=TCast<PrimType>( ftype.retType )
 					If Not ptype Or Not ptype.IsNumeric Throw New SemantEx( "Comparison operator '<=>' must return a numeric type" )
 					If ftype.argTypes.Length<>1 Throw New SemantEx( "Comparison operator '"+op+"' must have 1 parameter" )
 '					If Not ftype.argTypes[0].Equals( ctype ) Throw New SemantEx( "Comparison operator '"+op+"' parameter must be of type '"+ctype.ToString()+"'" )
@@ -219,24 +219,31 @@ Class FuncValue Extends Value
 		
 		'Check 'where' if present
 		'		
-		If fdecl.whereExpr 'And (Not types Or instanceOf)
+		If fdecl.whereExpr
 			Local t:=fdecl.whereExpr.SemantWhere( block )
 '			Print "Semanted where for "+Name+" -> "+Int(t)
 			If Not t Return Null
 		Endif
 		
-		'Good to go
-		'
 		If fdecl.kind="lambda"
+			used=True
 			semanted=Self
 			SemantStmts()
-		Else If Not types And Not fdecl.IsExtern
-			Local builder:=Builder.instance
-			builder.semantStmts.Push( Self )
+		Else If fdecl.IsExtern
+			used=True
+		Else If Not types
+			Used()
 		Endif
 		
 		Return Self
-		
+	End
+	
+	Method Used()
+	
+		If used Return
+		used=True
+
+		Builder.instance.semantStmts.Push( Self )
 	End
 	
 	Method ToValue:Value( instance:Value ) Override
@@ -370,20 +377,22 @@ Class FuncValue Extends Value
 		
 			transFile.functions.Push( Self )
 			
-			If fdecl.ident="Main" And ftype.retType=Type.VoidType And Not ftype.argTypes
+			If fdecl.ident="Main" And TCast<VoidType>( ftype.retType ) And Not ftype.argTypes
 				Local module:=scope.FindFile().fdecl.module
 				If module.main Throw New SemantEx( "Duplicate declaration of 'Main'" )
 				module.main=Self
 			Endif
 			
-			If instanceOf'IsGenInstance
+			If instanceOf
 				Local builder:=Builder.instance
 				Local module:=builder.semantingModule
 				module.genInstances.Push( Self )
 			Endif
 
 		Else
+		
 			scope.transMembers.Push( Self )
+
 		Endif
 	End
 	
@@ -420,18 +429,6 @@ Class FuncValue Extends Value
 		Return args2
 	End
 
-	Method Used()
-	
-		If used Return
-		used=True
-		
-		If fdecl.kind<>"lambda" And types And Not fdecl.IsExtern
-			Local builder:=Builder.instance
-			builder.semantStmts.Push( Self )
-		Endif
-		
-	End
-	
 End
 
 '***** MemberFuncValue *****
@@ -513,7 +510,7 @@ Class FuncListValue Extends Value
 	
 	Method UpCast:Value( type:Type ) Override
 	
-		Local ftype:=Cast<FuncType>( type )
+		Local ftype:=TCast<FuncType>( type )
 		If Not ftype Throw New UpCastEx( Self,type )
 		
 		Local func:=flistType.FindOverload( ftype.retType,ftype.argTypes )
@@ -574,7 +571,7 @@ Class FuncListType Extends Type
 	
 	Method DistanceToType:Int( type:Type ) Override
 
-		Local ftype:=Cast<FuncType>( type )
+		Local ftype:=TCast<FuncType>( type )
 		If Not ftype Return -1
 		
 		Local func:=FindOverload( ftype.retType,ftype.argTypes )
@@ -617,9 +614,7 @@ Class FuncList Extends SNode
 		If AnyTypeGeneric( argTypes ) SemantError( "FuncList.FindFunc()" )
 	
 		For Local func:=Eachin funcs
-			If func.IsGeneric Continue
-'			If func.ftype.IsGeneric Continue
-'			If func.types And Not func.instanceOf Continue
+			If func.block.IsGeneric Continue
 			If TypesEqual( func.ftype.argTypes,argTypes ) Return func
 		Next
 		
@@ -640,7 +635,7 @@ Class FuncList Extends SNode
 				Local func:=Cast<FuncValue>( tfunc.Semant() )
 				If Not func Continue
 				
-				If Not func.IsGeneric
+				If Not func.block.IsGeneric
 					Local func2:=FindFunc( func.ftype.argTypes )
 					If func2 Throw New SemantEx( "Duplicate declaration '"+func.ToString()+"'",tfunc.pnode )
 				Endif

+ 19 - 15
src/mx2new/htmldocsmaker.monkey2

@@ -218,6 +218,25 @@ Class HtmlDocsMaker Extends DocsMaker
 	
 	End
 	
+	Method EmitAliases( scope:Scope,kind:String )
+	
+		For Local node:=Eachin scope.nodes
+		
+			Local atype:=Cast<AliasType>( node.Value )
+			If Not atype Or atype.adecl.kind<>kind Continue
+			
+			Local docs:=MakeAliasDocs( atype )
+			If Not docs Continue
+			
+			Local page:=DeclPage( atype.adecl,atype.scope )
+			SavePage( docs,page )
+			
+			EmitLeaf( atype.adecl,page )
+
+		Next
+	
+	End
+	
 	Method EmitEnums( scope:Scope,kind:String )
 	
 		For Local node:=Eachin scope.nodes
@@ -274,21 +293,6 @@ Class HtmlDocsMaker Extends DocsMaker
 	
 	End
 	
-	Method EmitAliases( scope:Scope,kind:String )
-	
-		For Local node:=Eachin scope.nodes
-		
-			Local atype:=Cast<AliasType>( node.Value )
-			If Not atype Or atype.scope.FindFile().fdecl.module<>_module Or atype.adecl.kind<>kind Continue
-			
-			If atype.adecl.IsPrivate And Not atype.adecl.docs Continue
-			
-			EmitLeaf( atype.adecl,"" )
-
-		Next
-	
-	End
-	
 	Method EmitFuncs( scope:Scope,kind:String )
 	
 		For Local node:=Eachin scope.nodes

+ 3 - 3
src/mx2new/module.monkey2

@@ -22,9 +22,9 @@ Class Module
 	Field usings:=New Stack<NamespaceScope>
 	Field main:FuncValue
 	
-	Field moduleDeps:=New Stack<String>
+	Field moduleDeps:=New StringMap<Bool>
 	
-	Method New( name:String,srcPath:String,productType:String )
+	Method New( name:String,srcPath:String,productType:String,version:String )
 		Self.name=name
 		Self.srcPath=srcPath
 		Self.productType=productType
@@ -33,7 +33,7 @@ Class Module
 		
 		ident=MungPath( name )
 		baseDir=ExtractDir( srcPath )
-		buildDir=baseDir+name+".buildv"+MX2_BUILDV+"/"
+		buildDir=baseDir+name+".buildv"+version+"/"
 		outputDir=buildDir+builder.profileName+"/"
 		cacheDir=buildDir+"build_cache/"+builder.profileName+"/"
 		

+ 11 - 10
src/mx2new/mung.monkey2

@@ -39,10 +39,11 @@ End
 
 Function MungArg:String( type:Type )
 
-	If type=Type.VoidType Return "v"
+	If type.Dealias=Type.VoidType Return "v"
 	
-	If Cast<PrimType>( type )
-		Select type
+	Local ptype:=TCast<PrimType>( type )
+	If ptype
+		Select ptype
 		Case Type.BoolType	Return "z"
 		Case Type.ByteType	Return "b"
 		Case Type.UByteType	Return "c"
@@ -59,14 +60,14 @@ Function MungArg:String( type:Type )
 		Return "????? MungArg ?????"
 	End
 	
-	Local atype:=Cast<ArrayType>( type )
+	Local atype:=TCast<ArrayType>( type )
 	If atype
 		Local sym:="A"
 		If atype.rank>1 sym+=String( atype.rank )
 		Return sym+MungArg( atype.elemType )
 	Endif
 	
-	Local ftype:=Cast<FuncType>( type )
+	Local ftype:=TCast<FuncType>( type )
 	If ftype
 		Local sym:="F"+MungArg( ftype.retType )
 		For Local ty:=Eachin ftype.argTypes
@@ -75,14 +76,14 @@ Function MungArg:String( type:Type )
 		Return sym+"E"
 	Endif
 	
-	Local ctype:=Cast<ClassType>( type )
+	Local ctype:=TCast<ClassType>( type )
 	If ctype
 		Return "T"+ClassName( ctype )+"_2"
 	Endif
 
-	Local ptype:=Cast<PointerType>( type )
-	If ptype
-		Return "P"+MungArg( ptype.elemType )
+	Local qtype:=TCast<PointerType>( type )
+	If qtype
+		Return "P"+MungArg( qtype.elemType )
 	Endif
 	
 	Return "????? MungArg "+String.FromCString( type.typeName() )+" ?????"
@@ -92,7 +93,7 @@ Function MungArgs:String( types:Type[] )
 
 	Local sym:="_1"
 	For Local ty:=Eachin types
-		If Cast<GenArgType>( ty ) Continue
+		If TCast<GenArgType>( ty ) Continue
 		sym+=MungArg( ty )
 	Next
 	Return sym

+ 4 - 3
src/mx2new/mx2.monkey2

@@ -39,7 +39,8 @@ Using std.chartype
 Using std.filesystem
 Using std.collections
 Using lib.c
-'Using libc
 
-Const MX2CC_VERSION:="002"
-Const MX2_BUILDV:="002"
+Const MX2CC_VERSION:="003"
+
+Global MX2_MODULES_VERSION:=""
+Global MX2_PRODUCT_VERSION:=""

+ 29 - 3
src/mx2new/mx2cc.monkey2

@@ -19,14 +19,22 @@ Using libc
 
 Global StartDir:String
 
-Const TestArgs:="mx2cc makedocs monkey libc std"
+Const TestArgs:="mx2cc makemods -clean"
+
+'Const TestArgs:="mx2cc makeapp src/mx2new/test.monkey2"
+
+'Const TestArgs:="mx2cc makeapp tests/monkey/generics.monkey2"
+
+'Const TestArgs:="mx2cc makedocs monkey libc std"
+
+'Const TestArgs:="mx2cc makemods -clean"
+
+'Const TestArgs:="mx2cc makeapp src/mx2new/test.monkey2"
 
 'Const TestArgs:="mx2cc makemods -verbose -clean -target=emscripten -config=debug"
 
 'Const TestArgs:="mx2cc makemods -verbose -clean -config=release"
 
-'Const TestArgs:="mx2cc makeapp -target=desktop -target=emscripten -config=debug src/mx2new/test.monkey2"
-
 'Const TestArgs:="mx2cc makeapp -verbose -target=desktop -config=release src/mx2new/mx2cc.monkey2"
 
 'Const TestArgs:="mx2cc makemods"
@@ -50,6 +58,24 @@ Function Main()
 	
 	LoadEnv( env )
 	
+	MX2_PRODUCT_VERSION=GetEnv( "MX2_PRODUCT_VERSION" )
+	If MX2_PRODUCT_VERSION
+		If MX2_PRODUCT_VERSION<>MX2CC_VERSION
+			Print "MX2_PRODUCT_VERSION="+MX2_PRODUCT_VERSION
+		Endif
+	Else
+		MX2_PRODUCT_VERSION=MX2CC_VERSION
+	Endif
+	
+	MX2_MODULES_VERSION=GetEnv( "MX2_MODULES_VERSION" )
+	If MX2_MODULES_VERSION
+		If MX2_MODULES_VERSION<>MX2CC_VERSION
+			Print "MX2_MODULES_VERSION="+MX2_MODULES_VERSION
+		Endif
+	Else
+		MX2_MODULES_VERSION=MX2CC_VERSION
+	Endif
+	
 	Local args:=AppArgs()
 	
 	If args.Length<2

+ 3 - 3
src/mx2new/overload.monkey2

@@ -33,9 +33,9 @@ Function IsCandidate:Bool( func:FuncValue,ret:Type,args:Type[],infered:Type[] )
 		
 			Local arg:=args[i]
 			
-			Local flist:=Cast<FuncListType>( arg )
+			Local flist:=TCast<FuncListType>( arg )
 			If flist
-				Local ftype:=Cast<FuncType>( argTypes[i] )
+				Local ftype:=TCast<FuncType>( argTypes[i] )
 				If Not ftype Return False
 				Local func:=flist.FindOverload( Null,ftype.argTypes )'ftype.retType,ftype.argTypes )
 				If Not func Return False
@@ -132,7 +132,7 @@ Function Linearize( types:Type[],func:FuncValue,funcs:Stack<FuncValue>,j:Int=0 )
 	
 		Local type:=types[i]
 	
-		Local flist:=Cast<FuncListType>( type )
+		Local flist:=TCast<FuncListType>( type )
 		If Not flist Continue
 		
 		types=types.Slice( 0 )

+ 3 - 0
src/mx2new/parser.monkey2

@@ -204,6 +204,7 @@ Class Parser
 				decl.flags=flags
 				decl.ident=ParseIdent()
 				decl.idscope=_idscope
+				decl.genArgs=ParseGenArgs()
 				
 				Parse( ":" )
 				decl.type=ParseType()
@@ -389,6 +390,8 @@ Class Parser
 					ident=Parse()
 				Case "<",">","<=",">=","=","<>","<=>"
 					ident=Parse()
+				Case "cast"
+					ident=Parse()
 				Case "["
 					Bump()
 					Parse( "]" )

+ 4 - 4
src/mx2new/stmtexpr.monkey2

@@ -170,7 +170,7 @@ Class InvokeNewStmtExpr Extends StmtExpr
 		Local value:=expr.SemantRValue( block )
 		If Not Cast<SelfValue>( value ) And Not Cast<SuperValue>( value ) Throw New SemantEx( "'New' cannot be directly invoked" )
 
-		Local ctype:=Cast<ClassType>( value.type )
+		Local ctype:=TCast<ClassType>( value.type )
 		
 		Local func:=block.func
 
@@ -351,7 +351,7 @@ Class IfStmtExpr Extends StmtExpr
 			
 			tblock.Semant( expr.stmts )
 			
-			Local curr:=New IfStmt( Self,cond,tblock )
+			Local curr:=New IfStmt( expr,cond,tblock )
 			If prev prev.succ=curr Else head=curr
 			prev=curr
 			
@@ -570,7 +570,7 @@ Class ForStmtExpr Extends StmtExpr
 		Local curr:Value
 		Local init:=Self.init.SemantRValue( iblock )
 		
-		Local atype:=Cast<ArrayType>( init.type )
+		Local atype:=TCast<ArrayType>( init.type )
 		If atype And atype.rank<>1 Throw New SemantEx( "'Eachin' can only be used with 1 dimensional arrays" )
 		
 		If atype Or init.type=Type.StringType
@@ -769,7 +769,7 @@ Class ThrowStmtExpr Extends StmtExpr
 		If expr
 		
 			Local value:=expr.SemantRValue( block )
-			Local ctype:=Cast<ClassType>( value.type )
+			Local ctype:=TCast<ClassType>( value.type )
 			
 			If Not ctype 'Or Not ctype.ExtendsType( Type.ThrowableClass )
 				Throw New SemantEx( "Thrown value type must extend 'Throwable'" )

+ 3 - 12
src/mx2new/test.monkey2

@@ -1,18 +1,9 @@
 
 Namespace test
 
-#Import "<libc>"
-
-Function Test2()
-	Print "Debug Stack:"
-	Print "~n".Join( GetDebugStack() )
-End
-
-Function Test()
-	Test2()
-End
+#Import "<std>"
+#Import "<mojo2>"
 
 Function Main()
-	Test()
-	Print "Bye!"
+	Print "Yes"
 End

+ 10 - 10
src/mx2new/translator.monkey2

@@ -5,11 +5,11 @@ Namespace mx2
 
 Function IsGCType:Bool( type:Type )
 
-	If Cast<FuncType>( type ) Return True
+	If TCast<FuncType>( type ) Return True
 	
-	If Cast<ArrayType>( type ) Return True
+	If TCast<ArrayType>( type ) Return True
 	
-	Local ctype:=Cast<ClassType>( type )
+	Local ctype:=TCast<ClassType>( type )
 	If Not ctype Return False
 	
 	If ctype.IsVoid Return False
@@ -381,7 +381,7 @@ Class Translator
 	
 	Method Refs( type:Type )
 	
-		Local ctype:=Cast<ClassType>( type )
+		Local ctype:=TCast<ClassType>( type )
 		If ctype
 			If IsStruct( ctype ) Uses( ctype ) ; Return
 			If AddRef( ClassName( ctype ),ctype ) Return
@@ -389,7 +389,7 @@ Class Translator
 			Return
 		Endif
 		
-		Local ftype:=Cast<FuncType>( type )
+		Local ftype:=TCast<FuncType>( type )
 		If ftype
 			Refs( ftype.retType )
 			For Local type:=Eachin ftype.argTypes
@@ -398,13 +398,13 @@ Class Translator
 			Return
 		Endif
 		
-		Local atype:=Cast<ArrayType>( type )
+		Local atype:=TCast<ArrayType>( type )
 		If atype
 			Refs( atype.elemType )
 			Return
 		Endif
 		
-		Local ptype:=Cast<PointerType>( type )
+		Local ptype:=TCast<PointerType>( type )
 		If ptype
 			Refs( ptype.elemType )
 			Return
@@ -413,7 +413,7 @@ Class Translator
 	End
 	
 	Method Uses( type:Type )
-		Local ctype:=Cast<ClassType>( type )
+		Local ctype:=TCast<ClassType>( type )
 		If ctype Uses( ctype )
 	End
 	
@@ -430,13 +430,13 @@ Class Translator
 
 	Method IsStruct:Bool( type:Type )
 
-		Local ctype:=Cast<ClassType>( type )
+		Local ctype:=TCast<ClassType>( type )
 		Return ctype And ctype.cdecl.kind="struct"
 	End
 	
 	Method IsValue:Bool( type:Type )
 	
-		Return Cast<PrimType>( type ) Or Cast<FuncType>( type ) Or IsStruct( type )
+		Return TCast<PrimType>( type ) Or TCast<FuncType>( type ) Or IsStruct( type )
 	End
 	
 	Method CFuncType:String( type:FuncType )

+ 45 - 27
src/mx2new/translator_cpp.monkey2

@@ -119,10 +119,10 @@ Class Translator_CPP Extends Translator
 	
 	Method VarType:String( type:Type )
 	
-		Local ctype:=Cast<ClassType>( type )
+		Local ctype:=TCast<ClassType>( type )
 		If ctype And IsGCType( ctype ) Return "bbGCVar<"+ClassName( ctype )+">"
 		
-		Local atype:=Cast<ArrayType>( type )
+		Local atype:=TCast<ArrayType>( type )
 		If atype Return "bbGCVar<"+ArrayName( atype )+">"
 		
 		Return TransType( type )
@@ -565,7 +565,7 @@ Class Translator_CPP Extends Translator
 			Emit( "done=true;" )
 			
 			Local builder:=Builder.instance
-			For Local dep:=Eachin module.moduleDeps
+			For Local dep:=Eachin module.moduleDeps.Keys
 			
 				Local mod2:=builder.modulesMap[dep]
 				If Not mod2.main Continue
@@ -686,11 +686,21 @@ Class Translator_CPP Extends Translator
 	
 	'***** Stmt *****
 	
+	Method DebugInfo:String( stmt:Stmt )
+		If debug And stmt.pnode Return "bbDBStmt("+stmt.pnode.srcpos+")"
+		Return ""
+	End
+	
+	Method EmitDebugInfo( stmt:Stmt )
+		Local db:=DebugInfo( stmt )
+		If db Emit( db+";" )
+	End
+	
 	Method EmitStmt( stmt:Stmt )
 	
 		If Not stmt Return
 		
-		If debug And stmt.pnode Emit( "bbDBStmt("+stmt.pnode.srcpos+");" )
+		EmitDebugInfo( stmt )
 		
 		Local exitStmt:=Cast<ExitStmt>( stmt )
 		If exitStmt EmitStmt( exitStmt ) ; Return
@@ -803,7 +813,7 @@ Class Translator_CPP Extends Translator
 		Local lhs:=Trans( stmt.lhs )
 		Local rhs:=Trans( stmt.rhs )
 
-		Local etype:=Cast<EnumType>( stmt.lhs.type )
+		Local etype:=TCast<EnumType>( stmt.lhs.type )
 		If etype And etype.edecl.IsExtern
 			If op<>"="
 				If stmt.lhs.HasSideEffects Print "Danger Will Robinson!!!!!!"
@@ -827,12 +837,18 @@ Class Translator_CPP Extends Translator
 		EmitBlock( stmt.block )
 		
 		While stmt.succ
+		
 			stmt=stmt.succ
+			
 			If stmt.cond
-				Emit( "}else if("+Trans( stmt.cond )+"){" )
+				Local db:=DebugInfo( stmt )
+				If db db+=","
+				Emit( "}else if("+db+Trans( stmt.cond )+"){" )
 			Else
 				Emit( "}else{" )
+				EmitDebugInfo( stmt )
 			Endif
+			
 			EmitBlock( stmt.block )
 		Wend
 
@@ -1020,7 +1036,7 @@ Class Translator_CPP Extends Translator
 	
 	Method Trans:String( value:UpCastValue )
 	
-		Local ctype:=Cast<ClassType>( value.value.type )
+		Local ctype:=TCast<ClassType>( value.value.type )
 		If ctype Uses( ctype )
 		
 		Local t:="("+Trans( value.value )+")"
@@ -1032,7 +1048,7 @@ Class Translator_CPP Extends Translator
 	
 	Method Trans:String( value:ExplicitCastValue )
 	
-		Local ctype:=Cast<ClassType>( value.type )
+		Local ctype:=TCast<ClassType>( value.type )
 		If ctype 
 			Uses( ctype )
 			Return "bb_object_cast<"+ClassName( ctype )+"*>("+Trans( value.value )+")"
@@ -1047,7 +1063,7 @@ Class Translator_CPP Extends Translator
 	
 	Method TransNull:String( type:Type )
 	
-		Local ptype:=Cast<PrimType>( type )
+		Local ptype:=TCast<PrimType>( type )
 		If ptype
 			If ptype.IsIntegral Return "0"
 			If ptype=Type.FloatType Return ".0f"
@@ -1055,7 +1071,7 @@ Class Translator_CPP Extends Translator
 			If ptype=Type.BoolType Return "false"
 		Endif
 
-		Local etype:=Cast<EnumType>( type )
+		Local etype:=TCast<EnumType>( type )
 		If etype Return EnumName( etype )+"(0)"
 
 		If IsValue( type ) Return TransType( type )+"{}"
@@ -1067,17 +1083,18 @@ Class Translator_CPP Extends Translator
 	
 		If Not value.value Return TransNull( value.type )
 		
-		Select value.type
+		Local ptype:=TCast<PrimType>( value.type )
+		Select ptype
 		Case Type.FloatType,Type.DoubleType
 			Local t:=value.value
 			If t.Find( "." )=-1 And t.Find( "e" )=-1 And t.Find( "E" )=-1 t+=".0"
-			If value.type=Type.FloatType Return t+"f"
+			If ptype=Type.FloatType Return t+"f"
 			Return t
 		Case Type.StringType
 			Return "BB_T("+EnquoteCppString( value.value )+")"
 		End
 		
-		Local etype:=Cast<EnumType>( value.type )
+		Local etype:=TCast<EnumType>( value.type )
 		If etype Return EnumValueName( etype,value.value )
 		
 		If value.value="0" Return TransType( value.type )+"(0)"
@@ -1098,11 +1115,11 @@ Class Translator_CPP Extends Translator
 	
 	Method TransMember:String( instance:Value,member:Value )
 	
-		Local ctype:=Cast<ClassType>( instance.type )
+		Local ctype:=TCast<ClassType>( instance.type )
 		If ctype Uses( ctype )
 
 		Local supr:=Cast<SuperValue>( instance )
-		If supr Return ClassName( Cast<ClassType>( supr.type ) )+"::"+Trans( member )
+		If supr Return ClassName( TCast<ClassType>( supr.type ) )+"::"+Trans( member )
 		
 		Local tinst:=Trans( instance )
 		Local tmember:=Trans( member )
@@ -1195,7 +1212,7 @@ Class Translator_CPP Extends Translator
 		
 		Local t:=op+Trans( value.value )
 		
-		Local etype:=Cast<EnumType>( value.type )
+		Local etype:=TCast<EnumType>( value.type )
 		If etype And etype.edecl.IsExtern t=EnumName( etype )+"("+t+")"
 		
 		Return t
@@ -1212,12 +1229,13 @@ Class Translator_CPP Extends Translator
 		
 			If op="=" op="==" Else If op="<>" op="!="
 			
-			If IsStruct( value.lhs.type ) Or (Cast<FuncType>( value.lhs.type ) And op<>"==" And op<>"!=" )
+			If IsStruct( value.lhs.type ) Or (TCast<FuncType>( value.lhs.type ) And op<>"==" And op<>"!=" )
 				Return "(bbCompare("+Trans( value.lhs )+","+Trans( value.rhs )+")"+op+"0)"
 			Endif
 			
 		Case "mod"
-			If value.type=Type.FloatType Or value.type=Type.DoubleType Return "std::fmod("+Trans( value.lhs )+","+Trans( value.rhs )+")"
+			Local ptype:=TCast<PrimType>( value.type )
+			If ptype=Type.FloatType Or ptype=Type.DoubleType Return "std::fmod("+Trans( value.lhs )+","+Trans( value.rhs )+")"
 			op="%"
 		Case "and" op="&&"
 		Case "or" op="||"
@@ -1228,7 +1246,7 @@ Class Translator_CPP Extends Translator
 		
 		Local t:="("+Trans( value.lhs )+op+Trans( value.rhs )+")"
 		
-		Local etype:=Cast<EnumType>( value.type )
+		Local etype:=TCast<EnumType>( value.type )
 		If etype And etype.edecl.IsExtern t=EnumName( etype )+t
 		
 		Return t
@@ -1296,27 +1314,27 @@ Class Translator_CPP Extends Translator
 	
 	Method TransType:String( type:Type ) Override
 	
-		If type=Type.VoidType Return "void"
+		If TCast<VoidType>( type ) Return "void"
 	
-		Local classType:=Cast<ClassType>( type )
+		Local classType:=TCast<ClassType>( type )
 		If classType Return TransType( classType )
 		
-		Local enumType:=Cast<EnumType>( type )
+		Local enumType:=TCast<EnumType>( type )
 		If enumType Return TransType( enumType )
 	
-		Local primType:=Cast<PrimType>( type )
+		Local primType:=TCast<PrimType>( type )
 		If primType Return TransType( primType )
 		
-		Local funcType:=Cast<FuncType>( type )
+		Local funcType:=TCast<FuncType>( type )
 		If funcType Return TransType( funcType )
 		
-		Local arrayType:=Cast<ArrayType>( type )
+		Local arrayType:=TCast<ArrayType>( type )
 		If arrayType Return TransType( arrayType )
 		
-		Local pointerType:=Cast<PointerType>( type )
+		Local pointerType:=TCast<PointerType>( type )
 		If pointerType Return TransType( pointerType )
 		
-		Local genArgType:=Cast<GenArgType>( type )
+		Local genArgType:=TCast<GenArgType>( type )
 		If genArgType Return TransType( genArgType )
 		
 		Throw New TransEx( "Translator_CPP.Trans() Type '"+String.FromCString( type.typeName() )+"' not recognized" )

+ 117 - 22
src/mx2new/type.monkey2

@@ -33,17 +33,40 @@ Class Type Extends SNode
 	
 	Global ExceptionClass:ClassType
 	
+	Field _alias:Type
 	Field flags:Int
 	
+	Method New()
+		_alias=Self
+	End
+	
+	Property Dealias:Type()
+		Return _alias
+	End
+	
 	Property IsGeneric:Bool()
 		Return flags & TYPE_GENERIC
 	End
 	
-	Property Name:String() Abstract
+	'Not nice - should fix comparison ops
+	Operator=:Bool( type:Type )
+		If Not Self Return Object(type)=Null
+		If type Return Object(type._alias)=_alias
+		Return _alias=Null
+	End
 	
-	Property TypeId:String() Abstract
+	Operator<>:Bool( type:Type )
+		If Not Self Return Object(type)<>Null
+		If type Return Object(type._alias)<>_alias
+		Return _alias<>Null
+	End
 	
-	Method ToType:Type() Override
+	Operator<=>:Int( type:Type )
+		SemantError( "Type.Operator<=>()" )
+		Return 0
+	End
+	
+	Method ToType:Type() Override Final
 		Return Self
 	End
 
@@ -51,6 +74,10 @@ Class Type Extends SNode
 		Return New TypeValue( Self )
 	End
 	
+	Property Name:String() Abstract
+	
+	Property TypeId:String() Abstract
+	
 	Method FindNode:SNode( ident:String ) Virtual
 		Return Null
 	End
@@ -96,7 +123,77 @@ Class Type Extends SNode
 	Method CanCastToType:Bool( type:Type ) Virtual
 		Return DistanceToType( type )>=0 Or type.CanCastToType( Self )
 	End
+End
+
+Class ProxyType Extends Type
+
+	Property Name:String() Override
+		Return _alias.Name
+	End
+	
+	Property TypeId:String() Override
+		Return _alias.TypeId
+	End
+	
+	Method ToString:String() Override
+		Return _alias.ToString()
+	End
+	
+	Method ToValue:Value( instance:Value ) Override
+		Return _alias.ToValue( instance )
+	End
+	
+	Method FindNode:SNode( ident:String ) Override
+		Return _alias.FindNode( ident )
+	End
 	
+	Method FindType:Type( ident:String ) Override
+		Return _alias.FindType( ident )
+	End
+	
+	Method Invoke:Value( args:Value[],value:Value ) Override
+		Return _alias.Invoke( args,value )
+	End
+	
+	Method Index:Value( args:Value[],value:Value ) Override
+		Return _alias.Index( args,value )
+	End
+	
+	Method GenInstance:Type( types:Type[] ) Override
+		Return _alias.GenInstance( types )
+	End
+	
+	Method Equals:Bool( type:Type ) Override
+		Return _alias.Equals( type )
+	End
+	
+	Method ExtendsType:Bool( type:Type ) Override
+		Return _alias.ExtendsType( type )
+	End
+	
+	Method DistanceToType:Int( type:Type ) Override
+		Return _alias.DistanceToType( type )
+	End
+	
+	Method InferType:Type( type:Type,args:Type[] ) Override
+		Return _alias.InferType( type,args )
+	End
+	
+	Method CanCastToType:Bool( type:Type ) Override
+		Return _alias.CanCastToType( type )
+	End
+	
+End
+
+Function TCast<T>:T( type:Type )
+	If type Return Cast<T>( type._alias )
+	Return Null
+End
+
+Function TCast<T>:T( node:SNode )
+	Local type:=Cast<Type>( node )
+	If type Return Cast<T>( type._alias )
+	Return Null
 End
 
 Class PrimType Extends Type
@@ -156,7 +253,7 @@ Class PrimType Extends Type
 	
 		If type=Self Return 0
 
-		Local ptype:=Cast<PrimType>( type )
+		Local ptype:=TCast<PrimType>( type )
 		If ptype
 			If ptype=BoolType Return MAX_DISTANCE
 			If IsNumeric And (ptype=StringType Or ptype.IsNumeric) Return MAX_DISTANCE
@@ -168,8 +265,6 @@ Class PrimType Extends Type
 			Return MAX_DISTANCE
 		End
 		
-'		If ExtendsType( type ) Return MAX_DISTANCE
-		
 		Return -1
 	End
 	
@@ -229,7 +324,7 @@ Class ArrayType Extends Type
 		If Not IsGeneric
 			Local types:=New Type[1]
 			types[0]=elemType
-			ctype=Cast<ClassType>( ctype.GenInstance( types ) )
+			ctype=TCast<ClassType>( ctype.GenInstance( types ) )
 		Endif
 		
 		If Not ctype SemantError( "ArrayType.New()" )
@@ -276,7 +371,7 @@ Class ArrayType Extends Type
 	
 		If type=Self Or type=ctype Return True
 	
-		Local atype:=Cast<ArrayType>( type )
+		Local atype:=TCast<ArrayType>( type )
 		Return atype And rank=atype.rank And elemType.Equals( atype.elemType )
 	End
 	
@@ -284,7 +379,7 @@ Class ArrayType Extends Type
 	
 		If Equals( type ) Return 0
 		
-		If type=BoolType Return MAX_DISTANCE
+		If TCast<PrimType>( type )=BoolType Return MAX_DISTANCE
 		
 		Return -1
 	End
@@ -293,7 +388,7 @@ Class ArrayType Extends Type
 	
 		If Not IsGeneric Return Super.InferType( type,infered )
 		
-		Local atype:=Cast<ArrayType>( type )
+		Local atype:=TCast<ArrayType>( type )
 		If Not atype Or rank<>atype.rank Return Null
 		
 		Local elemType:=Self.elemType.InferType( atype.elemType,infered )
@@ -338,7 +433,7 @@ Class PointerType Extends Type
 	
 		If type=Self Return True
 	
-		Local ptype:=Cast<PointerType>( type )
+		Local ptype:=TCast<PointerType>( type )
 		Return ptype And elemType.Equals( ptype.elemType )
 	End
 	
@@ -346,9 +441,9 @@ Class PointerType Extends Type
 	
 		If type=Self Return 0
 		
-		If type=Type.BoolType Return MAX_DISTANCE
+		If type.Dealias=BoolType Return MAX_DISTANCE
 		
-		Local ptype:=Cast<PointerType>( type )
+		Local ptype:=TCast<PointerType>( type )
 		If Not ptype Return -1
 		
 		If elemType.Equals( ptype.elemType ) Return 0
@@ -361,9 +456,9 @@ Class PointerType Extends Type
 	
 	Method CanCastToType:Bool( type:Type ) Override
 	
-		If Cast<PointerType>( type ) Return True
+		If TCast<PointerType>( type ) Return True
 		
-		Local ptype:=Cast<PrimType>( type )
+		Local ptype:=TCast<PrimType>( type )
 		If ptype And ptype.IsIntegral Return True
 		
 		Return False
@@ -373,7 +468,7 @@ Class PointerType Extends Type
 	
 		If Not IsGeneric Return Super.InferType( type,infered )
 	
-		Local ptype:=Cast<PointerType>( type )
+		Local ptype:=TCast<PointerType>( type )
 		If Not ptype Return Null
 		
 		Local elemType:=Self.elemType.InferType( ptype.elemType,infered )
@@ -436,7 +531,7 @@ Class FuncType Extends Type
 	
 		If type=Self Return True
 	
-		Local ftype:=Cast<FuncType>( type )
+		Local ftype:=TCast<FuncType>( type )
 		If Not ftype Or argTypes.Length<>ftype.argTypes.Length Return False
 		
 		Return retType.Equals( ftype.retType ) And TypesEqual( argTypes,ftype.argTypes )
@@ -446,7 +541,7 @@ Class FuncType Extends Type
 	
 		If Equals( type ) Return 0
 		
-		If type=BoolType Return MAX_DISTANCE
+		If type.Dealias Return MAX_DISTANCE
 		
 		Return -1
 	End
@@ -455,7 +550,7 @@ Class FuncType Extends Type
 	
 		If Not IsGeneric Return Super.InferType( type,infered )
 		
-		Local ftype:=Cast<FuncType>( type )
+		Local ftype:=TCast<FuncType>( type )
 		If Not ftype Or argTypes.Length<>ftype.argTypes.Length Return Null
 		
 		Local retType:=Self.retType.InferType( ftype.retType,infered )
@@ -523,7 +618,7 @@ Class GenArgType Extends Type
 	
 		If type=Self Return True
 		
-		Local gtype:=Cast<GenArgType>( type )
+		Local gtype:=TCast<GenArgType>( type )
 	
 		If Not gtype Or ident<>gtype.ident Return False
 		
@@ -540,8 +635,8 @@ Class GenArgType Extends Type
 	
 		If types
 		
-			Local ctype:=Cast<ClassType>( type )
-			Local gtype:=Cast<GenArgType>( type )
+			Local ctype:=TCast<ClassType>( type )
+			Local gtype:=TCast<GenArgType>( type )
 			
 			Local gtypes:Type[]
 			

+ 7 - 7
src/mx2new/value.monkey2

@@ -110,7 +110,7 @@ Class Value Extends SNode
 
 		If op="=" Return True
 
-		Local ptype:=Cast<PrimType>( type )
+		Local ptype:=TCast<PrimType>( type )
 		If ptype
 			Select op
 			Case "+=" Return ptype=Type.StringType Or ptype.IsNumeric
@@ -122,9 +122,9 @@ Class Value Extends SNode
 			Return False
 		Endif
 		
-		If Cast<EnumType>( type ) Return op="&=" Or op="|=" Or op="~="
+		If TCast<EnumType>( type ) Return op="&=" Or op="|=" Or op="~="
 		
-		If Cast<FuncType>( type ) Return op="+=" Or op="-="
+		If TCast<FuncType>( type ) Return op="+=" Or op="-="
 		
 		Return False
 	End
@@ -258,11 +258,11 @@ Class LiteralValue Extends Value
 		If d=0 Return Self
 		
 		'upcast to...
-		Local ptype:=Cast<PrimType>( type )
+		Local ptype:=TCast<PrimType>( type )
 		If Not ptype Return New UpCastValue( type,Self )
 '		If Not ptype SemantError( "LiteralValue.UpCast()" )
 		
-		Local ptype2:=Cast<PrimType>( Self.type )
+		Local ptype2:=TCast<PrimType>( Self.type )
 		If Not ptype2 Return New UpCastValue( type,Self )
 '		If Not ptype2 SemantError( "LiteralValue.UpCast()" )
 		
@@ -307,7 +307,7 @@ Class LiteralValue Extends Value
 	End
 	
 	Property HasSideEffects:Bool() Override
-		Return type=Type.StringType
+		Return type.Dealias=Type.StringType
 	End
 	
 	Method RemoveSideEffects:Value( block:Block ) Override
@@ -353,7 +353,7 @@ Class InvokeValue Extends Value
 	Field args:Value[]
 	
 	Method New( value:Value,args:Value[] )
-		Self.ftype=Cast<FuncType>( value.type )
+		Self.ftype=TCast<FuncType>( value.type )
 		Self.type=ftype.retType
 		Self.value=value
 		Self.args=args