@designliquido/delegua 0.14.7 → 0.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (350) hide show
  1. package/README.md +85 -85
  2. package/bin/delegua +2 -2
  3. package/bin/package.json +88 -88
  4. package/fontes/avaliador-sintatico/avaliador-sintatico-base.d.ts +67 -67
  5. package/fontes/avaliador-sintatico/avaliador-sintatico-base.js +215 -215
  6. package/fontes/avaliador-sintatico/avaliador-sintatico-base.js.map +1 -1
  7. package/fontes/avaliador-sintatico/avaliador-sintatico.d.ts +92 -92
  8. package/fontes/avaliador-sintatico/avaliador-sintatico.js +857 -727
  9. package/fontes/avaliador-sintatico/avaliador-sintatico.js.map +1 -1
  10. package/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-birl.d.ts +27 -22
  11. package/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-birl.js +294 -145
  12. package/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-birl.js.map +1 -1
  13. package/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-egua-classico.d.ts +69 -69
  14. package/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-egua-classico.js +640 -640
  15. package/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-egua-classico.js.map +1 -1
  16. package/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-eguap.d.ts +84 -84
  17. package/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-eguap.js +714 -714
  18. package/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-eguap.js.map +1 -1
  19. package/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-guarani.d.ts +20 -20
  20. package/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-guarani.js +149 -149
  21. package/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-portugol-studio.d.ts +49 -33
  22. package/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-portugol-studio.js +419 -218
  23. package/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-portugol-studio.js.map +1 -1
  24. package/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-visualg.d.ts +73 -73
  25. package/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-visualg.js +534 -534
  26. package/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-visualg.js.map +1 -1
  27. package/fontes/avaliador-sintatico/dialetos/index.d.ts +5 -5
  28. package/fontes/avaliador-sintatico/dialetos/index.js +21 -21
  29. package/fontes/avaliador-sintatico/erro-avaliador-sintatico.d.ts +5 -5
  30. package/fontes/avaliador-sintatico/erro-avaliador-sintatico.js +11 -11
  31. package/fontes/avaliador-sintatico/index.d.ts +2 -2
  32. package/fontes/avaliador-sintatico/index.js +18 -18
  33. package/fontes/avaliador-sintatico/retornos/index.d.ts +3 -3
  34. package/fontes/avaliador-sintatico/retornos/index.js +19 -19
  35. package/fontes/avaliador-sintatico/retornos/retorno-declaracao.d.ts +3 -3
  36. package/fontes/avaliador-sintatico/retornos/retorno-declaracao.js +2 -2
  37. package/fontes/avaliador-sintatico/retornos/retorno-primario.d.ts +3 -3
  38. package/fontes/avaliador-sintatico/retornos/retorno-primario.js +2 -2
  39. package/fontes/avaliador-sintatico/retornos/retorno-resolver-declaracao.d.ts +2 -2
  40. package/fontes/avaliador-sintatico/retornos/retorno-resolver-declaracao.js +2 -2
  41. package/fontes/bibliotecas/biblioteca-global.d.ts +3 -3
  42. package/fontes/bibliotecas/biblioteca-global.js +315 -315
  43. package/fontes/bibliotecas/dialetos/egua-classico/biblioteca-global.d.ts +1 -1
  44. package/fontes/bibliotecas/dialetos/egua-classico/biblioteca-global.js +230 -230
  45. package/fontes/bibliotecas/dialetos/egua-classico/index.d.ts +2 -2
  46. package/fontes/bibliotecas/dialetos/egua-classico/index.js +32 -32
  47. package/fontes/bibliotecas/dialetos/egua-classico/matematica.d.ts +1 -1
  48. package/fontes/bibliotecas/dialetos/egua-classico/matematica.js +478 -478
  49. package/fontes/bibliotecas/dialetos/egua-classico/tempo.d.ts +1 -1
  50. package/fontes/bibliotecas/dialetos/egua-classico/tempo.js +39 -39
  51. package/fontes/bibliotecas/dialetos/egua-classico/textos.d.ts +8 -8
  52. package/fontes/bibliotecas/dialetos/egua-classico/textos.js +201 -201
  53. package/fontes/bibliotecas/primitivas-texto.d.ts +11 -11
  54. package/fontes/bibliotecas/primitivas-texto.js +12 -12
  55. package/fontes/bibliotecas/primitivas-vetor.d.ts +15 -15
  56. package/fontes/bibliotecas/primitivas-vetor.js +33 -33
  57. package/fontes/construtos/acesso-indice-variavel.d.ts +15 -15
  58. package/fontes/construtos/acesso-indice-variavel.js +20 -20
  59. package/fontes/construtos/acesso-metodo.d.ts +14 -14
  60. package/fontes/construtos/acesso-metodo.js +19 -19
  61. package/fontes/construtos/agrupamento.d.ts +14 -14
  62. package/fontes/construtos/agrupamento.js +19 -19
  63. package/fontes/construtos/atribuicao-sobrescrita.d.ts +11 -11
  64. package/fontes/construtos/atribuicao-sobrescrita.js +16 -16
  65. package/fontes/construtos/atribuir.d.ts +10 -10
  66. package/fontes/construtos/atribuir.js +15 -15
  67. package/fontes/construtos/binario.d.ts +22 -22
  68. package/fontes/construtos/binario.js +27 -27
  69. package/fontes/construtos/chamada.d.ts +13 -13
  70. package/fontes/construtos/chamada.js +36 -36
  71. package/fontes/construtos/construto.d.ts +7 -7
  72. package/fontes/construtos/construto.js +2 -2
  73. package/fontes/construtos/definir-valor.d.ts +11 -11
  74. package/fontes/construtos/definir-valor.js +16 -16
  75. package/fontes/construtos/dicionario.d.ts +10 -10
  76. package/fontes/construtos/dicionario.js +15 -15
  77. package/fontes/construtos/formatacao-escrita.d.ts +16 -16
  78. package/fontes/construtos/formatacao-escrita.js +21 -21
  79. package/fontes/construtos/funcao.d.ts +10 -10
  80. package/fontes/construtos/funcao.js +15 -15
  81. package/fontes/construtos/index.d.ts +19 -19
  82. package/fontes/construtos/index.js +35 -35
  83. package/fontes/construtos/isto.d.ts +9 -9
  84. package/fontes/construtos/isto.js +14 -14
  85. package/fontes/construtos/literal.d.ts +10 -10
  86. package/fontes/construtos/literal.js +14 -14
  87. package/fontes/construtos/logico.d.ts +11 -11
  88. package/fontes/construtos/logico.js +16 -16
  89. package/fontes/construtos/super.d.ts +10 -10
  90. package/fontes/construtos/super.js +15 -15
  91. package/fontes/construtos/unario.d.ts +11 -10
  92. package/fontes/construtos/unario.js +16 -15
  93. package/fontes/construtos/unario.js.map +1 -1
  94. package/fontes/construtos/variavel.d.ts +9 -9
  95. package/fontes/construtos/variavel.js +14 -14
  96. package/fontes/construtos/vetor.d.ts +9 -9
  97. package/fontes/construtos/vetor.js +14 -14
  98. package/fontes/declaracoes/bloco.d.ts +7 -7
  99. package/fontes/declaracoes/bloco.js +14 -14
  100. package/fontes/declaracoes/classe.d.ts +9 -9
  101. package/fontes/declaracoes/classe.js +16 -16
  102. package/fontes/declaracoes/continua.d.ts +6 -6
  103. package/fontes/declaracoes/continua.js +13 -13
  104. package/fontes/declaracoes/declaracao.d.ts +8 -8
  105. package/fontes/declaracoes/declaracao.js +17 -17
  106. package/fontes/declaracoes/enquanto.d.ts +9 -9
  107. package/fontes/declaracoes/enquanto.js +15 -15
  108. package/fontes/declaracoes/escolha.d.ts +14 -14
  109. package/fontes/declaracoes/escolha.js +19 -19
  110. package/fontes/declaracoes/escreva-mesma-linha.d.ts +8 -8
  111. package/fontes/declaracoes/escreva-mesma-linha.js +14 -14
  112. package/fontes/declaracoes/escreva.d.ts +8 -8
  113. package/fontes/declaracoes/escreva.js +14 -14
  114. package/fontes/declaracoes/expressao.d.ts +8 -8
  115. package/fontes/declaracoes/expressao.js +14 -14
  116. package/fontes/declaracoes/fazer.d.ts +8 -8
  117. package/fontes/declaracoes/fazer.js +15 -15
  118. package/fontes/declaracoes/funcao.d.ts +9 -9
  119. package/fontes/declaracoes/funcao.js +15 -15
  120. package/fontes/declaracoes/importar.d.ts +9 -9
  121. package/fontes/declaracoes/importar.js +15 -15
  122. package/fontes/declaracoes/index.d.ts +19 -19
  123. package/fontes/declaracoes/index.js +35 -35
  124. package/fontes/declaracoes/leia.d.ts +12 -12
  125. package/fontes/declaracoes/leia.js +18 -18
  126. package/fontes/declaracoes/para.d.ts +10 -10
  127. package/fontes/declaracoes/para.js +17 -17
  128. package/fontes/declaracoes/retorna.d.ts +8 -8
  129. package/fontes/declaracoes/retorna.js +15 -15
  130. package/fontes/declaracoes/se.d.ts +11 -11
  131. package/fontes/declaracoes/se.js +17 -17
  132. package/fontes/declaracoes/sustar.d.ts +6 -6
  133. package/fontes/declaracoes/sustar.js +13 -13
  134. package/fontes/declaracoes/tente.d.ts +14 -14
  135. package/fontes/declaracoes/tente.js +20 -20
  136. package/fontes/declaracoes/var.d.ts +9 -9
  137. package/fontes/declaracoes/var.js +15 -15
  138. package/fontes/depuracao/cyrb53.d.ts +9 -9
  139. package/fontes/depuracao/cyrb53.js +22 -22
  140. package/fontes/depuracao/index.d.ts +2 -2
  141. package/fontes/depuracao/index.js +23 -23
  142. package/fontes/depuracao/ponto-parada.d.ts +4 -4
  143. package/fontes/depuracao/ponto-parada.js +2 -2
  144. package/fontes/espaco-variaveis.d.ts +19 -19
  145. package/fontes/espaco-variaveis.js +19 -19
  146. package/fontes/estruturas/chamavel.d.ts +5 -5
  147. package/fontes/estruturas/chamavel.js +12 -12
  148. package/fontes/estruturas/classe-padrao.d.ts +17 -17
  149. package/fontes/estruturas/classe-padrao.js +28 -28
  150. package/fontes/estruturas/delegua-classe.d.ts +16 -16
  151. package/fontes/estruturas/delegua-classe.js +38 -38
  152. package/fontes/estruturas/delegua-funcao.d.ts +18 -18
  153. package/fontes/estruturas/delegua-funcao.js +60 -60
  154. package/fontes/estruturas/funcao-padrao.d.ts +12 -12
  155. package/fontes/estruturas/funcao-padrao.js +22 -22
  156. package/fontes/estruturas/index.d.ts +9 -9
  157. package/fontes/estruturas/index.js +25 -25
  158. package/fontes/estruturas/metodo-primitiva.d.ts +17 -17
  159. package/fontes/estruturas/metodo-primitiva.js +26 -26
  160. package/fontes/estruturas/modulo.d.ts +9 -9
  161. package/fontes/estruturas/modulo.js +13 -13
  162. package/fontes/estruturas/objeto-delegua-classe.d.ts +10 -10
  163. package/fontes/estruturas/objeto-delegua-classe.js +26 -26
  164. package/fontes/estruturas/objeto-padrao.d.ts +9 -9
  165. package/fontes/estruturas/objeto-padrao.js +21 -21
  166. package/fontes/excecoes/erro-em-tempo-de-execucao.d.ts +7 -7
  167. package/fontes/excecoes/erro-em-tempo-de-execucao.js +13 -13
  168. package/fontes/excecoes/index.d.ts +1 -1
  169. package/fontes/excecoes/index.js +17 -17
  170. package/fontes/formatadores/delegua.d.ts +18 -18
  171. package/fontes/formatadores/delegua.js +82 -82
  172. package/fontes/formatadores/index.d.ts +1 -1
  173. package/fontes/formatadores/index.js +17 -17
  174. package/fontes/interfaces/avaliador-sintatico-interface.d.ts +57 -57
  175. package/fontes/interfaces/avaliador-sintatico-interface.js +2 -2
  176. package/fontes/interfaces/construtos/index.d.ts +4 -4
  177. package/fontes/interfaces/construtos/index.js +2 -2
  178. package/fontes/interfaces/escopo-execucao.d.ts +11 -11
  179. package/fontes/interfaces/escopo-execucao.js +2 -2
  180. package/fontes/interfaces/index.d.ts +11 -11
  181. package/fontes/interfaces/index.js +27 -27
  182. package/fontes/interfaces/interpretador-com-depuracao-interface.d.ts +17 -17
  183. package/fontes/interfaces/interpretador-com-depuracao-interface.js +2 -2
  184. package/fontes/interfaces/interpretador-interface.d.ts +55 -55
  185. package/fontes/interfaces/interpretador-interface.js +2 -2
  186. package/fontes/interfaces/lexador-interface.d.ts +23 -23
  187. package/fontes/interfaces/lexador-interface.js +2 -2
  188. package/fontes/interfaces/parametro-interface.d.ts +6 -6
  189. package/fontes/interfaces/parametro-interface.js +2 -2
  190. package/fontes/interfaces/pilha-escopos-execucao-interface.d.ts +25 -25
  191. package/fontes/interfaces/pilha-escopos-execucao-interface.js +2 -2
  192. package/fontes/interfaces/pilha-interface.d.ts +7 -7
  193. package/fontes/interfaces/pilha-interface.js +2 -2
  194. package/fontes/interfaces/resolvedor-interface.d.ts +41 -41
  195. package/fontes/interfaces/resolvedor-interface.js +2 -2
  196. package/fontes/interfaces/retornos/index.d.ts +4 -4
  197. package/fontes/interfaces/retornos/index.js +20 -20
  198. package/fontes/interfaces/retornos/retorno-avaliador-sintatico.d.ts +6 -6
  199. package/fontes/interfaces/retornos/retorno-avaliador-sintatico.js +2 -2
  200. package/fontes/interfaces/retornos/retorno-execucao-interface.d.ts +5 -5
  201. package/fontes/interfaces/retornos/retorno-execucao-interface.js +2 -2
  202. package/fontes/interfaces/retornos/retorno-interpretador.d.ts +5 -5
  203. package/fontes/interfaces/retornos/retorno-interpretador.js +2 -2
  204. package/fontes/interfaces/retornos/retorno-lexador.d.ts +10 -10
  205. package/fontes/interfaces/retornos/retorno-lexador.js +2 -2
  206. package/fontes/interfaces/simbolo-interface.d.ts +7 -7
  207. package/fontes/interfaces/simbolo-interface.js +2 -2
  208. package/fontes/interfaces/tradutor-interface.d.ts +4 -4
  209. package/fontes/interfaces/tradutor-interface.js +2 -2
  210. package/fontes/interfaces/variavel-interface.d.ts +4 -4
  211. package/fontes/interfaces/variavel-interface.js +2 -2
  212. package/fontes/interpretador/dialetos/egua-classico/index.d.ts +1 -1
  213. package/fontes/interpretador/dialetos/egua-classico/index.js +17 -17
  214. package/fontes/interpretador/dialetos/egua-classico/interpretador-egua-classico.d.ts +99 -99
  215. package/fontes/interpretador/dialetos/egua-classico/interpretador-egua-classico.js +743 -743
  216. package/fontes/interpretador/dialetos/egua-classico/interpretador-egua-classico.js.map +1 -1
  217. package/fontes/interpretador/dialetos/egua-classico/resolvedor/erro-resolvedor.d.ts +5 -5
  218. package/fontes/interpretador/dialetos/egua-classico/resolvedor/erro-resolvedor.js +11 -11
  219. package/fontes/interpretador/dialetos/egua-classico/resolvedor/index.d.ts +3 -3
  220. package/fontes/interpretador/dialetos/egua-classico/resolvedor/index.js +19 -19
  221. package/fontes/interpretador/dialetos/egua-classico/resolvedor/pilha-escopos.d.ts +9 -9
  222. package/fontes/interpretador/dialetos/egua-classico/resolvedor/pilha-escopos.js +25 -25
  223. package/fontes/interpretador/dialetos/egua-classico/resolvedor/resolvedor.d.ts +87 -87
  224. package/fontes/interpretador/dialetos/egua-classico/resolvedor/resolvedor.js +387 -387
  225. package/fontes/interpretador/dialetos/egua-classico/resolvedor/retorno-resolvedor.d.ts +6 -6
  226. package/fontes/interpretador/dialetos/egua-classico/resolvedor/retorno-resolvedor.js +2 -2
  227. package/fontes/interpretador/dialetos/index.d.ts +4 -4
  228. package/fontes/interpretador/dialetos/index.js +20 -20
  229. package/fontes/interpretador/dialetos/portugol-studio/interpretador-portugol-studio.d.ts +12 -12
  230. package/fontes/interpretador/dialetos/portugol-studio/interpretador-portugol-studio.js +26 -26
  231. package/fontes/interpretador/dialetos/visualg/interpretador-visualg-com-depuracao.d.ts +40 -40
  232. package/fontes/interpretador/dialetos/visualg/interpretador-visualg-com-depuracao.js +96 -96
  233. package/fontes/interpretador/dialetos/visualg/interpretador-visualg-com-depuracao.js.map +1 -1
  234. package/fontes/interpretador/dialetos/visualg/interpretador-visualg.d.ts +46 -46
  235. package/fontes/interpretador/dialetos/visualg/interpretador-visualg.js +102 -102
  236. package/fontes/interpretador/dialetos/visualg/interpretador-visualg.js.map +1 -1
  237. package/fontes/interpretador/erro-interpretador.d.ts +8 -8
  238. package/fontes/interpretador/erro-interpretador.js +2 -2
  239. package/fontes/interpretador/index.d.ts +4 -4
  240. package/fontes/interpretador/index.js +20 -20
  241. package/fontes/interpretador/inferenciador.d.ts +1 -1
  242. package/fontes/interpretador/inferenciador.js +31 -31
  243. package/fontes/interpretador/interpretador-base.d.ts +188 -187
  244. package/fontes/interpretador/interpretador-base.js +1000 -972
  245. package/fontes/interpretador/interpretador-base.js.map +1 -1
  246. package/fontes/interpretador/interpretador-com-depuracao.d.ts +199 -199
  247. package/fontes/interpretador/interpretador-com-depuracao.js +516 -516
  248. package/fontes/interpretador/pilha-escopos-execucao.d.ts +38 -38
  249. package/fontes/interpretador/pilha-escopos-execucao.js +158 -158
  250. package/fontes/lexador/dialetos/index.d.ts +6 -6
  251. package/fontes/lexador/dialetos/index.js +22 -22
  252. package/fontes/lexador/dialetos/lexador-birl.d.ts +12 -12
  253. package/fontes/lexador/dialetos/lexador-birl.js +211 -165
  254. package/fontes/lexador/dialetos/lexador-birl.js.map +1 -1
  255. package/fontes/lexador/dialetos/lexador-egua-classico.d.ts +36 -36
  256. package/fontes/lexador/dialetos/lexador-egua-classico.js +286 -286
  257. package/fontes/lexador/dialetos/lexador-eguap.d.ts +51 -51
  258. package/fontes/lexador/dialetos/lexador-eguap.js +398 -398
  259. package/fontes/lexador/dialetos/lexador-guarani.d.ts +9 -9
  260. package/fontes/lexador/dialetos/lexador-guarani.js +113 -113
  261. package/fontes/lexador/dialetos/lexador-portugol-ipt.d.ts +33 -33
  262. package/fontes/lexador/dialetos/lexador-portugol-ipt.js +195 -195
  263. package/fontes/lexador/dialetos/lexador-portugol-studio.d.ts +21 -15
  264. package/fontes/lexador/dialetos/lexador-portugol-studio.js +280 -244
  265. package/fontes/lexador/dialetos/lexador-portugol-studio.js.map +1 -1
  266. package/fontes/lexador/dialetos/lexador-visualg.d.ts +18 -18
  267. package/fontes/lexador/dialetos/lexador-visualg.js +218 -218
  268. package/fontes/lexador/dialetos/palavras-reservadas/birl.d.ts +46 -41
  269. package/fontes/lexador/dialetos/palavras-reservadas/birl.js +63 -58
  270. package/fontes/lexador/dialetos/palavras-reservadas/birl.js.map +1 -1
  271. package/fontes/lexador/dialetos/palavras-reservadas/egua-classico.d.ts +36 -36
  272. package/fontes/lexador/dialetos/palavras-reservadas/egua-classico.js +41 -41
  273. package/fontes/lexador/dialetos/palavras-reservadas/guarani.d.ts +4 -4
  274. package/fontes/lexador/dialetos/palavras-reservadas/guarani.js +9 -9
  275. package/fontes/lexador/dialetos/palavras-reservadas/index.d.ts +3 -3
  276. package/fontes/lexador/dialetos/palavras-reservadas/index.js +19 -19
  277. package/fontes/lexador/dialetos/palavras-reservadas/portugol-ipt.d.ts +6 -6
  278. package/fontes/lexador/dialetos/palavras-reservadas/portugol-ipt.js +11 -11
  279. package/fontes/lexador/dialetos/palavras-reservadas/portugol-studio.d.ts +23 -11
  280. package/fontes/lexador/dialetos/palavras-reservadas/portugol-studio.js +28 -16
  281. package/fontes/lexador/dialetos/palavras-reservadas/portugol-studio.js.map +1 -1
  282. package/fontes/lexador/dialetos/palavras-reservadas/rantiaquin.d.ts +2 -2
  283. package/fontes/lexador/dialetos/palavras-reservadas/rantiaquin.js +3 -3
  284. package/fontes/lexador/dialetos/palavras-reservadas/visualg.d.ts +60 -60
  285. package/fontes/lexador/dialetos/palavras-reservadas/visualg.js +65 -65
  286. package/fontes/lexador/dialetos/pragma.d.ts +8 -8
  287. package/fontes/lexador/dialetos/pragma.js +2 -2
  288. package/fontes/lexador/erro-lexador.d.ts +5 -5
  289. package/fontes/lexador/erro-lexador.js +2 -2
  290. package/fontes/lexador/index.d.ts +2 -2
  291. package/fontes/lexador/index.js +18 -18
  292. package/fontes/lexador/lexador-base-linha-unica.d.ts +28 -28
  293. package/fontes/lexador/lexador-base-linha-unica.js +82 -82
  294. package/fontes/lexador/lexador-base.d.ts +41 -41
  295. package/fontes/lexador/lexador-base.js +112 -112
  296. package/fontes/lexador/lexador.d.ts +43 -43
  297. package/fontes/lexador/lexador.js +412 -408
  298. package/fontes/lexador/lexador.js.map +1 -1
  299. package/fontes/lexador/palavras-reservadas.d.ts +36 -36
  300. package/fontes/lexador/palavras-reservadas.js +41 -41
  301. package/fontes/lexador/simbolo.d.ts +10 -10
  302. package/fontes/lexador/simbolo.js +16 -16
  303. package/fontes/quebras/index.d.ts +10 -10
  304. package/fontes/quebras/index.js +19 -19
  305. package/fontes/tipos-de-simbolos/birl.d.ts +71 -57
  306. package/fontes/tipos-de-simbolos/birl.js +78 -61
  307. package/fontes/tipos-de-simbolos/birl.js.map +1 -1
  308. package/fontes/tipos-de-simbolos/comum.d.ts +22 -22
  309. package/fontes/tipos-de-simbolos/comum.js +23 -23
  310. package/fontes/tipos-de-simbolos/delegua.d.ts +80 -80
  311. package/fontes/tipos-de-simbolos/delegua.js +81 -81
  312. package/fontes/tipos-de-simbolos/egua-classico.d.ts +77 -77
  313. package/fontes/tipos-de-simbolos/egua-classico.js +78 -78
  314. package/fontes/tipos-de-simbolos/eguap.d.ts +73 -73
  315. package/fontes/tipos-de-simbolos/eguap.js +74 -74
  316. package/fontes/tipos-de-simbolos/guarani.d.ts +14 -14
  317. package/fontes/tipos-de-simbolos/guarani.js +15 -15
  318. package/fontes/tipos-de-simbolos/portugol-ipt.d.ts +28 -28
  319. package/fontes/tipos-de-simbolos/portugol-ipt.js +29 -29
  320. package/fontes/tipos-de-simbolos/portugol-studio.d.ts +53 -37
  321. package/fontes/tipos-de-simbolos/portugol-studio.js +54 -38
  322. package/fontes/tipos-de-simbolos/portugol-studio.js.map +1 -1
  323. package/fontes/tipos-de-simbolos/rantiaquin.d.ts +2 -2
  324. package/fontes/tipos-de-simbolos/rantiaquin.js +3 -3
  325. package/fontes/tipos-de-simbolos/visualg.d.ts +68 -68
  326. package/fontes/tipos-de-simbolos/visualg.js +69 -69
  327. package/fontes/tradutores/dicionarios/dicionario-delegua-javascript.d.ts +2 -2
  328. package/fontes/tradutores/dicionarios/dicionario-delegua-javascript.js +10 -10
  329. package/fontes/tradutores/dicionarios/index.d.ts +1 -1
  330. package/fontes/tradutores/dicionarios/index.js +17 -17
  331. package/fontes/tradutores/index.d.ts +2 -2
  332. package/fontes/tradutores/index.js +18 -18
  333. package/fontes/tradutores/python/python3-lexer.d.ts +152 -152
  334. package/fontes/tradutores/python/python3-lexer.js +1226 -1226
  335. package/fontes/tradutores/python/python3-listener.d.ts +953 -953
  336. package/fontes/tradutores/python/python3-listener.js +2 -2
  337. package/fontes/tradutores/python/python3-parser.d.ts +1330 -1330
  338. package/fontes/tradutores/python/python3-parser.js +11156 -11156
  339. package/fontes/tradutores/python/python3-visitor.d.ts +612 -612
  340. package/fontes/tradutores/python/python3-visitor.js +2 -2
  341. package/fontes/tradutores/tradutor-javascript.d.ts +83 -83
  342. package/fontes/tradutores/tradutor-javascript.js +470 -470
  343. package/fontes/tradutores/tradutor-javascript.js.map +1 -1
  344. package/fontes/tradutores/tradutor-python.d.ts +1 -1
  345. package/fontes/tradutores/tradutor-python.js +34 -34
  346. package/fontes/tradutores/tradutor-reverso-javascript.d.ts +47 -47
  347. package/fontes/tradutores/tradutor-reverso-javascript.js +342 -342
  348. package/index.d.ts +5 -5
  349. package/index.js +23 -23
  350. package/package.json +88 -88
@@ -1,973 +1,1001 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.InterpretadorBase = void 0;
7
- const browser_process_hrtime_1 = __importDefault(require("browser-process-hrtime"));
8
- const espaco_variaveis_1 = require("../espaco-variaveis");
9
- const biblioteca_global_1 = __importDefault(require("../bibliotecas/biblioteca-global"));
10
- const excecoes_1 = require("../excecoes");
11
- const estruturas_1 = require("../estruturas");
12
- const construtos_1 = require("../construtos");
13
- const pilha_escopos_execucao_1 = require("./pilha-escopos-execucao");
14
- const quebras_1 = require("../quebras");
15
- const inferenciador_1 = require("./inferenciador");
16
- const metodo_primitiva_1 = require("../estruturas/metodo-primitiva");
17
- const primitivas_texto_1 = __importDefault(require("../bibliotecas/primitivas-texto"));
18
- const primitivas_vetor_1 = __importDefault(require("../bibliotecas/primitivas-vetor"));
19
- const delegua_1 = __importDefault(require("../tipos-de-simbolos/delegua"));
20
- /**
21
- * O Interpretador visita todos os elementos complexos gerados pelo avaliador sintático (_parser_),
22
- * e de fato executa a lógica de programação descrita no código.
23
- *
24
- * O Interpretador Base não contém dependências com o Node.js. É
25
- * recomendado para uso em execuções que ocorrem no navegador de internet.
26
- */
27
- class InterpretadorBase {
28
- constructor(diretorioBase, performance = false, funcaoDeRetorno = null) {
29
- this.funcaoDeRetorno = null;
30
- this.interfaceDeEntrada = null;
31
- this.resultadoInterpretador = [];
32
- this.interfaceEntradaSaida = null;
33
- this.regexInterpolacao = /\$\{([a-z_][\w]*)\}/gi;
34
- this.diretorioBase = diretorioBase;
35
- this.performance = performance;
36
- this.funcaoDeRetorno = funcaoDeRetorno || console.log;
37
- this.erros = [];
38
- this.declaracoes = [];
39
- this.pilhaEscoposExecucao = new pilha_escopos_execucao_1.PilhaEscoposExecucao();
40
- const escopoExecucao = {
41
- declaracoes: [],
42
- declaracaoAtual: 0,
43
- ambiente: new espaco_variaveis_1.EspacoVariaveis(),
44
- finalizado: false,
45
- tipo: 'outro',
46
- };
47
- this.pilhaEscoposExecucao.empilhar(escopoExecucao);
48
- (0, biblioteca_global_1.default)(this, this.pilhaEscoposExecucao);
49
- }
50
- /**
51
- * Execução da leitura de valores da entrada configurada no
52
- * início da aplicação.
53
- * @param expressao Expressão do tipo Leia
54
- * @returns Promise com o resultado da leitura.
55
- */
56
- async visitarExpressaoLeia(expressao) {
57
- const mensagem = expressao.argumentos && expressao.argumentos[0] ? expressao.argumentos[0].valor : '> ';
58
- return new Promise((resolucao) => this.interfaceEntradaSaida.question(mensagem, (resposta) => {
59
- resolucao(resposta);
60
- }));
61
- }
62
- /**
63
- * Retira a interpolação de um texto.
64
- * @param {texto} texto O texto
65
- * @param {any[]} variaveis A lista de variaveis interpoladas
66
- * @returns O texto com o valor das variaveis.
67
- */
68
- retirarInterpolacao(texto, variaveis) {
69
- const valoresVariaveis = variaveis.map((v) => ({
70
- valorResolvido: this.pilhaEscoposExecucao.obterVariavelPorNome(v.variavel),
71
- variavel: v.variavel,
72
- }));
73
- let textoFinal = texto;
74
- valoresVariaveis.forEach((elemento) => {
75
- const valorFinal = elemento.valorResolvido.hasOwnProperty('valor')
76
- ? elemento.valorResolvido.valor
77
- : elemento.valorResolvido;
78
- textoFinal = textoFinal.replace('${' + elemento.variavel + '}', valorFinal);
79
- });
80
- return textoFinal;
81
- }
82
- /**
83
- * Busca variáveis interpoladas.
84
- * @param {texto} textoOriginal O texto original com as variáveis interpoladas.
85
- * @returns Uma lista de variáveis interpoladas.
86
- */
87
- buscarVariaveisInterpolacao(textoOriginal) {
88
- const variaveis = textoOriginal.match(this.regexInterpolacao);
89
- return variaveis.map((s) => {
90
- const nomeVariavel = s.replace(/[\$\{\}]*/g, '');
91
- return {
92
- variavel: nomeVariavel,
93
- valor: this.pilhaEscoposExecucao.obterVariavelPorNome(nomeVariavel),
94
- };
95
- });
96
- }
97
- visitarExpressaoLiteral(expressao) {
98
- if (this.regexInterpolacao.test(expressao.valor)) {
99
- const variaveis = this.buscarVariaveisInterpolacao(expressao.valor);
100
- return this.retirarInterpolacao(expressao.valor, variaveis);
101
- }
102
- return expressao.valor;
103
- }
104
- async avaliar(expressao) {
105
- // Descomente o código abaixo quando precisar detectar expressões undefined ou nulas.
106
- // Por algum motivo o depurador do VSCode não funciona direito aqui
107
- // com breakpoint condicional.
108
- /* if (expressao === null || expressao === undefined) {
109
- console.log('Aqui');
110
- } */
111
- return await expressao.aceitar(this);
112
- }
113
- async visitarExpressaoAgrupamento(expressao) {
114
- return await this.avaliar(expressao.expressao);
115
- }
116
- eVerdadeiro(objeto) {
117
- if (objeto === null)
118
- return false;
119
- if (typeof objeto === 'boolean')
120
- return Boolean(objeto);
121
- if (objeto.hasOwnProperty('valor')) {
122
- return Boolean(objeto.valor);
123
- }
124
- return true;
125
- }
126
- verificarOperandoNumero(operador, operando) {
127
- if (typeof operando === 'number' || operando.tipo === 'número')
128
- return;
129
- throw new excecoes_1.ErroEmTempoDeExecucao(operador, 'Operando precisa ser um número.', Number(operador.linha));
130
- }
131
- async visitarExpressaoUnaria(expressao) {
132
- const direita = await this.avaliar(expressao.direita);
133
- const valor = direita.hasOwnProperty('valor') ? direita.valor : direita;
134
- switch (expressao.operador.tipo) {
135
- case delegua_1.default.SUBTRACAO:
136
- this.verificarOperandoNumero(expressao.operador, valor);
137
- return -valor;
138
- case delegua_1.default.NEGACAO:
139
- return !this.eVerdadeiro(valor);
140
- case delegua_1.default.BIT_NOT:
141
- return ~valor;
142
- }
143
- return null;
144
- }
145
- async visitarExpressaoFormatacaoEscrita(declaracao) {
146
- let resultado = '';
147
- const conteudo = await this.avaliar(declaracao.expressao);
148
- const valorConteudo = (conteudo === null || conteudo === void 0 ? void 0 : conteudo.hasOwnProperty('valor')) ? conteudo.valor : conteudo;
149
- const tipoConteudo = conteudo.hasOwnProperty('tipo') ? conteudo.tipo : typeof conteudo;
150
- resultado = valorConteudo;
151
- if (['número', 'number'].includes(tipoConteudo) && declaracao.casasDecimais > 0) {
152
- resultado = valorConteudo.toLocaleString('pt', { maximumFractionDigits: declaracao.casasDecimais });
153
- }
154
- if (declaracao.espacos > 0) {
155
- resultado += ' '.repeat(declaracao.espacos);
156
- }
157
- return resultado;
158
- }
159
- eIgual(esquerda, direita) {
160
- if (esquerda === null && direita === null)
161
- return true;
162
- if (esquerda === null)
163
- return false;
164
- return esquerda === direita;
165
- }
166
- /**
167
- * Verifica se operandos são números, que podem ser tanto variáveis puras do JavaScript
168
- * (neste caso, `number`), ou podem ser variáveis de Delégua com inferência (`VariavelInterface`).
169
- * @param operador O símbolo do operador.
170
- * @param direita O operando direito.
171
- * @param esquerda O operando esquerdo.
172
- * @returns Se ambos os operandos são números ou não.
173
- */
174
- verificarOperandosNumeros(operador, direita, esquerda) {
175
- const tipoDireita = direita.tipo ? direita.tipo : typeof direita === 'number' ? 'número' : String(NaN);
176
- const tipoEsquerda = esquerda.tipo
177
- ? esquerda.tipo
178
- : typeof esquerda === 'number'
179
- ? 'número'
180
- : String(NaN);
181
- if (tipoDireita === 'número' && tipoEsquerda === 'número')
182
- return;
183
- throw new excecoes_1.ErroEmTempoDeExecucao(operador, 'Operadores precisam ser números.', operador.linha);
184
- }
185
- async visitarExpressaoBinaria(expressao) {
186
- try {
187
- const esquerda = await this.avaliar(expressao.esquerda);
188
- const direita = await this.avaliar(expressao.direita);
189
- const valorEsquerdo = (esquerda === null || esquerda === void 0 ? void 0 : esquerda.hasOwnProperty('valor')) ? esquerda.valor : esquerda;
190
- const valorDireito = (direita === null || direita === void 0 ? void 0 : direita.hasOwnProperty('valor')) ? direita.valor : direita;
191
- const tipoEsquerdo = (esquerda === null || esquerda === void 0 ? void 0 : esquerda.hasOwnProperty('tipo'))
192
- ? esquerda.tipo
193
- : (0, inferenciador_1.inferirTipoVariavel)(esquerda);
194
- const tipoDireito = (direita === null || direita === void 0 ? void 0 : direita.hasOwnProperty('tipo')) ? direita.tipo : (0, inferenciador_1.inferirTipoVariavel)(direita);
195
- switch (expressao.operador.tipo) {
196
- case delegua_1.default.EXPONENCIACAO:
197
- this.verificarOperandosNumeros(expressao.operador, esquerda, direita);
198
- return Math.pow(valorEsquerdo, valorDireito);
199
- case delegua_1.default.MAIOR:
200
- this.verificarOperandosNumeros(expressao.operador, esquerda, direita);
201
- return Number(valorEsquerdo) > Number(valorDireito);
202
- case delegua_1.default.MAIOR_IGUAL:
203
- this.verificarOperandosNumeros(expressao.operador, esquerda, direita);
204
- return Number(valorEsquerdo) >= Number(valorDireito);
205
- case delegua_1.default.MENOR:
206
- this.verificarOperandosNumeros(expressao.operador, esquerda, direita);
207
- return Number(valorEsquerdo) < Number(valorDireito);
208
- case delegua_1.default.MENOR_IGUAL:
209
- this.verificarOperandosNumeros(expressao.operador, esquerda, direita);
210
- return Number(valorEsquerdo) <= Number(valorDireito);
211
- case delegua_1.default.SUBTRACAO:
212
- case delegua_1.default.MENOS_IGUAL:
213
- this.verificarOperandosNumeros(expressao.operador, esquerda, direita);
214
- return Number(valorEsquerdo) - Number(valorDireito);
215
- case delegua_1.default.ADICAO:
216
- case delegua_1.default.MAIS_IGUAL:
217
- if (tipoEsquerdo === 'número' && tipoDireito === 'número') {
218
- return Number(valorEsquerdo) + Number(valorDireito);
219
- }
220
- else {
221
- return String(valorEsquerdo) + String(valorDireito);
222
- }
223
- case delegua_1.default.DIVISAO:
224
- case delegua_1.default.DIVISAO_IGUAL:
225
- this.verificarOperandosNumeros(expressao.operador, esquerda, direita);
226
- return Number(valorEsquerdo) / Number(valorDireito);
227
- case delegua_1.default.DIVISAO_INTEIRA:
228
- case delegua_1.default.DIVISAO_INTEIRA_IGUAL:
229
- this.verificarOperandosNumeros(expressao.operador, esquerda, direita);
230
- return Math.floor(Number(valorEsquerdo) / Number(valorDireito));
231
- case delegua_1.default.MULTIPLICACAO:
232
- case delegua_1.default.MULTIPLICACAO_IGUAL:
233
- if (tipoEsquerdo === 'texto' || tipoDireito === 'texto') {
234
- // Sem ambos os valores resolvem como texto, multiplica normal.
235
- // Se apenas um resolve como texto, o outro repete o
236
- // texto n vezes, sendo n o valor do outro.
237
- if (tipoEsquerdo === 'texto' && tipoDireito === 'texto') {
238
- return Number(valorEsquerdo) * Number(valorDireito);
239
- }
240
- if (tipoEsquerdo === 'texto') {
241
- return valorEsquerdo.repeat(Number(valorDireito));
242
- }
243
- return valorDireito.repeat(Number(valorEsquerdo));
244
- }
245
- return Number(valorEsquerdo) * Number(valorDireito);
246
- case delegua_1.default.MODULO:
247
- case delegua_1.default.MODULO_IGUAL:
248
- this.verificarOperandosNumeros(expressao.operador, esquerda, direita);
249
- return Number(valorEsquerdo) % Number(valorDireito);
250
- case delegua_1.default.BIT_AND:
251
- this.verificarOperandosNumeros(expressao.operador, esquerda, direita);
252
- return Number(valorEsquerdo) & Number(valorDireito);
253
- case delegua_1.default.BIT_XOR:
254
- this.verificarOperandosNumeros(expressao.operador, esquerda, direita);
255
- return Number(valorEsquerdo) ^ Number(valorDireito);
256
- case delegua_1.default.BIT_OR:
257
- this.verificarOperandosNumeros(expressao.operador, esquerda, direita);
258
- return Number(valorEsquerdo) | Number(valorDireito);
259
- case delegua_1.default.MENOR_MENOR:
260
- this.verificarOperandosNumeros(expressao.operador, esquerda, direita);
261
- return Number(valorEsquerdo) << Number(valorDireito);
262
- case delegua_1.default.MAIOR_MAIOR:
263
- this.verificarOperandosNumeros(expressao.operador, esquerda, direita);
264
- return Number(valorEsquerdo) >> Number(valorDireito);
265
- case delegua_1.default.DIFERENTE:
266
- return !this.eIgual(valorEsquerdo, valorDireito);
267
- case delegua_1.default.IGUAL_IGUAL:
268
- return this.eIgual(valorEsquerdo, valorDireito);
269
- }
270
- }
271
- catch (erro) {
272
- return Promise.reject(erro);
273
- }
274
- }
275
- /**
276
- * Executa uma chamada de função, método ou classe.
277
- * @param expressao A expressão chamada.
278
- * @returns O resultado da chamada.
279
- */
280
- async visitarExpressaoDeChamada(expressao) {
281
- try {
282
- const variavelEntidadeChamada = await this.avaliar(expressao.entidadeChamada);
283
- if (variavelEntidadeChamada === null) {
284
- return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(expressao.parentese, 'Chamada de função ou método inexistente: ' + String(expressao.entidadeChamada), expressao.linha));
285
- }
286
- const entidadeChamada = variavelEntidadeChamada.hasOwnProperty('valor')
287
- ? variavelEntidadeChamada.valor
288
- : variavelEntidadeChamada;
289
- let argumentos = [];
290
- for (let i = 0; i < expressao.argumentos.length; i++) {
291
- argumentos.push(await this.avaliar(expressao.argumentos[i]));
292
- }
293
- if (entidadeChamada instanceof estruturas_1.DeleguaModulo) {
294
- return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(expressao.parentese, 'Entidade chamada é um módulo de Delégua. Provavelmente você quer chamar um de seus componentes?', expressao.linha));
295
- }
296
- if (entidadeChamada instanceof metodo_primitiva_1.MetodoPrimitiva) {
297
- const argumentosResolvidos = [];
298
- for (const argumento of expressao.argumentos) {
299
- const valorResolvido = await this.avaliar(argumento);
300
- argumentosResolvidos.push(valorResolvido.hasOwnProperty('valor') ? valorResolvido.valor : valorResolvido);
301
- }
302
- return entidadeChamada.chamar(argumentosResolvidos);
303
- }
304
- let parametros;
305
- if (entidadeChamada instanceof estruturas_1.DeleguaFuncao) {
306
- parametros = entidadeChamada.declaracao.parametros;
307
- }
308
- else if (entidadeChamada instanceof estruturas_1.DeleguaClasse) {
309
- parametros = entidadeChamada.metodos.inicializacao
310
- ? entidadeChamada.metodos.inicializacao.declaracao.parametros
311
- : [];
312
- }
313
- else {
314
- parametros = [];
315
- }
316
- const aridade = entidadeChamada.aridade ? entidadeChamada.aridade() : entidadeChamada.length;
317
- // Completar os parâmetros não preenchidos com nulos.
318
- if (argumentos.length < aridade) {
319
- const diferenca = aridade - argumentos.length;
320
- for (let i = 0; i < diferenca; i++) {
321
- argumentos.push(null);
322
- }
323
- }
324
- else {
325
- if (parametros && parametros.length > 0 && parametros[parametros.length - 1].tipo === 'estrela') {
326
- const novosArgumentos = argumentos.slice(0, parametros.length - 1);
327
- novosArgumentos.push(argumentos.slice(parametros.length - 1, argumentos.length));
328
- argumentos = novosArgumentos;
329
- }
330
- }
331
- if (entidadeChamada instanceof estruturas_1.FuncaoPadrao) {
332
- try {
333
- return entidadeChamada.chamar(argumentos.map((a) => (a !== null && a.hasOwnProperty('valor') ? a.valor : a)), expressao.entidadeChamada.nome);
334
- }
335
- catch (erro) {
336
- this.erros.push(erro);
337
- }
338
- }
339
- if (entidadeChamada instanceof estruturas_1.Chamavel) {
340
- return entidadeChamada.chamar(this, argumentos);
341
- }
342
- // A função chamada pode ser de uma biblioteca JavaScript.
343
- // Neste caso apenas testamos se o tipo é uma função.
344
- if (typeof entidadeChamada === 'function') {
345
- let objeto = null;
346
- if (expressao.entidadeChamada.objeto) {
347
- objeto = await this.avaliar(expressao.entidadeChamada.objeto);
348
- }
349
- return entidadeChamada.apply(objeto.hasOwnProperty('valor') ? objeto.valor : objeto, argumentos);
350
- }
351
- return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(expressao.parentese, 'Só pode chamar função ou classe.', expressao.linha));
352
- }
353
- catch (erro) {
354
- console.log(erro);
355
- }
356
- }
357
- /**
358
- * Execução de uma expressão de atribuição.
359
- * @param expressao A expressão.
360
- * @returns O valor atribuído.
361
- */
362
- async visitarDeclaracaoDeAtribuicao(expressao) {
363
- const valor = await this.avaliar(expressao.valor);
364
- this.pilhaEscoposExecucao.atribuirVariavel(expressao.simbolo, valor);
365
- return valor;
366
- }
367
- procurarVariavel(simbolo) {
368
- return this.pilhaEscoposExecucao.obterValorVariavel(simbolo);
369
- }
370
- visitarExpressaoDeVariavel(expressao) {
371
- return this.procurarVariavel(expressao.simbolo);
372
- }
373
- async visitarDeclaracaoDeExpressao(declaracao) {
374
- return await this.avaliar(declaracao.expressao);
375
- }
376
- async visitarExpressaoLogica(expressao) {
377
- const esquerda = await this.avaliar(expressao.esquerda);
378
- if (expressao.operador.tipo === delegua_1.default.EM) {
379
- const direita = await this.avaliar(expressao.direita);
380
- if (Array.isArray(direita) || typeof direita === 'string') {
381
- return direita.includes(esquerda);
382
- }
383
- else if (direita.constructor === Object) {
384
- return esquerda in direita;
385
- }
386
- else {
387
- throw new excecoes_1.ErroEmTempoDeExecucao(esquerda, "Tipo de chamada inválida com 'em'.", expressao.linha);
388
- }
389
- }
390
- // se um estado for verdadeiro, retorna verdadeiro
391
- if (expressao.operador.tipo === delegua_1.default.OU) {
392
- if (this.eVerdadeiro(esquerda))
393
- return esquerda;
394
- }
395
- // se um estado for falso, retorna falso
396
- if (expressao.operador.tipo === delegua_1.default.E) {
397
- if (!this.eVerdadeiro(esquerda))
398
- return esquerda;
399
- }
400
- return await this.avaliar(expressao.direita);
401
- }
402
- /**
403
- * Executa uma expressão Se, que tem uma condição, pode ter um bloco
404
- * Senão, e múltiplos blocos Senão-se.
405
- * @param declaracao A declaração Se.
406
- * @returns O resultado da avaliação do bloco cuja condição é verdadeira.
407
- */
408
- async visitarDeclaracaoSe(declaracao) {
409
- if (this.eVerdadeiro(await this.avaliar(declaracao.condicao))) {
410
- return await this.executar(declaracao.caminhoEntao);
411
- }
412
- for (let i = 0; i < declaracao.caminhosSeSenao.length; i++) {
413
- const atual = declaracao.caminhosSeSenao[i];
414
- if (this.eVerdadeiro(await this.avaliar(atual.condicao))) {
415
- return await this.executar(atual.caminho);
416
- }
417
- }
418
- if (declaracao.caminhoSenao !== null) {
419
- return await this.executar(declaracao.caminhoSenao);
420
- }
421
- return null;
422
- }
423
- async visitarDeclaracaoPara(declaracao) {
424
- if (declaracao.inicializador !== null) {
425
- await this.avaliar(declaracao.inicializador);
426
- }
427
- let retornoExecucao;
428
- while (!(retornoExecucao instanceof quebras_1.Quebra)) {
429
- if (declaracao.condicao !== null && !this.eVerdadeiro(await this.avaliar(declaracao.condicao))) {
430
- break;
431
- }
432
- try {
433
- retornoExecucao = await this.executar(declaracao.corpo);
434
- if (retornoExecucao instanceof quebras_1.ContinuarQuebra) {
435
- retornoExecucao = null;
436
- }
437
- }
438
- catch (erro) {
439
- return Promise.reject(erro);
440
- }
441
- if (declaracao.incrementar !== null) {
442
- await this.avaliar(declaracao.incrementar);
443
- }
444
- }
445
- return null;
446
- }
447
- async visitarDeclaracaoFazer(declaracao) {
448
- let retornoExecucao;
449
- do {
450
- try {
451
- retornoExecucao = await this.executar(declaracao.caminhoFazer);
452
- if (retornoExecucao instanceof quebras_1.ContinuarQuebra) {
453
- retornoExecucao = null;
454
- }
455
- }
456
- catch (erro) {
457
- return Promise.reject(erro);
458
- }
459
- } while (!(retornoExecucao instanceof quebras_1.Quebra) &&
460
- this.eVerdadeiro(await this.avaliar(declaracao.condicaoEnquanto)));
461
- }
462
- async visitarDeclaracaoEscolha(declaracao) {
463
- const condicaoEscolha = await this.avaliar(declaracao.identificadorOuLiteral);
464
- const valorCondicaoEscolha = condicaoEscolha.hasOwnProperty('valor') ?
465
- condicaoEscolha.valor :
466
- condicaoEscolha;
467
- const caminhos = declaracao.caminhos;
468
- const caminhoPadrao = declaracao.caminhoPadrao;
469
- let encontrado = false;
470
- try {
471
- for (let i = 0; i < caminhos.length; i++) {
472
- const caminho = caminhos[i];
473
- for (let j = 0; j < caminho.condicoes.length; j++) {
474
- const condicaoAvaliada = await this.avaliar(caminho.condicoes[j]);
475
- if (condicaoAvaliada === valorCondicaoEscolha) {
476
- encontrado = true;
477
- try {
478
- await this.executarBloco(caminho.declaracoes);
479
- }
480
- catch (erro) {
481
- return Promise.reject(erro);
482
- }
483
- }
484
- }
485
- }
486
- if (caminhoPadrao !== null && !encontrado) {
487
- await this.executarBloco(caminhoPadrao.declaracoes);
488
- }
489
- }
490
- catch (erro) {
491
- throw erro;
492
- }
493
- }
494
- /**
495
- * Interpretação de uma declaração `tente`.
496
- * @param declaracao O objeto da declaração.
497
- */
498
- async visitarDeclaracaoTente(declaracao) {
499
- let valorRetorno;
500
- try {
501
- let sucesso = true;
502
- try {
503
- valorRetorno = await this.executarBloco(declaracao.caminhoTente);
504
- }
505
- catch (erro) {
506
- sucesso = false;
507
- if (declaracao.caminhoPegue !== null) {
508
- // `caminhoPegue` aqui pode ser um construto de função (se `pegue` tem parâmetros)
509
- // ou um vetor de `Declaracao` (`pegue` sem parâmetros).
510
- // As execuções, portanto, são diferentes.
511
- if (Array.isArray(declaracao.caminhoPegue)) {
512
- valorRetorno = await this.executarBloco(declaracao.caminhoPegue);
513
- }
514
- else {
515
- const literalErro = new construtos_1.Literal(declaracao.hashArquivo, Number(declaracao.linha), erro.mensagem);
516
- const chamadaPegue = new construtos_1.Chamada(declaracao.caminhoPegue.hashArquivo, declaracao.caminhoPegue, null, [literalErro]);
517
- valorRetorno = await chamadaPegue.aceitar(this);
518
- }
519
- }
520
- }
521
- }
522
- finally {
523
- if (declaracao.caminhoFinalmente !== null)
524
- valorRetorno = await this.executarBloco(declaracao.caminhoFinalmente);
525
- }
526
- return valorRetorno;
527
- }
528
- async visitarDeclaracaoEnquanto(declaracao) {
529
- let retornoExecucao;
530
- while (!(retornoExecucao instanceof quebras_1.Quebra) && this.eVerdadeiro(await this.avaliar(declaracao.condicao))) {
531
- try {
532
- retornoExecucao = await this.executar(declaracao.corpo);
533
- if (retornoExecucao instanceof quebras_1.ContinuarQuebra) {
534
- retornoExecucao = null;
535
- }
536
- }
537
- catch (erro) {
538
- throw erro;
539
- }
540
- }
541
- return null;
542
- }
543
- async visitarDeclaracaoImportar(declaracao) {
544
- return Promise.reject("Importação de arquivos não suportada por Interpretador Base.");
545
- }
546
- async avaliarArgumentosEscreva(argumentos) {
547
- let formatoTexto = '';
548
- for (const argumento of argumentos) {
549
- const resultadoAvaliacao = await this.avaliar(argumento);
550
- let valor = (resultadoAvaliacao === null || resultadoAvaliacao === void 0 ? void 0 : resultadoAvaliacao.hasOwnProperty('valor')) ? resultadoAvaliacao.valor : resultadoAvaliacao;
551
- formatoTexto += `${this.paraTexto(valor)} `;
552
- }
553
- return formatoTexto;
554
- }
555
- /**
556
- * Execução de uma escrita na saída padrão, sem quebras de linha.
557
- * Implementada para alguns dialetos, como VisuAlg.
558
- * @param declaracao A declaração.
559
- * @returns Sempre nulo, por convenção de visita.
560
- */
561
- async visitarExpressaoEscrevaMesmaLinha(declaracao) {
562
- try {
563
- const formatoTexto = await this.avaliarArgumentosEscreva(declaracao.argumentos);
564
- process.stdout.write(formatoTexto);
565
- return null;
566
- }
567
- catch (erro) {
568
- this.erros.push({
569
- erroInterno: erro,
570
- linha: declaracao.linha,
571
- hashArquivo: declaracao.hashArquivo,
572
- });
573
- }
574
- }
575
- /**
576
- * Execução de uma escrita na saída configurada, que pode ser `console` (padrão) ou
577
- * alguma função para escrever numa página Web.
578
- * @param declaracao A declaração.
579
- * @returns Sempre nulo, por convenção de visita.
580
- */
581
- async visitarDeclaracaoEscreva(declaracao) {
582
- try {
583
- const formatoTexto = await this.avaliarArgumentosEscreva(declaracao.argumentos);
584
- this.funcaoDeRetorno(formatoTexto);
585
- return null;
586
- }
587
- catch (erro) {
588
- this.erros.push({
589
- erroInterno: erro,
590
- linha: declaracao.linha,
591
- hashArquivo: declaracao.hashArquivo,
592
- });
593
- }
594
- }
595
- /**
596
- * Empilha declarações na pilha de escopos de execução, cria um novo ambiente e
597
- * executa as declarações empilhadas.
598
- * Se o retorno do último bloco foi uma exceção (normalmente um erro em tempo de execução),
599
- * atira a exceção daqui.
600
- * Isso é usado, por exemplo, em blocos tente ... pegue ... finalmente.
601
- * @param declaracoes Um vetor de declaracoes a ser executado.
602
- * @param ambiente O ambiente de execução quando houver, como parâmetros, argumentos, etc.
603
- */
604
- async executarBloco(declaracoes, ambiente) {
605
- const escopoExecucao = {
606
- declaracoes: declaracoes,
607
- declaracaoAtual: 0,
608
- ambiente: ambiente || new espaco_variaveis_1.EspacoVariaveis(),
609
- finalizado: false,
610
- tipo: 'outro',
611
- };
612
- this.pilhaEscoposExecucao.empilhar(escopoExecucao);
613
- const retornoUltimoEscopo = await this.executarUltimoEscopo();
614
- if (retornoUltimoEscopo instanceof excecoes_1.ErroEmTempoDeExecucao) {
615
- return Promise.reject(retornoUltimoEscopo);
616
- }
617
- return retornoUltimoEscopo;
618
- }
619
- async visitarExpressaoBloco(declaracao) {
620
- return await this.executarBloco(declaracao.declaracoes);
621
- }
622
- async avaliacaoDeclaracaoVar(declaracao) {
623
- let valorOuOutraVariavel = null;
624
- if (declaracao.inicializador !== null) {
625
- valorOuOutraVariavel = await this.avaliar(declaracao.inicializador);
626
- }
627
- let valorFinal = null;
628
- if (valorOuOutraVariavel !== null && valorOuOutraVariavel !== undefined) {
629
- valorFinal = valorOuOutraVariavel.hasOwnProperty('valor')
630
- ? valorOuOutraVariavel.valor
631
- : valorOuOutraVariavel;
632
- }
633
- return valorFinal;
634
- }
635
- /**
636
- * Executa expressão de definição de variável.
637
- * @param declaracao A declaração Var
638
- * @returns Sempre retorna nulo.
639
- */
640
- async visitarDeclaracaoVar(declaracao) {
641
- const valorFinal = await this.avaliacaoDeclaracaoVar(declaracao);
642
- this.pilhaEscoposExecucao.definirVariavel(declaracao.simbolo.lexema, valorFinal);
643
- return null;
644
- }
645
- visitarExpressaoContinua(declaracao) {
646
- return new quebras_1.ContinuarQuebra();
647
- }
648
- visitarExpressaoSustar(declaracao) {
649
- return new quebras_1.SustarQuebra();
650
- }
651
- async visitarExpressaoRetornar(declaracao) {
652
- let valor = null;
653
- if (declaracao.valor != null)
654
- valor = await this.avaliar(declaracao.valor);
655
- return new quebras_1.RetornoQuebra(valor);
656
- }
657
- visitarExpressaoDeleguaFuncao(declaracao) {
658
- return new estruturas_1.DeleguaFuncao(null, declaracao);
659
- }
660
- async visitarExpressaoAtribuicaoSobrescrita(expressao) {
661
- const promises = await Promise.all([
662
- this.avaliar(expressao.objeto),
663
- this.avaliar(expressao.indice),
664
- this.avaliar(expressao.valor),
665
- ]);
666
- let objeto = promises[0];
667
- let indice = promises[1];
668
- const valor = promises[2];
669
- objeto = objeto.hasOwnProperty('valor') ? objeto.valor : objeto;
670
- indice = indice.hasOwnProperty('valor') ? indice.valor : indice;
671
- if (Array.isArray(objeto)) {
672
- if (indice < 0 && objeto.length !== 0) {
673
- while (indice < 0) {
674
- indice += objeto.length;
675
- }
676
- }
677
- while (objeto.length < indice) {
678
- objeto.push(null);
679
- }
680
- objeto[indice] = valor;
681
- }
682
- else if (objeto.constructor === Object ||
683
- objeto instanceof estruturas_1.ObjetoDeleguaClasse ||
684
- objeto instanceof estruturas_1.DeleguaFuncao ||
685
- objeto instanceof estruturas_1.DeleguaClasse ||
686
- objeto instanceof estruturas_1.DeleguaModulo) {
687
- objeto[indice] = valor;
688
- }
689
- else {
690
- return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(expressao.objeto.nome, 'Somente listas, dicionários, classes e objetos podem ser mudados por sobrescrita.', expressao.linha));
691
- }
692
- }
693
- async visitarExpressaoAcessoIndiceVariavel(expressao) {
694
- const variavelObjeto = await this.avaliar(expressao.entidadeChamada);
695
- const objeto = variavelObjeto.hasOwnProperty('valor') ? variavelObjeto.valor : variavelObjeto;
696
- const indice = await this.avaliar(expressao.indice);
697
- let valorIndice = indice.hasOwnProperty('valor') ? indice.valor : indice;
698
- if (Array.isArray(objeto)) {
699
- if (!Number.isInteger(valorIndice)) {
700
- return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(expressao.simboloFechamento, 'Somente inteiros podem ser usados para indexar um vetor.', expressao.linha));
701
- }
702
- if (valorIndice < 0 && objeto.length !== 0) {
703
- while (valorIndice < 0) {
704
- valorIndice += objeto.length;
705
- }
706
- }
707
- if (valorIndice >= objeto.length) {
708
- return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(expressao.simboloFechamento, 'Índice do vetor fora do intervalo.', expressao.linha));
709
- }
710
- return objeto[valorIndice];
711
- }
712
- else if (objeto.constructor === Object ||
713
- objeto instanceof estruturas_1.ObjetoDeleguaClasse ||
714
- objeto instanceof estruturas_1.DeleguaFuncao ||
715
- objeto instanceof estruturas_1.DeleguaClasse ||
716
- objeto instanceof estruturas_1.DeleguaModulo) {
717
- return objeto[valorIndice] || null;
718
- }
719
- else if (typeof objeto === 'string') {
720
- if (!Number.isInteger(valorIndice)) {
721
- return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(expressao.simboloFechamento, 'Somente inteiros podem ser usados para indexar um vetor.', expressao.linha));
722
- }
723
- if (valorIndice < 0 && objeto.length !== 0) {
724
- while (valorIndice < 0) {
725
- valorIndice += objeto.length;
726
- }
727
- }
728
- if (valorIndice >= objeto.length) {
729
- return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(expressao.simboloFechamento, 'Índice fora do tamanho.', expressao.linha));
730
- }
731
- return objeto.charAt(valorIndice);
732
- }
733
- else {
734
- return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(expressao.entidadeChamada.nome, 'Somente listas, dicionários, classes e objetos podem ser mudados por sobrescrita.', expressao.linha));
735
- }
736
- }
737
- async visitarExpressaoDefinirValor(expressao) {
738
- const variavelObjeto = await this.avaliar(expressao.objeto);
739
- const objeto = variavelObjeto.hasOwnProperty('valor') ? variavelObjeto.valor : variavelObjeto;
740
- if (!(objeto instanceof estruturas_1.ObjetoDeleguaClasse) && objeto.constructor !== Object) {
741
- return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(expressao.objeto.nome, 'Somente instâncias e dicionários podem possuir campos.', expressao.linha));
742
- }
743
- const valor = await this.avaliar(expressao.valor);
744
- if (objeto instanceof estruturas_1.ObjetoDeleguaClasse) {
745
- objeto.definir(expressao.nome, valor);
746
- return valor;
747
- }
748
- else if (objeto.constructor === Object) {
749
- objeto[expressao.simbolo.lexema] = valor;
750
- }
751
- }
752
- visitarDeclaracaoDefinicaoFuncao(declaracao) {
753
- const funcao = new estruturas_1.DeleguaFuncao(declaracao.simbolo.lexema, declaracao.funcao);
754
- this.pilhaEscoposExecucao.definirVariavel(declaracao.simbolo.lexema, funcao);
755
- }
756
- /**
757
- * Executa uma declaração de classe.
758
- * @param declaracao A declaração de classe.
759
- * @returns Sempre retorna nulo, por ser requerido pelo contrato de visita.
760
- */
761
- async visitarDeclaracaoClasse(declaracao) {
762
- let superClasse = null;
763
- if (declaracao.superClasse !== null) {
764
- const variavelSuperClasse = await this.avaliar(declaracao.superClasse);
765
- superClasse = variavelSuperClasse.valor;
766
- if (!(superClasse instanceof estruturas_1.DeleguaClasse)) {
767
- throw new excecoes_1.ErroEmTempoDeExecucao(declaracao.superClasse.nome, 'Superclasse precisa ser uma classe.', declaracao.linha);
768
- }
769
- }
770
- this.pilhaEscoposExecucao.definirVariavel(declaracao.simbolo.lexema, null);
771
- if (declaracao.superClasse !== null) {
772
- this.pilhaEscoposExecucao.definirVariavel('super', superClasse);
773
- }
774
- const metodos = {};
775
- const definirMetodos = declaracao.metodos;
776
- for (let i = 0; i < declaracao.metodos.length; i++) {
777
- const metodoAtual = definirMetodos[i];
778
- const eInicializador = metodoAtual.simbolo.lexema === 'construtor';
779
- const funcao = new estruturas_1.DeleguaFuncao(metodoAtual.simbolo.lexema, metodoAtual.funcao, undefined, eInicializador);
780
- metodos[metodoAtual.simbolo.lexema] = funcao;
781
- }
782
- const deleguaClasse = new estruturas_1.DeleguaClasse(declaracao.simbolo.lexema, superClasse, metodos);
783
- // TODO: Recolocar isso se for necessário.
784
- /* if (superClasse !== null) {
785
- this.ambiente = this.ambiente.enclosing;
786
- } */
787
- this.pilhaEscoposExecucao.atribuirVariavel(declaracao.simbolo, deleguaClasse);
788
- return null;
789
- }
790
- /**
791
- * Executa um acesso a método, normalmente de um objeto de classe.
792
- * @param expressao A expressão de acesso.
793
- * @returns O resultado da execução.
794
- */
795
- async visitarExpressaoAcessoMetodo(expressao) {
796
- const variavelObjeto = await this.avaliar(expressao.objeto);
797
- const objeto = variavelObjeto.hasOwnProperty('valor') ? variavelObjeto.valor : variavelObjeto;
798
- if (objeto instanceof estruturas_1.ObjetoDeleguaClasse) {
799
- return objeto.obter(expressao.simbolo) || null;
800
- }
801
- // TODO: Possivelmente depreciar esta forma.
802
- // Não parece funcionar em momento algum.
803
- if (objeto.constructor === Object) {
804
- return objeto[expressao.simbolo.lexema] || null;
805
- }
806
- // Função tradicional do JavaScript.
807
- // Normalmente executa quando uma biblioteca é importada.
808
- if (typeof objeto[expressao.simbolo.lexema] === 'function') {
809
- return objeto[expressao.simbolo.lexema];
810
- }
811
- // Objeto tradicional do JavaScript.
812
- // Normalmente executa quando uma biblioteca é importada.
813
- if (typeof objeto[expressao.simbolo.lexema] === 'object') {
814
- return objeto[expressao.simbolo.lexema];
815
- }
816
- if (objeto instanceof estruturas_1.DeleguaModulo) {
817
- return objeto.componentes[expressao.simbolo.lexema] || null;
818
- }
819
- switch (variavelObjeto.tipo) {
820
- case 'texto':
821
- const metodoDePrimitivaTexto = primitivas_texto_1.default[expressao.simbolo.lexema];
822
- if (metodoDePrimitivaTexto) {
823
- return new metodo_primitiva_1.MetodoPrimitiva(objeto, metodoDePrimitivaTexto);
824
- }
825
- break;
826
- case 'vetor':
827
- const metodoDePrimitivaVetor = primitivas_vetor_1.default[expressao.simbolo.lexema];
828
- if (metodoDePrimitivaVetor) {
829
- return new metodo_primitiva_1.MetodoPrimitiva(objeto, metodoDePrimitivaVetor);
830
- }
831
- break;
832
- }
833
- return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(expressao.nome, 'Você só pode acessar métodos do objeto e dicionários.', expressao.linha));
834
- }
835
- visitarExpressaoIsto(expressao) {
836
- return this.procurarVariavel(expressao.palavraChave);
837
- }
838
- async visitarExpressaoDicionario(expressao) {
839
- const dicionario = {};
840
- for (let i = 0; i < expressao.chaves.length; i++) {
841
- const promises = await Promise.all([this.avaliar(expressao.chaves[i]), this.avaliar(expressao.valores[i])]);
842
- dicionario[promises[0]] = promises[1];
843
- }
844
- return dicionario;
845
- }
846
- async visitarExpressaoVetor(expressao) {
847
- const valores = [];
848
- for (let i = 0; i < expressao.valores.length; i++) {
849
- valores.push(await this.avaliar(expressao.valores[i]));
850
- }
851
- return valores;
852
- }
853
- // TODO: Após remoção do Resolvedor, simular casos que usem 'super' e 'isto'.
854
- visitarExpressaoSuper(expressao) {
855
- const superClasse = this.pilhaEscoposExecucao.obterVariavelPorNome('super');
856
- const objeto = this.pilhaEscoposExecucao.obterVariavelPorNome('isto');
857
- const metodo = superClasse.valor.encontrarMetodo(expressao.metodo.lexema);
858
- if (metodo === undefined) {
859
- throw new excecoes_1.ErroEmTempoDeExecucao(expressao.metodo, 'Método chamado indefinido.', expressao.linha);
860
- }
861
- return metodo.definirInstancia(objeto.valor);
862
- }
863
- paraTexto(objeto) {
864
- if (objeto === null || objeto === undefined)
865
- return 'nulo';
866
- if (typeof objeto === 'boolean') {
867
- return objeto ? 'verdadeiro' : 'falso';
868
- }
869
- if (objeto instanceof Date) {
870
- const formato = Intl.DateTimeFormat('pt', {
871
- dateStyle: 'full',
872
- timeStyle: 'full',
873
- });
874
- return formato.format(objeto);
875
- }
876
- if (Array.isArray(objeto))
877
- return objeto;
878
- if (objeto.valor instanceof estruturas_1.ObjetoPadrao)
879
- return objeto.valor.paraTexto();
880
- if (typeof objeto === 'object')
881
- return JSON.stringify(objeto);
882
- return objeto.toString();
883
- }
884
- /**
885
- * Efetivamente executa uma declaração.
886
- * @param declaracao A declaração a ser executada.
887
- * @param mostrarResultado Se resultado deve ser mostrado ou não. Normalmente usado
888
- * pelo modo LAIR.
889
- */
890
- async executar(declaracao, mostrarResultado = false) {
891
- const resultado = await declaracao.aceitar(this);
892
- if (mostrarResultado) {
893
- this.funcaoDeRetorno(this.paraTexto(resultado));
894
- }
895
- if (resultado || typeof resultado === 'boolean') {
896
- this.resultadoInterpretador.push(this.paraTexto(resultado));
897
- }
898
- return resultado;
899
- }
900
- /**
901
- * Executa o último escopo empilhado no topo na pilha de escopos do interpretador.
902
- * Esse método pega exceções, mas apenas as devolve.
903
- *
904
- * O tratamento das exceções é feito de acordo com o bloco chamador.
905
- * Por exemplo, em `tente ... pegue ... finalmente`, a exceção é capturada e tratada.
906
- * Em outros blocos, pode ser desejável ter o erro em tela.
907
- * @param manterAmbiente Se verdadeiro, ambiente do topo da pilha de escopo é copiado para o ambiente imediatamente abaixo.
908
- * @returns O resultado da execução do escopo, se houver.
909
- */
910
- async executarUltimoEscopo(manterAmbiente = false) {
911
- const ultimoEscopo = this.pilhaEscoposExecucao.topoDaPilha();
912
- try {
913
- let retornoExecucao;
914
- for (; !(retornoExecucao instanceof quebras_1.Quebra) && ultimoEscopo.declaracaoAtual < ultimoEscopo.declaracoes.length; ultimoEscopo.declaracaoAtual++) {
915
- retornoExecucao = await this.executar(ultimoEscopo.declaracoes[ultimoEscopo.declaracaoAtual]);
916
- }
917
- return retornoExecucao;
918
- }
919
- catch (erro) {
920
- return Promise.reject(erro);
921
- }
922
- finally {
923
- this.pilhaEscoposExecucao.removerUltimo();
924
- if (manterAmbiente) {
925
- const escopoAnterior = this.pilhaEscoposExecucao.topoDaPilha();
926
- escopoAnterior.ambiente.valores = Object.assign(escopoAnterior.ambiente.valores, ultimoEscopo.ambiente.valores);
927
- }
928
- }
929
- }
930
- /**
931
- * Interpretação sem depurador, com medição de performance.
932
- * Método que efetivamente inicia o processo de interpretação.
933
- * @param declaracoes Um vetor de declarações gerado pelo Avaliador Sintático.
934
- * @param manterAmbiente Se ambiente de execução (variáveis, classes, etc.) deve ser mantido. Normalmente usado
935
- * pelo modo REPL (LAIR).
936
- * @returns Um objeto com o resultado da interpretação.
937
- */
938
- async interpretar(declaracoes, manterAmbiente = false) {
939
- this.erros = [];
940
- const escopoExecucao = {
941
- declaracoes: declaracoes,
942
- declaracaoAtual: 0,
943
- ambiente: new espaco_variaveis_1.EspacoVariaveis(),
944
- finalizado: false,
945
- tipo: 'outro',
946
- };
947
- this.pilhaEscoposExecucao.empilhar(escopoExecucao);
948
- const inicioInterpretacao = (0, browser_process_hrtime_1.default)();
949
- try {
950
- const retornoOuErro = await this.executarUltimoEscopo(manterAmbiente);
951
- if (retornoOuErro instanceof excecoes_1.ErroEmTempoDeExecucao) {
952
- this.erros.push(retornoOuErro);
953
- }
954
- }
955
- catch (erro) {
956
- this.erros.push(erro);
957
- }
958
- finally {
959
- if (this.performance) {
960
- const deltaInterpretacao = (0, browser_process_hrtime_1.default)(inicioInterpretacao);
961
- console.log(`[Interpretador] Tempo para interpretaçao: ${deltaInterpretacao[0] * 1e9 + deltaInterpretacao[1]}ns`);
962
- }
963
- const retorno = {
964
- erros: this.erros,
965
- resultado: this.resultadoInterpretador,
966
- };
967
- this.resultadoInterpretador = [];
968
- return retorno;
969
- }
970
- }
971
- }
972
- exports.InterpretadorBase = InterpretadorBase;
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.InterpretadorBase = void 0;
7
+ const browser_process_hrtime_1 = __importDefault(require("browser-process-hrtime"));
8
+ const espaco_variaveis_1 = require("../espaco-variaveis");
9
+ const biblioteca_global_1 = __importDefault(require("../bibliotecas/biblioteca-global"));
10
+ const excecoes_1 = require("../excecoes");
11
+ const estruturas_1 = require("../estruturas");
12
+ const construtos_1 = require("../construtos");
13
+ const pilha_escopos_execucao_1 = require("./pilha-escopos-execucao");
14
+ const quebras_1 = require("../quebras");
15
+ const inferenciador_1 = require("./inferenciador");
16
+ const metodo_primitiva_1 = require("../estruturas/metodo-primitiva");
17
+ const primitivas_texto_1 = __importDefault(require("../bibliotecas/primitivas-texto"));
18
+ const primitivas_vetor_1 = __importDefault(require("../bibliotecas/primitivas-vetor"));
19
+ const delegua_1 = __importDefault(require("../tipos-de-simbolos/delegua"));
20
+ /**
21
+ * O Interpretador visita todos os elementos complexos gerados pelo avaliador sintático (_parser_),
22
+ * e de fato executa a lógica de programação descrita no código.
23
+ *
24
+ * O Interpretador Base não contém dependências com o Node.js. É
25
+ * recomendado para uso em execuções que ocorrem no navegador de internet.
26
+ */
27
+ class InterpretadorBase {
28
+ constructor(diretorioBase, performance = false, funcaoDeRetorno = null, funcaoDeRetornoMesmaLinha = null) {
29
+ this.funcaoDeRetorno = null;
30
+ this.funcaoDeRetornoMesmaLinha = null;
31
+ this.interfaceDeEntrada = null;
32
+ this.resultadoInterpretador = [];
33
+ this.interfaceEntradaSaida = null;
34
+ this.regexInterpolacao = /\$\{([a-z_][\w]*)\}/gi;
35
+ this.diretorioBase = diretorioBase;
36
+ this.performance = performance;
37
+ this.funcaoDeRetorno = funcaoDeRetorno || console.log;
38
+ this.funcaoDeRetornoMesmaLinha = funcaoDeRetornoMesmaLinha || process.stdout.write;
39
+ this.erros = [];
40
+ this.declaracoes = [];
41
+ this.pilhaEscoposExecucao = new pilha_escopos_execucao_1.PilhaEscoposExecucao();
42
+ const escopoExecucao = {
43
+ declaracoes: [],
44
+ declaracaoAtual: 0,
45
+ ambiente: new espaco_variaveis_1.EspacoVariaveis(),
46
+ finalizado: false,
47
+ tipo: 'outro',
48
+ };
49
+ this.pilhaEscoposExecucao.empilhar(escopoExecucao);
50
+ (0, biblioteca_global_1.default)(this, this.pilhaEscoposExecucao);
51
+ }
52
+ /**
53
+ * Execução da leitura de valores da entrada configurada no
54
+ * início da aplicação.
55
+ * @param expressao Expressão do tipo Leia
56
+ * @returns Promise com o resultado da leitura.
57
+ */
58
+ async visitarExpressaoLeia(expressao) {
59
+ const mensagem = expressao.argumentos && expressao.argumentos[0] ? expressao.argumentos[0].valor : '> ';
60
+ return new Promise((resolucao) => this.interfaceEntradaSaida.question(mensagem, (resposta) => {
61
+ resolucao(resposta);
62
+ }));
63
+ }
64
+ /**
65
+ * Retira a interpolação de um texto.
66
+ * @param {texto} texto O texto
67
+ * @param {any[]} variaveis A lista de variaveis interpoladas
68
+ * @returns O texto com o valor das variaveis.
69
+ */
70
+ retirarInterpolacao(texto, variaveis) {
71
+ const valoresVariaveis = variaveis.map((v) => ({
72
+ valorResolvido: this.pilhaEscoposExecucao.obterVariavelPorNome(v.variavel),
73
+ variavel: v.variavel,
74
+ }));
75
+ let textoFinal = texto;
76
+ valoresVariaveis.forEach((elemento) => {
77
+ const valorFinal = elemento.valorResolvido.hasOwnProperty('valor')
78
+ ? elemento.valorResolvido.valor
79
+ : elemento.valorResolvido;
80
+ textoFinal = textoFinal.replace('${' + elemento.variavel + '}', valorFinal);
81
+ });
82
+ return textoFinal;
83
+ }
84
+ /**
85
+ * Busca variáveis interpoladas.
86
+ * @param {texto} textoOriginal O texto original com as variáveis interpoladas.
87
+ * @returns Uma lista de variáveis interpoladas.
88
+ */
89
+ buscarVariaveisInterpolacao(textoOriginal) {
90
+ const variaveis = textoOriginal.match(this.regexInterpolacao);
91
+ return variaveis.map((s) => {
92
+ const nomeVariavel = s.replace(/[\$\{\}]*/g, '');
93
+ return {
94
+ variavel: nomeVariavel,
95
+ valor: this.pilhaEscoposExecucao.obterVariavelPorNome(nomeVariavel),
96
+ };
97
+ });
98
+ }
99
+ visitarExpressaoLiteral(expressao) {
100
+ if (this.regexInterpolacao.test(expressao.valor)) {
101
+ const variaveis = this.buscarVariaveisInterpolacao(expressao.valor);
102
+ return this.retirarInterpolacao(expressao.valor, variaveis);
103
+ }
104
+ return expressao.valor;
105
+ }
106
+ async avaliar(expressao) {
107
+ // Descomente o código abaixo quando precisar detectar expressões undefined ou nulas.
108
+ // Por algum motivo o depurador do VSCode não funciona direito aqui
109
+ // com breakpoint condicional.
110
+ /* if (expressao === null || expressao === undefined) {
111
+ console.log('Aqui');
112
+ } */
113
+ return await expressao.aceitar(this);
114
+ }
115
+ async visitarExpressaoAgrupamento(expressao) {
116
+ return await this.avaliar(expressao.expressao);
117
+ }
118
+ eVerdadeiro(objeto) {
119
+ if (objeto === null)
120
+ return false;
121
+ if (typeof objeto === 'boolean')
122
+ return Boolean(objeto);
123
+ if (objeto.hasOwnProperty('valor')) {
124
+ return Boolean(objeto.valor);
125
+ }
126
+ return true;
127
+ }
128
+ verificarOperandoNumero(operador, operando) {
129
+ if (typeof operando === 'number' || operando.tipo === 'número')
130
+ return;
131
+ throw new excecoes_1.ErroEmTempoDeExecucao(operador, 'Operando precisa ser um número.', Number(operador.linha));
132
+ }
133
+ async visitarExpressaoUnaria(expressao) {
134
+ const operando = await this.avaliar(expressao.operando);
135
+ let valor = operando.hasOwnProperty('valor') ? operando.valor : operando;
136
+ switch (expressao.operador.tipo) {
137
+ case delegua_1.default.SUBTRACAO:
138
+ this.verificarOperandoNumero(expressao.operador, valor);
139
+ return -valor;
140
+ case delegua_1.default.NEGACAO:
141
+ return !this.eVerdadeiro(valor);
142
+ case delegua_1.default.BIT_NOT:
143
+ return ~valor;
144
+ // Para incrementar e decrementar, primeiro precisamos saber se o operador
145
+ // veio antes do literal ou variável.
146
+ // Se veio antes e o operando é uma variável, precisamos incrementar/decrementar,
147
+ // armazenar o valor da variável pra só então devolver o valor.
148
+ case delegua_1.default.INCREMENTAR:
149
+ if (expressao.incidenciaOperador === 'ANTES') {
150
+ valor++;
151
+ if (expressao.operando instanceof construtos_1.Variavel) {
152
+ this.pilhaEscoposExecucao.atribuirVariavel(expressao.operando.simbolo, valor);
153
+ }
154
+ return valor;
155
+ }
156
+ const valorAnteriorIncremento = valor;
157
+ this.pilhaEscoposExecucao.atribuirVariavel(expressao.operando.simbolo, ++valor);
158
+ return valorAnteriorIncremento;
159
+ case delegua_1.default.DECREMENTAR:
160
+ if (expressao.incidenciaOperador === 'ANTES') {
161
+ valor--;
162
+ if (expressao.operando instanceof construtos_1.Variavel) {
163
+ this.pilhaEscoposExecucao.atribuirVariavel(expressao.operando.simbolo, valor);
164
+ }
165
+ return valor;
166
+ }
167
+ const valorAnteriorDecremento = valor;
168
+ this.pilhaEscoposExecucao.atribuirVariavel(expressao.operando.simbolo, --valor);
169
+ return valorAnteriorDecremento;
170
+ }
171
+ return null;
172
+ }
173
+ async visitarExpressaoFormatacaoEscrita(declaracao) {
174
+ let resultado = '';
175
+ const conteudo = await this.avaliar(declaracao.expressao);
176
+ const valorConteudo = (conteudo === null || conteudo === void 0 ? void 0 : conteudo.hasOwnProperty('valor')) ? conteudo.valor : conteudo;
177
+ const tipoConteudo = conteudo.hasOwnProperty('tipo') ? conteudo.tipo : typeof conteudo;
178
+ resultado = valorConteudo;
179
+ if (['número', 'number'].includes(tipoConteudo) && declaracao.casasDecimais > 0) {
180
+ resultado = valorConteudo.toLocaleString('pt', { maximumFractionDigits: declaracao.casasDecimais });
181
+ }
182
+ if (declaracao.espacos > 0) {
183
+ resultado += ' '.repeat(declaracao.espacos);
184
+ }
185
+ return resultado;
186
+ }
187
+ eIgual(esquerda, direita) {
188
+ if (esquerda === null && direita === null)
189
+ return true;
190
+ if (esquerda === null)
191
+ return false;
192
+ return esquerda === direita;
193
+ }
194
+ /**
195
+ * Verifica se operandos são números, que podem ser tanto variáveis puras do JavaScript
196
+ * (neste caso, `number`), ou podem ser variáveis de Delégua com inferência (`VariavelInterface`).
197
+ * @param operador O símbolo do operador.
198
+ * @param direita O operando direito.
199
+ * @param esquerda O operando esquerdo.
200
+ * @returns Se ambos os operandos são números ou não.
201
+ */
202
+ verificarOperandosNumeros(operador, direita, esquerda) {
203
+ const tipoDireita = direita.tipo ? direita.tipo : typeof direita === 'number' ? 'número' : String(NaN);
204
+ const tipoEsquerda = esquerda.tipo
205
+ ? esquerda.tipo
206
+ : typeof esquerda === 'number'
207
+ ? 'número'
208
+ : String(NaN);
209
+ if (tipoDireita === 'número' && tipoEsquerda === 'número')
210
+ return;
211
+ throw new excecoes_1.ErroEmTempoDeExecucao(operador, 'Operadores precisam ser números.', operador.linha);
212
+ }
213
+ async visitarExpressaoBinaria(expressao) {
214
+ try {
215
+ const esquerda = await this.avaliar(expressao.esquerda);
216
+ const direita = await this.avaliar(expressao.direita);
217
+ const valorEsquerdo = (esquerda === null || esquerda === void 0 ? void 0 : esquerda.hasOwnProperty('valor')) ? esquerda.valor : esquerda;
218
+ const valorDireito = (direita === null || direita === void 0 ? void 0 : direita.hasOwnProperty('valor')) ? direita.valor : direita;
219
+ const tipoEsquerdo = (esquerda === null || esquerda === void 0 ? void 0 : esquerda.hasOwnProperty('tipo'))
220
+ ? esquerda.tipo
221
+ : (0, inferenciador_1.inferirTipoVariavel)(esquerda);
222
+ const tipoDireito = (direita === null || direita === void 0 ? void 0 : direita.hasOwnProperty('tipo')) ? direita.tipo : (0, inferenciador_1.inferirTipoVariavel)(direita);
223
+ switch (expressao.operador.tipo) {
224
+ case delegua_1.default.EXPONENCIACAO:
225
+ this.verificarOperandosNumeros(expressao.operador, esquerda, direita);
226
+ return Math.pow(valorEsquerdo, valorDireito);
227
+ case delegua_1.default.MAIOR:
228
+ this.verificarOperandosNumeros(expressao.operador, esquerda, direita);
229
+ return Number(valorEsquerdo) > Number(valorDireito);
230
+ case delegua_1.default.MAIOR_IGUAL:
231
+ this.verificarOperandosNumeros(expressao.operador, esquerda, direita);
232
+ return Number(valorEsquerdo) >= Number(valorDireito);
233
+ case delegua_1.default.MENOR:
234
+ this.verificarOperandosNumeros(expressao.operador, esquerda, direita);
235
+ return Number(valorEsquerdo) < Number(valorDireito);
236
+ case delegua_1.default.MENOR_IGUAL:
237
+ this.verificarOperandosNumeros(expressao.operador, esquerda, direita);
238
+ return Number(valorEsquerdo) <= Number(valorDireito);
239
+ case delegua_1.default.SUBTRACAO:
240
+ case delegua_1.default.MENOS_IGUAL:
241
+ this.verificarOperandosNumeros(expressao.operador, esquerda, direita);
242
+ return Number(valorEsquerdo) - Number(valorDireito);
243
+ case delegua_1.default.ADICAO:
244
+ case delegua_1.default.MAIS_IGUAL:
245
+ if (tipoEsquerdo === 'número' && tipoDireito === 'número') {
246
+ return Number(valorEsquerdo) + Number(valorDireito);
247
+ }
248
+ else {
249
+ return String(valorEsquerdo) + String(valorDireito);
250
+ }
251
+ case delegua_1.default.DIVISAO:
252
+ case delegua_1.default.DIVISAO_IGUAL:
253
+ this.verificarOperandosNumeros(expressao.operador, esquerda, direita);
254
+ return Number(valorEsquerdo) / Number(valorDireito);
255
+ case delegua_1.default.DIVISAO_INTEIRA:
256
+ case delegua_1.default.DIVISAO_INTEIRA_IGUAL:
257
+ this.verificarOperandosNumeros(expressao.operador, esquerda, direita);
258
+ return Math.floor(Number(valorEsquerdo) / Number(valorDireito));
259
+ case delegua_1.default.MULTIPLICACAO:
260
+ case delegua_1.default.MULTIPLICACAO_IGUAL:
261
+ if (tipoEsquerdo === 'texto' || tipoDireito === 'texto') {
262
+ // Sem ambos os valores resolvem como texto, multiplica normal.
263
+ // Se apenas um resolve como texto, o outro repete o
264
+ // texto n vezes, sendo n o valor do outro.
265
+ if (tipoEsquerdo === 'texto' && tipoDireito === 'texto') {
266
+ return Number(valorEsquerdo) * Number(valorDireito);
267
+ }
268
+ if (tipoEsquerdo === 'texto') {
269
+ return valorEsquerdo.repeat(Number(valorDireito));
270
+ }
271
+ return valorDireito.repeat(Number(valorEsquerdo));
272
+ }
273
+ return Number(valorEsquerdo) * Number(valorDireito);
274
+ case delegua_1.default.MODULO:
275
+ case delegua_1.default.MODULO_IGUAL:
276
+ this.verificarOperandosNumeros(expressao.operador, esquerda, direita);
277
+ return Number(valorEsquerdo) % Number(valorDireito);
278
+ case delegua_1.default.BIT_AND:
279
+ this.verificarOperandosNumeros(expressao.operador, esquerda, direita);
280
+ return Number(valorEsquerdo) & Number(valorDireito);
281
+ case delegua_1.default.BIT_XOR:
282
+ this.verificarOperandosNumeros(expressao.operador, esquerda, direita);
283
+ return Number(valorEsquerdo) ^ Number(valorDireito);
284
+ case delegua_1.default.BIT_OR:
285
+ this.verificarOperandosNumeros(expressao.operador, esquerda, direita);
286
+ return Number(valorEsquerdo) | Number(valorDireito);
287
+ case delegua_1.default.MENOR_MENOR:
288
+ this.verificarOperandosNumeros(expressao.operador, esquerda, direita);
289
+ return Number(valorEsquerdo) << Number(valorDireito);
290
+ case delegua_1.default.MAIOR_MAIOR:
291
+ this.verificarOperandosNumeros(expressao.operador, esquerda, direita);
292
+ return Number(valorEsquerdo) >> Number(valorDireito);
293
+ case delegua_1.default.DIFERENTE:
294
+ return !this.eIgual(valorEsquerdo, valorDireito);
295
+ case delegua_1.default.IGUAL_IGUAL:
296
+ return this.eIgual(valorEsquerdo, valorDireito);
297
+ }
298
+ }
299
+ catch (erro) {
300
+ return Promise.reject(erro);
301
+ }
302
+ }
303
+ /**
304
+ * Executa uma chamada de função, método ou classe.
305
+ * @param expressao A expressão chamada.
306
+ * @returns O resultado da chamada.
307
+ */
308
+ async visitarExpressaoDeChamada(expressao) {
309
+ try {
310
+ const variavelEntidadeChamada = await this.avaliar(expressao.entidadeChamada);
311
+ if (variavelEntidadeChamada === null) {
312
+ return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(expressao.parentese, 'Chamada de função ou método inexistente: ' + String(expressao.entidadeChamada), expressao.linha));
313
+ }
314
+ const entidadeChamada = variavelEntidadeChamada.hasOwnProperty('valor')
315
+ ? variavelEntidadeChamada.valor
316
+ : variavelEntidadeChamada;
317
+ let argumentos = [];
318
+ for (let i = 0; i < expressao.argumentos.length; i++) {
319
+ argumentos.push(await this.avaliar(expressao.argumentos[i]));
320
+ }
321
+ if (entidadeChamada instanceof estruturas_1.DeleguaModulo) {
322
+ return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(expressao.parentese, 'Entidade chamada é um módulo de Delégua. Provavelmente você quer chamar um de seus componentes?', expressao.linha));
323
+ }
324
+ if (entidadeChamada instanceof metodo_primitiva_1.MetodoPrimitiva) {
325
+ const argumentosResolvidos = [];
326
+ for (const argumento of expressao.argumentos) {
327
+ const valorResolvido = await this.avaliar(argumento);
328
+ argumentosResolvidos.push(valorResolvido.hasOwnProperty('valor') ? valorResolvido.valor : valorResolvido);
329
+ }
330
+ return entidadeChamada.chamar(argumentosResolvidos);
331
+ }
332
+ let parametros;
333
+ if (entidadeChamada instanceof estruturas_1.DeleguaFuncao) {
334
+ parametros = entidadeChamada.declaracao.parametros;
335
+ }
336
+ else if (entidadeChamada instanceof estruturas_1.DeleguaClasse) {
337
+ parametros = entidadeChamada.metodos.inicializacao
338
+ ? entidadeChamada.metodos.inicializacao.declaracao.parametros
339
+ : [];
340
+ }
341
+ else {
342
+ parametros = [];
343
+ }
344
+ const aridade = entidadeChamada.aridade ? entidadeChamada.aridade() : entidadeChamada.length;
345
+ // Completar os parâmetros não preenchidos com nulos.
346
+ if (argumentos.length < aridade) {
347
+ const diferenca = aridade - argumentos.length;
348
+ for (let i = 0; i < diferenca; i++) {
349
+ argumentos.push(null);
350
+ }
351
+ }
352
+ else {
353
+ if (parametros && parametros.length > 0 && parametros[parametros.length - 1].abrangencia === 'multiplo') {
354
+ const novosArgumentos = argumentos.slice(0, parametros.length - 1);
355
+ novosArgumentos.push(argumentos.slice(parametros.length - 1, argumentos.length));
356
+ argumentos = novosArgumentos;
357
+ }
358
+ }
359
+ if (entidadeChamada instanceof estruturas_1.FuncaoPadrao) {
360
+ try {
361
+ return entidadeChamada.chamar(argumentos.map((a) => (a !== null && a.hasOwnProperty('valor') ? a.valor : a)), expressao.entidadeChamada.nome);
362
+ }
363
+ catch (erro) {
364
+ this.erros.push(erro);
365
+ }
366
+ }
367
+ if (entidadeChamada instanceof estruturas_1.Chamavel) {
368
+ return entidadeChamada.chamar(this, argumentos);
369
+ }
370
+ // A função chamada pode ser de uma biblioteca JavaScript.
371
+ // Neste caso apenas testamos se o tipo é uma função.
372
+ if (typeof entidadeChamada === 'function') {
373
+ let objeto = null;
374
+ if (expressao.entidadeChamada.objeto) {
375
+ objeto = await this.avaliar(expressao.entidadeChamada.objeto);
376
+ }
377
+ return entidadeChamada.apply(objeto.hasOwnProperty('valor') ? objeto.valor : objeto, argumentos);
378
+ }
379
+ return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(expressao.parentese, 'Só pode chamar função ou classe.', expressao.linha));
380
+ }
381
+ catch (erro) {
382
+ console.log(erro);
383
+ }
384
+ }
385
+ /**
386
+ * Execução de uma expressão de atribuição.
387
+ * @param expressao A expressão.
388
+ * @returns O valor atribuído.
389
+ */
390
+ async visitarDeclaracaoDeAtribuicao(expressao) {
391
+ const valor = await this.avaliar(expressao.valor);
392
+ this.pilhaEscoposExecucao.atribuirVariavel(expressao.simbolo, valor);
393
+ return valor;
394
+ }
395
+ procurarVariavel(simbolo) {
396
+ return this.pilhaEscoposExecucao.obterValorVariavel(simbolo);
397
+ }
398
+ visitarExpressaoDeVariavel(expressao) {
399
+ return this.procurarVariavel(expressao.simbolo);
400
+ }
401
+ async visitarDeclaracaoDeExpressao(declaracao) {
402
+ return await this.avaliar(declaracao.expressao);
403
+ }
404
+ async visitarExpressaoLogica(expressao) {
405
+ const esquerda = await this.avaliar(expressao.esquerda);
406
+ if (expressao.operador.tipo === delegua_1.default.EM) {
407
+ const direita = await this.avaliar(expressao.direita);
408
+ if (Array.isArray(direita) || typeof direita === 'string') {
409
+ return direita.includes(esquerda);
410
+ }
411
+ else if (direita.constructor === Object) {
412
+ return esquerda in direita;
413
+ }
414
+ else {
415
+ throw new excecoes_1.ErroEmTempoDeExecucao(esquerda, "Tipo de chamada inválida com 'em'.", expressao.linha);
416
+ }
417
+ }
418
+ // se um estado for verdadeiro, retorna verdadeiro
419
+ if (expressao.operador.tipo === delegua_1.default.OU) {
420
+ if (this.eVerdadeiro(esquerda))
421
+ return esquerda;
422
+ }
423
+ // se um estado for falso, retorna falso
424
+ if (expressao.operador.tipo === delegua_1.default.E) {
425
+ if (!this.eVerdadeiro(esquerda))
426
+ return esquerda;
427
+ }
428
+ return await this.avaliar(expressao.direita);
429
+ }
430
+ /**
431
+ * Executa uma expressão Se, que tem uma condição, pode ter um bloco
432
+ * Senão, e múltiplos blocos Senão-se.
433
+ * @param declaracao A declaração Se.
434
+ * @returns O resultado da avaliação do bloco cuja condição é verdadeira.
435
+ */
436
+ async visitarDeclaracaoSe(declaracao) {
437
+ if (this.eVerdadeiro(await this.avaliar(declaracao.condicao))) {
438
+ return await this.executar(declaracao.caminhoEntao);
439
+ }
440
+ for (let i = 0; i < declaracao.caminhosSeSenao.length; i++) {
441
+ const atual = declaracao.caminhosSeSenao[i];
442
+ if (this.eVerdadeiro(await this.avaliar(atual.condicao))) {
443
+ return await this.executar(atual.caminho);
444
+ }
445
+ }
446
+ if (declaracao.caminhoSenao !== null) {
447
+ return await this.executar(declaracao.caminhoSenao);
448
+ }
449
+ return null;
450
+ }
451
+ async visitarDeclaracaoPara(declaracao) {
452
+ if (declaracao.inicializador !== null) {
453
+ await this.avaliar(declaracao.inicializador);
454
+ }
455
+ let retornoExecucao;
456
+ while (!(retornoExecucao instanceof quebras_1.Quebra)) {
457
+ if (declaracao.condicao !== null && !this.eVerdadeiro(await this.avaliar(declaracao.condicao))) {
458
+ break;
459
+ }
460
+ try {
461
+ retornoExecucao = await this.executar(declaracao.corpo);
462
+ if (retornoExecucao instanceof quebras_1.ContinuarQuebra) {
463
+ retornoExecucao = null;
464
+ }
465
+ }
466
+ catch (erro) {
467
+ return Promise.reject(erro);
468
+ }
469
+ if (declaracao.incrementar !== null) {
470
+ await this.avaliar(declaracao.incrementar);
471
+ }
472
+ }
473
+ return null;
474
+ }
475
+ async visitarDeclaracaoFazer(declaracao) {
476
+ let retornoExecucao;
477
+ do {
478
+ try {
479
+ retornoExecucao = await this.executar(declaracao.caminhoFazer);
480
+ if (retornoExecucao instanceof quebras_1.ContinuarQuebra) {
481
+ retornoExecucao = null;
482
+ }
483
+ }
484
+ catch (erro) {
485
+ return Promise.reject(erro);
486
+ }
487
+ } while (!(retornoExecucao instanceof quebras_1.Quebra) &&
488
+ this.eVerdadeiro(await this.avaliar(declaracao.condicaoEnquanto)));
489
+ }
490
+ async visitarDeclaracaoEscolha(declaracao) {
491
+ const condicaoEscolha = await this.avaliar(declaracao.identificadorOuLiteral);
492
+ const valorCondicaoEscolha = condicaoEscolha.hasOwnProperty('valor') ?
493
+ condicaoEscolha.valor :
494
+ condicaoEscolha;
495
+ const caminhos = declaracao.caminhos;
496
+ const caminhoPadrao = declaracao.caminhoPadrao;
497
+ let encontrado = false;
498
+ try {
499
+ for (let i = 0; i < caminhos.length; i++) {
500
+ const caminho = caminhos[i];
501
+ for (let j = 0; j < caminho.condicoes.length; j++) {
502
+ const condicaoAvaliada = await this.avaliar(caminho.condicoes[j]);
503
+ if (condicaoAvaliada === valorCondicaoEscolha) {
504
+ encontrado = true;
505
+ try {
506
+ await this.executarBloco(caminho.declaracoes);
507
+ }
508
+ catch (erro) {
509
+ return Promise.reject(erro);
510
+ }
511
+ }
512
+ }
513
+ }
514
+ if (caminhoPadrao !== null && !encontrado) {
515
+ await this.executarBloco(caminhoPadrao.declaracoes);
516
+ }
517
+ }
518
+ catch (erro) {
519
+ throw erro;
520
+ }
521
+ }
522
+ /**
523
+ * Interpretação de uma declaração `tente`.
524
+ * @param declaracao O objeto da declaração.
525
+ */
526
+ async visitarDeclaracaoTente(declaracao) {
527
+ let valorRetorno;
528
+ try {
529
+ let sucesso = true;
530
+ try {
531
+ valorRetorno = await this.executarBloco(declaracao.caminhoTente);
532
+ }
533
+ catch (erro) {
534
+ sucesso = false;
535
+ if (declaracao.caminhoPegue !== null) {
536
+ // `caminhoPegue` aqui pode ser um construto de função (se `pegue` tem parâmetros)
537
+ // ou um vetor de `Declaracao` (`pegue` sem parâmetros).
538
+ // As execuções, portanto, são diferentes.
539
+ if (Array.isArray(declaracao.caminhoPegue)) {
540
+ valorRetorno = await this.executarBloco(declaracao.caminhoPegue);
541
+ }
542
+ else {
543
+ const literalErro = new construtos_1.Literal(declaracao.hashArquivo, Number(declaracao.linha), erro.mensagem);
544
+ const chamadaPegue = new construtos_1.Chamada(declaracao.caminhoPegue.hashArquivo, declaracao.caminhoPegue, null, [literalErro]);
545
+ valorRetorno = await chamadaPegue.aceitar(this);
546
+ }
547
+ }
548
+ }
549
+ }
550
+ finally {
551
+ if (declaracao.caminhoFinalmente !== null)
552
+ valorRetorno = await this.executarBloco(declaracao.caminhoFinalmente);
553
+ }
554
+ return valorRetorno;
555
+ }
556
+ async visitarDeclaracaoEnquanto(declaracao) {
557
+ let retornoExecucao;
558
+ while (!(retornoExecucao instanceof quebras_1.Quebra) && this.eVerdadeiro(await this.avaliar(declaracao.condicao))) {
559
+ try {
560
+ retornoExecucao = await this.executar(declaracao.corpo);
561
+ if (retornoExecucao instanceof quebras_1.ContinuarQuebra) {
562
+ retornoExecucao = null;
563
+ }
564
+ }
565
+ catch (erro) {
566
+ throw erro;
567
+ }
568
+ }
569
+ return null;
570
+ }
571
+ async visitarDeclaracaoImportar(declaracao) {
572
+ return Promise.reject("Importação de arquivos não suportada por Interpretador Base.");
573
+ }
574
+ async avaliarArgumentosEscreva(argumentos) {
575
+ let formatoTexto = '';
576
+ for (const argumento of argumentos) {
577
+ const resultadoAvaliacao = await this.avaliar(argumento);
578
+ let valor = (resultadoAvaliacao === null || resultadoAvaliacao === void 0 ? void 0 : resultadoAvaliacao.hasOwnProperty('valor')) ? resultadoAvaliacao.valor : resultadoAvaliacao;
579
+ formatoTexto += `${this.paraTexto(valor)} `;
580
+ }
581
+ return formatoTexto;
582
+ }
583
+ /**
584
+ * Execução de uma escrita na saída padrão, sem quebras de linha.
585
+ * Implementada para alguns dialetos, como VisuAlg.
586
+ * @param declaracao A declaração.
587
+ * @returns Sempre nulo, por convenção de visita.
588
+ */
589
+ async visitarExpressaoEscrevaMesmaLinha(declaracao) {
590
+ try {
591
+ const formatoTexto = await this.avaliarArgumentosEscreva(declaracao.argumentos);
592
+ this.funcaoDeRetornoMesmaLinha(formatoTexto);
593
+ return null;
594
+ }
595
+ catch (erro) {
596
+ this.erros.push({
597
+ erroInterno: erro,
598
+ linha: declaracao.linha,
599
+ hashArquivo: declaracao.hashArquivo,
600
+ });
601
+ }
602
+ }
603
+ /**
604
+ * Execução de uma escrita na saída configurada, que pode ser `console` (padrão) ou
605
+ * alguma função para escrever numa página Web.
606
+ * @param declaracao A declaração.
607
+ * @returns Sempre nulo, por convenção de visita.
608
+ */
609
+ async visitarDeclaracaoEscreva(declaracao) {
610
+ try {
611
+ const formatoTexto = await this.avaliarArgumentosEscreva(declaracao.argumentos);
612
+ this.funcaoDeRetorno(formatoTexto);
613
+ return null;
614
+ }
615
+ catch (erro) {
616
+ this.erros.push({
617
+ erroInterno: erro,
618
+ linha: declaracao.linha,
619
+ hashArquivo: declaracao.hashArquivo,
620
+ });
621
+ }
622
+ }
623
+ /**
624
+ * Empilha declarações na pilha de escopos de execução, cria um novo ambiente e
625
+ * executa as declarações empilhadas.
626
+ * Se o retorno do último bloco foi uma exceção (normalmente um erro em tempo de execução),
627
+ * atira a exceção daqui.
628
+ * Isso é usado, por exemplo, em blocos tente ... pegue ... finalmente.
629
+ * @param declaracoes Um vetor de declaracoes a ser executado.
630
+ * @param ambiente O ambiente de execução quando houver, como parâmetros, argumentos, etc.
631
+ */
632
+ async executarBloco(declaracoes, ambiente) {
633
+ const escopoExecucao = {
634
+ declaracoes: declaracoes,
635
+ declaracaoAtual: 0,
636
+ ambiente: ambiente || new espaco_variaveis_1.EspacoVariaveis(),
637
+ finalizado: false,
638
+ tipo: 'outro',
639
+ };
640
+ this.pilhaEscoposExecucao.empilhar(escopoExecucao);
641
+ const retornoUltimoEscopo = await this.executarUltimoEscopo();
642
+ if (retornoUltimoEscopo instanceof excecoes_1.ErroEmTempoDeExecucao) {
643
+ return Promise.reject(retornoUltimoEscopo);
644
+ }
645
+ return retornoUltimoEscopo;
646
+ }
647
+ async visitarExpressaoBloco(declaracao) {
648
+ return await this.executarBloco(declaracao.declaracoes);
649
+ }
650
+ async avaliacaoDeclaracaoVar(declaracao) {
651
+ let valorOuOutraVariavel = null;
652
+ if (declaracao.inicializador !== null) {
653
+ valorOuOutraVariavel = await this.avaliar(declaracao.inicializador);
654
+ }
655
+ let valorFinal = null;
656
+ if (valorOuOutraVariavel !== null && valorOuOutraVariavel !== undefined) {
657
+ valorFinal = valorOuOutraVariavel.hasOwnProperty('valor')
658
+ ? valorOuOutraVariavel.valor
659
+ : valorOuOutraVariavel;
660
+ }
661
+ return valorFinal;
662
+ }
663
+ /**
664
+ * Executa expressão de definição de variável.
665
+ * @param declaracao A declaração Var
666
+ * @returns Sempre retorna nulo.
667
+ */
668
+ async visitarDeclaracaoVar(declaracao) {
669
+ const valorFinal = await this.avaliacaoDeclaracaoVar(declaracao);
670
+ this.pilhaEscoposExecucao.definirVariavel(declaracao.simbolo.lexema, valorFinal);
671
+ return null;
672
+ }
673
+ visitarExpressaoContinua(declaracao) {
674
+ return new quebras_1.ContinuarQuebra();
675
+ }
676
+ visitarExpressaoSustar(declaracao) {
677
+ return new quebras_1.SustarQuebra();
678
+ }
679
+ async visitarExpressaoRetornar(declaracao) {
680
+ let valor = null;
681
+ if (declaracao.valor != null)
682
+ valor = await this.avaliar(declaracao.valor);
683
+ return new quebras_1.RetornoQuebra(valor);
684
+ }
685
+ visitarExpressaoDeleguaFuncao(declaracao) {
686
+ return new estruturas_1.DeleguaFuncao(null, declaracao);
687
+ }
688
+ async visitarExpressaoAtribuicaoSobrescrita(expressao) {
689
+ const promises = await Promise.all([
690
+ this.avaliar(expressao.objeto),
691
+ this.avaliar(expressao.indice),
692
+ this.avaliar(expressao.valor),
693
+ ]);
694
+ let objeto = promises[0];
695
+ let indice = promises[1];
696
+ const valor = promises[2];
697
+ objeto = objeto.hasOwnProperty('valor') ? objeto.valor : objeto;
698
+ indice = indice.hasOwnProperty('valor') ? indice.valor : indice;
699
+ if (Array.isArray(objeto)) {
700
+ if (indice < 0 && objeto.length !== 0) {
701
+ while (indice < 0) {
702
+ indice += objeto.length;
703
+ }
704
+ }
705
+ while (objeto.length < indice) {
706
+ objeto.push(null);
707
+ }
708
+ objeto[indice] = valor;
709
+ }
710
+ else if (objeto.constructor === Object ||
711
+ objeto instanceof estruturas_1.ObjetoDeleguaClasse ||
712
+ objeto instanceof estruturas_1.DeleguaFuncao ||
713
+ objeto instanceof estruturas_1.DeleguaClasse ||
714
+ objeto instanceof estruturas_1.DeleguaModulo) {
715
+ objeto[indice] = valor;
716
+ }
717
+ else {
718
+ return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(expressao.objeto.nome, 'Somente listas, dicionários, classes e objetos podem ser mudados por sobrescrita.', expressao.linha));
719
+ }
720
+ }
721
+ async visitarExpressaoAcessoIndiceVariavel(expressao) {
722
+ const variavelObjeto = await this.avaliar(expressao.entidadeChamada);
723
+ const objeto = variavelObjeto.hasOwnProperty('valor') ? variavelObjeto.valor : variavelObjeto;
724
+ const indice = await this.avaliar(expressao.indice);
725
+ let valorIndice = indice.hasOwnProperty('valor') ? indice.valor : indice;
726
+ if (Array.isArray(objeto)) {
727
+ if (!Number.isInteger(valorIndice)) {
728
+ return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(expressao.simboloFechamento, 'Somente inteiros podem ser usados para indexar um vetor.', expressao.linha));
729
+ }
730
+ if (valorIndice < 0 && objeto.length !== 0) {
731
+ while (valorIndice < 0) {
732
+ valorIndice += objeto.length;
733
+ }
734
+ }
735
+ if (valorIndice >= objeto.length) {
736
+ return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(expressao.simboloFechamento, 'Índice do vetor fora do intervalo.', expressao.linha));
737
+ }
738
+ return objeto[valorIndice];
739
+ }
740
+ else if (objeto.constructor === Object ||
741
+ objeto instanceof estruturas_1.ObjetoDeleguaClasse ||
742
+ objeto instanceof estruturas_1.DeleguaFuncao ||
743
+ objeto instanceof estruturas_1.DeleguaClasse ||
744
+ objeto instanceof estruturas_1.DeleguaModulo) {
745
+ return objeto[valorIndice] || null;
746
+ }
747
+ else if (typeof objeto === 'string') {
748
+ if (!Number.isInteger(valorIndice)) {
749
+ return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(expressao.simboloFechamento, 'Somente inteiros podem ser usados para indexar um vetor.', expressao.linha));
750
+ }
751
+ if (valorIndice < 0 && objeto.length !== 0) {
752
+ while (valorIndice < 0) {
753
+ valorIndice += objeto.length;
754
+ }
755
+ }
756
+ if (valorIndice >= objeto.length) {
757
+ return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(expressao.simboloFechamento, 'Índice fora do tamanho.', expressao.linha));
758
+ }
759
+ return objeto.charAt(valorIndice);
760
+ }
761
+ else {
762
+ return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(expressao.entidadeChamada.nome, 'Somente listas, dicionários, classes e objetos podem ser mudados por sobrescrita.', expressao.linha));
763
+ }
764
+ }
765
+ async visitarExpressaoDefinirValor(expressao) {
766
+ const variavelObjeto = await this.avaliar(expressao.objeto);
767
+ const objeto = variavelObjeto.hasOwnProperty('valor') ? variavelObjeto.valor : variavelObjeto;
768
+ if (!(objeto instanceof estruturas_1.ObjetoDeleguaClasse) && objeto.constructor !== Object) {
769
+ return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(expressao.objeto.nome, 'Somente instâncias e dicionários podem possuir campos.', expressao.linha));
770
+ }
771
+ const valor = await this.avaliar(expressao.valor);
772
+ if (objeto instanceof estruturas_1.ObjetoDeleguaClasse) {
773
+ objeto.definir(expressao.nome, valor);
774
+ return valor;
775
+ }
776
+ else if (objeto.constructor === Object) {
777
+ objeto[expressao.simbolo.lexema] = valor;
778
+ }
779
+ }
780
+ visitarDeclaracaoDefinicaoFuncao(declaracao) {
781
+ const funcao = new estruturas_1.DeleguaFuncao(declaracao.simbolo.lexema, declaracao.funcao);
782
+ this.pilhaEscoposExecucao.definirVariavel(declaracao.simbolo.lexema, funcao);
783
+ }
784
+ /**
785
+ * Executa uma declaração de classe.
786
+ * @param declaracao A declaração de classe.
787
+ * @returns Sempre retorna nulo, por ser requerido pelo contrato de visita.
788
+ */
789
+ async visitarDeclaracaoClasse(declaracao) {
790
+ let superClasse = null;
791
+ if (declaracao.superClasse !== null) {
792
+ const variavelSuperClasse = await this.avaliar(declaracao.superClasse);
793
+ superClasse = variavelSuperClasse.valor;
794
+ if (!(superClasse instanceof estruturas_1.DeleguaClasse)) {
795
+ throw new excecoes_1.ErroEmTempoDeExecucao(declaracao.superClasse.nome, 'Superclasse precisa ser uma classe.', declaracao.linha);
796
+ }
797
+ }
798
+ this.pilhaEscoposExecucao.definirVariavel(declaracao.simbolo.lexema, null);
799
+ if (declaracao.superClasse !== null) {
800
+ this.pilhaEscoposExecucao.definirVariavel('super', superClasse);
801
+ }
802
+ const metodos = {};
803
+ const definirMetodos = declaracao.metodos;
804
+ for (let i = 0; i < declaracao.metodos.length; i++) {
805
+ const metodoAtual = definirMetodos[i];
806
+ const eInicializador = metodoAtual.simbolo.lexema === 'construtor';
807
+ const funcao = new estruturas_1.DeleguaFuncao(metodoAtual.simbolo.lexema, metodoAtual.funcao, undefined, eInicializador);
808
+ metodos[metodoAtual.simbolo.lexema] = funcao;
809
+ }
810
+ const deleguaClasse = new estruturas_1.DeleguaClasse(declaracao.simbolo.lexema, superClasse, metodos);
811
+ // TODO: Recolocar isso se for necessário.
812
+ /* if (superClasse !== null) {
813
+ this.ambiente = this.ambiente.enclosing;
814
+ } */
815
+ this.pilhaEscoposExecucao.atribuirVariavel(declaracao.simbolo, deleguaClasse);
816
+ return null;
817
+ }
818
+ /**
819
+ * Executa um acesso a método, normalmente de um objeto de classe.
820
+ * @param expressao A expressão de acesso.
821
+ * @returns O resultado da execução.
822
+ */
823
+ async visitarExpressaoAcessoMetodo(expressao) {
824
+ const variavelObjeto = await this.avaliar(expressao.objeto);
825
+ const objeto = variavelObjeto.hasOwnProperty('valor') ? variavelObjeto.valor : variavelObjeto;
826
+ if (objeto instanceof estruturas_1.ObjetoDeleguaClasse) {
827
+ return objeto.obter(expressao.simbolo) || null;
828
+ }
829
+ // TODO: Possivelmente depreciar esta forma.
830
+ // Não parece funcionar em momento algum.
831
+ if (objeto.constructor === Object) {
832
+ return objeto[expressao.simbolo.lexema] || null;
833
+ }
834
+ // Função tradicional do JavaScript.
835
+ // Normalmente executa quando uma biblioteca é importada.
836
+ if (typeof objeto[expressao.simbolo.lexema] === 'function') {
837
+ return objeto[expressao.simbolo.lexema];
838
+ }
839
+ // Objeto tradicional do JavaScript.
840
+ // Normalmente executa quando uma biblioteca é importada.
841
+ if (typeof objeto[expressao.simbolo.lexema] === 'object') {
842
+ return objeto[expressao.simbolo.lexema];
843
+ }
844
+ if (objeto instanceof estruturas_1.DeleguaModulo) {
845
+ return objeto.componentes[expressao.simbolo.lexema] || null;
846
+ }
847
+ switch (variavelObjeto.tipo) {
848
+ case 'texto':
849
+ const metodoDePrimitivaTexto = primitivas_texto_1.default[expressao.simbolo.lexema];
850
+ if (metodoDePrimitivaTexto) {
851
+ return new metodo_primitiva_1.MetodoPrimitiva(objeto, metodoDePrimitivaTexto);
852
+ }
853
+ break;
854
+ case 'vetor':
855
+ const metodoDePrimitivaVetor = primitivas_vetor_1.default[expressao.simbolo.lexema];
856
+ if (metodoDePrimitivaVetor) {
857
+ return new metodo_primitiva_1.MetodoPrimitiva(objeto, metodoDePrimitivaVetor);
858
+ }
859
+ break;
860
+ }
861
+ return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(expressao.nome, 'Você só pode acessar métodos do objeto e dicionários.', expressao.linha));
862
+ }
863
+ visitarExpressaoIsto(expressao) {
864
+ return this.procurarVariavel(expressao.palavraChave);
865
+ }
866
+ async visitarExpressaoDicionario(expressao) {
867
+ const dicionario = {};
868
+ for (let i = 0; i < expressao.chaves.length; i++) {
869
+ const promises = await Promise.all([this.avaliar(expressao.chaves[i]), this.avaliar(expressao.valores[i])]);
870
+ dicionario[promises[0]] = promises[1];
871
+ }
872
+ return dicionario;
873
+ }
874
+ async visitarExpressaoVetor(expressao) {
875
+ const valores = [];
876
+ for (let i = 0; i < expressao.valores.length; i++) {
877
+ valores.push(await this.avaliar(expressao.valores[i]));
878
+ }
879
+ return valores;
880
+ }
881
+ // TODO: Após remoção do Resolvedor, simular casos que usem 'super' e 'isto'.
882
+ visitarExpressaoSuper(expressao) {
883
+ const superClasse = this.pilhaEscoposExecucao.obterVariavelPorNome('super');
884
+ const objeto = this.pilhaEscoposExecucao.obterVariavelPorNome('isto');
885
+ const metodo = superClasse.valor.encontrarMetodo(expressao.metodo.lexema);
886
+ if (metodo === undefined) {
887
+ throw new excecoes_1.ErroEmTempoDeExecucao(expressao.metodo, 'Método chamado indefinido.', expressao.linha);
888
+ }
889
+ return metodo.definirInstancia(objeto.valor);
890
+ }
891
+ paraTexto(objeto) {
892
+ if (objeto === null || objeto === undefined)
893
+ return 'nulo';
894
+ if (typeof objeto === 'boolean') {
895
+ return objeto ? 'verdadeiro' : 'falso';
896
+ }
897
+ if (objeto instanceof Date) {
898
+ const formato = Intl.DateTimeFormat('pt', {
899
+ dateStyle: 'full',
900
+ timeStyle: 'full',
901
+ });
902
+ return formato.format(objeto);
903
+ }
904
+ if (Array.isArray(objeto))
905
+ return objeto;
906
+ if (objeto.valor instanceof estruturas_1.ObjetoPadrao)
907
+ return objeto.valor.paraTexto();
908
+ if (typeof objeto === 'object')
909
+ return JSON.stringify(objeto);
910
+ return objeto.toString();
911
+ }
912
+ /**
913
+ * Efetivamente executa uma declaração.
914
+ * @param declaracao A declaração a ser executada.
915
+ * @param mostrarResultado Se resultado deve ser mostrado ou não. Normalmente usado
916
+ * pelo modo LAIR.
917
+ */
918
+ async executar(declaracao, mostrarResultado = false) {
919
+ const resultado = await declaracao.aceitar(this);
920
+ if (mostrarResultado) {
921
+ this.funcaoDeRetorno(this.paraTexto(resultado));
922
+ }
923
+ if (resultado || typeof resultado === 'boolean') {
924
+ this.resultadoInterpretador.push(this.paraTexto(resultado));
925
+ }
926
+ return resultado;
927
+ }
928
+ /**
929
+ * Executa o último escopo empilhado no topo na pilha de escopos do interpretador.
930
+ * Esse método pega exceções, mas apenas as devolve.
931
+ *
932
+ * O tratamento das exceções é feito de acordo com o bloco chamador.
933
+ * Por exemplo, em `tente ... pegue ... finalmente`, a exceção é capturada e tratada.
934
+ * Em outros blocos, pode ser desejável ter o erro em tela.
935
+ * @param manterAmbiente Se verdadeiro, ambiente do topo da pilha de escopo é copiado para o ambiente imediatamente abaixo.
936
+ * @returns O resultado da execução do escopo, se houver.
937
+ */
938
+ async executarUltimoEscopo(manterAmbiente = false) {
939
+ const ultimoEscopo = this.pilhaEscoposExecucao.topoDaPilha();
940
+ try {
941
+ let retornoExecucao;
942
+ for (; !(retornoExecucao instanceof quebras_1.Quebra) && ultimoEscopo.declaracaoAtual < ultimoEscopo.declaracoes.length; ultimoEscopo.declaracaoAtual++) {
943
+ retornoExecucao = await this.executar(ultimoEscopo.declaracoes[ultimoEscopo.declaracaoAtual]);
944
+ }
945
+ return retornoExecucao;
946
+ }
947
+ catch (erro) {
948
+ return Promise.reject(erro);
949
+ }
950
+ finally {
951
+ this.pilhaEscoposExecucao.removerUltimo();
952
+ if (manterAmbiente) {
953
+ const escopoAnterior = this.pilhaEscoposExecucao.topoDaPilha();
954
+ escopoAnterior.ambiente.valores = Object.assign(escopoAnterior.ambiente.valores, ultimoEscopo.ambiente.valores);
955
+ }
956
+ }
957
+ }
958
+ /**
959
+ * Interpretação sem depurador, com medição de performance.
960
+ * Método que efetivamente inicia o processo de interpretação.
961
+ * @param declaracoes Um vetor de declarações gerado pelo Avaliador Sintático.
962
+ * @param manterAmbiente Se ambiente de execução (variáveis, classes, etc.) deve ser mantido. Normalmente usado
963
+ * pelo modo REPL (LAIR).
964
+ * @returns Um objeto com o resultado da interpretação.
965
+ */
966
+ async interpretar(declaracoes, manterAmbiente = false) {
967
+ this.erros = [];
968
+ const escopoExecucao = {
969
+ declaracoes: declaracoes,
970
+ declaracaoAtual: 0,
971
+ ambiente: new espaco_variaveis_1.EspacoVariaveis(),
972
+ finalizado: false,
973
+ tipo: 'outro',
974
+ };
975
+ this.pilhaEscoposExecucao.empilhar(escopoExecucao);
976
+ const inicioInterpretacao = (0, browser_process_hrtime_1.default)();
977
+ try {
978
+ const retornoOuErro = await this.executarUltimoEscopo(manterAmbiente);
979
+ if (retornoOuErro instanceof excecoes_1.ErroEmTempoDeExecucao) {
980
+ this.erros.push(retornoOuErro);
981
+ }
982
+ }
983
+ catch (erro) {
984
+ this.erros.push(erro);
985
+ }
986
+ finally {
987
+ if (this.performance) {
988
+ const deltaInterpretacao = (0, browser_process_hrtime_1.default)(inicioInterpretacao);
989
+ console.log(`[Interpretador] Tempo para interpretaçao: ${deltaInterpretacao[0] * 1e9 + deltaInterpretacao[1]}ns`);
990
+ }
991
+ const retorno = {
992
+ erros: this.erros,
993
+ resultado: this.resultadoInterpretador,
994
+ };
995
+ this.resultadoInterpretador = [];
996
+ return retorno;
997
+ }
998
+ }
999
+ }
1000
+ exports.InterpretadorBase = InterpretadorBase;
973
1001
  //# sourceMappingURL=interpretador-base.js.map