浏览代码

Mx2cc tweaks + more work on debug stuff.

Mark Sibly 9 年之前
父节点
当前提交
30de719587

+ 8 - 2
src/common.sh

@@ -1,12 +1,18 @@
 
 mx2cc=""
 mx2cc_new=""
+ted2=""
+ted2_new=""
 
 if [ "$OSTYPE" = "linux-gnu" ]
 then
 	mx2cc="../bin/mx2cc_linux"
-	mx2cc_new="mx2new/mx2cc.buildv003/desktop_release_linux/mx2cc"
+	mx2cc_new="mx2new/mx2cc.buildv004/desktop_release_linux/mx2cc"
+	ted2="../bin/ted2_linux"
+	ted2_new="ted2/ted2.buildv004/desktop_release_linux/ted2"
 else
 	mx2cc="../bin/mx2cc_macos"
-	mx2cc_new="mx2new/mx2cc.buildv003/desktop_release_macos/mx2cc.app/Contents/MacOS/mx2cc"
+	mx2cc_new="mx2new/mx2cc.buildv004/desktop_release_macos/mx2cc.app/Contents/MacOS/mx2cc"
+	ted2="../bin/ted2.app"
+	ted2_new="ted2/ted2.buildv004/desktop_release_macos/ted2.app"
 fi

+ 35 - 17
src/mx2new/builder.monkey2

@@ -124,7 +124,6 @@ Class Builder
 		ppsyms["__HOSTOS__"]="~q"+HostOS+"~q"
 		ppsyms["__TARGET__"]="~q"+opts.target+"~q"
 		ppsyms["__CONFIG__"]="~q"+opts.config+"~q"
-'		ppsyms["__CONFIG__"]="~qmx2new~q"
 		
 		profileName=opts.target+"_"+opts.config+"_"+HostOS
 		
@@ -144,7 +143,7 @@ Class Builder
 		
 		Local name:=StripDir( StripExt( opts.mainSource ) )
 
-		Local module:=New Module( name,opts.mainSource,opts.productType,MX2_PRODUCT_VERSION )
+		Local module:=New Module( name,opts.mainSource,opts.productType,MX2CC_VERSION )
 		modulesMap[name]=module
 		modules.Push( module )
 		
@@ -175,7 +174,7 @@ Class Builder
 				Local name:=MX2_LIBS.Pop()
 				Local srcPath:=modulesDir+name+"/"+name+".monkey2"
 				
-				module=New Module( name,srcPath,"module",MX2_MODULES_VERSION )
+				module=New Module( name,srcPath,"module",MX2CC_VERSION )
 				modulesMap[name]=module
 				modules.Push( module )
 				
@@ -456,7 +455,7 @@ Class Builder
 			Case ".c",".m"
 				cmd=CC_CMD+" "+CC_OPTS.Join( " " )
 			Case ".cc",".cxx",".cpp",".mm"
-				cmd=CXX_CMD+" -std=c++11 -g "+CPP_OPTS.Join( " " )
+				cmd=CXX_CMD+" "+CPP_OPTS.Join( " " )
 			End
 			
 			cmd+=" -Wno-int-to-pointer-cast"
@@ -510,26 +509,29 @@ Class Builder
 			
 			cmd+=" -c -o ~q"+obj+"~q ~q"+src+"~q"
 			
-			Exec( cmd ) 
-
+			Exec( cmd )
+			
 			maxObjTime=Max( maxObjTime,GetFileTime( obj ) )
+			
 			OBJ_FILES.Push( obj )
 			
 		Next
 	
 	End
 	
-	Method Link()
+	Method Link:String()
 	
 		Select opts.productType
 		Case "app"
-			CreateApp()
+			Return CreateApp()
 		Case "module"
-			CreateArchive()
+			Return CreateArchive()
 		End
+		
+		Return ""
 	End
 	
-	Method CreateApp()
+	Method CreateApp:String()
 	
 		Local module:=mainModule
 		
@@ -660,8 +662,8 @@ Class Builder
 			
 		Next
 		
-		If Not opts.run Return
-		
+		If Not opts.run Return outputFile
+	
 		Local run:=""
 		If opts.target="emscripten"
 			Local mserver:=GetEnv( "MX2_MSERVER" )
@@ -670,7 +672,10 @@ Class Builder
 			run="~q"+outputFile+"~q"
 		Endif
 		
+		If opts.verbose>=0 Print "Running "+outputFile
 		Exec( run )
+		
+		Return outputFile
 	End
 	
 	Method CopyAll:Bool( src:String,dst:String )
@@ -705,12 +710,15 @@ Class Builder
 		
 	End
 	
-	Method CreateArchive()
+	Method CreateArchive:String()
 
 		Local module:=mainModule
 		
 		Local outputFile:=module.outputDir+module.name+".a"
 		
+		'AR is slow! This is probably not quite right, but it'll do for now...
+		If GetFileTime( outputFile )>maxObjTime Return outputFile
+		
 		If opts.verbose>=0 Print "Archiving "+outputFile
 		
 		DeleteFile( outputFile )
@@ -731,6 +739,8 @@ Class Builder
 			
 		Next
 		
+		Return outputFile
+		
 	End
 	
 	Method GetNamespace:NamespaceScope( path:String )
@@ -1048,12 +1058,20 @@ Class Builder
 	End
 	
 	Method Exec:Bool( cmd:String )
-	
-		If Not system( cmd+" 2>errs.txt" ) Return True
+
+		Local errs:=""
+		For Local i:=1 Until 10
+			errs="tmp/errs"+i+".txt"
+			DeleteFile( errs )
+			If GetFileType( errs )=FileType.None Exit
+			errs=""
+		Next
+			
+		If Not system( cmd+" 2>"+errs ) Return True
 		
-		Local errs:=LoadString( "errs.txt" )
+		Local terrs:=LoadString( errs )
 		
-		Throw New BuildEx( "System command '"+cmd+"' failed.~n~n"+cmd+"~n~n"+errs )
+		Throw New BuildEx( "System command '"+cmd+"' failed.~n~n"+cmd+"~n~n"+terrs )
 		
 		Return False
 	End

+ 8 - 1
src/mx2new/class.monkey2

@@ -48,6 +48,9 @@ Class ClassType Extends Type
 
 	Field abstractMethods:FuncValue[]
 	
+	Field fields:=New Stack<SNode>
+	Field methods:=New Stack<SNode>
+	
 	Method New( cdecl:ClassDecl,outer:Scope,types:Type[],instanceOf:ClassType )
 	
 		Self.pnode=cdecl
@@ -63,6 +66,10 @@ Class ClassType Extends Type
 		For Local member:=Eachin cdecl.members
 			Local node:=member.ToNode( scope )
 			scope.Insert( member.ident,node )
+			Select member.kind
+			Case "field" fields.Push( node )
+'			Case "method" methods.Push( node )
+			End
 		Next
 		
 	End
@@ -378,7 +385,7 @@ Class ClassType Extends Type
 		If membersSemanting SemantError( "ClassType.FindNode() class='"+ToString()+"', ident='"+ident+"'" )
 	
 		Local node:=scope.GetNode( ident )
-		If node Return node
+		If node Or ident="new" Return node
 		
 		If superType Return superType.FindNode( ident )
 		

+ 23 - 22
src/mx2new/decl.monkey2

@@ -1,32 +1,30 @@
 
 Namespace mx2
 
-Const DECL_PUBLIC:=1
-Const DECL_PRIVATE:=2
-Const DECL_PROTECTED:=4
-Const DECL_ACCESSMASK:=DECL_PUBLIC|DECL_PRIVATE|DECL_PROTECTED
+Const DECL_PUBLIC:=		$000001
+Const DECL_PRIVATE:=	$000002
+Const DECL_PROTECTED:=	$000004
+Const DECL_INTERNAL:=	$000008
 
-Const DECL_VIRTUAL:=8
-Const DECL_OVERRIDE:=16
-Const DECL_ABSTRACT:=32
-Const DECL_FINAL:=64
+Const DECL_VIRTUAL:=	$000100
+Const DECL_OVERRIDE:=	$000200
+Const DECL_ABSTRACT:=	$000400
+Const DECL_FINAL:=		$000800
+Const DECL_EXTERN:=		$001000
+Const DECL_EXTENSION:=	$002000
+Const DECL_DEFAULT:=	$004000
 
-Const DECL_EXTERN:=128
+Const DECL_GETTER:=		$010000
+Const DECL_SETTER:=		$020000
+Const DECL_OPERATOR:=	$040000
+Const DECL_IFACEMEMBER:=$080000
 
-Const DECL_GETTER:=256
-Const DECL_SETTER:=512
-Const DECL_OPERATOR:=1024
-Const DECL_IFACEMEMBER:=2048
-
-Const DECL_EXTENSION:=4096
-
-Const DECL_DEFAULT:=8192
+Const DECL_ACCESSMASK:=DECL_PUBLIC|DECL_PRIVATE|DECL_PROTECTED|DECL_INTERNAL
 
 Class Decl Extends PNode
 
 	Field kind:String
 	Field ident:String
-	Field idscope:String
 	Field flags:Int
 	Field symbol:String
 	Field docs:String
@@ -41,12 +39,16 @@ Class Decl Extends PNode
 		Return (flags & DECL_PUBLIC)<>0
 	End
 	
+	Property IsPrivate:Bool()
+		Return (flags & DECL_PRIVATE)<>0
+	End
+
 	Property IsProtected:Bool()
 		Return (flags & DECL_PROTECTED)<>0
 	End
 	
-	Property IsPrivate:Bool()
-		Return (flags & DECL_PRIVATE)<>0
+	Property IsInternal:Bool()
+		Return (flags & DECL_INTERNAL)<>0
 	End
 	
 	Property IsVirtual:Bool()
@@ -90,7 +92,7 @@ Class Decl Extends PNode
 	End
 	
 	Method ToString:String() Override
-		Return kind.Capitalize()+" "+idscope+ident
+		Return kind.Capitalize()+" "+ident
 	End
 	
 	Method Emit( buf:StringStack,spc:String ) Virtual
@@ -117,7 +119,6 @@ Class FileDecl Extends Decl
 	Field imports:String[]
 	Field errors:ParseEx[]
 
-	'for trans...!
 	Field module:Module	
 	Field exhfile:String	
 	Field hfile:String

+ 13 - 6
src/mx2new/docsmaker.monkey2

@@ -182,13 +182,13 @@ Class DocsMaker
 			If i2=-1 Exit
 			slug=slug.Slice( 0,i )+slug.Slice( i2+1 )
 		Forever
-		slug=slug.Replace( ".","-" )
+		'slug=slug.Replace( ".","-" )
 		Return slug
 	End
 	
 	Method NamespaceSlug:String( nmspace:NamespaceScope )
 		Local slug:=nmspace.Name
-		slug=slug.Replace( ".","-" )
+		'slug=slug.Replace( ".","-" )
 		Return slug
 	End
 	
@@ -208,8 +208,12 @@ Class DocsMaker
 	End
 	
 	Method MakeLink:String( text:String,module:String,page:String )
+	
+		Local url:=module+":"+page
+		
+		Return "<a href=~qjavascript:void('"+url+"')~q onclick=~qdocsLinkClicked('"+url+"')~q>"+text+"</a>"
 		
-		Return "<a href='javascript:void(0)' onclick=~qdocsLinkClicked('"+page+"','"+module+"')~q>"+text+"</a>"
+'		Return "<a href='javascript:void(0)' onclick=~qdocsLinkClicked('"+module+":"+page+"')~q>"+text+"</a>"
 	End
 	
 	Method MakeLink:String( text:String,decl:Decl,scope:Scope )
@@ -253,7 +257,7 @@ Class DocsMaker
 			Local id:=path.Slice( i0,i1 )
 			i0=i1+1
 			
-			Print "Finding type "+id+" in "+scope.Name
+'			Print "Finding type "+id+" in "+scope.Name
 			
 			Local type:=scope.FindType( id )
 			If Not type Return ""
@@ -342,6 +346,7 @@ Class DocsMaker
 	End
 	
 	Method SavePage( docs:String,page:String )
+		page=page.Replace( ".","-" )
 		docs=_pageTemplate.Replace( "${CONTENT}",docs )
 		stringio.SaveString( docs,_pagesDir+page+".html" )
 	End
@@ -459,7 +464,7 @@ Class DocsMaker
 				If init
 					init=False
 					EmitBr()
-					Emit( "| Aliases | |" )
+					Emit( "| Aliases | &nbsp; |" )
 					Emit( "|:---|:---" )
 				Endif
 				
@@ -639,7 +644,9 @@ Class DocsMaker
 		
 		Local xtends:=""
 		If ctype.superType
-			xtends=" Extends "+TypeName( ctype.superType,ctype.scope.outer )
+			If ctype.superType<>Type.ObjectClass
+				xtends=" Extends "+TypeName( ctype.superType,ctype.scope.outer )
+			Endif
 		Else If ctype.isvoid
 			xtends=" Extends Void"
 		Endif

+ 5 - 4
src/mx2new/expr.monkey2

@@ -314,20 +314,21 @@ Class NewObjectExpr Extends Expr
 		Endif
 		
 		Local args:=SemantArgs( Self.args,scope )
-		
-		Local ctor:=ctype.FindNode( "new" )
-		
 		Local ctorFunc:FuncValue
 		
+		Local ctor:=ctype.FindNode( "new" )
 		If ctor
 
-			Local invoke:=Cast<InvokeValue>( ctor.ToValue( Null ).Invoke( args ) )
+			Local ctorValue:=ctor.ToValue( Null )
 			
+			Local invoke:=Cast<InvokeValue>( ctorValue.Invoke( args ) )
 			If Not invoke Throw New SemantEx( "Can't invoke class '"+ctype.Name+"' constuctor with arguments '"+Join( args )+"'" )
 			
 			ctorFunc=Cast<FuncValue>( invoke.value )
 			If Not ctorFunc SemantError( "NewObjectExpr.OnSemant()" )
 			
+			ctorFunc.CheckAccess( scope )
+			
 			args=invoke.args
 
 		Else If args

+ 5 - 0
src/mx2new/func.monkey2

@@ -45,6 +45,7 @@ Class FuncValue Extends Value
 	Field instanceOf:FuncValue
 	Field pdecls:VarDecl[]
 	Field transFile:FileDecl
+	Field cscope:ClassScope
 	
 	Field block:Block
 	Field ftype:FuncType
@@ -73,6 +74,7 @@ Class FuncValue Extends Value
 		Self.instanceOf=instanceOf
 		Self.pdecls=fdecl.type.params
 		Self.transFile=scope.FindFile().fdecl
+		Self.cscope=Cast<ClassScope>( scope )
 		
 		If fdecl.kind="lambda" captures=New Stack<VarValue>
 	End
@@ -293,6 +295,7 @@ Class FuncValue Extends Value
 	End
 	
 	Method CheckAccess( tscope:Scope ) Override
+
 		CheckAccess( fdecl,scope,tscope )
 	End
 	
@@ -395,6 +398,8 @@ Class FuncValue Extends Value
 
 		Else
 		
+			If fdecl.kind="method" cscope.ctype.methods.Push( Self )
+		
 			scope.transMembers.Push( Self )
 
 		Endif

+ 23 - 8
src/mx2new/htmldocsmaker.monkey2

@@ -80,11 +80,17 @@ Class HtmlDocsMaker Extends DocsMaker
 	End
 	
 	Method BeginNode( name:String,page:String="" )
-		If page page=",page:'"+page+"'"
-		Local module:=",module:'"+_module.name+"'"
+	
+		If page page=",page:'"+_module.name+":"+page+"'"
 		_posStack.Push( _sep )
 		_posStack.Push( _buf.Length )
-		EmitTree( "{ name:'"+name+"'"+module+page+",children:[" )
+		EmitTree( "{ name:'"+name+"'"+page+",children:[" )
+			
+'		If page page=",page:'"+page+"'"
+'		Local module:=",module:'"+_module.name+"'"
+'		_posStack.Push( _sep )
+'		_posStack.Push( _buf.Length )
+'		EmitTree( "{ name:'"+name+"'"+module+page+",children:[" )
 	End
 	
 	Method EndNode( force:Bool=False )
@@ -97,19 +103,28 @@ Class HtmlDocsMaker Extends DocsMaker
 	End
 	
 	Method EmitLeaf( name:String,page:String="" )
-		If page page=",page:'"+page+"'"
-		Local module:=",module:'"+_module.name+"'"
-		EmitTree( "{ name:'"+name+"'"+module+page+",children:[] }" )
+	
+		If page page=",page:'"+_module.name+":"+page+"'"
+		EmitTree( "{ name:'"+name+"'"+page+",children:[] }" )
+
+'		If page page=",page:'"+page+"'"
+'		Local module:=",module:'"+_module.name+"'"
+'		EmitTree( "{ name:'"+name+"'"+module+page+",children:[] }" )
+		
 	End
 	
 	Method EmitLeaf( decl:Decl,page:String="" )
 
-		EmitLeaf( DeclIdent( decl,False ),page )
+		EmitLeaf( decl.ident,page )
+
+'		EmitLeaf( DeclIdent( decl,False ),page )
 	End
 	
 	Method EmitNode( decl:Decl,scope:Scope,page:String="",force:Bool=False )
 	
-		EmitNode( DeclIdent( decl,False ),scope,page,force )
+		EmitNode( decl.ident,scope,page,force )
+
+'		EmitNode( DeclIdent( decl,False ),scope,page,force )
 	End
 	
 	Method EmitNode( name:String,scope:Scope,page:String="",force:Bool=False )

+ 5 - 0
src/mx2new/mung.monkey2

@@ -80,6 +80,11 @@ Function MungArg:String( type:Type )
 	If ctype
 		Return "T"+ClassName( ctype )+"_2"
 	Endif
+	
+	Local etype:=TCast<EnumType>( type )
+	If etype
+		Return "T"+EnumName( etype )+"_2"
+	Endif
 
 	Local qtype:=TCast<PointerType>( type )
 	If qtype

+ 8 - 4
src/mx2new/mx2.monkey2

@@ -40,7 +40,11 @@ Using std.filesystem
 Using std.collections
 Using lib.c
 
-Const MX2CC_VERSION:="003"
-
-Global MX2_MODULES_VERSION:=""
-Global MX2_PRODUCT_VERSION:=""
+' Messy, but to update version:
+'
+' 1) Update MX2CC_VERSION below
+' 2) ./updatemx2cc
+' 3) edit .sh and .bat files to use new version (common.sh, updatemx2cc.bat, rebuildmx2cc.bat)
+' 4) ./rebuildall
+'
+Const MX2CC_VERSION:="004"

+ 12 - 34
src/mx2new/mx2cc.monkey2

@@ -19,26 +19,20 @@ Using libc
 
 Global StartDir:String
 
-Const TestArgs:="mx2cc makemods -clean"
-
-'Const TestArgs:="mx2cc makeapp src/mx2new/test.monkey2"
-
-'Const TestArgs:="mx2cc makeapp tests/monkey/generics.monkey2"
+'Const TestArgs:="mx2cc makemods -clean"
 
-'Const TestArgs:="mx2cc makedocs monkey libc std"
+Const TestArgs:="mx2cc makeapp src/ted2/ted2.monkey2"
 
-'Const TestArgs:="mx2cc makemods -clean"
+'Const TestArgs:="mx2cc makeapp src/mx2new/test.monkey2"
 
 'Const TestArgs:="mx2cc makeapp src/mx2new/test.monkey2"
 
-'Const TestArgs:="mx2cc makemods -verbose -clean -target=emscripten -config=debug"
+'Const TestArgs:="mx2cc makeapp src/mx2new/test.monkey2"
 
-'Const TestArgs:="mx2cc makemods -verbose -clean -config=release"
+'Const TestArgs:="mx2cc makemods -clean -config=release monkey libc miniz stb-image hoedown std"
 
 'Const TestArgs:="mx2cc makeapp -verbose -target=desktop -config=release src/mx2new/mx2cc.monkey2"
 
-'Const TestArgs:="mx2cc makemods"
-
 Function Main()
 
 	Print "MX2CC V0."+MX2CC_VERSION
@@ -58,24 +52,6 @@ Function Main()
 	
 	LoadEnv( env )
 	
-	MX2_PRODUCT_VERSION=GetEnv( "MX2_PRODUCT_VERSION" )
-	If MX2_PRODUCT_VERSION
-		If MX2_PRODUCT_VERSION<>MX2CC_VERSION
-			Print "MX2_PRODUCT_VERSION="+MX2_PRODUCT_VERSION
-		Endif
-	Else
-		MX2_PRODUCT_VERSION=MX2CC_VERSION
-	Endif
-	
-	MX2_MODULES_VERSION=GetEnv( "MX2_MODULES_VERSION" )
-	If MX2_MODULES_VERSION
-		If MX2_MODULES_VERSION<>MX2CC_VERSION
-			Print "MX2_MODULES_VERSION="+MX2_MODULES_VERSION
-		Endif
-	Else
-		MX2_MODULES_VERSION=MX2CC_VERSION
-	Endif
-	
 	Local args:=AppArgs()
 	
 	If args.Length<2
@@ -143,10 +119,7 @@ Function MakeApp( args:String[] )
 	
 	builder.Parse()
 	builder.Semant()
-	If builder.errors.Length 
-		Print "Errors..."
-		Return
-	Endif
+	If builder.errors.Length Return
 	
 	builder.Translate()
 	If builder.errors.Length Return
@@ -154,7 +127,10 @@ Function MakeApp( args:String[] )
 	builder.Compile()
 	If builder.errors.Length Return
 
-	builder.Link()
+	Local app:=builder.Link()
+	If builder.errors.Length Return
+	
+	If Not opts.run Print "Application built:"+app
 End
 
 Function MakeMods( args:String[] )
@@ -256,6 +232,8 @@ Function ParseOpts:String[]( opts:BuildOpts,args:String[] )
 			Select arg
 			Case "-run"
 				opts.run=True
+			Case "-build"
+				opts.run=False
 			Case "-clean"
 				opts.clean=True
 			Case "-verbose"

+ 131 - 146
src/mx2new/parser.monkey2

@@ -1,4 +1,6 @@
 
+'Help!
+
 Namespace mx2
 
 Class TryParseEx Extends Throwable
@@ -24,58 +26,21 @@ Class Parser
 		_fdecl=New FileDecl
 		_fdecl.ident=ident
 		_fdecl.path=srcPath
-		_fdecl.nmspace="default"
+		_fdecl.nmspace=""
 		
 		Local source:=LoadString( srcPath )
 		_toker=New Toker( source )
 		
-		'PARSE!
-		
 		PNode.parsing=_fdecl
 
 		Bump()
 		CParseEol()
 		
-		If CParse( "namespace" )
-			Try
-				_fdecl.nmspace=ParseNamespaceIdent()
-				ParseEol()
-			Catch ex:ParseEx
-				SkipToNextLine()
-			End
-		Endif
-		
-		_idscope=_fdecl.nmspace+"."
+		_fdecl.members=ParseDecls( DECL_PUBLIC,True )
 		
-		Local flags:=DECL_PUBLIC
+		If Not _fdecl.nmspace _fdecl.nmspace="default"
 		
-		Local usings:=New StringStack
-		usings.Push( "monkey" )
-		
-		While Toke
-			Select Toke
-			Case "public"
-				flags=CParseAccess( flags )
-				CParseEol()
-			Case "private"
-				flags=CParseAccess( flags )
-				CParseEol()
-			Case "using"
-				Try
-					Bump()
-					usings.Push( ParseUsingIdent() )
-					ParseEol()
-				Catch ex:ParseEx
-					SkipToNextLine()
-				End
-			Default
-				Exit
-			End
-		Wend
-		
-		_fdecl.members=ParseDecls( Null,flags )
-		
-		_fdecl.usings=usings.ToArray()
+		_fdecl.usings=_usings.ToArray()
 		_fdecl.imports=_imports.ToArray()
 		_fdecl.errors=_errors.ToArray()
 		_fdecl.endpos=EndPos
@@ -112,10 +77,7 @@ Class Parser
 		Return ident
 	End
 	
-	Method ParseDecls:Decl[]( parent:Decl,flags:Int )
-	
-		Local idscope:=_idscope
-		If parent _idscope+=parent.ident+"."
+	Method ParseDecls:Decl[]( flags:Int,fileScope:Bool )
 	
 		Local decls:=New Stack<Decl>
 		
@@ -124,26 +86,15 @@ Class Parser
 				Select Toke
 				Case "end"
 					Exit
-				Case "extern"
-					Bump()
-					If parent ErrorNx( "Extern must appear at file scope" )
-					flags&= ~DECL_ACCESSMASK
-					flags|= DECL_EXTERN | DECL_PUBLIC
-					flags=CParseAccess( flags )
-					CParseEol()
-				Case "public","private","protected"
-					flags&= ~DECL_ACCESSMASK
-					If Not parent flags&= ~DECL_EXTERN
-					flags=CParseAccess( flags )
-					CParseEol()
 				Case "const"
 					ParseVars( decls,flags )
 				Case "global"
 					ParseVars( decls,flags )
 				Case "field"
+					If fileScope Error( "Fields can only be declared inside a class, struct or interface" )
 					ParseVars( decls,flags )
 				Case "local"
-					ParseVars( decls,flags )
+					Error( "Locals can only be declared in a statement block" )
 				Case "alias"
 					ParseAliases( decls,flags )
 				Case "class"
@@ -152,18 +103,58 @@ Class Parser
 					decls.Push( ParseClass( flags ) )
 				Case "interface"
 					decls.Push( ParseClass( flags ) )
-				Case "protocol"
-					decls.Push( ParseClass( flags ) )
+'				Case "protocol"
+'					decls.Push( ParseClass( flags ) )
 				Case "enum"
 					decls.Push( ParseEnum( flags ) )
 				Case "function"
 					decls.Push( ParseFunc( flags ) )
 				Case "method"
+					If fileScope Error( "Methods can only be declared inside a class, struct or interface" )
 					decls.Push( ParseFunc( flags ) )
 				Case "operator"
+					If fileScope Error( "Operators can only be declared inside a class, struct or interface" )
 					decls.Push( ParseFunc( flags ) )
 				Case "property"
+					If fileScope Error( "Properties can only be declared inside a class, struct or interface" )
 					decls.Push( ParseProperty( flags ) )
+				Case "namespace"
+					If Not fileScope Or decls.Length Or _usings.Length Error( "'Namespace' must appear at the start of the file" )
+					If _fdecl.nmspace Error( "Duplicate namespace declaration" )
+					Bump()					
+					_fdecl.nmspace=ParseNamespaceIdent()
+					ParseEol()
+				Case "using"
+					If Not fileScope Or decls.Length Error( "Usings must appear before any declarations in a file" )
+					Bump()
+					_usings.Push( ParseUsingIdent() )
+					ParseEol()
+				Case "extern"
+					If Not fileScope Error( "'Extern' must appear at file scope" )
+					Bump()
+					flags=(flags & ~DECL_ACCESSMASK) | DECL_EXTERN
+					If CParse( "private" )
+						flags|=DECL_PRIVATE
+					Else
+						CParse( "public" )
+						flags|=DECL_PUBLIC
+					Endif
+					ParseEol()
+				Case "public","private"
+					flags&=~DECL_ACCESSMASK
+					If fileScope flags&=~DECL_EXTERN
+					If CParse( "private" )
+						flags|=DECL_PRIVATE
+					Else
+						Parse( "public" )
+						flags|=DECL_PUBLIC
+					Endif
+					ParseEol()
+				Case "protected"
+					If fileScope Error( "'Protected' can only be used in a class, struct or interface" )
+					Bump()
+					flags=(flags & ~DECL_ACCESSMASK)|DECL_PROTECTED
+					ParseEol()
 				Default
 					Error( "Unexpected token '"+Toke+"'" )
 				End
@@ -172,8 +163,6 @@ Class Parser
 			End
 		Wend
 		
-		_idscope=idscope
-		
 		Return decls.ToArray()
 	End
 	
@@ -183,6 +172,7 @@ Class Parser
 		Case "public" flags=flags & ~(DECL_ACCESSMASK) | DECL_PUBLIC
 		Case "private" flags=flags & ~(DECL_ACCESSMASK) | DECL_PRIVATE
 		Case "protected" flags=flags & ~(DECL_ACCESSMASK) | DECL_PROTECTED
+		Case "internal" flags=flags & ~(DECL_ACCESSMASK) | DECL_INTERNAL
 		Default Return flags
 		End
 		Bump()
@@ -203,7 +193,6 @@ Class Parser
 				decl.docs=Docs()
 				decl.flags=flags
 				decl.ident=ParseIdent()
-				decl.idscope=_idscope
 				decl.genArgs=ParseGenArgs()
 				
 				Parse( ":" )
@@ -236,12 +225,11 @@ Class Parser
 				decl.docs=Docs()
 				decl.flags=flags
 				decl.ident=ParseIdent()
-				decl.idscope=_idscope
 				
 				If flags & DECL_EXTERN
 					Parse( ":" )
 					decl.type=ParseType()
-					If CParse( "=" ) decl.symbol=ParseString() 'Else decl.symbol=decl.ident
+					If CParse( "=" ) decl.symbol=ParseString()
 				Else If CParse( ":" )
 					decl.type=ParseType()
 					If CParse( "=" ) decl.init=ParseExpr()
@@ -263,47 +251,37 @@ Class Parser
 	End
 	
 	Method ParseClass:ClassDecl( flags:Int )
-	
-		Local srcpos:=SrcPos
-		Local kind:=Parse()
-		Local docs:=Docs()
-		Local ident:="?????"
-		Local genArgs:String[]
-		Local superType:TypeExpr
-		Local ifaceTypes:TypeExpr[]
-		Local symbol:=""
-	
-		Local mflags:=DECL_PUBLIC | (flags & DECL_EXTERN)
-		
-		If kind="interface" mflags|=DECL_IFACEMEMBER|DECL_ABSTRACT
 		
-		If kind="protocol" mflags|=DECL_IFACEMEMBER|DECL_ABSTRACT
+		Local decl:=New ClassDecl
+		decl.srcpos=SrcPos
+		decl.kind=Parse()
+		decl.docs=Docs()
+		decl.ident="?????"
 		
 		Try
-			ident=ParseIdent()
-
-			genArgs=ParseGenArgs()
+			decl.ident=ParseIdent()
+			
+			decl.genArgs=ParseGenArgs()
 			
 			If CParse( "extends" )
-				If kind="interface"
-					ifaceTypes=ParseTypes()
-				Else If kind="protocol"
-					ifaceTypes=ParseTypes()
+				If decl.kind="interface" Or decl.kind="protocol"
+					decl.ifaceTypes=ParseTypes()
 				Else
-					superType=ParseType()
+					decl.superType=ParseType()
 				Endif
 			Endif
 			
 			If CParse( "implements" )
-				ifaceTypes=ParseTypes()
+				If decl.kind<>"class" And decl.kind<>"struct" Error( "'Implements' can only be used with classes and structs" )
+				decl.ifaceTypes=ParseTypes()
 			Endif
 			
 			Select Toke
 			Case "virtual","abstract","final"
 			
-				If kind="interface" Error( "Interfaces are implicitly abstract" )
+				If decl.kind="interface" Error( "Interfaces are implicitly abstract" )
 				
-				If kind="protocol" Error( "Protocols cannot have modifiers" )
+				If decl.kind="protocol" Error( "Protocols cannot have modifiers" )
 				
 				If CParse( "virtual" )
 					flags|=DECL_VIRTUAL
@@ -315,9 +293,10 @@ Class Parser
 				
 			End
 			
-			If flags & DECL_EXTERN
-				If CParse( "=" ) symbol=ParseString()
-			Endif
+			If CParse( "=" )
+				If Not (flags & DECL_EXTERN) Error( "Non-extern declaration cannot be assigned an extern symbol" )
+				decl.symbol=ParseString()
+			End
 		
 			ParseEol()
 		
@@ -326,18 +305,12 @@ Class Parser
 			SkipToNextLine()
 		End
 		
-		Local decl:=New ClassDecl
-		decl.srcpos=srcpos
-		decl.kind=kind
-		decl.ident=ident
 		decl.flags=flags
-		decl.docs=docs
-		decl.genArgs=genArgs
-		decl.superType=superType
-		decl.ifaceTypes=ifaceTypes
-		decl.symbol=symbol
 		
-		decl.members=ParseDecls( decl,mflags )
+		Local mflags:=(flags & DECL_EXTERN) | DECL_PUBLIC
+		If decl.kind="interface" Or decl.kind="protocol" mflags|=DECL_IFACEMEMBER|DECL_ABSTRACT
+		
+		decl.members=ParseDecls( mflags,False )
 		
 		Try
 			Parse( "end" )
@@ -350,7 +323,7 @@ Class Parser
 		decl.endpos=EndPos
 		Return decl
 	End
-	
+
 	Method ParseFunc:FuncDecl( flags:Int )
 	
 		Local srcpos:=SrcPos
@@ -433,7 +406,7 @@ Class Parser
 					kind="method"
 					flags|=DECL_SETTER
 				Else
-					Error( "Property must have 0 or 1 parameters" )
+					Error( "Properties must have 0 or 1 parameters" )
 				End
 			Case "method"
 				If (flags & DECL_GETTER)
@@ -465,6 +438,7 @@ Class Parser
 			End
 			
 			If CParse( "=" )
+				If Not (flags & DECL_EXTERN) Error( "Non-extern declarations cannot be assigned an extern symbol" )
 				symbol=ParseString()
 			Endif
 
@@ -538,12 +512,12 @@ Class Parser
 		
 		Try
 			decl.ident=ParseIdent()
-			decl.idscope=_idscope
 			
 			If CParse( "extends" ) decl.superType=ParseType()
 			
-			If flags & DECL_EXTERN
-				If CParse( "=" ) decl.symbol=ParseString() 'Else decl.symbol=decl.ident
+			If CParse( "=" )
+				If Not (flags & DECL_EXTERN) Error( "Non-extern declaration cannot be assigned an extern symbol" )
+				decl.symbol=ParseString()
 			Endif
 			
 			ParseEol()
@@ -564,11 +538,10 @@ Class Parser
 				decl.kind="const"
 				decl.flags=DECL_PUBLIC|(flags & DECL_EXTERN)
 				decl.ident=ParseIdent()
-				decl.idscope=_idscope
 				decl.docs=Docs()
 				
 				If flags & DECL_EXTERN
-					If CParse( "=" ) decl.symbol=ParseString() 'Else decl.symbol=decl.ident
+					If CParse( "=" ) decl.symbol=ParseString()
 				Else
 					If CParse( "=" ) decl.init=ParseExpr()
 				Endif
@@ -1145,7 +1118,6 @@ Class Parser
 				If ident
 					If CParse( ":" )
 						decl.ident=ident
-						decl.idscope=_idscope
 						decl.type=ParseType()
 						If CParse( "=" ) decl.init=ParseExpr()
 					Else
@@ -1725,7 +1697,7 @@ Class Parser
 	
 	'THROWS!
 	Method ParseEol()
-		If TokeType<>TOKE_EOL Error( "Expecting end of line" )
+		If TokeType And TokeType<>TOKE_EOL Error( "Expecting end of line" )
 		EatEols()
 	End
 	
@@ -1874,8 +1846,8 @@ Class Parser
 	
 	Field _fdecl:FileDecl
 	Field _toker:Toker
-	Field _idscope:String
 	Field _stateStack:=New Stack<Toker>
+	Field _usings:=New StringStack
 	Field _errors:=New Stack<ParseEx>
 	
 	'***** Messy Preprocessor - FIXME! *****
@@ -1897,12 +1869,17 @@ Class Parser
 	End
 	
 	Method EvalError()
-	
-		Error( "Failed to evaluate preprocessor expression" )
+		Error( "Failed to evaluate preprocessor expression: toke='"+Toke+"'" )
 	End
 		
 	Method EvalPrimary:String()
 	
+		If CParse( "(" )
+			Local expr:=Eval()
+			Parse( ")" )
+			Return expr
+		Endif
+		
 		Select TokeType
 		Case TOKE_IDENT
 			Local id:=Parse()
@@ -1912,53 +1889,61 @@ Class Parser
 		Case TOKE_STRINGLIT
 			Return Parse()
 		End
-		
+
 		EvalError()
 		Return Null
 	End
 	
 	Method EvalUnary:String()
-	
-		If Toke="not"
-			Local t:=ToBool( EvalPrimary() )
-			If t="true" Return "false" Else Return "true"
+		If CParse( "not" )
+			Local expr:=ToBool( EvalUnary() )
+			If expr="true" Return "false" Else Return "true"
 		Endif
-		
 		Return EvalPrimary()
 	End
 	
-	Method EvalCompare:String()
-	
-		Local t:=EvalUnary()
-		Repeat
-			Select Toke
-			Case "=","<>"
-				Local op:=Parse()
-				Local v:=EvalUnary()
-				If IsBool( t ) Or IsBool( v )
-					t=ToBool( t )
-					v=ToBool( v )
-				Endif
-				Select op
-				Case "="
-					If t=v t="true" Else t="false"
-				Case "<>"
-					If t<>v t="true" Else t="false"
-				End
-			Default
-				Exit
+	Method EvalEquals:String()
+		Local lhs:=EvalUnary()
+		While Toke="=" Or Toke="<>"
+			Local op:=Parse()
+			Local rhs:=EvalUnary()
+			If IsBool( lhs ) Or IsBool( rhs ) 
+				lhs=ToBool( lhs )
+				rhs=ToBool( rhs )
+			Endif
+			Select op
+			Case "=" If lhs=rhs lhs="true" Else lhs="false"
+			Case "<>" If lhs<>rhs lhs="true" Else lhs="false"
 			End
-		Forever
-		Return t
+		Wend
+		Return  lhs
 	End
 	
-	Method Eval:String()
+	Method EvalAnd:String()
+		Local lhs:=EvalEquals()
+		While CParse( "and" )
+			lhs=ToBool( lhs )
+			Local rhs:=ToBool( EvalEquals() )
+			If lhs="true" And rhs="true" lhs="true" Else lhs="false"
+		Wend
+		Return lhs
+	End
 	
-		Return EvalCompare()
+	Method EvalOr:String()
+		Local lhs:=EvalAnd()
+		While CParse( "or" )
+			lhs=ToBool( lhs )
+			Local rhs:=ToBool( EvalAnd() )
+			If lhs="true" Or rhs="true" lhs="true" Else lhs="false"
+		Wend
+		Return lhs
 	End
 	
-	Method EvalBool:Bool()
+	Method Eval:String()
+		Return EvalOr()
+	End
 	
+	Method EvalBool:Bool()
 		Return ToBool( Eval() )="true"
 	End
 	

+ 20 - 3
src/mx2new/test.monkey2

@@ -1,9 +1,26 @@
 
 Namespace test
 
-#Import "<std>"
-#Import "<mojo2>"
+'#Import "<std.monkey2>"
+
+Class B
+End
+
+Struct Test
+	Field z:Int
+	Field y:Int
+	Field x:Int
+	Field a:Int
+	Field b:Int
+	Field c:Int
+	Field m:B
+End
+
+Class C
+	Field t:=New Test[10]
+End
 
 Function Main()
-	Print "Yes"
+	Local c:=New C
+	c.t[0].x=10
 End

+ 1 - 1
src/mx2new/toker.monkey2

@@ -24,7 +24,7 @@ Function InitToker:Void()
 	tokerInited=True
 
 	Local keyWords:="Namespace;Using;Import;Extern;"
-	keyWords+="Public;Private;Protected;Friend;"
+	keyWords+="Public;Private;Protected;Internal;Friend;"
 	keyWords+="Void;Bool;Byte;UByte;Short;UShort;Int;UInt;Long;ULong;Float;Double;String;Object;Continue;Exit;"
 	keyWords+="New;Self;Super;Eachin;True;False;Null;Where;"
 	keyWords+="Alias;Const;Local;Global;Field;Method;Function;Property;Getter;Setter;Operator;Lambda;"

+ 24 - 1
src/mx2new/translator.monkey2

@@ -21,6 +21,15 @@ Function IsGCType:Bool( type:Type )
 	Return False
 End
 
+Function IsGCVarType:Bool( type:Type )
+
+	Local ctype:=TCast<ClassType>( type )
+	If ctype Return ctype.cdecl.kind="class" Or ctype.cdecl.kind="interface"
+	
+	Local atype:=TCast<ArrayType>( type )
+	Return atype<>Null
+End
+
 Function HasGCMembers:Bool( scope:Scope )
 
 	For Local node:=Eachin scope.transMembers
@@ -299,7 +308,18 @@ Class Translator
 		EmitBr()
 		For Local ctype:=Eachin _refsTypes
 		
-			If Not Included( ctype.transFile ) Emit( "struct "+ClassName( ctype )+";" )
+			If Not Included( ctype.transFile ) 
+			
+				Local cname:=ClassName( ctype )
+				Emit( "struct "+ClassName( ctype )+";" )
+				
+				If debug
+					Local tname:=cname
+					If Not IsStruct( ctype ) tname+="*"
+					Emit( "template<> bbDBType *bbDBTypeOf("+tname+"*);" )
+				Endif
+				
+			Endif
 		Next
 		_refsTypes.Clear()
 		
@@ -415,6 +435,9 @@ Class Translator
 	Method Uses( type:Type )
 		Local ctype:=TCast<ClassType>( type )
 		If ctype Uses( ctype )
+		
+		Local atype:=TCast<ArrayType>( type )
+		If atype Uses( atype.elemType )
 	End
 	
 	Method Uses( ctype:ClassType )

+ 78 - 24
src/mx2new/translator_cpp.monkey2

@@ -95,7 +95,10 @@ Class Translator_CPP Extends Translator
 
 		EmitBr()
 		For Local vvar:=Eachin fdecl.globals
-			Emit( VarProto( vvar )+";" )
+			Uses( vvar.type )
+			Local proto:=VarProto( vvar )
+			If IsStruct( vvar.type ) proto+="( bbNullCtor )"
+			Emit( proto+";" )
 		Next
 		
 		For Local func:=Eachin fdecl.functions
@@ -107,7 +110,7 @@ Class Translator_CPP Extends Translator
 		Next
 		
 		EmitGlobalInits( fdecl )
-		
+
 		EndDeps()
 		
 		EmitBr()
@@ -117,13 +120,28 @@ Class Translator_CPP Extends Translator
 	
 	'***** Decls *****
 	
+	Method IsGCVarType:Bool( type:Type )
+	
+		Local ctype:=TCast<ClassType>( type )
+		If ctype Return (ctype.cdecl.kind="class" Or ctype.cdecl.kind="interface") 
+
+		Local atype:=TCast<ArrayType>( type )
+		If atype Return True
+		
+		Return False
+	End
+	
 	Method VarType:String( type:Type )
 	
 		Local ctype:=TCast<ClassType>( type )
-		If ctype And IsGCType( ctype ) Return "bbGCVar<"+ClassName( ctype )+">"
+		If ctype And (ctype.cdecl.kind="class" Or ctype.cdecl.kind="interface")
+			Return "bbGCVar<"+ClassName( ctype )+">"
+		Endif
 		
 		Local atype:=TCast<ArrayType>( type )
-		If atype Return "bbGCVar<"+ArrayName( atype )+">"
+		If atype
+			Return "bbGCVar<"+ArrayName( atype )+">"
+		Endif
 		
 		Return TransType( type )
 	End
@@ -305,7 +323,7 @@ Class Translator_CPP Extends Translator
 			Next
 		Endif
 		
-		Emit( "const char *typeName(){return~q"+cname+"~q;}" )
+		Emit( "const char *typeName()const{return ~q"+cname+"~q;}" )
 		
 		'Emit fields...
 		'
@@ -313,9 +331,17 @@ Class Translator_CPP Extends Translator
 		Local needsMark:=False
 
 		EmitBr()		
-		For Local node:=Eachin ctype.scope.transMembers
+		For Local node:=Eachin ctype.fields	'scope.transMembers
 			Local vvar:=Cast<VarValue>( node )
 			If Not vvar Continue
+
+			#rem			
+			If cdecl.kind="struct"
+				Uses( vvar.type )
+			Else
+				Refs( vvar.type )
+			Endif
+			#end
 			
 			Refs( vvar.type )
 
@@ -350,7 +376,7 @@ Class Translator_CPP Extends Translator
 		Local hasDefaultCtor:=False
 		
 		EmitBr()
-		For Local node:=Eachin ctype.scope.transMembers
+		For Local node:=Eachin ctype.methods	'scope.transMembers
 			Local func:=Cast<FuncValue>( node )
 			If Not func Or func.fdecl.ident<>"new" Continue
 			
@@ -366,7 +392,7 @@ Class Translator_CPP Extends Translator
 		Local hasCmp:=False
 		
 		EmitBr()
-		For Local node:=Eachin ctype.scope.transMembers
+		For Local node:=Eachin ctype.methods	'scope.transMembers
 			Local func:=Cast<FuncValue>( node )
 			If Not func Or func.fdecl.ident="new" Continue
 			
@@ -383,10 +409,22 @@ Class Translator_CPP Extends Translator
 			Emit( cname+"(){" )
 			If needsInit Emit( "init();" )
 			Emit( "}" )
-		End
+		Endif
+		
+		If IsStruct( ctype )
+			EmitBr()
+			Emit( cname+"(bbNullCtor_t){" )
+			Emit( "}" )
+		Endif
 		
 		Emit( "};" )
 		
+		If debug
+			Local tname:=cname
+			If Not IsStruct( ctype ) tname+="*"
+			Emit( "template<> bbDBType *bbDBTypeOf("+tname+"*);" )
+		Endif
+		
 		If IsStruct( ctype )
 
 			EmitBr()
@@ -411,14 +449,14 @@ Class Translator_CPP Extends Translator
 		
 		Local cdecl:=ctype.cdecl
 		Local cname:=ClassName( ctype )
-	
+		
 		'Emit fields...
 		'
 		Local needsInit:=False
 		Local needsMark:=False
 
 		EmitBr()		
-		For Local node:=Eachin ctype.scope.transMembers
+		For Local node:=Eachin ctype.fields	'scope.transMembers
 			Local vvar:=Cast<VarValue>( node )
 			If Not vvar Continue
 			
@@ -435,7 +473,7 @@ Class Translator_CPP Extends Translator
 			
 			BeginGCFrame()
 			
-			For Local node:=Eachin ctype.scope.transMembers
+			For Local node:=Eachin ctype.fields	'scope.transMembers
 				Local vvar:=Cast<VarValue>( node )
 				If Not vvar Or Not vvar.init Or Cast<LiteralValue>( vvar.init ) Continue
 				
@@ -459,7 +497,7 @@ Class Translator_CPP Extends Translator
 				Emit( ClassName( ctype.superType )+"::gcMark();" )
 			End
 		
-			For Local node:=Eachin ctype.scope.transMembers
+			For Local node:=Eachin ctype.fields	'scope.transMembers
 				Local vvar:=Cast<VarValue>( node )
 				If Not vvar Or Not IsGCType( vvar.type ) Continue
 				
@@ -473,7 +511,7 @@ Class Translator_CPP Extends Translator
 	
 		'Emit ctor methods
 		'
-		For Local node:=Eachin ctype.scope.transMembers
+		For Local node:=Eachin ctype.methods	'scope.transMembers
 			Local func:=Cast<FuncValue>( node )
 			If Not func Or func.fdecl.ident<>"new" Continue
 			
@@ -485,7 +523,7 @@ Class Translator_CPP Extends Translator
 		'
 		Local hasCmp:=False
 		
-		For Local node:=Eachin ctype.scope.transMembers
+		For Local node:=Eachin ctype.methods	'scope.transMembers
 			Local func:=Cast<FuncValue>( node )
 			If Not func Or func.fdecl.ident="new" Continue
 			
@@ -497,6 +535,18 @@ Class Translator_CPP Extends Translator
 			EmitFunc( func )
 		Next
 		
+		If debug
+			Local tname:=cname
+			If Not IsStruct( ctype ) tname+="*"
+			Emit(	"template<> bbDBType *bbDBTypeOf("+tname+"*){" )
+			Emit(		"struct type : public bbDBType{" )
+			Emit(			"bbString name(){return ~q"+ctype.Name+"~q;}" )
+			Emit(		"};" )
+			Emit(		"static type _type;" )
+			Emit(	 	"return &_type;" )
+			Emit(	"}" )
+		Endif
+
 		'Emit static struct methods
 		'
 		If IsStruct( ctype ) 
@@ -504,7 +554,7 @@ Class Translator_CPP Extends Translator
 			If Not hasCmp
 				EmitBr()
 				Emit( "int bbCompare("+cname+"&x,"+cname+"&y){" )
-				For Local node:=Eachin ctype.scope.transMembers
+				For Local node:=Eachin ctype.fields	'scope.transMembers
 					Local vvar:=Cast<VarValue>( node )
 					If Not vvar Continue
 					Local vname:=VarName( vvar )
@@ -523,7 +573,7 @@ Class Translator_CPP Extends Translator
 					Emit( "bbGCMark(("+ClassName( ctype.superType )+"&)t);" )
 				Endif
 	
-				For Local node:=Eachin ctype.scope.transMembers
+				For Local node:=Eachin ctype.fields	'scope.transMembers
 					Local vvar:=Cast<VarValue>( node )
 					If Not vvar Or Not IsGCType( vvar.type ) Continue
 					
@@ -573,10 +623,12 @@ Class Translator_CPP Extends Translator
 			For Local dep:=Eachin module.moduleDeps.Keys
 			
 				Local mod2:=builder.modulesMap[dep]
-				If Not mod2.main Continue
 				
-				Emit( "void mx2_"+mod2.ident+"_main();mx2_"+mod2.ident+"_main();" )
+				If mod2.main
+					Emit( "void mx2_"+mod2.ident+"_main();mx2_"+mod2.ident+"_main();" )
+				Endif
 			Next
+			
 		Endif
 		
 		EmitBlock( func )
@@ -679,7 +731,7 @@ Class Translator_CPP Extends Translator
 			Emit( "bbDBFrame db_f{~q"+func.Name+":"+func.ftype.retType.Name+"("+func.ParamNames+")~q,~q"+func.pnode.srcfile.path+"~q};" )
 			
 			For Local vvar:=Eachin func.params
-				Emit( "bbDBLocal(~q"+vvar.vdecl.ident+":"+vvar.type.TypeId+"~q,&"+Trans( vvar )+");" )
+				Emit( "bbDBLocal(~q"+vvar.vdecl.ident+"~q,&"+Trans( vvar )+");" )
 			Next
 			
 		Endif
@@ -798,7 +850,7 @@ Class Translator_CPP Extends Translator
 			Emit( TransType( vvar.type )+" "+dbvar+init+";" )
 		Endif
 		
-		If debug And dbvar Emit( "bbDBLocal(~q"+vvar.vdecl.ident+":"+vvar.type.TypeId+"~q,&"+dbvar+");" )
+		If debug And dbvar Emit( "bbDBLocal(~q"+vvar.vdecl.ident+"~q,&"+dbvar+");" )
 
 	End
 	
@@ -1180,7 +1232,6 @@ Class Translator_CPP Extends Translator
 	Method Trans:String( value:NewObjectValue )
 	
 		Local ctype:=value.ctype
-	
 		Uses( ctype )
 	
 		If IsStruct( ctype ) Return ClassName( ctype )+"("+TransArgs( value.args )+")"
@@ -1192,9 +1243,12 @@ Class Translator_CPP Extends Translator
 	
 	Method Trans:String( value:NewArrayValue )
 	
-		If value.inits Return ArrayName( value.atype )+"::create({"+TransArgs( value.inits )+"},"+value.inits.Length+")"
+		Local atype:=value.atype
+		Uses( atype )
+	
+		If value.inits Return ArrayName( atype )+"::create({"+TransArgs( value.inits )+"},"+value.inits.Length+")"
 		
-		Return ArrayName( value.atype )+"::create("+TransArgs( value.sizes )+")"
+		Return ArrayName( atype )+"::create("+TransArgs( value.sizes )+")"
 	End
 	
 	Method Trans:String( value:ArrayIndexValue )

+ 4 - 4
src/mx2new/type.monkey2

@@ -51,14 +51,14 @@ Class Type Extends SNode
 	'Not nice - should fix comparison ops
 	Operator=:Bool( type:Type )
 		If Not Self Return Object(type)=Null
-		If type Return Object(type._alias)=_alias
-		Return _alias=Null
+		If Not type Return Object(_alias)=Null
+		Return Object(type._alias)=_alias
 	End
 	
 	Operator<>:Bool( type:Type )
 		If Not Self Return Object(type)<>Null
-		If type Return Object(type._alias)<>_alias
-		Return _alias<>Null
+		If Not type Return Object(_alias)<>Null
+		Return Object(type._alias)<>_alias
 	End
 	
 	Operator<=>:Int( type:Type )

+ 11 - 3
src/mx2new/value.monkey2

@@ -82,9 +82,15 @@ Class Value Extends SNode
 		
 		Local cscope:=Cast<ClassScope>( scope )
 		If cscope
-
+		
 			If scope.FindFile()=tscope.FindFile() Return
 
+			If decl.IsInternal
+				If scope.FindFile().fdecl.module=tscope.FindFile().fdecl.module Return
+
+				Throw New SemantEx( "Internal member '"+decl.ident+"' cannot be accessed from different module" )
+			Endif
+
 			Local ctype:=cscope.ctype
 			Local ctype2:=tscope.FindClass()
 			
@@ -92,6 +98,8 @@ Class Value Extends SNode
 			
 				If ctype=ctype2 Return
 				
+				Throw New SemantEx( "Private member '"+decl.ident+"' cannot be accessed from here" )
+				
 			Else If decl.IsProtected
 			
 				While ctype2
@@ -99,9 +107,9 @@ Class Value Extends SNode
 					ctype2=ctype2.superType
 				Wend
 				
+				Throw New SemantEx( "Protected member '"+decl.ident+"' cannot be accessed from here" )
 			Endif
-			
-			Throw New SemantEx( "Private member '"+decl.ident+"' cannot be accessed from here" )
+
 		Endif
 		
 	End

+ 1 - 1
src/rebuildmx2cc.bat

@@ -6,4 +6,4 @@ echo ***** Updating mx2cc *****
 echo.
 
 ..\bin\mx2cc_windows makeapp -clean -config=release mx2new/mx2cc.monkey2
-copy mx2new\mx2cc.buildv003\desktop_release_windows\mx2cc.exe ..\bin\mx2cc_windows.exe
+copy mx2new\mx2cc.buildv004\desktop_release_windows\mx2cc.exe ..\bin\mx2cc_windows.exe

+ 1 - 1
src/updatemx2cc.bat

@@ -6,4 +6,4 @@ echo ***** Updating mx2cc *****
 echo.
 
 ..\bin\mx2cc_windows makeapp -config=release mx2new/mx2cc.monkey2
-copy mx2new\mx2cc.buildv003\desktop_release_windows\mx2cc.exe ..\bin\mx2cc_windows.exe
+copy mx2new\mx2cc.buildv004\desktop_release_windows\mx2cc.exe ..\bin\mx2cc_windows.exe