config.bmx 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. ' Copyright (c) 2013-2016 Bruce A Henderson
  2. '
  3. ' Based on the public domain Monkey "trans" by Mark Sibly
  4. '
  5. ' This software is provided 'as-is', without any express or implied
  6. ' warranty. In no event will the authors be held liable for any damages
  7. ' arising from the use of this software.
  8. '
  9. ' Permission is granted to anyone to use this software for any purpose,
  10. ' including commercial applications, and to alter it and redistribute it
  11. ' freely, subject to the following restrictions:
  12. '
  13. ' 1. The origin of this software must not be misrepresented; you must not
  14. ' claim that you wrote the original software. If you use this software
  15. ' in a product, an acknowledgment in the product documentation would be
  16. ' appreciated but is not required.
  17. '
  18. ' 2. Altered source versions must be plainly marked as such, and must not be
  19. ' misrepresented as being the original software.
  20. '
  21. ' 3. This notice may not be removed or altered from any source
  22. ' distribution.
  23. '
  24. SuperStrict
  25. Import BRL.LinkedList
  26. Import BRL.Map
  27. Import BRL.FileSystem
  28. Import "options.bmx"
  29. Import "base.stringhelper.bmx"
  30. ' debugging help
  31. Const DEBUG:Int = False
  32. Const ABORT_ON_NULL:Int = True
  33. Const PROFILER:Int = False
  34. Const DEBUGSTOP_ON_ERROR:Int = False
  35. Global ENV_LANG$
  36. Global _errInfo$
  37. Global _errStack:TList = New TList
  38. ' bytes offset to the first field
  39. Global OBJECT_BASE_OFFSET:Int = 8
  40. ' 4 bytes on 32-bit, 8 bytes on 64-bit
  41. Global POINTER_SIZE:Int = 4
  42. Global _symbols$[]=[ "..","[]",":*",":/",":+",":-",":|",":&",":~~",":shr",":shl",":sar",":mod"]
  43. Global _symbols_map$[]=[ "..","[]","*=","/=","+=","-=","|=","&=","^=",">>=", "<<=",">>=","%=" ]
  44. Function PushErr( errInfo$ )
  45. _errStack.AddLast _errInfo
  46. _errInfo=errInfo
  47. End Function
  48. Function PopErr()
  49. _errInfo=String(_errStack.RemoveLast())
  50. End Function
  51. Function Err( err$ )
  52. If DEBUGSTOP_ON_ERROR Then
  53. DebugStop ' useful for debugging!
  54. End If
  55. Throw "Compile Error: "+err + "~n" + _errInfo + "~n"
  56. End Function
  57. Function Warn( err$ )
  58. 'If DEBUGSTOP_ON_ERROR Then
  59. ' DebugStop ' useful for debugging!
  60. 'End If
  61. Print "Compile Warning: "+err + "~n" + _errInfo + "~n"
  62. End Function
  63. Function FormatError:String(path:String, line:Int, char:Int)
  64. Return "[" + path + ";" + line + ";" + char + "]"
  65. End Function
  66. Function InternalErr()
  67. If DEBUGSTOP_ON_ERROR Then
  68. DebugStop ' useful for debugging!
  69. End If
  70. Throw "Internal Error.~n" + _errInfo + "~n"
  71. End Function
  72. Function IsSpace:Int( ch:Int )
  73. Return ch<=Asc(" ") Or ch=$A0 ' NO-BREAK SPACE (U+00A0)
  74. End Function
  75. Function IsDigit:Int( ch:Int )
  76. Return ch>=Asc("0") And ch<=Asc("9")
  77. End Function
  78. Function IsAlpha:Int( ch:Int )
  79. Return (ch>=Asc("A") And ch<=Asc("Z")) Or (ch>=Asc("a") And ch<=Asc("z"))
  80. End Function
  81. Function IsBinDigit:Int( ch:Int )
  82. Return ch=Asc("0") Or ch=Asc("1")
  83. End Function
  84. Function IsHexDigit:Int( ch:Int )
  85. Return IsDigit(ch) Or (ch>=Asc("A") And ch<=Asc("F")) Or (ch>=Asc("a") And ch<=Asc("f"))
  86. End Function
  87. Function Todo()
  88. Err "TODO!"
  89. End Function
  90. Function IsStandardFunc:Int(func:String)
  91. func = func.ToLower()
  92. Global funcs:String = ";isalnum;isalpha;isascii;isblank;iscntrl;isdigit;isgraph;islower;isprint;ispunct;isspace;isupper;isxdigit;" + ..
  93. "strlen;_wgetenv;_wputenv;"
  94. Return funcs.Find(func) > 0
  95. End Function
  96. Function mapSymbol:String(sym:String)
  97. For Local i:Int = 0 Until _symbols.length
  98. If sym = _symbols[i] Then
  99. Return _symbols_map[i]
  100. End If
  101. Next
  102. Return sym
  103. End Function
  104. 'enquote depending on ENV_LANG
  105. '
  106. Function LangEnquote$( str$ )
  107. str=EscapeString(str)
  108. ' str=str.Replace( "~0","\0" ) 'Fix me?
  109. For Local i:Int=0 Until str.Length
  110. If str[i]>=32 And str[i]<128 Continue
  111. Local t$,n:Int=str[i]
  112. While n
  113. Local c:Int=(n&15)+48
  114. If c>=58 c:+97-58
  115. t=Chr( c )+t
  116. n=(n Shr 4) & $0fffffff
  117. Wend
  118. If Not t t="0"
  119. If ENV_LANG = "cpp" Then
  120. 'Case "cpp"
  121. t="~q~q\x"+t+"~q~q"
  122. Else
  123. t="\u"+("0000"+t)[-4..]
  124. End If
  125. str=str[..i]+t+str[i+1..]
  126. i:+t.Length-1
  127. Next
  128. str="~q"+str+"~q"
  129. If ENV_LANG="cpp" str="L"+str
  130. Return str
  131. End Function
  132. Function EscapeString$(str$)
  133. str=str.Replace( "\","\\" )
  134. str=str.Replace( "~q","\~q" )
  135. str=str.Replace( "~n","\n" )
  136. str=str.Replace( "~r","\r" )
  137. str=str.Replace( "~t","\t" )
  138. Return str
  139. End Function
  140. Function BmxEnquote$( str$ )
  141. str=str.Replace( "~~","~~~~" )
  142. str=str.Replace( "~q","~~q" )
  143. str=str.Replace( "~n","~~n" )
  144. str=str.Replace( "~r","~~r" )
  145. str=str.Replace( "~t","~~t" )
  146. str=str.Replace( "~0","~~0" )
  147. str="~q"+str+"~q"
  148. Return str
  149. End Function
  150. Function BmxUnquote$( str$, unicodeConvert:Int = False )
  151. If str.length = 1 Or str[str.length - 1] <> Asc("~q") Then
  152. Err "Expecting expression but encountered malformed string literal"
  153. End If
  154. str=str[1..str.Length-1]
  155. If unicodeConvert Then
  156. Local pos:Int = str.Find("~~")
  157. While pos <> -1
  158. If pos + 1 < str.length Then
  159. If str[pos + 1] >= Asc("1") And str[pos + 1] <= Asc("9") Then
  160. Local p2:Int = str.Find("~~", pos + 1)
  161. If p2 <> -1 Then
  162. Local s:String = Chr(str[pos + 1.. p2].ToInt())
  163. str = str[..pos] + s + str[p2 + 1..]
  164. End If
  165. End If
  166. End If
  167. pos = str.Find("~~", pos + 1)
  168. Wend
  169. End If
  170. str=str.Replace( "~~~~","~~z" ) 'a bit dodgy - uses bad esc sequence ~z
  171. str=str.Replace( "~~q","~q" )
  172. str=str.Replace( "~~n","~n" )
  173. str=str.Replace( "~~r","~r" )
  174. str=str.Replace( "~~t","~t" )
  175. str=str.Replace( "~~0","~0" )
  176. str=str.Replace( "~~z","~~" )
  177. Return str
  178. End Function
  179. Type TStack Extends TList
  180. Method Push(obj:Object)
  181. AddFirst(obj)
  182. End Method
  183. Method Length:Int()
  184. Return count()
  185. End Method
  186. Method Get:Object(index:Int)
  187. Return ValueAtIndex(index)
  188. End Method
  189. Method Pop:Object()
  190. Return RemoveFirst()
  191. End Method
  192. End Type
  193. Type TStringList Extends TList
  194. Method Join:String(s:String)
  195. Local arr:String[] = New String[count()]
  196. Local index:Int
  197. For Local t:String = EachIn Self
  198. arr[index] = t
  199. index :+ 1
  200. Next
  201. Return s.Join(arr)
  202. End Method
  203. End Type
  204. Type TKeyValue
  205. Field key:Object
  206. Field value:Object
  207. Method Create:TKeyValue(key:Object,value:Object)
  208. Self.key = key
  209. Self.value = value
  210. Return Self
  211. End Method
  212. Method Compare:Int(other:Object)
  213. If Not TKeyValue(other) Return 0
  214. Return key.Compare(TKeyValue(other).key)
  215. End Method
  216. End Type
  217. Type TUnorderedMap
  218. Field list:TList = New TList
  219. Field map:TMap = New TMap
  220. Field valuesList:TList = New TList
  221. Method Insert( key:Object,value:Object )
  222. list.AddLAst(New TKeyValue.Create(key, value))
  223. valuesList.AddLast(value)
  224. map.Insert(key, value)
  225. End Method
  226. Method Keys:TList()
  227. Local klist:TList = New TList
  228. For Local kv:TKeyValue = EachIn list
  229. klist.AddLast(kv.key)
  230. Next
  231. Return klist
  232. End Method
  233. Method Values:TList()
  234. 'Local vlist:TList = New TList
  235. 'For Local kv:TKeyValue = EachIn list
  236. ' vlist.AddLast(kv.value)
  237. 'Next
  238. Return valuesList
  239. End Method
  240. Method Contains:Int( key:Object )
  241. Return map.Contains(key)
  242. End Method
  243. Method ValueForKey:Object( key:Object )
  244. Return map.ValueForKey(key)
  245. End Method
  246. End Type
  247. Function MakeKeywords:String()
  248. Local keywords:String
  249. keywords :+ "import brl.classes~n"
  250. keywords :+ "Asc%(v$)=~qbrl_blitz_keywords_asc~q~n"
  251. keywords :+ "Sgn#(v#)=~qbrl_blitz_keywords_sgn~q~n"
  252. keywords :+ "Chr$(v%)=~qbrl_blitz_keywords_chr~q~n"
  253. keywords :+ "Len%(v:Object)=~qbrl_blitz_keywords_len~q~n"
  254. keywords :+ "Min%(v1%,v2%)=~qbrl_blitz_keywords_min~q~n"
  255. keywords :+ "Max%(v1%,v2%)=~qbrl_blitz_keywords_max~q~n"
  256. 'keywords :+ "SizeOf%(v%)=~qbrl_blitz_keywords_sizeof~q~n"
  257. 'keywords :+ "Incbin(v$)=~qbrl_blitz_keywords_incbin~q~n"
  258. keywords :+ "IncbinPtr@*(v$)=~qbbIncbinPtr~q~n"
  259. keywords :+ "IncbinLen%(v$)=~qbbIncbinLen~q~n"
  260. Return keywords
  261. End Function
  262. Function FilePath:String(path:String)
  263. Local baseDir:String = ExtractDir(path)
  264. Local bmxDir:String = baseDir + "/.bmx"
  265. If FileType(bmxDir) <> FILETYPE_DIR Then
  266. Throw "Missing : " + bmxDir
  267. End If
  268. Return bmxDir
  269. End Function
  270. Function BuildHeaderName:String(path:String)
  271. If opt_buildtype = BUILDTYPE_MODULE Then
  272. path = opt_modulename + "_" + StripDir(path)
  273. Else
  274. Local dir:String = ExtractDir(path).ToLower().Replace("/.bmx","")
  275. dir = dir[dir.findLast("/") + 1..]
  276. If dir.EndsWith(".mod") Then
  277. dir = dir.Replace(".mod", "")
  278. End If
  279. Local file:String = StripDir(path).ToLower()
  280. path = dir + "_" + file
  281. End If
  282. Return TStringHelper.Sanitize(path, , True)
  283. End Function
  284. Rem
  285. bbdoc: Get the header file name from a given module ident, optionally with include path.
  286. End Rem
  287. Function ModuleHeaderFromIdent:String(ident:String, includePath:Int = False)
  288. Local ns:String = ident[..ident.find(".")]
  289. Local name:String = ident[ident.find(".") + 1..]
  290. Local file:String = name + ".bmx" + FileMung() + ".h"
  291. If includePath Then
  292. file = ns + ".mod/" + name + ".mod/.bmx/" + file
  293. End If
  294. Return file
  295. End Function
  296. Function HeaderFile:String(path:String, mung:String)
  297. Local fileDir:String = FilePath(path)
  298. Local file:String = StripDir(path)
  299. Return fileDir + "/" + file + mung + ".h"
  300. End Function
  301. Function OutputFilePath:String(path:String, mung:String, suffix:String, bmxDir:Int = False)
  302. Local fileDir:String = FilePath(path)
  303. If bmxDir Then
  304. fileDir :+ "/.bmx"
  305. End If
  306. Local file:String = StripDir(path)
  307. Return fileDir + "/" + file + mung + "." + suffix
  308. End Function
  309. Function FileMung:String(makeApp:Int = False)
  310. Local m:String = "."
  311. If makeApp Then
  312. Select opt_apptype
  313. Case APPTYPE_CONSOLE
  314. m :+ "console."
  315. Case APPTYPE_GUI
  316. m :+ "gui."
  317. End Select
  318. End If
  319. If opt_release Then
  320. m :+ "release"
  321. Else
  322. m :+ "debug"
  323. End If
  324. If opt_threaded Then
  325. m :+ ".mt"
  326. End If
  327. m :+ "." + opt_platform
  328. m :+ "." + opt_arch
  329. Return m
  330. End Function
  331. Function HeaderComment:String()
  332. ' TODO
  333. End Function