HOST.ob07 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. (*
  2. BSD 2-Clause License
  3. Copyright (c) 2018-2022, Anton Krotov
  4. All rights reserved.
  5. *)
  6. MODULE HOST;
  7. IMPORT SYSTEM;
  8. CONST
  9. slash* = "\";
  10. eol* = 0DX + 0AX;
  11. bit_depth* = (ORD(LSL(1, 31) > 0) + 1) * 32;
  12. maxint* = ROR(-2, 1);
  13. minint* = ROR(1, 1);
  14. MAX_PARAM = 1024;
  15. OFS_MAXPATHNAME = 128;
  16. TYPE
  17. POverlapped = POINTER TO OVERLAPPED;
  18. OVERLAPPED = RECORD
  19. Internal: INTEGER;
  20. InternalHigh: INTEGER;
  21. Offset: INTEGER;
  22. OffsetHigh: INTEGER;
  23. hEvent: INTEGER
  24. END;
  25. OFSTRUCT = RECORD
  26. cBytes: CHAR;
  27. fFixedDisk: CHAR;
  28. nErrCode: WCHAR;
  29. Reserved1: WCHAR;
  30. Reserved2: WCHAR;
  31. szPathName: ARRAY OFS_MAXPATHNAME OF CHAR
  32. END;
  33. PSecurityAttributes = POINTER TO TSecurityAttributes;
  34. TSecurityAttributes = RECORD
  35. nLength: INTEGER;
  36. lpSecurityDescriptor: INTEGER;
  37. bInheritHandle: INTEGER
  38. END;
  39. VAR
  40. hConsoleOutput: INTEGER;
  41. Params: ARRAY MAX_PARAM, 2 OF INTEGER;
  42. argc: INTEGER;
  43. maxreal*, inf*: REAL;
  44. PROCEDURE [windows-, "kernel32.dll", "GetTickCount"]
  45. _GetTickCount (): INTEGER;
  46. PROCEDURE [windows-, "kernel32.dll", "GetStdHandle"]
  47. _GetStdHandle (nStdHandle: INTEGER): INTEGER;
  48. PROCEDURE [windows-, "kernel32.dll", "GetCommandLineA"]
  49. _GetCommandLine (): INTEGER;
  50. PROCEDURE [windows-, "kernel32.dll", "ReadFile"]
  51. _ReadFile (hFile, Buffer, nNumberOfBytesToRW: INTEGER; VAR NumberOfBytesRW: INTEGER; lpOverlapped: POverlapped): INTEGER;
  52. PROCEDURE [windows-, "kernel32.dll", "WriteFile"]
  53. _WriteFile (hFile, Buffer, nNumberOfBytesToRW: INTEGER; VAR NumberOfBytesRW: INTEGER; lpOverlapped: POverlapped): INTEGER;
  54. PROCEDURE [windows-, "kernel32.dll", "CloseHandle"]
  55. _CloseHandle (hObject: INTEGER): INTEGER;
  56. PROCEDURE [windows-, "kernel32.dll", "CreateFileA"]
  57. _CreateFile (
  58. lpFileName, dwDesiredAccess, dwShareMode: INTEGER;
  59. lpSecurityAttributes: PSecurityAttributes;
  60. dwCreationDisposition, dwFlagsAndAttributes,
  61. hTemplateFile: INTEGER): INTEGER;
  62. PROCEDURE [windows-, "kernel32.dll", "OpenFile"]
  63. _OpenFile (lpFileName: INTEGER; lpReOpenBuff: OFSTRUCT; uStyle: INTEGER): INTEGER;
  64. PROCEDURE [windows-, "kernel32.dll", "GetCurrentDirectoryA"]
  65. _GetCurrentDirectory (nBufferLength, lpBuffer: INTEGER): INTEGER;
  66. PROCEDURE [windows, "kernel32.dll", "ExitProcess"]
  67. _ExitProcess (code: INTEGER);
  68. PROCEDURE [ccall, "msvcrt.dll", "time"]
  69. _time (ptr: INTEGER): INTEGER;
  70. PROCEDURE ExitProcess* (code: INTEGER);
  71. BEGIN
  72. _ExitProcess(code)
  73. END ExitProcess;
  74. PROCEDURE GetCurrentDirectory* (VAR path: ARRAY OF CHAR);
  75. VAR
  76. n: INTEGER;
  77. BEGIN
  78. n := _GetCurrentDirectory(LEN(path), SYSTEM.ADR(path[0]));
  79. path[n] := slash;
  80. path[n + 1] := 0X
  81. END GetCurrentDirectory;
  82. PROCEDURE GetChar (adr: INTEGER): CHAR;
  83. VAR
  84. res: CHAR;
  85. BEGIN
  86. SYSTEM.GET(adr, res)
  87. RETURN res
  88. END GetChar;
  89. PROCEDURE ParamParse;
  90. VAR
  91. p, count, cond: INTEGER;
  92. c: CHAR;
  93. PROCEDURE ChangeCond (A, B, C: INTEGER; VAR cond: INTEGER; c: CHAR);
  94. BEGIN
  95. IF (c <= 20X) & (c # 0X) THEN
  96. cond := A
  97. ELSIF c = 22X THEN
  98. cond := B
  99. ELSIF c = 0X THEN
  100. cond := 6
  101. ELSE
  102. cond := C
  103. END
  104. END ChangeCond;
  105. BEGIN
  106. p := _GetCommandLine();
  107. cond := 0;
  108. count := 0;
  109. WHILE (count < MAX_PARAM) & (cond # 6) DO
  110. c := GetChar(p);
  111. CASE cond OF
  112. |0: ChangeCond(0, 4, 1, cond, c); IF cond = 1 THEN Params[count, 0] := p END
  113. |1: ChangeCond(0, 3, 1, cond, c); IF cond IN {0, 6} THEN Params[count, 1] := p - 1; INC(count) END
  114. |3: ChangeCond(3, 1, 3, cond, c); IF cond = 6 THEN Params[count, 1] := p - 1; INC(count) END
  115. |4: ChangeCond(5, 0, 5, cond, c); IF cond = 5 THEN Params[count, 0] := p END
  116. |5: ChangeCond(5, 1, 5, cond, c); IF cond = 6 THEN Params[count, 1] := p - 1; INC(count) END
  117. |6:
  118. END;
  119. INC(p)
  120. END;
  121. argc := count
  122. END ParamParse;
  123. PROCEDURE GetArg* (n: INTEGER; VAR s: ARRAY OF CHAR);
  124. VAR
  125. i, j, len: INTEGER;
  126. c: CHAR;
  127. BEGIN
  128. j := 0;
  129. IF n < argc THEN
  130. len := LEN(s) - 1;
  131. i := Params[n, 0];
  132. WHILE (j < len) & (i <= Params[n, 1]) DO
  133. c := GetChar(i);
  134. IF c # 22X THEN
  135. s[j] := c;
  136. INC(j)
  137. END;
  138. INC(i)
  139. END
  140. END;
  141. s[j] := 0X
  142. END GetArg;
  143. PROCEDURE FileRead* (F: INTEGER; VAR Buffer: ARRAY OF CHAR; bytes: INTEGER): INTEGER;
  144. VAR
  145. res: INTEGER;
  146. BEGIN
  147. IF _ReadFile(F, SYSTEM.ADR(Buffer[0]), bytes, res, NIL) = 0 THEN
  148. res := -1
  149. END
  150. RETURN res
  151. END FileRead;
  152. PROCEDURE FileWrite* (F: INTEGER; Buffer: ARRAY OF BYTE; bytes: INTEGER): INTEGER;
  153. VAR
  154. res: INTEGER;
  155. BEGIN
  156. IF _WriteFile(F, SYSTEM.ADR(Buffer[0]), bytes, res, NIL) = 0 THEN
  157. res := -1
  158. END
  159. RETURN res
  160. END FileWrite;
  161. PROCEDURE FileCreate* (FName: ARRAY OF CHAR): INTEGER;
  162. RETURN _CreateFile(SYSTEM.ADR(FName[0]), 0C0000000H, 0, NIL, 2, 80H, 0)
  163. END FileCreate;
  164. PROCEDURE FileClose* (F: INTEGER);
  165. BEGIN
  166. _CloseHandle(F)
  167. END FileClose;
  168. PROCEDURE FileOpen* (FName: ARRAY OF CHAR): INTEGER;
  169. VAR
  170. ofstr: OFSTRUCT;
  171. res: INTEGER;
  172. BEGIN
  173. res := _OpenFile(SYSTEM.ADR(FName[0]), ofstr, 0);
  174. IF res = 0FFFFFFFFH THEN
  175. res := -1
  176. END
  177. RETURN res
  178. END FileOpen;
  179. PROCEDURE chmod* (FName: ARRAY OF CHAR);
  180. END chmod;
  181. PROCEDURE OutChar* (c: CHAR);
  182. VAR
  183. count: INTEGER;
  184. BEGIN
  185. _WriteFile(hConsoleOutput, SYSTEM.ADR(c), 1, count, NIL)
  186. END OutChar;
  187. PROCEDURE GetTickCount* (): INTEGER;
  188. RETURN _GetTickCount() DIV 10
  189. END GetTickCount;
  190. PROCEDURE letter (c: CHAR): BOOLEAN;
  191. RETURN ("a" <= c) & (c <= "z") OR ("A" <= c) & (c <= "Z")
  192. END letter;
  193. PROCEDURE isRelative* (path: ARRAY OF CHAR): BOOLEAN;
  194. RETURN ~(letter(path[0]) & (path[1] = ":"))
  195. END isRelative;
  196. PROCEDURE UnixTime* (): INTEGER;
  197. RETURN _time(0)
  198. END UnixTime;
  199. PROCEDURE splitf* (x: REAL; VAR a, b: INTEGER): INTEGER;
  200. VAR
  201. res: INTEGER;
  202. BEGIN
  203. a := 0;
  204. b := 0;
  205. SYSTEM.GET32(SYSTEM.ADR(x), a);
  206. SYSTEM.GET32(SYSTEM.ADR(x) + 4, b);
  207. SYSTEM.GET(SYSTEM.ADR(x), res)
  208. RETURN res
  209. END splitf;
  210. PROCEDURE d2s* (x: REAL): INTEGER;
  211. VAR
  212. h, l, s, e: INTEGER;
  213. BEGIN
  214. e := splitf(x, l, h);
  215. s := ASR(h, 31) MOD 2;
  216. e := (h DIV 100000H) MOD 2048;
  217. IF e <= 896 THEN
  218. h := (h MOD 100000H) * 8 + (l DIV 20000000H) MOD 8 + 800000H;
  219. REPEAT
  220. h := h DIV 2;
  221. INC(e)
  222. UNTIL e = 897;
  223. e := 896;
  224. l := (h MOD 8) * 20000000H;
  225. h := h DIV 8
  226. ELSIF (1151 <= e) & (e < 2047) THEN
  227. e := 1151;
  228. h := 0;
  229. l := 0
  230. ELSIF e = 2047 THEN
  231. e := 1151;
  232. IF (h MOD 100000H # 0) OR (BITS(l) * {0..31} # {}) THEN
  233. h := 80000H;
  234. l := 0
  235. END
  236. END;
  237. DEC(e, 896)
  238. RETURN LSL(s, 31) + LSL(e, 23) + (h MOD 100000H) * 8 + (l DIV 20000000H) MOD 8
  239. END d2s;
  240. BEGIN
  241. inf := SYSTEM.INF();
  242. maxreal := 1.9;
  243. PACK(maxreal, 1023);
  244. hConsoleOutput := _GetStdHandle(-11);
  245. ParamParse
  246. END HOST.