Browse Source

Began work on debugger + typeid system.

blitz-research 9 years ago
parent
commit
b5f48c1c88
41 changed files with 890 additions and 358 deletions
  1. 12 4
      README.TXT
  2. BIN
      bin/mx2cc_macos
  3. BIN
      bin/mx2cc_windows.exe
  4. 21 0
      modules/monkey/assert.monkey2
  5. 2 14
      modules/monkey/debug.monkey2
  6. 2 0
      modules/monkey/monkey.monkey2
  7. 12 10
      modules/monkey/native/bbarray.h
  8. 2 0
      modules/monkey/native/bbassert.cpp
  9. 23 0
      modules/monkey/native/bbassert.h
  10. 62 0
      modules/monkey/native/bbdebug.cpp
  11. 49 13
      modules/monkey/native/bbdebug.h
  12. 16 15
      modules/monkey/native/bbmonkey.cpp
  13. 3 2
      modules/monkey/native/bbmonkey.h
  14. 15 0
      modules/monkey/native/bbobject.cpp
  15. 34 3
      modules/monkey/native/bbobject.h
  16. 1 0
      modules/monkey/native/bbstring.cpp
  17. 8 1
      modules/monkey/native/bbstring.h
  18. 93 0
      modules/monkey/native/bbtypes.cpp
  19. 3 1
      modules/monkey/native/bbtypes.h
  20. 21 3
      modules/monkey/types.monkey2
  21. 16 17
      modules/std/filesystemex.monkey2
  22. 9 0
      src/mx2new/alias.monkey2
  23. 32 2
      src/mx2new/class.monkey2
  24. 8 0
      src/mx2new/enum.monkey2
  25. 19 4
      src/mx2new/func.monkey2
  26. 0 68
      src/mx2new/monkey.monkey2x
  27. 7 3
      src/mx2new/mx2cc.monkey2
  28. 26 0
      src/mx2new/namespace.monkey2
  29. 2 2
      src/mx2new/parser.monkey2
  30. 2 2
      src/mx2new/property.monkey2
  31. 12 4
      src/mx2new/scope.monkey2
  32. 41 14
      src/mx2new/stmt.monkey2
  33. 24 24
      src/mx2new/stmtexpr.monkey2
  34. 50 0
      src/mx2new/test.monkey2
  35. 0 14
      src/mx2new/test.monkey2x
  36. 0 0
      src/mx2new/test2.monkey2
  37. 29 30
      src/mx2new/translator.monkey2
  38. 136 104
      src/mx2new/translator_cpp.monkey2
  39. 96 2
      src/mx2new/type.monkey2
  40. 2 2
      src/mx2new/value.monkey2
  41. 0 0
      tests/sdl2/simple_gles20_window.monkey2

+ 12 - 4
README.TXT

@@ -20,9 +20,13 @@ Before getting started, make sure the monkey2 folder is installed alongside (not
 
 2) Once mingw64 is installed, open a command prompt and change to the 'monkey2\src' directory.
 
-3) Enter 'rebuildmods' and hit return.
+3) Enter 'rebuildmods' and hit return. Wait...
 
-4) You should now be able to build and run monkey2 apps with monkey1. There is a 'simple hello-world.monkey2' test in the monkey2 directory.
+4) Enter 'rebuildmx2cc' and hit return. Wait...
+
+5) You should now be able to build and run monkey2 apps with monkey1. There is a 'simple hello-world.monkey2' test in the monkey2 directory.
+
+6) Following a github update, you may need to rebuild the compiler. To do this, perform steps 2-4 again.
 
 
 ***** Installation on MacOS/Linux *****
@@ -33,9 +37,13 @@ Before getting started, make sure the monkey2 folder is installed alongside (not
 
 2) Open a shell and change to the 'monkey2/src' directory.
 
-3) Enter './rebuildmods.sh' and hit return.
+3) Enter './rebuildmods.sh' and hit return. Wait...
+
+4) Enter './rebuildmx2cc.sh' and hit return. Wait...
+
+5) You should now be able to build and run monkey2 apps with monkey1. There is a simple 'hello-world.monkey2' test in the monkey2 directory.
 
-4) You should now be able to build and run monkey2 apps with monkey1. There is a simple 'hello-world.monkey2' test in the monkey2 directory.
+6) Following a github update, you may need to rebuild the compiler. To do this, perform steps 2-4 again.
 
 
 ***** More information *****

BIN
bin/mx2cc_macos


BIN
bin/mx2cc_windows.exe


+ 21 - 0
modules/monkey/assert.monkey2

@@ -0,0 +1,21 @@
+
+Namespace monkey
+
+Extern
+
+Class RuntimeError="bbRuntimeError"
+
+	Method New( message:String )
+	
+	Property Message:String()="message"
+	
+	Property DebugStack:String[]()="debugStack"
+End
+
+Function Assert( condition:Bool )="bbAssert"
+
+Function Assert( condition:Bool,message:String )="bbAssert"
+
+Function DebugAssert( condition:Bool )="bbDebugAssert"
+
+Function DebugAssert( condition:Bool,message:String )="bbDebugAssert"

+ 2 - 14
modules/monkey/debug.monkey2

@@ -1,18 +1,6 @@
 
-Namespace monkey
+Namespace monkey.debug
 
 Extern
 
-Class RuntimeError="bbRuntimeError"
-
-	Method New( msg:String )
-
-End
-
-Function Assert( condition:Bool )="bbAssert"
-
-Function Assert( condition:Bool,message:String )="bbAssert"
-
-Function DebugAssert( condition:Bool )="bbDebugAssert"
-
-Function DebugAssert( condition:Bool,message:String )="bbDebugAssert"
+Function Stop()="bbDB::stop"

+ 2 - 0
modules/monkey/monkey.monkey2

@@ -3,6 +3,7 @@ Namespace monkey
 
 #Import "types.monkey2"
 #Import "math.monkey2"
+#Import "assert.monkey2"
 #Import "debug.monkey2"
 
 #Import "native/bbtypes.cpp"
@@ -15,3 +16,4 @@ Namespace monkey
 #Import "native/bbobject.cpp"
 #Import "native/bbinit.cpp"
 #Import "native/bbdebug.cpp"
+#Import "native/bbassert.cpp"

+ 12 - 10
modules/monkey/native/bbarray.h

@@ -2,10 +2,10 @@
 #ifndef BB_ARRAY_H
 #define BB_ARRAY_H
 
-#include "bbtypes.h"
 #include "bbgc.h"
+#include "bbassert.h"
 
-template<class T,int D=1> class bbArray : public bbGCNode{
+template<class T,int D> class bbArray : public bbGCNode{
 
 	int _sizes[D];
 	T _data[0];
@@ -139,22 +139,24 @@ template<class T,int D=1> class bbArray : public bbGCNode{
 	
 	//fast 1D version	
 	T &at( int index )const{
-		if( index<0 || index>=length() ) puts( "Out of range" );
+		bbDebugAssert( index>=0 && index<length(),"Array index out of range" );
 		return data()[index];
 	}
 	
+	//slower N-D version
 	template<class...Args> T &at( Args...args ){
 	
-		//debug only...
-		if( !this ) puts( "Out of range" );
-		
 		int indices[]{args...};
+		
 		int index=indices[0];
+		bbDebugAssert( index>=0,"Array index out of range" );
+		
 		for( int i=1;i<D;++i ){
-			if( index>=_sizes[i-1] ) puts( "Out of range!" );
+			bbDebugAssert( indices[i]>=0 && index<_sizes[i-1],"Array index out of range" );
 			index+=indices[i]*_sizes[i-1];
 		}
-		if( index>=length() ) puts( "Out of range" );
+		
+		bbDebugAssert( index<length(),"Array index out of range" );
 		return data()[index];
 	}
 	
@@ -326,12 +328,12 @@ template<class T,int D=1> class bbArray{
 	}
 
 	T &operator[]( int index ){
-		if( index<0 || index>=length() ) puts( "OUT OF RANGE" );
+		bbDebugAssert( index>=0 && index<length(),"Array index out of range" );
 		return data()[index];
 	}
 	
 	const T &operator[]( int index )const{
-		if( index<0 || index>=length() ) puts( "OUT OF RANGE" );
+		bbDebugAssert( index>=0 && index<length(),"Array index out of range" );
 		return data()[index];
 	}
 	

+ 2 - 0
modules/monkey/native/bbassert.cpp

@@ -0,0 +1,2 @@
+
+#include "bbassert.h"

+ 23 - 0
modules/monkey/native/bbassert.h

@@ -0,0 +1,23 @@
+
+#ifndef BB_ASSERT_H
+#define BB_ASSERT_H
+
+#include "bbobject.h"
+
+inline void bbAssert( bool cond ){
+	if( !cond ) throw new bbRuntimeError( "Assert failed" );
+}
+
+inline void bbAssert( bool cond,bbString msg ){
+	if( !cond ) throw new bbRuntimeError( msg );
+}
+
+inline void bbDebugAssert( bool cond ){
+	if( !cond ) throw new bbRuntimeError( "Assert failed" );
+}
+
+inline void bbDebugAssert( bool cond,bbString msg ){
+	if( !cond ) throw new bbRuntimeError( msg );
+}
+
+#endif

+ 62 - 0
modules/monkey/native/bbdebug.cpp

@@ -1,2 +1,64 @@
 
 #include "bbdebug.h"
+
+namespace bbDB{
+
+	bbDBFrame *frames;
+	bbDBVar localsBuf[1024];
+	bbDBVar *locals=localsBuf;
+	int srcpos;
+	bool stopper;
+	
+	void dumpStack(){
+	
+		bbDBVar *ev=locals;
+		
+		for( bbDBFrame *f=frames;f;f=f->succ ){
+
+			printf( "%s\n",f->decl );
+			
+			for( bbDBVar *v=f->locals;v!=ev;++v ){
+				char id[64],type[64],value[128];
+				strcpy( id,v->ident().c_str() );
+				strcpy( type,v->typeName().c_str() );
+				strcpy( value,v->getValue().c_str() );
+				printf( "   %s:%s=%s\n",id,type,value );
+			}
+
+			ev=f->locals;
+		}
+	}
+	
+	void stop(){
+		dumpStack();
+	}
+	
+	void stopped(){
+		dumpStack();
+		stopper=false;
+	}
+	
+}
+
+bbString bbDBVar::ident()const{
+	const char *p=strchr( decl,':' );
+	return bbString( decl,p-decl );
+}
+
+bbString bbDBVar::typeName()const{
+	const char *p=strchr( decl,':' )+1;
+	return bbTypeName( p );
+}
+
+bbString bbDBVar::getValue()const{
+	const char *p=strchr( decl,':' )+1;
+	switch( *p ){
+	case 'i':return bbString( *(int*)ptr );
+	case 'f':return bbString( *(float*)ptr );
+	case 's':return "\""+bbString( *(bbString*)ptr )+"\"";
+	case 'A':return "[...]";
+	}
+	
+	return "????";
+}
+

+ 49 - 13
modules/monkey/native/bbdebug.h

@@ -4,28 +4,64 @@
 
 #include "bbstring.h"
 
-struct bbRuntimeError{
+struct bbDBFrame;
 
-	bbString msg;
+struct bbDBVar{
+	const char *decl;
+	void *ptr;
 	
-	bbRuntimeError( bbString msg ):msg( msg ){
-	}
+	bbString ident()const;
+	
+	bbString typeName()const;
+	
+	bbString getValue()const;
 };
 
-inline void bbAssert( bool cond ){
-	if( !cond ) throw new bbRuntimeError( "Assert failed" );
+namespace bbDB{
+	extern bbDBFrame *frames;
+	extern bbDBVar *locals;
+	extern bool stopper;
+	
+	void stop();
+	
+	void stopped();
 }
 
-inline void bbAssert( bool cond,bbString msg ){
-	if( !cond ) throw new bbRuntimeError( msg );
-}
+struct bbDBFrame{
+	bbDBFrame *succ;
+	bbDBVar *locals;
+	const char *decl;
+	const char *srcFile;
+	int srcPos;
+	
+	bbDBFrame( const char *decl,const char *srcFile ):succ( bbDB::frames ),locals( bbDB::locals ),decl( decl ),srcFile( srcFile ){
+		bbDB::frames=this;
+	}
+	
+	~bbDBFrame(){
+		bbDB::locals=locals;
+		bbDB::frames=succ;
+	}
+};
+
+struct bbDBBlock{
+	bbDBVar *locals;
+	bbDBBlock():locals( bbDB::locals ){
+	}
+	~bbDBBlock(){
+		bbDB::locals=locals;
+	}
+};
 
-inline void bbDebugAssert( bool cond ){
-	if( !cond ) throw new bbRuntimeError( "Assert failed" );
+inline void bbDBStmt( int srcPos ){
+	bbDB::frames->srcPos=srcPos;
+	if( bbDB::stopper ) bbDB::stopped();
 }
 
-inline void bbDebugAssert( bool cond,bbString msg ){
-	if( !cond ) throw new bbRuntimeError( msg );
+inline void bbDBLocal( const char *decl,void *ptr ){
+	bbDB::locals->decl=decl;
+	bbDB::locals->ptr=ptr;
+	++bbDB::locals;
 }
 
 #endif

+ 16 - 15
modules/monkey/native/bbmonkey.cpp

@@ -29,6 +29,8 @@ namespace{
 	#endif	
 		}
 		
+		bbAssert( false,err );
+		
 		printf( "Caught signal:%s\n",err );
 		
 #if __APPLE__
@@ -92,32 +94,31 @@ int main( int argc,char **argv ){
 	try{
 	
 		bbGC::init();
-		
-		for( bbInit *init=bbInit::first;init;init=init->succ ){
-//			printf( "Executing initializer '%s'\n",init->info );fflush( stdout );
-			init->init();
+
+		{		
+			bbDBFrame( "_void()","" );
+			
+			for( bbInit *init=bbInit::first;init;init=init->succ ){
+	//			printf( "Executing initializer '%s'\n",init->info );fflush( stdout );
+				init->init();
+			}
 		}
 		
 		bbMain();
 		
 	}catch( bbRuntimeError *ex ){
 	
-		printf( "Monkey2 Runtime Error:%s\n",bbCString( ex->msg ).data() );
+		printf( "\n***** Uncaught RuntimeError exception: %s *****\n\n",ex->message().c_str() );
+		
+		for( int i=0;i<ex->debugStack()->length();++i ){
+			printf( "%s\n",ex->debugStack()->at( i ).c_str() );
+		}
 
 	}catch(...){
 	
-		printf( "Uncaught exception\n" );fflush( stdout );
+		printf( "***** Uncaught native exception *****\n" );fflush( stdout );
 //		throw;
 	}
 	
 	return 0;
 }
-
-/*
-void *operator new( size_t size ){
-}
-
-void operator delete( void *p ){
-	printf( "delete:%p\n",p );
-}
-*/

+ 3 - 2
modules/monkey/native/bbmonkey.h

@@ -6,12 +6,13 @@
 #include "bbtypes.h"
 #include "bbmemory.h"
 #include "bbstring.h"
+#include "bbdebug.h"
+#include "bbassert.h"
 #include "bbgc.h"
-#include "bbfunction.h"
 #include "bbarray.h"
+#include "bbfunction.h"
 #include "bbobject.h"
 #include "bbinit.h"
-#include "bbdebug.h"
 
 extern int bb_argc;
 extern char **bb_argv;

+ 15 - 0
modules/monkey/native/bbobject.cpp

@@ -1,2 +1,17 @@
 
 #include "bbobject.h"
+#include "bbdebug.h"
+#include "bbarray.h"
+
+bbThrowable::bbThrowable(){
+
+	int n=0;
+	for( bbDBFrame *frame=bbDB::frames;frame;frame=frame->succ ) ++n;
+	
+	_debugStack=bbArray<bbString>::create( n );
+	
+	int i=0;
+	for( bbDBFrame *frame=bbDB::frames;frame;frame=frame->succ ){
+		_debugStack->at( i++ )=BB_T( frame->srcFile )+" ["+bbString( frame->srcPos>>12 )+"] "+frame->decl;
+	}
+}

+ 34 - 3
modules/monkey/native/bbobject.h

@@ -3,9 +3,10 @@
 #define BB_OBJECT_H
 
 #include "bbgc.h"
+#include "bbstring.h"
+
+struct bbObject : public bbGCNode{
 
-class bbObject : public bbGCNode{
-public:
 	bbObject(){
 		bbGC::beginCtor( this );
 	}
@@ -13,7 +14,7 @@ public:
 	virtual ~bbObject(){
 	}
 	
-	virtual const char *typeName(){
+	virtual const char *typeName()const{
 		return "monkey.Object";
 	}
 
@@ -34,6 +35,36 @@ public:
 	}
 };
 
+struct bbThrowable : public bbObject{
+
+	bbThrowable();
+	
+	bbArray<bbString> *debugStack()const{
+		return _debugStack;
+	}
+	
+	private:
+	
+	bbGCVar<bbArray<bbString>> _debugStack;
+};
+
+struct bbRuntimeError : public bbThrowable{
+
+	bbRuntimeError(){
+	}
+
+	bbRuntimeError( bbString message ):_message( message ){
+	}
+	
+	bbString message()const{ 
+		return _message; 
+	}
+	
+	private:
+	
+	bbString _message;
+};
+
 template<class T,class...A> T *bbGCNew( A...a ){
 	T *p=new T( a... );
 	bbGC::endCtor( p );

+ 1 - 0
modules/monkey/native/bbstring.cpp

@@ -1,5 +1,6 @@
 
 #include "bbstring.h"
+#include "bbarray.h"
 
 bbString::Rep bbString::_nullRep;
 

+ 8 - 1
modules/monkey/native/bbstring.h

@@ -4,7 +4,6 @@
 
 #include "bbtypes.h"
 #include "bbmemory.h"
-#include "bbarray.h"
 
 class bbCString;
 
@@ -152,6 +151,10 @@ class bbString{
 		return rep;
 	}
 	
+	bbString operator+( const char *str ){
+		return operator+( bbString( str ) );
+	}
+	
 	bbString operator*( int n ){
 		Rep *rep=Rep::alloc( length()*n );
 		bbChar *p=rep->data;
@@ -179,6 +182,10 @@ class bbString{
 		return *this;
 	}
 	
+	bbString &operator+=( const char *str ){
+		return operator+=( bbString( str ) );
+	}
+	
 	int find( bbString str,int from=0 )const{
 		if( from<0 ) from=0;
 		for( int i=from;i<=length()-str.length();++i ){

+ 93 - 0
modules/monkey/native/bbtypes.cpp

@@ -1,2 +1,95 @@
 
 #include "bbtypes.h"
+
+#include "bbstring.h"
+
+namespace{
+
+	bbString typeName( const char *&p );
+	
+	bbString funcName( const char *&p ){
+	
+		bbString retType=typeName( p ),argTypes;
+		while( *p && *p!='E' ){
+			if( argTypes.length() ) argTypes+=",";
+			argTypes+=typeName( p );
+		}
+		if( *p ) ++p;
+		
+		return retType+"("+argTypes+")";
+	}
+
+	bbString arrayName( const char *&p ){
+	
+		int rank=1;
+		if( *p>'0' && *p<='9' ) rank=(*p++)-'0';
+		
+		bbString e=typeName( p );
+		
+		return e+bbString( "[,,,,,,,,,",rank )+"]";
+	}
+	
+	bbString className( const char *&p ){
+		bbString name;
+		
+		const char *p0=p;
+		for( ;; ){
+		
+			if( !*p || *p=='E' ){
+
+				name+=bbString( p0,p-p0 );
+				if( *p ) ++p;
+				return name;
+			}
+			
+			if( *p++!='_' ) continue;
+			
+			name+=bbString( p0,p-p0-1 );
+			
+			if( *p<'0' || *p>'9' ){
+				name+=".";
+				p0=p;
+				continue;
+			}
+			
+			int c=*p++;
+			
+			if( c=='0' ){
+
+				name+="_";
+				
+			}else if( c=='1' ){
+
+				bbString types;
+				while( *p && *p!='E' ){
+					if( types.length() ) types+=",";
+					types+=typeName( p );
+				}
+				name+="<"+types+">";
+				if( !*p ) return name;
+				++p;
+			}
+			
+			p0=p;
+		}
+	}
+	
+	bbString typeName( const char *&p ){
+		switch( *p++ ){
+		case 'v':return "Void";
+		case 'z':return "Bool";
+		case 'i':return "Int";
+		case 'f':return "Float";
+		case 's':return "String";
+		case 'F':return funcName( p );
+		case 'A':return arrayName( p );
+		case 'T':return className( p );
+		case 'P':return typeName( p )+" Ptr";
+		}
+		return "?!?!?";
+	}
+}
+
+bbString bbTypeName( const char *type ){
+	return typeName( type );
+}

+ 3 - 1
modules/monkey/native/bbtypes.h

@@ -20,6 +20,8 @@ typedef unsigned short bbChar;
 
 class bbString;
 template<class T> class bbFunction;
-template<class T,int D> class bbArray;
+template<class T,int D=1> class bbArray;
+
+bbString bbTypeName( const char *type );
 
 #endif

+ 21 - 3
modules/monkey/types.monkey2

@@ -9,7 +9,7 @@ End
 Struct WChar="wchar_t"
 End
 
-Struct Utf8Char="char"
+Struct Utf8Char="unsigned char"
 End
 
 Struct CString="bbCString"
@@ -151,8 +151,6 @@ Struct @Array<T>
 	
 	Property Length:Int()="length"
 	
-	Method Get:T( index:Int )="get"
-	
 	Method Slice:T[]( from:Int )="slice"
 	
 	Method Slice:T[]( from:Int,term:Int )="slice" 
@@ -166,3 +164,23 @@ Class @Object="bbObject"
 	Method typeName:CChar Ptr()="typeName"
 
 End
+
+Class @Throwable="bbThrowable"
+
+	Method DebugStack:String[]()="debugStack"
+	
+End
+
+#rem
+Class @RuntimeError Extends @Throwable="bbRuntimeError"
+
+	Method New()
+	
+	Method New( message:String )
+	
+	Property Message:String()="message"
+
+End
+#end
+
+Function TypeName:String( type:CString )="bbTypeName"

+ 16 - 17
modules/std/filesystemex.monkey2

@@ -277,7 +277,6 @@ Function GetFileTime:Long( path:String )
 	path=StripSlashes( path )
 
 	Local st:stat_t
-	
 	If stat( path,Varptr st )<0 Return 0
 	
 	Return st.st_mtime
@@ -295,7 +294,6 @@ Function GetFileType:FileType( path:String )
 	path=StripSlashes( path )
 
 	Local st:stat_t
-
 	If stat( path,Varptr st )<0 Return FileType.None
 	
 	Select st.st_mode & S_IFMT
@@ -397,18 +395,9 @@ Function CreateDirectory:Bool( path:String,recursive:Bool=True )
 	Return GetFileType( path )=FileType.Directory
 End
 
-#rem monkeydoc Deletes everything at a filesystem path.
-
-Warning! As it's name suggests, this function recursively deletes all files and directories - use carefully!
-
-@param path The filesystem path.
+Private
 
-@return True if succesful.
-
-#end
-Function DeleteEverything:Bool( path:String )
-
-	path=StripSlashes( path )
+Function DeleteAll:Bool( path:String )
 
 	Select GetFileType( path )
 	Case FileType.None
@@ -422,7 +411,7 @@ Function DeleteEverything:Bool( path:String )
 	Case FileType.Directory
 	
 		For Local f:=Eachin LoadDirectory( path )
-			If Not DeleteEverything( path+"/"+f ) Return False
+			If Not DeleteAll( path+"/"+f ) Return False
 		Next
 		
 		rmdir( path )
@@ -432,6 +421,17 @@ Function DeleteEverything:Bool( path:String )
 	Return False
 End
 
+Public
+
+#rem monkeydoc Deletes a directory at a filesystem path.
+
+@path The filesystem path.
+
+@recursive True to delete subdirectories too.
+
+@return True if the directory was successfully deleted or never existed.
+
+#end
 Function DeleteDirectory:Bool( path:String,recursive:Bool=False )
 
 	path=StripSlashes( path )
@@ -447,7 +447,7 @@ Function DeleteDirectory:Bool( path:String,recursive:Bool=False )
 		
 	Case FileType.Directory
 	
-		If recursive Return DeleteEverything( path )
+		If recursive Return DeleteAll( path )
 		
 		rmdir( path )
 		Return GetFileType( path )=FileType.None
@@ -460,13 +460,12 @@ End
 
 @path The filesystem path.
 
-@return true if the file was successfully deleted.
+@return True if the file was successfully deleted.
 
 #end
 Function DeleteFile:Bool( path:String )
 
 	remove( path )
-	
 	Return GetFileType( path )=FileType.None
 End
 

+ 9 - 0
src/mx2new/alias.monkey2

@@ -21,6 +21,15 @@ Class AliasType Extends Type
 		Self.scope=scope
 	End
 	
+	Property Name:String() Override
+		Return "{Alias}"
+	End
+	
+	Property TypeId:String() Override
+		SemantError( "AliasType.TypeId()" )
+		Return ""
+	End
+	
 	Method OnSemant:SNode() Override
 		Local node:=adecl.type.Semant( scope )
 		If Not node Throw New SemantEx( "Can't find type '"+adecl.type.ToString()+"'" )

+ 32 - 2
src/mx2new/class.monkey2

@@ -95,6 +95,14 @@ Class ClassType Extends Type
 		Return str
 	End
 	
+	Property Name:String() Override
+		Return scope.Name
+	End
+	
+	Property TypeId:String() Override
+		Return scope.TypeId
+	End
+	
 	Method OnSemant:SNode() Override
 	
 		If cdecl.superType
@@ -588,7 +596,7 @@ Class OpIndexValue Extends Value
 	End
 	#end
 	
-	Method Assign:Stmt( op:String,rvalue:Value,block:Block ) Override
+	Method Assign:Stmt( pnode:PNode,op:String,rvalue:Value,block:Block ) Override
 		
 		If Not setters Throw New SemantEx( "Value cannot be index assigned" )
 		
@@ -632,7 +640,7 @@ Class OpIndexValue Extends Value
 		Next
 		args2[args.Length]=rvalue
 		
-		Return New EvalStmt( setters.ToValue( inst ).Invoke( args2 ) )
+		Return New EvalStmt( pnode,setters.ToValue( inst ).Invoke( args2 ) )
 	End
 	
 	'should never be called
@@ -665,6 +673,28 @@ Class ClassScope Extends Scope
 		Next
 	End
 	
+	Property Name:String() Override
+
+		Local args:=""
+		For Local arg:=Eachin ctype.types
+			args+=","+arg.Name
+		Next
+		If args args="<"+args.Slice( 1 )+">"
+		
+		Return outer.Name+"."+ctype.cdecl.ident+args
+	End
+	
+	Property TypeId:String() Override
+	
+		Local args:=""
+		For Local arg:=Eachin ctype.types
+			args+=arg.TypeId
+		Next
+		If args args="_1"+args+"E"
+		
+		Return "T"+outer.TypeId+"_"+ctype.cdecl.ident+args+"E"
+	End
+	
 	Property IsGeneric:Bool() Override
 
 		If ctype.IsGeneric Return True

+ 8 - 0
src/mx2new/enum.monkey2

@@ -30,6 +30,14 @@ Class EnumType Extends Type
 		Return edecl.ident
 	End
 	
+	Property Name:String() Override
+		Return scope.Name+"."+edecl.ident
+	End
+	
+	Property TypeId:String() Override
+		Return scope.TypeId+"_"+edecl.ident
+	End
+	
 	Method OnSemant:SNode() Override
 	
 		If edecl.superType

+ 19 - 4
src/mx2new/func.monkey2

@@ -75,8 +75,16 @@ Class FuncValue Extends Value
 		If fdecl.kind="lambda" captures=New Stack<VarValue>
 	End
 	
-	Property IsGeneric:Bool()
+	Property Name:String()
+		Local name:=scope.Name
+		If name name+="."+fdecl.ident Else name=fdecl.ident
+		Local kind:=fdecl.kind.Capitalize()
+		If fdecl.IsOperator kind="Operator"
+'		Return kind+" "+name+":"+ftype.Name
+		Return name+":"+ftype.Name
+	End
 	
+	Property IsGeneric:Bool()
 		If Not ftype SemantError( "FuncValue.IsGeneric()" )
 		
 		Return ftype.IsGeneric
@@ -451,10 +459,17 @@ Class FuncListType Extends Type
 		Return flist.ident+str+"(...)"
 	End
 	
-	Method ToValue:Value( instance:Value ) Override
+	Property Name:String() Override
+		Return "{FuncListType}"
+	End
 	
-		SemantError( "FuncListValue.ToValue()" )
-		
+	Property TypeId:String() Override
+		SemantError( "FuncListType.TypeId()" )
+		Return ""
+	End
+	
+	Method ToValue:Value( instance:Value ) Override
+		SemantError( "FuncListType.ToValue()" )
 		Return Null
 	End
 	

+ 0 - 68
src/mx2new/monkey.monkey2x

@@ -1,68 +0,0 @@
-
-Namespace monkey
-
-Extern
-
-Struct @Void="void"
-End
-
-Struct @Bool="bbBool"
-End
-
-Struct @Byte="bbByte"
-End
-
-Struct @UByte="bbUByte"
-End
-
-Struct @Short="bbShort"
-End
-
-Struct @UShort="bbUShort"
-End
-
-Struct @Int="bbInt"
-End
-
-Struct @UInt="bbUInt"
-End
-
-Struct @Long="bbLong"
-End
-
-Struct @ULong="bbULong"
-End
-
-Struct @Float="bbFloat"
-End
-
-Struct @Double="bbDouble"
-End
-
-Struct @String="bbString"
-
-	Property Length:Int()="length"
-	
-	Method Split:Int[]( separator:String )="split"
-	
-	Method Slice:String( start:Int )="slice"
-	
-	method Slice:String( start:Int,term:Int )="slice"
-	
-End
-
-Struct @Array<T> ="bbArray"
-
-	Property Length:Int()
-	
-	Method Slice:T[]( start:Int )
-	
-	Method Slice:T[]( start:Int,term:Int )
-	
-End
-
-Class @Object="bbObject"
-
-	Property TypeName:String()
-
-End

+ 7 - 3
src/mx2new/mx2cc.monkey2

@@ -14,9 +14,13 @@ Using libc
 
 Global StartDir:String
 
-'Const TestArgs:="mx2cc makemods -clean -verbose -config=release monkey libc miniz stb std hoedown"
+'Const TestArgs:="mx2cc makemods -clean -verbose -config=debug"
 
-Const TestArgs:="mx2cc makeapp -clean -verbose -target=desktop -config=release src/mx2new/mx2cc.monkey2"
+Const TestArgs:="mx2cc makeapp -clean -verbose -target=desktop -config=debug src/mx2new/test.monkey2"
+
+'Const TestArgs:="mx2cc makeapp -verbose -target=desktop -config=release src/mx2new/mx2cc.monkey2"
+
+'Const TestArgs:="mx2cc makemods"
 
 Function Main()
 
@@ -41,7 +45,7 @@ Function Main()
 	If args.Length<2
 
 		Print "Usage: mx2cc makeapp|makemods|makedocs [-run] [-clean] [-verbose] [-target=desktop|emscripten] [-config=debug|release] source|modules..."
-		
+
 #If __CONFIG__="release"
 		exit_(0)
 #Endif

+ 26 - 0
src/mx2new/namespace.monkey2

@@ -15,6 +15,14 @@ Class NamespaceType Extends Type
 		Return ident
 	End
 	
+	Property Name:String() Override
+		Return scope.Name
+	End
+	
+	Property TypeId:String() Override
+		Return scope.TypeId
+	End
+	
 	'***** Type overrides *****
 
 	Method FindNode:SNode( ident:String ) Override
@@ -44,6 +52,24 @@ Class NamespaceScope Extends Scope
 		Self.ntype=ntype
 	End
 	
+	Property Name:String() Override
+		If Not ntype Return ""
+		If outer
+			Local name:=outer.Name
+			If name Return name+"."+ntype.ident
+		Endif
+		Return ntype.ident
+	End
+	
+	Property TypeId:String() Override
+		If Not ntype Return ""
+		If outer
+			Local id:=outer.TypeId
+			If id Return id+"_"+ntype.ident
+		Endif
+		Return ntype.ident
+	End
+		
 	Method ToString:String() Override
 	
 		If Not ntype Return ""

+ 2 - 2
src/mx2new/parser.monkey2

@@ -937,7 +937,7 @@ Class Parser
 		
 		Local stmts:=ParseStmts( True )
 		
-		Local catches:=New Stack<CatchStmtExpr>
+		Local catches:=New Stack<CatchExpr>
 		
 		While Toke="catch"
 		
@@ -962,7 +962,7 @@ Class Parser
 			
 			Local stmts:=ParseStmts( True )
 			
-			catches.Push( New CatchStmtExpr( varIdent,varType,stmts ) )
+			catches.Push( New CatchExpr( varIdent,varType,stmts ) )
 		Wend
 		
 		Try

+ 2 - 2
src/mx2new/property.monkey2

@@ -102,7 +102,7 @@ Class PropertyValue Extends Value
 	End
 	#end
 	
-	Method Assign:Stmt( op:String,rvalue:Value,block:Block ) Override
+	Method Assign:Stmt( pnode:PNode,op:String,rvalue:Value,block:Block ) Override
 	
 		Local inst:=instance
 		
@@ -135,7 +135,7 @@ Class PropertyValue Extends Value
 		args[0]=rvalue
 		Local invoke:=plist.setFunc.ToValue( inst ).Invoke( args )
 		
-		Return New EvalStmt( invoke )
+		Return New EvalStmt( pnode,invoke )
 	End
 
 	'should never be called?

+ 12 - 4
src/mx2new/scope.monkey2

@@ -18,10 +18,18 @@ Class Scope
 		If outer outer.inner.Push( Self )
 	End
 	
-	Method ToString:String() Virtual
+	Property Name:String() Virtual
+		If outer Return outer.Name
+		Return ""
+	End
+	
+	Property TypeId:String() Virtual
+		If outer Return outer.Name
+		Return ""
+	End
 	
+	Method ToString:String() Virtual
 		If outer Return outer.ToString()
-		
 		Return ""
 	End
 	
@@ -358,7 +366,7 @@ Class Block Extends Scope
 
 		Local varValue:=New VarValue( "local",ident,init,Self )
 		
-		stmts.Push( New VarDeclStmt( varValue ) )
+		stmts.Push( New VarDeclStmt( Null,varValue ) )
 
 		Return varValue
 	End
@@ -367,7 +375,7 @@ Class Block Extends Scope
 
 		Local varValue:=New VarValue( "local",ident,init,Self )
 		
-		stmts.Push( New VarDeclStmt( varValue ) )
+		stmts.Push( New VarDeclStmt( Null,varValue ) )
 
 		Insert( ident,varValue )
 

+ 41 - 14
src/mx2new/stmt.monkey2

@@ -2,13 +2,21 @@
 Namespace mx2
 
 Class Stmt
-
+	Field pnode:PNode
+	
+	Method New()
+	End
+	
+	Method New( pnode:PNode )
+		Self.pnode=pnode
+	End
 End
 
 Class PrintStmt Extends Stmt
 	Field value:Value
 	
-	Method New( value:Value )
+	Method New( pnode:PNode,value:Value )
+		Super.New( pnode )
 		Self.value=value
 	End
 	
@@ -18,7 +26,8 @@ Class ReturnStmt Extends Stmt
 
 	Field value:Value
 	
-	Method New( value:Value )
+	Method New( pnode:PNode,value:Value )
+		Super.New( pnode )
 		Self.value=value
 	End
 End
@@ -27,7 +36,8 @@ Class VarDeclStmt Extends Stmt
 
 	Field varValue:VarValue
 	
-	Method New( varValue:VarValue )
+	Method New( pnode:PNode,varValue:VarValue )
+		Super.New( pnode )
 		Self.varValue=varValue
 	End
 
@@ -39,7 +49,8 @@ Class AssignStmt Extends Stmt
 	Field lhs:Value
 	Field rhs:Value
 	
-	Method New( op:String,lhs:Value,rhs:Value )
+	Method New( pnode:PNode,op:String,lhs:Value,rhs:Value )
+		Super.New( pnode )
 		Self.op=op
 		Self.lhs=lhs
 		Self.rhs=rhs
@@ -50,7 +61,8 @@ Class EvalStmt Extends Stmt
 
 	Field value:Value
 	
-	Method New( value:Value )
+	Method New( pnode:PNode,value:Value )
+		Super.New( pnode )
 		Self.value=value
 	End
 End
@@ -60,7 +72,8 @@ Class IfStmt Extends Stmt
 	Field block:Block
 	Field succ:IfStmt
 	
-	Method New( cond:Value,block:Block )
+	Method New( pnode:PNode,cond:Value,block:Block )
+		Super.New( pnode )
 		Self.cond=cond
 		Self.block=block
 	End
@@ -71,7 +84,8 @@ Class WhileStmt Extends Stmt
 	Field cond:Value
 	Field block:Block
 	
-	Method New( cond:Value,block:Block )
+	Method New( pnode:PNode,cond:Value,block:Block )
+		Super.New( pnode )
 		Self.cond=cond
 		Self.block=block
 	End
@@ -82,14 +96,15 @@ Class RepeatStmt Extends Stmt
 	Field cond:Value
 	Field block:Block
 	
-	Method New( cond:Value,block:Block )
+	Method New( pnode:PNode,cond:Value,block:Block )
+		Super.New( pnode )
 		Self.cond=cond
 		Self.block=block
 	End
 	
 End
 
-Class CaseStmt
+Class CaseStmt Extends Stmt
 	Field values:Value[]
 	Field block:Block
 	
@@ -103,7 +118,8 @@ Class SelectStmt Extends Stmt
 	Field value:Value
 	Field cases:CaseStmt[]
 	
-	Method New( value:Value,cases:CaseStmt[] )
+	Method New( pnode:PNode,value:Value,cases:CaseStmt[] )
+		Super.New( pnode )
 		Self.value=value
 		Self.cases=cases
 	End
@@ -116,7 +132,8 @@ Class ForStmt Extends Stmt
 	Field incr:Stmt
 	Field block:Block
 	
-	Method New( iblock:Block,cond:Value,incr:Stmt,block:Block )
+	Method New( pnode:PNode,iblock:Block,cond:Value,incr:Stmt,block:Block )
+		Super.New( pnode )
 		Self.iblock=iblock
 		Self.cond=cond
 		Self.incr=incr
@@ -140,7 +157,8 @@ Class TryStmt Extends Stmt
 	Field block:Block
 	Field catches:CatchStmt[]
 	
-	Method New( block:Block,catches:CatchStmt[] )
+	Method New( pnode:PNode,block:Block,catches:CatchStmt[] )
+		Super.New( pnode )
 		Self.block=block
 		Self.catches=catches
 	End
@@ -150,15 +168,24 @@ End
 Class ThrowStmt Extends Stmt
 	Field value:Value
 	
-	Method New( value:Value )
+	Method New( pnode:PNode,value:Value )
+		Super.New( pnode )
 		Self.value=value
 	End
 End
 
 Class ContinueStmt Extends Stmt
+
+	Method New( pnode:PNode )
+		Super.New( pnode )
+	End
 End
 
 Class ExitStmt Extends Stmt
+
+	Method New( pnode:PNode )
+		Super.New( pnode )
+	End
 End
 
 '***** StmtVisitor *****

+ 24 - 24
src/mx2new/stmtexpr.monkey2

@@ -87,7 +87,7 @@ Class AssignStmtExpr Extends StmtExpr
 				Local args:=New Value[1]
 				args[0]=rhs
 				Local value:=node.Invoke( args )
-				Return New EvalStmt( value )
+				Return New EvalStmt( Self,value )
 			Endif
 			
 			node=lhs.FindValue( op.Slice( 0,-1 ) )
@@ -102,7 +102,7 @@ Class AssignStmtExpr Extends StmtExpr
 		
 		If Not lhs.IsAssignable Throw New SemantEx( "Value '"+lhs.ToString()+"' is not assignable" )
 		
-		Return lhs.Assign( op,rhs,block )
+		Return lhs.Assign( Self,op,rhs,block )
 	End
 End
 
@@ -127,7 +127,7 @@ Class VarDeclStmtExpr Extends StmtExpr
 		
 		block.Insert( decl.ident,value )
 		
-		Return New VarDeclStmt( value )
+		Return New VarDeclStmt( Self,value )
 	End
 
 End
@@ -149,7 +149,7 @@ Class EvalStmtExpr Extends StmtExpr
 	
 		Local value:=expr.SemantRValue( block )
 		
-		Return New EvalStmt( value )
+		Return New EvalStmt( Self,value )
 	End
 
 End
@@ -221,7 +221,7 @@ Class PrintStmtExpr Extends StmtExpr
 	
 		Local value:=expr.SemantRValue( block,Type.StringType )
 		
-		Return New PrintStmt( value )
+		Return New PrintStmt( Self,value )
 	End
 
 End
@@ -254,7 +254,7 @@ Class ReturnStmtExpr Extends StmtExpr
 				value=expr.SemantRValue( block,rtype )
 			Endif
 			
-			block.Emit( New ReturnStmt( value ) )
+			block.Emit( New ReturnStmt( Self,value ) )
 		
 		Catch ex:SemantEx
 		End
@@ -280,7 +280,7 @@ Class ContinueStmtExpr Extends StmtExpr
 	
 		If Not block.loop Throw New SemantEx( "'Exit' must appear inside a loop" )
 		
-		Return New ContinueStmt
+		Return New ContinueStmt( Self )
 	End
 
 End
@@ -299,7 +299,7 @@ Class ExitStmtExpr Extends StmtExpr
 	
 		If Not block.loop Throw New SemantEx( "'Exit' must appear inside a loop" )
 		
-		Return New ExitStmt
+		Return New ExitStmt( Self )
 	End
 End
 
@@ -351,7 +351,7 @@ Class IfStmtExpr Extends StmtExpr
 			
 			tblock.Semant( expr.stmts )
 			
-			Local curr:=New IfStmt( cond,tblock )
+			Local curr:=New IfStmt( Self,cond,tblock )
 			If prev prev.succ=curr Else head=curr
 			prev=curr
 			
@@ -395,7 +395,7 @@ Class WhileStmtExpr Extends StmtExpr
 		
 		iblock.Semant( stmts )
 		
-		return New WhileStmt( cond,iblock )
+		return New WhileStmt( Self,cond,iblock )
 	End
 End
 
@@ -434,7 +434,7 @@ Class RepeatStmtExpr Extends StmtExpr
 		
 		iblock.Semant( stmts )
 		
-		Return New RepeatStmt( cond,iblock )
+		Return New RepeatStmt( Self,cond,iblock )
 	End
 
 End
@@ -501,7 +501,7 @@ Class SelectStmtExpr Extends StmtExpr
 		
 		Next
 		
-		Return New SelectStmt( value,cases.ToArray() )
+		Return New SelectStmt( Self,value,cases.ToArray() )
 	End
 	
 End
@@ -585,7 +585,7 @@ Class ForStmtExpr Extends StmtExpr
 			cond=New BinaryopValue( Type.BoolType,"<",iter,len )
 			
 			'iter+=1			
-			incr=iter.Assign( "+=",LiteralValue.IntValue( 1 ),iblock )
+			incr=iter.Assign( Null,"+=",LiteralValue.IntValue( 1 ),iblock )
 			
 			If atype
 				Local indices:=New Value[1]
@@ -634,7 +634,7 @@ Class ForStmtExpr Extends StmtExpr
 				Local bump:=iter.FindValue( "Bump" )
 				If Not bump Throw New SemantEx( "Iterator has no 'Bump' method" )
 				bump=bump.Invoke( Null )
-				incr=New EvalStmt( bump )
+				incr=New EvalStmt( Null,bump )
 			Endif
 			
 #rem
@@ -657,12 +657,12 @@ Class ForStmtExpr Extends StmtExpr
 		Else
 			Local iter:=varExpr.Semant( block ).RemoveSideEffects( block )
 			If Not iter.IsAssignable Throw New SemantEx( "For loop index '"+iter.ToString()+"' is not assignable" )
-			block.Emit( iter.Assign( "=",curr,block ) )
+			block.Emit( iter.Assign( Null,"=",curr,block ) )
 		Endif
 		
 		block.Semant( stmts )
 		
-		Return New ForStmt( iblock,cond,incr,block )
+		Return New ForStmt( Self,iblock,cond,incr,block )
 	End
 	
 	Method OnSemant:Stmt( block:Block ) Override
@@ -685,7 +685,7 @@ Class ForStmtExpr Extends StmtExpr
 		Else
 			iter=varExpr.Semant( iblock ).RemoveSideEffects( iblock )
 			If Not iter.IsAssignable Throw New SemantEx( "For loop index '"+iter.ToString()+"' is not assignable" )
-			iblock.Emit( iter.Assign( "=",init,iblock ) )
+			iblock.Emit( iter.Assign( Null,"=",init,iblock ) )
 		Endif
 		
 		Local iterExpr:=New ValueExpr( iter,srcpos,endpos )
@@ -703,12 +703,12 @@ Class ForStmtExpr Extends StmtExpr
 		
 		block.Semant( stmts )
 		
-		Return New ForStmt( iblock,cond,incr,block )
+		Return New ForStmt( Self,iblock,cond,incr,block )
 	End
 	
 End
 
-Class CatchStmtExpr
+Class CatchExpr
 
 	Field varIdent:String
 	Field varType:TypeExpr
@@ -725,9 +725,9 @@ End
 Class TryStmtExpr Extends StmtExpr
 
 	Field stmts:StmtExpr[]
-	Field catches:CatchStmtExpr[]
+	Field catches:CatchExpr[]
 	
-	Method New( stmts:StmtExpr[],catches:CatchStmtExpr[],srcpos:Int,endpos:Int )
+	Method New( stmts:StmtExpr[],catches:CatchExpr[],srcpos:Int,endpos:Int )
 		Super.New( srcpos,endpos )
 		Self.stmts=stmts
 		Self.catches=catches
@@ -759,7 +759,7 @@ Class TryStmtExpr Extends StmtExpr
 			catches.Push( New CatchStmt( vvar,iblock ) )
 		Next
 		
-		Return New TryStmt( iblock,catches.ToArray() )
+		Return New TryStmt( Self,iblock,catches.ToArray() )
 	End
 End
 
@@ -776,11 +776,11 @@ Class ThrowStmtExpr Extends StmtExpr
 
 		Try
 			If expr	
-				block.Emit( New ThrowStmt( expr.SemantRValue( block ) ) )
+				block.Emit( New ThrowStmt( Self,expr.SemantRValue( block ) ) )
 			Else If Not block.inex
 				Throw New SemantEx( "Exceptions can only be rethrown inside 'Catch' blocks" )
 			Else
-				block.Emit( New ThrowStmt( Null ) )
+				block.Emit( New ThrowStmt( Self,Null ) )
 			Endif
 			
 		Catch ex:SemantEx

+ 50 - 0
src/mx2new/test.monkey2

@@ -0,0 +1,50 @@
+
+Namespace test
+
+#Import "<std.monkey2>"
+
+Using std
+
+Class C
+
+	Method Update() Virtual
+	
+		Print "C.Update()!"
+		
+		Assert( False )
+	End
+
+End
+
+Function Test()
+
+	Print "Test!"
+	
+	Local c:C
+	
+	c.Update()
+	
+	New C().Update()
+
+End
+
+Function Main()
+
+	Local p:Int[]
+	
+	Local f:Float
+
+	For Local i:=0 Until 10
+		Local t:=String( i*2 )
+		debug.Stop()
+	Next
+
+	Print "Hello World!"
+	
+	Local t:=New Int[10]
+	
+	t[9]=0
+
+	Test()
+
+End

+ 0 - 14
src/mx2new/test.monkey2x

@@ -1,14 +0,0 @@
-
-Namespace test
-
-#Import "<std.monkey2>"
-
-Using std.filesystem
-
-Function Main()
-
-	Print ExtractDir( "D:/test/" )
-	
-	Print ExtractDir( "D:/" )
-
-End

+ 0 - 0
src/mx2new/test2.monkey2x → src/mx2new/test2.monkey2


+ 29 - 30
src/mx2new/translator.monkey2

@@ -33,40 +33,36 @@ Function HasGCMembers:Bool( scope:Scope )
 	Return False
 End
 	
-'Visitor that looks for assigned params
+'Visitor that looks for gc params on LHS of an assignment.
 '
-Class AssignedParamsVisitor Extends StmtVisitor
+Class AssignedGCParamsVisitor Extends StmtVisitor
 
-	Field params:=New StringMap<VarValue>
+	Field gcparams:=New StringMap<VarValue>
 	
 	Method Visit( stmt:AssignStmt ) Override
 		Local vvar:=Cast<VarValue>( stmt.lhs )
-		If vvar And vvar.vdecl.kind="param" params[vvar.vdecl.ident]=vvar
+		If vvar And vvar.vdecl.kind="param" And IsGCType( vvar.type ) gcparams[vvar.vdecl.ident]=vvar
 	End
 
 End
 
 Class Translator
 
-	Method Translate( fdecl:FileDecl ) Virtual
-	End
-	
-	Method Trans:String( value:Value ) Virtual
-		Return "?"
-	End
+	Field debug:Bool
 	
-	Method Trans:String( type:Type ) Virtual
-		Return  "?"
+	Method New()
+		Local builder:=Builder.instance
+		Self.debug=builder.opts.config="debug"
 	End
 	
-	Method VarProto:String( vvar:VarValue ) Virtual
-		Return "?"
-	End
+	Method Trans:String( value:Value ) Abstract
 	
-	Method FuncProto:String( func:FuncValue ) Virtual
-		Return "?"
-	End
+	Method TransType:String( type:Type ) Abstract
+
+	Method VarProto:String( vvar:VarValue ) Abstract
 	
+	Method FuncProto:String( func:FuncValue ) Abstract
+
 	'***** Emit *****
 	
 	Field _buf:=New StringStack
@@ -145,18 +141,21 @@ Class Translator
 	End
 	
 	Field _gcframe:GCFrame
-
-	Method BeginGCFrame( block:Block=Null )
+	
+	Method BeginGCFrame()
 
 		_gcframe=New GCFrame( _gcframe,InsertPos )
+	End
+	
+	Method BeginGCFrame( func:FuncValue )
+	
+		BeginGCFrame()
 		
-		If _gcframe.outer Or Not block Return
-		
-		Local visitor:=New AssignedParamsVisitor
-		visitor.Visit( block )
+		Local visitor:=New AssignedGCParamsVisitor
+		visitor.Visit( func.block )
 		
-		For Local it:=Eachin visitor.params
-			If IsGCType( it.Value.type ) InsertGCTmp( it.Value )
+		For Local it:=Eachin visitor.gcparams
+			InsertGCTmp( it.Value )
 		Next
 		
 	End
@@ -173,7 +172,7 @@ Class Translator
 			
 			For Local varval:=Eachin _gcframe.vars.Values
 
-				Local varty:=Trans( varval.type )
+				Local varty:=TransType( varval.type )
 				Local varid:=VarName( varval )
 			
 				Emit( varty+" "+varid+"{};" )
@@ -187,7 +186,7 @@ Class Translator
 			Next
 			
 			For Local tmp:=Eachin _gcframe.tmps
-				Emit( Trans( tmp.type )+" "+tmp.ident+"{};" )
+				Emit( TransType( tmp.type )+" "+tmp.ident+"{};" )
 			Next
 			
 			If ctorArgs
@@ -443,12 +442,12 @@ Class Translator
 	
 	Method CFuncType:String( type:FuncType )
 	
-		Local retType:=Trans( type.retType )
+		Local retType:=TransType( type.retType )
 		
 		Local argTypes:=""
 		For Local i:=0 Until type.argTypes.Length
 			If argTypes argTypes+=","
-			argTypes+=Trans( type.argTypes[i] )
+			argTypes+=TransType( type.argTypes[i] )
 		Next
 		
 		Return retType+"("+argTypes+")"

+ 136 - 104
src/mx2new/translator_cpp.monkey2

@@ -5,7 +5,7 @@ Class Translator_CPP Extends Translator
 
 	Field _lambdaId:Int
 	
-	Method Translate( fdecl:FileDecl ) Override
+	Method Translate( fdecl:FileDecl ) 'Override
 	
 		_incs[fdecl.ident]=fdecl
 
@@ -123,7 +123,7 @@ Class Translator_CPP Extends Translator
 		Local atype:=Cast<ArrayType>( type )
 		If atype Return "bbGCVar<"+ArrayName( atype )+">"
 		
-		Return Trans( type )
+		Return TransType( type )
 	End
 	
 	Method VarProto:String( vvar:VarValue ) Override
@@ -143,14 +143,14 @@ Class Translator_CPP Extends Translator
 		Local ctype:=func.scope.FindClass()
 	
 		Local retType:=""
-		If Not func.IsCtor retType=Trans( ftype.retType )+" "
+		If Not func.IsCtor retType=TransType( ftype.retType )+" "
 
 		Local params:=""
-		If func.IsExtension params=Trans( ctype )+" l_self"
+		If func.IsExtension params=TransType( ctype )+" l_self"
 
 		For Local p:=Eachin func.params
 			If params params+=","
-			params+=Trans( p.type )+" "+VarName( p )
+			params+=TransType( p.type )+" "+VarName( p )
 		Next
 		
 		Local ident:=FuncName( func )
@@ -566,8 +566,8 @@ Class Translator_CPP Extends Translator
 				Emit( "void mx2_"+mod2.ident+"_main();mx2_"+mod2.ident+"_main();" )
 			Next
 		Endif
-	
-		Emit( func.block )
+		
+		EmitBlock( func )
 		
 		Emit( "}" )
 	End
@@ -584,7 +584,7 @@ Class Translator_CPP Extends Translator
 		Local ctorArgs:="",ctorInits:="",ctorVals:=""
 		
 		For Local vvar:=Eachin func.captures
-			Local varty:=Trans( vvar.type )
+			Local varty:=TransType( vvar.type )
 			Local varid:=VarName( vvar )
 			Emit( varty+" "+varid+";" )
 			ctorArgs+=","+varty+" "+varid
@@ -598,17 +598,17 @@ Class Translator_CPP Extends Translator
 			Emit( "}" )
 		Endif
 		
-		Local retType:=Trans( func.ftype.retType )
+		Local retType:=TransType( func.ftype.retType )
 
 		Local params:=""
 		For Local p:=Eachin func.params
 			If params params+=","
-			params+=Trans( p.type )+" "+VarName( p )
+			params+=TransType( p.type )+" "+VarName( p )
 		Next
 		
 		Emit( retType+" invoke("+params+"){" )
 		
-		Emit( func.block )
+		EmitBlock( func )
 		
 		Emit( "}" )
 
@@ -628,115 +628,151 @@ Class Translator_CPP Extends Translator
 	
 	'***** Block *****
 	
-	Method Emit( block:Block,gc:Bool=True )
+	Method BeginBlock()
+
+		BeginGCFrame()
+
+		If debug Emit( "bbDBBlock db_blk;" )
+	End
 	
-		If gc BeginGCFrame( block )
-		
+	Method EmitStmts( block:Block )
+
 		For Local stmt:=Eachin block.stmts
-		
-			Emit( stmt )
+			EmitStmt( stmt )
 			FreeGCTmps()
-			
 		Next
+
+	End
+	
+	Method EndBlock()
+	
+		EndGCFrame()
+	End
+	
+	Method EmitBlock( block:Block )
+	
+		BeginBlock()
 		
-		If gc EndGCFrame()
+		EmitStmts( block )
+		
+		EndBlock()
+	End
+	
+	Method EmitBlock( func:FuncValue )
+	
+		BeginGCFrame( func )
+		
+		If debug Emit( "bbDBFrame db_f{~q"+func.Name+"~q,~q"+func.pnode.srcfile.path+"~q};" )
+		
+		EmitStmts( func.block )
+	
+		EndGCFrame()
 	End
 	
 	'***** Stmt *****
 	
-	Method Emit( stmt:Stmt )
+	Method EmitStmt( stmt:Stmt )
 	
 		If Not stmt Return
-	
+		
+		If debug And stmt.pnode Emit( "bbDBStmt("+stmt.pnode.srcpos+");" )
+		
 		Local exitStmt:=Cast<ExitStmt>( stmt )
-		If exitStmt Emit( exitStmt ) ; Return
+		If exitStmt EmitStmt( exitStmt ) ; Return
 		
 		Local continueStmt:=Cast<ContinueStmt>( stmt )
-		If continueStmt Emit( continueStmt ) ; Return
+		If continueStmt EmitStmt( continueStmt ) ; Return
 		
 		Local returnStmt:=Cast<ReturnStmt>( stmt )
-		If returnStmt Emit( returnStmt ) ; Return
+		If returnStmt EmitStmt( returnStmt ) ; Return
 		
 		Local varDeclStmt:=Cast<VarDeclStmt>( stmt )
-		If varDeclStmt Emit( varDeclStmt ) ; Return
+		If varDeclStmt EmitStmt( varDeclStmt ) ; Return
 		
 		Local assignStmt:=Cast<AssignStmt>( stmt )
-		If assignStmt Emit( assignStmt ) ; Return
+		If assignStmt EmitStmt( assignStmt ) ; Return
 		
 		Local evalStmt:=Cast<EvalStmt>( stmt )
-		If evalStmt Emit( evalStmt ) ; Return
+		If evalStmt EmitStmt( evalStmt ) ; Return
 		
 		Local ifStmt:=Cast<IfStmt>( stmt )
-		If ifStmt Emit( ifStmt ) ; Return
+		If ifStmt EmitStmt( ifStmt ) ; Return
 		
 		Local whileStmt:=Cast<WhileStmt>( stmt )
-		If whileStmt Emit( whileStmt ) ; Return
+		If whileStmt EmitStmt( whileStmt ) ; Return
 		
 		Local repeatStmt:=Cast<RepeatStmt>( stmt )
-		If repeatStmt Emit( repeatStmt ) ; Return
+		If repeatStmt EmitStmt( repeatStmt ) ; Return
 		
 		Local selectStmt:=Cast<SelectStmt>( stmt )
-		If selectStmt Emit( selectStmt ) ; Return
+		If selectStmt EmitStmt( selectStmt ) ; Return
 		
 		Local forStmt:=Cast<ForStmt>( stmt )
-		If forStmt Emit( forStmt ) ; Return
+		If forStmt EmitStmt( forStmt ) ; Return
 		
 		Local tryStmt:=Cast<TryStmt>( stmt )
-		If tryStmt Emit( tryStmt ) ; Return
+		If tryStmt EmitStmt( tryStmt ) ; Return
 		
 		Local throwStmt:=Cast<ThrowStmt>( stmt )
-		If throwStmt Emit( throwStmt ) ; Return
+		If throwStmt EmitStmt( throwStmt ) ; Return
 		
 		Local printStmt:=Cast<PrintStmt>( stmt )
-		If printStmt Emit( printStmt ) ; Return
+		If printStmt EmitStmt( printStmt ) ; Return
 		
-		Throw New TransEx( "Translator_CPP.Emit() Stmt '"+String.FromCString( stmt.typeName() )+"' not recognized" )
+		Throw New TransEx( "Translator_CPP.EmitStmt() Stmt '"+String.FromCString( stmt.typeName() )+"' not recognized" )
 	End
 	
-	Method Emit( stmt:PrintStmt )
+	Method EmitStmt( stmt:PrintStmt )
 	
 		Emit( "puts("+Trans( stmt.value )+".c_str());fflush( stdout );" )
 	End
 	
-	Method Emit( stmt:ExitStmt )
+	Method EmitStmt( stmt:ExitStmt )
 	
 		Emit( "break;" )
 	End
 	
-	Method Emit( stmt:ContinueStmt )
+	Method EmitStmt( stmt:ContinueStmt )
 	
 		Emit( "continue;" )
 	End
 	
-	Method Emit( stmt:ReturnStmt )
+	Method EmitStmt( stmt:ReturnStmt )
 	
 		If Not stmt.value Emit( "return;" ) ; Return
 		
 		Emit( "return "+Trans( stmt.value )+";" )
 	End
 	
-	Method Emit( stmt:VarDeclStmt )
+	Method EmitStmt( stmt:VarDeclStmt )
 		
 		Local vvar:=stmt.varValue
 		Local vdecl:=vvar.vdecl
 		
 		Refs( vvar.type )
 		
+		Local dbvar:=""
+		
 		If vdecl.kind="local" And IsGCType( vvar.type )
 		
-			Local t:=InsertGCTmp( vvar )
-			If vvar.init Emit( t+"="+Trans( vvar.init )+";" )
-			Return
+			dbvar=InsertGCTmp( vvar )
 
-		Endif
+			If vvar.init Emit( dbvar+"="+Trans( vvar.init )+";" )
+		Else
 
-		Local init:="{}"
-		If vvar.init init="="+Trans( vvar.init )
+			dbvar=VarName( vvar )
+
+			Local init:="{}"
+			If vvar.init init="="+Trans( vvar.init )
+			
+			Emit( TransType( vvar.type )+" "+dbvar+init+";" )
+		Endif
 		
-		Emit( Trans( vvar.type )+" "+VarName( vvar )+init+";" )
+		If debug And dbvar Emit( "bbDBLocal(~q"+vvar.vdecl.ident+":"+vvar.type.TypeId+"~q,&"+dbvar+");" )
+
 	End
 	
-	Method Emit( stmt:AssignStmt )
+	Method EmitStmt( stmt:AssignStmt )
 	
 		Local op:=stmt.op
 		Select op
@@ -765,15 +801,15 @@ Class Translator_CPP Extends Translator
 		Emit( lhs+op+rhs+";" )
 	End
 
-	Method Emit( stmt:EvalStmt )
+	Method EmitStmt( stmt:EvalStmt )
 		Emit( Trans( stmt.value )+";" )
 	End
 	
-	Method Emit( stmt:IfStmt )
+	Method EmitStmt( stmt:IfStmt )
 	
 		Emit( "if("+Trans( stmt.cond )+"){" )
 		
-		Emit( stmt.block )
+		EmitBlock( stmt.block )
 		
 		While stmt.succ
 			stmt=stmt.succ
@@ -782,31 +818,31 @@ Class Translator_CPP Extends Translator
 			Else
 				Emit( "}else{" )
 			Endif
-			Emit( stmt.block )
+			EmitBlock( stmt.block )
 		Wend
 
 		Emit( "}" )
 	End
 	
-	Method Emit( stmt:WhileStmt )
+	Method EmitStmt( stmt:WhileStmt )
 	
 		Emit( "while("+Trans( stmt.cond )+"){" )
 		
-		Emit( stmt.block )
+		EmitBlock( stmt.block )
 		
 		Emit( "}" )
 	End
 	
-	Method Emit( stmt:RepeatStmt )
+	Method EmitStmt( stmt:RepeatStmt )
 	
 		If stmt.cond Emit( "do{" ) Else Emit( "for(;;){" )
 		
-		Emit( stmt.block )
+		EmitBlock( stmt.block )
 		
 		If stmt.cond Emit( "}while(!("+Trans( stmt.cond )+"));" ) Else Emit( "}" )
 	End
 	
-	Method Emit( stmt:SelectStmt )
+	Method EmitStmt( stmt:SelectStmt )
 	
 		Local tvalue:=Trans( stmt.value ),head:=True
 		
@@ -826,25 +862,25 @@ Class Translator_CPP Extends Translator
 			Endif
 			head=False
 			
-			Emit( cstmt.block )
+			EmitBlock( cstmt.block )
 		Next
 		
 		Emit( "}" )
 	End
 	
-	Method Emit( stmt:ForStmt )
+	Method EmitStmt( stmt:ForStmt )
 	
 		Emit( "{" )
 		
-		BeginGCFrame()
-		
-		Emit( stmt.iblock,False )
+		BeginBlock()
+
+		EmitStmts( stmt.iblock )
 		
 		Local cond:=Trans( stmt.cond )
 		
 		If stmt.incr
 
-			Emit( stmt.incr )
+			EmitStmt( stmt.incr )
 			Local incr:=_buf.Pop().Trim().Slice( 0,-1 )
 
 			Emit( "for(;"+cond+";"+incr+"){" )
@@ -852,20 +888,20 @@ Class Translator_CPP Extends Translator
 			Emit( "while("+cond+"){" )
 		Endif
 		
-		Emit( stmt.block,False )
+		EmitBlock( stmt.block )
 		
 		Emit( "}" )
-		
-		EndGCFrame()
+
+		EndBlock()		
 		
 		Emit( "}" )
 	End
 	
-	Method Emit( stmt:TryStmt )
+	Method EmitStmt( stmt:TryStmt )
 	
 		Emit( "try{" )
 
-		Emit( stmt.block )
+		EmitBlock( stmt.block )
 		
 		For Local cstmt:=Eachin stmt.catches
 		
@@ -875,21 +911,22 @@ Class Translator_CPP Extends Translator
 			
 			If IsGCType( vvar.type )
 			
-				Emit( "}catch("+Trans( vvar.type )+" ex){" )
+				Emit( "}catch("+TransType( vvar.type )+" ex){" )
 				
-				BeginGCFrame()
+				BeginBlock()
 				
-				Emit( InsertGCTmp( vvar )+"=ex;" )
+				Local tmp:=InsertGCTmp( vvar )
 				
-				Emit( cstmt.block,False )
+				Emit( tmp+"=ex;" )
 				
-				EndGCFrame()
+				EmitStmts( cstmt.block )
 				
+				EndBlock()
 			Else
 			
 				Emit( "}catch("+VarProto( vvar )+"){" )
 				
-				Emit( cstmt.block )
+				EmitBlock( cstmt.block )
 
 			Endif
 			
@@ -898,7 +935,7 @@ Class Translator_CPP Extends Translator
 		Emit( "}" )
 	End
 	
-	Method Emit( stmt:ThrowStmt )
+	Method EmitStmt( stmt:ThrowStmt )
 	
 		Emit( "throw "+Trans( stmt.value )+";" )
 	End
@@ -974,9 +1011,9 @@ Class Translator_CPP Extends Translator
 		
 		Local t:="("+Trans( value.value )+")"
 		
-		If IsValue( value.type ) Return Trans( value.type )+t
+		If IsValue( value.type ) Return TransType( value.type )+t
 
-		Return "(("+Trans( value.type )+")"+t+")"
+		Return "(("+TransType( value.type )+")"+t+")"
 	End
 	
 	Method Trans:String( value:ExplicitCastValue )
@@ -989,9 +1026,9 @@ Class Translator_CPP Extends Translator
 		
 		Local t:="("+Trans( value.value )+")"
 		
-		If IsValue( value.type ) Return Trans( value.type )+t
+		If IsValue( value.type ) Return TransType( value.type )+t
 
-		Return "(("+Trans( value.type )+")"+t+")"
+		Return "(("+TransType( value.type )+")"+t+")"
 	End
 	
 	Method TransNull:String( type:Type )
@@ -1010,7 +1047,7 @@ Class Translator_CPP Extends Translator
 			Return "0"
 		Endif
 		
-		If IsValue( type ) Return Trans( type )+"{}"
+		If IsValue( type ) Return TransType( type )+"{}"
 		
 		Return "nullptr"
 	End
@@ -1029,7 +1066,7 @@ Class Translator_CPP Extends Translator
 			Return "BB_T("+EnquoteCppString( value.value )+")"
 		End
 		
-		If value.value="0" Return Trans( value.type )+"(0)"
+		If value.value="0" Return TransType( value.type )+"(0)"
 		
 		Return value.value
 	End
@@ -1220,13 +1257,7 @@ Class Translator_CPP Extends Translator
 	
 	Method IsVolatile:Bool( arg:Value )
 	
-		If Not IsGCType( arg.type ) Return False
-		
-'		If _gcframe Return True
-		
-		If arg.HasSideEffects Return True
-		
-		Return False
+		Return IsGCType( arg.type ) And arg.HasSideEffects
 	End
 		
 	Method TransArgs:String( args:Value[] )
@@ -1248,65 +1279,66 @@ Class Translator_CPP Extends Translator
 	
 	'***** Type *****
 	
-	Method Trans:String( type:Type ) Override
+	Method TransType:String( type:Type ) Override
 	
 		If type=Type.VoidType Return "void"
 	
 		Local classType:=Cast<ClassType>( type )
-		If classType Return Trans( classType )
+		If classType Return TransType( classType )
 		
 		Local enumType:=Cast<EnumType>( type )
-		If enumType Return Trans( enumType )
+		If enumType Return TransType( enumType )
 	
 		Local primType:=Cast<PrimType>( type )
-		If primType Return Trans( primType )
+		If primType Return TransType( primType )
 		
 		Local funcType:=Cast<FuncType>( type )
-		If funcType Return Trans( funcType )
+		If funcType Return TransType( funcType )
 		
 		Local arrayType:=Cast<ArrayType>( type )
-		If arrayType Return Trans( arrayType )
+		If arrayType Return TransType( arrayType )
 		
 		Local pointerType:=Cast<PointerType>( type )
-		If pointerType Return Trans( pointerType )
+		If pointerType Return TransType( pointerType )
 		
 		Local genArgType:=Cast<GenArgType>( type )
-		If genArgType Return Trans( genArgType )
+		If genArgType Return TransType( genArgType )
 		
 		Throw New TransEx( "Translator_CPP.Trans() Type '"+String.FromCString( type.typeName() )+"' not recognized" )
 	End
 	
-	Method Trans:String( type:ClassType )
+	Method TransType:String( type:ClassType )
 		If IsStruct( type ) Return ClassName( type )
 		Return ClassName( type )+"*"
 	End
 	
-	Method Trans:String( type:EnumType )
+	Method TransType:String( type:EnumType )
 		If type.edecl.IsExtern Return type.edecl.symbol
 		Return "bbInt"
 	End
 	
-	Method Trans:String( type:PrimType )
+	Method TransType:String( type:PrimType )
 		Return type.ctype.cdecl.symbol
 	End
 	
-	Method Trans:String( type:FuncType )
+	Method TransType:String( type:FuncType )
 		Return "bbFunction<"+CFuncType( type )+">"
 	End
 	
-	Method Trans:String( type:ArrayType )
+	Method TransType:String( type:ArrayType )
 		Return ArrayName( type )+"*"
 	End
 	
-	Method Trans:String( type:PointerType )
-		Return Trans( type.elemType )+"*"
+	Method TransType:String( type:PointerType )
+		Return TransType( type.elemType )+"*"
 	End
 	
-	Method Trans:String( type:GenArgType )
+	Method TransType:String( type:GenArgType )
 		Return type.ToString()
 	End
 	
 	Method ArrayName:String( type:ArrayType )
+		If type.rank=1 Return "bbArray<"+VarType( type.elemType )+">"
 		Return "bbArray<"+VarType( type.elemType )+","+type.rank+">"
 	End
 	

+ 96 - 2
src/mx2new/type.monkey2

@@ -36,6 +36,10 @@ Class Type Extends SNode
 		Return flags & TYPE_GENERIC
 	End
 	
+	Property Name:String() Abstract
+	
+	Property TypeId:String() Abstract
+	
 	Method ToType:Type() Override
 		Return Self
 	End
@@ -101,6 +105,19 @@ Class PrimType Extends Type
 		Return ctype.cdecl.ident.Slice( 1 )	'slice off '@' prefix
 	End
 	
+	Property Name:String() Override
+		Return ctype.Name
+	End
+	
+	Property TypeId:String() Override
+		Select Self
+		Case IntType Return "i"
+		Case FloatType Return "f"
+		Case StringType Return "s"
+		End
+		Return "?"
+	End
+	
 	Method FindNode:SNode( ident:String ) Override
 		Return ctype.FindNode( ident )
 	End
@@ -197,7 +214,7 @@ Class ArrayType Extends Type
 		
 		If elemType.IsGeneric flags|=TYPE_GENERIC
 
-		If Not IsGeneric 
+		If Not IsGeneric
 			Local types:=New Type[1]
 			types[0]=elemType
 			ctype=Cast<ClassType>( ctype.GenInstance( types ) )
@@ -205,12 +222,21 @@ Class ArrayType Extends Type
 		
 		If Not ctype SemantError( "ArrayType.New()" )
 	End
-
+	
 	Method ToString:String() Override
 
 		Return elemType.ToString()+"[,,,,,,,,,,".Slice( 0,rank )+"]"
 	End
 	
+	Property Name:String() Override
+		Return elemType.Name+"[,,,,,,,,,,".Slice( 0,rank )+"]"
+	End
+	
+	Property TypeId:String() Override
+		If rank>1 Return "A"+rank+elemType.TypeId
+		Return "A"+elemType.TypeId
+	End
+
 	Method FindNode:SNode( ident:String ) Override
 	
 		Return ctype.FindNode( ident )
@@ -281,6 +307,14 @@ Class PointerType Extends Type
 		Return elemType.ToString()+" Ptr"
 	End
 	
+	Property Name:String() Override
+		Return elemType.Name+" Ptr"
+	End
+	
+	Property TypeId:String() Override
+		Return "P"+elemType.TypeId
+	End
+	
 	Method Index:Value( args:Value[],value:Value ) Override
 	
 		If args.Length<>1 Throw New SemantEx( "Wrong number of indices" )
@@ -355,6 +389,24 @@ Class FuncType Extends Type
 		Return retType.ToString()+"("+Join( argTypes )+")"
 	End
 	
+	Property Name:String() Override
+	
+		Local args:=""
+		For Local arg:=Eachin argTypes
+			args+=arg.Name
+		Next
+		
+		Return retType.Name+"("+args.Slice( 1 )+")"
+	End
+	
+	Property TypeId:String() Override
+		Local args:=""
+		For Local arg:=Eachin argTypes
+			args+=arg.TypeId
+		Next
+		Return "F"+retType.TypeId+args+"E"
+	End
+	
 	Method Invoke:Value( args:Value[],value:Value ) Override
 	
 		If args.Length<>argTypes.Length Throw New SemantEx( "Wrong number of arguments - expecting "+argTypes.Length+" not "+args.Length )
@@ -432,6 +484,22 @@ Class GenArgType Extends Type
 		Return str+"?"
 	End
 	
+	Property Name:String() Override
+	
+		Local args:=""
+		For Local arg:=Eachin types
+			args+=","+arg.Name
+		Next
+		If args args="<"+args.Slice( 1 )+">"
+		
+		Return ident+args+"?"
+	End
+	
+	Property TypeId:String() Override
+		SemantError( "GenArgType.TypeId()" )
+		Return ""
+	End
+	
 	Method GenInstance:Type( types:Type[] ) Override
 	
 		If Self.types SemantError( "GenArgType.GenInstance()" )
@@ -503,6 +571,14 @@ Class VoidType Extends Type
 		Return "Void"
 	End
 	
+	Property Name:String() Override
+		Return "Void"
+	End
+	
+	Property TypeId:String() Override
+		Return "v"
+	End
+	
 End
 
 Class BadType Extends Type
@@ -511,6 +587,15 @@ Class BadType Extends Type
 		Return "<BadType>"
 	End
 	
+	Property Name:String() Override
+		Return "{BadType}"
+	End
+	
+	Property TypeId:String() Override
+		SemantError( "BadType.TypeId()" )
+		Return ""
+	End
+	
 	Method Equals:Bool( type:Type ) Override
 		Return False
 	End
@@ -523,6 +608,15 @@ Class NullType Extends Type
 		Return "<NullType>"
 	End
 
+	Property Name:String() Override
+		Return "{NullType}"
+	End
+
+	Property TypeId:String() Override
+		SemantError( "NullType.TypeId()" )
+		Return ""
+	End
+	
 	Method Equals:Bool( type:Type ) Override
 		Return False
 	End

+ 2 - 2
src/mx2new/value.monkey2

@@ -66,11 +66,11 @@ Class Value Extends SNode
 		Throw New SemantEx( "Value '"+ToString()+"' is Not generic" )
 	End
 	
-	Method Assign:Stmt( op:String,value:Value,block:Block ) Virtual
+	Method Assign:Stmt( pnode:PNode,op:String,value:Value,block:Block ) Virtual
 		If Not IsAssignable SemantError( "Value.Assign()" )
 		ValidateAssignOp( op,type )
 		value=value.UpCast( type )
-		Return New AssignStmt( op,Self,value )
+		Return New AssignStmt( pnode,op,Self,value )
 	End
 	
 	Method CheckAccess( tscope:Scope ) Virtual

+ 0 - 0
modules/sdl2/tests/simple_gles20_window.monkey2 → tests/sdl2/simple_gles20_window.monkey2