Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

202 řádky
5.1KB

  1. #!/usr/bin/env ruby
  2. # frozen_string_literal: true
  3. ## ---------------------------------------------------------------------------|
  4. ##
  5. ## Distributed under the CC0 public domain license.
  6. ## By Alison G. Watson. Attribution is encouraged, though not required.
  7. ## See licenses/cc0.txt for more information.
  8. ##
  9. ## ---------------------------------------------------------------------------|
  10. ##
  11. ## Upgrade info text compiler.
  12. ##
  13. ## ---------------------------------------------------------------------------|
  14. require_relative "corinth.rb"
  15. def zstr s
  16. s.gsub "\0", "\\\\0"
  17. end
  18. def generate_strhash_switch kvp, ind = 1, it = 0
  19. res = String.new
  20. itx = " "
  21. res.concat "#{itx*ind}switch(#{%w"fst snd thd"[it]}) {\n"
  22. for key, nxt in kvp
  23. ind += 1
  24. z0 = zstr key[0]
  25. z1 = zstr key[1]
  26. z2 = zstr key[2]
  27. z3 = zstr key[3]
  28. res.concat "#{itx*ind}case FourCC('#{z0}', '#{z1}', '#{z2}', '#{z3}'):\n"
  29. ind += 1
  30. if nxt.is_a? String
  31. res.concat "#{itx*ind}return #{nxt};\n"
  32. else
  33. res.concat generate_strhash_switch nxt, ind, it + 1
  34. res.concat "#{itx*ind}break;\n"
  35. end
  36. ind -= 2
  37. end
  38. res.concat "#{itx*ind}}\n"
  39. res
  40. end
  41. def generate_strhasher keys, pfx
  42. sorted_keys = {}
  43. for key in keys
  44. fst = key[0... 4].to_s.ljust 4, "\0"
  45. snd = key[4... 8].to_s.ljust 4, "\0"
  46. thd = key[8...12].to_s.ljust 4, "\0"
  47. sorted_keys[fst] = {} unless sorted_keys[fst]
  48. sorted_keys[fst][snd] = {} unless sorted_keys[fst][snd]
  49. sorted_keys[fst][snd][thd] = pfx + key unless sorted_keys[fst][snd][thd]
  50. end
  51. generate_strhash_switch sorted_keys
  52. end
  53. common_main do
  54. tks = tokenize ARGV.shift
  55. upgrades = {}
  56. category = ""
  57. loop do
  58. tok = tks.next.expect_in_top [:colon, :plus, :eof]
  59. case tok.type
  60. when :colon
  61. tok = tks.next.expect_after tok, :identi
  62. category = "UC_" + tok.text
  63. when :plus
  64. tok = tks.next.expect_after tok, :identi
  65. una = tok.text
  66. tok = tks.next.expect_after tok, :identi
  67. inf = if tok.text == "N/A" then "snil" else 's"' + tok.text + '"' end
  68. scr = tks.peek_or :number, "0"
  69. pcl = []
  70. tks.while_drop :bar do
  71. tok = tks.next.expect_after tok, :identi
  72. pcl.push tok.text
  73. end
  74. pcl = pcl.join " | "
  75. flg = []
  76. tok = tks.next.expect_after tok, :identi
  77. for c, i in tok.text.chars.each_with_index
  78. if c == "-" then next
  79. elsif c == "A" && i == 0 then flg.push c
  80. elsif c == "D" && i == 1 then flg.push c
  81. elsif c == "U" && i == 2 then flg.push c
  82. elsif c == "R" && i == 3 then flg.push c
  83. elsif c == "E" && i == 4 then flg.push c
  84. else tok.raise_kw "funcs" end
  85. end
  86. prf = tks.peek_or :number, "0"
  87. mul = tks.peek_or :period, "0" do |orig|
  88. tok = tks.next.expect_after orig, :number
  89. tok.text
  90. end
  91. grp = tks.peek_or :assign, "0" do |orig|
  92. tok = tks.next.expect_after orig, :identi
  93. "UG_" + tok.text
  94. end
  95. req = tks.peek_or :modulo, "0" do |orig|
  96. req = []
  97. tok = orig
  98. tks.while_drop :bar do
  99. tok = tks.next.expect_after tok, :identi
  100. req.push "dst_bit(UR_" + tok.text + ")"
  101. end
  102. req.join " | "
  103. end
  104. upgrades[una] = {inf: inf, scr: scr, pcl: pcl, prf: prf, grp: grp,
  105. req: req, mul: mul, flg: flg, cat: category}
  106. when :eof
  107. break
  108. end
  109. end
  110. open(ARGV.shift, "wt").puts <<_end_h_; open(ARGV.shift, "wt").puts <<_end_c_; open(ARGV.shift, "wt").puts <<_end_f_
  111. #{generated_header "upgc"}
  112. /* decompat-out pk7/lzscript/Constants/u_names.zsc */
  113. enum /* UpgradeName */ {
  114. #{
  115. res = String.new
  116. upgrades.each_key do |una| res.concat " UPGR_#{una},\n" end
  117. res.concat " UPGR_MAX"
  118. res
  119. }
  120. };
  121. /* EOF */
  122. _end_h_
  123. #{generated_header "upgc"}
  124. #include "u_common.h"
  125. /* Extern Objects ---------------------------------------------------------- */
  126. struct upgradeinfo upgrinfo[UPGR_MAX] = {
  127. #{
  128. res = String.new
  129. for una, upg in upgrades
  130. res.concat %( {{s"#{una}", #{upg[:inf]}, #{upg[:scr]}}, #{upg[:pcl]}, #{upg[:cat]}, #{upg[:prf]}, #{upg[:grp]}, #{upg[:req]}, #{upg[:mul]}, UPGR_#{una}},\n)
  131. end
  132. res
  133. }
  134. };
  135. i32 Upgr_StrToEnum(cstr s) {
  136. u32 fst = FourCCPtr(s + 0);
  137. u32 snd = FourCCPtr(s + 4);
  138. u32 thd = FourCCPtr(s + 8);
  139. #{generate_strhasher upgrades.keys, "UPGR_"}
  140. return UPGR_MAX;
  141. }
  142. cstr Upgr_EnumToStr(i32 n) {
  143. switch(n) {
  144. #{
  145. res = String.new
  146. upgrades.each_key do |una| res.concat " case UPGR_#{una}: return \"#{zstr una.ljust 12, "\0"}\";\n" end
  147. res
  148. }
  149. }
  150. return nil;
  151. }
  152. /* EOF */
  153. _end_c_
  154. #{generated_header "upgc"}
  155. #include "u_func_beg.h"
  156. #{
  157. res = String.new
  158. for una, upg in upgrades
  159. unless upg[:flg].empty?
  160. flg = upg[:flg].map do |a| " #{a}(#{una})\n" end.join
  161. res.concat "Case(" + una +")\n" + flg
  162. end
  163. end
  164. res
  165. }
  166. #include "u_func_end.h"
  167. /* EOF */
  168. _end_f_
  169. end
  170. ## EOF