فهرست منبع

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

woollybah 11 سال پیش
والد
کامیت
109b3c127b
7فایلهای تغییر یافته به همراه180 افزوده شده و 50 حذف شده
  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