Răsfoiți Sursa

Added namespace scope.
Arrays can be added even more.
New munging for module ids, adding subfolder names where required.

woollybah 11 ani în urmă
părinte
comite
109b3c127b
7 a modificat fișierele cu 180 adăugiri și 50 ștergeri
  1. 0 5
      config.bmx
  2. 29 9
      ctranslator.bmx
  3. 33 1
      decl.bmx
  4. 43 1
      expr.bmx
  5. 17 2
      iparser.bmx
  6. 51 31
      parser.bmx
  7. 7 1
      type.bmx

+ 0 - 5
config.bmx

@@ -219,11 +219,6 @@ Function BuildHeaderName:String(path:String)
 	Return path
 End Function
 
-Function MungModuleName:String(ident:String)
-	Local mung:String = "__bb_" + ident + "_" + ident[ident.Find(".") + 1..]
-	Return mung.Replace(".", "_").Replace("-", "_")
-End Function
-
 Rem
 bbdoc: Get the header file name from a given module ident, optionally with include path.
 End Rem

+ 29 - 9
ctranslator.bmx

@@ -893,8 +893,12 @@ Type TCTranslator Extends TTranslator
 			t_rhs = "*" + t_rhs
 		End If
 
-		If TStringType(expr.exprType) And expr.op = "+" Then
-			Return "bbStringConcat(" + t_lhs + "," + t_rhs + ")"
+		If expr.op = "+" Then
+			If TStringType(expr.exprType) Then
+				Return "bbStringConcat(" + t_lhs + "," + t_rhs + ")"
+			Else If TArrayType(expr.exprType) Then
+				Return "bbArrayConcat(" + TransArrayType(TArrayType(expr.lhs.exprType).elemType) + "," + t_lhs + "," + t_rhs + ")"
+			End If
 		End If
 
 		If TBinaryCompareExpr(expr) And TStringType(TBinaryCompareExpr(expr).ty) Then
@@ -2322,7 +2326,7 @@ End Rem
 		If moduleDecl.filepath Then
 			' a module import
 			If FileType(moduleDecl.filepath) = FILETYPE_DIR Then
-				Emit MungModuleName(moduleDecl.ident) + "();"
+				Emit MungModuleName(moduleDecl) + "();"
 			Else
 				' maybe a file import...
 				Emit MungImportFromFile(moduleDecl) + "();"
@@ -2399,6 +2403,8 @@ End Rem
 		Emit "int " + app.munged + "();"
 
 		For Local decl:TDecl=EachIn app.Semanted()
+
+			If decl.declImported Continue
 		
 			MungDecl decl
 
@@ -2422,6 +2428,8 @@ End Rem
 		'prototypes/header!
 		For Local decl:TDecl=EachIn app.Semanted()
 		
+			If decl.declImported Continue
+		
 			Local gdecl:TGlobalDecl=TGlobalDecl( decl )
 			If gdecl
 				If Not TFunctionPtrType(gdecl.ty) Then
@@ -2498,6 +2506,8 @@ End Rem
 		'definitions!
 		For Local decl:TDecl=EachIn app.Semanted()
 			
+			If decl.declImported Continue
+			
 			Local gdecl:TGlobalDecl=TGlobalDecl( decl )
 			If gdecl
 				If Not TFunctionPtrType(gdecl.ty) Then
@@ -2546,6 +2556,9 @@ End Rem
 		
 		' register types
 		For Local decl:TDecl=EachIn app.Semanted()
+		
+			If decl.declImported Continue
+		
 			Local cdecl:TClassDecl=TClassDecl( decl )
 			If cdecl
 				Emit "bbObjectRegisterType(&" + cdecl.munged + ");"
@@ -2562,6 +2575,8 @@ End Rem
 		' initialise globals
 		For Local decl:TGlobalDecl=EachIn app.semantedGlobals
 
+			If decl.declImported Continue
+
 			decl.Semant
 			
 			' TODO : what about OnDebugStop etc, who have no init ?
@@ -2597,7 +2612,10 @@ End Rem
 						EmitIfcImports(mdecl, processed)
 
 						For Local s:String = EachIn mdecl.fileImports
-							Emit "import ~q" + s + "~q"
+							If Not processed.Contains("XX" + s + "XX") Then
+								Emit "import ~q" + s + "~q"
+								processed.Insert("XX" + s + "XX", "")
+							End If
 						Next
 					End If
 				Else
@@ -2621,7 +2639,9 @@ End Rem
 					processed.Insert(mdecl, mdecl)
 					
 					For Local decl:TDecl=EachIn mdecl._decls
-
+					
+						decl.Semant
+					
 						' consts
 						Local cdecl:TConstDecl=TConstDecl( decl )
 						If cdecl
@@ -2745,7 +2765,7 @@ End Rem
 		' consts
 		For Local decl:TDecl=EachIn app.Semanted()
 			Local cdecl:TConstDecl=TConstDecl( decl )
-			If cdecl
+			If cdecl And Not cdecl.declImported
 				EmitIfcConstDecl(cdecl)
 			End If
 		Next
@@ -2753,7 +2773,7 @@ End Rem
 		' classes
 		For Local decl:TDecl=EachIn app.Semanted()
 			Local cdecl:TClassDecl=TClassDecl( decl )
-			If cdecl
+			If cdecl And Not cdecl.declImported
 				EmitIfcClassDecl(cdecl)
 			EndIf
 		Next
@@ -2761,7 +2781,7 @@ End Rem
 		' functions
 		For Local decl:TDecl=EachIn app.Semanted()
 			Local fdecl:TFuncDecl=TFuncDecl( decl )
-			If fdecl And fdecl <> app.mainFunc Then
+			If fdecl And fdecl <> app.mainFunc  And Not fdecl.declImported Then
 				EmitIfcFuncDecl(fdecl)
 			End If
 		Next
@@ -2769,7 +2789,7 @@ End Rem
 		' globals
 		For Local decl:TDecl=EachIn app.Semanted()
 			Local gdecl:TGlobalDecl=TGlobalDecl( decl )
-			If gdecl
+			If gdecl And Not gdecl.declImported
 				EmitIfcGlobalDecl(gdecl)
 			End If
 		Next

+ 33 - 1
decl.bmx

@@ -1652,6 +1652,22 @@ Const MODULE_STRICT:Int=1
 Const MODULE_SUPERSTRICT:Int=2
 Const MODULE_ACTUALMOD:Int=4
 
+Type TNamespaceDecl Extends TScopeDecl
+
+'	Field mods:TMap = New TMap
+
+	Method Create:TNamespaceDecl( ident$,munged$ )
+		Self.ident=ident
+		Self.munged=munged
+		Return Self
+	End Method
+
+'	Method GetDecl:Object( ident$ )
+'		Return mods.ValueForKey(ident.ToLower())
+'	End Method
+	
+End Type
+
 Type TModuleDecl Extends TScopeDecl
 
 	Field filepath$
@@ -1673,6 +1689,22 @@ Type TModuleDecl Extends TScopeDecl
 		Self.munged=munged
 		Self.filepath=filepath
 		Self.attrs=attrs
+
+		If ident.Find(".") <> -1 Then
+			Local m:String = ident[..ident.Find(".")]
+			Local ns:TNamespaceDecl = TNamespaceDecl(_appInstance.GetDecl(m))
+			If Not ns Then
+				ns = New TNamespaceDecl.Create(m, m)
+				If _appInstance.mainModule Then
+					_appInstance.mainModule.InsertDecl(ns)
+				Else
+					' this must be the main module...
+					InsertDecl(ns)
+				End If
+			End If
+			ns.InsertDecl(Self)
+		End If
+
 		Return Self
 	End Method
 	
@@ -1809,7 +1841,7 @@ Type TAppDecl Extends TScopeDecl
 	
 	Method GetDecl:Object( ident$ )
 		Local obj:Object = Super.GetDecl(ident)
-		If Not obj Then
+		If Not obj And mainModule Then
 			Return mainModule.GetDecl(ident)
 		End If
 		Return obj

+ 43 - 1
expr.bmx

@@ -271,6 +271,15 @@ Type TConstExpr Extends TExpr
 		Return _trans.TransConstExpr( Self )
 	End Method
 
+	Method SemantAndCast:TExpr( ty:TType,castFlags:Int=0 )
+		Local expr:TExpr=Semant()
+		If expr.exprType.EqualsType( ty ) Return expr
+		If value = "bbNullObject" Then
+			Return expr
+		End If
+		Return New TCastExpr.Create( ty,expr,castFlags ).Semant()
+	End Method
+
 End Type
 
 Type TVarExpr Extends TExpr
@@ -1571,7 +1580,7 @@ Type TIdentExpr Extends TExpr
 
 			Return New TInvokeExpr.Create( fdecl,args ).Semant()
 		End If
-
+		
 		IdentErr
 	End Method
 
@@ -1616,6 +1625,15 @@ Type TIdentExpr Extends TExpr
 	Method SemantScope:TScopeDecl()
 		If Not expr Return _env.FindScopeDecl( ident )
 		Local scope:TScopeDecl=expr.SemantScope()
+
+		' If scope is a namespace, then we are a module. Look up the module id and return it as the real scope.
+		If TNamespaceDecl(scope) Then
+			Local mdecl:TModuleDecl=TModuleDecl(scope.FindDecl(scope.ident + "." + ident))
+			If mdecl Then
+				Return mdecl
+			End If
+		End If
+
 		If scope Return scope.FindScopeDecl( ident )
 	End Method
 
@@ -1850,3 +1868,27 @@ Type TFuncCallExpr Extends TExpr
 
 End Type
 
+Type TScopeExpr Extends TExpr
+	Field scope:TScopeDecl
+
+	Method Create:TScopeExpr( scope:TScopeDecl )
+		Self.scope=scope
+		Return Self
+	End Method
+
+	Method Copy:TExpr()
+		Return Self
+	End Method
+
+	Method ToString$()
+		Return "TScopeExpr("+scope.ToString()+")"
+	End Method
+
+	Method Semant:TExpr()
+		Err "Syntax error."
+	End Method
+
+	Method SemantScope:TScopeDecl()
+		Return scope
+	End Method
+End Type

+ 17 - 2
iparser.bmx

@@ -166,7 +166,16 @@ DebugLog "FILE NOT FOUND : " + ipath
 				
 						Local modpath:String
 						If opt_buildtype = BUILDTYPE_MODULE Then
-							modpath = opt_modulename + "_" + StripExt(iRelPath)
+							Local dir:String = ExtractDir(origPath).ToLower()
+							dir = dir[dir.findLast("/") + 1..]
+							If dir.EndsWith(".mod") Then
+								dir = ""
+							Else
+								dir = dir.Replace(".", "_").Replace("-", "_") + "_"
+							End If
+							Local file:String = StripDir(origPath).ToLower()
+			
+							modpath = opt_modulename + "_" + dir + StripExt(file)
 							modpath = modpath.ToLower().Replace(".", "_").Replace("-", "_")
 						Else
 							' todo file imports for apps
@@ -183,7 +192,9 @@ DebugLog "FILE NOT FOUND : " + ipath
 '					EndIf
 					Else
 						If iRelPath.StartsWith("-") Then
-							_mod.fileImports.AddLast(iRelPath)
+							If Not _mod.fileImports.Contains(iRelPath) Then
+								_mod.fileImports.AddLast(iRelPath)
+							End If
 						End If
 					End If
 				Else
@@ -231,6 +242,7 @@ DebugLog "FILE NOT FOUND : " + ipath
 						toker.NextToke()
 						' class decl
 						class = ParseClassDecl( stm,0 )
+						class.declImported = True
 						_mod.InsertDecl(class)
 
 						If CParse("F")
@@ -271,6 +283,7 @@ DebugLog "FILE NOT FOUND : " + ipath
 						toker.NextToke()
 
 						Local decl:TFuncDecl = ParseFuncDecl( _toke, 0 )
+						decl.declImported = True
 						
 						If decl.attrs & FUNC_PTR Then
 							ty = New TFunctionPtrType
@@ -280,6 +293,7 @@ DebugLog "FILE NOT FOUND : " + ipath
 							Local gdecl:TGlobalDecl = New TGlobalDecl.Create( decl.ident,ty, Null, DECL_GLOBAL )
 							gdecl.munged = decl.munged
 							_mod.InsertDecl gdecl
+							gdecl.declImported = True
 						Else
 							_mod.InsertDecl decl
 						End If
@@ -292,6 +306,7 @@ DebugLog "FILE NOT FOUND : " + ipath
 						
 						Local decl:TDecl = ParseDecl( _toke, DECL_CONST | DECL_EXTERN)'DECL_GLOBAL | DECL_EXTERN )
 						_mod.InsertDecl decl
+						decl.declImported = True
 
 					End If
 				

+ 51 - 31
parser.bmx

@@ -30,31 +30,6 @@ Import "iparser.bmx"
 
 Global FILE_EXT$="bmx"
 
-Type TScopeExpr Extends TExpr
-	Field scope:TScopeDecl
-
-	Method Create:TScopeExpr( scope:TScopeDecl )
-		Self.scope=scope
-		Return Self
-	End Method
-
-	Method Copy:TExpr()
-		Return Self
-	End Method
-
-	Method ToString$()
-		Return "TScopeExpr("+scope.ToString()+")"
-	End Method
-
-	Method Semant:TExpr()
-		Err "Syntax error."
-	End Method
-
-	Method SemantScope:TScopeDecl()
-		Return scope
-	End Method
-End Type
-
 Type TForEachinStmt Extends TStmt
 	Field varid$
 	Field varty:TType
@@ -319,6 +294,7 @@ Type TParser
 'DebugLog "ParseIdentType : " + id
 		If CParse( "." ) id:+"."+ParseIdent()
 		If CParse( "." ) id:+"."+ParseIdent()
+
 		Local args:TIdentType[]
 		If CParse( "<" )
 			Local nargs:Int
@@ -874,7 +850,6 @@ Type TParser
 
 			Select _toke
 			Case "."
-'DebugLog "FOUND DOT for : " + expr.ToString() + " : " + _toker._line
 				NextToke
 				expr=New TIdentExpr.Create( ParseIdent(),expr )
 'DebugLog expr.ToString()
@@ -2200,7 +2175,17 @@ End Rem
 
 			Local modpath:String
 			If opt_buildtype = BUILDTYPE_MODULE Then
-				modpath = opt_modulename + "_" + StripExt(filepath)
+
+				Local dir:String = ExtractDir(origPath).ToLower()
+				dir = dir[dir.findLast("/") + 1..]
+				If dir.EndsWith(".mod") Then
+					dir = ""
+				Else
+					dir = dir.Replace(".", "_").Replace("-", "_") + "_"
+				End If
+				Local file:String = StripDir(origPath).ToLower()
+
+				modpath = opt_modulename + "_" + dir + StripExt(file)
 				modpath = modpath.ToLower().Replace(".", "_").Replace("-", "_")
 			Else
 				modpath = StripExt(filepath)
@@ -2213,7 +2198,9 @@ End Rem
 			If par.ParseModuleImport(_module, modpath, origPath, path, , , filepath) Return
 		Else
 			If filepath.startswith("-") Then
-				_app.fileimports.AddLast filepath
+				If Not _app.fileimports.Contains(filepath) Then
+					_app.fileimports.AddLast filepath
+				End If
 			End If
 		End If
 
@@ -2305,9 +2292,11 @@ End Rem
 			Local dir:String = ExtractDir(opt_filepath).ToLower()
 			dir = dir[dir.findLast("/") + 1..]
 			If dir.EndsWith(".mod") Then
-				dir = dir.Replace(".mod", "")
+				dir = ""
+			Else
+				dir :+ "_"
 			End If
-			app.munged = "_bb_" + opt_modulename + "_" + StripExt(StripDir(opt_filepath).ToLower())
+			app.munged = "_bb_" + opt_modulename + "_" + dir + StripExt(StripDir(opt_filepath).ToLower())
 		Else
 			' main application file?
 			If opt_apptype Then
@@ -2455,7 +2444,16 @@ End Rem
 		If opt_buildtype = BUILDTYPE_MODULE And opt_ismain
 			ValidateModIdent ident
 		Else If opt_buildtype = BUILDTYPE_MODULE Then
-			munged = opt_modulename + "_" + ident
+			Local dir:String = ExtractDir(opt_filepath).ToLower()
+			dir = dir[dir.findLast("/") + 1..]
+			If dir.EndsWith(".mod") Then
+				dir = ""
+			Else
+				dir :+ "_"
+			End If
+			dir = dir.Replace(".", "_").Replace("-", "_")
+
+			munged = opt_modulename + "_" + dir + ident
 			munged = munged.ToLower().Replace(".", "_").Replace("-", "_")
 		End If
 
@@ -2888,6 +2886,28 @@ Function ParseApp:TAppDecl( path$ )
 	Return app
 End Function
 
+Function MungModuleName:String(ident:Object)
+	If String(ident) Then
+		Local id:String = String(ident)
+		Local mung:String = "__bb_" + id + "_" + id[id.Find(".") + 1..]
+		Return mung.Replace(".", "_").Replace("-", "_")
+	Else
+		Local mdecl:TModuleDecl = TModuleDecl(ident)
+		If mdecl Then
+			Local id:String = mdecl.ident
+			Local dir:String = ExtractDir(mdecl.filepath).ToLower()
+			dir = dir[dir.findLast("/") + 1..]
+			If dir.EndsWith(".mod") Then
+				dir = ""
+			Else
+				dir :+ "_"
+			End If
+			Local mung:String = "__bb_" + id + "_" + dir + id[id.Find(".") + 1..]
+			Return mung.Replace(".", "_").Replace("-", "_")
+		End If
+	End If
+End Function
+
 Function EvalS$( source$,ty:TType )
 
 	Local env:TScopeDecl=New TScopeDecl

+ 7 - 1
type.bmx

@@ -1264,7 +1264,13 @@ Type TFunctionPtrType Extends TPointerType
 		Next
 		
 		' same return type?
-		If Not func.retType.equalsType(fdecl.retType) Return False
+		If Not func.retType.equalsType(fdecl.retType) Then
+			' if function pointer specifies Int return type, our function can specify void...
+			If TIntType(func.retType) And TVoidType(fdecl.retType) Then
+				Return True
+			End If
+			Return False
+		End If
 		
 		Return True
 	End Method