Jelajahi Sumber

Merge remote-tracking branch 'origin/master' into bcc_gen

woollybah 8 tahun lalu
induk
melakukan
739b05c826

+ 1 - 1
COPYING.md

@@ -1,4 +1,4 @@
-Copyright (c) 2013-2015 Bruce A Henderson
+Copyright (c) 2013-2017 Bruce A Henderson
 
 
 This software is provided 'as-is', without any express or implied
 This software is provided 'as-is', without any express or implied
 warranty. In no event will the authors be held liable for any damages
 warranty. In no event will the authors be held liable for any damages

+ 3 - 0
TODO.md

@@ -1,5 +1,8 @@
 #TODO
 #TODO
 
 
+## Access Modifiers
+Allowing use of Private/Public for Type members.
+
 ##Documentation
 ##Documentation
 Need some user-friendly documentation for installing and configuration.
 Need some user-friendly documentation for installing and configuration.
 Details for each platform, notes on cross-compilation, etc.
 Details for each platform, notes on cross-compilation, etc.

+ 1 - 1
base.configmap.bmx

@@ -1,4 +1,4 @@
-' Copyright (c) 2013-2016 Ronny Otto
+' Copyright (c) 2013-2017 Ronny Otto
 ' 
 ' 
 ' This software is provided 'as-is', without any express or implied
 ' This software is provided 'as-is', without any express or implied
 ' warranty. In no event will the authors be held liable for any damages
 ' warranty. In no event will the authors be held liable for any damages

+ 2 - 2
base.stringhelper.bmx

@@ -1,5 +1,5 @@
-' Copyright (c) 2014-2016 Bruce A Henderson
-' Copyright (c) 2014-2016 Ronny Otto
+' Copyright (c) 2014-2017 Bruce A Henderson
+' Copyright (c) 2014-2017 Ronny Otto
 '
 '
 ' This software is provided 'as-is', without any express or implied
 ' This software is provided 'as-is', without any express or implied
 ' warranty. In no event will the authors be held liable for any damages
 ' warranty. In no event will the authors be held liable for any damages

+ 1 - 1
bcc.bmx

@@ -1,4 +1,4 @@
-' Copyright (c) 2013-2016 Bruce A Henderson
+' Copyright (c) 2013-2017 Bruce A Henderson
 '
 '
 ' Based on the public domain Monkey "trans" by Mark Sibly
 ' Based on the public domain Monkey "trans" by Mark Sibly
 '
 '

+ 14 - 1
config.bmx

@@ -1,4 +1,4 @@
-' Copyright (c) 2013-2016 Bruce A Henderson
+' Copyright (c) 2013-2017 Bruce A Henderson
 '
 '
 ' Based on the public domain Monkey "trans" by Mark Sibly
 ' Based on the public domain Monkey "trans" by Mark Sibly
 '
 '
@@ -47,6 +47,9 @@ Global OBJECT_BASE_OFFSET:Int = 8
 ' 4 bytes on 32-bit, 8 bytes on 64-bit
 ' 4 bytes on 32-bit, 8 bytes on 64-bit
 Global POINTER_SIZE:Int = 4
 Global POINTER_SIZE:Int = 4
 
 
+Global _symbols$[]=[ "..","[]",":*",":/",":+",":-",":|",":&",":~~",":shr",":shl",":sar",":mod"]
+Global _symbols_map$[]=[ "..","[]","*=","/=","+=","-=","|=","&=","^=",">>=", "<<=",">>=","%=" ]
+
 Function PushErr( errInfo$ )
 Function PushErr( errInfo$ )
 	_errStack.AddLast _errInfo
 	_errStack.AddLast _errInfo
 	_errInfo=errInfo
 	_errInfo=errInfo
@@ -114,6 +117,16 @@ Function IsStandardFunc:Int(func:String)
 	Return funcs.Find(func) > 0
 	Return funcs.Find(func) > 0
 End Function
 End Function
 
 
+Function mapSymbol:String(sym:String)
+	For Local i:Int = 0 Until _symbols.length
+		If sym = _symbols[i] Then
+			Return _symbols_map[i]
+		End If
+	Next
+	Return sym
+End Function
+
+
 'enquote depending on ENV_LANG
 'enquote depending on ENV_LANG
 '
 '
 Function LangEnquote$( str$ )
 Function LangEnquote$( str$ )

File diff ditekan karena terlalu besar
+ 484 - 101
ctranslator.bmx


+ 306 - 76
decl.bmx

@@ -1,4 +1,4 @@
-' Copyright (c) 2013-2016 Bruce A Henderson
+' Copyright (c) 2013-2017 Bruce A Henderson
 '
 '
 ' Based on the public domain Monkey "trans" by Mark Sibly
 ' Based on the public domain Monkey "trans" by Mark Sibly
 '
 '
@@ -36,9 +36,11 @@ Const DECL_ARG:Int=         $800000
 Const DECL_INITONLY:Int=   $1000000
 Const DECL_INITONLY:Int=   $1000000
 
 
 Const DECL_NODEBUG:Int=    $2000000
 Const DECL_NODEBUG:Int=    $2000000
+Const DECL_PROTECTED:Int=  $4000000
 
 
-Const DECL_API_WIN32:Int= $10000000
-Const DECL_API_OS:Int=DECL_API_WIN32
+Const DECL_API_CDECL:Int=   $00000000
+Const DECL_API_STDCALL:Int= $10000000
+Const DECL_API_DEFAULT:Int= DECL_API_CDECL
 
 
 Const CLASS_INTERFACE:Int=  $001000
 Const CLASS_INTERFACE:Int=  $001000
 Const CLASS_THROWABLE:Int=  $002000
 Const CLASS_THROWABLE:Int=  $002000
@@ -50,6 +52,10 @@ Const SCOPE_CLASS_HEIRARCHY:Int = 2
 Const SCOPE_MODULE:Int = 3
 Const SCOPE_MODULE:Int = 3
 Const SCOPE_ALL:Int = 4
 Const SCOPE_ALL:Int = 4
 
 
+'Const CALL_CONV_CDECL:Int = 0
+'Const CALL_CONV_STDCALL:Int = 1
+'Const CALL_CONV_DEFAULT:Int = CALL_CONV_CDECL
+
 Global _env:TScopeDecl
 Global _env:TScopeDecl
 Global _envStack:TList=New TList
 Global _envStack:TList=New TList
 
 
@@ -139,9 +145,21 @@ Type TDecl
 		Return (attrs & DECL_EXTERN)<>0
 		Return (attrs & DECL_EXTERN)<>0
 	End Method
 	End Method
 	
 	
+	Method IsFinal:Int()
+		Return (attrs & DECL_FINAL)<>0
+	End Method
+
 	Method IsPrivate:Int()
 	Method IsPrivate:Int()
 		Return (attrs & DECL_PRIVATE)<>0
 		Return (attrs & DECL_PRIVATE)<>0
 	End Method
 	End Method
+
+	Method IsProtected:Int()
+		Return (attrs & DECL_PROTECTED)<>0
+	End Method
+	
+	Method IsPublic:Int()
+		Return Not (IsPrivate() Or IsProtected())
+	End Method
 	
 	
 	Method IsAbstract:Int()
 	Method IsAbstract:Int()
 		Return (attrs & DECL_ABSTRACT)<>0
 		Return (attrs & DECL_ABSTRACT)<>0
@@ -188,7 +206,11 @@ Type TDecl
 	
 	
 	Method AssertAccess()
 	Method AssertAccess()
 		If Not CheckAccess()
 		If Not CheckAccess()
-			Err ToString() +" is private."
+			If IsPrivate() Then
+				Err ToString() +" is private."
+			Else
+				Err ToString() +" is protected."
+			End If
 		EndIf
 		EndIf
 	End Method
 	End Method
 
 
@@ -311,15 +333,22 @@ Type TValDecl Extends TDecl
 	End Method
 	End Method
 	
 	
 	Method OnSemant()
 	Method OnSemant()
-
+	
 		If declTy
 		If declTy
+
+			Local at:TType = TArrayType(declTy)
+			
+			While TArrayType(at)
+				at = TArrayType(at).elemType
+			Wend
+		
 			' ensure to set the scope for a function pointer array before semanting
 			' ensure to set the scope for a function pointer array before semanting
-			If TArrayType(declTy) And TFunctionPtrType(TArrayType(declTy).elemType) Then
-				If Not TFunctionPtrType(TArrayType(declTy).elemType).func.scope Then
+			If TFunctionPtrType(at) Then
+				If Not TFunctionPtrType(at).func.scope Then
 					If scope Then
 					If scope Then
-						TFunctionPtrType(TArrayType(declTy).elemType).func.scope = scope
+						TFunctionPtrType(at).func.scope = scope
 					Else
 					Else
-						TFunctionPtrType(TArrayType(declTy).elemType).func.scope = _env
+						TFunctionPtrType(at).func.scope = _env
 					End If
 					End If
 				End If
 				End If
 			End If
 			End If
@@ -365,46 +394,82 @@ Type TValDecl Extends TDecl
 			If declInit Then
 			If declInit Then
 				If TFunctionPtrType(ty) Then
 				If TFunctionPtrType(ty) Then
 					
 					
-					' the default munged function value as defined in the interface
+					Local expr:TExpr
+					
 					If TInvokeExpr(declInit) Then
 					If TInvokeExpr(declInit) Then
-						init = declInit.Copy()
+						expr = declInit.Copy()
 					Else If TConstExpr(declInit) Then
 					Else If TConstExpr(declInit) Then
-						init = declInit.Copy().Semant()
+						expr = declInit.Copy().Semant()
+					Else If TFuncCallExpr(declInit) Then
+						expr=declInit.Copy().Semant()
+					Else If TNullExpr(declInit) Then
+						expr = declInit
 					Else
 					Else
-						Local expr:TExpr
-						
-						If TFuncCallExpr(declInit) Then
-							expr=declInit.Copy().Semant()
-						Else If TNullExpr(declInit) Then
-							expr = declInit
-						Else
-							Local argExpr:TExpr[] = New TExpr[0]
-
-							For Local arg:TArgDecl = EachIn TFunctionPtrType(ty).func.argDecls
-								Local ldecl:TLocalDecl = New TLocalDecl.Create(arg.ident, arg.declTy, Null, 0)
-								ldecl.Semant()
-								Local aexp:TVarExpr = New TVarExpr.Create(ldecl)
-								'Local aexp:TIdentTypeExpr = New TIdentTypeExpr.Create(arg.declTy)
-								aexp.Semant()
-								argExpr :+ [aexp]
-							Next
+						' declInit can only be an expression, never a statement
+						' this means that any function call in there is required to have parentheses, and will
+						' thus appear in the form of a TFuncCallExpr
+						' as such, trying SemantFunc in the Else branch seems pointless and will in fact wrongly
+						' interpret function pointers (as TIdentExpr, TIndexExpr, possibly others?) as calls
+						Rem
+						Local argExpr:TExpr[] = New TExpr[0]
+
+						For Local arg:TArgDecl = EachIn TFunctionPtrType(ty).func.argDecls
+							Local ldecl:TLocalDecl = New TLocalDecl.Create(arg.ident, arg.declTy, Null, 0)
+							ldecl.Semant()
+							Local aexp:TVarExpr = New TVarExpr.Create(ldecl)
+							'Local aexp:TIdentTypeExpr = New TIdentTypeExpr.Create(arg.declTy)
+							aexp.Semant()
+							argExpr :+ [aexp]
+						Next
 
 
-							expr=declInit.Copy().SemantFunc(argExpr, False, False)
-							If Not expr Then
-								expr = declInit.Copy().Semant()
-							End If
+						expr=declInit.Copy().SemantFunc(argExpr, False, False)
+						If Not expr Then
+							expr = declInit.Copy().Semant()
 						End If
 						End If
+						End Rem
 						
 						
-						If expr.exprType.EqualsType( ty ) Then
-							init = expr
-						Else
-							init = New TCastExpr.Create( ty,expr,CAST_EXPLICIT ).Semant()
-						End If
+						expr = declInit.Copy().Semant()
+					End If
+					
+					If expr.exprType.EqualsType( ty ) Then
+						init = expr
+					Else
+						init = New TCastExpr.Create( ty,expr,CAST_EXPLICIT ).Semant()
 					End If
 					End If
 					
 					
 					
 					
 				Else
 				Else
+					If TArrayExpr(declInit) And TArrayType(ty) And TNumericType(TArrayType(ty).elemType) Then
+						TArrayExpr(declInit).toType = TArrayType(ty).elemType
+					End If
+				
 					init=declInit.Copy().SemantAndCast(ty)
 					init=declInit.Copy().SemantAndCast(ty)
+					
+					' check if struct has been initialised
+					If TObjectType(ty) And TObjectType(ty).classDecl.IsStruct() Then
+					
+						' new not used
+						If TConstExpr(init) And Not TConstExpr(init).value Then
+							
+							Local found:Int = False
+							' struct contains any objects?
+							For Local fld:TFieldDecl = EachIn TObjectType(ty).classDecl._decls
+								If Not fld.IsSemanted() Then
+									fld.Semant()
+								End If
+							
+								If TObjectType(fld.ty) Or TStringType(fld.ty) Or TArrayType(fld.ty) Then
+									found = True
+									Exit
+								End If
+							Next
+						
+							' we need to initialise object fields, so we'll call the default constructor
+							If found Then
+								init = New TNewObjectExpr.Create(ty, Null).Semant()
+							End If
+						End If
+					End If
 				End If
 				End If
 			End If
 			End If
 		Else If declInit
 		Else If declInit
@@ -478,18 +543,20 @@ End Type
 Type TLocalDecl Extends TVarDecl
 Type TLocalDecl Extends TVarDecl
 
 
 	Field done:Int
 	Field done:Int
+	Field volatile:Int = True
 
 
-	Method Create:TLocalDecl( ident$,ty:TType,init:TExpr,attrs:Int=0, generated:Int = False )
+	Method Create:TLocalDecl( ident$,ty:TType,init:TExpr,attrs:Int=0, generated:Int = False, volatile:Int = True )
 		Self.ident=ident
 		Self.ident=ident
 		Self.declTy=ty
 		Self.declTy=ty
 		Self.declInit=init
 		Self.declInit=init
 		Self.attrs=attrs
 		Self.attrs=attrs
 		Self.generated=generated
 		Self.generated=generated
+		Self.volatile=volatile
 		Return Self
 		Return Self
 	End Method
 	End Method
 	
 	
 	Method OnCopy:TDecl(deep:Int = True)
 	Method OnCopy:TDecl(deep:Int = True)
-		Return New TLocalDecl.Create( ident,ty,CopyInit(),attrs, generated )
+		Return New TLocalDecl.Create( ident,ty,CopyInit(),attrs, generated, volatile )
 	End Method
 	End Method
 
 
 	Method GetDeclPrefix:String()
 	Method GetDeclPrefix:String()
@@ -506,12 +573,13 @@ Type TArgDecl Extends TLocalDecl
 
 
 	Field castTo:String
 	Field castTo:String
 	
 	
-	Method Create:TArgDecl( ident$,ty:TType,init:TExpr,attrs:Int=0, generated:Int = False )
+	Method Create:TArgDecl( ident$,ty:TType,init:TExpr,attrs:Int=0, generated:Int = False, volatile:Int = True )
 		Self.ident=ident
 		Self.ident=ident
 		Self.declTy=ty
 		Self.declTy=ty
 		Self.declInit=init
 		Self.declInit=init
 		Self.attrs=attrs
 		Self.attrs=attrs
 		Self.generated=generated
 		Self.generated=generated
+		Self.volatile=volatile
 		Return Self
 		Return Self
 	End Method
 	End Method
 	
 	
@@ -524,7 +592,7 @@ Type TArgDecl Extends TLocalDecl
 	End Method
 	End Method
 	
 	
 	Method OnCopy:TDecl(deep:Int = True)
 	Method OnCopy:TDecl(deep:Int = True)
-		Local d:TArgDecl = New TArgDecl.Create( ident,ty,CopyInit(),attrs,generated )
+		Local d:TArgDecl = New TArgDecl.Create( ident,ty,CopyInit(),attrs,generated,volatile )
 		d.ty = d.declTy
 		d.ty = d.declTy
 		d.init = d.declInit
 		d.init = d.declInit
 		Return d
 		Return d
@@ -573,6 +641,20 @@ Type TGlobalDecl Extends TVarDecl
 		Return inst
 		Return inst
 	End Method
 	End Method
 
 
+	Method CheckAccess:Int()
+		Local cd:TClassDecl = ClassScope()
+		If cd Then
+			If IsPrivate() And cd<>_env.ClassScope() Return False
+			If IsProtected() Then
+				Local ec:TClassDecl = _env.ClassScope()
+				If Not ec Return False
+				If Not ec.ExtendsClass(cd) Return False
+			End If
+			Return True
+		End If
+		Return Super.CheckAccess()
+	End Method
+
 End Type
 End Type
 
 
 Type TFieldDecl Extends TVarDecl
 Type TFieldDecl Extends TVarDecl
@@ -605,7 +687,17 @@ Type TFieldDecl Extends TVarDecl
 		inst.declInit=declInit
 		inst.declInit=declInit
 		Return inst
 		Return inst
 	End Method
 	End Method
-	
+
+	Method CheckAccess:Int()
+		If IsPrivate() And ClassScope()<>_env.ClassScope() Return False
+		If IsProtected() And ClassScope() Then
+			Local ec:TClassDecl = _env.ClassScope()
+			If Not ec Return False
+			If Not ec.ExtendsClass(ClassScope()) Return False
+		End If
+		Return True
+	End Method
+
 End Type
 End Type
 
 
 Type TAliasDecl Extends TDecl
 Type TAliasDecl Extends TDecl
@@ -790,7 +882,7 @@ Type TScopeDecl Extends TDecl
 		If TFuncDeclList(decl) Then
 		If TFuncDeclList(decl) Then
 			For Local fdecl:TFuncDecl = EachIn TFuncDeclList(decl)
 			For Local fdecl:TFuncDecl = EachIn TFuncDeclList(decl)
 
 
-				If Not fdecl.IsSemanted() Then
+				If Not fdecl.IsSemanted() And Not fdecl.IsSemanting() Then
 					fdecl.Semant
 					fdecl.Semant
 				End If
 				End If
 				
 				
@@ -840,6 +932,27 @@ Type TScopeDecl Extends TDecl
 					declList.AddLast(decl)
 					declList.AddLast(decl)
 				End If
 				End If
 			End If
 			End If
+
+			' if scope is an interface, also check implemented/extended interfaces?
+			If TClassDecl(tscope) And TClassDecl(tscope).IsInterface() Then
+				If TClassDecl(tscope).implments Then
+					For Local idecl:TScopeDecl = EachIn TClassDecl(tscope).implments
+						Local decl:Object=idecl.GetDeclList( ident, declList, maxSearchDepth )
+						If decl Then
+							If TFuncDeclList(decl) Then
+								If TFuncDeclList(decl) <> declList Then
+									For Local d:TDecl = EachIn TFuncDeclList(decl)
+										declList.AddLast(d)
+									Next
+								End If
+							Else
+								declList.AddLast(decl)
+							End If
+						End If
+					Next
+				End If 
+			End If
+			
 			tscope=tscope.scope
 			tscope=tscope.scope
 			
 			
 			If TClassDecl(tscope) And maxSearchDepth < SCOPE_CLASS_HEIRARCHY Then
 			If TClassDecl(tscope) And maxSearchDepth < SCOPE_CLASS_HEIRARCHY Then
@@ -1034,6 +1147,9 @@ End Rem
 					' 
 					' 
 				Else If Not bestMatch.IsMethod() And func.IsMethod() Then
 				Else If Not bestMatch.IsMethod() And func.IsMethod() Then
 					bestMatch = func
 					bestMatch = func
+				Else If (bestMatch.scope <> func.scope) And (TClassDecl(bestMatch.scope).ExtendsClass(TClassDecl(func.scope))) Then
+					' match is in different level of class hierarchy
+					Exit
 				Else
 				Else
 					' a tie?
 					' a tie?
 					Err "Unable to determine overload to use: "+ bestMatch.ToString()+" or "+func.ToString()+"."
 					Err "Unable to determine overload to use: "+ bestMatch.ToString()+" or "+func.ToString()+"."
@@ -1091,7 +1207,9 @@ End Rem
 '		If Not funcs Then Return Null
 '		If Not funcs Then Return Null
 		
 		
 		For Local func:TDecl = EachIn funcs
 		For Local func:TDecl = EachIn funcs
-			func.Semant()
+			If Not func.IsSemanting() Then
+				func.Semant()
+			End If
 		Next
 		Next
 		
 		
 		'Local f:TDecl = TDecl(findDecl(ident))
 		'Local f:TDecl = TDecl(findDecl(ident))
@@ -1189,20 +1307,23 @@ End Rem
 				
 				
 				Local argDecls:TArgDecl[]=func.argDecls
 				Local argDecls:TArgDecl[]=func.argDecls
 				
 				
-				If argExprs.Length>argDecls.Length Continue
-				
 				Local exact:Int=True
 				Local exact:Int=True
 				Local possible:Int=True
 				Local possible:Int=True
 				
 				
 				foundIdentMatch = True
 				foundIdentMatch = True
-				
+
 				' we found a matching name - this is probably the one we mean...
 				' we found a matching name - this is probably the one we mean...
 				If isArg Then
 				If isArg Then
 					'match=func
 					'match=func
 					matches.AddLast(func)
 					matches.AddLast(func)
 					Exit
 					Exit
 				End If
 				End If
-				
+
+				If argExprs.Length>argDecls.Length
+					exact = False
+					Continue
+				End If
+
 				For Local i:Int=0 Until argDecls.Length
 				For Local i:Int=0 Until argDecls.Length
 	
 	
 					If i<argExprs.Length And argExprs[i]
 					If i<argExprs.Length And argExprs[i]
@@ -1430,10 +1551,11 @@ Const FUNC_METHOD:Int=   $0001			'mutually exclusive with ctor
 Const FUNC_CTOR:Int=     $0002
 Const FUNC_CTOR:Int=     $0002
 Const FUNC_PROPERTY:Int= $0004
 Const FUNC_PROPERTY:Int= $0004
 Const FUNC_DTOR:Int=     $0008
 Const FUNC_DTOR:Int=     $0008
-Const FUNC_PTR:Int=      $0100
 Const FUNC_BUILTIN:Int = $0080
 Const FUNC_BUILTIN:Int = $0080
+Const FUNC_PTR:Int=      $0100
 Const FUNC_INIT:Int =    $0200
 Const FUNC_INIT:Int =    $0200
 Const FUNC_NESTED:Int =  $0400
 Const FUNC_NESTED:Int =  $0400
+Const FUNC_OPERATOR:Int= $0800
 
 
 'Fix! A func is NOT a block/scope!
 'Fix! A func is NOT a block/scope!
 '
 '
@@ -1475,7 +1597,7 @@ Type TFuncDecl Extends TBlockDecl
 		For Local i:Int=0 Until args.Length
 		For Local i:Int=0 Until args.Length
 			args[i]=TArgDecl( args[i].Copy() )
 			args[i]=TArgDecl( args[i].Copy() )
 		Next
 		Next
-		Local t:TFuncDecl=New TFuncDecl.CreateF( ident,retType,args,attrs )
+		Local t:TFuncDecl=New TFuncDecl.CreateF( ident,retType,args,attrs)
 		If deep Then
 		If deep Then
 			For Local stmt:TStmt=EachIn stmts
 			For Local stmt:TStmt=EachIn stmts
 				t.AddStmt stmt.Copy( t )
 				t.AddStmt stmt.Copy( t )
@@ -1565,6 +1687,10 @@ Type TFuncDecl Extends TBlockDecl
 		Return (attrs & FUNC_METHOD)<>0
 		Return (attrs & FUNC_METHOD)<>0
 	End Method
 	End Method
 	
 	
+	Method IsAnyMethod:Int()
+		Return IsMethod() Or IsCtor() Or IsDtor() 
+	End Method
+	
 	Method IsStatic:Int()
 	Method IsStatic:Int()
 		Return (attrs & (FUNC_METHOD|FUNC_CTOR))=0
 		Return (attrs & (FUNC_METHOD|FUNC_CTOR))=0
 	End Method
 	End Method
@@ -1573,26 +1699,40 @@ Type TFuncDecl Extends TBlockDecl
 		Return (attrs & FUNC_PROPERTY)<>0
 		Return (attrs & FUNC_PROPERTY)<>0
 	End Method
 	End Method
 	
 	
-	Method EqualsArgs:Int( decl:TFuncDecl )
+	Method EqualsArgs:Int( decl:TFuncDecl ) ' careful, this is not commutative!
 		If argDecls.Length<>decl.argDecls.Length Return False
 		If argDecls.Length<>decl.argDecls.Length Return False
 		For Local i:Int=0 Until argDecls.Length
 		For Local i:Int=0 Until argDecls.Length
-			If Not argDecls[i].ty.EqualsType( decl.argDecls[i].ty ) Return False
+			' objects can be subclasses as well as the same.
+			If TObjectType(decl.argDecls[i].ty) Then
+				If Not decl.argDecls[i].ty.EqualsType( argDecls[i].ty ) And Not decl.argDecls[i].ty.ExtendsType( argDecls[i].ty ) Return False
+			Else
+				If Not decl.argDecls[i].ty.EqualsType( argDecls[i].ty ) Return False
+			End If
 		Next
 		Next
 		Return True
 		Return True
 	End Method
 	End Method
 
 
-	Method EqualsFunc:Int( decl:TFuncDecl )
+	Method EqualsFunc:Int( decl:TFuncDecl ) ' careful, this is not commutative!
 		If IsCtor() Then
 		If IsCtor() Then
 			Return EqualsArgs( decl )
 			Return EqualsArgs( decl )
 		Else
 		Else
-			Return (retType.EqualsType( decl.retType ) Or retType.ExtendsType( decl.retType ) Or decl.retType.EqualsType( retType )) And EqualsArgs( decl )
+			' matching args?
+			If EqualsArgs( decl ) Then
+				' matching return type?
+				If TObjectType(retType) Or TArrayType(retType) Or TStringType(retType) Then
+					Return retType.EqualsType( decl.retType ) Or retType.ExtendsType( decl.retType )' Or decl.retType.EqualsType( retType )) And EqualsArgs( decl )
+				Else
+					Return retType.EqualsType( decl.retType )
+				End If
+			End If
 		End If
 		End If
+		Return False
 	End Method
 	End Method
 
 
 	Method OnSemant()
 	Method OnSemant()
 
 
 		Local strictVoidToInt:Int = False
 		Local strictVoidToInt:Int = False
-		
+
 		'semant ret type
 		'semant ret type
 		If Not retTypeExpr Then
 		If Not retTypeExpr Then
 			If Not retType Then ' may have previously been set (if this is a function pointer)
 			If Not retType Then ' may have previously been set (if this is a function pointer)
@@ -1607,6 +1747,21 @@ Type TFuncDecl Extends TBlockDecl
 				End If
 				End If
 			End If
 			End If
 		Else
 		Else
+			' pass the scope into the function ptr
+			Local retTypeExpr_:TType = retTypeExpr
+			While TArrayType(retTypeExpr_) ' look into array types, since the element type might be function ptr
+				retTypeExpr_ = TArrayType(retTypeExpr_).elemType
+			Wend
+			If TFunctionPtrType(retTypeExpr_) Then
+				If Not TFunctionPtrType(retTypeExpr_).func.scope Then
+					If scope Then
+						TFunctionPtrType(retTypeExpr_).func.scope = scope
+					Else
+						TFunctionPtrType(retTypeExpr_).func.scope = _env
+					End If
+				End If
+			End If
+		
 			retType=retTypeExpr.Semant()
 			retType=retTypeExpr.Semant()
 			
 			
 			' for Strict code, a void return type becomes Int
 			' for Strict code, a void return type becomes Int
@@ -1704,12 +1859,41 @@ Type TFuncDecl Extends TBlockDecl
 
 
 						If EqualsFunc( decl ) And Not voidReturnTypeFail
 						If EqualsFunc( decl ) And Not voidReturnTypeFail
 
 
-							If Not retType.EqualsType( decl.retType ) And retType.ExtendsType( decl.retType ) Then
-								returnTypeSubclassed = True
+							' check we aren't attempting to assign weaker access modifiers
+							If (IsProtected() And decl.IsPublic()) Or (IsPrivate() And (decl.IsProtected() Or decl.IsPublic())) Then
+							
+								Local p:String
+								If IsProtected() Then
+									p = "Protected"
+								Else
+									p = "Private"
+								End If
+								
+								Local dp:String
+								If decl.IsPublic() Then
+									dp = "Public"
+								Else
+									dp = "Protected"
+								End If
+							
+								Err ToString() + " clashes with " + decl.ToString() + ". Attempt to assign weaker access privileges ('" + p + "'), was '" + dp + "'."
+							
+							End If
+						
+							If TObjectType(retType) And TObjectType(decl.retType ) Then
+								If Not retType.EqualsType( decl.retType ) And retType.ExtendsType( decl.retType ) Then
+									returnTypeSubclassed = True
+								End If
 							End If
 							End If
 							
 							
 							overrides=TFuncDecl( decl.actual )
 							overrides=TFuncDecl( decl.actual )
 						Else
 						Else
+							' method overloading?
+							If Not EqualsArgs(decl) Then
+								found = False
+								Continue
+							End If
+							
 							'prepare a more detailed error message
 							'prepare a more detailed error message
 							If (Not retType.EqualsType( decl.retType ) Or Not retType.ExtendsType( decl.retType )) Or (decl.retType And Not decl.retType.EqualsType( retType )) Or voidReturnTypeFail
 							If (Not retType.EqualsType( decl.retType ) Or Not retType.ExtendsType( decl.retType )) Or (decl.retType And Not decl.retType.EqualsType( retType )) Or voidReturnTypeFail
 								errorDetails :+ "Return type is ~q"+retType.ToString()+"~q, expected ~q"+decl.retType.ToString()+"~q. "
 								errorDetails :+ "Return type is ~q"+retType.ToString()+"~q, expected ~q"+decl.retType.ToString()+"~q. "
@@ -1720,11 +1904,7 @@ Type TFuncDecl Extends TBlockDecl
 								found = False
 								found = False
 								Continue
 								Continue
 							End If
 							End If
-' TODO REMOVE
-' the following doesn't apply when supporting overloading, as we can have methods of the same name with different args length/types
-							If argDecls.Length <> decl.argDecls.Length
-								errorDetails :+ "Argument count differs. Got " + argDecls.Length +", expected " + decl.argDecls.Length + " arguments."
-							End If
+
 							Local argCount:Int = Min(argDecls.Length, decl.argDecls.Length)
 							Local argCount:Int = Min(argDecls.Length, decl.argDecls.Length)
 							If argCount > 0
 							If argCount > 0
 								For Local i:Int=0 Until argCount
 								For Local i:Int=0 Until argCount
@@ -1740,6 +1920,7 @@ Type TFuncDecl Extends TBlockDecl
 				Next
 				Next
 				If found
 				If found
 					If Not overrides Err "Overriding method does not match any overridden method. (Detail: " + errorDetails+")"
 					If Not overrides Err "Overriding method does not match any overridden method. (Detail: " + errorDetails+")"
+					If overrides.IsFinal() Err "Final methods cannot be overridden."
 					' for overrides, make the ident match that of the superclass
 					' for overrides, make the ident match that of the superclass
 					ident = overrides.ident
 					ident = overrides.ident
 					
 					
@@ -1766,7 +1947,21 @@ Type TFuncDecl Extends TBlockDecl
 		
 		
 		Super.OnSemant()
 		Super.OnSemant()
 	End Method
 	End Method
-	
+
+	Method CheckAccess:Int()
+		Local cd:TClassDecl = ClassScope()
+		If cd Then
+			If IsPrivate() And cd<>_env.ClassScope() Return False
+			If IsProtected() Then
+				Local ec:TClassDecl = _env.ClassScope()
+				If Not ec Return False
+				If Not ec.ExtendsClass(cd) Return False
+			End If
+			Return True
+		End If
+		Return Super.CheckAccess()
+	End Method
+
 End Type
 End Type
 
 
 Type TNewDecl Extends TFuncDecl
 Type TNewDecl Extends TFuncDecl
@@ -1794,7 +1989,7 @@ Type TClassDecl Extends TScopeDecl
 
 
 	Field lastOffset:Int
 	Field lastOffset:Int
 
 
-	Field args:TClassDecl[]
+	Field args:String[]
 	Field superTy:TIdentType
 	Field superTy:TIdentType
 	Field impltys:TIdentType[]
 	Field impltys:TIdentType[]
 
 
@@ -1808,10 +2003,11 @@ Type TClassDecl Extends TScopeDecl
 	Field instArgs:TType[]
 	Field instArgs:TType[]
 
 
 	Field objectType:TObjectType '"canned" objectType
 	Field objectType:TObjectType '"canned" objectType
+	Field globInit:Int
 
 
 	'Global nullObjectClass:TClassDecl=New TNullDecl.Create( "{NULL}",Null,Null,Null,DECL_ABSTRACT|DECL_EXTERN )
 	'Global nullObjectClass:TClassDecl=New TNullDecl.Create( "{NULL}",Null,Null,Null,DECL_ABSTRACT|DECL_EXTERN )
 	
 	
-	Method Create:TClassDecl( ident$,args:TClassDecl[],superTy:TIdentType,impls:TIdentType[],attrs:Int )
+	Method Create:TClassDecl( ident$,args:String[],superTy:TIdentType,impls:TIdentType[],attrs:Int )
 		Self.ident=ident
 		Self.ident=ident
 		Self.args=args
 		Self.args=args
 		Self.superTy=superTy
 		Self.superTy=superTy
@@ -1845,7 +2041,7 @@ Type TClassDecl Extends TScopeDecl
 	Method ToTypeString:String()
 	Method ToTypeString:String()
 		Return ident
 		Return ident
 	End Method
 	End Method
-Rem	
+Rem
 	Method GenClassInstance:TClassDecl( instArgs:TClassDecl[] )
 	Method GenClassInstance:TClassDecl( instArgs:TClassDecl[] )
 		If Not IsSemanted() InternalErr
 		If Not IsSemanted() InternalErr
 		
 		
@@ -1904,7 +2100,6 @@ Rem
 		Return inst
 		Return inst
 	End Method
 	End Method
 End Rem
 End Rem
-
 	Method GenClassInstance:TClassDecl( instArgs:TType[] )
 	Method GenClassInstance:TClassDecl( instArgs:TType[] )
 
 
 		If instanceof InternalErr
 		If instanceof InternalErr
@@ -1959,10 +2154,6 @@ End Rem
 		Return (attrs & CLASS_INTERFACE)<>0
 		Return (attrs & CLASS_INTERFACE)<>0
 	End Method
 	End Method
 
 
-	Method IsFinal:Int()
-		Return (attrs & DECL_FINAL)<>0
-	End Method
-
 	Method IsThrowable:Int()
 	Method IsThrowable:Int()
 		Return (attrs & CLASS_THROWABLE)<>0
 		Return (attrs & CLASS_THROWABLE)<>0
 	End Method
 	End Method
@@ -2087,6 +2278,7 @@ End Rem
 	End Method
 	End Method
 	
 	
 	Method GetAllFuncDecls:TFuncDecl[](funcs:TFuncDecl[] = Null, includeSuper:Int = True)
 	Method GetAllFuncDecls:TFuncDecl[](funcs:TFuncDecl[] = Null, includeSuper:Int = True)
+
 		If Not funcs Then
 		If Not funcs Then
 			funcs = New TFuncDecl[0]
 			funcs = New TFuncDecl[0]
 		End If
 		End If
@@ -2108,6 +2300,10 @@ End Rem
 				' found a match - we are overriding it
 				' found a match - we are overriding it
 				If func.IdentLower() = funcs[i].IdentLower() And func.EqualsArgs(funcs[i]) Then
 				If func.IdentLower() = funcs[i].IdentLower() And func.EqualsArgs(funcs[i]) Then
 					matched = True
 					matched = True
+					' but don't override if we are an interface and the function is implemented
+					If IsInterface() And Not funcs[i].ClassScope().IsInterface() Then
+						Exit
+					End If
 					' set this to our own func
 					' set this to our own func
 					funcs[i] = func
 					funcs[i] = func
 					Exit
 					Exit
@@ -2468,11 +2664,10 @@ End Rem
 						
 						
 						While cdecl And Not found
 						While cdecl And Not found
 							For Local decl2:TFuncDecl=EachIn cdecl.SemantedMethods( decl.ident )
 							For Local decl2:TFuncDecl=EachIn cdecl.SemantedMethods( decl.ident )
-								If decl.EqualsFunc( decl2 )
-									If decl2.munged And Not iface.IsExtern()
-										Err "Extern methods cannot be used to implement interface methods."
-									EndIf
+								' equals (or extends - for object types)
+								If decl2.EqualsFunc( decl )
 									found=True
 									found=True
+									Exit
 								EndIf
 								EndIf
 							Next
 							Next
 						
 						
@@ -2485,12 +2680,47 @@ End Rem
 					Next
 					Next
 				Next
 				Next
 			End If
 			End If
+		Else
+			' check for compatible overloads, etc.
+
+			Local impls:TList=New TList
+
+			CheckInterface(Self, impls)
+			
 		EndIf
 		EndIf
 		
 		
 		PopErr
 		PopErr
 		
 		
 	End Method
 	End Method
 	
 	
+	Method CheckInterface(cdecl:TClassDecl, impls:TList)
+		While cdecl
+		
+			For Local decl:TFuncDecl=EachIn cdecl.SemantedMethods()
+				Local found:Int
+				For Local decl2:TFuncDecl=EachIn impls
+					If decl.IdentLower() = decl2.IdentLower()
+						If Not decl2.EqualsFunc( decl )
+							Err "Cannot mix incompatible method signatures." + decl2.ToString() + " vs " + decl.ToString() + "."
+						Else
+							found = True
+						End If
+					EndIf
+				Next
+				If Not found Then
+					impls.AddLast decl
+				End If
+				'EndIf
+			Next
+			
+			For Local idecl:TClassDecl = EachIn cdecl.implments
+				CheckInterface(idecl, impls)
+			Next
+
+			cdecl=cdecl.superClass
+		Wend
+	End Method
+	
 	Method GetFieldOffset(decl:TFieldDecl)
 	Method GetFieldOffset(decl:TFieldDecl)
 		
 		
 		Local ty:TType = decl.declTy
 		Local ty:TType = decl.declTy

+ 316 - 54
expr.bmx

@@ -1,4 +1,4 @@
-' Copyright (c) 2013-2016 Bruce A Henderson
+' Copyright (c) 2013-2017 Bruce A Henderson
 '
 '
 ' Based on the public domain Monkey "trans" by Mark Sibly
 ' Based on the public domain Monkey "trans" by Mark Sibly
 '
 '
@@ -171,6 +171,12 @@ Type TExpr
 					End If
 					End If
 				End If
 				End If
 
 
+				' re-test auto array for compatible consts.
+				If TArrayExpr(args[i]) And TArrayType(funcDecl.argDecls[i].ty) And TNumericType(TArrayType(funcDecl.argDecls[i].ty).elemType) Then
+					TArrayExpr(args[i]).toType = TArrayType(funcDecl.argDecls[i].ty).elemType
+					args[i].exprType = Null
+					args[i].Semant()
+				End If
 				args[i]=args[i].Cast( funcDecl.argDecls[i].ty )
 				args[i]=args[i].Cast( funcDecl.argDecls[i].ty )
 			Else If funcDecl.argDecls[i].init
 			Else If funcDecl.argDecls[i].init
 				If i = args.length Then
 				If i = args.length Then
@@ -186,14 +192,6 @@ Type TExpr
 	End Method
 	End Method
 
 
 	Method BalanceTypes:TType( lhs:TType,rhs:TType )
 	Method BalanceTypes:TType( lhs:TType,rhs:TType )
-'DebugStop
-		'If lhs._flags & TType.T_VAR Then
-		'	lhs = TType.MapVarPointerToPrim(lhs)
-		'End If
-
-		'If rhs._flags & TType.T_VAR Then
-		'	rhs = TType.MapVarPointerToPrim(rhs)
-		'End If
 
 
 		If TStringType( lhs ) Or TStringType( rhs ) Then
 		If TStringType( lhs ) Or TStringType( rhs ) Then
 			If TObjectType(lhs) Or TObjectType(rhs) Then
 			If TObjectType(lhs) Or TObjectType(rhs) Then
@@ -211,16 +209,22 @@ Type TExpr
 			If IsPointerType( lhs, 0, TType.T_POINTER ) Return lhs
 			If IsPointerType( lhs, 0, TType.T_POINTER ) Return lhs
 			If IsPointerType( rhs, 0, TType.T_POINTER ) Return rhs
 			If IsPointerType( rhs, 0, TType.T_POINTER ) Return rhs
 		End If
 		End If
+		If TDouble128Type( lhs ) Or TDouble128Type( rhs ) Return New TDouble128Type
+		If TFloat128Type( lhs ) Or TFloat128Type( rhs ) Return New TFloat128Type
+		If TFloat64Type( lhs ) Or TFloat64Type( rhs ) Return New TFloat64Type
 		If TDoubleType( lhs ) Or TDoubleType( rhs ) Return New TDoubleType
 		If TDoubleType( lhs ) Or TDoubleType( rhs ) Return New TDoubleType
 		If TFloatType( lhs ) Or TFloatType( rhs ) Return New TFloatType
 		If TFloatType( lhs ) Or TFloatType( rhs ) Return New TFloatType
 		If TFunctionPtrType( lhs ) Or TFunctionPtrType( rhs ) Then
 		If TFunctionPtrType( lhs ) Or TFunctionPtrType( rhs ) Then
 			If TFunctionPtrType( lhs ) Return lhs
 			If TFunctionPtrType( lhs ) Return lhs
 			If TFunctionPtrType( rhs ) Return rhs
 			If TFunctionPtrType( rhs ) Return rhs
 		End If
 		End If
+		If TInt128Type( lhs ) Or TInt128Type( rhs ) Return New TInt128Type
 		If TULongType( lhs ) Or TULongType( rhs ) Return New TULongType
 		If TULongType( lhs ) Or TULongType( rhs ) Return New TULongType
 		If TSizeTType( lhs ) Or TSizeTType( rhs ) Return New TSizeTType
 		If TSizeTType( lhs ) Or TSizeTType( rhs ) Return New TSizeTType
+		If TWParamType( lhs ) Or TWParamType( rhs ) Return New TWParamType
 		If TLongType( lhs ) And TUIntType( rhs ) Return New TULongType
 		If TLongType( lhs ) And TUIntType( rhs ) Return New TULongType
 		If TUIntType( lhs ) And TLongType( rhs ) Return New TULongType
 		If TUIntType( lhs ) And TLongType( rhs ) Return New TULongType
+		If TLParamType( lhs ) Or TLParamType( rhs ) Return New TLParamType
 		If TLongType( lhs ) Or TLongType( rhs ) Return New TLongType
 		If TLongType( lhs ) Or TLongType( rhs ) Return New TLongType
 		If TUIntType( lhs ) Or TUIntType( rhs ) Return New TUIntType
 		If TUIntType( lhs ) Or TUIntType( rhs ) Return New TUIntType
 		If TIntType( lhs ) Or TIntType( rhs ) Return New TIntType
 		If TIntType( lhs ) Or TIntType( rhs ) Return New TIntType
@@ -352,7 +356,6 @@ Type TConstExpr Extends TExpr
 	Field typeSpecific:Int
 	Field typeSpecific:Int
 
 
 	Method Create:TConstExpr( ty:TType,value$ )
 	Method Create:TConstExpr( ty:TType,value$ )
-
 		originalValue = value
 		originalValue = value
 		
 		
 		If TNumericType( ty ) And IsPointerType(ty, 0, TType.T_POINTER) Then
 		If TNumericType( ty ) And IsPointerType(ty, 0, TType.T_POINTER) Then
@@ -365,7 +368,7 @@ Type TConstExpr Extends TExpr
 			Return Self
 			Return Self
 		End If
 		End If
 		
 		
-		If TIntType( ty ) Or TShortType( ty ) Or TByteType( ty ) Or TLongType( ty ) Or TUIntType( ty ) Or TULongType( ty )
+		If TIntType( ty ) Or TShortType( ty ) Or TByteType( ty ) Or TLongType( ty ) Or TUIntType( ty ) Or TULongType( ty ) Or TWParamType(ty) Or TLParamType(ty)
 			Local radix:Int
 			Local radix:Int
 			If value.StartsWith( "%" )
 			If value.StartsWith( "%" )
 				radix=1
 				radix=1
@@ -401,7 +404,43 @@ Type TConstExpr Extends TExpr
 				Else If TByteType( ty ) Then
 				Else If TByteType( ty ) Then
 					value = String.FromLong(Byte(value.ToLong()))
 					value = String.FromLong(Byte(value.ToLong()))
 				Else
 				Else
-					value = String.FromLong(value.ToLong())
+					Local buf:Byte[64]
+					Local b:Int
+					Local v:String = value.Trim()
+					Local leading0:Int = True
+					If v Then
+						Local i:Int
+						If v[0] = Asc("+") Then
+							i = 1
+						Else If v[0] = Asc("-") Then
+							i = 1
+							buf[b] = Asc("-")
+							b:+ 1
+						End If
+						
+						While i < value.Length
+							If Not IsDigit(v[i]) Then
+								Exit
+							End If
+							If leading0 And v[i] = Asc("0") Then
+								i :+ 1
+								Continue
+							End If
+							leading0 = False
+							buf[b] = v[i]
+							
+							b :+ 1
+							i :+ 1
+						Wend
+						
+						If leading0 Then
+							value = "0"
+						Else
+							value = String.FromBytes(buf, b)
+						End If
+					Else
+						value = "0"
+					End If
 				End If
 				End If
 			EndIf
 			EndIf
 
 
@@ -470,7 +509,7 @@ Type TConstExpr Extends TExpr
 			Local val:Long = value.ToLong()
 			Local val:Long = value.ToLong()
 			
 			
 			If val < 0 Then
 			If val < 0 Then
-				If TByteType(ty) Or TShortType(ty) Or TUIntType(ty) Or TULongType(ty) Or TSizeTType(ty) Then
+				If TByteType(ty) Or TShortType(ty) Or TUIntType(ty) Or TULongType(ty) Or TSizeTType(ty) Or TInt128Type(ty) Or TWParamType(ty) Then
 					Return False
 					Return False
 				End If
 				End If
 			Else
 			Else
@@ -480,13 +519,13 @@ Type TConstExpr Extends TExpr
 					End If
 					End If
 				End If
 				End If
 
 
-				If TUIntType(ty) Or (TSizeTType(ty) And WORD_SIZE = 4) Then
+				If TUIntType(ty) Or ((TSizeTType(ty) Or TWParamType(ty)) And WORD_SIZE = 4) Then
 					If val > 4294967296:Long Then
 					If val > 4294967296:Long Then
 						Return False
 						Return False
 					End If
 					End If
 				End If
 				End If
 				
 				
-				If TULongType(ty) Or (TSizeTType(ty) And WORD_SIZE = 8) Then
+				If TULongType(ty) Or ((TSizeTType(ty) Or TWParamType(ty)) And WORD_SIZE = 8) Then
 					If value.length > 20 Then
 					If value.length > 20 Then
 						Return False
 						Return False
 					Else If value.length = 20 Then
 					Else If value.length = 20 Then
@@ -509,13 +548,13 @@ Type TConstExpr Extends TExpr
 				End If
 				End If
 			End If
 			End If
 
 
-			If TIntType(ty) Then
+			If TIntType(ty) Or (TLParamType(ty) And WORD_SIZE = 4) Then
 				If value <> String.FromInt(Int(val)) Then
 				If value <> String.FromInt(Int(val)) Then
 					Return False
 					Return False
 				End If
 				End If
 			End If
 			End If
 
 
-			If TLongType(ty) Then
+			If TLongType(ty) Or (TLParamType(ty) And WORD_SIZE = 8) Then
 				If value <> String.FromLong(Long(val)) Then
 				If value <> String.FromLong(Long(val)) Then
 					Return False
 					Return False
 				End If
 				End If
@@ -651,8 +690,15 @@ Type TInvokeExpr Extends TExpr
 		'	exprType=decl.retType
 		'	exprType=decl.retType
 		'End If
 		'End If
 
 
-		If ((isArg Or isRhs) And Not invokedWithBraces) And (args = Null Or args.length = 0) Then
-			' nothing to do here, as we are probably a function pointer. i.e. no braces and no 
+		'If ((isArg Or isRhs) And Not invokedWithBraces) And (args = Null Or args.length = 0) Then
+
+		' if the call was a statement (even one written without parentheses), then invokedWithBraces is true
+		' so no complicated checks are needed here; if invokedWithBraces is false, this is definitely not a call
+		If Not invokedWithBraces Then
+			' nothing to do here, as we are a function pointer. i.e. no braces
+			' and our expression type is a function ptr...
+			exprType = New TFunctionPtrType.Create(decl)
+			
 		Else
 		Else
 			args=CastArgs( args,decl )
 			args=CastArgs( args,decl )
 		End If
 		End If
@@ -773,16 +819,21 @@ Type TNewObjectExpr Extends TExpr
 		args=SemantArgs( args )
 		args=SemantArgs( args )
 
 
 		Local objTy:TObjectType=TObjectType( ty )
 		Local objTy:TObjectType=TObjectType( ty )
-		If Not objTy
+		Local clsTy:TClassType=TClassType( ty )
+		If Not objTy And Not clsTy
 			Err "Expression is not a class."
 			Err "Expression is not a class."
 		EndIf
 		EndIf
 		
 		
 		' 
 		' 
-		If objTy.instance Then
+		If clsTy And clsTy.instance Then
 			instanceExpr = New TSelfExpr.Semant()
 			instanceExpr = New TSelfExpr.Semant()
 		End If
 		End If
 
 
-		classDecl=objTy.classDecl
+		If objTy Then
+			classDecl=objTy.classDecl
+		Else
+			classDecl=clsTy.classDecl
+		End If
 
 
 		If Not instanceExpr Then
 		If Not instanceExpr Then
 			If classDecl.IsInterface() Err "Cannot create instance of an interface."
 			If classDecl.IsInterface() Err "Cannot create instance of an interface."
@@ -814,7 +865,11 @@ Type TNewObjectExpr Extends TExpr
 
 
 		classDecl.attrs:|CLASS_INSTANCED
 		classDecl.attrs:|CLASS_INSTANCED
 
 
-		exprType=ty
+		If TClassType(ty) Then
+			exprType=New TObjectType.Create(TClassType(ty).classDecl)
+		Else
+			exprType=ty
+		End If
 		
 		
 		If it Then
 		If it Then
 			'Local parts:String[] = it.ident.ToLower().Split(".")
 			'Local parts:String[] = it.ident.ToLower().Split(".")
@@ -829,10 +884,10 @@ Type TNewObjectExpr Extends TExpr
 
 
 			Local expr:TExpr = Self
 			Local expr:TExpr = Self
 			Local cdecl:TClassDecl = classDecl
 			Local cdecl:TClassDecl = classDecl
-			Local eType:TType = objTy
+			Local eType:TType = ty
 			
 			
 			Local errorDetails:String
 			Local errorDetails:String
-			
+
 			While i < parts.length
 			While i < parts.length
 				Local id:String = parts[i]
 				Local id:String = parts[i]
 				i :+ 1
 				i :+ 1
@@ -1033,7 +1088,15 @@ Type TSelfExpr Extends TExpr
 		If Not scope Then
 		If Not scope Then
 			Err "'Self' can only be used within methods."
 			Err "'Self' can only be used within methods."
 		End If
 		End If
-		exprType=New TObjectType.Create( scope )
+		
+		Local funcScope:TFuncDecl = _env.FuncScope()
+		If funcScope.IsAnyMethod() Then
+			exprType=New TObjectType.Create( scope )
+			TObjectType(exprType).instance = True
+		Else
+			exprType=New TClassType.Create( scope )
+		End If
+
 		Return Self
 		Return Self
 	End Method
 	End Method
 
 
@@ -1119,12 +1182,16 @@ Type TCastExpr Extends TExpr
 					op="ToFloat"
 					op="ToFloat"
 				Else If TStringType( ty )
 				Else If TStringType( ty )
 					op="ToString"
 					op="ToString"
-				Else If IsPointerType( ty, TType.T_BYTE )
+				Else If IsPointerType(ty, 0, TType.T_POINTER)
 					exprType = ty
 					exprType = ty
 					If flags = CAST_EXPLICIT Then
 					If flags = CAST_EXPLICIT Then
 						Return Self
 						Return Self
 					Else
 					Else
-						Return expr
+						If Not TObjectType( src ).classDecl.IsExtern() Then
+							Return Self
+						Else
+							Return expr
+						End If
 					End If
 					End If
 				Else
 				Else
 					InternalErr
 					InternalErr
@@ -1143,6 +1210,22 @@ Type TCastExpr Extends TExpr
 			End If
 			End If
 			
 			
 			If TNumericType(src) And (TNumericType(ty) Or TStringType(ty)) Then
 			If TNumericType(src) And (TNumericType(ty) Or TStringType(ty)) Then
+				' intrinsics can only cast between selves
+				If (TIntrinsicType(src) And TIntrinsicType(ty)=Null) Or (TIntrinsicType(ty) And TIntrinsicType(src)=Null) Then
+					If TFloat64Type(src) Or TFloat64Type(ty) Then
+						If (TFloat64Type(src) And (TLongType(ty) Or TULongType(ty))) Or (TFloat64Type(ty) And (TLongType(src) Or TULongType(src))) Then
+							' ok
+						Else
+							Err "Unable to convert from "+src.ToString()+" to "+ty.ToString()+"."
+						End If
+					Else
+						Err "Unable to convert from "+src.ToString()+" to "+ty.ToString()+"."
+					End If
+				Else If TIntrinsicType(src) And TIntrinsicType(ty) Then
+					If (TFloat64Type(src) And TFloat64Type(ty)=Null) Or (TFloat64Type(ty) And TFloat64Type(src)=Null) Then
+						Err "Unable to convert from "+src.ToString()+" to "+ty.ToString()+"."
+					End If
+				End If
 				exprType = ty
 				exprType = ty
 			End If
 			End If
 			
 			
@@ -1154,13 +1237,6 @@ Type TCastExpr Extends TExpr
 			If TFunctionPtrType(src) And IsPointerType(ty, 0, TType.T_POINTER) Then
 			If TFunctionPtrType(src) And IsPointerType(ty, 0, TType.T_POINTER) Then
 				exprType = ty
 				exprType = ty
 			End If
 			End If
-			
-			If TArrayType(ty) And TArrayType(src) Then
-				If TArrayType(ty).dims = TArrayType(src).dims Then
-					exprType = ty
-					Return Self
-				End If
-			End If
 
 
 		Else If TBoolType( ty )
 		Else If TBoolType( ty )
 
 
@@ -1197,6 +1273,40 @@ Type TCastExpr Extends TExpr
 
 
 		EndIf
 		EndIf
 
 
+
+		If TArrayType(ty) And TArrayType(src) Then
+			If TArrayType(ty).dims = TArrayType(src).dims Then
+				If TArrayExpr(expr) Then
+					Local last:TType
+					For Local e:TExpr = EachIn TArrayExpr(expr).exprs
+						If TNullType(e.exprType) Then
+							Err "Auto array element has no type"
+						End If
+
+						If TObjectType(TArrayType(ty).elemType) And TObjectType(TArrayType(ty).elemType).classDecl.ident = "Object" And (TStringType(e.exprType) Or TObjectType(e.exprType) Or TArrayType(e.exprType)) Then
+							' array takes generic objects, so we don't care if source elements are the same kinds.
+						Else
+							If last <> Null And Not last.EqualsType(e.exprType) Then
+								Err "Auto array elements must have identical types"
+							End If
+							If Not TArrayType(ty).elemType.EqualsType(e.exprType) Then
+								If (TObjectType(TArrayType(ty).elemType) = Null And TStringType(TArrayType(ty).elemType) = Null) Or (TObjectType(e.exprType) = Null And TStringType(e.exprType) = Null) Then
+									Err "Unable to convert from "+src.ToString()+" to "+ty.ToString()+"."
+								Else If TStringType(e.exprType) = Null And Not TObjectType(e.exprType).ExtendsType(TObjectType(TArrayType(ty).elemType)) Then
+									Err "Unable to convert from "+src.ToString()+" to "+ty.ToString()+"."
+								End If
+							End If
+						End If
+						
+						last = e.exprType
+					Next
+				End If
+				
+				exprType = ty
+				Return Self
+			End If
+		End If
+
 		'If TStringType(src) And TStringVarPtrType(ty) Then
 		'If TStringType(src) And TStringVarPtrType(ty) Then
 		'	exprType = ty
 		'	exprType = ty
 		'	Return Self
 		'	Return Self
@@ -1212,17 +1322,19 @@ Type TCastExpr Extends TExpr
 			If Not TInvokeExpr(expr).invokedWithBraces Then
 			If Not TInvokeExpr(expr).invokedWithBraces Then
 				src = New TFunctionPtrType
 				src = New TFunctionPtrType
 				TFunctionPtrType(src).func = TInvokeExpr(expr).decl
 				TFunctionPtrType(src).func = TInvokeExpr(expr).decl
-			
+
 				' signatures should match
 				' signatures should match
-				If TFunctionPtrType(ty).func.EqualsFunc(TInvokeExpr(expr).decl) Then
+				If TInvokeExpr(expr).decl.equalsFunc(TFunctionPtrType(ty).func)  Then
 					exprType = ty
 					exprType = ty
 					Return expr
 					Return expr
 				End If
 				End If
 			Else
 			Else
 				' return type should be function ptr?
 				' return type should be function ptr?
-				' TODO
-				exprType = ty
-				Return expr
+				Local retType:TType = expr.exprType
+				If TFunctionPtrType(retType) And TFunctionPtrType(ty).func.EqualsFunc(TFunctionPtrType(retType).func) Then
+					exprType = retType
+					Return expr
+				End If
 			End If
 			End If
 		End If
 		End If
 
 
@@ -1306,6 +1418,15 @@ Type TCastExpr Extends TExpr
 			Else If TNumericType(src) And (src._flags & TType.T_VARPTR) Then
 			Else If TNumericType(src) And (src._flags & TType.T_VARPTR) Then
 				exprType = expr.exprType
 				exprType = expr.exprType
 			Else If TArrayType(src) Then
 			Else If TArrayType(src) Then
+			
+				' for functions and index access, use a new local variable
+				If Not TVarExpr(expr) And Not TMemberVarExpr(expr) Then
+					Local tmp:TLocalDecl=New TLocalDecl.Create( "", expr.exprType, expr,, True )
+					tmp.Semant()
+					Local v:TVarExpr = New TVarExpr.Create( tmp )
+					expr = New TStmtExpr.Create( New TDeclStmt.Create( tmp ), v ).Semant()
+				End If
+			
 				If TNumericType(TArrayType(src).elemType) Then
 				If TNumericType(TArrayType(src).elemType) Then
 					exprType = TNumericType(TArrayType(src).elemType).ToPointer()
 					exprType = TNumericType(TArrayType(src).elemType).ToPointer()
 					Return Self
 					Return Self
@@ -1367,11 +1488,11 @@ Type TCastExpr Extends TExpr
 		Local val$=expr.Eval()
 		Local val$=expr.Eval()
 		If Not val Return val
 		If Not val Return val
 		If TBoolType( exprType )
 		If TBoolType( exprType )
-			If TIntType( expr.exprType )
-				If Int( val ) Return "1"
+			If TIntegralType(expr.exprType)
+				If Long( val ) Return "1"
 				Return ""
 				Return ""
-			Else If TFloatType( expr.exprType )
-				If Float( val ) Return "1"
+			Else If TDecimalType( expr.exprType )
+				If Double( val ) Return "1"
 				Return ""
 				Return ""
 			Else If TStringType( expr.exprType )
 			Else If TStringType( expr.exprType )
 				If val.Length Return "1"
 				If val.Length Return "1"
@@ -1397,10 +1518,22 @@ Type TCastExpr Extends TExpr
 			Return Long( val )
 			Return Long( val )
 		Else If TSizeTType( exprType )
 		Else If TSizeTType( exprType )
 			Return Long( val )
 			Return Long( val )
+		Else If TInt128Type( exprType )
+			Return Long( val )
+		Else If TFloat128Type( exprType )
+			Return Float( val )
+		Else If TDouble128Type( exprType )
+			Return Float( val )
+		Else If TFloat64Type( exprType )
+			Return Float( val )
 		Else If TStringType( exprType )
 		Else If TStringType( exprType )
 			Return String( val )
 			Return String( val )
 		Else If TByteType( exprType )
 		Else If TByteType( exprType )
 			Return Byte( val )
 			Return Byte( val )
+		Else If TWParamType( exprType )
+			Return Long( val )
+		Else If TLParamType( exprType )
+			Return Long( val )
 		Else If TObjectType( exprType )
 		Else If TObjectType( exprType )
 			If TStringType( expr.exprType )
 			If TStringType( expr.exprType )
 				Return val
 				Return val
@@ -1520,11 +1653,39 @@ Type TBinaryMathExpr Extends TBinaryExpr
 		If exprType Return Self
 		If exprType Return Self
 
 
 		lhs=lhs.Semant()
 		lhs=lhs.Semant()
+
+		If TIdentExpr(rhs) Then
+			TIdentExpr(rhs).isRhs = True
+		End If
+
 		rhs=rhs.Semant()
 		rhs=rhs.Semant()
+		
+		' operator overload?
+		If TObjectType(lhs.exprType) Then
+			Local args:TExpr[] = [rhs]
+			Try
+				Local decl:TFuncDecl = TFuncDecl(TObjectType(lhs.exprType).classDecl.FindFuncDecl(op, args,,,,True,SCOPE_CLASS_HEIRARCHY))
+				If decl Then
+					Return New TInvokeMemberExpr.Create( lhs, decl, args ).Semant()
+				End If
+			Catch error:String
+				If error.StartsWith("Compile Error") Then
+					Throw error
+				Else
+					Err "Operator " + op + " cannot be used with Objects."
+				End If
+			End Try
+		End If
 
 
 		Select op
 		Select op
 		Case "&","~~","|","shl","shr"
 		Case "&","~~","|","shl","shr"
-			If TDoubleType(lhs.exprType) Then
+			If TFloat128Type(lhs.exprType) Then
+				exprType=New TInt128Type
+			Else If TDouble128Type(lhs.exprType) Then
+				exprType=New TInt128Type
+			Else If TFloat64Type(lhs.exprType) Then
+				exprType=New TInt128Type
+			Else If TDoubleType(lhs.exprType) Then
 				exprType=New TLongType
 				exprType=New TLongType
 			Else If TFloatType(lhs.exprType) Then
 			Else If TFloatType(lhs.exprType) Then
 				exprType=New TIntType
 				exprType=New TIntType
@@ -1536,6 +1697,10 @@ Type TBinaryMathExpr Extends TBinaryExpr
 				exprType=New TULongType
 				exprType=New TULongType
 			Else If TSizeTType(lhs.exprType) Then
 			Else If TSizeTType(lhs.exprType) Then
 				exprType=New TSizeTType
 				exprType=New TSizeTType
+			Else If TWParamType(lhs.exprType) Then
+				exprType=New TWParamType
+			Else If TLParamType(lhs.exprType) Then
+				exprType=New TLParamType
 			Else
 			Else
 				exprType=New TIntType
 				exprType=New TIntType
 			End If
 			End If
@@ -1597,7 +1762,7 @@ Type TBinaryMathExpr Extends TBinaryExpr
 			Case "~~" Return x ~ y
 			Case "~~" Return x ~ y
 			Case "|" Return x | y
 			Case "|" Return x | y
 			End Select
 			End Select
-		Else If TLongType( exprType ) Or TSizeTType(exprType) Or TUIntType(exprType) Or TULongType(exprType)
+		Else If TLongType( exprType ) Or TSizeTType(exprType) Or TUIntType(exprType) Or TULongType(exprType) Or TInt128Type(exprType) Or TWParamType(exprType) Or TLParamType(exprType) 
 			Local x:Long=Long(lhs),y:Long=Long(rhs)
 			Local x:Long=Long(lhs),y:Long=Long(rhs)
 			Select op
 			Select op
 			Case "^" Return x^y
 			Case "^" Return x^y
@@ -1622,7 +1787,7 @@ Type TBinaryMathExpr Extends TBinaryExpr
 			Case "+" Return x + y
 			Case "+" Return x + y
 			Case "-" Return x - y
 			Case "-" Return x - y
 			End Select
 			End Select
-		Else If TDoubleType( exprType )
+		Else If TDoubleType( exprType ) Or TFloat128Type(exprType) Or TDouble128Type(exprType) Or TFloat64Type(exprType)
 			Local x:Double=Double(lhs),y:Double=Double(rhs)
 			Local x:Double=Double(lhs),y:Double=Double(rhs)
 			Select op
 			Select op
 			Case "^" Return x^y
 			Case "^" Return x^y
@@ -1666,6 +1831,20 @@ Type TBinaryCompareExpr Extends TBinaryExpr
 		lhs=lhs.Semant()
 		lhs=lhs.Semant()
 		rhs=rhs.Semant()
 		rhs=rhs.Semant()
 
 
+		' operator overload?
+		If TObjectType(lhs.exprType) Then
+			Local args:TExpr[] = [rhs]
+			Try
+				Local decl:TFuncDecl = TFuncDecl(TObjectType(lhs.exprType).classDecl.FindFuncDecl(op, args,,,,True,SCOPE_CLASS_HEIRARCHY))
+				If decl Then
+					Return New TInvokeMemberExpr.Create( lhs, decl, args ).Semant()
+				End If
+			Catch error:String
+				' no overload, continue...
+			End Try
+		End If
+
+
 		ty=BalanceTypes( lhs.exprType,rhs.exprType )
 		ty=BalanceTypes( lhs.exprType,rhs.exprType )
 
 
 		lhs=lhs.Cast( ty )
 		lhs=lhs.Cast( ty )
@@ -1698,7 +1877,7 @@ Type TBinaryCompareExpr Extends TBinaryExpr
 			Case ">"  r=(lhs> rhs)
 			Case ">"  r=(lhs> rhs)
 			Case ">=", "=>" r=(lhs>=rhs)
 			Case ">=", "=>" r=(lhs>=rhs)
 			End Select
 			End Select
-		Else If TLongType( ty ) Or TSizeTType( ty ) Or TUIntType( ty ) Or TULongType( ty )
+		Else If TLongType( ty ) Or TSizeTType( ty ) Or TUIntType( ty ) Or TULongType( ty ) Or TInt128Type(ty) Or TWParamType(ty) Or TLParamType(ty)
 			Local lhs:Long=Long( Self.lhs.Eval() )
 			Local lhs:Long=Long( Self.lhs.Eval() )
 			Local rhs:Long=Long( Self.rhs.Eval() )
 			Local rhs:Long=Long( Self.rhs.Eval() )
 			Select op
 			Select op
@@ -1720,7 +1899,7 @@ Type TBinaryCompareExpr Extends TBinaryExpr
 			Case ">"  r=(lhs> rhs)
 			Case ">"  r=(lhs> rhs)
 			Case ">=", "=>" r=(lhs>=rhs)
 			Case ">=", "=>" r=(lhs>=rhs)
 			End Select
 			End Select
-		Else If TDoubleType( ty )
+		Else If TDoubleType( ty ) Or TFloat128Type(ty) Or TDouble128Type(ty) Or TFloat64Type(ty)
 			Local lhs:Double=Double( Self.lhs.Eval() )
 			Local lhs:Double=Double( Self.lhs.Eval() )
 			Local rhs:Double=Double( Self.rhs.Eval() )
 			Local rhs:Double=Double( Self.rhs.Eval() )
 			Select op
 			Select op
@@ -1812,14 +1991,18 @@ Type TIndexExpr Extends TExpr
 
 
 		' for functions and index access, use a new local variable
 		' for functions and index access, use a new local variable
 		If Not TVarExpr(expr) And Not TMemberVarExpr(expr) Then
 		If Not TVarExpr(expr) And Not TMemberVarExpr(expr) Then
-			Local tmp:TLocalDecl=New TLocalDecl.Create( "", expr.exprType, expr,, True )
+			Local tmp:TLocalDecl=New TLocalDecl.Create( "", TType.MapVarPointerToPointerType(expr.exprType.Copy()), expr,, True )
 			tmp.Semant()
 			tmp.Semant()
 			Local v:TVarExpr = New TVarExpr.Create( tmp )
 			Local v:TVarExpr = New TVarExpr.Create( tmp )
 			expr = New TStmtExpr.Create( New TDeclStmt.Create( tmp ), v ).Semant()
 			expr = New TStmtExpr.Create( New TDeclStmt.Create( tmp ), v ).Semant()
 		End If
 		End If
 
 
 		For Local i:Int = 0 Until index.length
 		For Local i:Int = 0 Until index.length
-			index[i]=index[i].SemantAndCast( New TUIntType, True )
+			If Not(TNumericType(expr.exprType) And IsPointerType( expr.exprType, 0 , TType.T_POINTER | TType.T_VARPTR)) Then
+				index[i]=index[i].SemantAndCast( New TUIntType, True )
+			Else
+				index[i]=index[i].Semant()
+			End If
 		Next
 		Next
 
 
 		If TStringType( expr.exprType )
 		If TStringType( expr.exprType )
@@ -1865,6 +2048,8 @@ Type TIndexExpr Extends TExpr
 		Else If TNumericType(expr.exprType) And IsPointerType( expr.exprType, 0 , TType.T_POINTER | TType.T_VARPTR)' And Not TFunctionPtrType( expr.exprType )
 		Else If TNumericType(expr.exprType) And IsPointerType( expr.exprType, 0 , TType.T_POINTER | TType.T_VARPTR)' And Not TFunctionPtrType( expr.exprType )
 			exprType=TType.MapPointerToPrim(TNumericType(expr.exprType))
 			exprType=TType.MapPointerToPrim(TNumericType(expr.exprType))
 			'exprType=TType.intType
 			'exprType=TType.intType
+		Else If TObjectType(expr.exprType) And TObjectType(expr.exprType).classDecl.IsStruct() And IsPointerType( expr.exprType, 0 , TType.T_POINTER | TType.T_VARPTR)' And Not TFunctionPtrType( expr.exprType )
+			exprType = expr.exprType
 		Else
 		Else
 			Err "Only strings, arrays and pointers may be indexed."
 			Err "Only strings, arrays and pointers may be indexed."
 		EndIf
 		EndIf
@@ -1958,6 +2143,8 @@ End Type
 
 
 Type TArrayExpr Extends TExpr
 Type TArrayExpr Extends TExpr
 	Field exprs:TExpr[]
 	Field exprs:TExpr[]
+	
+	Field toType:TType
 
 
 	Method Create:TArrayExpr( exprs:TExpr[] )
 	Method Create:TArrayExpr( exprs:TExpr[] )
 		Self.exprs=exprs
 		Self.exprs=exprs
@@ -1965,12 +2152,17 @@ Type TArrayExpr Extends TExpr
 	End Method
 	End Method
 
 
 	Method Copy:TExpr()
 	Method Copy:TExpr()
-		Return New TArrayExpr.Create( CopyArgs(exprs) )
+		Local expr:TArrayExpr = New TArrayExpr.Create( CopyArgs(exprs) )
+		expr.toType = toType
+		Return expr
 	End Method
 	End Method
 
 
 	Method Semant:TExpr()
 	Method Semant:TExpr()
 		If exprType Return Self
 		If exprType Return Self
 
 
+		If TIdentExpr(exprs[0]) Then
+			TIdentExpr(exprs[0]).isRhs = True
+		End If
 		exprs[0]=exprs[0].Semant()
 		exprs[0]=exprs[0].Semant()
 		Local ty:TType=exprs[0].exprType
 		Local ty:TType=exprs[0].exprType
 		' convert from varptr to ptr if required
 		' convert from varptr to ptr if required
@@ -1985,6 +2177,9 @@ Type TArrayExpr Extends TExpr
 			TFunctionPtrType(ty).func = TInvokeExpr(exprs[0]).decl
 			TFunctionPtrType(ty).func = TInvokeExpr(exprs[0]).decl
 
 
 			For Local i:Int=1 Until exprs.Length
 			For Local i:Int=1 Until exprs.Length
+				If TIdentExpr(exprs[1]) Then
+					TIdentExpr(exprs[1]).isRhs = True
+				End If
 				exprs[i]=exprs[i].Semant()
 				exprs[i]=exprs[i].Semant()
 				
 				
 				If TInvokeExpr(exprs[i]) And Not TInvokeExpr(exprs[i]).invokedWithBraces
 				If TInvokeExpr(exprs[i]) And Not TInvokeExpr(exprs[i]).invokedWithBraces
@@ -2006,11 +2201,42 @@ Type TArrayExpr Extends TExpr
 			Next
 			Next
 		End If
 		End If
 
 
+		Local comp:Int = True
+		Local last:TType
 		For Local i:Int=0 Until exprs.Length
 		For Local i:Int=0 Until exprs.Length
-			exprs[i]=exprs[i].Cast( ty )
+
+			Local expr:TExpr = exprs[i]
+
+			' don't cast null types
+			If TNullType(expr.exprType) <> Null Then
+				Err "Auto array element has no type"
+			End If
+
+			Local ety:TType = expr.exprType
+			If TBoolType(ety) Then
+				ety = New TIntType
+			End If
+			
+			If last <> Null And Not last.EqualsType(ety) Then
+				If (Not TConstExpr(expr) And Not IsNumericType(ety)) Or (TConstExpr(expr) And IsNumericType(ety) And Not TConstExpr(expr).CompatibleWithType(ty)) Then
+					Err "Auto array elements must have identical types : Index " + i
+				End If
+			End If
+			
+			If toType And TConstExpr(expr) And Not TConstExpr(expr).CompatibleWithType(toType) Then
+				comp = False
+			End If
+		
+			last = ety
+			
+			exprs[i]=expr.Cast( ty )
 		Next
 		Next
 
 
-		exprType=New TArrayType.Create( ty )
+		If comp And toType Then
+			exprType=New TArrayType.Create( toType )
+		Else
+			exprType=New TArrayType.Create( ty )
+		End If
 		Return Self
 		Return Self
 	End Method
 	End Method
 
 
@@ -2578,6 +2804,12 @@ Type TAbsExpr Extends TBuiltinExpr
 		expr=expr.Semant()
 		expr=expr.Semant()
 
 
 		If TNumericType(expr.exprType) Or TBoolType(expr.exprType) Then
 		If TNumericType(expr.exprType) Or TBoolType(expr.exprType) Then
+
+			If TInt128Type(expr.exprType) Err "'Abs' does not support Int128 type. Use specific intrinsic function instead."
+			If TFloat64Type(expr.exprType) Err "'Abs' does not support Float64 type. Use specific intrinsic function instead."
+			If TFloat128Type(expr.exprType) Err "'Abs' does not support Float128 type. Use specific intrinsic function instead."
+			If TDouble128Type(expr.exprType) Err "'Abs' does not support Double128 type. Use specific intrinsic function instead."
+
 			If TIntType(expr.exprType) Or TByteType(expr.exprType) Or TShortType(expr.exprType) Then
 			If TIntType(expr.exprType) Or TByteType(expr.exprType) Or TShortType(expr.exprType) Then
 				exprType=New TIntType
 				exprType=New TIntType
 			Else
 			Else
@@ -2665,6 +2897,11 @@ Type TSgnExpr Extends TBuiltinExpr
 		If Not TNumericType(expr.exprType) Then
 		If Not TNumericType(expr.exprType) Then
 			Err "Subexpression for 'Sgn' must be of numeric type"
 			Err "Subexpression for 'Sgn' must be of numeric type"
 		End If
 		End If
+
+		If TInt128Type(expr.exprType) Err "'Sgn' does not support Int128 type. Use specific intrinsic function instead."
+		If TFloat64Type(expr.exprType) Err "'Sgn' does not support Float64 type. Use specific intrinsic function instead."
+		If TFloat128Type(expr.exprType) Err "'Sgn' does not support Float128 type. Use specific intrinsic function instead."
+		If TDouble128Type(expr.exprType) Err "'Sgn' does not support Double128 type. Use specific intrinsic function instead."
 		
 		
 		exprType=expr.exprType
 		exprType=expr.exprType
 		Return Self
 		Return Self
@@ -2696,6 +2933,11 @@ Type TMinExpr Extends TBuiltinExpr
 
 
 		expr=expr.Semant()
 		expr=expr.Semant()
 		expr2=expr2.Semant()
 		expr2=expr2.Semant()
+		
+		If TInt128Type(expr.exprType) Or TInt128Type(expr2.exprType) Err "'Min' does not support Int128 type. Use specific intrinsic function instead."
+		If TFloat64Type(expr.exprType) Or TFloat64Type(expr2.exprType) Err "'Min' does not support Float64 type. Use specific intrinsic function instead."
+		If TFloat128Type(expr.exprType) Or TFloat128Type(expr2.exprType) Err "'Min' does not support Float128 type. Use specific intrinsic function instead."
+		If TDouble128Type(expr.exprType) Or TDouble128Type(expr2.exprType) Err "'Min' does not support Double128 type. Use specific intrinsic function instead."
 
 
 		exprType=BalanceTypes(expr.exprType, expr2.exprType)
 		exprType=BalanceTypes(expr.exprType, expr2.exprType)
 		Return Self
 		Return Self
@@ -2728,6 +2970,11 @@ Type TMaxExpr Extends TBuiltinExpr
 		expr=expr.Semant()
 		expr=expr.Semant()
 		expr2=expr2.Semant()
 		expr2=expr2.Semant()
 
 
+		If TInt128Type(expr.exprType) Or TInt128Type(expr2.exprType) Err "'Max' does not support Int128 type. Use specific intrinsic function instead."
+		If TFloat64Type(expr.exprType) Or TFloat64Type(expr2.exprType) Err "'Max' does not support Float64 type. Use specific intrinsic function instead."
+		If TFloat128Type(expr.exprType) Or TFloat128Type(expr2.exprType) Err "'Max' does not support Float128 type. Use specific intrinsic function instead."
+		If TDouble128Type(expr.exprType) Or TDouble128Type(expr2.exprType) Err "'Max' does not support Double128 type. Use specific intrinsic function instead."
+
 		exprType=BalanceTypes(expr.exprType, expr2.exprType)
 		exprType=BalanceTypes(expr.exprType, expr2.exprType)
 		Return Self
 		Return Self
 	End Method
 	End Method
@@ -2838,6 +3085,21 @@ Type TFuncCallExpr Extends TExpr
 		End If
 		End If
 	End Method
 	End Method
 
 
+	Method SemantFunc:TExpr( args:TExpr[] , throwError:Int = True, funcCall:Int = False )
+		' we are only likely to be called if a function returns and invokes a function pointer.
+
+		Local ex:TExpr = Semant()
+		
+		If TFunctionPtrType(ex.exprType) Then
+			exprType = TFunctionPtrType(ex.exprType).func.retType
+		End If
+		
+		Self.args = SemantArgs(args)
+		expr = ex
+		
+		Return Self
+	End Method
+
 	Method Trans$()
 	Method Trans$()
 		Return _trans.TransFuncCallExpr( Self )
 		Return _trans.TransFuncCallExpr( Self )
 	End Method
 	End Method

+ 206 - 33
iparser.bmx

@@ -1,4 +1,4 @@
-' Copyright (c) 2013-2016 Bruce A Henderson
+' Copyright (c) 2013-2017 Bruce A Henderson
 '
 '
 ' Based on the public domain Monkey "trans" by Mark Sibly
 ' Based on the public domain Monkey "trans" by Mark Sibly
 ' 
 ' 
@@ -93,7 +93,11 @@ Type TIParser
 			
 			
 			' import Object and String definitions
 			' import Object and String definitions
 			Local par:TIParser = New TIParser
 			Local par:TIParser = New TIParser
-			par.ParseModuleImport(_mod, "brl.classes", modulepath("brl.blitz"), modulepath("brl.blitz") + "\blitz_classes.i")
+			If FileType(modulepath("brl.blitz") + "\blitz_classes." + opt_platform + ".i") Then
+				par.ParseModuleImport(_mod, "brl.classes", modulepath("brl.blitz"), modulepath("brl.blitz") + "\blitz_classes." + opt_platform + ".i")
+			Else
+				par.ParseModuleImport(_mod, "brl.classes", modulepath("brl.blitz"), modulepath("brl.blitz") + "\blitz_classes.i")
+			End If
 	
 	
 			' set up built-in keywords
 			' set up built-in keywords
 			par = New TIParser
 			par = New TIParser
@@ -266,6 +270,9 @@ Type TIParser
 						Else If CParse("A")
 						Else If CParse("A")
 							class.attrs :| DECL_ABSTRACT
 							class.attrs :| DECL_ABSTRACT
 
 
+						Else If CParse("S")
+							class.attrs :| CLASS_STRUCT
+
 						Else If CParse("AF")
 						Else If CParse("AF")
 							class.attrs :| DECL_ABSTRACT | DECL_FINAL
 							class.attrs :| DECL_ABSTRACT | DECL_FINAL
 
 
@@ -274,8 +281,8 @@ Type TIParser
 							ApplyFunctionAttributes(class, DECL_EXTERN)
 							ApplyFunctionAttributes(class, DECL_EXTERN)
 
 
 						Else If CParse("EW")
 						Else If CParse("EW")
-							class.attrs :| DECL_EXTERN | DECL_API_WIN32 
-							ApplyFunctionAttributes(class, DECL_EXTERN | DECL_API_WIN32)
+							class.attrs :| DECL_EXTERN | DECL_API_STDCALL
+							ApplyFunctionAttributes(class, DECL_EXTERN | DECL_API_STDCALL)
 						
 						
 						Else If CParse("AI")
 						Else If CParse("AI")
 							class.attrs :| CLASS_INTERFACE | DECL_ABSTRACT
 							class.attrs :| CLASS_INTERFACE | DECL_ABSTRACT
@@ -286,14 +293,14 @@ Type TIParser
 							ApplyFunctionAttributes(class, DECL_EXTERN | DECL_ABSTRACT)
 							ApplyFunctionAttributes(class, DECL_EXTERN | DECL_ABSTRACT)
 
 
 						Else If CParse("EIW")
 						Else If CParse("EIW")
-							class.attrs :| DECL_EXTERN | CLASS_INTERFACE | DECL_API_WIN32
-							ApplyFunctionAttributes(class, DECL_EXTERN | DECL_ABSTRACT | DECL_API_WIN32)
+							class.attrs :| DECL_EXTERN | CLASS_INTERFACE | DECL_API_STDCALL
+							ApplyFunctionAttributes(class, DECL_EXTERN | DECL_ABSTRACT | DECL_API_STDCALL)
 
 
 						Else If CParse("ES")
 						Else If CParse("ES")
 							class.attrs :| DECL_EXTERN | CLASS_STRUCT
 							class.attrs :| DECL_EXTERN | CLASS_STRUCT
 
 
 						Else If CParse("ESW")
 						Else If CParse("ESW")
-							class.attrs :| DECL_EXTERN | CLASS_STRUCT | DECL_API_WIN32 
+							class.attrs :| DECL_EXTERN | CLASS_STRUCT | DECL_API_STDCALL
 
 
 						End If
 						End If
 'DebugStop
 'DebugStop
@@ -501,7 +508,7 @@ Type TIParser
 		'If toke Parse toke
 		'If toke Parse toke
 		
 		
 		Local id$=ParseIdent()
 		Local id$=ParseIdent()
-		Local args:TClassDecl[]
+		Local args:String[]
 		Local superTy:TIdentType
 		Local superTy:TIdentType
 		Local imps:TIdentType[]
 		Local imps:TIdentType[]
 
 
@@ -722,7 +729,7 @@ Type TIParser
 		Return str
 		Return str
 	End Method
 	End Method
 
 
-	Method ParseFuncDecl:TFuncDecl( toke$,attrs:Int )
+	Method ParseFuncDecl:TFuncDecl( toke$,attrs:Int, returnType:TType = Null )
 		SetErr
 		SetErr
 
 
 		'If toke Parse toke
 		'If toke Parse toke
@@ -730,31 +737,30 @@ Type TIParser
 		Local id$
 		Local id$
 		Local ty:TType
 		Local ty:TType
 		Local meth:Int = attrs & FUNC_METHOD
 		Local meth:Int = attrs & FUNC_METHOD
-		
-		If attrs & FUNC_METHOD
-			If _toker._toke.tolower() = "new"
-'DebugStop
-				If attrs & DECL_EXTERN
-					Err "Extern classes cannot have constructors"
+
+		If Not returnType Then		
+			If attrs & FUNC_METHOD
+				If _toker._toke.tolower() = "new"
+					If attrs & DECL_EXTERN
+						Err "Extern classes cannot have constructors"
+					EndIf
+					id=_toker._toke
+					NextToke
+					attrs:|FUNC_CTOR
+					attrs:&~FUNC_METHOD
+					ty=ParseDeclType(attrs, True)
+				Else
+					If _toker._tokeType = TOKE_STRINGLIT Then
+						id = ParseStringLit()
+					Else
+						id=ParseIdent()
+					End If
+					ty=ParseDeclType(attrs, True)
 				EndIf
 				EndIf
-				id=_toker._toke
-				NextToke
-				attrs:|FUNC_CTOR
-				attrs:&~FUNC_METHOD
-				ty=ParseDeclType(attrs, True)
 			Else
 			Else
 				id=ParseIdent()
 				id=ParseIdent()
 				ty=ParseDeclType(attrs, True)
 				ty=ParseDeclType(attrs, True)
 			EndIf
 			EndIf
-		Else
-			id=ParseIdent()
-			ty=ParseDeclType(attrs, True)
-		EndIf
-
-		If attrs & FUNC_METHOD
-'DebugLog "Found Method :  " + id
-		Else
-'DebugLog "Found Function :  " + id
 		End If
 		End If
 		
 		
 		Local args:TArgDecl[]
 		Local args:TArgDecl[]
@@ -833,18 +839,92 @@ Type TIParser
 			args=args[..nargs]
 			args=args[..nargs]
 		EndIf
 		EndIf
 		Parse ")"
 		Parse ")"
+		
+		If returnType Then
+			Return New TFuncDecl.CreateF(Null, returnType, args, 0)
+		End If
 
 
+		Local fdecl:TFuncDecl
+		' wait.. so everything until now was a function pointer return type, and we still have to process the function declaration...
+		If _toke = "(" Then
+			Local retTy:TType = New TFunctionPtrType
+			TFunctionPtrType(retTy).func = New TFuncDecl.CreateF("",ty,args,attrs )
+			TFunctionPtrType(retTy).func.attrs :| FUNC_PTR
+			fdecl = ParseFuncDecl("", attrs, retTy)
+			ty = retTy
+		End If
+		
 		Repeat		
 		Repeat		
 			If CParse( "F" )
 			If CParse( "F" )
 				attrs:|DECL_FINAL
 				attrs:|DECL_FINAL
 			Else If CParse( "FW" )
 			Else If CParse( "FW" )
-				attrs:|DECL_FINAL | DECL_API_WIN32
+				attrs:|DECL_FINAL | DECL_API_STDCALL
+			Else If CParse( "FP" )
+				attrs:|DECL_FINAL|DECL_PRIVATE
+			Else If CParse( "FPW" )
+				attrs:|DECL_FINAL|DECL_PRIVATE | DECL_API_STDCALL
+			Else If CParse( "FR" )
+				attrs:|DECL_FINAL|DECL_PROTECTED
+			Else If CParse( "FRW" )
+				attrs:|DECL_FINAL|DECL_PROTECTED | DECL_API_STDCALL
 			Else If CParse( "A" )
 			Else If CParse( "A" )
 				attrs:|DECL_ABSTRACT
 				attrs:|DECL_ABSTRACT
 			Else If CParse( "AW" )
 			Else If CParse( "AW" )
-				attrs:|DECL_ABSTRACT | DECL_API_WIN32
+				attrs:|DECL_ABSTRACT | DECL_API_STDCALL
+			Else If CParse( "AP" )
+				attrs:|DECL_ABSTRACT|DECL_PRIVATE
+			Else If CParse( "APW" )
+				attrs:|DECL_ABSTRACT|DECL_PRIVATE | DECL_API_STDCALL
+			Else If CParse( "AR" )
+				attrs:|DECL_ABSTRACT|DECL_PROTECTED
+			Else If CParse( "ARW" )
+				attrs:|DECL_ABSTRACT|DECL_PROTECTED | DECL_API_STDCALL
 			Else If CParse( "W" )
 			Else If CParse( "W" )
-				attrs:|DECL_API_WIN32
+				attrs:| DECL_API_STDCALL
+			Else If CParse( "O" )
+				attrs:|FUNC_OPERATOR
+			Else If CParse( "OW" )
+				attrs:|FUNC_OPERATOR | DECL_API_STDCALL
+			Else If CParse( "OP" )
+				attrs:|FUNC_OPERATOR|DECL_PRIVATE
+			Else If CParse( "OPW" )
+				attrs:|FUNC_OPERATOR|DECL_PRIVATE | DECL_API_STDCALL
+			Else If CParse( "OR" )
+				attrs:|FUNC_OPERATOR|DECL_PROTECTED
+			Else If CParse( "ORW" )
+				attrs:|FUNC_OPERATOR|DECL_PROTECTED | DECL_API_STDCALL
+			Else If CParse( "P" )
+				attrs:|DECL_PRIVATE
+			Else If CParse( "PW" )
+				attrs:|DECL_PRIVATE | DECL_API_STDCALL
+			Else If CParse( "R" )
+				attrs:|DECL_PROTECTED
+			Else If CParse( "RW" )
+				attrs:|DECL_PROTECTED | DECL_API_STDCALL
+			Else If CParse( "FO" )
+				attrs:|DECL_FINAL|FUNC_OPERATOR
+			Else If CParse( "FOW" )
+				attrs:|DECL_FINAL|FUNC_OPERATOR | DECL_API_STDCALL
+			Else If CParse( "FOP" )
+				attrs:|DECL_FINAL|FUNC_OPERATOR|DECL_PRIVATE
+			Else If CParse( "FOPW" )
+				attrs:|DECL_FINAL|FUNC_OPERATOR|DECL_PRIVATE | DECL_API_STDCALL
+			Else If CParse( "FOR" )
+				attrs:|DECL_FINAL|FUNC_OPERATOR|DECL_PROTECTED
+			Else If CParse( "FORW" )
+				attrs:|DECL_FINAL|FUNC_OPERATOR|DECL_PROTECTED | DECL_API_STDCALL
+			Else If CParse( "AO" )
+				attrs:|DECL_ABSTRACT|FUNC_OPERATOR
+			Else If CParse( "AOW" )
+				attrs:|DECL_ABSTRACT|FUNC_OPERATOR | DECL_API_STDCALL
+			Else If CParse( "AOP" )
+				attrs:|DECL_ABSTRACT|FUNC_OPERATOR|DECL_PRIVATE
+			Else If CParse( "AOPW" )
+				attrs:|DECL_ABSTRACT|FUNC_OPERATOR|DECL_PRIVATE | DECL_API_STDCALL
+			Else If CParse( "AOR" )
+				attrs:|DECL_ABSTRACT|FUNC_OPERATOR|DECL_PROTECTED
+			Else If CParse( "AORW" )
+				attrs:|DECL_ABSTRACT|FUNC_OPERATOR|DECL_PROTECTED | DECL_API_STDCALL
 			'Else If CParse( "property" )
 			'Else If CParse( "property" )
 			'	If attrs & FUNC_METHOD
 			'	If attrs & FUNC_METHOD
 			'		attrs:|FUNC_PROPERTY
 			'		attrs:|FUNC_PROPERTY
@@ -860,7 +940,12 @@ Type TIParser
 		If attrs & FUNC_CTOR Then
 		If attrs & FUNC_CTOR Then
 			funcDecl = New TNewDecl.CreateF( id,ty,args,attrs )
 			funcDecl = New TNewDecl.CreateF( id,ty,args,attrs )
 		Else
 		Else
-			funcDecl = New TFuncDecl.CreateF( id,ty,args,attrs )
+			If fdecl Then
+				funcDecl = fdecl
+				funcDecl.ident = id
+			Else
+				funcDecl = New TFuncDecl.CreateF( id,ty,args,attrs )
+			End If
 		End If
 		End If
 		
 		
 		funcDecl.retType = ty
 		funcDecl.retType = ty
@@ -897,6 +982,11 @@ Type TIParser
 		If CParse(":") Then
 		If CParse(":") Then
 			' ret type
 			' ret type
 			Local rt$=_toker._toke
 			Local rt$=_toker._toke
+
+			If CParse("unsigned") Then
+				rt :+ " " + _toker._toke
+			End If
+
 			NextToke
 			NextToke
 			If CParse("*") Then
 			If CParse("*") Then
 				rt:+ "*"
 				rt:+ "*"
@@ -1029,6 +1119,15 @@ Type TIParser
 					Wend
 					Wend
 
 
 				End If
 				End If
+				
+				If CParse("`") Then
+					If CParse("`") Then
+						attrs :| DECL_PROTECTED
+					Else
+						attrs :| DECL_PRIVATE
+					End If
+				End If
+				
 
 
 Rem
 Rem
 			If CParse( "=" )
 			If CParse( "=" )
@@ -1192,6 +1291,12 @@ End Rem
 				ty = New TLongType
 				ty = New TLongType
 			ElseIf CParse("z") Then
 			ElseIf CParse("z") Then
 				ty = New TSizetType
 				ty = New TSizetType
+			ElseIf CParse("j") Then
+				ty = New TInt128Type
+			ElseIf CParse("w") Then
+				ty = New TWParamType
+			ElseIf CParse("x") Then
+				ty = New TLParamType
 			End If
 			End If
 			
 			
 			If CParse("&") And Not (attrs & DECL_FIELD) Then
 			If CParse("&") And Not (attrs & DECL_FIELD) Then
@@ -1253,6 +1358,14 @@ End Rem
 		Case "!"
 		Case "!"
 			NextToke
 			NextToke
 			ty=New TDoubleType
 			ty=New TDoubleType
+			
+			If CParse("k") Then
+				ty = New TFloat128Type
+			Else If CParse("m") Then
+				ty = New TDouble128Type
+			Else If CParse("h") Then
+				ty = New TFloat64Type
+			End If
 
 
 			If CParse("&")  And Not (attrs & DECL_FIELD) Then
 			If CParse("&")  And Not (attrs & DECL_FIELD) Then
 				attrs :| DECL_GLOBAL
 				attrs :| DECL_GLOBAL
@@ -1460,6 +1573,66 @@ End Rem
 			Wend
 			Wend
 			Return ty
 			Return ty
 		End If
 		End If
+		If CParse( "int128" )
+			Local ty:TType = New TInt128Type
+			While CParse("ptr")
+				ty = TType.MapToPointerType(ty)
+			Wend
+			While CParse( "*" )
+				ty = TType.MapToPointerType(ty)
+			Wend
+			Return ty
+		End If
+		If CParse( "float64" )
+			Local ty:TType = New TFloat64Type
+			While CParse("ptr")
+				ty = TType.MapToPointerType(ty)
+			Wend
+			While CParse( "*" )
+				ty = TType.MapToPointerType(ty)
+			Wend
+			Return ty
+		End If
+		If CParse( "float128" )
+			Local ty:TType = New TFloat128Type
+			While CParse("ptr")
+				ty = TType.MapToPointerType(ty)
+			Wend
+			While CParse( "*" )
+				ty = TType.MapToPointerType(ty)
+			Wend
+			Return ty
+		End If
+		If CParse( "double128" )
+			Local ty:TType = New TDouble128Type
+			While CParse("ptr")
+				ty = TType.MapToPointerType(ty)
+			Wend
+			While CParse( "*" )
+				ty = TType.MapToPointerType(ty)
+			Wend
+			Return ty
+		End If
+		If CParse( "wparam" )
+			Local ty:TType = New TWParamType
+			While CParse("ptr")
+				ty = TType.MapToPointerType(ty)
+			Wend
+			While CParse( "*" )
+				ty = TType.MapToPointerType(ty)
+			Wend
+			Return ty
+		End If
+		If CParse( "lparam" )
+			Local ty:TType = New TLParamType
+			While CParse("ptr")
+				ty = TType.MapToPointerType(ty)
+			Wend
+			While CParse( "*" )
+				ty = TType.MapToPointerType(ty)
+			Wend
+			Return ty
+		End If
 		Return ParseIdentType()
 		Return ParseIdentType()
 	End Method
 	End Method
 	
 	

+ 7 - 2
options.bmx

@@ -1,4 +1,4 @@
-' Copyright (c) 2013-2016 Bruce A Henderson
+' Copyright (c) 2013-2017 Bruce A Henderson
 '
 '
 ' Based on the public domain Monkey "trans" by Mark Sibly
 ' Based on the public domain Monkey "trans" by Mark Sibly
 '
 '
@@ -25,7 +25,7 @@ SuperStrict
 
 
 Import "base.configmap.bmx"
 Import "base.configmap.bmx"
 
 
-Const version:String = "0.77"
+Const version:String = "0.88"
 
 
 Const BUILDTYPE_APP:Int = 0
 Const BUILDTYPE_APP:Int = 0
 Const BUILDTYPE_MODULE:Int = 1
 Const BUILDTYPE_MODULE:Int = 1
@@ -101,6 +101,9 @@ Global opt_strictupgrade:Int = True
 '    generate warnings (and accept) instead of errors for calling methods with arguments that need to be cast down.
 '    generate warnings (and accept) instead of errors for calling methods with arguments that need to be cast down.
 '    May cause issues using overloaded methods.
 '    May cause issues using overloaded methods.
 Global opt_warnover:Int = False
 Global opt_warnover:Int = False
+' musl libc support
+'    
+Global opt_musl:Int = False
 
 
 Global opt_filepath:String
 Global opt_filepath:String
 
 
@@ -194,6 +197,8 @@ Function ParseArgs:String[](args:String[])
 				opt_gdbdebug=True
 				opt_gdbdebug=True
 			Case "w"
 			Case "w"
 				opt_warnover=True
 				opt_warnover=True
+			Case "musl"
+				opt_musl=True
 		End Select
 		End Select
 	
 	
 		count:+ 1
 		count:+ 1

File diff ditekan karena terlalu besar
+ 440 - 266
parser.bmx


+ 55 - 6
stmt.bmx

@@ -1,4 +1,4 @@
-' Copyright (c) 2013-2016 Bruce A Henderson
+' Copyright (c) 2013-2017 Bruce A Henderson
 '
 '
 ' Based on the public domain Monkey "trans" by Mark Sibly
 ' Based on the public domain Monkey "trans" by Mark Sibly
 '
 '
@@ -124,22 +124,49 @@ Type TAssignStmt Extends TStmt
 						rhs=rhs.Cast( lhs.exprType )
 						rhs=rhs.Cast( lhs.exprType )
 						splitOp = False
 						splitOp = False
 						
 						
-					Case "*=","/=","+=","-="
+					Case ":*",":/",":+",":-"
 					
 					
 						If TNumericType( lhs.exprType ) And lhs.exprType.EqualsType( rhs.exprType ) Then
 						If TNumericType( lhs.exprType ) And lhs.exprType.EqualsType( rhs.exprType ) Then
 							splitOp = False
 							splitOp = False
 						End If
 						End If
+						
+						If TObjectType(lhs.exprType) Then
+							Local args:TExpr[] = [rhs]
+							Try
+								Local decl:TFuncDecl = TFuncDecl(TObjectType(lhs.exprType).classDecl.FindFuncDecl(op, args,,,,True,SCOPE_CLASS_HEIRARCHY))
+								If decl Then
+									lhs = New TInvokeMemberExpr.Create( lhs, decl, args ).Semant()
+									rhs = Null
+									Return
+								End If
+							Catch error:String
+								Err "Operator " + op + " cannot be used with Objects."
+							End Try
+						End If
 					
 					
-					Case "&=","|=","^=","<<=",">>=","%="
+					Case ":&",":|",":^",":shl",":shr",":mod"
 					
 					
-						If TIntType( lhs.exprType ) And lhs.exprType.EqualsType( rhs.exprType ) Then
+						If (TIntType( lhs.exprType ) And lhs.exprType.EqualsType( rhs.exprType ))  Or TObjectType(lhs.exprType) Then
 							splitOp = False
 							splitOp = False
 						End If
 						End If
-				
+
+						If TObjectType(lhs.exprType) Then
+							Local args:TExpr[] = [rhs]
+							Try
+								Local decl:TFuncDecl = TFuncDecl(TObjectType(lhs.exprType).classDecl.FindFuncDecl(op, args,,,,,SCOPE_CLASS_HEIRARCHY))
+								If decl Then
+									lhs = New TInvokeMemberExpr.Create( lhs, decl, args ).Semant()
+									rhs = Null
+									Return
+								End If
+							Catch error:String
+								Err "Operator " + op + " cannot be used with Objects."
+							End Try
+						End If
 				End Select
 				End Select
 				
 				
 				If splitOp Then
 				If splitOp Then
-					rhs = New TBinaryMathExpr.Create(op[..op.length - 1], lhs, rhs).Semant().Cast(lhs.exprType)
+					rhs = New TBinaryMathExpr.Create(op[1..], lhs, rhs).Semant().Cast(lhs.exprType)
 					op = "="
 					op = "="
 				End If
 				End If
 				
 				
@@ -192,6 +219,9 @@ Type TReturnStmt Extends TStmt
 	Method OnSemant()
 	Method OnSemant()
 		Local fdecl:TFuncDecl=_env.FuncScope()
 		Local fdecl:TFuncDecl=_env.FuncScope()
 		If expr
 		If expr
+			If TIdentExpr(expr) Then
+				TIdentExpr(expr).isRhs = True
+			End If
 			If fdecl.IsCtor() Err "Constructors may not return a value."
 			If fdecl.IsCtor() Err "Constructors may not return a value."
 			If TVoidType( fdecl.retType ) Then
 			If TVoidType( fdecl.retType ) Then
 				Local errorText:String = "Function can not return a value."
 				Local errorText:String = "Function can not return a value."
@@ -688,3 +718,22 @@ Type TRestoreDataStmt Extends TStmt
 	
 	
 End Type
 End Type
 
 
+Type TNativeStmt Extends TStmt
+	Field raw:String
+	
+	Method Create:TNativeStmt( raw:String )
+		Self.raw = raw
+		Return Self
+	End Method
+
+	Method OnCopy:TStmt( scope:TScopeDecl )
+		Return New TNativeStmt.Create( raw )
+	End Method
+		
+	Method OnSemant()
+	End Method
+
+	Method Trans$()
+		Return _trans.TransNativeStmt( Self )
+	End Method
+End Type

+ 1 - 1
stringbuffer_common.bmx

@@ -1,4 +1,4 @@
-' Copyright (c) 2016 Bruce A Henderson
+' Copyright (c) 2016-2017 Bruce A Henderson
 ' 
 ' 
 ' Permission is hereby granted, free of charge, to any person obtaining a copy
 ' Permission is hereby granted, free of charge, to any person obtaining a copy
 ' of this software and associated documentation files (the "Software"), to deal
 ' of this software and associated documentation files (the "Software"), to deal

+ 1 - 1
stringbuffer_core.bmx

@@ -1,4 +1,4 @@
-' Copyright (c) 2016 Bruce A Henderson
+' Copyright (c) 2016-2017 Bruce A Henderson
 ' 
 ' 
 ' Permission is hereby granted, free of charge, to any person obtaining a copy
 ' Permission is hereby granted, free of charge, to any person obtaining a copy
 ' of this software and associated documentation files (the "Software"), to deal
 ' of this software and associated documentation files (the "Software"), to deal

+ 1 - 1
stringbuffer_glue.c

@@ -1,5 +1,5 @@
 /*
 /*
-  Copyright (c) 2016 Bruce A Henderson
+  Copyright (c) 2016-2017 Bruce A Henderson
  
  
   Permission is hereby granted, free of charge, to any person obtaining a copy
   Permission is hereby granted, free of charge, to any person obtaining a copy
   of this software and associated documentation files (the "Software"), to deal
   of this software and associated documentation files (the "Software"), to deal

+ 17 - 0
tests/framework/language/function_02.bmx

@@ -0,0 +1,17 @@
+'Test for nested functions
+'Source: https://github.com/bmx-ng/bcc/issues/255
+'Author: HurryStarfish
+SuperStrict
+Framework BRL.StandardIO
+
+Type T
+	Function F1()
+		Function G()
+		End Function
+	End Function
+	
+	Function F2()
+		Function G()
+		End Function
+	End Function
+End Type

+ 25 - 0
tests/framework/language/function_03.bmx

@@ -0,0 +1,25 @@
+'Test for nested functions
+'Source: https://github.com/bmx-ng/bcc/issues/251
+'Author: HurryStarfish
+SuperStrict
+Framework BRL.Blitz
+
+Function F()
+	G
+	Function G()
+		F
+	End Function
+End Function
+
+
+
+Function F2()
+	G2
+	Function G2()
+		H2
+	End Function
+End Function
+
+Function H2()
+	F2
+End Function

+ 22 - 0
tests/framework/language/inheritance_03.extend.overridereturn.bmx

@@ -0,0 +1,22 @@
+SuperStrict
+Framework Brl.StandardIO
+
+Type TBase
+	Field child:TBase
+
+	Method MyChildren:TBase[](param:Int, param2:String)
+		Return [child]
+	End Method
+End Type
+	
+
+Type TExtend Extends TBase
+	Method MyChildren:TExtend[](param:Int, param2:String)
+		Local children:TBase[] = Super.MyChildren(param, param2)
+		Local result:TExtend[]
+		For Local e:TExtend = EachIn children
+			result :+ [e]
+		Next
+		Return result
+	End Method
+End Type

+ 11 - 0
tests/framework/language/label_01.bmx

@@ -0,0 +1,11 @@
+'Test for nested functions
+'Source: https://github.com/bmx-ng/bcc/issues/236
+'Author: HurryStarfish
+SuperStrict
+Framework BRL.StandardIO
+
+#Loop
+For Local a:Int = EachIn [1, 2, 3]
+	If a = 2 Then Exit Loop
+	Print a
+Next

+ 4 - 0
tests/framework/language/metadata_01.bmx

@@ -1,6 +1,7 @@
 Rem
 Rem
 	This test checks:
 	This test checks:
 	- if you can define "metadata" {meta="bla"}
 	- if you can define "metadata" {meta="bla"}
+	- if you use an "empty" meta tag
 End Rem
 End Rem
 SuperStrict
 SuperStrict
 Framework BRL.StandardIO
 Framework BRL.StandardIO
@@ -12,4 +13,7 @@ Type TMyClass {typemetadata="available"}
 
 
 	Function myfunc:int() {funcmetadata="available"}
 	Function myfunc:int() {funcmetadata="available"}
 	End Function
 	End Function
+
+	Function emptyfunc:int() {}
+	End Function
 End Type
 End Type

+ 9 - 0
tests/framework/language/pointer_02.bmx

@@ -0,0 +1,9 @@
+'Test for negative array indices
+'Source: https://github.com/bmx-ng/bcc/issues/248
+'Author: HurryStarfish
+SuperStrict
+Framework BRL.StandardIO
+
+Local a:Int[] = [7,8,9]
+Local p:Int Ptr = Varptr a[1]
+Print p[-1]

+ 1 - 0
tests/framework/language/pointer_02.res

@@ -0,0 +1 @@
+7

+ 85 - 40
toker.bmx

@@ -1,4 +1,4 @@
-' Copyright (c) 2013-2016 Bruce A Henderson
+' Copyright (c) 2013-2017 Bruce A Henderson
 '
 '
 ' Based on the public domain Monkey "trans" by Mark Sibly
 ' Based on the public domain Monkey "trans" by Mark Sibly
 '
 '
@@ -38,29 +38,19 @@ Const TOKE_STRINGLITEX:Int=7
 Const TOKE_SYMBOL:Int=8
 Const TOKE_SYMBOL:Int=8
 Const TOKE_LINECOMMENT:Int=9
 Const TOKE_LINECOMMENT:Int=9
 Const TOKE_LONGLIT:Int=10
 Const TOKE_LONGLIT:Int=10
+Const TOKE_NATIVE:Int=11
 
 
 '***** Tokenizer *****
 '***** Tokenizer *****
 Type TToker
 Type TToker
 
 
-	Const _keywords$=";"+ ..
-	"strict;superstrict;"+ ..
-	"public;private;"+ ..
-	"short;int;float;double;long;string;object;ptr;var;varptr;mod;continue;exit;"+ ..
-	"include;import;module;extern;framework;"+ ..
-	"new;self;super;eachin;true;false;null;not;"+ ..
-	"extends;abstract;select;case;default;"+ ..
-	"const;local;global;field;method;function;type;"+ ..
-	"and;or;shl;shr;sar;end;if;then;else;elseif;endif;while;wend;repeat;until;forever;"+ ..
-	"for;to;step;next;return;"+ ..
-	"alias;rem;endrem;throw;assert;try;catch;nodebug;incbin;"+ ..
-	"endselect;endmethod;endfunction;endtype;endextern;endtry;endwhile;pi;release;defdata;readdata;restoredata;" + ..
-	"interface;endinterface;implements;"+ ..
-	"size_t;uint;ulong;struct;endstruct;"
-
-	Global _symbols$[]=[ "..","[]",":*",":/",":+",":-",":|",":&",":~~",":shr",":shl",":sar",":mod" ]
-	Global _symbols_map$[]=[ "..","[]","*=","/=","+=","-=","|=","&=","^=",">>=", "<<=",">>=","%=" ]
-	'Global _symbols$[]=[ "..","[]",":=",":*",":/",":+",":-",":|",":&",":~~" ]
-	'Global _symbols_map$[]=[ "..","[]",":=","*=","/=","+=","-=","|=","&=","~~=" ]
+	Const __keywords$="strict,superstrict,public,private,protected,short,int,float,double,long,string,object,ptr,var,varptr," + ..
+		"mod,continue,exit,include,import,module,extern,framework,new,self,super,eachin,true,false," + ..
+		"null,not,extends,abstract,select,case,default,const,local,global,field,method,function,type," + ..
+		"and,or,shl,shr,sar,end,if,then,else,elseif,endif,while,wend,repeat,until,forever,for,to,step," + ..
+		"next,return,alias,rem,endrem,throw,assert,try,catch,nodebug,incbin,endselect,endmethod," + ..
+		"endfunction,endtype,endextern,endtry,endwhile,pi,release,defdata,readdata,restoredata,interface," + ..
+		"endinterface,implements,size_t,uint,ulong,struct,endstruct,operator"
+	Global _keywords:TMap
 
 
 	Field _path$
 	Field _path$
 	Field _line:Int
 	Field _line:Int
@@ -83,9 +73,19 @@ Type TToker
 		_tokePos=0
 		_tokePos=0
 		_lines = source.split("~n")
 		_lines = source.split("~n")
 		_preprocess = preprocess
 		_preprocess = preprocess
+		If Not _keywords Then
+			initKeywords()
+		End If
 		Return Self
 		Return Self
 	End Method
 	End Method
 	
 	
+	Method initKeywords()
+		_keywords = New TMap
+		For Local k:String = EachIn __keywords.Split(",")
+			_keywords.Insert(k, "")
+		Next
+	End Method
+	
 	Method rollback(pos:Int, toketype:Int = -1)
 	Method rollback(pos:Int, toketype:Int = -1)
 		_tokePos = pos
 		_tokePos = pos
 		If toketype >= 0
 		If toketype >= 0
@@ -147,7 +147,7 @@ Type TToker
 			Wend
 			Wend
 			_toke=_source[start.._tokePos]
 			_toke=_source[start.._tokePos]
 			_tokeLower = _toke.ToLower()
 			_tokeLower = _toke.ToLower()
-			If _keywords.Contains( ";"+_tokeLower+";" )
+			If _keywords.Contains( _tokeLower )
 				_tokeType=TOKE_KEYWORD
 				_tokeType=TOKE_KEYWORD
 
 
 				If Not _lookingForEndRem And _tokeLower = "rem" Then
 				If Not _lookingForEndRem And _tokeLower = "rem" Then
@@ -169,10 +169,12 @@ Type TToker
 					_tokePos:+1
 					_tokePos:+1
 				Wend
 				Wend
 			EndIf
 			EndIf
-			If TSTR().ToLower()="e"
+			Local _tstr:String = TSTR()
+			If _tstr="e" Or _tstr="E" Then
 				_tokeType=TOKE_FLOATLIT
 				_tokeType=TOKE_FLOATLIT
 				_tokePos:+1
 				_tokePos:+1
-				If TSTR()="+" Or TSTR()="-" _tokePos:+1
+				_tstr = TSTR()
+				If _tstr="+" Or _tstr="-" _tokePos:+1
 				While IsDigit( TCHR() )
 				While IsDigit( TCHR() )
 					_tokePos:+1
 					_tokePos:+1
 				Wend
 				Wend
@@ -194,39 +196,59 @@ Type TToker
 			Wend
 			Wend
 		Else If str="~q"
 		Else If str="~q"
 			_tokeType=TOKE_STRINGLIT
 			_tokeType=TOKE_STRINGLIT
-			While TSTR() And TSTR()<>"~q"
+			Local _tstr:String = TSTR()
+			While _tstr And _tstr<>"~q"
 				' Strings can't cross line boundries
 				' Strings can't cross line boundries
-				If TSTR()="~n" Then
+				If _tstr="~n" Then
 					_tokePos:-1
 					_tokePos:-1
 					Exit
 					Exit
 				End If
 				End If
 				_tokePos:+1
 				_tokePos:+1
+				_tstr = TSTR()
 			Wend
 			Wend
 			If _tokePos<_source.Length _tokePos:+1 Else _tokeType=TOKE_STRINGLITEX
 			If _tokePos<_source.Length _tokePos:+1 Else _tokeType=TOKE_STRINGLITEX
 		Else If str="'"
 		Else If str="'"
-			_tokeType=TOKE_LINECOMMENT
-			
-			SkipToEOL()
-
-			' completely ignore line comments
-			If TSTR()="~n" Then
-				start = _tokePos
-				If _tokePos<_source.Length
+			Local _tstr:String = TSTR()
+			If _tstr="!" Then
+		
+				_tokeType=TOKE_NATIVE
+				
+				While _tstr 
+					If _tstr="~n" Then
+						_tokePos:-1
+						Exit
+					End If
 					_tokePos:+1
 					_tokePos:+1
+					_tstr = TSTR()
+				Wend
+		
+			Else
+				_tokeType=TOKE_LINECOMMENT
+				
+				SkipToEOL()
+	
+				' completely ignore line comments
+				If TSTR()="~n" Then
+					start = _tokePos
+					If _tokePos<_source.Length
+						_tokePos:+1
+					End If
+					_line:+1
+					_tokeType=TOKE_SYMBOL
 				End If
 				End If
-				_line:+1
-				_tokeType=TOKE_SYMBOL
 			End If
 			End If
-
 		Else If str="." And TSTR()="." Then
 		Else If str="." And TSTR()="." Then
 			Local pos:Int = _tokePos
 			Local pos:Int = _tokePos
 			Local isValidTilEOL:Int = True
 			Local isValidTilEOL:Int = True
 			_tokePos:+1
 			_tokePos:+1
-			While TSTR() And TSTR()<>"~n"
+			
+			Local _tstr:String = TSTR()
+			While _tstr And _tstr<>"~n"
 				If Not IsSpace(TCHR()) Then
 				If Not IsSpace(TCHR()) Then
 					isValidTilEOL = False
 					isValidTilEOL = False
 				End If
 				End If
 				_tokePos:+1
 				_tokePos:+1
+				_tstr = TSTR()
 			Wend
 			Wend
 			
 			
 			If Not isValidTilEOL Or _preprocess Then
 			If Not isValidTilEOL Or _preprocess Then
@@ -239,7 +261,6 @@ Type TToker
 				_line:+1
 				_line:+1
 				_tokeType=TOKE_SPACE
 				_tokeType=TOKE_SPACE
 			End If
 			End If
-			
 		Else
 		Else
 
 
 			_tokeType=TOKE_SYMBOL
 			_tokeType=TOKE_SYMBOL
@@ -348,12 +369,36 @@ Type TToker
 'Private
 'Private
 
 
 	Method TCHR:Int( i:Int=0 )
 	Method TCHR:Int( i:Int=0 )
-		If _tokePos+i<_source.Length Return _source[_tokePos+i]
+		If _lastIndex <> _tokePos+i Then
+			_lastIndex = _tokePos+i
+			If _lastIndex < _source.Length Then
+				_lastTCHR = _source[_lastIndex]
+				_lastTSTR = Chr( _lastTCHR )
+			Else
+				_lastTCHR = 0
+				_lastTSTR = ""
+			End If
+		End If
+		Return _lastTCHR
 	End Method
 	End Method
 	
 	
+	Field _lastIndex:Int = -1
+	Field _lastTCHR:Int
+	
 	Method TSTR$( i:Int=0 )
 	Method TSTR$( i:Int=0 )
-		If _tokePos+i<_source.Length Return Chr( _source[_tokePos+i] )
+		If _lastIndex <> _tokePos+i Then
+			_lastIndex = _tokePos+i
+			If _lastIndex < _source.Length Then
+				_lastTCHR = _source[_lastIndex]
+				_lastTSTR = Chr( _lastTCHR )
+			Else
+				_lastTCHR = 0
+				_lastTSTR = ""
+			End If
+		End If
+		Return _lastTSTR
 	End Method
 	End Method
 	
 	
+	Field _lastTSTR:String
 	
 	
 End Type
 End Type

+ 1 - 1
transform.c

@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2016 Bruce A Henderson
+/* Copyright (c) 2014-2017 Bruce A Henderson
 
 
   This software is provided 'as-is', without any express or implied
   This software is provided 'as-is', without any express or implied
   warranty. In no event will the authors be held liable for any damages
   warranty. In no event will the authors be held liable for any damages

+ 119 - 36
translator.bmx

@@ -1,4 +1,4 @@
-' Copyright (c) 2013-2016 Bruce A Henderson
+' Copyright (c) 2013-2017 Bruce A Henderson
 '
 '
 ' Based on the public domain Monkey "trans" by Mark Sibly
 ' Based on the public domain Monkey "trans" by Mark Sibly
 '
 '
@@ -58,8 +58,6 @@ Type TTranslator
 	
 	
 	Field processingReturnStatement:Int
 	Field processingReturnStatement:Int
 
 
-	Field _inBinary:Int
-
 	Method PushVarScope()
 	Method PushVarScope()
 		varStack.Push customVarStack
 		varStack.Push customVarStack
 		customVarStack = New TStack
 		customVarStack = New TStack
@@ -191,7 +189,13 @@ Type TTranslator
 		If TLongType( ty ) Return p + "l"
 		If TLongType( ty ) Return p + "l"
 		If TULongType( ty ) Return p + "y"
 		If TULongType( ty ) Return p + "y"
 		If TSizeTType( ty ) Return p + "z"
 		If TSizeTType( ty ) Return p + "z"
+		If TFloat64Type( ty ) Return p + "h"
+		If TFloat128Type( ty ) Return p + "k"
+		If TInt128Type( ty ) Return p + "j"
+		If TDouble128Type( ty ) Return p + "m"
 		If TStringType( ty ) Return p + "S"
 		If TStringType( ty ) Return p + "S"
+		If TWParamType( ty ) Return p + "W"
+		If TLParamType( ty ) Return p + "L"
 		If TArrayType( ty ) Then
 		If TArrayType( ty ) Then
 			Return p + "a" + TransMangleType(TArrayType( ty ).elemType)
 			Return p + "a" + TransMangleType(TArrayType( ty ).elemType)
 		End If
 		End If
@@ -216,10 +220,12 @@ Type TTranslator
 '			Next
 '			Next
 			Return s + "_" + TransMangleType(func.retType) + "_"
 			Return s + "_" + TransMangleType(func.retType) + "_"
 		End If
 		End If
+		
+		Err "Unsupported type for name mangling : " + ty.ToString()
 	End Method
 	End Method
 
 
 	Method MangleMethod:String(fdecl:TFuncDecl)
 	Method MangleMethod:String(fdecl:TFuncDecl)
-		If fdecl.IsMethod() Or fdecl.IsCtor() Then
+		If (fdecl.IsMethod() And Not fdecl.ClassScope().IsStruct())Or fdecl.IsCtor() Then
 			Return MangleMethodArgs(fdecl)
 			Return MangleMethodArgs(fdecl)
 		Else
 		Else
 			Return MangleMethodRetType(fdecl) + MangleMethodArgs(fdecl)
 			Return MangleMethodRetType(fdecl) + MangleMethodArgs(fdecl)
@@ -306,7 +312,7 @@ Type TTranslator
 		Local funcs:TFuncDeclList=TFuncDeclList(funcMungs.ValueForKey( fdecl.ident ))
 		Local funcs:TFuncDeclList=TFuncDeclList(funcMungs.ValueForKey( fdecl.ident ))
 		If funcs
 		If funcs
 			For Local tdecl:TFuncDecl=EachIn funcs
 			For Local tdecl:TFuncDecl=EachIn funcs
-				If fdecl.EqualsArgs( tdecl )
+				If fdecl.EqualsArgs( tdecl ) And fdecl.scope = tdecl.scope
 					fdecl.munged=tdecl.munged
 					fdecl.munged=tdecl.munged
 					Return
 					Return
 				EndIf
 				EndIf
@@ -317,7 +323,13 @@ Type TTranslator
 		EndIf
 		EndIf
 
 
 		If fdecl.scope Then
 		If fdecl.scope Then
-			fdecl.munged = fdecl.scope.munged + "_" + fdecl.ident
+			Local id:String = fdecl.ident
+
+			If fdecl.attrs & FUNC_OPERATOR Then
+				id = MungSymbol(id)
+			End If
+			
+			fdecl.munged = fdecl.scope.munged + "_" + id
 			
 			
 			If Not equalsBuiltInFunc(fdecl.classScope(), fdecl) And Not fdecl.noMangle Then
 			If Not equalsBuiltInFunc(fdecl.classScope(), fdecl) And Not fdecl.noMangle Then
 				fdecl.munged :+ MangleMethod(fdecl)
 				fdecl.munged :+ MangleMethod(fdecl)
@@ -335,6 +347,58 @@ Type TTranslator
 		funcs.AddLast fdecl
 		funcs.AddLast fdecl
 	End Method
 	End Method
 	
 	
+	Method MungSymbol:String(sym:String)
+		Select sym
+			Case "*"
+				Return "_mul"
+			Case "/"
+				Return "_div"
+			Case "+"
+				Return "_add"
+			Case "-"
+				Return "_sub"
+			Case "&"
+				Return "_and"
+			Case "|"
+				Return "_or"
+			Case "~~"
+				Return "_xor"
+			Case ":*"
+				Return "_muleq"
+			Case ":/"
+				Return "_diveq"
+			Case ":+"
+				Return "_addeq"
+			Case ":-"
+				Return "_subeq"
+			Case ":&"
+				Return "_andeq"
+			Case ":|"
+				Return "_oreq"
+			Case ":~~"
+				Return "_xoreq"
+			Case "<"
+				Return "_lt"
+			Case "<="
+				Return "_le"
+			Case ">"
+				Return "_gt"
+			Case ">="
+				Return "_ge"
+			Case "="
+				Return "_eq"
+			Case "<>"
+				Return "_ne"
+			Case "mod"
+				Return "_mod"
+			Case "shl"
+				Return "_shl"
+			Case "shr"
+				Return "_shr"
+		End Select
+		Return "?? unknown symbol ?? : " + sym
+	End Method
+	
 	Method MungDecl( decl:TDecl, addIfNotInScope:Int = False )
 	Method MungDecl( decl:TDecl, addIfNotInScope:Int = False )
 
 
 		If decl.munged Then
 		If decl.munged Then
@@ -562,6 +626,7 @@ End Rem
 	
 	
 	Method TransBinaryOp$( op$,rhs$ )
 	Method TransBinaryOp$( op$,rhs$ )
 'DebugLog "TransBinaryOp '" + op + "' : '" + rhs + "'"
 'DebugLog "TransBinaryOp '" + op + "' : '" + rhs + "'"
+op = mapSymbol(op)
 		Select op
 		Select op
 		Case "+","-"
 		Case "+","-"
 			If rhs.StartsWith( op ) Return op+" "
 			If rhs.StartsWith( op ) Return op+" "
@@ -587,11 +652,12 @@ End Rem
 	End Method
 	End Method
 	
 	
 	Method TransAssignOp$( op$ )
 	Method TransAssignOp$( op$ )
+op = mapSymbol(op)
 		Select op
 		Select op
-		Case "mod=" Return "%="
-		Case "shl=" Return "<<="
-		Case "shr=" Return ">>="
-		Case "sar=" Return ">>="
+		Case ":mod" Return "%="
+		Case ":shl" Return "<<="
+		Case ":shr" Return ">>="
+		Case ":sar" Return ">>="
 		End Select
 		End Select
 		Return op
 		Return op
 	End Method
 	End Method
@@ -643,10 +709,10 @@ End Rem
 		Return CreateLocal( expr )
 		Return CreateLocal( expr )
 	End Method
 	End Method
 	
 	
-	Method CreateLocal$( expr:TExpr )
-		Local tmp:TLocalDecl=New TLocalDecl.Create( "",expr.exprType,expr, True )
+	Method CreateLocal$( expr:TExpr, init:Int = True, vol:Int = True )
+		Local tmp:TLocalDecl=New TLocalDecl.Create( "",expr.exprType,expr, True, , vol )
 		MungDecl tmp
 		MungDecl tmp
-		Emit TransLocalDecl( tmp,expr, True )+";"
+		Emit TransLocalDecl( tmp,expr, True, init )+";"
 
 
 		EmitGDBDebug(_errInfo)
 		EmitGDBDebug(_errInfo)
 		
 		
@@ -655,7 +721,7 @@ End Rem
 
 
 	'***** Utility *****
 	'***** Utility *****
 
 
-	Method TransLocalDecl$( decl:TLocalDecl,init:TExpr, declare:Int = False ) Abstract
+	Method TransLocalDecl$( decl:TLocalDecl,init:TExpr, declare:Int = False, outputInit:Int = True ) Abstract
 
 
 	Method TransGlobalDecl$( gdecl:TGlobalDecl ) Abstract
 	Method TransGlobalDecl$( gdecl:TGlobalDecl ) Abstract
 	
 	
@@ -711,7 +777,7 @@ End Rem
 	
 	
 	Method EmitLocalDeclarations(decl:TScopeDecl, v:TValDecl = Null) Abstract
 	Method EmitLocalDeclarations(decl:TScopeDecl, v:TValDecl = Null) Abstract
 	
 	
-	Method TransType$( ty:TType, ident:String) Abstract
+	Method TransType$( ty:TType, ident:String, fpReturnTypeFunctionArgs:String = Null, fpReturnTypeClassFunc:Int = False) Abstract
 	
 	
 	Method BeginLocalScope()
 	Method BeginLocalScope()
 		mungStack.Push mungScope
 		mungStack.Push mungScope
@@ -811,6 +877,8 @@ End Rem
 		
 		
 		If TFieldDecl( decl ) Return TransField( TFieldDecl( decl ),expr.expr )
 		If TFieldDecl( decl ) Return TransField( TFieldDecl( decl ),expr.expr )
 
 
+		If TGlobalDecl( decl ) Return TransGlobal( TGlobalDecl( decl ) )
+
 		InternalErr
 		InternalErr
 	End Method
 	End Method
 	
 	
@@ -820,12 +888,16 @@ End Rem
 		If Not decl.munged Then
 		If Not decl.munged Then
 			MungDecl decl
 			MungDecl decl
 		End If
 		End If
-
-		If (decl.attrs & FUNC_PTR) And (decl.attrs & FUNC_INIT) And Not expr.InvokedWithBraces Return decl.munged
 		
 		
-		If ((decl.attrs & FUNC_PTR) Or (expr.decl.attrs & FUNC_PTR)) And Not expr.InvokedWithBraces Return decl.munged
+		'If (decl.attrs & FUNC_PTR) And (decl.attrs & FUNC_INIT) And Not expr.InvokedWithBraces Return decl.munged
+		
+		'If ((decl.attrs & FUNC_PTR) Or (expr.decl.attrs & FUNC_PTR)) And Not expr.InvokedWithBraces Return decl.munged
 		
 		
-		If Not expr.InvokedWithBraces And expr.IsRhs And Not expr.args Return decl.munged
+		'If Not expr.InvokedWithBraces And expr.IsRhs Return decl.munged
+		
+		' if the call was a statement (even one written without parentheses), then invokedWithBraces is true
+		' so no complicated checks are needed here; if invokedWithBraces is false, this is definitely not a call
+		If Not expr.InvokedWithBraces Then Return decl.munged
 		
 		
 		If decl.munged.StartsWith( "$" ) Return TransIntrinsicExpr( decl,Null,expr.args )
 		If decl.munged.StartsWith( "$" ) Return TransIntrinsicExpr( decl,Null,expr.args )
 		
 		
@@ -883,6 +955,14 @@ End Rem
 			expr.args=expr.CastArgs( expr.args,TFuncDecl(decl) )
 			expr.args=expr.CastArgs( expr.args,TFuncDecl(decl) )
 			Return expr.expr.Trans() + TransArgs(expr.args, TFuncDecl(decl))
 			Return expr.expr.Trans() + TransArgs(expr.args, TFuncDecl(decl))
 		End If
 		End If
+
+		' hmmm, complicated - a function returning and invoking a function pointer...		
+		If TInvokeExpr(expr.expr) And TFunctionPtrType(TInvokeExpr(expr.expr).exprType) Then
+			Local decl:TDecl = TFunctionPtrType(TInvokeExpr(expr.expr).exprType).func.actual
+			decl.Semant()
+			expr.args=expr.CastArgs( expr.args,TFuncDecl(decl) )
+			Return expr.expr.Trans() + TransArgs(expr.args, TFuncDecl(decl))
+		End If
 		
 		
 		InternalErr
 		InternalErr
 	End Method
 	End Method
@@ -915,19 +995,26 @@ End Rem
 
 
 			Else
 			Else
 				
 				
-				Local s:String = stmt.expr.Trans()
-				
-				' we have some temp variables that need to be freed before we can return
-				' put the results into a new variable, and return that.
-				If customVarStack.Count() > 0 Then
-					If Not TFunctionPtrType( stmt.expr.exprType ) Then
-						Emit TransType(stmt.expr.exprType, "rt_") + " rt_ = " + s + ";"
+				If TSelfExpr(stmt.expr) And TObjectType(TSelfExpr(stmt.expr).exprType).classDecl And TObjectType(TSelfExpr(stmt.expr).exprType).classDecl.IsStruct() Then
+					t :+ Bra("*" + stmt.expr.Trans())
+				Else If TObjectType(stmt.expr.exprType) And TObjectType(stmt.expr.exprType).classDecl.IsStruct() And TConstExpr(stmt.expr) And Not TConstExpr(stmt.expr).value Then
+					Local lvar:String = CreateLocal(stmt.expr)
+					t :+ " " + lvar
+				Else
+					Local s:String = stmt.expr.Trans()
+					
+					' we have some temp variables that need to be freed before we can return
+					' put the results into a new variable, and return that.
+					If customVarStack.Count() > 0 Then
+						If Not TFunctionPtrType( stmt.expr.exprType ) Then
+							Emit TransType(stmt.expr.exprType, "rt_") + " rt_ = " + s + ";"
+						Else
+							Emit TransType(stmt.expr.exprType, "rt_") + " = " + s + ";"
+						End If
+						t:+ " rt_"
 					Else
 					Else
-						Emit TransType(stmt.expr.exprType, "rt_") + " = " + s + ";"
+						t:+" " + s
 					End If
 					End If
-					t:+ " rt_"
-				Else
-					t:+" " + s
 				End If
 				End If
 			End If
 			End If
 			
 			
@@ -1341,9 +1428,7 @@ End Rem
 				Emit "}"
 				Emit "}"
 			EndIf
 			EndIf
 		Else If stmt.elseBlock.stmts.First()
 		Else If stmt.elseBlock.stmts.First()
-			_inBinary :+ 1
 			Emit "if"+Bra( stmt.expr.Trans() )+"{"
 			Emit "if"+Bra( stmt.expr.Trans() )+"{"
-			_inBinary :- 1
 			EmitLocalDeclarations(stmt.thenBlock)
 			EmitLocalDeclarations(stmt.thenBlock)
 			FreeVarsIfRequired(False)
 			FreeVarsIfRequired(False)
 			PushVarScope
 			PushVarScope
@@ -1367,10 +1452,8 @@ End Rem
 '					Emit "if"+Bra( stmt.expr.Trans() )+"{"
 '					Emit "if"+Bra( stmt.expr.Trans() )+"{"
 '				End If
 '				End If
 '			Else
 '			Else
-			_inBinary :+ 1
 				Emit "if"+Bra( stmt.expr.Trans() )+"{"
 				Emit "if"+Bra( stmt.expr.Trans() )+"{"
 				FreeVarsIfRequired(False)
 				FreeVarsIfRequired(False)
-			_inBinary :- 1
 '			End If
 '			End If
 			EmitLocalDeclarations(stmt.thenBlock)
 			EmitLocalDeclarations(stmt.thenBlock)
 			PushVarScope
 			PushVarScope
@@ -1412,9 +1495,7 @@ End Rem
 	Method TransWhileStmt$( stmt:TWhileStmt )
 	Method TransWhileStmt$( stmt:TWhileStmt )
 		Local nbroken:Int=broken
 		Local nbroken:Int=broken
 
 
-		_inBinary :+ 1
 		Emit "while"+Bra( stmt.expr.Trans() )+"{"
 		Emit "while"+Bra( stmt.expr.Trans() )+"{"
-		_inBinary :- 1
 		
 		
 		Local check:TTryBreakCheck = New TTryBreakCheck
 		Local check:TTryBreakCheck = New TTryBreakCheck
 		check.stmt = stmt
 		check.stmt = stmt
@@ -1568,6 +1649,8 @@ End Rem
 	Method TransRestoreDataStmt$( stmt:TRestoreDataStmt ) Abstract
 	Method TransRestoreDataStmt$( stmt:TRestoreDataStmt ) Abstract
 
 
 	Method TransReadDataStmt$( stmt:TReadDataStmt ) Abstract
 	Method TransReadDataStmt$( stmt:TReadDataStmt ) Abstract
+	
+	Method TransNativeStmt$( stmt:TNativeStmt) Abstract
 
 
 	'module
 	'module
 	Method TransApp( app:TAppDecl ) Abstract
 	Method TransApp( app:TAppDecl ) Abstract

+ 646 - 71
type.bmx

@@ -1,4 +1,4 @@
-' Copyright (c) 2013-2016 Bruce A Henderson
+' Copyright (c) 2013-2017 Bruce A Henderson
 '
 '
 ' Based on the public domain Monkey "trans" by Mark Sibly
 ' Based on the public domain Monkey "trans" by Mark Sibly
 '
 '
@@ -192,18 +192,24 @@ Type TType
 
 
 	Const T_POINTER:Int = T_PTR | T_PTRPTR | T_PTRPTRPTR
 	Const T_POINTER:Int = T_PTR | T_PTRPTR | T_PTRPTRPTR
 
 
-	Const T_BYTE:Int        = $001
-	Const T_SHORT:Int       = $002
-	Const T_INT:Int         = $004
-	Const T_LONG:Int        = $008
-	Const T_FLOAT:Int       = $010
-	Const T_DOUBLE:Int      = $020
-	Const T_STRING:Int      = $040
-	Const T_ARRAY:Int       = $080
-	Const T_FUNCTIONPTR:Int = $100
-	Const T_SIZET:Int       = $200
-	Const T_UINT:Int        = $400
-	Const T_ULONG:Int       = $800
+	Const T_BYTE:Int        =  $001
+	Const T_SHORT:Int       =  $002
+	Const T_INT:Int         =  $004
+	Const T_LONG:Int        =  $008
+	Const T_FLOAT:Int       =  $010
+	Const T_DOUBLE:Int      =  $020
+	Const T_STRING:Int      =  $040
+	Const T_ARRAY:Int       =  $080
+	Const T_FUNCTIONPTR:Int =  $100
+	Const T_SIZET:Int       =  $200
+	Const T_UINT:Int        =  $400
+	Const T_ULONG:Int       =  $800
+	Const T_FLOAT64:Int     = $1000
+	Const T_INT128:Int      = $2000
+	Const T_FLOAT128:Int    = $4000
+	Const T_DOUBLE128:Int   = $8000
+	Const T_LPARAM:Int      =$10000
+	Const T_WPARAM:Int      =$20000
 
 
 	Const T_MAX_DISTANCE:Int = $FFFF
 	Const T_MAX_DISTANCE:Int = $FFFF
 
 
@@ -248,12 +254,22 @@ Function NewType:TType(kind:Int = 0)
 			ty = New TUIntType
 			ty = New TUIntType
 		Case TType.T_LONG
 		Case TType.T_LONG
 			ty = New TLongType
 			ty = New TLongType
+		Case TType.T_ULONG
+			ty = New TULongType
 		Case TType.T_SIZET
 		Case TType.T_SIZET
 			ty = New TSizeTType
 			ty = New TSizeTType
+		Case TType.T_INT128
+			ty = New TInt128Type
 		Case TType.T_FLOAT
 		Case TType.T_FLOAT
 			ty = New TFloatType
 			ty = New TFloatType
 		Case TType.T_DOUBLE
 		Case TType.T_DOUBLE
 			ty = New TDoubleType
 			ty = New TDoubleType
+		Case TType.T_FLOAT64
+			ty = New TFloat64Type
+		Case TType.T_FLOAT128
+			ty = New TFloat128Type
+		Case TType.T_DOUBLE128
+			ty = New TDouble128Type
 		Case TType.T_STRING
 		Case TType.T_STRING
 			ty = New TStringType
 			ty = New TStringType
 		Case TType.T_ARRAY
 		Case TType.T_ARRAY
@@ -303,12 +319,22 @@ Function IsType:Int(ty:TType, kind:Int)
 			Return TUIntType(ty) <> Null
 			Return TUIntType(ty) <> Null
 		Case TType.T_LONG
 		Case TType.T_LONG
 			Return TLongType(ty) <> Null
 			Return TLongType(ty) <> Null
+		Case TType.T_ULONG
+			Return TULongType(ty) <> Null
 		Case TType.T_SIZET
 		Case TType.T_SIZET
 			Return TSizeTType(ty) <> Null
 			Return TSizeTType(ty) <> Null
+		Case TType.T_INT128
+			Return TInt128Type(ty) <> Null
 		Case TType.T_FLOAT
 		Case TType.T_FLOAT
 			Return TFloatType(ty) <> Null
 			Return TFloatType(ty) <> Null
 		Case TType.T_DOUBLE
 		Case TType.T_DOUBLE
 			Return TDoubleType(ty) <> Null
 			Return TDoubleType(ty) <> Null
+		Case TType.T_FLOAT64
+			Return TFloat64Type(ty) <> Null
+		Case TType.T_FLOAT128
+			Return TFloat128Type(ty) <> Null
+		Case TType.T_DOUBLE128
+			Return TDouble128Type(ty) <> Null
 		Case TType.T_STRING
 		Case TType.T_STRING
 			Return TStringType(ty) <> Null
 			Return TStringType(ty) <> Null
 		Case TType.T_ARRAY
 		Case TType.T_ARRAY
@@ -397,7 +423,10 @@ Type TNumericType Extends TType
 	
 	
 End Type
 End Type
 
 
-Type TIntType Extends TNumericType
+Type TIntegralType Extends TNumericType
+End Type
+
+Type TIntType Extends TIntegralType
 	
 	
 	Method EqualsType:Int( ty:TType )
 	Method EqualsType:Int( ty:TType )
 		Return TIntType( ty )<>Null And (_flags = ty._flags Or ..
 		Return TIntType( ty )<>Null And (_flags = ty._flags Or ..
@@ -411,26 +440,38 @@ Type TIntType Extends TNumericType
 		'	Return ctor And ctor.IsCtor()
 		'	Return ctor And ctor.IsCtor()
 		'EndIf
 		'EndIf
 		If _flags & T_VARPTR And (TIntType(ty) <> Null Or IsPointerType(ty, 0, T_POINTER)) Return True
 		If _flags & T_VARPTR And (TIntType(ty) <> Null Or IsPointerType(ty, 0, T_POINTER)) Return True
-		Return (widensTest And WidensToType(ty)) Or (Not widensTest And TNumericType( ty )<>Null) Or (Not noExtendString And TStringType( ty )<>Null)
+		Return (widensTest And WidensToType(ty)) Or (Not widensTest And TNumericType( ty )<>Null) Or (Not noExtendString And TStringType( ty )<>Null) Or (WORD_SIZE=4 And TLParamType(ty)<>Null)
 	End Method
 	End Method
 
 
 	Method WidensToType:Int( ty:TType )
 	Method WidensToType:Int( ty:TType )
-		Return (IsPointerType(ty, 0, T_POINTER) And IsPointerType(Self, 0, T_POINTER)) Or (TIntType(ty)<>Null And (ty._flags & T_VAR)) Or TLongType(ty)<>Null Or TFloatType(ty)<>Null Or TDoubleType(ty)<>Null
+		Return (IsPointerType(ty, 0, T_POINTER) And IsPointerType(Self, 0, T_POINTER)) Or (TIntType(ty)<>Null And (ty._flags & T_VAR)) Or TLongType(ty)<>Null Or TFloatType(ty)<>Null Or TDoubleType(ty)<>Null Or (WORD_SIZE=8 And TLParamType(ty)<>Null)
 	End Method
 	End Method
 	
 	
 	Method DistanceToType:Int(ty:TType)
 	Method DistanceToType:Int(ty:TType)
-		If (IsPointerType(ty, 0, T_POINTER) And IsPointerType(Self, 0, T_POINTER)) Then
-			Return 0
+		If IsPointerType(ty, 0, T_POINTER) Then
+			If IsPointerType(Self, 0, T_POINTER) Then
+				Return 0
+			Else
+				Return T_MAX_DISTANCE
+			End If
 		End If
 		End If
 
 
 		If TIntType(ty)<>Null Then
 		If TIntType(ty)<>Null Then
 			Return 0
 			Return 0
 		End If
 		End If
 		
 		
+		If WORD_SIZE = 4 And TLParamType(ty)<>Null Then
+			Return 0
+		End If
+		
 		If TLongType(ty)<>Null Then
 		If TLongType(ty)<>Null Then
 			Return 2
 			Return 2
 		End If
 		End If
 
 
+		If WORD_SIZE = 8 And TLParamType(ty)<>Null Then
+			Return 2
+		End If
+		
 		If TFloatType(ty)<>Null Then
 		If TFloatType(ty)<>Null Then
 			Return 4
 			Return 4
 		End If
 		End If
@@ -456,7 +497,7 @@ Type TIntType Extends TNumericType
 
 
 End Type
 End Type
 
 
-Type TUIntType Extends TNumericType
+Type TUIntType Extends TIntegralType
 	
 	
 	Method EqualsType:Int( ty:TType )
 	Method EqualsType:Int( ty:TType )
 		Return TUIntType( ty )<>Null And (_flags = ty._flags Or ..
 		Return TUIntType( ty )<>Null And (_flags = ty._flags Or ..
@@ -470,19 +511,23 @@ Type TUIntType Extends TNumericType
 		'	Return ctor And ctor.IsCtor()
 		'	Return ctor And ctor.IsCtor()
 		'EndIf
 		'EndIf
 		If _flags & T_VARPTR And (TUIntType(ty) <> Null Or IsPointerType(ty, 0, T_POINTER)) Return True
 		If _flags & T_VARPTR And (TUIntType(ty) <> Null Or IsPointerType(ty, 0, T_POINTER)) Return True
-		Return (widensTest And WidensToType(ty)) Or (Not widensTest And TNumericType( ty )<>Null) Or (Not noExtendString And TStringType( ty )<>Null) 'Or TIntVarPtrType( ty )<> Null
+		Return (widensTest And WidensToType(ty)) Or (Not widensTest And TNumericType( ty )<>Null) Or (Not noExtendString And TStringType( ty )<>Null) Or (WORD_SIZE=4 And (TSizeTType(ty)<>Null Or TWParamType(ty)<>Null))
 	End Method
 	End Method
 
 
 	Method WidensToType:Int( ty:TType )
 	Method WidensToType:Int( ty:TType )
-		Return (IsPointerType(ty, 0, T_POINTER) And IsPointerType(Self, 0, T_POINTER)) Or (TUIntType(ty)<>Null And (ty._flags & T_VAR)) Or TIntType(ty)<> Null Or TLongType(ty)<>Null Or TULongType(ty)<>Null Or TFloatType(ty)<>Null Or TDoubleType(ty)<>Null
+		Return (IsPointerType(ty, 0, T_POINTER) And IsPointerType(Self, 0, T_POINTER)) Or (TUIntType(ty)<>Null And (ty._flags & T_VAR)) Or TIntType(ty)<> Null Or TLongType(ty)<>Null Or TULongType(ty)<>Null Or TFloatType(ty)<>Null Or TDoubleType(ty)<>Null Or (WORD_SIZE=8 And TWParamType(ty)<>Null)
 	End Method
 	End Method
 
 
 	Method DistanceToType:Int(ty:TType)
 	Method DistanceToType:Int(ty:TType)
-		If (IsPointerType(ty, 0, T_POINTER) And IsPointerType(Self, 0, T_POINTER)) Then
-			Return 0
+		If IsPointerType(ty, 0, T_POINTER) Then
+			If IsPointerType(Self, 0, T_POINTER) Then
+				Return 0
+			Else
+				Return T_MAX_DISTANCE
+			End If
 		End If
 		End If
 
 
-		If WORD_SIZE = 4 And TSizeTType(ty)<>Null Then
+		If WORD_SIZE = 4 And (TSizeTType(ty)<>Null Or TWParamType(ty)<>Null) Then
 			Return 0
 			Return 0
 		End If
 		End If
 		
 		
@@ -494,7 +539,7 @@ Type TUIntType Extends TNumericType
 			Return 1
 			Return 1
 		End If
 		End If
 		
 		
-		If WORD_SIZE = 8 And TSizeTType(ty)<>Null Then
+		If WORD_SIZE = 8 And (TSizeTType(ty)<>Null Or TWParamType(ty)<>Null) Then
 			Return 2
 			Return 2
 		End If
 		End If
 		
 		
@@ -531,7 +576,7 @@ Type TUIntType Extends TNumericType
 
 
 End Type
 End Type
 
 
-Type TSizeTType Extends TNumericType
+Type TSizeTType Extends TIntegralType
 	
 	
 	Method EqualsType:Int( ty:TType )
 	Method EqualsType:Int( ty:TType )
 		Return TSizeTType( ty )<>Null And (_flags = ty._flags Or ..
 		Return TSizeTType( ty )<>Null And (_flags = ty._flags Or ..
@@ -545,26 +590,34 @@ Type TSizeTType Extends TNumericType
 		'	Return ctor And ctor.IsCtor()
 		'	Return ctor And ctor.IsCtor()
 		'EndIf
 		'EndIf
 		If _flags & T_VARPTR And (TSizeTType(ty) <> Null Or IsPointerType(ty, 0, T_POINTER)) Return True
 		If _flags & T_VARPTR And (TSizeTType(ty) <> Null Or IsPointerType(ty, 0, T_POINTER)) Return True
-		Return (widensTest And WidensToType(ty)) Or (Not widensTest And TNumericType( ty )<>Null) Or (Not noExtendString And TStringType( ty )<>Null) 'Or TIntVarPtrType( ty )<> Null
+		Return (widensTest And WidensToType(ty)) Or (Not widensTest And TNumericType( ty )<>Null) Or (Not noExtendString And TStringType( ty )<>Null) Or (WORD_SIZE=4 And TUIntType(ty)<>Null) Or (WORD_SIZE=8 And TULongType(ty)<>Null)
 	End Method
 	End Method
 
 
 	Method WidensToType:Int( ty:TType )
 	Method WidensToType:Int( ty:TType )
 		If WORD_SIZE = 4 Then
 		If WORD_SIZE = 4 Then
-			Return (IsPointerType(ty, 0, T_POINTER) And IsPointerType(Self, 0, T_POINTER)) Or ((TSizeTType(ty)<>Null Or TUIntType(ty)<>Null) And (ty._flags & T_VAR)) Or TIntType(ty)<>Null Or TUIntType(ty)<>Null Or TLongType(ty)<>Null Or TULongType(ty)<>Null Or TFloatType(ty)<>Null Or TDoubleType(ty)<>Null
+			Return (IsPointerType(ty, 0, T_POINTER) And IsPointerType(Self, 0, T_POINTER)) Or ((TSizeTType(ty)<>Null Or TUIntType(ty)<>Null) And (ty._flags & T_VAR)) Or TIntType(ty)<>Null Or TUIntType(ty)<>Null Or TLongType(ty)<>Null Or TULongType(ty)<>Null Or TFloatType(ty)<>Null Or TDoubleType(ty)<>Null Or TWParamType(ty)<>Null Or TLParamType(ty)<>Null
 		Else
 		Else
-			Return (IsPointerType(ty, 0, T_POINTER) And IsPointerType(Self, 0, T_POINTER)) Or ((TSizeTType(ty)<>Null Or TULongType(ty)<>Null) And (ty._flags & T_VAR)) Or TLongType(ty)<>Null Or TULongType(ty)<>Null Or TFloatType(ty)<>Null Or TDoubleType(ty)<>Null
+			Return (IsPointerType(ty, 0, T_POINTER) And IsPointerType(Self, 0, T_POINTER)) Or ((TSizeTType(ty)<>Null Or TULongType(ty)<>Null) And (ty._flags & T_VAR)) Or TLongType(ty)<>Null Or TULongType(ty)<>Null Or TFloatType(ty)<>Null Or TDoubleType(ty)<>Null Or TFloat64Type(ty)<>Null Or TWParamType(ty)<>Null Or TLParamType(ty)<>Null
 		End If
 		End If
 	End Method
 	End Method
 
 
 	Method DistanceToType:Int(ty:TType)
 	Method DistanceToType:Int(ty:TType)
-		If (IsPointerType(ty, 0, T_POINTER) And IsPointerType(Self, 0, T_POINTER)) Then
-			Return 0
+		If IsPointerType(ty, 0, T_POINTER) Then
+			If IsPointerType(Self, 0, T_POINTER) Then
+				Return 0
+			Else
+				Return T_MAX_DISTANCE
+			End If
 		End If
 		End If
 
 
 		If TSizeTType(ty)<>Null Then
 		If TSizeTType(ty)<>Null Then
 			Return 0
 			Return 0
 		End If
 		End If
 
 
+		If TWParamType(ty)<>Null Then
+			Return 0
+		End If
+
 		If WORD_SIZE = 4 Then
 		If WORD_SIZE = 4 Then
 			If TUIntType(ty)<>Null Then
 			If TUIntType(ty)<>Null Then
 				Return 0
 				Return 0
@@ -573,6 +626,10 @@ Type TSizeTType Extends TNumericType
 			If TIntType(ty)<>Null Then
 			If TIntType(ty)<>Null Then
 				Return 2
 				Return 2
 			End If
 			End If
+			
+			If TLParamType(ty)<>Null Then
+				Return 2
+			End If
 
 
 			If TULongType(ty)<>Null Then
 			If TULongType(ty)<>Null Then
 				Return 3
 				Return 3
@@ -599,6 +656,10 @@ Type TSizeTType Extends TNumericType
 				Return 2
 				Return 2
 			End If
 			End If
 
 
+			If TLParamType(ty)<>Null Then
+				Return 2
+			End If
+
 			If TFloatType(ty)<>Null Then
 			If TFloatType(ty)<>Null Then
 				Return 4
 				Return 4
 			End If
 			End If
@@ -606,6 +667,11 @@ Type TSizeTType Extends TNumericType
 			If TDoubleType(ty)<>Null Then
 			If TDoubleType(ty)<>Null Then
 				Return 6
 				Return 6
 			End If
 			End If
+
+			If TFloat64Type(ty)<>Null Then
+				Return 8
+			End If
+
 		End If
 		End If
 	
 	
 		Return T_MAX_DISTANCE
 		Return T_MAX_DISTANCE
@@ -625,7 +691,7 @@ Type TSizeTType Extends TNumericType
 
 
 End Type
 End Type
 
 
-Type TByteType Extends TNumericType
+Type TByteType Extends TIntegralType
 	
 	
 	Method EqualsType:Int( ty:TType )
 	Method EqualsType:Int( ty:TType )
 		Return TByteType( ty )<>Null And (_flags = ty._flags Or ..
 		Return TByteType( ty )<>Null And (_flags = ty._flags Or ..
@@ -643,12 +709,16 @@ Type TByteType Extends TNumericType
 	End Method
 	End Method
 
 
 	Method WidensToType:Int( ty:TType )
 	Method WidensToType:Int( ty:TType )
-		Return (IsPointerType(ty, 0, T_POINTER) And IsPointerType(Self, 0, T_POINTER)) Or (TByteType(ty)<>Null And (ty._flags & T_VAR)) Or TShortType(ty)<>Null Or TIntType(ty)<>Null Or TUIntType(ty)<>Null Or TLongType(ty)<>Null Or TULongType(ty)<>Null Or TFloatType(ty)<>Null Or TDoubleType(ty)<>Null
+		Return (IsPointerType(ty, 0, T_POINTER) And IsPointerType(Self, 0, T_POINTER)) Or (TByteType(ty)<>Null And (ty._flags & T_VAR)) Or TShortType(ty)<>Null Or TIntType(ty)<>Null Or TUIntType(ty)<>Null Or TLongType(ty)<>Null Or TULongType(ty)<>Null Or TFloatType(ty)<>Null Or TDoubleType(ty)<>Null Or TWParamType(ty)<>Null Or TLParamType(ty)<>Null
 	End Method
 	End Method
 
 
 	Method DistanceToType:Int(ty:TType)
 	Method DistanceToType:Int(ty:TType)
-		If (IsPointerType(ty, 0, T_POINTER) And IsPointerType(Self, 0, T_POINTER)) Then
-			Return 0
+		If IsPointerType(ty, 0, T_POINTER) Then
+			If IsPointerType(Self, 0, T_POINTER) Then
+				Return 0
+			Else
+				Return T_MAX_DISTANCE
+			End If
 		End If
 		End If
 
 
 		If TByteType(ty)<>Null Then
 		If TByteType(ty)<>Null Then
@@ -659,7 +729,7 @@ Type TByteType Extends TNumericType
 			Return 2
 			Return 2
 		End If
 		End If
 
 
-		If WORD_SIZE = 4 And TSizeTType(ty)<>Null Then
+		If WORD_SIZE = 4 And (TSizeTType(ty)<>Null Or TWParamType(ty)<>Null) Then
 			Return 4
 			Return 4
 		End If
 		End If
 		
 		
@@ -670,8 +740,12 @@ Type TByteType Extends TNumericType
 		If TIntType(ty)<>Null Then
 		If TIntType(ty)<>Null Then
 			Return 5
 			Return 5
 		End If
 		End If
+
+		If WORD_SIZE = 4 And TLParamType(ty)<>Null Then
+			Return 5
+		End If
 		
 		
-		If WORD_SIZE = 8 And TSizeTType(ty)<>Null Then
+		If WORD_SIZE = 8 And (TSizeTType(ty)<>Null Or TWParamType(ty)<>Null) Then
 			Return 6
 			Return 6
 		End If
 		End If
 		
 		
@@ -683,6 +757,10 @@ Type TByteType Extends TNumericType
 			Return 7
 			Return 7
 		End If
 		End If
 
 
+		If WORD_SIZE = 8 And TLParamType(ty)<>Null Then
+			Return 7
+		End If
+
 		If TFloatType(ty)<>Null Then
 		If TFloatType(ty)<>Null Then
 			Return 8
 			Return 8
 		End If
 		End If
@@ -708,7 +786,7 @@ Type TByteType Extends TNumericType
 
 
 End Type
 End Type
 
 
-Type TShortType Extends TNumericType
+Type TShortType Extends TIntegralType
 
 
 	Method EqualsType:Int( ty:TType )
 	Method EqualsType:Int( ty:TType )
 		Return TShortType( ty )<>Null And (_flags = ty._flags Or ..
 		Return TShortType( ty )<>Null And (_flags = ty._flags Or ..
@@ -726,19 +804,23 @@ Type TShortType Extends TNumericType
 	End Method
 	End Method
 
 
 	Method WidensToType:Int( ty:TType )
 	Method WidensToType:Int( ty:TType )
-		Return (IsPointerType(ty, 0, T_POINTER) And IsPointerType(Self, 0, T_POINTER)) Or (TShortType(ty)<>Null And (ty._flags & T_VAR)) Or TIntType(ty)<>Null Or TUIntType(ty)<>Null Or TLongType(ty)<>Null Or TULongType(ty)<>Null Or TFloatType(ty)<>Null Or TDoubleType(ty)<>Null
+		Return (IsPointerType(ty, 0, T_POINTER) And IsPointerType(Self, 0, T_POINTER)) Or (TShortType(ty)<>Null And (ty._flags & T_VAR)) Or TIntType(ty)<>Null Or TUIntType(ty)<>Null Or TLongType(ty)<>Null Or TULongType(ty)<>Null Or TFloatType(ty)<>Null Or TDoubleType(ty)<>Null Or TWParamType(ty)<>Null Or TLParamType(ty)<>Null
 	End Method
 	End Method
 
 
 	Method DistanceToType:Int(ty:TType)
 	Method DistanceToType:Int(ty:TType)
-		If (IsPointerType(ty, 0, T_POINTER) And IsPointerType(Self, 0, T_POINTER)) Then
-			Return 0
+		If IsPointerType(ty, 0, T_POINTER) Then
+			If IsPointerType(Self, 0, T_POINTER) Then
+				Return 0
+			Else
+				Return T_MAX_DISTANCE
+			End If
 		End If
 		End If
 
 
 		If TShortType(ty)<>Null Then
 		If TShortType(ty)<>Null Then
 			Return 0
 			Return 0
 		End If
 		End If
 
 
-		If WORD_SIZE = 4 And TSizeTType(ty)<>Null Then
+		If WORD_SIZE = 4 And (TSizeTType(ty)<>Null Or TWParamType(ty)<>Null) Then
 			Return 2
 			Return 2
 		End If
 		End If
 		
 		
@@ -749,8 +831,12 @@ Type TShortType Extends TNumericType
 		If TIntType(ty)<>Null Then
 		If TIntType(ty)<>Null Then
 			Return 3
 			Return 3
 		End If
 		End If
+
+		If WORD_SIZE = 4 And TLParamType(ty)<>Null Then
+			Return 3
+		End If
 		
 		
-		If WORD_SIZE = 8 And TSizeTType(ty)<>Null Then
+		If WORD_SIZE = 8 And (TSizeTType(ty)<>Null Or TWParamType(ty)<>Null) Then
 			Return 4
 			Return 4
 		End If
 		End If
 
 
@@ -762,6 +848,10 @@ Type TShortType Extends TNumericType
 			Return 5
 			Return 5
 		End If
 		End If
 
 
+		If WORD_SIZE = 8 And TLParamType(ty)<>Null Then
+			Return 5
+		End If
+
 		If TFloatType(ty)<>Null Then
 		If TFloatType(ty)<>Null Then
 			Return 6
 			Return 6
 		End If
 		End If
@@ -787,7 +877,7 @@ Type TShortType Extends TNumericType
 
 
 End Type
 End Type
 
 
-Type TLongType Extends TNumericType ' BaH Long
+Type TLongType Extends TIntegralType ' BaH Long
 	
 	
 	Method EqualsType:Int( ty:TType )
 	Method EqualsType:Int( ty:TType )
 		Return TLongType( ty )<>Null And (_flags = ty._flags Or ..
 		Return TLongType( ty )<>Null And (_flags = ty._flags Or ..
@@ -805,17 +895,25 @@ Type TLongType Extends TNumericType ' BaH Long
 	End Method
 	End Method
 
 
 	Method WidensToType:Int( ty:TType )
 	Method WidensToType:Int( ty:TType )
-		Return (IsPointerType(ty, 0, T_POINTER) And IsPointerType(Self, 0, T_POINTER)) Or (TLongType(ty)<>Null And (ty._flags & T_VAR)) Or TFloatType(ty)<>Null Or TDoubleType(ty)<>Null
+		Return (IsPointerType(ty, 0, T_POINTER) And IsPointerType(Self, 0, T_POINTER)) Or (TLongType(ty)<>Null And (ty._flags & T_VAR)) Or TFloatType(ty)<>Null Or TDoubleType(ty)<>Null Or TFloat64Type(ty)<>Null
 	End Method
 	End Method
 
 
 	Method DistanceToType:Int(ty:TType)
 	Method DistanceToType:Int(ty:TType)
-		If (IsPointerType(ty, 0, T_POINTER) And IsPointerType(Self, 0, T_POINTER)) Then
-			Return 0
+		If IsPointerType(ty, 0, T_POINTER) Then
+			If IsPointerType(Self, 0, T_POINTER) Then
+				Return 0
+			Else
+				Return T_MAX_DISTANCE
+			End If
 		End If
 		End If
 
 
 		If TLongType(ty)<>Null Then
 		If TLongType(ty)<>Null Then
 			Return 0
 			Return 0
 		End If
 		End If
+		
+		If WORD_SIZE = 8 And TLParamType(ty)<>Null Then
+			Return 0
+		End If
 
 
 		If TFloatType(ty)<>Null Then
 		If TFloatType(ty)<>Null Then
 			Return 2
 			Return 2
@@ -824,6 +922,10 @@ Type TLongType Extends TNumericType ' BaH Long
 		If TDoubleType(ty)<>Null Then
 		If TDoubleType(ty)<>Null Then
 			Return 4
 			Return 4
 		End If
 		End If
+
+		If TFloat64Type(ty)<>Null Then
+			Return 6
+		End If
 		
 		
 		Return T_MAX_DISTANCE
 		Return T_MAX_DISTANCE
 	End Method
 	End Method
@@ -837,7 +939,7 @@ Type TLongType Extends TNumericType ' BaH Long
 	End Method
 	End Method
 End Type
 End Type
 
 
-Type TULongType Extends TNumericType
+Type TULongType Extends TIntegralType
 	
 	
 	Method EqualsType:Int( ty:TType )
 	Method EqualsType:Int( ty:TType )
 		Return TULongType( ty )<>Null And (_flags = ty._flags Or ..
 		Return TULongType( ty )<>Null And (_flags = ty._flags Or ..
@@ -855,19 +957,23 @@ Type TULongType Extends TNumericType
 	End Method
 	End Method
 
 
 	Method WidensToType:Int( ty:TType )
 	Method WidensToType:Int( ty:TType )
-		Return (IsPointerType(ty, 0, T_POINTER) And IsPointerType(Self, 0, T_POINTER)) Or (TULongType(ty)<>Null And (ty._flags & T_VAR)) Or TDoubleType(ty)<>Null
+		Return (IsPointerType(ty, 0, T_POINTER) And IsPointerType(Self, 0, T_POINTER)) Or (TULongType(ty)<>Null And (ty._flags & T_VAR)) Or TDoubleType(ty)<>Null Or TFloat64Type(ty)<>Null
 	End Method
 	End Method
 
 
 	Method DistanceToType:Int(ty:TType)
 	Method DistanceToType:Int(ty:TType)
-		If (IsPointerType(ty, 0, T_POINTER) And IsPointerType(Self, 0, T_POINTER)) Then
-			Return 0
+		If IsPointerType(ty, 0, T_POINTER) Then
+			If IsPointerType(Self, 0, T_POINTER) Then
+				Return 0
+			Else
+				Return T_MAX_DISTANCE
+			End If
 		End If
 		End If
 
 
 		If TULongType(ty)<>Null Then
 		If TULongType(ty)<>Null Then
 			Return 0
 			Return 0
 		End If
 		End If
 
 
-		If WORD_SIZE = 8 And TSizeTType(ty)<>Null Then
+		If WORD_SIZE = 8 And (TSizeTType(ty)<>Null Or TWParamType(ty)<>Null) Then
 			Return 0
 			Return 0
 		End If
 		End If
 		
 		
@@ -882,7 +988,11 @@ Type TULongType Extends TNumericType
 		If TDoubleType(ty)<>Null Then
 		If TDoubleType(ty)<>Null Then
 			Return 4
 			Return 4
 		End If
 		End If
-		
+
+		If TFloat64Type(ty)<>Null Then
+			Return 6
+		End If
+
 		Return T_MAX_DISTANCE
 		Return T_MAX_DISTANCE
 	End Method
 	End Method
 
 
@@ -920,8 +1030,12 @@ Type TFloatType Extends TDecimalType
 	End Method
 	End Method
 
 
 	Method DistanceToType:Int(ty:TType)
 	Method DistanceToType:Int(ty:TType)
-		If (IsPointerType(ty, 0, T_POINTER) And IsPointerType(Self, 0, T_POINTER)) Then
-			Return 0
+		If IsPointerType(ty, 0, T_POINTER) Then
+			If IsPointerType(Self, 0, T_POINTER) Then
+				Return 0
+			Else
+				Return T_MAX_DISTANCE
+			End If
 		End If
 		End If
 
 
 		If TFloatType(ty)<>Null Then
 		If TFloatType(ty)<>Null Then
@@ -971,8 +1085,12 @@ Type TDoubleType Extends TDecimalType
 	End Method
 	End Method
 
 
 	Method DistanceToType:Int(ty:TType)
 	Method DistanceToType:Int(ty:TType)
-		If (IsPointerType(ty, 0, T_POINTER) And IsPointerType(Self, 0, T_POINTER)) Then
-			Return 0
+		If IsPointerType(ty, 0, T_POINTER) Then
+			If IsPointerType(Self, 0, T_POINTER) Then
+				Return 0
+			Else
+				Return T_MAX_DISTANCE
+			End If
 		End If
 		End If
 
 
 		If TDoubleType(ty)<>Null Then
 		If TDoubleType(ty)<>Null Then
@@ -992,6 +1110,220 @@ Type TDoubleType Extends TDecimalType
 
 
 End Type
 End Type
 
 
+Type TIntrinsicType Extends TNumericType
+End Type
+
+Type TInt128Type Extends TIntrinsicType
+	
+	Method EqualsType:Int( ty:TType )
+		Return TInt128Type( ty )<>Null And (_flags = ty._flags Or ..
+			(_flags & T_VARPTR And ty._flags & T_PTR) Or (ty._flags & T_VARPTR And _flags & T_PTR) Or (_flags & T_VAR))
+	End Method
+	
+	Method ExtendsType:Int( ty:TType, noExtendString:Int = False, widensTest:Int = False )
+		'If TObjectType( ty )
+		'	Local expr:TExpr=New TConstExpr.Create( Self,"" ).Semant()
+		'	Local ctor:TFuncDecl=ty.GetClass().FindFuncDecl( "new",[expr],True )
+		'	Return ctor And ctor.IsCtor()
+		'EndIf
+		If _flags & T_VARPTR And (TLongType(ty) <> Null Or IsPointerType(ty, 0, T_POINTER)) Return True
+		Return (widensTest And WidensToType(ty)) Or (Not widensTest And TNumericType( ty )<>Null) Or (Not noExtendString And TStringType( ty )<>Null) 'Or TLongVarPtrType( ty )<> Null
+	End Method
+
+	Method WidensToType:Int( ty:TType )
+		Return (IsPointerType(ty, 0, T_POINTER) And IsPointerType(Self, 0, T_POINTER)) Or (TInt128Type(ty)<>Null And (ty._flags & T_VAR)) Or TFloat128Type(ty)<>Null Or TDouble128Type(ty)<>Null
+	End Method
+
+	Method DistanceToType:Int(ty:TType)
+		If IsPointerType(ty, 0, T_POINTER) Then
+			If IsPointerType(Self, 0, T_POINTER) Then
+				Return 0
+			Else
+				Return T_MAX_DISTANCE
+			End If
+		End If
+
+		If TInt128Type(ty)<>Null Then
+			Return 0
+		End If
+
+		If TFloat128Type(ty)<>Null Then
+			Return 2
+		End If
+
+		If TDouble128Type(ty)<>Null Then
+			Return 4
+		End If
+		
+		Return T_MAX_DISTANCE
+	End Method
+	
+	Method OnCopy:TType()
+		Return New TInt128Type
+	End Method
+
+	Method ToString$()
+		Return "Int128" + ToStringParts()
+	End Method
+End Type
+
+Type TFloat64Type Extends TIntrinsicType
+	
+	Method EqualsType:Int( ty:TType )
+		Return TFloat64Type( ty )<>Null And (_flags = ty._flags Or ..
+			(_flags & T_VARPTR And ty._flags & T_PTR) Or (ty._flags & T_VARPTR And _flags & T_PTR) Or (_flags & T_VAR))
+	End Method
+	
+	Method ExtendsType:Int( ty:TType, noExtendString:Int = False, widensTest:Int = False )
+		'If TObjectType( ty )
+		'	Local expr:TExpr=New TConstExpr.Create( Self,"" ).Semant()
+		'	Local ctor:TFuncDecl=ty.GetClass().FindFuncDecl( "new",[expr],True )
+		'	Return ctor And ctor.IsCtor()
+		'EndIf	
+		If _flags & T_VARPTR And (TFloat64Type(ty) <> Null Or IsPointerType(ty, 0, T_POINTER)) Return True
+		Return (widensTest And WidensToType(ty)) Or (Not widensTest And TNumericType( ty )<>Null) Or (Not noExtendString And TStringType( ty )<>Null) 'Or TDoubleVarPtrType( ty )<> Null
+	End Method
+
+	Method WidensToType:Int( ty:TType )
+		Return (IsPointerType(ty, 0, T_POINTER) And IsPointerType(Self, 0, T_POINTER)) Or (TFloat64Type(ty)<>Null And (ty._flags & T_VAR))
+	End Method
+
+	Method DistanceToType:Int(ty:TType)
+		If IsPointerType(ty, 0, T_POINTER) Then
+			If IsPointerType(Self, 0, T_POINTER) Then
+				Return 0
+			Else
+				Return T_MAX_DISTANCE
+			End If
+		End If
+
+		If TFloat64Type(ty)<>Null Then
+			Return 0
+		End If
+		
+		Return T_MAX_DISTANCE
+	End Method
+
+	Method OnCopy:TType()
+		Return New TFloat64Type
+	End Method
+
+	Method ToString$()
+		Return "Float64" + ToStringParts()
+	End Method
+
+End Type
+
+Type TFloat128Type Extends TIntrinsicType
+	
+	Method EqualsType:Int( ty:TType )
+		Return TFloat128Type( ty )<>Null And (_flags = ty._flags Or ..
+			(_flags & T_VARPTR And ty._flags & T_PTR) Or (ty._flags & T_VARPTR And _flags & T_PTR) Or (_flags & T_VAR))
+	End Method
+	
+	Method ExtendsType:Int( ty:TType, noExtendString:Int = False, widensTest:Int = False )
+		'If TObjectType( ty )
+		'	Local expr:TExpr=New TConstExpr.Create( Self,"" ).Semant()
+		'	Local ctor:TFuncDecl=ty.GetClass().FindFuncDecl( "new",[expr],True )
+		'	Return ctor And ctor.IsCtor()
+		'EndIf	
+		If _flags & T_VARPTR And (TFloat128Type(ty) <> Null Or IsPointerType(ty, 0, T_POINTER)) Return True
+		Return (widensTest And WidensToType(ty)) Or (Not widensTest And TNumericType( ty )<>Null) Or (Not noExtendString And TStringType( ty )<>Null) 'Or TDoubleVarPtrType( ty )<> Null
+	End Method
+
+	Method WidensToType:Int( ty:TType )
+		Return (IsPointerType(ty, 0, T_POINTER) And IsPointerType(Self, 0, T_POINTER)) Or (TFloat128Type(ty)<>Null And (ty._flags & T_VAR)) Or TInt128Type(ty)<>Null Or TDouble128Type(ty)<>Null
+	End Method
+
+	Method DistanceToType:Int(ty:TType)
+		If IsPointerType(ty, 0, T_POINTER) Then
+			If IsPointerType(Self, 0, T_POINTER) Then
+				Return 0
+			Else
+				Return T_MAX_DISTANCE
+			End If
+		End If
+
+		If TFloat128Type(ty)<>Null Then
+			Return 0
+		End If
+
+		If TDouble128Type(ty)<>Null Then
+			Return 2
+		End If
+		
+		If TInt128Type(ty)<>Null Then
+			Return 4
+		End If
+	
+		Return T_MAX_DISTANCE
+	End Method
+
+	Method OnCopy:TType()
+		Return New TFloat128Type
+	End Method
+
+	Method ToString$()
+		Return "Float128" + ToStringParts()
+	End Method
+
+End Type
+
+Type TDouble128Type Extends TIntrinsicType
+	
+	Method EqualsType:Int( ty:TType )
+		Return TDouble128Type( ty )<>Null And (_flags = ty._flags Or ..
+			(_flags & T_VARPTR And ty._flags & T_PTR) Or (ty._flags & T_VARPTR And _flags & T_PTR) Or (_flags & T_VAR))
+	End Method
+	
+	Method ExtendsType:Int( ty:TType, noExtendString:Int = False, widensTest:Int = False )
+		'If TObjectType( ty )
+		'	Local expr:TExpr=New TConstExpr.Create( Self,"" ).Semant()
+		'	Local ctor:TFuncDecl=ty.GetClass().FindFuncDecl( "new",[expr],True )
+		'	Return ctor And ctor.IsCtor()
+		'EndIf	
+		If _flags & T_VARPTR And (TDouble128Type(ty) <> Null Or IsPointerType(ty, 0, T_POINTER)) Return True
+		Return (widensTest And WidensToType(ty)) Or (Not widensTest And TNumericType( ty )<>Null) Or (Not noExtendString And TStringType( ty )<>Null) 'Or TDoubleVarPtrType( ty )<> Null
+	End Method
+
+	Method WidensToType:Int( ty:TType )
+		Return (IsPointerType(ty, 0, T_POINTER) And IsPointerType(Self, 0, T_POINTER)) Or (TDouble128Type(ty)<>Null And (ty._flags & T_VAR)) Or TInt128Type(ty)<>Null Or TFloat128Type(ty)<>Null
+	End Method
+
+	Method DistanceToType:Int(ty:TType)
+		If IsPointerType(ty, 0, T_POINTER) Then
+			If IsPointerType(Self, 0, T_POINTER) Then
+				Return 0
+			Else
+				Return T_MAX_DISTANCE
+			End If
+		End If
+
+		If TDouble128Type(ty)<>Null Then
+			Return 0
+		End If
+
+		If TFloat128Type(ty)<>Null Then
+			Return 2
+		End If
+
+		If TInt128Type(ty)<>Null Then
+			Return 4
+		End If
+		
+		Return T_MAX_DISTANCE
+	End Method
+
+	Method OnCopy:TType()
+		Return New TDouble128Type
+	End Method
+
+	Method ToString$()
+		Return "Double128" + ToStringParts()
+	End Method
+
+End Type
+
 Type TStringType Extends TType
 Type TStringType Extends TType
 
 
 	Field cdecl:TClassDecl
 	Field cdecl:TClassDecl
@@ -1065,7 +1397,7 @@ Type TArrayType Extends TType
 	
 	
 	Method ExtendsType:Int( ty:TType, noExtendString:Int = False, widensTest:Int = False )
 	Method ExtendsType:Int( ty:TType, noExtendString:Int = False, widensTest:Int = False )
 		Local arrayType:TArrayType=TArrayType( ty )
 		Local arrayType:TArrayType=TArrayType( ty )
-		Return (arrayType And ( TVoidType( elemType ) Or elemType.EqualsType( arrayType.elemType ) Or elemType.ExtendsType( arrayType.elemType ) )) Or IsPointerType(ty, 0, TType.T_POINTER) <> Null Or (TObjectType( ty ) And TObjectType( ty ).classDecl.ident="Object")
+		Return (arrayType And dims = arrayType.dims And ( TVoidType( elemType ) Or (TObjectType(elemType) And elemType.EqualsType( arrayType.elemType ) Or elemType.ExtendsType( arrayType.elemType )))) Or IsPointerType(ty, 0, TType.T_POINTER) <> Null Or (TObjectType( ty ) And TObjectType( ty ).classDecl.ident="Object")
 	End Method
 	End Method
 	
 	
 	Method Semant:TType(option:Int = False)
 	Method Semant:TType(option:Int = False)
@@ -1111,6 +1443,7 @@ Type TObjectType Extends TType
 	End Method
 	End Method
 	
 	
 	Method ExtendsType:Int( ty:TType, noExtendString:Int = False, widensTest:Int = False )
 	Method ExtendsType:Int( ty:TType, noExtendString:Int = False, widensTest:Int = False )
+		If classDecl.IsStruct() Return False
 		Local objty:TObjectType=TObjectType( ty )
 		Local objty:TObjectType=TObjectType( ty )
 		If objty Return classDecl.ExtendsClass( objty.classDecl )
 		If objty Return classDecl.ExtendsClass( objty.classDecl )
 		If IsPointerType( ty, T_BYTE ) Return True
 		If IsPointerType( ty, T_BYTE ) Return True
@@ -1133,6 +1466,33 @@ Type TObjectType Extends TType
 
 
 End Type
 End Type
 
 
+Type TClassType Extends TType
+
+	Field classDecl:TClassDecl
+	Field instance:Int
+	
+	Method Create:TClassType( classDecl:TClassDecl )
+		Self.classDecl=classDecl
+		Return Self
+	End Method
+
+	Method GetClass:TClassDecl()
+		Return classDecl
+	End Method
+
+	Method OnCopy:TType()
+		Local ty:TClassType = New TClassType
+		ty.classDecl = classDecl
+		ty.instance = instance
+		Return ty
+	End Method
+
+	Method ToString:String()
+		Return "Type"
+	End Method
+	
+End Type
+
 Type TIdentType Extends TType
 Type TIdentType Extends TType
 	Field ident$
 	Field ident$
 	Field args:TType[]
 	Field args:TType[]
@@ -1192,18 +1552,18 @@ Type TIdentType Extends TType
 		
 		
 		If i=-1
 		If i=-1
 			tyid=ident.ToLower()
 			tyid=ident.ToLower()
-			
+
 			If tyid = "self" Then
 			If tyid = "self" Then
 				' find owning class
 				' find owning class
 				Local scope:TClassDecl = _env.ClassScope()
 				Local scope:TClassDecl = _env.ClassScope()
 				If scope Then
 				If scope Then
 					tyid = scope.ident
 					tyid = scope.ident
-					ty = New TObjectType.Create(scope)
+					ty = New TClassType.Create(scope)
 					
 					
 					' test for method scope - self is already an instance
 					' test for method scope - self is already an instance
 					Local funcScope:TFuncDecl = _env.FuncScope()
 					Local funcScope:TFuncDecl = _env.FuncScope()
-					If funcScope.IsMethod() Then
-						TObjectType(ty).instance = True
+					If funcScope.IsAnyMethod() Then
+						TClassType(ty).instance = True
 					End If
 					End If
 				Else
 				Else
 					Err "'Self' can only be used within methods."
 					Err "'Self' can only be used within methods."
@@ -1233,12 +1593,12 @@ Type TIdentType Extends TType
 				Local scope:TClassDecl = _env.ClassScope()
 				Local scope:TClassDecl = _env.ClassScope()
 				If scope Then
 				If scope Then
 					tyid = scope.ident
 					tyid = scope.ident
-					ty = New TObjectType.Create(scope)
+					ty = New TClassType.Create(scope)
 					
 					
 					' test for method scope - self is already an instance
 					' test for method scope - self is already an instance
 					Local funcScope:TFuncDecl = _env.FuncScope()
 					Local funcScope:TFuncDecl = _env.FuncScope()
-					If funcScope.IsMethod() Then
-						TObjectType(ty).instance = True
+					If funcScope.IsAnyMethod() Then
+						TClassType(ty).instance = True
 					End If
 					End If
 				Else
 				Else
 					Err "'Self' can only be used within methods."
 					Err "'Self' can only be used within methods."
@@ -1279,6 +1639,10 @@ Type TIdentType Extends TType
 		End If
 		End If
 
 
 		If (_flags & T_POINTER) And TObjectType(ty) Then
 		If (_flags & T_POINTER) And TObjectType(ty) Then
+			' FIXME #200
+			'If Not TObjectType(ty).classDecl.IsExtern() Then
+			'	Err "Invalid Pointer type."
+			'End If
 			ty = New TObjectType.Create(TObjectType(ty).classDecl)
 			ty = New TObjectType.Create(TObjectType(ty).classDecl)
 			ty._flags :| (_flags & T_POINTER)
 			ty._flags :| (_flags & T_POINTER)
 		End If
 		End If
@@ -1369,17 +1733,36 @@ End Type
 Type TFunctionPtrType Extends TType
 Type TFunctionPtrType Extends TType
 
 
 	Field func:TFuncDecl
 	Field func:TFuncDecl
+	
+	Method Create:TFunctionPtrType(func:TFuncDecl)
+		Self.func = func
+		Return Self
+	End Method
 
 
 	Method EqualsType:Int( ty:TType )
 	Method EqualsType:Int( ty:TType )
-' TODO : compare function decl
-		Return TFunctionPtrType( ty )<>Null
+		If Not TFunctionPtrType(ty) Then Return False
+		' declared function pointer
+		Local tyfunc:TFuncDecl = TFunctionPtrType(ty).func
+		If Not tyfunc.retType.EqualsType(func.retType) Then Return False
+		If Not (tyfunc.argDecls.Length = func.argDecls.Length) Then Return False
+		For Local a:Int = 0 Until func.argDecls.Length
+			' does our arg equal declared arg?
+			If Not func.argDecls[a].ty.EqualsType(tyfunc.argDecls[a].ty) Then Return False
+		Next
+		Return True
 	End Method
 	End Method
 	
 	
 	Method ExtendsType:Int( ty:TType, noExtendString:Int = False, widensTest:Int = False )
 	Method ExtendsType:Int( ty:TType, noExtendString:Int = False, widensTest:Int = False )
-		If TObjectType( ty )
-			Local expr:TExpr=New TConstExpr.Create( Self,"" ).Semant()
-			Local ctor:TFuncDecl=ty.GetClass().FindFuncDecl( "new",[expr],True,,,,SCOPE_CLASS_HEIRARCHY )
-			Return ctor And ctor.IsCtor()
+		If TFunctionPtrType( ty )
+			' declared function pointer
+			Local tyfunc:TFuncDecl = TFunctionPtrType(ty).func
+			If Not func.retType.ExtendsType(tyfunc.retType) Then Return False
+			If Not (func.argDecls.Length = tyfunc.argDecls.Length) Then Return False
+			For Local a:Int = 0 Until func.argDecls.Length
+				' does declared arg extend our arg?
+				If Not tyfunc.argDecls[a].ty.ExtendsType(func.argDecls[a].ty) Then Return False
+			Next
+			Return True
 		EndIf
 		EndIf
 		Return IsPointerType( ty, 0, T_POINTER )<>Null
 		Return IsPointerType( ty, 0, T_POINTER )<>Null
 	End Method
 	End Method
@@ -1434,3 +1817,195 @@ Type TVarPtrType Extends TType
 		Return New TVarPtrType
 		Return New TVarPtrType
 	End Method
 	End Method
 End Type
 End Type
+
+Type TParamType Extends TIntegralType
+End Type
+
+Type TWParamType Extends TParamType
+
+	Method EqualsType:Int( ty:TType )
+		Return TWParamType( ty )<>Null And (_flags = ty._flags Or ..
+			(_flags & T_VARPTR And ty._flags & T_PTR) Or (ty._flags & T_VARPTR And _flags & T_PTR) Or (_flags & T_VAR))
+	End Method
+	
+	Method ExtendsType:Int( ty:TType, noExtendString:Int = False, widensTest:Int = False )
+		If _flags & T_VARPTR And (TWParamType(ty) <> Null Or IsPointerType(ty, 0, T_POINTER)) Return True
+		Return (widensTest And WidensToType(ty)) Or (Not widensTest And TNumericType( ty )<>Null) Or (Not noExtendString And TStringType( ty )<>Null) 'Or TIntVarPtrType( ty )<> Null
+	End Method
+
+	Method WidensToType:Int( ty:TType )
+		If WORD_SIZE = 4 Then
+			Return (IsPointerType(ty, 0, T_POINTER) And IsPointerType(Self, 0, T_POINTER)) Or ((TWParamType(ty)<>Null Or TSizeTType(ty)<>Null Or TUIntType(ty)<>Null) And (ty._flags & T_VAR)) Or TIntType(ty)<>Null Or TUIntType(ty)<>Null Or TLongType(ty)<>Null Or TULongType(ty)<>Null Or TFloatType(ty)<>Null Or TDoubleType(ty)<>Null
+		Else
+			Return (IsPointerType(ty, 0, T_POINTER) And IsPointerType(Self, 0, T_POINTER)) Or ((TWParamType(ty)<>Null Or TSizeTType(ty)<>Null Or TULongType(ty)<>Null) And (ty._flags & T_VAR)) Or TLongType(ty)<>Null Or TULongType(ty)<>Null Or TFloatType(ty)<>Null Or TDoubleType(ty)<>Null Or TFloat64Type(ty)<>Null
+		End If
+	End Method
+
+	Method DistanceToType:Int(ty:TType)
+		If IsPointerType(ty, 0, T_POINTER) Then
+			If IsPointerType(Self, 0, T_POINTER) Then
+				Return 0
+			Else
+				Return T_MAX_DISTANCE
+			End If
+		End If
+
+		If TWParamType(ty)<>Null Then
+			Return 0
+		End If
+
+		If TSizeTType(ty)<>Null Then
+			Return 0
+		End If
+
+		If WORD_SIZE = 4 Then
+			If TUIntType(ty)<>Null Then
+				Return 0
+			End If
+
+			If TIntType(ty)<>Null Then
+				Return 2
+			End If
+
+			If TULongType(ty)<>Null Then
+				Return 3
+			End If
+
+			If TLongType(ty)<>Null Then
+				Return 4
+			End If
+
+			If TFloatType(ty)<>Null Then
+				Return 5
+			End If
+	
+			If TDoubleType(ty)<>Null Then
+				Return 6
+			End If
+			
+		Else
+			If TULongType(ty)<>Null Then
+				Return 0
+			End If
+
+			If TLongType(ty)<>Null Then
+				Return 2
+			End If
+
+			If TFloatType(ty)<>Null Then
+				Return 4
+			End If
+	
+			If TDoubleType(ty)<>Null Then
+				Return 6
+			End If
+
+			If TFloat64Type(ty)<>Null Then
+				Return 8
+			End If
+
+		End If
+	
+		Return T_MAX_DISTANCE
+	End Method
+	
+	Method OnCopy:TType()
+		Return New TWParamType
+	End Method
+
+	Method ToString$()
+		Return "WPARAM" + ToStringParts()
+	End Method
+
+	Method GetSize:Int()
+		Return WORD_SIZE
+	End Method
+
+End Type
+
+Type TLParamType Extends TParamType
+
+	Method EqualsType:Int( ty:TType )
+		Return TLParamType( ty )<>Null And (_flags = ty._flags Or ..
+			(_flags & T_VARPTR And ty._flags & T_PTR) Or (ty._flags & T_VARPTR And _flags & T_PTR) Or (_flags & T_VAR))
+	End Method
+	
+	Method ExtendsType:Int( ty:TType, noExtendString:Int = False, widensTest:Int = False )
+		If _flags & T_VARPTR And (TLParamType(ty) <> Null Or IsPointerType(ty, 0, T_POINTER)) Return True
+		Return (widensTest And WidensToType(ty)) Or (Not widensTest And TNumericType( ty )<>Null) Or (Not noExtendString And TStringType( ty )<>Null) 'Or TIntVarPtrType( ty )<> Null
+	End Method
+
+	Method WidensToType:Int( ty:TType )
+		If WORD_SIZE = 4 Then
+			Return (IsPointerType(ty, 0, T_POINTER) And IsPointerType(Self, 0, T_POINTER)) Or ((TIntType(ty)<>Null Or TLParamType(ty)<>Null) And (ty._flags & T_VAR)) Or TFloatType(ty)<>Null Or TDoubleType(ty)<>Null Or TFloat64Type(ty)<>Null
+		Else
+			Return (IsPointerType(ty, 0, T_POINTER) And IsPointerType(Self, 0, T_POINTER)) Or ((TLongType(ty)<>Null Or TLParamType(ty)<>Null) And (ty._flags & T_VAR)) Or TFloatType(ty)<>Null Or TDoubleType(ty)<>Null Or TFloat64Type(ty)<>Null
+		End If
+	End Method
+
+	Method DistanceToType:Int(ty:TType)
+		If IsPointerType(ty, 0, T_POINTER) Then
+			If IsPointerType(Self, 0, T_POINTER) Then
+				Return 0
+			Else
+				Return T_MAX_DISTANCE
+			End If
+		End If
+
+		If TLParamType(ty)<>Null Then
+			Return 0
+		End If
+
+		If WORD_SIZE = 4 Then
+		
+			If TIntType(ty)<>Null Then
+				Return 0
+			End If
+			
+			If TLongType(ty)<>Null Then
+				Return 2
+			End If
+			
+			If TFloatType(ty)<>Null Then
+				Return 4
+			End If
+			
+			If TDoubleType(ty)<>Null Then
+				Return 6
+			End If
+			
+		Else
+			If TLongType(ty)<>Null Then
+				Return 0
+			End If
+	
+			If TFloatType(ty)<>Null Then
+				Return 2
+			End If
+	
+			If TDoubleType(ty)<>Null Then
+				Return 4
+			End If
+	
+			If TFloat64Type(ty)<>Null Then
+				Return 6
+			End If
+
+		End If
+	
+		Return T_MAX_DISTANCE
+	End Method
+	
+	Method OnCopy:TType()
+		Return New TLParamType
+	End Method
+
+	Method ToString$()
+		Return "LPARAM" + ToStringParts()
+	End Method
+
+	Method GetSize:Int()
+		Return WORD_SIZE
+	End Method
+
+End Type

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini