Bladeren bron

Merge branch 'develop-tmp' into develop

Mark Sibly 7 jaren geleden
bovenliggende
commit
127a175d43

+ 38 - 0
src/mx2cc/.mx2/test.monkey2

@@ -0,0 +1,38 @@
+
+Function Main:Void()
+	
+	Local x:=0,y:=50,z:=100
+	
+	If x<10
+		Local t:=100
+	Else
+		Local t:=20
+	Endif
+	
+	While True
+		Local a:=10
+	Wend
+	
+	Repeat
+		Local q:=70
+	Until True
+	
+	For Local b:=0 Until 10
+		Local c:=20
+	Next
+	
+	Select x
+	Case 10
+		Local d:=30
+	Default
+		Local e:=40
+	End
+	
+	Try
+		Local f:=50
+	Catch ex:Throwable
+		Local g:=60
+	End
+
+End
+

+ 5 - 7
src/mx2cc/block.monkey2

@@ -26,13 +26,11 @@ Class Block Extends Scope
 		inex=outer.inex
 	End
 	
-'	Property IsGeneric:Bool() Override
-
-'		If func.IsGeneric Return True
-
-'		Return Super.IsGeneric
-'	End
-
+	Property IsInstanceOf:Bool() Override
+		
+		Return func.instanceOf<>Null ?Else Super.IsInstanceOf
+	End
+	
 	Method FindValue:Value( ident:String ) Override
 
 		Local node:=FindNode( ident )

+ 2 - 1
src/mx2cc/decl.monkey2

@@ -104,7 +104,8 @@ End
 
 Class FileDecl Extends Decl
 
-	Field path:String
+	Field path:String		'path for .monkey2 file
+	Field gpath:String		'path for .geninfo file
 	Field nmspace:String
 	Field usings:String[]
 	Field imports:String[]

+ 6 - 0
src/mx2cc/errors.monkey2

@@ -130,11 +130,17 @@ Class OverloadEx Extends SemantEx
 End
 
 Function SemantError( func:String )
+#If __CONFIG__="debug"
+	DebugStop()
+#endif
 	Print "~n".Join( GetDebugStack() )
 	Throw New SemantEx( func+" Internal Error" )
 End
 
 Function TransError( func:String )
+#If __CONFIG__="debug"
+	DebugStop()
+#endif
 	Print "~n".Join( GetDebugStack() )
 	Throw New SemantEx( func+" Internal Error" )
 End

+ 180 - 31
src/mx2cc/geninfo/geninfo.monkey2

@@ -1,7 +1,19 @@
 
 Namespace mx2.geninfo
 
-Class ParseInfoGenerator
+#rem
+
+Possible optimizations:
+
+* Use semType for functions.
+
+* Erase blocks with no vardecls.
+
+* Remove 'monkey.types.' prefix from primitive sem types.
+
+#end
+
+Class GeninfoGenerator
 
 	Method GenParseInfo:JsonValue( fdecl:FileDecl )
 	
@@ -10,26 +22,63 @@ Class ParseInfoGenerator
 		Return node
 	End
 	
-	Private
+	Method GenSemantInfo()
+		
+		For Local fdecl:=Eachin Builder.mainModule.fileDecls
+			
+			If Not fdecl.gpath Continue
+			
+'			Print "path="+fdecl.path+" gpath="+fdecl.gpath
+			
+			Local jobj:=GenParseInfo( fdecl )
+			
+			Local json:=jobj.ToJson()
+			
+			CreateDir( ExtractDir( fdecl.gpath ) )
+			
+			CSaveString( json,fdecl.gpath )
+		Next
+		
+	End
 	
-	'Generic...
-	'
+	Private
+
 	Method GenNode<T>:JsonArray( args:T[] )
 	
-		Local arr:=New JsonArray
+		Local jarr:=New JsonArray
+		
 		For Local arg:=Eachin args
-			arr.Push( GenNode( arg ) )
+			If Not arg Continue
+			
+'			Local jval:=GenNode( arg )
+'			If jval jarr.Add( jval )
+
+			Local jval:=GenNode( arg )
+			If Not jval Continue
+			
+			Local jarr2:=Cast<JsonArray>( jval )
+			
+			If jarr2 
+				For Local jval:=Eachin jarr2
+					jarr.Add( jval )
+				Next
+			Else
+				jarr.Add( jval )
+			Endif
 		Next
-		Return arr
+		
+		Return jarr
 	End
 	
 	Method GenNode:JsonArray( args:String[] )
 
-		Local arr:=New JsonArray
+		Local jarr:=New JsonArray
+			
 		For Local arg:=Eachin args
-			arr.Push( New JsonString( arg ) )
+			jarr.Add( New JsonString( arg ) )
 		Next
-		Return arr
+		
+		Return jarr
 	End
 	
 	'Decls...
@@ -49,7 +98,7 @@ Class ParseInfoGenerator
 		Return node
 	End
 	
-	Method GenNode:JsonObject( decl:Decl )
+	Method GenNode:JsonValue( decl:Decl )
 	
 		Local classDecl:=Cast<ClassDecl>( decl )
 		If classDecl Return GenNode( classDecl )
@@ -69,7 +118,7 @@ Class ParseInfoGenerator
 		Return MakeNode( decl )
 	End
 
-	Method GenNode:JsonObject( decl:FileDecl )
+	Method GenNode:JsonValue( decl:FileDecl )
 	
 		local node:=MakeNode( decl )
 		
@@ -81,7 +130,7 @@ Class ParseInfoGenerator
 		Return node
 	End
 	
-	Method GenNode:JsonObject( decl:ClassDecl )
+	Method GenNode:JsonValue( decl:ClassDecl )
 	
 		Local node:=MakeNode( decl )
 		
@@ -94,7 +143,7 @@ Class ParseInfoGenerator
 		Return node
 	End
 
-	Method GenNode:JsonObject( decl:FuncDecl )
+	Method GenNode:JsonValue( decl:FuncDecl )
 
 		Local node:=MakeNode( decl )
 		
@@ -103,11 +152,13 @@ Class ParseInfoGenerator
 		If decl.type node.SetValue( "type",GenNode( decl.type ) )
 		
 		If decl.whereExpr node.SetValue( "where",GenNode( decl.whereExpr ) )
-		
+			
+		If decl.stmts node.SetValue( "stmts",GenNode( decl.stmts ) )
+			
 		Return node
 	End
 	
-	Method GenNode:JsonObject( decl:AliasDecl )
+	Method GenNode:JsonValue( decl:AliasDecl )
 
 		Local node:=MakeNode( decl )
 		
@@ -118,18 +169,20 @@ Class ParseInfoGenerator
 		Return node
 	End
 	
-	Method GenNode:JsonObject( decl:VarDecl )
+	Method GenNode:JsonValue( decl:VarDecl )
 	
 		Local node:=MakeNode( decl )
 		
 		If decl.type node.SetValue( "type",GenNode( decl.type ) )
 		
 		If decl.init node.SetValue( "init",GenNode( decl.init ) )
-		
+			
+		If decl.semtype node.SetString( "semtype",decl.semtype.Name )
+			
 		Return node
 	End
 	
-	Method GenNode:JsonObject( decl:PropertyDecl )
+	Method GenNode:JsonValue( decl:PropertyDecl )
 	
 		Local node:=MakeNode( decl )
 		
@@ -141,6 +194,102 @@ Class ParseInfoGenerator
 	
 	End
 	
+	'StmtExprs...
+	Method MakeNode:JsonObject( stmt:StmtExpr,kind:String )
+	
+		Local node:=New JsonObject
+
+		node.SetString( "srcpos",(stmt.srcpos Shr 12)+":"+(stmt.srcpos & $fff) )
+		node.SetString( "endpos",(stmt.endpos Shr 12)+":"+(stmt.endpos & $fff) )
+		node.SetString( "kind",kind )
+		
+		Return node
+	End
+	
+	Method GenNode:JsonValue( stmt:StmtExpr )
+		
+		Local vdeclStmt:=Cast<VarDeclStmtExpr>( stmt )
+		If vdeclStmt Return GenNode( vdeclStmt.decl )
+		
+		Local ifStmt:=Cast<IfStmtExpr>( stmt )
+		If ifStmt Return GenNode( ifStmt )
+		
+		Local whileStmt:=Cast<WhileStmtExpr>( stmt )
+		If whileStmt Return GenNode( whileStmt )
+		
+		Local repeatStmt:=Cast<RepeatStmtExpr>( stmt )
+		If repeatStmt Return GenNode( repeatStmt )
+		
+		Local selectStmt:=Cast<SelectStmtExpr>( stmt )
+		If selectStmt Return GenNode( selectStmt )
+		
+		Local forStmt:=Cast<ForStmtExpr>( stmt )
+		If forStmt Return GenNode( forStmt )
+		
+		Local tryStmt:=Cast<TryStmtExpr>( stmt )
+		If tryStmt Return GenNode( tryStmt )
+		
+		Return Null
+	End
+	
+	Method GenNode:JsonValue( ifStmt:IfStmtExpr )
+
+		Local jarr:=New JsonArray
+		While ifStmt
+			Local jobj:=MakeNode( ifStmt,"block" )
+			jobj.SetValue( "stmts",GenNode( ifStmt.stmts ) )
+			jarr.Add( jobj )
+			ifStmt=ifStmt.succ
+		Wend
+		Return jarr
+	End
+	
+	Method GenNode:JsonValue( whileStmt:WhileStmtExpr )
+		
+		Local jobj:=MakeNode( whileStmt,"block" )
+		jobj.SetValue( "stmts",GenNode( whileStmt.stmts ) )
+		Return jobj
+	End
+	
+	Method GenNode:JsonValue( repeatStmt:RepeatStmtExpr )
+
+		Local jobj:=MakeNode( repeatStmt,"block" )
+		jobj.SetValue( "stmts",GenNode( repeatStmt.stmts ) )
+		Return jobj
+	End
+	
+	Method GenNode:JsonValue( selectStmt:SelectStmtExpr )
+		
+		Local jarr:=New JsonArray
+		For Local caseStmt:=Eachin selectStmt.cases
+			Local jobj:=MakeNode( caseStmt,"block" )
+			jobj.SetValue( "stmts",GenNode( caseStmt.stmts ) )
+			jarr.Add( jobj )
+		Next
+		Return jarr
+	End
+	
+	Method GenNode:JsonValue( forStmt:ForStmtExpr )
+		
+		Local jobj:=MakeNode( forStmt,"block" )
+		jobj.SetValue( "stmts",GenNode( forStmt.stmts ) )
+		Return jobj
+	End
+	
+	Method GenNode:JsonValue( tryStmt:TryStmtExpr )
+
+		Local jarr:=New JsonArray
+		Local jobj:=MakeNode( tryStmt,"block" )
+		jobj.SetValue( "stmts",GenNode( tryStmt.stmts ) )
+		jarr.Add( jobj )
+		For Local catchStmt:=Eachin tryStmt.catches
+			Local jobj:=MakeNode( catchStmt,"block" )
+			jobj.SetValue( "stmts",GenNode( catchStmt.stmts ) )
+			jarr.Add( jobj )
+		Next
+		Return jarr
+	End
+	
 	'Expressions...
 	'
 	Method MakeNode:JsonObject( expr:Expr,kind:String )
@@ -154,8 +303,8 @@ Class ParseInfoGenerator
 		Return node
 	End
 	
-	Method GenNode:JsonObject( expr:Expr )
-	
+	Method GenNode:JsonValue( expr:Expr )
+		
 		Local identExpr:=Cast<IdentExpr>( expr )
 		If identExpr Return GenNode( identExpr )
 		
@@ -186,7 +335,7 @@ Class ParseInfoGenerator
 		Return MakeNode( expr,"????Expr?????" )
 	End
 	
-	Method GenNode:JsonObject( expr:IdentExpr )
+	Method GenNode:JsonValue( expr:IdentExpr )
 	
 		Local node:=MakeNode( expr,"ident" )
 		
@@ -195,7 +344,7 @@ Class ParseInfoGenerator
 		Return node
 	End
 	
-	Method GenNode:JsonObject( expr:MemberExpr )
+	Method GenNode:JsonValue( expr:MemberExpr )
 	
 		Local node:=MakeNode( expr,"member" )
 		
@@ -206,7 +355,7 @@ Class ParseInfoGenerator
 		Return node
 	End
 	
-	Method GenNode:JsonObject( expr:GenericExpr )
+	Method GenNode:JsonValue( expr:GenericExpr )
 
 		Local node:=MakeNode( expr,"generic" )
 		
@@ -217,7 +366,7 @@ Class ParseInfoGenerator
 		Return node
 	End
 	
-	Method GenNode:JsonObject( expr:LiteralExpr )
+	Method GenNode:JsonValue( expr:LiteralExpr )
 	
 		Local node:=MakeNode( expr,"literal" )
 		
@@ -226,7 +375,7 @@ Class ParseInfoGenerator
 		Return node
 	End
 	
-	Method GenNode:JsonObject( expr:NewObjectExpr )
+	Method GenNode:JsonValue( expr:NewObjectExpr )
 	
 		Local node:=MakeNode( expr,"newobject" )
 		
@@ -237,7 +386,7 @@ Class ParseInfoGenerator
 		Return node
 	End
 		
-	Method GenNode:JsonObject( expr:NewArrayExpr )
+	Method GenNode:JsonValue( expr:NewArrayExpr )
 	
 		Local node:=MakeNode( expr,"newarray" )
 		
@@ -250,7 +399,7 @@ Class ParseInfoGenerator
 		Return node
 	End
 		
-	Method GenNode:JsonObject( expr:FuncTypeExpr )
+	Method GenNode:JsonValue( expr:FuncTypeExpr )
 
 		Local node:=MakeNode( expr,"functype" )
 		
@@ -261,7 +410,7 @@ Class ParseInfoGenerator
 		Return node
 	End
 
-	Method GenNode:JsonObject( expr:ArrayTypeExpr )
+	Method GenNode:JsonValue( expr:ArrayTypeExpr )
 	
 		Local node:=MakeNode( expr,"arraytype" )
 		
@@ -272,7 +421,7 @@ Class ParseInfoGenerator
 		Return node
 	End
 	
-	Method GenNode:JsonObject( expr:PointerTypeExpr )
+	Method GenNode:JsonValue( expr:PointerTypeExpr )
 	
 		Local node:=MakeNode( expr,"pointertype" )
 		
@@ -280,5 +429,5 @@ Class ParseInfoGenerator
 		
 		Return node
 	End
-
+	
 End

+ 54 - 20
src/mx2cc/mx2cc.monkey2

@@ -22,12 +22,11 @@ Global opts_time:Bool
 
 Global StartDir:String
 
-'Const TestArgs:="mx2cc makemods -verbose=1 -clean -target=emscripten pyro-framework"
-'Const TestArgs:="mx2cc makemods -verbose -target=desktop pyro-framework"
+'Const TestArgs:="mx2cc makemods"
  
-Const TestArgs:="mx2cc makeapp src/mx2cc/test.monkey2"
-
-'Const TestArgs:="mx2cc makeapp -parse -geninfo src/mx2cc/test.monkey2"
+Const TestArgs:="mx2cc geninfo src/mx2cc/test.monkey2"
+'Const TestArgs:="mx2cc geninfo modules/mojo3d/mojo3d.monkey2"
+'Const TestArgs:="mx2cc geninfo src/ted2go/Ted2.monkey2"
 
 'Const TestArgs:="mx2cc makeapp -verbose src/mx2cc/catan/main.monkey2"
 
@@ -140,6 +139,8 @@ Function Main()
 		Local start:=std.time.Now()
 		
 		Select cmd
+		Case "geninfo"
+			ok=GenInfo( args )
 		Case "makeapp"
 			ok=MakeApp( args )
 		Case "makemods"
@@ -162,6 +163,49 @@ Function Main()
 	If Not ok libc.exit_( 1 )
 End
 
+Function GenInfo:Bool( args:String[] )
+
+	Local opts:=New BuildOpts
+	opts.productType="module"
+	opts.target="desktop"
+	opts.config="debug"
+	opts.clean=False
+	opts.fast=True
+	opts.verbose=0
+	opts.passes=2
+	opts.geninfo=True
+	
+	args=ParseOpts( opts,args )
+	If args.Length<>1 Fail( "Invalid app source file" )
+	
+	Local cd:=CurrentDir()
+	ChangeDir( StartDir )
+	opts.mainSource=RealPath( args[0].Replace( "\","/" ) )
+	ChangeDir( cd )
+	
+	Print ""
+	Print "***** Generating info for "+opts.mainSource+"' ("+opts.target+" "+opts.config+" "+opts.arch+" "+opts.toolchain+") *****"
+	Print ""
+
+	New BuilderInstance( opts )
+	
+	Builder.Parse()
+	If opts.passes=1
+		Local gen:=New GeninfoGenerator
+		Local jobj:=gen.GenParseInfo( Builder.mainModule.fileDecls[0] )
+		Print jobj.ToJson()
+		Return Builder.errors.Length=0
+	Endif
+	If Builder.errors.Length Return False
+	
+	Builder.Semant()
+	
+	Local gen:=New GeninfoGenerator
+	gen.GenSemantInfo()
+	
+	Return Builder.errors.Length=0
+End
+
 Function MakeApp:Bool( args:String[] )
 
 	Local opts:=New BuildOpts
@@ -193,29 +237,19 @@ Function MakeApp:Bool( args:String[] )
 	Print ""
 
 	New BuilderInstance( opts )
-	
+
+	'pass1 	
 	Builder.Parse()
-	If opts.passes=1
-		If opts.geninfo
-			Local gen:=New ParseInfoGenerator
-			Local jobj:=gen.GenParseInfo( Builder.mainModule.fileDecls[0] )
-			Print jobj.ToJson()
-		Endif
-		Return True
-	Endif
+	If opts.passes=1 Return Builder.errors.Length=0
 	If Builder.errors.Length Return False
 	
 	Builder.Semant()
+	If opts.passes=2 Return Builder.errors.Length=0
 	If Builder.errors.Length Return False
-	If opts.passes=2
-		Return True
-	Endif
 	
 	Builder.Translate()
+	If opts.passes=3 Return Builder.errors.Length=0
 	If Builder.errors.Length Return False
-	If opts.passes=3
-		Return True
-	Endif
 	
 	Builder.product.Build()
 	If Builder.errors.Length Return False

+ 30 - 8
src/mx2cc/parser.monkey2

@@ -21,6 +21,19 @@ Class Parser
 	End	
 
 	Method ParseFile:FileDecl( ident:String,srcPath:String,ppsyms:StringMap<String> )
+		
+		Local gpath:=""
+		
+		If Builder.opts.geninfo
+			
+			Local dir:=ExtractDir( srcPath )+".mx2/"
+			Local name:=StripDir( srcPath )
+			Local path:=dir+name
+			
+			If GetFileType( path )=FileType.File srcPath=path
+				
+			gpath=StripExt( path )+".geninfo"
+		Endif
 	
 		_ppsyms=ppsyms
 		
@@ -30,6 +43,7 @@ Class Parser
 		_fdecl=New FileDecl
 		_fdecl.ident=ident
 		_fdecl.path=srcPath
+		_fdecl.gpath=gpath
 		_fdecl.nmspace=""
 		
 		Local source:=LoadString( srcPath )
@@ -1049,9 +1063,13 @@ Class Parser
 			SkipToNextLine()
 		End
 		
-		Local cases:=New Stack<CaseExpr>
+		Local cases:=New Stack<CaseStmtExpr>
 		
-		While CParse( "case" )
+		While Toke="case"
+			
+			Local srcpos:=SrcPos
+			
+			Bump()
 
 			Local exprs:=New Stack<Expr>
 
@@ -1070,18 +1088,22 @@ Class Parser
 			
 			Local stmts:=ParseStmts( True )
 			
-			cases.Push( New CaseExpr( exprs.ToArray(),stmts ) )
+			cases.Push( New CaseStmtExpr( exprs.ToArray(),stmts,srcpos,SrcPos ) )
 		Wend
 		
 		If cases.Empty ErrorNx( "Select statement must have at least one case" )
-		
-		If CParse( "default" )
+			
+		If Toke="default"
+			
+			Local srcpos:=SrcPos
+			
+			Bump()
 		
 			CParseEol()
 		
 			Local stmts:=ParseStmts( True )
 			
-			cases.Push( New CaseExpr( Null,stmts ) )
+			cases.Push( New CaseStmtExpr( Null,stmts,srcpos,SrcPos ) )
 		Endif
 		
 		Try
@@ -1112,7 +1134,7 @@ Class Parser
 		
 		Local stmts:=ParseStmts( True )
 		
-		Local catches:=New Stack<CatchExpr>
+		Local catches:=New Stack<CatchStmtExpr>
 		
 		While Toke="catch"
 		
@@ -1137,7 +1159,7 @@ Class Parser
 			
 			Local stmts:=ParseStmts( True )
 			
-			catches.Push( New CatchExpr( varIdent,varType,stmts ) )
+			catches.Push( New CatchStmtExpr( varIdent,varType,stmts,srcpos,SrcPos ) )
 		Wend
 		
 		Try

+ 12 - 9
src/mx2cc/stmtexpr.monkey2

@@ -499,12 +499,14 @@ Class RepeatStmtExpr Extends StmtExpr
 
 End
 
-Class CaseExpr
-
+Class CaseStmtExpr Extends StmtExpr
+	
 	Field exprs:Expr[]
 	Field stmts:StmtExpr[]
 	
-	Method New( exprs:Expr[],stmts:StmtExpr[] )
+	Method New( exprs:Expr[],stmts:StmtExpr[],srcpos:Int,endpos:Int )
+		Super.New( srcpos,endpos )
+		
 		Self.exprs=exprs
 		Self.stmts=stmts
 	End
@@ -514,9 +516,9 @@ End
 Class SelectStmtExpr Extends StmtExpr
 
 	Field expr:Expr
-	Field cases:CaseExpr[]
+	Field cases:CaseStmtExpr[]
 	
-	Method New( expr:Expr,cases:CaseExpr[],srcpos:Int,endpos:Int )
+	Method New( expr:Expr,cases:CaseStmtExpr[],srcpos:Int,endpos:Int )
 		Super.New( srcpos,endpos )
 		
 		Self.expr=expr
@@ -777,13 +779,14 @@ Class ForStmtExpr Extends StmtExpr
 	
 End
 
-Class CatchExpr
+Class CatchStmtExpr Extends StmtExpr
 
 	Field varIdent:String
 	Field varType:Expr
 	Field stmts:StmtExpr[]
 
-	Method New( varIdent:String,varType:Expr,stmts:StmtExpr[] )
+	Method New( varIdent:String,varType:Expr,stmts:StmtExpr[],srcpos:Int,endpos:Int )
+		Super.New( srcpos,endpos )
 		Self.varIdent=varIdent
 		Self.varType=varType
 		Self.stmts=stmts
@@ -794,9 +797,9 @@ End
 Class TryStmtExpr Extends StmtExpr
 
 	Field stmts:StmtExpr[]
-	Field catches:CatchExpr[]
+	Field catches:CatchStmtExpr[]
 	
-	Method New( stmts:StmtExpr[],catches:CatchExpr[],srcpos:Int,endpos:Int )
+	Method New( stmts:StmtExpr[],catches:CatchStmtExpr[],srcpos:Int,endpos:Int )
 		Super.New( srcpos,endpos )
 		Self.stmts=stmts
 		Self.catches=catches

+ 1 - 10
src/mx2cc/test2.monkey2

@@ -1,12 +1,3 @@
 
-
-Class VertexFormat
-	
-	Property Pitch:Int() Virtual
-		Return 0
-	End
-
-	Method UpdateGLAttribs() Virtual
-	End
+Function Test2()
 End
-

+ 39 - 30
src/mx2cc/toker.monkey2

@@ -81,10 +81,11 @@ Class Toker
 		_toke=""
 		_tokePos=0
 		_tokeType=TOKE_EOL
-		_line=0
 		_srcPos=0
 		_endPos=0
 		_linePos=0
+		_line=1
+		_flags=0
 	End
 	
 	Property Toke:String()
@@ -139,27 +140,27 @@ Class Toker
 		_srcPos=toker._srcPos
 		_endPos=toker._endPos
 		_linePos=toker._linePos
+		_flags=toker._flags
 	End
 	
 	Method Bump:String()
-	
-		Local newLine:=False
-		If _tokeType=TOKE_EOL Or _tokeType=TOKE_PREPROC
-			_line+=1
-			_linePos=_pos
-			newLine=True
-		End
-	
+		
+		'update endpos
+		If _flags & 1 _endPos=(_line Shl 12) | (_pos-_linePos)
+		
+		'skip whitespace
 		While _pos<_len And _text[_pos]<=32 And _text[_pos]<>CHAR_EOL
 			_pos+=1
 		Wend
-		
+
+		'update toke start pos
+		_toke=""		
 		_tokePos=_pos
-		_endPos=_srcPos+_toke.Length
-		_srcPos=(_line Shl 12) | (_tokePos-_linePos)
-		
+		_srcPos=(_line Shl 12) | (_pos-_linePos)
+		_flags|=1
+
+		'check end of file
 		If _pos=_len
-			_toke=""
 			_tokeType=TOKE_EOF
 			Return _toke
 		Endif
@@ -186,8 +187,6 @@ Class Toker
 				_tokeType=TOKE_IDENT
 			Endif
 			
-			Return _toke
-			
 		Else If IsDigit( ch ) Or (ch=CHAR_DOT And _pos<_len And IsDigit( _text[_pos] ))
 
 			_tokeType=TOKE_INTLIT
@@ -227,12 +226,11 @@ Class Toker
 			While _pos<_len
 				Local ch:=_text[_pos]
 				If ch=CHAR_QUOTE Exit
+				_pos+=1
 				If ch=CHAR_EOL
-					_line+=1
 					_linePos=_pos
-				
+					_line+=1
 				Endif
-				_pos+=1
 			Wend
 			If _pos<_len And _text[_pos]=CHAR_QUOTE
 				_tokeType=TOKE_STRINGLIT
@@ -250,13 +248,18 @@ Class Toker
 			
 			_tokeType=TOKE_INTLIT
 			
-		Else If ch=CHAR_HASH And newLine
+		Else If ch=CHAR_HASH And (_tokeType=TOKE_EOL Or _tokeType=TOKE_PREPROC)
 		
 			While _pos<_len And _text[_pos]<>CHAR_EOL
 				_pos+=1
 			Wend
+			If _pos<_len
+				_pos+=1
+				_linePos=_pos
+				_line+=1
+			Endif
 			
-			If _pos<_len _pos+=1
+			If _tokeType=TOKE_PREPROC Or _tokeType=TOKE_EOL _flags&=~1
 			
 			_tokeType=TOKE_PREPROC
 			
@@ -265,17 +268,25 @@ Class Toker
 			While _pos<_len And _text[_pos]<>CHAR_EOL
 				_pos+=1
 			Wend
+
+			If _pos<_len
+				_pos+=1
+				_linePos=_pos
+				_line+=1
+			Endif
 			
-			_tokePos=_pos
-			
-			If _pos<_len _pos+=1
+			If _tokeType=TOKE_PREPROC Or _tokeType=TOKE_EOL _flags&=~1
 			
 			_tokeType=TOKE_EOL
 			
 		Else If ch=CHAR_EOL
+			
+			_linePos=_pos
+			_line+=1
 		
+			If _tokeType=TOKE_PREPROC Or _tokeType=TOKE_EOL _flags&=~1
+				
 			_tokeType=TOKE_EOL
-
 		Else
 		
 			Local found:=False
@@ -303,11 +314,10 @@ Class Toker
 			Endif
 			
 			_tokeType=TOKE_SYMBOL
-
 		Endif
 		
-		_toke=_text.Slice( _tokePos,_pos )
-		
+		If Not _toke _toke=_text.Slice( _tokePos,_pos )
+
 		Return _toke
 	End
 	
@@ -323,6 +333,5 @@ Class Toker
 	Field _srcPos:Int
 	Field _endPos:Int
 	Field _linePos:Int
-	
+	Field _flags:Int
 End
-

+ 8 - 14
src/mx2cc/var.monkey2

@@ -6,6 +6,8 @@ Class VarDecl Extends Decl
 	Field type:Expr
 	Field init:Expr
 	
+	Field semtype:Type
+	
 	Method ToNode:SNode( scope:Scope ) Override
 	
 		Return New VarValue( Self,scope )
@@ -80,7 +82,7 @@ Class VarValue Extends Value
 			type=vdecl.type.SemantType( scope )
 			
 			If vdecl.init init=vdecl.init.SemantRValue( scope,type )
-			
+				
 		Else If vdecl.init
 		
 			init=vdecl.init.SemantRValue( scope )
@@ -88,34 +90,26 @@ Class VarValue Extends Value
 			If TCast<VoidType>( init.type ) Throw New SemantEx( "Variables cannot have 'Void' type" )
 			
 			type=init.type
-			
 		Else 
 
 			SemantError( "VarValue.OnSemant()" )
 
 		Endif
 		
-		If Not scope.IsGeneric And Not vdecl.IsExtern And Not Cast<Block>( scope )
-		
-			If vdecl.kind="global" Or vdecl.kind="const"
-				transFile.globals.Push( Self )
-			Else
-				scope.transMembers.Push( Self )
-			Endif
-  		
+		If Not scope.IsInstanceOf
+			If vdecl.semtype SemantError( "VarValue.OnSemant() 2" )
+			vdecl.semtype=type
 		Endif
 		
-		#rem
-		If Not type.IsGeneric And Not vdecl.IsExtern And Not Cast<Block>( scope )
+		If Not scope.IsGeneric And Not vdecl.IsExtern And Not Cast<Block>( scope )
 		
 			If vdecl.kind="global" Or vdecl.kind="const"
 				transFile.globals.Push( Self )
 			Else
 				scope.transMembers.Push( Self )
 			Endif
-			
+  		
 		Endif
-		#end
 		
 		Scope.semanting.Pop()