Prechádzať zdrojové kódy

Implemented DefData, ReadData and RestoreData.
Fixed type lookup for when ident matches module name.

woollybah 11 rokov pred
rodič
commit
1cf70df7b8
7 zmenil súbory, kde vykonal 345 pridanie a 9 odobranie
  1. 78 0
      ctranslator.bmx
  2. 83 1
      decl.bmx
  3. 37 4
      expr.bmx
  4. 76 2
      parser.bmx
  5. 63 0
      stmt.bmx
  6. 1 1
      toker.bmx
  7. 7 1
      translator.bmx

+ 78 - 0
ctranslator.bmx

@@ -77,6 +77,36 @@ Type TCTranslator Extends TTranslator
 		If TFunctionPtrType( ty ) Return "~q(~q"
 
 	End Method
+
+	Method TransDefDataType$( ty:TType)
+		If TByteType( ty ) Return "~qb~q"
+		If TShortType( ty ) Return "~qs~q"
+		If TIntType( ty ) Return "~qi~q"
+		If TFloatType( ty ) Return "~qf~q"
+		If TDoubleType( ty ) Return "~qd~q"
+		If TLongType( ty ) Return "~ql~q"
+		If TStringType( ty ) Return "~q$~q"
+	End Method
+
+	Method TransDefDataConversion$(ty:TType)
+		If TByteType( ty ) Return "bbConvertToInt"
+		If TShortType( ty ) Return "bbConvertToInt"
+		If TIntType( ty ) Return "bbConvertToInt"
+		If TFloatType( ty ) Return "bbConvertToFloat"
+		If TDoubleType( ty ) Return "bbConvertToDouble"
+		If TLongType( ty ) Return "bbConvertToLong"
+		If TStringType( ty ) Return "bbConvertToString"
+	End Method
+
+	Method TransDefDataUnionType$(ty:TType)
+		If TByteType( ty ) Return "b"
+		If TShortType( ty ) Return "s"
+		If TIntType( ty ) Return "i"
+		If TFloatType( ty ) Return "f"
+		If TDoubleType( ty ) Return "d"
+		If TLongType( ty ) Return "l"
+		If TStringType( ty ) Return "t"
+	End Method
 	
 	Method TransDebugScopeType$(ty:TType)
 		Local p:String = TransSPointer(ty)
@@ -1840,6 +1870,16 @@ EndRem
 		Emit "bbHandleRelease" + Bra(stmt.expr.Trans()) + ";"
 	End Method
 
+	Method TransRestoreDataStmt$( stmt:TRestoreDataStmt )
+		Emit "_defDataOffset = &_defData[" + TDataLabelExpr(stmt.expr).dataDef.label.index + "];"
+	End Method
+
+	Method TransReadDataStmt$( stmt:TReadDataStmt )
+		For Local expr:TExpr = EachIn stmt.args
+			Emit expr.Trans() + " = " + TransDefDataConversion(expr.exprType) + Bra("_defDataOffset++") + ";"
+		Next
+	End Method
+
 	Method TransFullName:String(decl:TDecl)
 		Local s:String
 		
@@ -3663,6 +3703,11 @@ End Rem
 		For Local ib:TIncbin = EachIn app.incbins
 			Emit "bbIncbinAdd(&" + TStringConst(app.stringConsts.ValueForKey(ib.file)).id + ",&" + app.munged + "_ib_" + ib.id + "," + ib.length + ");"
 		Next
+		
+		' defdata init
+		If Not app.dataDefs.IsEmpty() Then
+			Emit "_defDataOffset = &_defData;"
+		End If
 
 		' initialise globals
 		For Local decl:TGlobalDecl=EachIn app.semantedGlobals
@@ -3729,8 +3774,41 @@ End Rem
 				End If
 			End If
 		Next
+		
+		' defdata
+		EmitDefDataArray(app)
 
 	End Method
+	
+	Method EmitDefDataArray(app:TAppDecl)
+		If Not app.dataDefs.IsEmpty() Then
+			' 
+			Emit "static struct bbDataDef * _defDataOffset;"
+			Emit "static struct bbDataDef _defData[" + TDefDataDecl.count + "]={"
+			
+			For Local decl:TDefDataDecl = EachIn app.dataDefs
+				EmitDefData(decl)
+			Next
+			
+			Emit "};"
+		End If
+	End Method
+
+	Method EmitDefData(decl:TDefDataDecl)
+		For Local i:Int = 0 Until decl.data.length
+			Local expr:TExpr = decl.data[i]
+			
+			Emit "{"
+		
+			Emit TransDefDataType(expr.exprType) + ","
+			
+			Emit "{"
+			Emit "." + TransDefDataUnionType(expr.exprType) + " = " + expr.Trans()
+			Emit "}"
+		
+			Emit "},"
+		Next
+	End Method
 
 	Method EmitIfcImports(impMod:TModuleDecl, processed:TMap)
 

+ 83 - 1
decl.bmx

@@ -727,6 +727,9 @@ Type TScopeDecl Extends TDecl
 'DebugLog Self.ident + "::FindType::" + ident
 		Local decl:Object=(GetDecl( ident ))
 		If decl Then
+			If TModuleDecl(decl) Then
+				decl = TModuleDecl(decl).GetDecl(ident)
+			End If
 			Local ty:TType=TType(decl)
 			If ty
 				If args.Length Err "Wrong number of type arguments"
@@ -1848,6 +1851,65 @@ Type TLoopLabelDecl Extends TDecl
 	
 End Type
 
+Type TDataLabelDecl Extends TDecl
+
+	Field index:Int
+
+	Method Create:TDataLabelDecl( ident$, attrs:Int=0 )
+		Self.ident=ident
+		Self.attrs=attrs
+		Return Self
+	End Method
+	
+	Method OnCopy:TDecl()
+		Return New TDataLabelDecl.Create( ident,attrs )
+	End Method
+	
+	Method OnSemant()
+	End Method
+	
+End Type
+
+Type TDefDataDecl Extends TDecl
+
+	Global count:Int
+
+	Field label:TDataLabelDecl
+	Field data:TExpr[]
+
+	Method Create:TDefDataDecl(data:TExpr[], label:TDataLabelDecl = Null, attrs:Int=0 )
+		Self.data=data
+		Self.label=label
+		Self.attrs=attrs
+		Return Self
+	End Method
+	
+	Method OnCopy:TDecl()
+		Return New TDefDataDecl.Create(TExpr.CopyArgs(data),TDataLabelDecl(label.Copy()),attrs)
+	End Method
+
+	Method OnSemant()
+		If data Then
+			If label Then
+				label.index = count
+			End If
+		
+			For Local i:Int = 0 Until data.length
+				data[i] = data[i].Semant()
+				If Not TConstExpr(data[i]) Then
+					Err "Data items must be numeric or strings"
+				Else
+					' todo : more type tests?
+				End If
+				count :+ 1
+			Next
+		Else
+			' err?
+		End If
+	End Method
+	
+End Type
+
 Const MODULE_STRICT:Int=1
 Const MODULE_SUPERSTRICT:Int=2
 Const MODULE_ACTUALMOD:Int=4
@@ -2015,6 +2077,8 @@ Type TAppDecl Extends TScopeDecl
 	Field incbins:TList = New TList
 	Field genIncBinHeader:Int = False
 	
+	Field dataDefs:TList = New TList
+	
 	Method GetPathPrefix:String()
 		If opt_buildtype = BUILDTYPE_MODULE Then
 			Local prefix:String
@@ -2059,6 +2123,8 @@ Type TAppDecl Extends TScopeDecl
 		_env=Null
 		pushenv Self
 		
+		SemantDataDefs()	
+
 		mainModule.Semant
 
 		mainFunc=mainModule.FindFuncDecl( "LocalMain" )
@@ -2066,7 +2132,7 @@ Type TAppDecl Extends TScopeDecl
 		
 		' FIXME
 		If Not mainFunc Err "Function 'Main' not found."
-		
+	
 		SemantDecls()
 
 		Repeat
@@ -2082,6 +2148,14 @@ Type TAppDecl Extends TScopeDecl
 		Next
 	End Method
 	
+	Method SemantDataDefs()
+		TDefDataDecl.count = 0
+		
+		For Local decl:TDecl = EachIn dataDefs
+			decl.Semant
+		Next
+	End Method
+	
 	Method SemantDecls()
 		For Local decl:TDecl=EachIn mainModule._decls
 
@@ -2158,6 +2232,14 @@ Type TAppDecl Extends TScopeDecl
 		End If
 	End Method
 	
+	Method FindDataLabel:TDecl(ident:String)
+		For Local dd:TDefDataDecl = EachIn dataDefs
+			If dd.label And dd.label.ident.ToLower() = ident.ToLower() Then
+				Return dd
+			End If
+		Next
+	End Method
+	
 End Type
 
 Type TStringConst

+ 37 - 4
expr.bmx

@@ -176,18 +176,18 @@ Type TExpr
 		Err "Can't balance types "+lhs.ToString()+" and "+rhs.ToString()+"."
 	End Method
 
-	Method CopyExpr:TExpr( expr:TExpr )
+	Function CopyExpr:TExpr( expr:TExpr )
 		If Not expr Return Null
 		Return expr.Copy()
-	End Method
+	End Function
 
-	Method CopyArgs:TExpr[]( exprs:TExpr[] )
+	Function CopyArgs:TExpr[]( exprs:TExpr[] )
 		exprs=exprs[..]
 		For Local i:Int=0 Until exprs.Length
 			exprs[i]=CopyExpr( exprs[i] )
 		Next
 		Return exprs
-	End Method
+	End Function
 
 End Type
 
@@ -1825,6 +1825,13 @@ Type TIdentExpr Extends TExpr
 			Return New TLoopLabelExpr.Create(stmt)
 		End If
 		
+		' maybe it's a data label?
+		Local ddecl:TDefDataDecl = TDefDataDecl(_appInstance.FindDataLabel(ident))
+		
+		If ddecl Then
+			Return New TDataLabelExpr.Create(ddecl)
+		End If
+		
 		IdentErr
 	End Method
 
@@ -2223,3 +2230,29 @@ Type TLoopLabelExpr Extends TExpr
 
 End Type
 
+Type TDataLabelExpr Extends TExpr
+
+	Field dataDef:TDefDataDecl
+	
+	Method Create:TDataLabelExpr(dataDef:TDefDataDecl)
+		Self.dataDef = dataDef
+		Return Self
+	End Method
+
+	Method Copy:TExpr()
+		Return New TDataLabelExpr.Create(dataDef)
+	End Method
+
+	Method Semant:TExpr()
+		Return Self
+	End Method
+
+	Method Trans$()
+		DebugStop
+	End Method
+
+	Method Eval$()
+		Return ""
+	End Method
+
+End Type

+ 76 - 2
parser.bmx

@@ -350,6 +350,14 @@ Type TParser
 		Return toker._toke
 	End Method
 
+	Method DescribeToke:String( toke:String )
+		Select toke
+			Case "~n"
+				Return "end-of-line"
+		End Select
+		Return toke
+	End Method
+
 	Method CParse:Int( toke$ )
 		If _toke.ToLower()<>toke
 			Return False
@@ -1422,6 +1430,64 @@ Type TParser
 		_block.AddStmt stmt
 	End Method
 
+	Method ParseDefDataStmt(label:TLoopLabelDecl = Null)
+		Parse "defdata"
+		
+		If AtEos() Then
+			Err "Expecting expression but encountered " + DescribeToke(_toke)
+		End If
+		
+		Local args:TExpr[]
+		Local nargs:Int
+
+		Repeat
+			Local arg:TExpr
+			If _toke And _toke<>"," arg=ParseExpr()
+			If args.Length=nargs args=args + New TExpr[10]
+			args[nargs]=arg
+			nargs:+1
+		Until Not CParse(",")
+		args=args[..nargs]
+		
+		Local dataLabel:TDataLabelDecl
+		If label Then
+			dataLabel = New TDataLabelDecl.Create(label.ident, label.attrs)
+		End If
+		
+		Local decl:TDefDataDecl = New TDefDataDecl.Create(args, dataLabel)
+		
+		_app.dataDefs.AddLast(decl)
+		
+	End Method
+
+	Method ParseReadDataStmt()
+		Parse "readdata"
+
+		Local args:TExpr[]
+		Local nargs:Int
+
+		If Not AtEos() Then
+			Repeat
+				Local arg:TExpr
+				If _toke And _toke<>"," arg=ParseExpr()
+				If args.Length=nargs args=args + New TExpr[10]
+				args[nargs]=arg
+				nargs:+1
+			Until Not CParse(",")
+			args=args[..nargs]
+		End If
+
+		_block.AddStmt New TReadDataStmt.Create( args )
+	End Method
+
+	Method ParseRestoreDataStmt()
+		Parse "restoredata"
+		
+		Local expr:TExpr = ParseExpr()
+
+		_block.AddStmt New TRestoreDataStmt.Create( expr )
+	End Method
+	
 	Method ParseReturnStmt()
 		Parse "return"
 		Local expr:TExpr
@@ -1730,18 +1796,26 @@ Type TParser
 			Case "#"
 				Local decl:TLoopLabelDecl = ParseLoopLabelDecl()
 				NextToke
-				Select _toke
+				Select _toke.ToLower()
 					Case "while"
 						ParseWhileStmt(decl)
 					Case "repeat"
 						ParseRepeatStmt(decl)
 					Case "for"
 						ParseForStmt(decl)
+					Case "defdata"
+						ParseDefDataStmt(decl)
 					Default
-						Err "Expecting loop statement"
+						Err "Labels must appear before a loop or DefData statement"
 				End Select
 			Case "release"
 				ParseReleaseStmt()
+			Case "defdata"
+				ParseDefDataStmt()
+			Case "readdata"
+				ParseReadDataStmt()
+			Case "restoredata"
+				ParseRestoreDataStmt()
 			Default
 				Local expr:TExpr=ParsePrimaryExpr( True )
 

+ 63 - 0
stmt.bmx

@@ -537,3 +537,66 @@ Type TReleaseStmt Extends TStmt
 		Return _trans.TransReleaseStmt( Self )
 	End Method
 End Type
+
+Type TReadDataStmt Extends TStmt
+	Field args:TExpr[]
+
+	Method Create:TReadDataStmt( args:TExpr[] )
+		Self.args=args
+		Return Self
+	End Method
+
+	Method OnCopy:TStmt( scope:TScopeDecl )
+		Return New TReadDataStmt.Create( TExpr.CopyArgs(args) )
+	End Method
+
+	Method OnSemant()
+		If args Then
+			For Local i:Int = 0 Until args.length
+				args[i]=args[i].Semant()
+				
+				If Not TVarExpr(args[i]) And Not TMemberVarExpr(args[i]) And Not TIndexExpr(args[i]) Then
+					Err "Expression must be a variable"
+				End If
+			Next
+		End If
+	End Method
+
+	Method Trans$()
+		Return _trans.TransReadDataStmt( Self )
+	End Method
+	
+End Type
+
+Type TRestoreDataStmt Extends TStmt
+	Field expr:TExpr
+
+	Method Create:TRestoreDataStmt( expr:TExpr )
+		Self.expr=expr
+		Return Self
+	End Method
+
+	Method OnCopy:TStmt( scope:TScopeDecl )
+		Return New TRestoreDataStmt.Create( expr.Copy() )
+	End Method
+
+	Method OnSemant()
+		If Not TIdentExpr(expr) Then
+			' todo : better (more specific) error?
+			Err "Expecting identifier"
+		Else
+			Local label:String = TIdentExpr(expr).ident
+			expr=expr.Semant()
+			
+			If Not expr Then
+				Err "Label '" + label + "' not found"
+			End If
+		End If
+	End Method
+
+	Method Trans$()
+		Return _trans.TransRestoreDataStmt( Self )
+	End Method
+	
+End Type
+

+ 1 - 1
toker.bmx

@@ -53,7 +53,7 @@ Type TToker
 	"and;or;shl;shr;sar;end;if;then;else;elseif;endif;while;wend;repeat;until;forever;"+ ..
 	"for;to;step;next;return;"+ ..
 	"alias;rem;endrem;throw;assert;try;catch;nodebug;incbin;"+ ..
-	"endselect;endmethod;endfunction;endtype;endextern;endtry;pi;release;"
+	"endselect;endmethod;endfunction;endtype;endextern;endtry;pi;release;defdata;readdata;restoredata;"
 
 	Global _symbols$[]=[ "..","[]",":*",":/",":+",":-",":|",":&",":~~",":shr",":shl",":sar",":mod" ]
 	Global _symbols_map$[]=[ "..","[]","*=","/=","+=","-=","|=","&=","^=",">>=", "<<=",">>=","%=" ]

+ 7 - 1
translator.bmx

@@ -1099,7 +1099,13 @@ End Rem
 	End Method
 
 	Method TransEndStmt$( stmt:TEndStmt ) Abstract
-	
+
+	Method TransReleaseStmt$( stmt:TReleaseStmt ) Abstract
+
+	Method TransRestoreDataStmt$( stmt:TRestoreDataStmt ) Abstract
+
+	Method TransReadDataStmt$( stmt:TReadDataStmt ) Abstract
+
 	'module
 	Method TransApp( app:TAppDecl ) Abstract