2
0
Brucey 5 жил өмнө
parent
commit
28e63e7a86
5 өөрчлөгдсөн 228 нэмэгдсэн , 64 устгасан
  1. 55 12
      ctranslator.bmx
  2. 33 12
      decl.bmx
  3. 40 10
      iparser.bmx
  4. 84 27
      parser.bmx
  5. 16 3
      type.bmx

+ 55 - 12
ctranslator.bmx

@@ -240,7 +240,13 @@ Type TCTranslator Extends TTranslator
 			End If
 			Return "BBSTRING" + p
 		End If
-		If TArrayType( ty ) Return "BBARRAY" + p
+		If TArrayType( ty ) Then
+			If TArrayType( ty ).isStatic Then
+				Return TransType(TArrayType( ty ).elemType, ident)
+			Else
+				Return "BBARRAY" + p
+			End If
+		End If
 		If TObjectType( ty ) Then
 			Return TransObject(TObjectType(ty).classdecl) + p
 		End If
@@ -334,9 +340,13 @@ Type TCTranslator Extends TTranslator
 		End If
 		If TArrayType( ty )  Then
 			Local s:String = TransIfcType(TArrayType( ty ).elemType) + "&["
-			For Local i:Int = 0 Until TArrayType( ty ).dims - 1
-				s:+ ","
-			Next
+			If TArrayType( ty ).isStatic Then
+				s :+ TArrayType( ty ).length
+			Else
+				For Local i:Int = 0 Until TArrayType( ty ).dims - 1
+					s:+ ","
+				Next
+			End If
 			Return s + "]" + p
 		End If
 		If TObjectType( ty ) Then
@@ -744,7 +754,11 @@ t:+"NULLNULLNULL"
 			If TInvokeExpr(init) And Not TInvokeExpr(init).invokedWithBraces Then
 				initTrans = "=" + cast + TInvokeExpr(init).decl.munged
 			Else
-				initTrans = "=" + cast + init.Trans()
+				If Not TArrayType(decl.ty) Or Not TArrayType(decl.ty).isStatic Then
+					initTrans = "=" + cast + init.Trans()
+				Else
+					initTrans = "[" + TArrayType(decl.ty).length + "]"
+				End If
 			End If
 		End If
 		
@@ -1818,7 +1832,11 @@ t:+"NULLNULLNULL"
 		Else If IsPointerType( dst, 0, TType.T_POINTER | TType.T_CHAR_PTR | TType.T_SHORT_PTR )
 
 			If TArrayType(src) Then
-				Return Bra(Bra(TransType(dst, "")) + "BBARRAYDATA(" + t + ",1)")
+				If TArrayType(src).isStatic Then
+					Return Bra("&" + Bra(t))
+				Else
+					Return Bra(Bra(TransType(dst, "")) + "BBARRAYDATA(" + t + ",1)")
+				End If
 			End If
 			'If TByteType(src) And Not IsPointerType(src, TType.T_BYTE, TType.T_POINTER) Return Bra("&"+t)
 
@@ -2425,10 +2443,14 @@ t:+"NULLNULLNULL"
 					Return Bra(Bra(TransType(TArrayType( expr.expr.exprType).elemType, "*")) + Bra("BBARRAYDATA(" + t_expr + ",1)")) + "[" + t_index + "]"
 				End If
 			Else
-				If opt_debug Then
-					Return Bra("(" + TransType(expr.exprType, "") + "*)BBARRAYDATAINDEX(" + Bra(t_expr) + "," + Bra(t_expr) + "->dims," + t_index + ")") + "[" + t_index + "]"
+				If TArrayType( expr.expr.exprType ).isStatic Then
+					Return t_expr + "[" + t_index + "]"
 				Else
-					Return Bra("(" + TransType(expr.exprType, "") + "*)BBARRAYDATA(" + t_expr + ",1)") + "[" + t_index + "]"
+					If opt_debug Then
+						Return Bra("(" + TransType(expr.exprType, "") + "*)BBARRAYDATAINDEX(" + Bra(t_expr) + "," + Bra(t_expr) + "->dims," + t_index + ")") + "[" + t_index + "]"
+					Else
+						Return Bra("(" + TransType(expr.exprType, "") + "*)BBARRAYDATA(" + t_expr + ",1)") + "[" + t_index + "]"
+					End If
 				End If
 			End If
 		End If
@@ -3315,6 +3337,9 @@ End Rem
 			If Not TFunctionPtrType(oarg.ty) Then
 				If Not odecl.castTo Then
 					args:+TransType( oarg.ty, arg.munged )+" "+arg.munged
+					If TArrayType(oarg.ty) And TArrayType(oarg.ty).isStatic Then
+						args :+ "[" + TArrayType(oarg.ty).length + "]"
+					End If
 				Else
 					args:+ oarg.castTo + " " + arg.munged
 				End If
@@ -3489,7 +3514,13 @@ End Rem
 				If classDecl.IsExtern() Then
 					Emit TransType(decl.ty, "") + " " + decl.ident + ";"
 				Else
-					Emit TransType(decl.ty, classDecl.actual.munged) + " _" + classDecl.actual.munged.ToLower() + "_" + decl.IdentLower() + ";"
+					Local t:String = TransType(decl.ty, classDecl.actual.munged) + " _" + classDecl.actual.munged.ToLower() + "_" + decl.IdentLower()
+					
+					If TArrayType(decl.ty) And TArrayType(decl.ty).isStatic Then
+						t :+ "[" + decl.init.Trans() + "]"
+					End If
+					
+					Emit t + ";"
 				End If
 			Else
 				If classDecl.IsExtern() Then
@@ -4769,6 +4800,8 @@ End Rem
 							fld :+ "= " + TInvokeExpr(decl.init).decl.munged + ";"
 						Else If TObjectType(decl.ty) Then
 							fld :+ "= " + Bra(TransObject(TObjectType(decl.ty).classDecl)) + decl.init.Trans() + ";"
+						Else If TArrayType(decl.ty) And TArrayType(decl.ty).isStatic Then
+							doEmit = False
 						Else
 							fld :+ "= " + decl.init.Trans() + ";"
 						End If
@@ -5129,7 +5162,11 @@ End Rem
 		' array.length
 		If decl.scope And decl.scope.ident = "___Array" Then
 			If decl.ident = "length" Then
-				Return Bra(variable + "->scales[0]")
+				If TArrayType(exprType) And TArrayType(exprType).isStatic Then
+					Return TArrayType(exprType).length
+				Else
+					Return Bra(variable + "->scales[0]")
+				End If
 			End If
 			If decl.ident = "numberOfDimensions" Then
 				Return Bra(variable + "->dims")
@@ -5399,7 +5436,13 @@ End Rem
 		Local f:String
 		If fieldDecl.IsReadOnly() Then
 			f :+ "@"
-		Else
+		End If
+
+		If fieldDecl.IsStatic() Then
+			f :+ "~~"
+		End If
+		
+		If Not f Then
 			f :+ "."
 		End If
 		f :+ fieldDecl.ident + TransIfcType(fieldDecl.ty, fieldDecl.ModuleScope().IsSuperStrict())

+ 33 - 12
decl.bmx

@@ -27,6 +27,7 @@ Const DECL_PRIVATE:Int=       $020000
 Const DECL_ABSTRACT:Int=      $040000
 Const DECL_FINAL:Int=         $080000
 Const DECL_READ_ONLY:Int=     $000100
+Const DECL_STATIC:Int=      $20000000
 Const DECL_OVERRIDE:Int=    $40000000
 Const DECL_INLINE:Int=      $80000000
 
@@ -193,6 +194,10 @@ Type TDecl
 	Method IsAbstract:Int()
 		Return (attrs & DECL_ABSTRACT)<>0
 	End Method
+
+	Method IsStatic:Int()
+		Return (attrs & DECL_STATIC)<>0
+	End Method
 	
 	Method IsSemanted:Int()
 		Return (attrs & DECL_SEMANTED)<>0
@@ -515,19 +520,24 @@ Type TValDecl Extends TDecl
 					
 					
 				Else
-					If TArrayExpr(declInit) And TArrayType(ty) And TNumericType(TArrayType(ty).elemType) Then
-						TArrayExpr(declInit).toType = TArrayType(ty).elemType
-					End If
-				
-					init=declInit.Copy().SemantAndCast(ty)
-					
-					' check if struct has been initialised
-					If TObjectType(ty) And TObjectType(ty).classDecl.IsStruct() And Not TObjectType(ty).classDecl.IsExtern() Then
+					If TArrayType(ty) And TArrayType(ty).isStatic Then
+						init = declInit.Copy().Semant()
+						TArrayType(ty).length = init.Eval()
+					Else
+						If TArrayExpr(declInit) And TArrayType(ty) And TNumericType(TArrayType(ty).elemType) Then
+							TArrayExpr(declInit).toType = TArrayType(ty).elemType
+						End If
 					
-						' new not used
-						If TConstExpr(init) And Not TConstExpr(init).value And Not IsPointerType(ty,0,TType.T_POINTER) Then
-							' always call the default constructor to init all the fields correctly
-							init = New TNewObjectExpr.Create(ty, Null).Semant()
+						init=declInit.Copy().SemantAndCast(ty)
+						
+						' check if struct has been initialised
+						If TObjectType(ty) And TObjectType(ty).classDecl.IsStruct() And Not TObjectType(ty).classDecl.IsExtern() Then
+						
+							' new not used
+							If TConstExpr(init) And Not TConstExpr(init).value And Not IsPointerType(ty,0,TType.T_POINTER) Then
+								' always call the default constructor to init all the fields correctly
+								init = New TNewObjectExpr.Create(ty, Null).Semant()
+							End If
 						End If
 					End If
 				End If
@@ -693,6 +703,17 @@ Type TArgDecl Extends TLocalDecl
 		If ty Then
 			ty = ty.Semant()
 		End If
+		
+		If attrs & DECL_STATIC Then
+			If Not TArrayType(ty) Then
+				Err "Expecting array"
+			End If
+			
+			If Not TNumericType(TArrayType(ty).elemType) Then
+				Err "Static array elements must be numeric"
+			End If
+		End If
+		
 		If init And Not TConstExpr(init) Then
 			If TCastExpr(init) Then
 				If TConstExpr(TCastExpr(init).expr) Or TNullExpr(TCastExpr(init).expr) Then

+ 40 - 10
iparser.bmx

@@ -733,12 +733,21 @@ Type TIParser
 				'If decl.IsCtor() decl.retTypeExpr=New TObjectType.Create( classDecl )
 				classDecl.InsertDecl decl
 
-			Case ".", "@" ' field
+			Case ".", "@", "~~" ' field			
 				Local d_attrs:Int = decl_attrs | DECL_FIELD
-				If _toker._toke = "@" Then
-					d_attrs :| DECL_READ_ONLY
+				If _toker._toke = "." Then
+					NextToke
+				Else
+					While _toker._toke = "@" Or _toker._toke = "~~"
+						If _toker._toke = "@" Then
+							d_attrs :| DECL_READ_ONLY
+						End If
+						If _toker._toke = "~~" Then
+							d_attrs :| DECL_STATIC
+						End If
+						NextToke
+					Wend
 				End If
-				NextToke
 				Local decl:TDecl= ParseDecl( _toke,d_attrs )
 				classDecl.InsertDecl decl
 			Rem
@@ -1292,8 +1301,8 @@ Type TIParser
 					If CParse( "&" ) Then
 					End If
 
-					While IsArrayDef()
-						ty = ParseArrayType(ty)
+					While IsArrayDef(attrs & DECL_STATIC > 0)
+						ty = ParseArrayType(ty, attrs & DECL_STATIC > 0)
 			
 						If CParse( "&" ) Then
 						End If
@@ -1413,7 +1422,17 @@ End Rem
 	End Method
 
 	' replaces While CParse( "[]" ) sections, with support for multi-dimension arrays
-	Method ParseArrayType:TType(ty:TType)
+	Method ParseArrayType:TType(ty:TType, isStatic:Int = False)
+		If isStatic Then
+			Parse("[")
+			Local expr:TExpr = ParseUnaryExpr()
+			ty = New TArrayType.Create( ty )
+			TArrayType(ty).isStatic = True
+			TArrayType(ty).length = expr.Eval()
+			Parse("]")
+			Return ty
+		End If
+		
 		While True
 			Local dims:Int = 1
 			
@@ -1438,9 +1457,19 @@ End Rem
 		Return ty
 	End Method
 
-	Method IsArrayDef:Int()
+	Method IsArrayDef:Int(isStatic:Int = False)
 		Local isDef:Int = True
 		Local toker:TToker=New TToker.Copy(_toker)
+		If isStatic Then
+			If Not CParseToker(toker, "[") Then
+				Return False
+			End If
+			NextTokeToker(toker)
+			If Not CParseToker(toker, "]") Then
+				Return False
+			End If
+			Return True
+		End If
 		While True
 			If CParseToker(toker, "[]") Then
 				Exit
@@ -1670,8 +1699,9 @@ End Rem
 		If CParse( "&" ) Then
 		End If
 
-		While IsArrayDef()
-			ty = ParseArrayType(ty)
+		While IsArrayDef(attrs & DECL_STATIC > 0)
+
+			ty = ParseArrayType(ty, attrs & DECL_STATIC > 0)
 
 			If CParse( "&" ) Then
 			End If

+ 84 - 27
parser.bmx

@@ -902,8 +902,8 @@ Type TParser Extends TGenProcessor
 		
 		' array or function pointer?
 		Repeat
-			If (_toke = "[" Or _toke = "[]") And IsArrayDef()
-				ty = ParseArrayType(ty)
+			If (_toke = "[" Or _toke = "[]") And IsArrayDef(attr & DECL_STATIC > 0)
+				ty = ParseArrayType(ty, attr & DECL_STATIC > 0)
 			Else If _toke = "(" Then
 				Local args:TArgDecl[] = ParseFuncParamDecl()
 				attr :| ParseCallConvention(attr & DECL_API_STDCALL)
@@ -931,7 +931,16 @@ Type TParser Extends TGenProcessor
 	End Method
 
 	' replaces While CParse( "[]" ) sections, with support for multi-dimension arrays
-	Method ParseArrayType:TType(ty:TType)
+	Method ParseArrayType:TType(ty:TType, isStatic:Int = False)
+		If isStatic Then
+			Parse("[")
+			Local expr:TExpr = ParseUnaryExpr()
+			ty = New TArrayType.Create( ty )
+			TArrayType(ty).isStatic = True
+			TArrayType(ty).length = expr.Eval()
+			Parse("]")
+			Return ty
+		End If
 
 		While True
 			Local dims:Int = 1
@@ -977,9 +986,19 @@ Type TParser Extends TGenProcessor
 		Return False
 	End Method
 	
-	Method IsArrayDef:Int()
+	Method IsArrayDef:Int(isStatic:Int = False)
 		Local isDef:Int = True
 		Local toker:TToker=New TToker.Copy(_toker)
+		If isStatic Then
+			If Not CParseToker(toker, "[") Then
+				Return False
+			End If
+			NextTokeToker(toker)
+			If Not CParseToker(toker, "]") Then
+				Return False
+			End If
+			Return True
+		End If
 		While True
 			'Local dims:Int = 1
 			
@@ -2421,6 +2440,13 @@ End Rem
 
 		SetErr
 
+		If CParse("staticarray") Then
+			If attrs & DECL_STATIC Then
+				Err "Already declared as a static array"
+			End If
+			attrs :| DECL_STATIC
+		End If
+
 		Local id$=ParseIdent()
 		Local ty:TType
 		Local init:TExpr
@@ -2441,26 +2467,35 @@ End Rem
 			ty=ParseDeclType(attrs & DECL_API_STDCALL)
 
 			If CParse( "=" )
+				If (attrs & DECL_STATIC) Then
+					Err "Static arrays cannot be initialized in this way"
+				End If
 				init=ParseExpr()
 			Else If CParse( "[" ) ' an initialised array?
-				Local ln:TExpr[]
-				Repeat
-					If CParse(",") Then
-						ln = ln + [New TNullExpr]
-						Continue
-					End If
-					If CParse("]") Exit
-					ln = ln + [ParseExpr()]
-					If CParse("]") Exit
-					Parse(",")
-				Forever
-				'Parse "]"
-				ty = ParseArrayType(ty)
-				'While CParse( "[]" )
-				'	ty=New TArrayType.Create(ty)
-				'Wend
-				init=New TNewArrayExpr.Create( ty,ln)
-				ty=New TArrayType.Create( ty, ln.length )
+				If (attrs & DECL_STATIC) Then
+					init = ParseExpr()
+					Parse "]"
+					ty=New TArrayType.Create( ty,1,, attrs & DECL_STATIC > 0 )
+				Else
+					Local ln:TExpr[]
+					Repeat
+						If CParse(",") Then
+							ln = ln + [New TNullExpr]
+							Continue
+						End If
+						If CParse("]") Exit
+						ln = ln + [ParseExpr()]
+						If CParse("]") Exit
+						Parse(",")
+					Forever
+					'Parse "]"
+					ty = ParseArrayType(ty)
+					'While CParse( "[]" )
+					'	ty=New TArrayType.Create(ty)
+					'Wend
+					init=New TNewArrayExpr.Create( ty,ln)
+					ty=New TArrayType.Create( ty, ln.length,, attrs & DECL_STATIC > 0 )
+				End If
 			Else If toke <> "const"
 				If toke="global" Or toke="local" Then
 					init=New TConstExpr.Create( ty,"" )
@@ -2549,9 +2584,24 @@ End Rem
 		If toke Parse toke
 
 		If isField Then
-			If CParse("readonly") Then
-				attrs :| DECL_READ_ONLY
-			End If
+			Repeat
+				If CParse("readonly") Then
+					If attrs & DECL_READ_ONLY
+						Err "Duplicate modifier 'ReadOnly'."
+					End If
+
+					attrs :| DECL_READ_ONLY
+
+				Else If CParse("staticarray") Then
+					If attrs & DECL_STATIC
+						Err "Duplicate modifier 'Static'."
+					End If
+
+					attrs :| DECL_STATIC
+				Else
+					Exit
+				End If
+			Forever
 		End If
 
 		Local decls:TList=New TList'<Decl>
@@ -3047,21 +3097,28 @@ End Rem
 		If _toke<>")"
 			Local nargs:Int
 			Repeat
+				Local attrs:Int
+				If CParse("staticarray") Then
+					attrs :| DECL_STATIC
+				End If
 				
 				Local argId$=ParseIdent()
 
-				Local ty:TType=ParseDeclType()
+				Local ty:TType=ParseDeclType(attrs)
 
 				Local init:TExpr
 				
 				' var argument?
 				If CParse("var") Then
+					If attrs & DECL_STATIC Then
+						Err "Unexpected 'Var' for static array argument"
+					End If
 					ty = TType.MapToVarType(ty)
 				Else If CParse( "=" )
 					init=ParseExpr()
 				End If
 				
-				Local arg:TArgDecl=New TArgDecl.Create( argId,ty,init )
+				Local arg:TArgDecl=New TArgDecl.Create( argId,ty,init,attrs )
 				If args.Length=nargs args=args + New TArgDecl[10]
 				args[nargs]=arg
 				nargs:+1

+ 16 - 3
type.bmx

@@ -1406,11 +1406,15 @@ End Type
 Type TArrayType Extends TType
 	Field elemType:TType
 	Field dims:Int
+	Field isStatic:Int
+	Field length:String
 	
-	Method Create:TArrayType( elemType:TType, dims:Int = 1, flags:Int = 0 )
+	Method Create:TArrayType( elemType:TType, dims:Int = 1, flags:Int = 0, isStatic:Int = False, length:Int = 0 )
 		Self.elemType=elemType
 		Self.dims = dims
 		Self._flags = flags
+		Self.isStatic = isStatic
+		Self.length = length
 		Return Self
 	End Method
 	
@@ -1422,12 +1426,13 @@ Type TArrayType Extends TType
 		
 	Method EqualsType:Int( ty:TType )
 		Local arrayType:TArrayType=TArrayType( ty )
-		Return arrayType And elemType.EqualsType( arrayType.elemType ) And dims = arrayType.dims
+		Return arrayType And elemType.EqualsType( arrayType.elemType ) And dims = arrayType.dims And arrayType.isStatic = isStatic And arrayType.length = length
 	End Method
 	
 	Method ExtendsType:Int( ty:TType, noExtendString:Int = False, widensTest:Int = False )
 		Local arrayType:TArrayType=TArrayType( ty )
 		Return (arrayType And dims = arrayType.dims And ..
+			(arrayType.isStatic = isStatic And arrayType.length = length) And ..
 			( TVoidType( elemType ) ..
 				Or elemType.EqualsType( arrayType.elemType ) ..
 				Or ((TObjectType(elemType) Or TStringType(elemType) Or TArrayType(elemType)) And ..
@@ -1453,11 +1458,19 @@ Type TArrayType Extends TType
 		Local ty:TArrayType = New TArrayType
 		ty.elemType = elemType
 		ty.dims = dims
+		ty.isStatic = isStatic
+		ty.length = length
 		Return ty
 	End Method
 
 	Method ToString$()
-		Return elemType.ToString()+" Array"
+		Local t:String = elemType.ToString()
+		If isStatic Then
+			t :+ " StaticArray[" + length + "]"
+		Else
+			t :+ " Array"
+		End If
+		Return t
 	End Method
 	
 	Method DistanceToType:Int(ty:TType)