Compiler.ob07 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. MODULE Compiler;
  2. IMPORT ST := STATEMENTS, PARS, UTILS IN "./utils/UTILS.ob07", PATHS, PROG, C := CONSOLE,
  3. ERRORS, STRINGS, WRITER, MSP430, THUMB, TARGETS, SCAN, TEXTDRV;
  4. CONST
  5. DEF_WINDOWS = "WINDOWS";
  6. DEF_LINUX = "LINUX";
  7. DEF_KOLIBRIOS = "KOLIBRIOS";
  8. DEF_CPU_X86 = "CPU_X86";
  9. DEF_CPU_X8664 = "CPU_X8664";
  10. PROCEDURE keys (VAR options: PROG.OPTIONS; VAR out: PARS.PATH);
  11. VAR
  12. param: PARS.PATH;
  13. i, j: INTEGER;
  14. _end: BOOLEAN;
  15. value: INTEGER;
  16. minor,
  17. major: INTEGER;
  18. checking: SET;
  19. PROCEDURE getVal (VAR i: INTEGER; VAR value: INTEGER);
  20. VAR
  21. param: PARS.PATH;
  22. val: INTEGER;
  23. BEGIN
  24. INC(i);
  25. UTILS.GetArg(i, param);
  26. IF STRINGS.StrToInt(param, val) THEN
  27. value := val
  28. END;
  29. IF param[0] = "-" THEN
  30. DEC(i)
  31. END
  32. END getVal;
  33. BEGIN
  34. options.lower := TRUE;
  35. out := "";
  36. checking := options.checking;
  37. _end := FALSE;
  38. i := 3;
  39. REPEAT
  40. UTILS.GetArg(i, param);
  41. IF param = "-stk" THEN
  42. INC(i);
  43. UTILS.GetArg(i, param);
  44. IF STRINGS.StrToInt(param, value) & (1 <= value) & (value <= 32) THEN
  45. options.stack := value
  46. END;
  47. IF param[0] = "-" THEN
  48. DEC(i)
  49. END
  50. ELSIF param = "-fa" THEN
  51. getVal(i, options.PE32FileAlignment)
  52. ELSIF param = "-out" THEN
  53. INC(i);
  54. UTILS.GetArg(i, param);
  55. IF param[0] = "-" THEN
  56. DEC(i)
  57. ELSE
  58. out := param
  59. END
  60. ELSIF param = "-tab" THEN
  61. getVal(i, options.tab)
  62. ELSIF param = "-ram" THEN
  63. getVal(i, options.ram)
  64. ELSIF param = "-rom" THEN
  65. getVal(i, options.rom)
  66. ELSIF param = "-nochk" THEN
  67. INC(i);
  68. UTILS.GetArg(i, param);
  69. IF param[0] = "-" THEN
  70. DEC(i)
  71. ELSE
  72. j := 0;
  73. WHILE param[j] # 0X DO
  74. IF param[j] = "p" THEN
  75. EXCL(checking, ST.chkPTR)
  76. ELSIF param[j] = "t" THEN
  77. EXCL(checking, ST.chkGUARD)
  78. ELSIF param[j] = "i" THEN
  79. EXCL(checking, ST.chkIDX)
  80. ELSIF param[j] = "b" THEN
  81. EXCL(checking, ST.chkBYTE)
  82. ELSIF param[j] = "c" THEN
  83. EXCL(checking, ST.chkCHR)
  84. ELSIF param[j] = "w" THEN
  85. EXCL(checking, ST.chkWCHR)
  86. ELSIF param[j] = "r" THEN
  87. EXCL(checking, ST.chkCHR);
  88. EXCL(checking, ST.chkWCHR);
  89. EXCL(checking, ST.chkBYTE)
  90. ELSIF param[j] = "s" THEN
  91. EXCL(checking, ST.chkSTK)
  92. ELSIF param[j] = "a" THEN
  93. checking := {}
  94. END;
  95. INC(j)
  96. END;
  97. END
  98. ELSIF param = "-ver" THEN
  99. INC(i);
  100. UTILS.GetArg(i, param);
  101. IF STRINGS.StrToVer(param, major, minor) THEN
  102. options.version := major * 65536 + minor
  103. END;
  104. IF param[0] = "-" THEN
  105. DEC(i)
  106. END
  107. ELSIF param = "-lower" THEN
  108. options.lower := TRUE
  109. ELSIF param = "-upper" THEN
  110. options.lower := FALSE
  111. ELSIF param = "-pic" THEN
  112. options.pic := TRUE
  113. ELSIF param = "-uses" THEN
  114. options.uses := TRUE
  115. ELSIF param = "-def" THEN
  116. INC(i);
  117. UTILS.GetArg(i, param);
  118. SCAN.NewDef(param)
  119. ELSIF param = "" THEN
  120. _end := TRUE
  121. ELSE
  122. ERRORS.BadParam(param)
  123. END;
  124. INC(i)
  125. UNTIL _end;
  126. options.checking := checking
  127. END keys;
  128. PROCEDURE OutTargetItem (target: INTEGER; text: ARRAY OF CHAR);
  129. VAR
  130. width: INTEGER;
  131. BEGIN
  132. width := 15;
  133. width := width - LENGTH(TARGETS.Targets[target].ComLinePar) - 4;
  134. C.String(" '"); C.String(TARGETS.Targets[target].ComLinePar); C.String("'");
  135. WHILE width > 0 DO
  136. C.String(20X);
  137. DEC(width)
  138. END;
  139. C.StringLn(text)
  140. END OutTargetItem;
  141. PROCEDURE main;
  142. VAR
  143. path: PARS.PATH;
  144. inname: PARS.PATH;
  145. ext: PARS.PATH;
  146. app_path: PARS.PATH;
  147. lib_path: PARS.PATH;
  148. modname: PARS.PATH;
  149. outname: PARS.PATH;
  150. param: PARS.PATH;
  151. temp: PARS.PATH;
  152. target: INTEGER;
  153. time: INTEGER;
  154. options: PROG.OPTIONS;
  155. BEGIN
  156. options.stack := 2;
  157. options.tab := TEXTDRV.defTabSize;
  158. options.version := 65536;
  159. options.pic := FALSE;
  160. options.lower := FALSE;
  161. options.uses := FALSE;
  162. options.checking := ST.chkALL;
  163. PATHS.GetCurrentDirectory(app_path);
  164. UTILS.GetArg(0, temp);
  165. PATHS.split(temp, path, modname, ext);
  166. IF PATHS.isRelative(path) THEN
  167. PATHS.RelPath(app_path, path, temp);
  168. path := temp
  169. END;
  170. lib_path := path;
  171. UTILS.GetArg(1, inname);
  172. STRINGS.replace(inname, "\", UTILS.slash);
  173. STRINGS.replace(inname, "/", UTILS.slash);
  174. C.Ln;
  175. C.String("Akron Oberon Compiler v"); C.Int(UTILS.vMajor); C.String("."); C.Int2(UTILS.vMinor);
  176. C.String(" ("); C.Int(UTILS.bit_depth); C.StringLn("-bit) " + UTILS.Date);
  177. C.StringLn("Copyright (c) 2018-2023, Anton Krotov");
  178. IF inname = "" THEN
  179. C.Ln;
  180. C.StringLn("Usage: Compiler <main module> <target> [optional settings]"); C.Ln;
  181. C.StringLn("target =");
  182. IF UTILS.bit_depth = 64 THEN
  183. OutTargetItem(TARGETS.Win64C, "Windows64 Console");
  184. OutTargetItem(TARGETS.Win64GUI, "Windows64 GUI");
  185. OutTargetItem(TARGETS.Win64DLL, "Windows64 DLL");
  186. OutTargetItem(TARGETS.Linux64, "Linux64 Exec");
  187. OutTargetItem(TARGETS.Linux64SO, "Linux64 SO")
  188. END;
  189. OutTargetItem(TARGETS.Win32C, "Windows32 Console");
  190. OutTargetItem(TARGETS.Win32GUI, "Windows32 GUI");
  191. OutTargetItem(TARGETS.Win32DLL, "Windows32 DLL");
  192. OutTargetItem(TARGETS.Linux32, "Linux32 Exec");
  193. OutTargetItem(TARGETS.Linux32SO, "Linux32 SO");
  194. OutTargetItem(TARGETS.KolibriOS, "KolibriOS Exec");
  195. OutTargetItem(TARGETS.KolibriOSDLL, "KolibriOS DLL");
  196. OutTargetItem(TARGETS.MSP430, "MSP430x{1,2}xx microcontrollers");
  197. OutTargetItem(TARGETS.STM32CM3, "STM32 Cortex-M3 microcontrollers");
  198. C.Ln;
  199. C.StringLn("optional settings:"); C.Ln;
  200. C.StringLn(" -out <file name> output"); C.Ln;
  201. C.StringLn(" -stk <size> set size of stack in Mbytes (Windows, Linux, KolibriOS)"); C.Ln;
  202. C.StringLn(" -nochk <'ptibcwra'> disable runtime checking (pointers, types, indexes,");
  203. C.StringLn(" BYTE, CHR, WCHR)"); C.Ln;
  204. C.StringLn(" -lower allow lower case for keywords (default)"); C.Ln;
  205. C.StringLn(" -upper only upper case for keywords"); C.Ln;
  206. C.StringLn(" -def <identifier> define conditional compilation symbol"); C.Ln;
  207. C.StringLn(" -ver <major.minor> set version of program (KolibriOS DLL)"); C.Ln;
  208. C.StringLn(" -ram <size> set size of RAM in bytes (MSP430) or Kbytes (STM32)"); C.Ln;
  209. C.StringLn(" -rom <size> set size of ROM in bytes (MSP430) or Kbytes (STM32)"); C.Ln;
  210. C.StringLn(" -tab <width> set width for tabs"); C.Ln;
  211. C.StringLn(" -uses list imported modules"); C.Ln;
  212. C.StringLn(" -fa <size> set PE32 file alignment {512 (def.), 1024, 2048, 4096}"); C.Ln;
  213. UTILS.Exit(0)
  214. END;
  215. C.Dashes;
  216. PATHS.split(inname, path, modname, ext);
  217. IF ext # UTILS.FILE_EXT THEN
  218. ERRORS.Error(207)
  219. END;
  220. IF PATHS.isRelative(path) THEN
  221. PATHS.RelPath(app_path, path, temp);
  222. path := temp
  223. END;
  224. UTILS.GetArg(2, param);
  225. IF param = "" THEN
  226. ERRORS.Error(205)
  227. END;
  228. SCAN.NewDef(param);
  229. IF TARGETS.Select(param) THEN
  230. target := TARGETS.target
  231. ELSE
  232. ERRORS.Error(206)
  233. END;
  234. IF TARGETS.CPU = TARGETS.cpuMSP430 THEN
  235. options.ram := MSP430.minRAM;
  236. options.rom := MSP430.minROM
  237. END;
  238. IF (TARGETS.CPU = TARGETS.cpuTHUMB) & (TARGETS.OS = TARGETS.osNONE) THEN
  239. options.ram := THUMB.minRAM;
  240. options.rom := THUMB.minROM
  241. END;
  242. IF UTILS.bit_depth < TARGETS.BitDepth THEN
  243. ERRORS.Error(206)
  244. END;
  245. STRINGS.append(lib_path, "lib");
  246. STRINGS.append(lib_path, UTILS.slash);
  247. STRINGS.append(lib_path, TARGETS.LibDir);
  248. STRINGS.append(lib_path, UTILS.slash);
  249. keys(options, outname);
  250. TEXTDRV.setTabSize(options.tab);
  251. IF outname = "" THEN
  252. outname := path;
  253. STRINGS.append(outname, modname);
  254. STRINGS.append(outname, TARGETS.FileExt)
  255. ELSE
  256. IF PATHS.isRelative(outname) THEN
  257. PATHS.RelPath(app_path, outname, temp);
  258. outname := temp
  259. END
  260. END;
  261. PARS.init(options);
  262. CASE TARGETS.OS OF
  263. |TARGETS.osNONE:
  264. |TARGETS.osWIN32,
  265. TARGETS.osWIN64: SCAN.NewDef(DEF_WINDOWS)
  266. |TARGETS.osLINUX32,
  267. TARGETS.osLINUX64: SCAN.NewDef(DEF_LINUX)
  268. |TARGETS.osKOS: SCAN.NewDef(DEF_KOLIBRIOS)
  269. END;
  270. CASE TARGETS.CPU OF
  271. |TARGETS.cpuX86: SCAN.NewDef(DEF_CPU_X86)
  272. |TARGETS.cpuAMD64: SCAN.NewDef(DEF_CPU_X8664)
  273. |TARGETS.cpuMSP430:
  274. |TARGETS.cpuTHUMB:
  275. |TARGETS.cpuRVM32I:
  276. |TARGETS.cpuRVM64I:
  277. END;
  278. ST.compile(path, lib_path, modname, outname, target, options);
  279. time := UTILS.GetTickCount() - UTILS.time;
  280. C.Dashes;
  281. C.Int(PARS.lines); C.String(" lines, ");
  282. C.Int(time DIV 100); C.String("."); C.Int2(time MOD 100); C.String(" sec, ");
  283. C.Int(WRITER.counter); C.StringLn(" bytes");
  284. UTILS.Exit(0)
  285. END main;
  286. BEGIN
  287. main
  288. END Compiler.