lang.js 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. import * as Commands from "./../../ast/commands";
  2. import { Types } from "./../../typeSystem/types";
  3. import * as Parsers from "./../../typeSystem/parsers";
  4. import { IVProgParser } from "../../ast/ivprogParser";
  5. import { RealLiteral, IntLiteral, BoolLiteral } from "../../ast/expressions";
  6. import { Modes } from "../modes";
  7. import { MultiType } from "../../typeSystem/multiType";
  8. import { ProcessorErrorFactory } from "../error/processorErrorFactory";
  9. import { StoreValue } from "../store/value/store_value";
  10. /**
  11. *
  12. * is_real
  13. * is_int
  14. * is_bool
  15. * cast_real
  16. * cast_int
  17. * cast_bool
  18. * cast_string
  19. * cast_char
  20. */
  21. export function createIsRealFun () {
  22. const isRealFun = async (sto, _) => {
  23. const str = sto.applyStore("str");
  24. const parser = IVProgParser.createParser(str.get());
  25. let result = false;
  26. try {
  27. const val = parser.parseTerm();
  28. if (val instanceof RealLiteral) {
  29. result = true;
  30. }
  31. } catch (error) {
  32. // ignore
  33. }
  34. const temp = new StoreValue(Types.BOOLEAN, result);
  35. sto.insertStore("$", temp);
  36. sto.mode = Modes.RETURN;
  37. return sto;
  38. };
  39. const block = new Commands.CommandBlock(
  40. [],
  41. [new Commands.SysCall(isRealFun)]
  42. );
  43. const func = new Commands.Function(
  44. "$isReal",
  45. Types.BOOLEAN,
  46. [new Commands.FormalParameter(Types.STRING, "str", false)],
  47. block
  48. );
  49. return func;
  50. }
  51. export function createIsIntFun () {
  52. const isIntFun = async (sto, _) => {
  53. const str = sto.applyStore("str");
  54. const parser = IVProgParser.createParser(str.get());
  55. let result = false;
  56. try {
  57. const val = parser.parseTerm();
  58. if (val instanceof IntLiteral) {
  59. result = true;
  60. }
  61. } catch {
  62. // ignore
  63. }
  64. const temp = new StoreValue(Types.BOOLEAN, result);
  65. sto.insertStore("$", temp);
  66. sto.mode = Modes.RETURN;
  67. return sto;
  68. };
  69. const block = new Commands.CommandBlock([], [new Commands.SysCall(isIntFun)]);
  70. const func = new Commands.Function(
  71. "$isInt",
  72. Types.BOOLEAN,
  73. [new Commands.FormalParameter(Types.STRING, "str", false)],
  74. block
  75. );
  76. return func;
  77. }
  78. export function createIsBoolFun () {
  79. const isBoolFun = (sto, _) => {
  80. const str = sto.applyStore("str");
  81. const parser = IVProgParser.createParser(str.get());
  82. let result = false;
  83. try {
  84. const val = parser.parseTerm();
  85. if (val instanceof BoolLiteral) {
  86. result = true;
  87. }
  88. } catch (error) {
  89. // ignore
  90. }
  91. const temp = new StoreValue(Types.BOOLEAN, result);
  92. sto.insertStore("$", temp);
  93. sto.mode = Modes.RETURN;
  94. return sto;
  95. };
  96. const block = new Commands.CommandBlock(
  97. [],
  98. [new Commands.SysCall(isBoolFun)]
  99. );
  100. const func = new Commands.Function(
  101. "$isBool",
  102. Types.BOOLEAN,
  103. [new Commands.FormalParameter(Types.STRING, "str", false)],
  104. block
  105. );
  106. return func;
  107. }
  108. export function createCastRealFun () {
  109. const castRealFun = async (sto, _) => {
  110. const val = sto.applyStore("val");
  111. let value = val.get();
  112. switch (val.type.ord) {
  113. case Types.INTEGER.ord: {
  114. value = value.toNumber();
  115. const temp = new StoreValue(Types.REAL, Parsers.toReal(value));
  116. sto.insertStore("$", temp);
  117. sto.mode = Modes.RETURN;
  118. return sto;
  119. }
  120. case Types.STRING.ord: {
  121. const parser = IVProgParser.createParser(value);
  122. try {
  123. const result = parser.parseTerm();
  124. if (result instanceof RealLiteral) {
  125. const temp = new StoreValue(
  126. Types.REAL,
  127. Parsers.toReal(result.value)
  128. );
  129. sto.insertStore("$", temp);
  130. sto.mode = Modes.RETURN;
  131. return sto;
  132. }
  133. } catch (error) {
  134. // ignore
  135. }
  136. }
  137. }
  138. const typeStringInfoArray = Types.REAL.stringInfo();
  139. const typeInfo = typeStringInfoArray[0];
  140. throw ProcessorErrorFactory.invalid_type_conversion(
  141. value,
  142. typeInfo.type,
  143. typeInfo.dim
  144. );
  145. };
  146. const block = new Commands.CommandBlock(
  147. [],
  148. [new Commands.SysCall(castRealFun)]
  149. );
  150. const func = new Commands.Function(
  151. "$castReal",
  152. Types.REAL,
  153. [
  154. new Commands.FormalParameter(
  155. new MultiType([Types.INTEGER, Types.STRING]),
  156. "val",
  157. false
  158. ),
  159. ],
  160. block
  161. );
  162. return func;
  163. }
  164. export function createCastIntFun () {
  165. const castIntFun = async (sto, _) => {
  166. const val = sto.applyStore("val");
  167. let value = val.get();
  168. switch (val.type.ord) {
  169. case Types.REAL.ord: {
  170. value = value.toNumber();
  171. const temp = new StoreValue(
  172. Types.INTEGER,
  173. Parsers.toInt(Math.floor(value))
  174. );
  175. sto.insertStore("$", temp);
  176. sto.mode = Modes.RETURN;
  177. return sto;
  178. }
  179. case Types.CHAR.ord: {
  180. const temp = new StoreValue(
  181. Types.INTEGER,
  182. Parsers.toInt(value.charCodeAt(0))
  183. );
  184. sto.insertStore("$", temp);
  185. sto.mode = Modes.RETURN;
  186. return sto;
  187. }
  188. case Types.STRING.ord: {
  189. const parser = IVProgParser.createParser(value);
  190. try {
  191. const result = parser.parseTerm();
  192. if (result instanceof IntLiteral) {
  193. const temp = new StoreValue(
  194. Types.INTEGER,
  195. Parsers.toInt(result.value)
  196. );
  197. sto.insertStore("$", temp);
  198. sto.mode = Modes.RETURN;
  199. return sto;
  200. }
  201. } catch (error) {
  202. // ignore
  203. }
  204. }
  205. }
  206. const typeStringInfoArray = Types.INTEGER.stringInfo();
  207. const typeInfo = typeStringInfoArray[0];
  208. throw ProcessorErrorFactory.invalid_type_conversion(
  209. value,
  210. typeInfo.type,
  211. typeInfo.dim
  212. );
  213. };
  214. const block = new Commands.CommandBlock(
  215. [],
  216. [new Commands.SysCall(castIntFun)]
  217. );
  218. const func = new Commands.Function(
  219. "$castInt",
  220. Types.INTEGER,
  221. [
  222. new Commands.FormalParameter(
  223. new MultiType([Types.REAL, Types.STRING, Types.CHAR]),
  224. "val",
  225. false
  226. ),
  227. ],
  228. block
  229. );
  230. return func;
  231. }
  232. export function createCastBoolFun () {
  233. const castBoolFun = async (sto, _) => {
  234. const str = sto.applyStore("str");
  235. const value = str.get();
  236. const parser = IVProgParser.createParser(value);
  237. try {
  238. const val = parser.parseTerm();
  239. if (val instanceof BoolLiteral) {
  240. const temp = new StoreValue(Types.BOOLEAN, val.value);
  241. sto.insertStore("$", temp);
  242. sto.mode = Modes.RETURN;
  243. return sto;
  244. }
  245. } catch (error) {
  246. // ignore
  247. }
  248. const typeStringInfoArray = Types.BOOLEAN.stringInfo();
  249. const typeInfo = typeStringInfoArray[0];
  250. throw ProcessorErrorFactory.invalid_type_conversion(
  251. value,
  252. typeInfo.type,
  253. typeInfo.dim
  254. );
  255. };
  256. const block = new Commands.CommandBlock(
  257. [],
  258. [new Commands.SysCall(castBoolFun)]
  259. );
  260. const func = new Commands.Function(
  261. "$castBool",
  262. Types.BOOLEAN,
  263. [new Commands.FormalParameter(Types.STRING, "str", false)],
  264. block
  265. );
  266. return func;
  267. }
  268. export function createCastStringFun () {
  269. const castStringFun = async function (store, _) {
  270. const val = store.applyStore("str");
  271. const result = Parsers.convertToString(val.get(), val.type);
  272. const temp = new StoreValue(Types.STRING, result);
  273. store.insertStore("$", temp);
  274. store.mode = Modes.RETURN;
  275. return store;
  276. };
  277. const block = new Commands.CommandBlock(
  278. [],
  279. [new Commands.SysCall(castStringFun)]
  280. );
  281. const func = new Commands.Function(
  282. "$castString",
  283. Types.STRING,
  284. [new Commands.FormalParameter(Types.ALL, "str", false)],
  285. block
  286. );
  287. return func;
  288. }
  289. export function createCastCharFun () {
  290. const castCharFun = (store, _) => {
  291. const valSV = store.applyStore("charCode");
  292. // Force the int value to the range [0, 255]
  293. const value = valSV.get().toNumber() & 0xff;
  294. const result = String.fromCharCode(value);
  295. const temp = new StoreValue(Types.CHAR, result);
  296. store.insertStore("$", temp);
  297. store.mode = Modes.RETURN;
  298. return store;
  299. };
  300. const block = new Commands.CommandBlock(
  301. [],
  302. [new Commands.SysCall(castCharFun)]
  303. );
  304. const func = new Commands.Function(
  305. "$castChar",
  306. Types.CHAR,
  307. [new Commands.FormalParameter(Types.INTEGER, "charCode", false)],
  308. block
  309. );
  310. return func;
  311. }