Ver Fonte

Alterações de @leo

Igor há 5 anos atrás
pai
commit
44444fe3cf
100 ficheiros alterados com 10113 adições e 51278 exclusões
  1. 83 0
      alteracoes_erros.txt~
  2. 12 12
      ex_pt/exerc/exerc_1_1_ler_imprimir_novo.ivph
  3. 3 4
      ex_pt/index.html
  4. 169 0
      ex_pt/index.html~
  5. BIN
      img/img_ivprogh_itarefa.png
  6. BIN
      img/img_ivprogh_soma_pares_1.png
  7. BIN
      img/img_ivprogh_soma_pares_2.png
  8. BIN
      img/img_ivprogh_soma_pares_3.png
  9. 11 13
      index.html
  10. 86 0
      index.html~
  11. 3254 612
      ivprogh/build/ivprog.bundle.js
  12. 1 1
      ivprogh/build/ivprog.bundle.js.map
  13. 0 50233
      ivprogh/build/ivprog.bundle.js~
  14. 180 12
      ivprogh/css/ivprog-visual-1.0.css
  15. 35 0
      ivprogh/i18n/en/error.json
  16. 9 0
      ivprogh/i18n/en/index.js
  17. 3 0
      ivprogh/i18n/en/message.json
  18. 125 0
      ivprogh/i18n/en/ui.json
  19. 3 0
      ivprogh/i18n/es/error.json
  20. 9 0
      ivprogh/i18n/es/index.js
  21. 3 0
      ivprogh/i18n/es/message.json
  22. 130 0
      ivprogh/i18n/es/ui.json
  23. 117 0
      ivprogh/i18n/i18n-database.json
  24. 9 0
      ivprogh/i18n/index.js
  25. 85 0
      ivprogh/i18n/pt/error.json
  26. 9 0
      ivprogh/i18n/pt/index.js
  27. 3 0
      ivprogh/i18n/pt/message.json
  28. 132 0
      ivprogh/i18n/pt/ui.json
  29. BIN
      ivprogh/img/background-panel.png
  30. 19 34
      ivprogh/index.html
  31. 90 0
      ivprogh/js/assessment/ivprogAssessment.js
  32. 47 0
      ivprogh/js/ast/ASA.txt
  33. 10 0
      ivprogh/js/ast/commands/arrayAssign.js
  34. 10 0
      ivprogh/js/ast/commands/arrayDeclaration.js
  35. 10 0
      ivprogh/js/ast/commands/assign.js
  36. 8 0
      ivprogh/js/ast/commands/break.js
  37. 18 0
      ivprogh/js/ast/commands/case.js
  38. 14 0
      ivprogh/js/ast/commands/command.js
  39. 16 0
      ivprogh/js/ast/commands/commandBlock.js
  40. 12 0
      ivprogh/js/ast/commands/declaration.js
  41. 13 0
      ivprogh/js/ast/commands/doWhile.js
  42. 16 0
      ivprogh/js/ast/commands/for.js
  43. 17 0
      ivprogh/js/ast/commands/formalParameter.js
  44. 32 0
      ivprogh/js/ast/commands/function.js
  45. 11 0
      ivprogh/js/ast/commands/ifThenElse.js
  46. 37 0
      ivprogh/js/ast/commands/index.js
  47. 10 0
      ivprogh/js/ast/commands/return.js
  48. 10 0
      ivprogh/js/ast/commands/switch.js
  49. 12 0
      ivprogh/js/ast/commands/sysCall.js
  50. 18 0
      ivprogh/js/ast/commands/while.js
  51. 8 0
      ivprogh/js/ast/error/syntaxError.js
  52. 70 0
      ivprogh/js/ast/error/syntaxErrorFactory.js
  53. 24 0
      ivprogh/js/ast/expressions/arrayAccess.js
  54. 87 0
      ivprogh/js/ast/expressions/arrayLiteral.js
  55. 15 0
      ivprogh/js/ast/expressions/boolLiteral.js
  56. 14 0
      ivprogh/js/ast/expressions/expression.js
  57. 36 0
      ivprogh/js/ast/expressions/functionCall.js
  58. 23 0
      ivprogh/js/ast/expressions/index.js
  59. 18 0
      ivprogh/js/ast/expressions/infixApp.js
  60. 15 0
      ivprogh/js/ast/expressions/intLiteral.js
  61. 9 0
      ivprogh/js/ast/expressions/literal.js
  62. 15 0
      ivprogh/js/ast/expressions/realLiteral.js
  63. 14 0
      ivprogh/js/ast/expressions/stringLiteral.js
  64. 14 0
      ivprogh/js/ast/expressions/unaryApp.js
  65. 14 0
      ivprogh/js/ast/expressions/variableLiteral.js
  66. 1182 0
      ivprogh/js/ast/ivprogParser.js
  67. 35 0
      ivprogh/js/ast/operators.js
  68. 22 0
      ivprogh/js/ast/sourceInfo.js
  69. 0 343
      ivprogh/js/iassign-integration-functions.js~
  70. 138 0
      ivprogh/js/io/domConsole.js
  71. 37 0
      ivprogh/js/io/domInput.js
  72. 21 0
      ivprogh/js/io/domOutput.js
  73. 6 0
      ivprogh/js/io/input.js
  74. 6 0
      ivprogh/js/io/output.js
  75. 13 0
      ivprogh/js/main.js
  76. 180 0
      ivprogh/js/processor/compatibilityTable.js
  77. 5 0
      ivprogh/js/processor/context.js
  78. 128 0
      ivprogh/js/processor/definedFunctions.js
  79. 398 0
      ivprogh/js/processor/error/processorErrorFactory.js
  80. 8 0
      ivprogh/js/processor/error/runtimeError.js
  81. 8 0
      ivprogh/js/processor/error/semanticError.js
  82. 968 0
      ivprogh/js/processor/ivprogProcessor.js
  83. 58 0
      ivprogh/js/processor/lib/arrays.js
  84. 57 0
      ivprogh/js/processor/lib/io.js
  85. 188 0
      ivprogh/js/processor/lib/lang.js
  86. 254 0
      ivprogh/js/processor/lib/math.js
  87. 94 0
      ivprogh/js/processor/lib/strings.js
  88. 6 0
      ivprogh/js/processor/modes.js
  89. 517 0
      ivprogh/js/processor/semantic/semanticAnalyser.js
  90. 76 0
      ivprogh/js/processor/store/store.js
  91. 54 0
      ivprogh/js/processor/store/storeObject.js
  92. 79 0
      ivprogh/js/processor/store/storeObjectArray.js
  93. 101 0
      ivprogh/js/processor/store/storeObjectArrayAddress.js
  94. 43 0
      ivprogh/js/processor/store/storeObjectArrayAddressRef.js
  95. 43 0
      ivprogh/js/processor/store/storeObjectRef.js
  96. 49 0
      ivprogh/js/runner.js
  97. 0 14
      ivprogh/js/semantic/semantic-buttons.js
  98. 22 0
      ivprogh/js/services/i18nHelper.js
  99. 40 0
      ivprogh/js/services/languageService.js
  100. 0 0
      ivprogh/js/services/localizedStringsService.js

+ 83 - 0
alteracoes_erros.txt~

@@ -0,0 +1,83 @@
+2018/11/17
+
+Usei marcador "//leo1"
+
+/home/leo/projetos/iMA/ima/ivprog_html5/2018/manual_ima/www/ivprogh/i18n/i18n-engine.js
+ + fuction i18n(identifier): no Vivaldi resulta erro (e NAO carrega)
+     at i18n (i18n-engine.js:11)
+       Uncaught TypeError: Cannot read property 'ERROR' of undefined
+     Solucao: acrescentei 'try/catch'
+       try { // Vivaldi: error 'Uncaught TypeError: Cannot read property 'ERROR' of undefined
+         if (StringTypes.ERROR === type) ...
+       } catch (error) { 
+         //DEBUG alert('./ivprogh/i18n/i18n-engine.js: i18n('+identifier+'): error ' + error);
+         }
+
+
+/home/leo/projetos/iMA/ima/ivprog_html5/2018/manual_ima/www/ivprogh/build/ivprog.bundle.js:
+  + linha 49198/50226: var lang = localStorage.getItem(this.lsKey);
+    Erro: SecurityError: Failed to read the 'localStorage' property from 'Window': Access is denied for this document.
+    Rever: essa funcao esta sendo chamada MUITAS vezes!
+    LanguageService.prototype.getLang = function (): linha "var lang = localStorage.getItem(this.lsKey);"
+    Troque por:
+    var lang;
+    try { lang = localStorage.getItem(this.lsKey); } catch (error) {
+      //DEBUG alert('./ivprogh/build/ivprog.bundle.js: LanguageService.prototype.getLang(): error ' + error);
+      /TODO   rever aqui, pois ao carregar iVProg esse metodo esta sendo chamado MUITAS vezes!		
+      return "pt"; //TODO "pt_BR" "en_US"
+      }
+
+
+/home/leo/projetos/iMA/ima/ivprog_html5/2018/manual_ima/www/ivprogh/js/iassign-integration-functions.js
+  + linha 20/340 (antes de alterar, depois 341)
+    Uncaught DOMException: Failed to read the 'localStorage' property from 'Window': Access is denied for this document.
+      at file:///home/leo/projetos/iMA/ima/ivprog_html5/2018/manual_ima/www/ivprogh/js/iassign-integration-functions.js:20:1
+    Troqui: localStorage.setItem('ivprog.lang', iLMparameters.lang);
+    Por:
+    try { localStorage.setItem('ivprog.lang', iLMparameters.lang); }
+    catch (error) { } //leo1 If NOT in iAssign 'localStorage' is undefined! Do not try: localStorage.setItem('ivprog.lang', 'pt');
+
+---
+
+Botao 'submit'
+
+/home/leo/projetos/iMA/ima/ivprog_html5/2018/manual_ima/www/ivprogh/js/iassign-integration-functions.js
+  + function getEvaluation (): if (iLMparameters.iLM_PARAM_SendAnswer == 'false') runCodeAssessment();
+
+
+/home/leo/projetos/iMA/ima/ivprog_html5/2018/manual_ima/www/ivprogh/build/ivprog.bundle.js
+  + 19265/50232:
+    window.runCodeAssessment = runCodeAssessment;
+  + 19587/50232:
+    function runCodeAssessment(): ...
+    
+
+---
+
+Manual
+
+Eliminar recurso de: https://www.w3schools.com/w3css/4/w3.css
+Usar origem: https://pastebin.com/raw/VLAn1rV0
+
+Eliminar recurso de: https://www.w3schools.com/lib/w3-theme-teal.css
+
+Eliminar: https://fonts.googleapis.com/css?family=Roboto
+
+Eliminar: https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css
+
+index.html
+ + 'myAccordion' -> 'manuItem'
+ + "onclick="carregar('..." -> "onclick="carregar('menu_...": 24 mudancas
+
+Alterados nomes de quase todos os HTML.
+
+Alterados inicio de quase todos os HTML.
+
+Alteradas explicacoes em quase todos os HTML.
+ 
+w3.css
+ .w3-button:hover: color:#000 -> color:#fff e background-color:#ccc -> background-color:#001A66
+ .w3-show: acresc ";color:#001065;background-color:#eee" em "{display:block!important;color:#001065;background-color:#eee}"
+ .w3-item{padding:4px;display:block;border:1pt;border-bottom:1px solid #001A66;width:100%}: novo!
+
+ 

+ 12 - 12
ex_pt/exerc/exerc_1_1_ler_imprimir_novo.ivph

@@ -1,25 +1,25 @@
 {
-"testcases" : [
-{
+"testcases" : [ 
+{ 
  "input": ["-123"], 
 "output": ["-123"]
 },
-{
- "input": ["0"],
+{ 
+ "input": ["0"], 
 "output": ["0"]
 },
-{
- "input": ["123"],
+{ 
+ "input": ["123"], 
 "output": ["123"]
 },
-{
- "input": ["4321"],
+{ 
+ "input": ["4321"], 
 "output": ["4321"]
 }
-],
-"settings_data_types":
+] ,
+"settings_data_types": 
 [{"name":"integer_data_type","value":"on"}],
-"settings_commands":
+"settings_commands": 
 [{"name":"commands_read","value":"on"},{"name":"commands_write","value":"on"},{"name":"commands_comment","value":"on"}],
-"settings_functions":
+"settings_functions": 
 [] }

+ 3 - 4
ex_pt/index.html

@@ -59,7 +59,6 @@
     }
 
   function getEvaluationCallback (evaluation) {
-console.log(evaluation);
     evaluationResult = evaluation;
     strAnswer = window.frames.iLM.getAnswer();
     alert('getEvaluationCallback(...)' + evaluation + ', strAnswer=' + strAnswer);
@@ -144,7 +143,7 @@ console.log(evaluation);
                 enctype='multipart/form-data'>
           <div class="embed-responsive embed-responsive-16by9"> <!-- 4by3 -->
             <iframe name="iLM" id="iLM" class="embed-responsive-item"
-                    src="../ivprogh/index.html?iLM_PARAM_AssignmentURL=true&iLM_PARAM_Assignment=../ex_pt/exerc/exerc_1_1_ler_imprimir_novo.ivph&iLM_PARAM_SendAnswer=false&lang=pt"
+                    src="../ivprogh/index.html?iLM_PARAM_AssignmentURL=true&iLM_PARAM_Assignment=./exerc/exerc_1_1_ler_imprimir_novo.ivphiLM_PARAM_SendAnswer=false&lang=en"
                     allowfullscreen></iframe><br/>
           </div>
           <div class="embed-responsive embed-responsive"> <!-- 4by3 -->
@@ -164,7 +163,7 @@ console.log(evaluation);
       <a href="http://www.matematica.br">iM&aacute;tica</a>
     </footer>
 
-    <script src="../js/jquery.min.js"></script>
-    <script src="../js/bootstrap.bundle.min.js"></script>
+    <script src="js/jquery-min.js"></script>
+    <script src="js/bootstrap.min.js"></script>
   </body>
 </html>

+ 169 - 0
ex_pt/index.html~

@@ -0,0 +1,169 @@
+<!doctype html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+    <title>iVProgH - LInE (free educational software and contents)</title>
+    <link href="../css/bootstrap.min.css" rel="stylesheet">
+    <link href="../css/style.css" rel="stylesheet">
+  </head>
+
+<!--
+   -------------------------------------------------------------------------------
+  JavaScript code: starting point
+  This JavaScript code could be inserted in any LMS to get the iLM content and send it to the server.
+  In this example it use a single "applet" instance, here from iHanoi.
+ -->
+<script Language="JavaScript">
+  //<![CDATA[
+  var strAnswer = '';
+  var evaluationResult = '';
+  var comment = '';
+
+  function submit_iMA_Answer () {
+    // alert('./ex_pt/index.html: window.frames=' + window.frames);
+    // alert('./ex_pt/index.html: window.frames.iLM=' + window.frames.iLM);
+    /* DEBUG
+    var strFrames = "";
+    var arrFrames = parent.document.getElementsByTagName("IFRAME");
+    for (var i=0; i<arrFrames.length; i++) {
+      strFrames += ', ' + arrFrames[i].name; // if (arrFrames[i].contentWindow === window) alert("yay!");
+      } // acho 'window.frames' de nome 'iLM'!!!
+    alert('./ex_pt/index.html: window.frames=' + strFrames);
+    */
+    window.frames.iLM.getEvaluation(); // ../ivprogh/js/iassign-integration-functions.js
+    // window.frames.iLM.runCodeAssessment();
+    var strAnswer = window.frames.iLM.getAnswer();
+    alert('./ex_pt/index.html: getAnswer()=' + strAnswer);
+
+    /*
+    var docForm = document.formEnvio;
+    // Prepared to be used with more than 1 "applet'
+    var exercise_answer = new Array(3); // answer: to get the learner answer
+    var exercise_value = new Array(3);  // value from the iLM automatic evaluator
+    // var doc = document.formEnvio; // ----------------------------------------------------------
+    // var doc = javascript:window.jsAnalyseAnswer();
+    try {
+      alert('submit_iMA_Answer(): evaluationResult=' + evaluationResult);
+      exercise_answer[0] = doc.getAnswer();    // answer: it must be first (usually the iLM first get the answer to compute the evaluation grade)
+      exercise_value[0] = doc.getEvaluation(); // value from the iLM automatic evaluator
+    } catch (Exception) { alert("Error!"); }
+    docForm.iLM_POST_Archive_0.value = exercise_answer[0]; // Content coming from the iLM
+    docForm.iLM_POST_Value_0.value = exercise_value[0];    // The activity evaluation coming from the iLM
+    // This is used to help the developer to debug his iLM
+    // It presents the file content that will be registered. 
+    alert('The file activity value is: ' + exercise_value[0] + '\nThe activity content is:\n' + exercise_answer[0]);
+    //uncomment_this docForm.submit(); // envia de fato o formulario
+    //uncomment_this return true;
+    */
+    }
+
+  function getEvaluationCallback (evaluation) {
+    evaluationResult = evaluation;
+    strAnswer = window.frames.iLM.getAnswer();
+    alert('getEvaluationCallback(...)' + evaluation + ', strAnswer=' + strAnswer);
+    comment = document.formEnvio.submission_comment.value;
+    //leo
+    if ((strAnswer==null || strAnswer=='' || strAnswer==-1) && (comment==null || comment=='')) { // undefined
+      alert('Activity sent without content.'); // 'Activity sent without content.'
+      return false; // error...
+      }
+    else {
+      //leo alert('getEvaluationCallback: enviando evaluationResult=' + evaluation + ', strAnswer=' + strAnswer);
+      document.formEnvio.iLM_PARAM_ArchiveContent.value = strAnswer;
+      document.formEnvio.iLM_PARAM_ActivityEvaluation.value = evaluationResult;
+      document.formEnvio.submit();
+      return true; // success
+      }
+    }
+//]]>
+</script>
+
+<!--
+  JavaScript code: final -------------------------------------------------------------------------------
+-->
+
+  <body>
+    <nav class="navbar navbar-expand-md navbar-dark fixed-top" style="background-color: #03396c;">
+      <b><a class="navbar-brand" href="#">iVProgH</a></b>
+      <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
+        <span class="navbar-toggler-icon"></span>
+      </button>
+      <div class="collapse navbar-collapse" id="navbarsExampleDefault">
+        <ul class="navbar-nav mr-auto">
+          <li class="nav-item active">
+            <a class="nav-link" href="#">Home</a>
+          </li>
+          <li class="nav-item">
+            <a class="nav-link" href="#">Conheça</a>
+          </li>
+          <li class="nav-item">
+            <a class="nav-link" href="#">Exemplos</a>
+          </li>
+          <li class="nav-item">
+            <a class="nav-link" href="#">Download</a>
+          </li>
+          <li class="nav-item">
+            <a class="nav-link" href="#">LInE</a>
+          </li>
+          <li class="nav-item">
+            <a class="nav-link" href="#">Ajuda</a>
+          </li>
+        </ul>
+        <div class="form-inline my-2 my-lg-0">
+          <img src="../img/img_flag_brazil.png">
+          <img src="../img/img_flag_usa.png">
+        </div>
+      </div>
+    </nav>
+
+    <main role="main">
+      <div class="jumbotron ivprogh-desc">
+        <div class="container">
+          <h1>iVProgH</h1>
+          <p class="text-reduced">
+          <!--
+          O <b>iVProg</b> (<i>Programação Visual interativa na Internet</i>) é um dos sistemas educacionais de código livre do
+          <a href="http://line.ime.usp.br" title="pagina LInE no IME-USP">LInE</a>, sendo destinado ao ensino e à aprendizagem
+          de <b>algoritmos</b> e <b>programação</b>.
+          -->
+          Exemplo de exercício com <i>avaliação automática</i> no <i>iVProg</i>.
+          </p>
+          
+          <p class="text-reduced">
+          <b>Fazer um programa que solicite do usuário um valor inteiro, depois imprima o valor por ele digitado.
+          </p>
+
+          <a class="btn btn-primary" href="manual_pt/index.html" role="button" title="manual iVProgH">Saiba mais &raquo;</a>
+        </div>
+      </div>
+      <div class="container ivprog-container">
+       <form name='formEnvio' id='formEnvio' method='post' \
+                action='#'\
+                enctype='multipart/form-data'>
+          <div class="embed-responsive embed-responsive-16by9"> <!-- 4by3 -->
+            <iframe name="iLM" id="iLM" class="embed-responsive-item"
+                    src="../ivprogh/index.html?iLM_PARAM_AssignmentURL=true&iLM_PARAM_Assignment=exerc/exerc_1_1_ler_imprimir_novo.ivphiLM_PARAM_SendAnswer=false&lang=en"
+                    allowfullscreen></iframe><br/>
+          </div>
+          <div class="embed-responsive embed-responsive"> <!-- 4by3 -->
+            <center>
+            <input type='button' name='Submit' value='Enviar resposta' 
+                   title='clique aqui para vesualizar seu codigo'
+                   onclick='javascript:window.submit_iMA_Answer();' /><!-- chama funcao iMA-->
+            </center>
+          </div>
+        </form>
+      </div>
+
+    </main>
+    <footer class="container text-center">
+      <a href="http://www.ime.usp.br/line">iVProgH</a> | 
+      <a href="http://www.ime.usp.br/line">LInE</a> |
+      <a href="http://www.matematica.br">iM&aacute;tica</a>
+    </footer>
+
+    <script src="js/jquery-min.js"></script>
+    <script src="js/bootstrap.min.js"></script>
+  </body>
+</html>

BIN
img/img_ivprogh_itarefa.png


BIN
img/img_ivprogh_soma_pares_1.png


BIN
img/img_ivprogh_soma_pares_2.png


BIN
img/img_ivprogh_soma_pares_3.png


+ 11 - 13
index.html

@@ -1,11 +1,11 @@
 <!doctype html>
 <html lang="en">
   <head>
-    <meta charset="utf-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+    <meta charset="utf-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
     <title>iVProgH - LInE (free educational software and contents)</title>
-    <link href="css/bootstrap.min.css" rel="stylesheet">
-    <link href="css/style.css" rel="stylesheet">
+    <link href="css/bootstrap.min.css" rel="stylesheet" />
+    <link href="css/style.css" rel="stylesheet" />
   </head>
 
   <body>
@@ -20,7 +20,8 @@
             <a class="nav-link" href="#">Home</a>
           </li>
           <li class="nav-item">
-            <a class="nav-link" href="manual_pt/index.html" title="manual iVProgH">Conheça</a>
+            <a class="nav-link" href="sobre_ivprog.html"
+               title="conheca resumidamente o que e' e para que serve o iVProgH">Conheça</a>
           </li>
           <li class="nav-item">
             <a class="nav-link" href="ex_pt/index.html">Exemplos</a>
@@ -28,19 +29,16 @@
           <li class="nav-item">
             <a class="nav-link" href="#">Download</a>
           </li>
-          <li class="nav-item">
-            <a class="nav-link" href="bugs/report.html">Informar uma falha</a>
-          </li>
           <li class="nav-item">
             <a class="nav-link" href="#">LInE</a>
           </li>
           <li class="nav-item">
-            <a class="nav-link" href="#">Ajuda</a>
+            <a class="nav-link" href="manual_pt/index.html" title="manual iVProgH">Manual</a>
           </li>
         </ul>
         <div class="form-inline my-2 my-lg-0">
-          <img src="img/img_flag_brazil.png">
-          <img src="img/img_flag_usa.png">
+          <img src="img/img_flag_brazil.png" />
+          <img src="img/img_flag_usa.png" ;>
         </div>
       </div>
     </nav>
@@ -82,7 +80,7 @@
       <a href="http://www.matematica.br">iM&aacute;tica</a>
     </footer>
 
-    <script src="js/jquery.min.js"></script>
-    <script src="js/bootstrap.bundle.min.js"></script>
+    <script src="js/jquery-min.js"></script>
+    <script src="js/bootstrap.min.js"></script>
   </body>
 </html>

+ 86 - 0
index.html~

@@ -0,0 +1,86 @@
+<!doctype html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
+    <title>iVProgH - LInE (free educational software and contents)</title>
+    <link href="css/bootstrap.min.css" rel="stylesheet" />
+    <link href="css/style.css" rel="stylesheet" />
+  </head>
+
+  <body>
+    <nav class="navbar navbar-expand-md navbar-dark fixed-top" style="background-color: #03396c;">
+      <b><a class="navbar-brand" href="#">iVProgH</a></b>
+      <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
+        <span class="navbar-toggler-icon"></span>
+      </button>
+      <div class="collapse navbar-collapse" id="navbarsExampleDefault">
+        <ul class="navbar-nav mr-auto">
+          <li class="nav-item active">
+            <a class="nav-link" href="#">Home</a>
+          </li>
+          <li class="nav-item">
+            <a class="nav-link" href="sobre_ivprog.html"
+               title="conheca resumidamente o que e' e para que serve o iVProgH">Conheça</a>
+          </li>
+          <li class="nav-item">
+            <a class="nav-link" href="ex_pt/index.html">Exemplos</a>
+          </li>
+          <li class="nav-item">
+            <a class="nav-link" href="#">Download</a>
+          </li>
+          <li class="nav-item">
+            <a class="nav-link" href="#">LInE</a>
+          </li>
+          <li class="nav-item">
+            <a class="nav-link" href="manual_pt/index.html" title="manual iVProgH">Manual</a>
+          </li>
+        </ul>
+        <div class="form-inline my-2 my-lg-0">
+          <img src="img/img_flag_brazil.png">
+          <img src="img/img_flag_usa.png">
+        </div>
+      </div>
+    </nav>
+
+    <main role="main">
+      <div class="jumbotron ivprogh-desc">
+        <div class="container">
+          <h1>iVProgH</h1>
+          <p class="text-reduced">
+          O <b>iVProg</b> (<i>Programação Visual interativa na Internet</i>) é um dos sistemas educacionais de código livre do
+          <a href="http://line.ime.usp.br" title="pagina LInE no IME-USP">LInE</a>, sendo destinado ao ensino e à aprendizagem
+          de <b>algoritmos</b> e <b>programação</b>.
+          O <i>iVProg</i> implementa o conceito de <b>Programação Visual (PV)</b> que emprega ícones e simplifica a construção de códigos,
+          reduzindo a necessidade do aprendiz conhecer detalhes de <i>linguagens de programação</i>.
+          </p>
+          
+          <p class="text-reduced">
+          Por esta versão ser implementada em <i>HTML5</i> (usa fortemente <i>JavaScript</i>), a denominamos <b>iVProgH</b>.
+          Ela dispõe de um
+          <a href="autoeval/index.html" title="saiba mais sobre"><b>avaliador automático</b></a>
+          para exercícios e pode facilmente ser integrado ao ambiente <i>Moodle</i> a partir do pacote
+          <a href="http://www.matematica.br/ia" title="pagina do iTarefa no iMatica"><b>iTarefa</b></a>.
+          A <a href="ivprog1/" title="primeira versao iVProg em Java">primeira versão do <i>iVProg</i></a> foi implementada em <i>Java</i> em 2009.
+          </p>
+
+          <a class="btn btn-primary" href="manual_pt/index.html" role="button" title="manual iVProgH">Saiba mais &raquo;</a>
+        </div>
+      </div>
+      <div class="container ivprog-container">
+        <div class="embed-responsive embed-responsive-16by9">
+          <iframe class="embed-responsive-item" src="ivprogh/index.html" allowfullscreen></iframe>
+        </div>
+      </div>
+
+    </main>
+    <footer class="container text-center">
+      <a href="http://www.ime.usp.br/line">iVProgH</a> | 
+      <a href="http://www.ime.usp.br/line">LInE</a> |
+      <a href="http://www.matematica.br">iM&aacute;tica</a>
+    </footer>
+
+    <script src="js/jquery-min.js"></script>
+    <script src="js/bootstrap.min.js"></script>
+  </body>
+</html>

Diff do ficheiro suprimidas por serem muito extensas
+ 3254 - 612
ivprogh/build/ivprog.bundle.js


Diff do ficheiro suprimidas por serem muito extensas
+ 1 - 1
ivprogh/build/ivprog.bundle.js.map


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 50233
ivprogh/build/ivprog.bundle.js~


+ 180 - 12
ivprogh/css/ivprog-visual-1.0.css

@@ -11,6 +11,7 @@ body {
   padding: 10px;
   padding-left: 6px;
   padding-right: 6px;
+  background-color: #1279c6;
 }
 
 .ivprog_visual_panel {
@@ -151,7 +152,8 @@ body {
 .function_name_div, .function_return_div, .function_name_parameter, .created_div_valor_var, .function_return, .var_value_menu_div, .variable_rendered, .variable_rendered div, .var_attributed,
 .expression_operand_1, .expression_operand_2, .operator, .div_comment_text, .value_rendered, .parameters_function_called, .parameters_function_called div, .expression_elements,
 .expression_element, .var_rendered, .menu_add_item, .component_element, .component_element, .conditional_expression, .variable_attribution, .attribution_expression, .var_value_expression,
-.incrementation_field, .incrementation_variable, .first_operand, .operator, .second_operand, .variable_to_switch, .variable_case, .button_remove_case, .editing_name_var, .parameter_div_edit {
+.incrementation_field, .incrementation_variable, .first_operand, .operator, .second_operand, .variable_to_switch, .variable_case, .button_remove_case, .editing_name_var, .parameter_div_edit,
+.all_elements_write, .container_var_element_control, .inline_add_command {
 	display: inline;
 }
 
@@ -178,13 +180,14 @@ body {
 .ui.segment.ivprog_visual_panel {
 	padding: 3px;
 	margin-top: -5px;
-	background: #edf4ff;
+	background: white;
 }
 
 .ui.segment.function_div {
 	padding: 5px;
 	margin: 0;
 	margin-bottom: 5px;
+	background-color: #bddbff;
 }
 
 .ui.button.add_function_button,
@@ -282,7 +285,15 @@ div.buttons_manage_columns {
 	margin: 5px;
 	background: #f9f9f9;
 }
-
+.ui.repeatNtimes .separator_character {
+	margin-right: 10px;
+}
+.ui.repeatNtimes, .ui.whiletrue {
+    min-height: 50px;
+}
+.ui.dowhiletrue .ui.block_commands {
+	min-height: 10px;
+}
 .add_var_top_button {
 	padding-right: 50px;
 }
@@ -429,8 +440,8 @@ div.function_name_div_updated {
 	margin-right: 3px;
 }
 
-.global_container .global_type:hover, .editing_name_var:hover, .global_container .span_value_variable:hover,
-.variable_container .variable_type:hover, .variable_container .span_name_variable:hover, .variable_container .span_value_variable:hover,
+.global_container .global_type:hover, .global_container .span_value_variable:hover,
+.variable_container .variable_type:hover, .variable_container .span_value_variable:hover,
 .ui.dropdown.function_return:hover, div.function_name_div_updated:hover,
 .ui.dropdown.parameter_type:hover, .parameter_div_edit:hover {
 	background: #848484;
@@ -466,17 +477,17 @@ div.function_name_div_updated:active,
     font-size: 150%;
 }
 
-.red.icon.times.remove_global,
-.red.icon.times.remove_variable,
-.red.icon.times.remove_parameter {
+.yellow.icon.times.remove_global,
+.yellow.icon.times.remove_variable,
+.yellow.icon.times.remove_parameter {
 	float: right;
     margin-right: -1px;
     margin-left: 8px;
     opacity: 0;
 }
 
-.global_container:hover > .red.icon.times.remove_global, .variable_container:hover > .red.icon.times.remove_variable,
-.function_name_parameter:hover > .red.icon.times.remove_parameter {
+.global_container:hover > .yellow.icon.times.remove_global, .variable_container:hover > .yellow.icon.times.remove_variable,
+.function_name_parameter:hover > .yellow.icon.times.remove_parameter {
 	opacity: 1;
 }
 
@@ -485,8 +496,9 @@ div.function_name_div_updated:active,
 }
 
 .ui.icon.button.add-globalVar-button.add_global_button {
-	padding: 8px;
-	margin-bottom: 4px;
+	padding: 7px;
+    margin-bottom: 4px;
+    padding-bottom: 9px;
 }
 .all_functions {
 	margin-top: -5px;
@@ -615,4 +627,160 @@ div.function_name_div_updated:active,
     width: 100%;
     display: inline-block;
     font-style: italic;
+}
+.ui.dropdown.menu_start_rendered .text i {
+    padding-right: 8px;
+}
+
+* {
+	font-family: 'Roboto', sans-serif;
+}
+
+.add_global_button i {
+	font-size: 130%;
+}
+
+.global_var .circle.add_global_button, .global_var i.back,
+.ui.add_var_context .icon.plus.circle, .ui.add_var_context .icon.circle.back,
+.ui.inline_add_command .icon.plus.circle, .ui.inline_add_command .icon.circle.back {
+	position: absolute;
+}
+.global_var .circle.add_global_button,
+.ui.add_var_context .icon.plus.circle,
+.inline_add_command .icon.plus.circle {
+	z-index: 10;
+	color: #bf80d4!important;
+	cursor: pointer;
+	font-style: 120%;
+}
+.global_var i.back,
+.ui.add_var_context .icon.circle.back,
+.inline_add_command .icon.circle.back {
+	z-index: 9;
+	color: white !important;
+}
+.ui.add_var_context{
+	margin-left: -4px;
+}
+.inline_add_command {
+	color: #ab0054 !important;
+}
+
+.ui.add_var_context .icon.superscript {
+	font-size: 110%;
+}
+.ui.add_var_context .ui.icon.button.purple {
+	padding: 8px;
+}
+
+.global_container .global_const, .global_container .global_type,
+.variable_container .variable_type {
+	font-size: 114%;
+}
+.global_container .editing_name_var,
+.variable_container .editing_name_var {
+	font-size: 108%;
+}
+.global_container .global_const i {
+	font-size: 120%;
+}
+.global_container .span_value_variable,
+.variable_container .span_value_variable {
+    font-size: 110%;
+}
+.global_container .global_type, .global_container .editing_name_var, .global_container .span_value_variable,
+.variable_container .variable_type,  .variable_container .span_value_variable, .variable_container .editing_name_var,
+.ui.dropdown.parameter_type, .parameter_div_edit {
+	background: black;
+	border-radius: 5px;
+	padding: 4px;
+	margin-left: 5px;
+	margin-right: 5px;
+}
+
+.global_container .global_type:hover, .global_container .editing_name_var:hover, .global_container .span_value_variable:hover,
+.variable_container .variable_type:hover,  .variable_container .span_value_variable:hover, .variable_container .editing_name_var:hover,
+.ui.dropdown.parameter_type:hover, .parameter_div_edit:hover {
+	background-color: #545353;
+}
+.yellow.icon.times.remove_global,
+.yellow.icon.times.remove_variable {
+	color: yellow;
+	font-size: 125%;
+}
+.inline_add_command .icon.plus.circle {
+	color: #ec9962 !important;
+}
+.inline_add_command .icon.plus.circle, 
+.inline_add_command .icon.circle.back,
+.ui.add_var_context .icon.plus.circle, 
+.ui.add_var_context .icon.circle.back,
+.global_var .icon.plus.circle, 
+.global_var .icon.circle.back {
+	left: 1.8em !important;
+	margin-top: 1.5em !important;
+}
+.ui.icon.button.dropdown.menu_commands {
+    float: left;
+    color: white;
+    margin-left: -4px;
+    padding: 8px;
+    margin-top: 0.3em;
+}
+
+.ui.dropdown.variable_type {
+	padding: 5px;
+}
+
+.global_var .global_container .ellipsis,
+.variable_container .ui.icon.ellipsis.vertical.inverted,
+.ui.label.function_name_parameter.pink .ui.icon.ellipsis.vertical.inverted {
+	position: relative;
+    margin-left: -3px;
+    margin-right: 4px;
+    opacity: 0;
+    cursor: move;
+    font-size: 120%;
+}
+
+.global_container:hover > .ellipsis,
+.variable_container:hover > .ui.icon.ellipsis.vertical.inverted {
+	opacity: 1;
+}
+
+.glyphicon.glyphicon-move.move_function i {
+	font-size: 130%;
+}
+
+.span_name_parameter.label_enable_name_parameter {
+	font-size: 94%;
+    font-weight: 700;
+}
+
+.ui.dropdown.parameter_type {
+	font-size: 96%;
+}
+.ui.label.function_name_parameter .ellipsis {
+	font-size: 96% !important;
+	margin-left: .05em !important;
+}
+.ui.label.function_name_parameter:hover > .ellipsis {
+	opacity: 1 !important;
+}
+
+.command_container {
+    background: #e9dede !important;
+	border: 2px solid #e76060 !important;
+    border-radius: 0.25em !important;
+}
+.command_drag {
+	cursor: move;
+}
+.command_container.over_command_drag {
+	border: 3px dotted blue !important;
+	padding: 0.315em !important;
+}
+.commands_list_div.over_command_drag {
+	border: 3px dotted blue !important;
+	padding: 0.2em !important;
 }

+ 35 - 0
ivprogh/i18n/en/error.json

@@ -0,0 +1,35 @@
+{
+  "token_missing_one": "Erro de sintaxe: Espera-se $0, mas encontrou-se $1 na linha:$2, coluna:$3",
+  "token_missing_two": "Erro de sintaxe: Esperava-se $0 ou $1 mas encontrou-se $2 na liha:$3, coluna: $4",
+  "eos_missing": "Falta uma nova linha ou ; na linha: $0, coluna: $1",
+  "invalid_type": "$0 na linha: $1, coluna: $2 é um tipo inválido. Os tipos válidos são: $3",
+  "invalid_array_dimension": "A dimensão inválida na linha: $0, coluna: $1. Insira um $2 ou identificador válido do mesmo tipo.",
+  "invalid_array_size": "O tamnho do vetor/matriz excede o máximo de 2 na linha $0",
+  "extra_lines": "Nenhum texto é permitido após '}' em 'programa {...}'",
+  "invalid_main_return": "A função $0 deve retornar $1 na linha $2",
+  "invalid_var_declaration": "Erro na linha $0. Variáveis só podem ser declarados no corpo principal da função e de preferência nas primeiras linhas.",
+  "invalid_break_command": "Erro na linha $0. O comando $1 não pode ser usado fora de uma estrutura de repetição ou 'escolha...caso'",
+  "invalid_terminal": "Não é possível utilizar $0 na expressão da linha: $1, coluna: $2. Tente um valor númerico, variável ou chamada de função.",
+  "id_missing": "Esperava-se um identificador, mas encontrou-se $0 na linha: $1, coluna: $2",
+  "main_missing": "A função principal não foi encontrada",
+  "invalid_global_var": "Erro crítico: Chamada inválida da função initGlobal fora do contexto BASE",
+  "not_implemented": "Erro interno crítico: A função definida pelo sistema $0 não foi implementada.",
+  "function_missing": "A função $0 não foi encontrada",
+  "invalid_parameters_size": "A quantidade de parâmetros fornecidos está incorreta. Esperava-se $0, encontrou-se $1",
+  "invalid_ref": "Você deve fornecer apenas um identificador como parâmetro",
+  "invalid_parameter_type": "O valor fornecido como parâmetro é do tipo $0, mas o tipo esperado é $1",
+  "unknown_command": "Erro interno crítico: Comando desconhecido encontrado",
+  "loop_condition_type": "A condição dos laços de repetição deve ser do tipo lógico",
+  "if_condition_type": "A condição de um comando se...senao deve ser do tipo lógico",
+  "invalid_return_type": "A função $0 deve retornar um tipo $1, ao invés de $1",
+  "unexpected_break_command": "Erro interno crítico: Comando pare encontrado fora do contexto de um laço/escolha..caso",
+  "invalid_dimension": "As dimensões de um vetor/matriz devem ser do tipo inteiro",
+  "void_in_expression": "A função $0 não pode ser utilizada aqui pois seu tipo de retorno é vazio",
+  "invalid_array": "Expressão literal de Vetor/Mariz inválida",
+  "invalid_array_access": "Identificador $0 não se refere a um vetor/matriz válido",
+  "column_outbounds": "Número de colunas $0 é inválido para a matriz $1 que possui $2 colunas",
+  "line_outbounds": "Número de linhas $0 é invaálido para a matriz $1 que possui $2 linhas",
+  "invalid_infix_op": "Não é possível aplicar a operação $0 entre os tipos $1 e $2",
+  "invalid_unary_op": "Não é possível aplicar a operação $0 ao tipo $1",
+  "unknown_op": "Erro interno crítico: Operação $0 desconhecida"
+}

+ 9 - 0
ivprogh/i18n/en/index.js

@@ -0,0 +1,9 @@
+import errors from './error.json';
+import messages from './message.json'
+import ui from './ui.json';
+
+export default {
+ 'message' : messages,
+ 'error': errors,
+ 'ui': ui
+}

+ 3 - 0
ivprogh/i18n/en/message.json

@@ -0,0 +1,3 @@
+{
+  
+}

+ 125 - 0
ivprogh/i18n/en/ui.json

@@ -0,0 +1,125 @@
+{
+  "function": "function",
+  "btn_clear": "Clear",
+  "btn_function": "Function",
+  "btn_arithmetic_plus": "Sum",
+  "btn_arithmetic_minus": "Minus",
+  "btn_arithmetic_multiplication": "Multiplication",
+  "btn_arithmetic_division": "Division",
+  "btn_arithmetic_module": "Module",
+  "btn_break":"Break",
+  "btn_case":"Case",
+  "start": "start",
+  "void": "void",
+  "integer": "integer",
+  "real": "real",
+  "program": "program",
+  "text": "string",
+  "text_start": "text",
+  "boolean": "boolean",
+  "true": "true",
+  "false": "false",
+  "variable": "Variable",
+  "command": "Command",
+  "new_parameter": "new_parameter",
+  "new_variable": "new_variable",
+  "new_global": "new_global",
+  "new_function": "new_function",
+  "vector": "vector",
+  "text_comment_start": "Initial comment of function...",
+  "text_comment_main": "This is the main function...",
+  "text_read_var": "Reading data",
+  "text_write_var": "Writing data",
+  "text_command_read":"read",
+  "text_command_write":"write",
+  "text_comment": "Comment",
+  "text_attribution": "Attribution",
+  "text_if":"if",
+  "text_else":"else",
+  "text_break":"break",
+  "text_for":"for",
+  "text_code_while":"while",
+  "text_code_do":"do",
+  "text_command_do":"do",
+  "text_code_switch": "switch",
+  "text_code_case": "case",
+  "text_logic_expression": "Logic Expression",
+  "text_arithmetic_expression": "Arithmetic Expression",
+  "text_iftrue": "If true then",
+  "text_receives": "receives",
+  "text_repeatNtimes": "Repeat N times",
+  "text_return":"return",
+  "text_btn_return":"Return",
+  "text_whiletrue": "While true",
+  "text_dowhiletrue": "Do while true",
+  "text_switch": "Switch",
+  "text_functioncall": "Function call",
+  "text_value": "Value",
+  "text_operator": "Operator",
+  "text_parentheses": "Parentheses",
+  "text_change": "Change",
+  "text_teacher_algorithm": "Algorithm",
+  "text_teacher_algorithm_include": "Include the following algorithm in exercise",
+  "text_teacher_test_case": "Test cases",
+  "text_teacher_config": "Settings",
+  "text_teacher_data_types": "Data types",
+  "text_teacher_commands": "Commands",
+  "text_teacher_functions": "Functions",
+  "text_teacher_create_functions": "Create new functions",
+  "text_teacher_create_movement_functions": "Move functions",
+  "text_teacher_test_case_input": "Input",
+  "text_teacher_test_case_output": "Output",
+  "text_teacher_test_case_actions": "Actions",
+  "text_teacher_test_case_add": "Add test cases",
+  "text_header_ivprog_functions": "iVProg Functions",
+  "text_menu_functions_math":"Mathematic",
+  "text_menu_functions_text":"Text",
+  "text_menu_functions_arrangement":"Arrangement",
+  "text_menu_functions_conversion":"Conversion",
+  "tooltip_visual": "Visual programming",
+  "tooltip_textual": "Textual programming",
+  "tooltip_upload": "Upload code file",
+  "tooltip_download": "Download code file",
+  "tooltip_undo": "Undo",
+  "tooltip_redo": "Redo",
+  "tooltip_run": "Run program",
+  "tooltip_evaluate": "Evaluate program",
+  "tooltip_help": "Help",
+  "tooltip_add_global": "Add global variable",
+  "tooltip_minimize": "Hidde function elements",
+  "tooltip_console": "Open/Close console",
+  "var_menu_select_var": "Select a var",
+  "var_menu_select_all": "Select",
+  "var_menu_select_function": "Select a function",
+  "expression_menu_select": "Select an expression",
+  "math": "Mathematic",
+  "text_t": "Text",
+  "arrangement": "Arrangement",
+  "conversion": "Conversion",
+  "$sin": "sin",
+  "$cos": "cos",
+  "$tan": "tan",
+  "$sqrt": "sqrt",
+  "$pow": "pow",
+  "$log": "log",
+  "$abs": "abs",
+  "$negate": "negate",
+  "$invert": "invert",
+  "$max": "maximum",
+  "$min": "minimum",
+  "$substring": "substring",
+  "$length": "length",
+  "$uppercase": "uppercase",
+  "$lowercase": "lowercase",
+  "$charAt": "char_at",
+  "$numElements": "total_of_elements",
+  "$matrixLines": "total_of_lines",
+  "$matrixColumns": "total_of_columns",
+  "$isReal": "is_real",
+  "$isInt": "is_integer",
+  "$isBool": "is_logic",
+  "$castReal": "to_real",
+  "$castInt": "to_integer",
+  "$castBool": "to_logic",
+  "$castString": "to_string"
+}

+ 3 - 0
ivprogh/i18n/es/error.json

@@ -0,0 +1,3 @@
+{
+  
+}

+ 9 - 0
ivprogh/i18n/es/index.js

@@ -0,0 +1,9 @@
+import errors from './error.json';
+import messages from './message.json'
+import ui from './ui.json';
+
+export default {
+ 'message' : messages,
+ 'error': errors,
+ 'ui': ui
+}

+ 3 - 0
ivprogh/i18n/es/message.json

@@ -0,0 +1,3 @@
+{
+  
+}

+ 130 - 0
ivprogh/i18n/es/ui.json

@@ -0,0 +1,130 @@
+{
+  "function": "function",
+  "btn_clear": "Clear",
+  "btn_function": "Function",
+  "btn_arithmetic_plus": "Sum",
+  "btn_arithmetic_minus": "Minus",
+  "btn_arithmetic_multiplication": "Multiplication",
+  "btn_arithmetic_division": "Division",
+  "btn_arithmetic_module": "Module",
+  "btn_break":"Break",
+  "btn_case":"Case",
+  "start": "start",
+  "void": "void",
+  "integer": "integer",
+  "real": "real",
+  "program": "program",
+  "text": "string",
+  "text_start": "text",
+  "boolean": "boolean",
+  "true": "true",
+  "false": "false",
+  "variable": "Variable",
+  "command": "Command",
+  "new_parameter": "new_parameter",
+  "new_variable": "new_variable",
+  "new_global": "new_global",
+  "new_function": "new_function",
+  "vector": "vector",
+  "text_comment_start": "Initial comment of function...",
+  "text_comment_main": "This is the main function...",
+  "text_read_var": "Reading data",
+  "text_write_var": "Writing data",
+  "text_command_read":"read",
+  "text_command_write":"write",
+  "text_comment": "Comment",
+  "text_attribution": "Attribution",
+  "text_if":"if",
+  "text_break":"break",
+  "text_else":"else",
+  "text_return":"return",
+  "text_btn_return":"Return",
+  "text_for":"for",
+  "text_code_while":"while",
+  "text_code_do":"do",
+  "text_command_do":"do",
+  "text_code_switch": "switch",
+  "text_code_case": "case",
+  "text_logic_expression": "Logic Expression",
+  "text_arithmetic_expression": "Arithmetic Expression",
+  "text_iftrue": "If true then",
+  "text_repeatNtimes": "Repeat N times",
+  "text_receives": "receives",
+  "text_whiletrue": "While true",
+  "text_dowhiletrue": "Do while true",
+  "text_switch": "Switch",
+  "text_functioncall": "Function call",
+  "text_value": "Value",
+  "text_operator": "Operator",
+  "text_parentheses": "Parentheses",
+  "text_change": "Change",
+  "text_teacher_algorithm": "Algorithm",
+  "text_teacher_algorithm_include": "Include the following algorithm in exercise",
+  "text_teacher_test_case": "Test cases",
+  "text_teacher_config": "Settings",
+  "text_teacher_data_types": "Data types",
+  "text_teacher_commands": "Commands",
+  "text_teacher_functions": "Functions",
+  "text_teacher_create_functions": "Create new functions",
+  "text_teacher_create_movement_functions": "Move functions",
+  "text_teacher_test_case_input": "Input",
+  "text_teacher_test_case_output": "Output",
+  "text_teacher_test_case_actions": "Actions",
+  "text_teacher_test_case_add": "Add test cases",
+  "text_header_ivprog_functions": "iVProg Functions",
+  "text_menu_functions_math":"Mathematics",
+  "text_menu_functions_text":"Text",
+  "text_menu_functions_arrangement":"Arrangement",
+  "text_menu_functions_conversion":"Conversion",
+  "tooltip_visual": "Visual programming",
+  "tooltip_textual": "Textual programming",
+  "tooltip_upload": "Upload code file",
+  "tooltip_download": "Download code file",
+  "tooltip_undo": "Undo",
+  "tooltip_redo": "Redo",
+  "tooltip_run": "Run program",
+  "tooltip_evaluate": "Evaluate program",
+  "tooltip_help": "Help",
+  "tooltip_add_global": "Add global variable",
+  "tooltip_minimize": "Hidde function elements",
+  "tooltip_console": "Open/Close console",
+  "var_menu_select_var": "Select a var",
+  "var_menu_select_all": "Select",
+  "var_menu_select_function": "Select a function",
+  "expression_menu_select": "Select an expression",
+  "$sin": "sen",
+  "math": "Mathematic",
+  "text": "Text",
+  "arrangement": "Arrangement",
+  "conversion": "Conversion",
+  "math": "Mathematic",
+  "text_t": "Text",
+  "arrangement": "Arrangement",
+  "conversion": "Conversion",
+  "$sin": "sin",
+  "$cos": "cos",
+  "$tan": "tan",
+  "$sqrt": "sqrt",
+  "$pow": "pow",
+  "$log": "log",
+  "$abs": "abs",
+  "$negate": "negate",
+  "$invert": "invert",
+  "$max": "maximum",
+  "$min": "minimum",
+  "$substring": "substring",
+  "$length": "length",
+  "$uppercase": "uppercase",
+  "$lowercase": "lowercase",
+  "$charAt": "char_at",
+  "$numElements": "total_of_elements",
+  "$matrixLines": "total_of_lines",
+  "$matrixColumns": "total_of_columns",
+  "$isReal": "is_real",
+  "$isInt": "is_integer",
+  "$isBool": "is_logic",
+  "$castReal": "to_real",
+  "$castInt": "to_integer",
+  "$castBool": "to_logic",
+  "$castString": "to_string"
+}

+ 117 - 0
ivprogh/i18n/i18n-database.json

@@ -0,0 +1,117 @@
+{
+	"function": {
+		"en": "function",
+		"es": "función",
+		"pt": "função"
+	},
+	"Function": {
+		"en": "Function",
+		"es": "Función",
+		"pt": "Função"
+	},
+	"start": {
+		"en": "start",
+		"es": "comienzo",
+		"pt": "inicio"
+	},
+	"void": {
+		"en": "void",
+		"es": "vacío",
+		"pt": "vazio"
+	},
+	"integer": {
+		"en": "integer",
+		"es": "entero",
+		"pt": "inteiro"
+	},
+	"real": {
+		"en": "real",
+		"es": "real",
+		"pt": "real"
+	},
+	"program": {
+		"en": "program",
+		"es": "programa",
+		"pt": "programa"
+	},
+	"text": {
+		"en": "text",
+		"es": "texto",
+		"pt": "texto"
+	},
+	"boolean": {
+		"en": "boolean",
+		"es": "booleano",
+		"pt": "booleano"
+	},
+	"true": {
+		"en": "true",
+		"es": "verdadero",
+		"pt": "verdadeiro"
+	},
+	"false": {
+		"en": "false",
+		"es": "falso",
+		"pt": "falso"
+	},
+	"Variable": {
+		"en": "Variable",
+		"es": "Variable",
+		"pt": "Variável"
+	},
+	"Command": {
+		"en": "Command",
+		"es": "Mando",
+		"pt": "Comando"
+	},
+	"new_parameter": {
+		"en": "new_parameter",
+		"es": "nuevo_parámetro",
+		"pt": "novo_parâmetro"
+	},
+	"new_variable": {
+		"en": "new_variable",
+		"es": "nuevo_variable",
+		"pt": "nova_variável"
+	},
+	"new_global": {
+		"en": "new_global",
+		"es": "nuevo_global",
+		"pt": "nova_global"
+	},
+	"new_function": {
+		"en": "new_function",
+		"es": "nueva_función",
+		"pt": "nova_função"
+	},
+	"vector": {
+		"en": "vector",
+		"es": "vector",
+		"pt": "vetor"
+	},
+	"text_comment_start": {
+		"en": "Initial comment of function...",
+		"es": "Comentario inicial de la función...",
+		"pt": "Comentário inicial da função..."
+	},
+	"text_comment_main": {
+		"en": "This is the main function...",
+		"es": "Esta es la función principal...",
+		"pt": "Esta é a função principal..."
+	},
+	"text_read_var": {
+		"en": "Reading data",
+		"es": "Leyendo datos",
+		"pt": "Leitura de dados"
+	},
+	"text_write_var": {
+		"en": "Writing data",
+		"es": "Escribir datos",
+		"pt": "Escrita de dados"
+	},
+	"text_comment": {
+		"en": "Comment",
+		"es": "Comentario",
+		"pt": "Comentário"
+	}
+}

+ 9 - 0
ivprogh/i18n/index.js

@@ -0,0 +1,9 @@
+import EN from './en';
+import PT from './pt';
+import ES from './es';
+
+export default {
+  'en': EN,
+  'pt': PT,
+  'es': ES
+}

+ 85 - 0
ivprogh/i18n/pt/error.json

@@ -0,0 +1,85 @@
+{
+  "token_missing_one": "Erro de sintaxe: Espera-se $0, mas encontrou-se $1 na linha:$2, coluna:$3",
+  "token_missing_two": "Erro de sintaxe: Esperava-se $0 ou $1 mas encontrou-se $2 na liha:$3, coluna: $4",
+  "eos_missing": "Falta uma nova linha ou ; na linha: $0, coluna: $1",
+  "invalid_type": "$0 na linha: $1, coluna: $2 é um tipo inválido. Os tipos válidos são: $3",
+  "invalid_array_dimension": "A dimensão inválida na linha: $0, coluna: $1. Insira um $2 ou identificador válido do mesmo tipo.",
+  "invalid_array_size": "O tamnho do vetor/matriz excede o máximo de 2 na linha $0",
+  "extra_lines": "Nenhum texto é permitido após '}' em 'programa {...}'",
+  "invalid_main_return": "A função $0 deve retornar $1 na linha $2",
+  "invalid_var_declaration": "Erro na linha $0. Variáveis só podem ser declarados no corpo principal da função e de preferência nas primeiras linhas.",
+  "invalid_break_command": "Erro na linha $0. O comando $1 não pode ser usado fora de uma estrutura de repetição ou 'escolha...caso'",
+  "invalid_terminal": "Não é possível utilizar $0 na expressão da linha: $1, coluna: $2. Tente um valor númerico, variável ou chamada de função.",
+  "const_not_init": "Erro na linha: $0, coluna: $1. Uma variável declarada como const deve ser inicializada",
+  "id_missing": "Esperava-se um identificador, mas encontrou-se $0 na linha: $1, coluna: $2",
+  "invalid_id_format": "$0 na linha: $1, coluna: $2 não é um identificador válido. O símbolo '.' não é permitido neste contexto.",
+  "main_missing": "A função principal não foi encontrada",
+  "invalid_global_var": "Erro crítico: Chamada inválida da função initGlobal fora do contexto BASE",
+  "not_implemented": "Erro interno crítico: A função definida pelo sistema $0 não foi implementada.",
+  "function_missing": "A função $0 não foi encontrada",
+  "function_missing_full": "A função $0 na linha: $1, coluna: $2 não foi encontrada",
+  "invalid_parameters_size_full": "Erro na linha $0: a quantidade de parâmetros fornecidos à função $1 está incorreta. Esperava-se $2, encontrou-se $3.",
+  "invalid_parameters_size": "A quantidade de parâmetros fornecidos à função $0 está incorreta. Esperava-se $1, encontrou-se $2",
+  "invalid_ref_full": "A expressão $0 fornecida como parâmetro para a função $1 na linha $2 não é válida para esta função. Use uma variável ou posição de vetor.",
+  "invalid_ref": "A expressão $0 fornecida como parâmetro para a função $1 não é válida para esta função. Use uma variável ou posição de vetor.",
+  "invalid_parameter_type_full": "A expressão $0 fornecida como parâmetro para a função $1 na linha $2 não é compatível com o tipo esperado.",
+  "invalid_parameter_type": "A expressão $0 fornecida como parâmetro para a função $1 não é compatível com o tipo esperado.",
+  "unknown_command_full": "Erro interno crítico: comando desconhecido encontrado na linha $0",
+  "unknown_command": "Erro interno crítico: comando desconhecido encontrado!",
+  "loop_condition_type_full": "Erro na linha: $0, coluna $1: a condição dos laços de repetição deve ser do tipo lógico",
+  "loop_condition_type": "A condição dos laços de repetição deve ser do tipo lógico",
+  "endless_loop_full": "Possível laço infinito detectado no seu código. Verifique a linha $0",
+  "endless_loop": "Possível laço infinito detectado no seu código.",
+  "for_condition_type_full": "Erro na linha: $0, coluna $1: a condição de parada do comando para(...) deve ser do tipo lógico",
+  "for_condition_type": "A condição de parada do comando para(...) deve ser do tipo lógico",
+  "if_condition_type_full": "Erro na linha: $0, coluna $1: a condição de um comando se...senao deve ser do tipo lógico",
+  "if_condition_type": "A condição de um comando se...senao deve ser do tipo lógico",
+  "invalid_return_type_full": "Erro na linha $0: a expressão não produz um tipo compatível com a função $1. Tipo esperado: $2.",
+  "invalid_return_type": "A expressão não produz um tipo compatível com a função $0. Tipo esperado: $1.",
+  "invalid_void_return_full": "Erro na linha $0: a função $1 não pode retornar uma expressão vazia, use uma espressão do tipo $2",
+  "invalid_void_return": "A função $0 não pode retornar uma expressão vazia, use uma espressão do tipo $1",
+  "unexpected_break_command_full": "Erro interno crítico: comando pare encontrado fora do contexto de um laço/escolha..caso na linha $0",
+  "unexpected_break_command": "Erro interno crítico: comando pare encontrado fora do contexto de um laço/escolha..caso",
+  "invalid_dimension": "As dimensões de um vetor/matriz devem ser do tipo inteiro",
+  "void_in_expression_full": "Erro na linha: $0, coluna: $1: a função $2 não pode ser utilizada em uma expressão pois seu tipo de retorno é vazio",
+  "void_in_expression": "A função $0 não pode ser utilizada em uma expressão pois seu tipo de retorno é vazio",
+  "invalid_array_access_full": "Identificador $0 na linha: $1, coluna: $2 não se refere a um vetor/matriz válido",
+  "invalid_array_access": "Identificador $0 não se refere a um vetor/matriz válido",
+  "invalid_matrix_access_full": "Identificador $0 na linha: $1, coluna: $2 não se refere a uma matriz válida",
+  "invalid_matrix_access": "Identificador $0 não se refere a uma matriz válida",
+  "matrix_column_outbounds_full": "Erro na linha $0: número de colunas $1 é inválido para a matriz $2 que possui $3 colunas",
+  "matrix_column_outbounds": "Número de colunas $0 é inválido para a matriz $1 que possui $2 colunas",
+  "matrix_line_outbounds_full": "Erro na linha $0: número de linhas $1 é inválido para a matriz $2 que possui $3 linhas",
+  "matrix_line_outbounds": "Número de linhas $0 é inválido para a matriz $1 que possui $2 linhas",
+  "vector_line_outbounds_full": "Erro na linha $0: número de linhas $1 é inválido para a matriz $2 que possui $3 linhas",
+  "vector_line_outbounds": "Número de linhas $0 é inválido para a matriz $1 que possui $2 linhas",
+  "vector_not_matrix_full": "Erro na linha $0: $1 não é uma matriz",
+  "vector_not_matrix": "$1 não é uma matriz",
+  "invalid_infix_op_full": "Erro na linha $0: não é possível aplicar a operação $1 entre os tipos $2 e $3",
+  "invalid_infix_op": "Não é possível aplicar a operação $0 entre os tipos $1 e $2",
+  "invalid_unary_op_full": "Erro na linha $0: não é possível aplicar a operação $1 ao tipo $2",
+  "invalid_unary_op": "Não é possível aplicar a operação $0 ao tipo $1",
+  "unknown_op": "Erro interno crítico: Operação $0 desconhecida",
+  "duplicate_function": "A função $0 na linha: $1, coluna: $2 já foi definida anteriormente.",
+  "duplicate_variable": "A variável $0 na linha: $1, coluna: $2 já foi declarada anteriormente.",
+  "main_parameters": "A função inicio não pode ter parâmetros.",
+  "symbol_not_found_full": "A variável $0 na linha: $1, coluna: $2 não foi declarada",
+  "symbol_not_found": "A variável $0 não foi declarada",
+  "array_dimension_not_int_full": "As dimensões de um vetor/matriz na linha: $0 devem ser do tipo inteiro.",
+  "array_dimension_not_int": "As dimensões de um vetor/matriz devem ser do tipo inteiro.",
+  "array_dimension_not_positive_full": "As dimensões de um vetor/matriz na linha: $0 devem ser valores positivos.",
+  "array_dimension_not_positive": "As dimensões de um vetor/matriz devem ser valores positivos.",
+  "incompatible_types_full": "O tipo $0 não é compatível com o tipo resultante da expressão na linha $1",
+  "incompatible_types": "O tipo $0 não é compatível com o tipo resultante da expressão fornecida.",
+  "incompatible_types_array_full": "A expressão $0 é incompatível com o tipo $1 na linha: $2, coluna: $3.",
+  "incompatible_types_array": "A expressão $0 é incompatível com o tipo $1.",
+  "invalid_case_type_full": "O caso $0 na linha $1 é incompatível com o tipo $2.",
+  "invalid_case_type": "O caso $0 é incompatível com o tipo $1.",
+  "function_no_return": "A função $0 não possui um retorno acessível. Toda função deve ter ao menos um retorno no seu corpo principal.",
+  "invalid_array_literal_type_full": "Erro na linha $0: a expressão $1 não resulta em um tipo compatível.",
+  "invalid_array_literal_type": "A expressão $0 não resulta em um tipo compatível.",
+  "invalid_array_literal_line_full": "Erro na linha $0: esperava-se $1 linhas mas encontrou $2.",
+  "invalid_array_literal_line": "Esperava-se $0 linhas mas encontrou $1.",
+  "invalid_array_literal_column_full": "Erro na linha $0: esperava-se $1 colunas mas encontrou $2.",
+  "invalid_array_literal_column": "Esperava-se $0 colunas mas encontrou $1."
+}

+ 9 - 0
ivprogh/i18n/pt/index.js

@@ -0,0 +1,9 @@
+import errors from './error.json';
+import messages from './message.json'
+import ui from './ui.json';
+
+export default {
+ 'message' : messages,
+ 'error': errors,
+ 'ui': ui
+}

+ 3 - 0
ivprogh/i18n/pt/message.json

@@ -0,0 +1,3 @@
+{
+  
+}

+ 132 - 0
ivprogh/i18n/pt/ui.json

@@ -0,0 +1,132 @@
+{
+  "function": "funcao",
+  "btn_clear": "Limpar",
+  "btn_function": "Função",
+  "btn_arithmetic_plus": "Adição",
+  "btn_arithmetic_minus": "Subtração",
+  "btn_arithmetic_multiplication": "Multiplicação",
+  "btn_arithmetic_division": "Divisão",
+  "btn_arithmetic_module": "Módulo",
+  "btn_break":"Pare",
+  "btn_case":"Caso",
+  "start": "inicio",
+  "void": "vazio",
+  "integer": "inteiro",
+  "and": "E",
+  "or": "OU",
+  "not": "nao",
+  "real": "real",
+  "program": "programa",
+  "text": "cadeia",
+  "text_start": "texto",
+  "boolean": "logico",
+  "true": "verdadeiro",
+  "false": "falso",
+  "variable": "Variável",
+  "command": "Comando",
+  "new_parameter": "novo_parametro",
+  "new_variable": "nova_variavel",
+  "new_global": "nova_global",
+  "new_function": "nova_funcao",
+  "vector": "vetor",
+  "text_comment_start": "Comentário inicial da função...",
+  "text_comment_main": "Esta é a função principal...",
+  "text_read_var": "Leitura de dados",
+  "text_write_var": "Escrita de dados",
+  "text_command_read":"leia",
+  "text_command_write":"escreva",
+  "text_return":"retorne",
+  "text_btn_return":"Retorno",
+  "text_comment": "Comentário",
+  "join_or": "ou",
+  "matrix_string": "matriz de $0",
+  "vector_string": "vetor de $0",
+  "text_attribution": "Atribuição",
+  "text_if":"se",
+  "text_break":"pare",
+  "text_else":"senao",
+  "text_for":"para",
+  "text_code_while":"enquanto",
+  "text_code_do":"faca",
+  "text_command_do":"faça",
+  "text_code_switch": "escolha",
+  "text_code_case": "caso",
+  "text_logic_expression": "Expressão Lógica",
+  "text_arithmetic_expression": "Expressão Aritmética",
+  "text_iftrue": "Se verdadeiro então",
+  "text_repeatNtimes": "Repita N vezes",
+  "text_receives": "recebe",
+  "text_whiletrue": "Enquanto verdadeiro",
+  "text_dowhiletrue": "Faça enquanto verdadeiro",
+  "text_switch": "Escolha",
+  "text_functioncall": "Chamada de função",
+  "text_value": "Valor",
+  "text_operator": "Operador",
+  "text_parentheses": "Parênteses",
+  "text_change": "Alterar",
+  "text_teacher_algorithm": "Algoritmo",
+  "text_teacher_algorithm_include": "Incluir o algoritmo abaixo no exercício",
+  "text_teacher_test_case": "Casos de teste",
+  "text_teacher_config": "Configurações",
+  "text_teacher_data_types": "Tipos de dados",
+  "text_teacher_commands": "Comandos",
+  "text_teacher_functions": "Funções",
+  "text_teacher_create_functions": "Criar novas funções",
+  "text_teacher_create_movement_functions": "Movimentar funções",
+  "text_teacher_test_case_input": "Entrada",
+  "text_teacher_test_case_output": "Saída",
+  "text_teacher_test_case_actions": "Ações",
+  "text_teacher_test_case_add": "Adicionar caso de teste",
+  "text_header_ivprog_functions": "Funções do iVProg",
+  "text_menu_functions_math":"Matemática",
+  "text_menu_functions_text":"Texto",
+  "text_menu_functions_arrangement":"Arranjo",
+  "text_menu_functions_conversion":"Conversão",
+  "tooltip_visual": "Programação visual",
+  "tooltip_textual": "Programação textual",
+  "tooltip_upload": "Upload de código fonte",
+  "tooltip_download": "Download do código fonte",
+  "tooltip_undo": "Desfazer",
+  "tooltip_redo": "Refazer",
+  "tooltip_run": "Executar o programa",
+  "tooltip_evaluate": "Avaliar o programa",
+  "tooltip_help": "Ajuda",
+  "tooltip_add_global": "Adicionar variável global",
+  "tooltip_minimize": "Ocultar os elementos da função",
+  "tooltip_console": "Abrir/fechar o terminal",
+  "var_menu_select_var": "Selecione uma variável",
+  "var_menu_select_all": "Selecione",
+  "var_menu_select_function": "Selecione uma função",
+  "expression_menu_select": "Selecione uma expressão",
+  "$sin": "sen",
+  "math": "Matematica",
+  "text_t": "Texto",
+  "arrangement": "Arranjo",
+  "conversion": "Conversao",
+  "$sin": "seno",
+  "$cos": "cosseno",
+  "$tan": "tangente",
+  "$sqrt": "raiz_quadrada",
+  "$pow": "potencia",
+  "$log": "logaritmo",
+  "$abs": "modulo",
+  "$negate": "trocar_sinal",
+  "$invert": "inverter_valor",
+  "$max": "maximo",
+  "$min": "minimo",
+  "$substring": "subcadeia",
+  "$length": "comprimento",
+  "$uppercase": "caixa_alta",
+  "$lowercase": "caixa_baixa",
+  "$charAt": "texto_na_posicao",
+  "$numElements": "total_de_elementos",
+  "$matrixLines": "total_de_linhas",
+  "$matrixColumns": "total_de_colunas",
+  "$isReal": "e_real",
+  "$isInt": "e_inteiro",
+  "$isBool": "e_logico",
+  "$castReal": "como_real",
+  "$castInt": "como_inteiro",
+  "$castBool": "como_logico",
+  "$castString": "como_cadeia"
+}

BIN
ivprogh/img/background-panel.png


+ 19 - 34
ivprogh/index.html

@@ -2,7 +2,13 @@
 <html>
   <head>
     <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+    <meta http-equiv="cache-control" content="no-cache">
+    <meta http-equiv="cache-control" content="no-store">
+    <meta http-equiv="cache-control" content="max-age=0">
+    <meta http-equiv="expires" content="-1">
+    <meta http-equiv="pragma" content="no-cache">
     <title></title>
+    <link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
     <link rel="stylesheet" type="text/css" href="js/semantic/semantic.min.css">
     <link rel="stylesheet" type="text/css" href="css/ivprog-visual-1.0.css">
     <link rel="stylesheet" type="text/css" href="css/ivprog-term.css">
@@ -27,49 +33,30 @@
 
     <div class="content height_100">
    
-    <div class="ui one column doubling stackable grid container">
-      <div class="column">
-        <div class="ui container main_title">
-          <h2>iVProg</h2>
-          <span>interactive coding</span>
-        </div>
-
-        <div class="ui container content_margin">
-          <div class="content_sub_margin">
-              <div class="blue ui ivprog_format buttons">
-                <button class="ui button active visual_coding_button">Visual</button>
-                <button class="ui button textual_coding_button">Textual</button>
-              </div>
-            </div>
-          </div>
-
-      </div>
-    </div>
-
-    <div class="ui container main_title only_in_frame" style="display: none;">
+    <div class="ui container main_title only_in_frame">
       <h2>iVProg</h2>
-      <span class="subtext">interactive coding</span>
+      <span class="subtext" style="display: inline;">interactive coding</span>
     </div>
 
     <div class="ui raised container segment div_to_body">
 
-      <div class="ui icon menu center aligned container" style="width: 438px; margin-top: -25px;">
-        <a class="item visual_coding_button">
+      <div class="ui icon menu center aligned container" style="width: 438px; margin-top: -20px;">
+        <a class="item active visual_coding_button">
           <i class="window maximize outline icon"></i>
         </a>
         <a class="item textual_coding_button">
           <i class="code icon"></i>
         </a>
-        <a class="item upload_file_button">
+        <a class="item upload_file_button disabled">
           <i class="upload icon"></i>
         </a>
-        <a class="item download_file_button">
+        <a class="item download_file_button disabled">
           <i class="download icon"></i>
         </a>
         <a class="item undo_button disabled">
           <i class="undo icon"></i>
         </a>
-        <a class="item redo_button">
+        <a class="item redo_button disabled">
           <i class="redo icon"></i>
         </a>
         <a class="item run_button">
@@ -86,10 +73,12 @@
       <div class="ui one column container segment ivprog_visual_panel loading">
 
         <div class="global_var">
-          
-          <div class="ui icon button add-globalVar-button add_global_button"><i class="icon superscript"></i></div>
+          <i class="icon plus circle purple add_global_button"></i>
+          <i class="icon circle white back"></i>
 
-          <div class="list_globals"></div>
+          <div class="ui icon button add-globalVar-button add_global_button purple"><i class="icon superscript"></i></div>
+
+          <div class="list_globals" id="listGlobalsHandle"></div>
 
         </div>
 
@@ -108,7 +97,7 @@
 
 
       <div class="ui one column container segment ivprog_textual_panel loading" style="display: none;">
-        <textarea class="ivprog_textual_code" disabled></textarea>
+        <textarea class="ivprog_textual_code" readonly></textarea>
       </div>
 
       <div id='ivprog-term' class="six column wide">
@@ -128,9 +117,5 @@
       });
     </script>
 
-
-    
-
-
   </body>
 </html>

+ 90 - 0
ivprogh/js/assessment/ivprogAssessment.js

@@ -0,0 +1,90 @@
+import { IVProgParser } from "./../ast/ivprogParser";
+import { SemanticAnalyser } from "./../processor/semantic/semanticAnalyser";
+import { IVProgProcessor } from "./../processor/ivprogProcessor";
+import { InputTest } from "./../util/inputTest";
+import { OutputTest } from "./../util/outputTest";
+
+export class IVProgAssessment {
+
+  constructor (textCode, testCases, domConsole) {
+    this.textCode = textCode;
+    this.testCases = testCases;
+    this.domConsole = domConsole;
+  }
+
+  runTest () {
+    try {
+      // try and show error messages through domconsole
+      const parser = IVProgParser.createParser(this.textCode);
+      const semantic = new SemanticAnalyser(parser.parseTree());
+      const validTree = semantic.analyseTree();
+      // loop test cases and show messages through domconsole
+      const partialTests = this.testCases.map( (t, name) => {
+        return this.partialEvaluateTestCase(new IVProgProcessor(validTree), t.input, t.output, name);
+      });
+      const testResult = partialTests.reduce((acc, curr) => acc.then( v => curr(v)), Promise.resolve(0));
+      return testResult.then(total => Promise.resolve(total / this.testCases.length))
+        .catch(err => {
+          this.domConsole.err("Erro durante a execução do programa");// try and show error messages through domconsole
+          this.domConsole.err(err.message);
+          return Promise.resolve(0);
+      });
+    } catch (error) {
+      this.domConsole.err("Erro durante a execução do programa");// try and show error messages through domconsole
+      this.domConsole.err(error.message);
+      return Promise.resolve(0);
+    }
+  }
+
+  evaluateTestCase (prog, inputList, outputList, name, accumulator) {
+    const outerThis = this;
+    const input = new InputTest(inputList);
+    const output = new OutputTest();
+    prog.registerInput(input);
+    prog.registerOutput(output);
+    const startTime = Date.now()
+    return prog.interpretAST().then( _ => {
+      const millis = Date.now() - startTime;
+      if (input.inputList.length !== input.index) {
+        outerThis.domConsole.err(`Caso de teste ${name + 1}: Falhou, ainda restam entradas!`);
+        outerThis.domConsole.info(`Levou ${millis}ms`);
+        return Promise.resolve(accumulator + 1 * (input.index/inputList.length));
+      } else if (output.list.length < outputList.length) {
+        outerThis.domConsole.err(`Caso de teste ${name + 1}: Falhou <${inputList.join(", ")};${outputList.join(", ")};${output.list.join(", ")}>`);
+        outerThis.domConsole.info(`Levou ${millis}ms`);
+        return Promise.resolve(accumulator + 1 * (output.list.length/outputList.length));
+      } else if (output.list.length > outputList.length) {
+        outerThis.domConsole.err(`Caso de teste ${name + 1}: Falhou <${inputList.join(", ")};${outputList.join(", ")};${output.list.join(", ")}>`);
+        outerThis.domConsole.info(`Levou ${millis}ms`);
+        return Promise.resolve(accumulator + 1 * (outputList.length/output.list.length));
+      } else {
+        const isOk = outerThis.checkOutput(output.list, outputList);
+        if(!isOk) {
+          outerThis.domConsole.err(`Caso de teste ${name + 1}: Falhou <${inputList.join(", ")};${outputList.join(", ")};${output.list.join(", ")}>`);
+          outerThis.domConsole.info(`Levou ${millis}ms`);
+          return Promise.resolve(accumulator);
+        } else {
+          outerThis.domConsole.info(`Caso de teste ${name + 1}: OK!`);
+          outerThis.domConsole.info(`Levou ${millis}ms`);
+          return Promise.resolve(accumulator + 1);
+        }
+      }
+    }).catch( _ => Promise.resolve(accumulator));
+  }
+
+  partialEvaluateTestCase (prog, inputList, outputList, name) {
+    let partial = (accumulator) => this.evaluateTestCase(prog, inputList, outputList, name, accumulator)
+    partial = partial.bind(this);
+    return partial;
+  }
+
+  checkOutput (aList, bList) {
+    for (let i = 0; i < aList.length; i++) {
+      const outValue = aList[i];
+      if(outValue != bList[i]) {
+        return false;
+      }
+    }
+    return true;
+  }
+}

+ 47 - 0
ivprogh/js/ast/ASA.txt

@@ -0,0 +1,47 @@
+/*
+  Raiz(ASA)
+    |
+    |
+  DeclaraçõesGlobais + Funções
+
+  DeclaracaoGlobal
+    |
+    |
+  const? TIPO ID (= EAnd)?
+
+  Função
+    |
+    |
+  Declaracao => TIPO ID (= EAnd)?
+  Attribuição => ID = EAnd
+  IF, WHILE, SWITCH, FuncCall, RETURN
+
+  EAnd
+    |
+    |
+  EOR ( 'and' EAnd)?
+
+  EOR   => ENot ('or' EAnd)?
+
+  ENot  => 'not'? ER
+
+  ER    => E ((>=, <=, ==, >, <) E)?
+
+  E     => factor ((+, -) E)?
+
+  factor=> term ((*, /, %) factor)?
+
+  term  => literal || arrayAccess || FuncCall || ID || '('EAnd')'
+
+  arrayAccess
+    |
+    |
+  ID'['E']'('['E']')*
+
+  FuncCall
+    |
+    |
+  ID'('p.a')'
+
+  p.a => E (, p.a)?
+**/

+ 10 - 0
ivprogh/js/ast/commands/arrayAssign.js

@@ -0,0 +1,10 @@
+import { Assign } from './assign';
+
+export class ArrayIndexAssign extends Assign {
+
+  constructor (id, lineExpression, columnExpression, expression) {
+    super(id, expression);
+    this.line = lineExpression;
+    this.column = columnExpression;
+  }
+}

+ 10 - 0
ivprogh/js/ast/commands/arrayDeclaration.js

@@ -0,0 +1,10 @@
+import { Declaration } from './declaration';
+
+export class ArrayDeclaration extends Declaration {
+
+  constructor (id, type, lines, columns, initial, isConst)   {
+    super(id, type, initial, isConst);
+    this.lines = lines;
+    this.columns = columns;
+  }
+}

+ 10 - 0
ivprogh/js/ast/commands/assign.js

@@ -0,0 +1,10 @@
+import { Command } from './command';
+
+export class Assign extends Command {
+  
+  constructor (id, expression) {
+    super();
+    this.id = id;
+    this.expression = expression;
+  }
+}

+ 8 - 0
ivprogh/js/ast/commands/break.js

@@ -0,0 +1,8 @@
+import { Command } from './command';
+
+export class Break extends Command {
+
+  constructor () {
+    super();
+  }
+}

+ 18 - 0
ivprogh/js/ast/commands/case.js

@@ -0,0 +1,18 @@
+import { Command } from './command';
+
+export class Case extends Command {
+
+  constructor (expression) {
+    super();
+    this.expression = expression;
+    this.commands = [];
+  }
+
+  setCommands (commands) {
+    this.commands = commands;
+  }
+
+  get isDefault () {
+    return this.expression === null;
+  }
+}

+ 14 - 0
ivprogh/js/ast/commands/command.js

@@ -0,0 +1,14 @@
+export class Command {
+
+  constructor () {
+    this._sourceInfo = null;
+  }
+
+  set sourceInfo (sourceInfo) {
+    this._sourceInfo = sourceInfo;
+  }
+
+  get sourceInfo () {
+    return this._sourceInfo;
+  }
+}

+ 16 - 0
ivprogh/js/ast/commands/commandBlock.js

@@ -0,0 +1,16 @@
+export class CommandBlock {
+	
+	constructor(variables, commands) {
+		this.variables = variables;
+		this.commands = commands;
+		this._sourceInfo = null;
+	}
+
+	set sourceInfo (sourceInfo) {
+		this._sourceInfo = sourceInfo;
+	}
+
+	get sourceInfo () {
+		return this._sourceInfo;
+	}
+}

+ 12 - 0
ivprogh/js/ast/commands/declaration.js

@@ -0,0 +1,12 @@
+import { Command } from './command';
+
+export class Declaration extends Command {
+  
+  constructor (id, type, initial, isConst) {
+    super();
+    this.id = id;
+    this.type = type;
+    this.initial = initial;
+    this.isConst = isConst;
+  }
+}

+ 13 - 0
ivprogh/js/ast/commands/doWhile.js

@@ -0,0 +1,13 @@
+import { While } from './while';
+
+export class DoWhile extends While {
+
+  constructor(condition, commandBlock) {
+    super(condition, commandBlock);
+  }
+
+  get testFirst () {
+    return false;
+  }
+  
+}

+ 16 - 0
ivprogh/js/ast/commands/for.js

@@ -0,0 +1,16 @@
+import { Command } from './command';
+
+export class For extends Command {
+
+  constructor (assignment, condition, increment, commandBlock) {
+    super();
+    this.assignment = assignment;
+    this.condition = condition;
+    this.increment = increment;
+    this.commandBlock = commandBlock;
+  }
+
+  get commands () {
+    return this.commandBlock.commands;
+  }
+}

+ 17 - 0
ivprogh/js/ast/commands/formalParameter.js

@@ -0,0 +1,17 @@
+export class FormalParameter {
+
+  constructor (type, id, byRef = false) {
+    this.type = type;
+    this.id = id;
+    this.byRef = byRef;
+    this._sourceInfo = null;
+  }
+
+  set sourceInfo (sourceInfo) {
+		this._sourceInfo = sourceInfo;
+	}
+
+	get sourceInfo () {
+		return this._sourceInfo;
+	}
+}

+ 32 - 0
ivprogh/js/ast/commands/function.js

@@ -0,0 +1,32 @@
+import { Types } from './../../typeSystem/types';
+
+export class Function {
+
+  constructor(name, returnType, formalParameters, commandBlock) {
+    this.name = name;
+    this.returnType = returnType;
+    this.formalParameters = formalParameters;
+    this.commandBlock = commandBlock;
+    this._sourceInfo = null;
+  }
+
+  get isMain () {
+    return this.name === null && this.returnType.isCompatible(Types.VOID);
+  }
+
+  get commands () {
+    return this.commandBlock.commands;
+  }
+
+  get variablesDeclarations () {
+    return this.commandBlock.variables;
+  }
+
+  set sourceInfo (sourceInfo) {
+		this._sourceInfo = sourceInfo;
+	}
+
+	get sourceInfo () {
+		return this._sourceInfo;
+	}
+}

+ 11 - 0
ivprogh/js/ast/commands/ifThenElse.js

@@ -0,0 +1,11 @@
+import { Command } from './command';
+
+export class IfThenElse extends Command {
+
+  constructor (condition, ifTrue, ifFalse) {
+    super();
+    this.condition = condition;
+    this.ifTrue = ifTrue;
+    this.ifFalse = ifFalse;
+  }
+}

+ 37 - 0
ivprogh/js/ast/commands/index.js

@@ -0,0 +1,37 @@
+import { Break } from './break';
+import { Return } from './return';
+import { Assign } from './assign';
+import { ArrayIndexAssign } from './arrayAssign';
+import { Declaration } from './declaration';
+import { ArrayDeclaration } from './arrayDeclaration';
+import { While } from './while';
+import { For } from './for';
+import { Function } from './function';
+import { IfThenElse } from './ifThenElse';
+import { CommandBlock } from './commandBlock';
+import { DoWhile } from './doWhile';
+import { Switch } from './switch';
+import { Case } from './case';
+import { SysCall } from './sysCall';
+import { FormalParameter } from './formalParameter';
+import { FunctionCall } from './../expressions/functionCall'; //Proxy to expression since they do exatcly the same thing
+
+export {
+  Break,
+  Return,
+  Assign,
+  ArrayIndexAssign,
+  Declaration,
+  ArrayDeclaration,
+  While,
+  For,
+  Function,
+  IfThenElse,
+  CommandBlock,
+  DoWhile,
+  Switch,
+  Case,
+  SysCall,
+  FormalParameter,
+  FunctionCall
+};

+ 10 - 0
ivprogh/js/ast/commands/return.js

@@ -0,0 +1,10 @@
+import { Command } from './command';
+
+export class Return extends Command {
+
+  constructor(expression) {
+    super();
+    this.expression = expression;
+  }
+  
+}

+ 10 - 0
ivprogh/js/ast/commands/switch.js

@@ -0,0 +1,10 @@
+import { Command } from './command';
+
+export class Switch extends Command {
+  
+  constructor (expression, cases) {
+    super();
+    this.expression = expression;
+    this.cases = cases;
+  }
+}

+ 12 - 0
ivprogh/js/ast/commands/sysCall.js

@@ -0,0 +1,12 @@
+/**
+ * This class represents all the language defined functions.
+ * The language processor uses the id provided here to properly execute the desired function.
+ * The function is actually implemented inside the language processor.
+ * All the functions can be found at: js/processor/definedFunctions.js
+ */
+export class SysCall {
+
+  constructor (langFunc) {
+    this.langFunc = langFunc;
+  }
+}

+ 18 - 0
ivprogh/js/ast/commands/while.js

@@ -0,0 +1,18 @@
+import { Command } from './command';
+
+export class While extends Command {
+
+  constructor (expression, commandBlock) {
+    super();
+    this.expression = expression;
+    this.commandBlock = commandBlock;
+  }
+
+  get commands () {
+    return this.commandBlock.commands;
+  }
+
+  get testFirst () {
+  	return true;
+  }
+}

+ 8 - 0
ivprogh/js/ast/error/syntaxError.js

@@ -0,0 +1,8 @@
+export class SyntaxError extends Error {
+
+  constructor (...msg) {
+    super(...msg);
+    if(Error.captureStackTrace)
+      Error.captureStackTrace(this, SyntaxError);
+  }
+}

+ 70 - 0
ivprogh/js/ast/error/syntaxErrorFactory.js

@@ -0,0 +1,70 @@
+import { LocalizedStrings } from './../../services/localizedStringsService';
+import { SyntaxError } from './syntaxError';
+
+export const SyntaxErrorFactory = Object.freeze({
+  extra_lines: () => new SyntaxError(LocalizedStrings.getError("extra_lines")),
+  token_missing_one: (expected, token) => {
+    const context = [expected, token.text, token.line, token.column];
+    return new SyntaxError(LocalizedStrings.getError("token_missing_one", context));
+  },
+  token_missing_list: (expectedList, token) => {
+    const line = expectedList.join(LocalizedStrings.getOR());
+    return SyntaxErrorFactory.token_missing_one(line, token);
+  },
+  id_missing: (token) => {
+    const context = [token.text, token.line, token.column];
+    return new SyntaxError(LocalizedStrings.getError("id_missing", context));
+  },
+  eos_missing: (token) => {
+    const context = [token.line, token.column];
+    return new SyntaxError(LocalizedStrings.getError("eos_missing", context));
+  },
+  invalid_array_dimension: (typeName, token) => {
+    const context = [token.line, token.column, typeName];
+    return new SyntaxError(LocalizedStrings.getError("invalid_array_dimension", context));
+  },
+  invalid_array_size: (token) => {
+    const context = [token.line];
+    return new SyntaxError(LocalizedStrings.getError("invalid_array_size", context));
+  },
+  invalid_main_return: (name, typeName, token) => {
+    const context = [name, typeName, token.line];
+    return new SyntaxError(LocalizedStrings.getError("invalid_main_return", context));
+  },
+  invalid_var_declaration: (token) => {
+    const context = [token.line];
+    return new SyntaxError(LocalizedStrings.getError("invalid_var_declaration", context));
+  },
+  invalid_break_command: (cmdName, token) => {
+    const context = [token.line, cmdName];
+    return new SyntaxError(LocalizedStrings.getError("invalid_break_command", context));
+  },
+  invalid_terminal: (token) => {
+    const context = [token.text, token.line, token.column];
+    return new SyntaxError(LocalizedStrings.getError('invalid_terminal', context));
+  },
+  invalid_type: (list, token) => {
+    const line = list.join(LocalizedStrings.getOR());
+    const context = [token.text, token.line, token.column, line]
+    return new SyntaxError(LocalizedStrings.getError("invalid_type", context));
+  },
+  const_not_init: (token) => {
+    const context = [token.line, token.column];
+    return new SyntaxError(LocalizedStrings.getError("const_not_init", context));
+  },
+  invalid_id_format: (token) => {
+    const context = [token.text, token.line, token.column];
+    return new SyntaxError(LocalizedStrings.getError("invalid_id_format", context));
+  },
+  duplicate_function: (token) => {
+    const context = [token.text, token.line, token.column];
+    return new SyntaxError(LocalizedStrings.getError("duplicate_function", context));
+  },
+  main_parameters: () => {
+    return new SyntaxError(LocalizedStrings.getError("main_parameters"));
+  },
+  duplicate_variable: (token) => {
+    const context = [token.text, token.line, token.column];
+    return new SyntaxError(LocalizedStrings.getError("duplicate_variable", context));
+  }
+});

+ 24 - 0
ivprogh/js/ast/expressions/arrayAccess.js

@@ -0,0 +1,24 @@
+import { Expression } from './expression';
+
+export class ArrayAccess extends Expression {
+	
+	constructor (id, line, column) {
+		super();
+		this.id = id;
+		this.line = line;
+		this.column = column;
+	}
+
+	toString () {
+		const strLine = this.line.toString();
+		let strColumn = null;
+		if(this.column) {
+			strColumn = this.column.toString();
+		}
+		if(strColumn) {
+			return `${this.id}[${strLine}][${strColumn}]`;
+		} else {
+			return `${this.id}[${strLine}]`;
+		}
+	}
+}

+ 87 - 0
ivprogh/js/ast/expressions/arrayLiteral.js

@@ -0,0 +1,87 @@
+import { Literal } from './literal';
+
+export class ArrayLiteral extends Literal {
+  
+  constructor(type, value) {
+    super(type);
+    this.value = value;
+  }
+
+  get subtype () {
+    let element = this.value[0];
+    if (element instanceof ArrayLiteral) {
+      return element.value[0].type;
+    } else {
+      return element.type;
+    }
+  }
+
+  get lines () {
+    return this.value.length;
+  }
+
+  get columns () {
+    let element = this.value[0];
+    if (!(element instanceof ArrayLiteral)){
+      return null;
+    } else {
+      return element.value[0].value.length;
+    }
+  }
+
+  get isVector () {
+    return this.columns === null;
+  }
+
+  get isValid () {
+    return true;//this.validateType() && this.validateSize();
+  }
+
+  validateType () {
+    // let valid = true;
+    // if(this.columns !== null) {
+    //   const len = this.columns;
+    //   const len2 = this.lines;
+    //   for (let i = len - 1; i >= 0; i--) {
+    //     for (let j = len2 - 1; j >= 0; j--) {
+    //       if(this.value[i].value[j].type !== this.subtype) {
+    //         valid = false;
+    //         break;
+    //       }
+    //     }
+    //   }
+    // } else {
+    //   const len = this.lines;
+    //   for (var i = len - 1; i >= 0; i--) {
+    //     if(this.value[i].type !== this.subtype) {
+    //       valid = false;
+    //       break;
+    //     }
+    //   }
+    // }
+    return true;//valid;
+  }
+
+  validateSize () {
+    let valid = true;
+    if(this.columns !== null) {
+      const equalityTest = data.value.map(v => v.length)
+      .reduce((old, next) => {
+        if (old === null) {
+          return next;
+        } else if (old === next) {
+          return old
+        } else {
+          return -1;
+        }
+      }, null);
+      valid = equalityTest !== -1;
+    }
+    return valid;
+  }
+
+  toString () {
+    const strList = this.value.map(arrayLiteral => arrayLiteral.toString());
+    return "{" + strList.join(',') + "}";
+  }
+}

+ 15 - 0
ivprogh/js/ast/expressions/boolLiteral.js

@@ -0,0 +1,15 @@
+import { Literal } from './literal';
+import { Types } from './../../typeSystem/types';
+import { convertBoolToString } from "./../../typeSystem/parsers";
+
+export class BoolLiteral extends Literal {
+  
+  constructor(value) {
+    super(Types.BOOLEAN);
+    this.value = value;
+  }
+
+  toString () {
+    return convertBoolToString(this.value);
+  }
+}

+ 14 - 0
ivprogh/js/ast/expressions/expression.js

@@ -0,0 +1,14 @@
+export class Expression {
+
+  constructor () {
+    this._sourceInfo = null;
+  }
+
+  set sourceInfo (sourceInfo) {
+		this._sourceInfo = sourceInfo;
+	}
+
+	get sourceInfo () {
+		return this._sourceInfo;
+	}
+}

+ 36 - 0
ivprogh/js/ast/expressions/functionCall.js

@@ -0,0 +1,36 @@
+import { Expression } from './expression';
+import { LanguageDefinedFunction } from '../../processor/definedFunctions';
+
+export class FunctionCall extends Expression {
+
+	constructor (id, actualParameters) {
+		super();
+		this.id = id;
+		this.actualParameters = actualParameters;
+	}
+
+	get isMainCall () {
+		return this.id === null;
+	}
+
+	get parametersSize () {
+		return this.actualParameters.length;
+	}
+
+	toString () {
+		let name = null;
+		if(this.isMainCall) {
+			name = LanguageDefinedFunction.getMainFunctionName();
+		} else {
+			name = LanguageDefinedFunction.getLocalName(this.id);
+		}
+		let params = null;
+		if(this.actualParameters.length == 0) {
+			params = "()";
+		} else {
+			const strParams = this.actualParameters.map(v => v.toString());
+			params = "(" + strParams.join(",") + ")";
+		}
+		return name + params;
+	}
+}

+ 23 - 0
ivprogh/js/ast/expressions/index.js

@@ -0,0 +1,23 @@
+import { ArrayAccess } from './arrayAccess';
+import { FunctionCall } from './functionCall';
+import { IntLiteral } from './intLiteral';
+import { RealLiteral } from './realLiteral';
+import { BoolLiteral } from './boolLiteral';
+import { StringLiteral } from './stringLiteral';
+import { ArrayLiteral } from './arrayLiteral';
+import { VariableLiteral } from './variableLiteral';
+import { InfixApp } from './infixApp';
+import { UnaryApp } from './unaryApp';
+
+export {
+	ArrayAccess,
+	FunctionCall,
+  IntLiteral,
+  RealLiteral,
+  BoolLiteral,
+  StringLiteral,
+  ArrayLiteral,
+  VariableLiteral,
+  InfixApp,
+  UnaryApp
+};

+ 18 - 0
ivprogh/js/ast/expressions/infixApp.js

@@ -0,0 +1,18 @@
+import { Expression } from './expression';
+
+export class InfixApp extends Expression {
+
+  constructor(op, left, right) {
+    super();
+    this.op = op;
+    this.left = left;
+    this.right = right;
+  }
+
+  toString () {
+    const l = this.left.toString();
+    const op = this.op.value;
+    const r = this.right.toString();
+    return l + op + r;
+  }
+}

+ 15 - 0
ivprogh/js/ast/expressions/intLiteral.js

@@ -0,0 +1,15 @@
+import { Literal } from './literal';
+import { Types } from './../../typeSystem/types';
+import { convertToString } from './../../typeSystem/parsers';
+
+export class IntLiteral extends Literal {
+  
+  constructor(value) {
+    super(Types.INTEGER);
+    this.value = value;
+  }
+
+  toString() {
+    return convertToString(this.value, this.type);
+  }
+}

+ 9 - 0
ivprogh/js/ast/expressions/literal.js

@@ -0,0 +1,9 @@
+import { Expression } from './expression';
+
+export class Literal extends Expression {
+  
+  constructor (type) {
+    super();
+    this.type = type;
+  }
+}

+ 15 - 0
ivprogh/js/ast/expressions/realLiteral.js

@@ -0,0 +1,15 @@
+import { Literal } from './literal';
+import { Types } from './../../typeSystem/types';
+import { convertToString } from './../../typeSystem/parsers';
+
+export class RealLiteral extends Literal {
+  
+  constructor(value) {
+    super(Types.REAL);
+    this.value = value;
+  }
+
+  toString() {
+    return convertToString(this.value, this.type);
+  }
+}

+ 14 - 0
ivprogh/js/ast/expressions/stringLiteral.js

@@ -0,0 +1,14 @@
+import { Literal } from './literal';
+import { Types } from './../../typeSystem/types';
+
+export class StringLiteral extends Literal {
+  
+  constructor(value) {
+    super(Types.STRING);
+    this.value = value;
+  }
+
+  toString() {
+    return this.value;
+  }
+}

+ 14 - 0
ivprogh/js/ast/expressions/unaryApp.js

@@ -0,0 +1,14 @@
+import {InfixApp} from './infixApp';
+
+export class UnaryApp extends InfixApp {
+  
+  constructor (op, left) {
+    super(op, left, null);
+  }
+
+  toString () {
+    const l = this.left.toString();
+    const op = this.op.value;
+    return op + l;
+  }
+}

+ 14 - 0
ivprogh/js/ast/expressions/variableLiteral.js

@@ -0,0 +1,14 @@
+import { Literal } from './literal';
+import { Types } from './../../typeSystem/types';
+
+export class VariableLiteral extends Literal {
+  
+  constructor(id) {
+    super(Types.UNDEFINED);
+    this.id = id;
+  }
+
+  toString () {
+    return this.id;
+  }
+}

Diff do ficheiro suprimidas por serem muito extensas
+ 1182 - 0
ivprogh/js/ast/ivprogParser.js


+ 35 - 0
ivprogh/js/ast/operators.js

@@ -0,0 +1,35 @@
+export const Operators = Object.freeze({
+  ADD: {ord: 0, value: "+"},
+  SUB: {ord: 1, value: "-"},
+  MULT: {ord: 2, value: '*'},
+  DIV: {ord: 3, value: '/'},
+  MOD: {ord: 4, value: '%'},
+  GT: {ord: 5, value: '>'},
+  GE: {ord: 6, value: '>='},
+  LT: {ord: 7, value: '<'},
+  LE: {ord: 8, value: '<='},
+  EQ: {ord: 9, value: '=='},
+  NEQ: {ord: 10, value: '!='},
+  AND: {ord: 11, value: 'and'},
+  OR: {ord: 12, value: 'or'},
+  NOT: {ord: 13, value: 'not'}
+});
+
+export function convertFromString (op) {
+  switch (op) {
+    case '+' : return Operators.ADD;
+    case '-' : return Operators.SUB;
+    case '*' : return Operators.MULT;
+    case '/' : return Operators.DIV;
+    case '%' : return Operators.MOD;
+    case '>' : return Operators.GT;
+    case '>=' : return Operators.GE;
+    case '<' : return Operators.LT;
+    case '<=' : return Operators.LE;
+    case '==' : return Operators.EQ;
+    case '!=' : return Operators.NEQ;
+    case 'and' : return Operators.AND;
+    case 'or' : return Operators.OR;
+    case 'not' : return Operators.NOT;
+  }
+}

+ 22 - 0
ivprogh/js/ast/sourceInfo.js

@@ -0,0 +1,22 @@
+export class SourceInfo {
+
+  static createSourceInfo (token) {
+    return new SourceInfo(token.line, token.column, token.text.length);
+  }
+
+  static createSourceInfoFromList (tokenA, tokenB) {
+    const line = tokenA.line;
+    const column = tokenA.column;
+    // copied from https://github.com/UNIVALI-LITE/Portugol-Studio/blob/master/core/src/main/java/br/univali/portugol/nucleo/analise/sintatica/Portugol.g
+    // No idea why...
+    const size = tokenB.tokenIndex + 1 - tokenA.tokenIndex
+    return new SourceInfo(line, column, size);
+  }
+
+  constructor (line, column, size) {
+    this.line = line;
+    this.column = column;
+    this.size = size;
+  }
+
+}

+ 0 - 343
ivprogh/js/iassign-integration-functions.js~

@@ -1,343 +0,0 @@
-// Funcao para ler parametros informados pelo iTarefa via URL
-// Apesar de nao ser obrigatorio, será muito útil para capturar os parametros
-function getParameterByName (name, defaultReturn = null) {
-  var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
-  return match ? decodeURIComponent(match[1].replace(/\+/g, ' ')) : defaultReturn;
-}
-
-// Criando um object com os parametros informados pelo iTarefa
-// Observe que para cada parametro, é realizada a chamada do método getParameterByName, implementado acima
-var iLMparameters = {
-  iLM_PARAM_ServerToGetAnswerURL: getParameterByName("iLM_PARAM_ServerToGetAnswerURL"),
-  iLM_PARAM_SendAnswer: getParameterByName("iLM_PARAM_SendAnswer"),
-  iLM_PARAM_AssignmentURL: getParameterByName("iLM_PARAM_AssignmentURL"),
-  iLM_PARAM_Assignment: getParameterByName("iLM_PARAM_Assignment"),
-  lang: getParameterByName("lang", "pt")
-};
-
-// Set the lang parameter to the localStorage for easy access
-// and no dependency to the global scope, avoind future 'strict mode' problems
-try { localStorage.setItem('ivprog.lang', iLMparameters.lang); }
-catch (error) { } //leo1 If NOT in iAssign 'localStorage' is undefined! Do not try: localStorage.setItem('ivprog.lang', 'pt');
-
-// Funcao chamada pelo iTarefa quando o professor finaliza a criacao da atividade
-// ou quando o aluno finaliza a resolucao do exercício
-// O retorno é um JSON com os dados do exercício ou da resolucao
-// Esse retorno será armazenado no banco de dados do Moodle, pelo iTarefa
-function getAnswer () {
-  // Se o parametro "iLM_PARAM_SendAnswer" for false,
-  // entao trata-se de resolucao de atividade
-  if (iLMparameters.iLM_PARAM_SendAnswer == 'false') {
-    // Montar o retorno com a resposta do aluno
-    var contentToSend = previousContent.split("\n::algorithm::")[0];
-    contentToSend += '\n::algorithm::\n';
-    contentToSend += JSON.stringify(window.program_obj);
-
-    contentToSend += '\n::logs::';
-    contentToSend += getTrackingLogs();
-
-    return contentToSend;
-
-  } else {
-    // Montar o retorno com a criacao da atividade do professor
-    var ret = ' { ' + prepareTestCases() 
-        + ',\n"settings_data_types": \n' + JSON.stringify($('form[name="settings_data_types"]').serializeArray()) 
-        + ',\n"settings_commands": \n' + JSON.stringify($('form[name="settings_commands"]').serializeArray()) 
-        + ',\n"settings_functions": \n' + JSON.stringify($('form[name="settings_functions"]').serializeArray()) 
-        + ' } ';
-
-    if ($("input[name='include_algo']").is(':checked')) {
-      ret += '\n::algorithm::\n';
-      ret += JSON.stringify(window.program_obj);
-    }
-
-    return ret;
-  }
-}
-
-function prepareTestCases () {
-  var ret = ' \n "testcases" : [ '
-  var test_cases_array = $('form[name="test_cases"]').serializeArray();
-  for (var i = 0; i < test_cases_array.length; i = i + 2) {
-    ret += '\n{ ';
-    ret += '\n "input": [';
-    var inps = test_cases_array[i].value.match(/[^\r\n]+/g);
-    if (inps) {
-      for (var j = 0; j < inps.length; j++) {
-          ret += '"' + inps[j] + '"';
-          if ((j + 1) < inps.length) {
-              ret += ', ';
-          }
-      }
-    }
-    ret += '], \n "output": [';
-    var outs = test_cases_array[i+1].value.match(/[^\r\n]+/g);
-    if (outs) {
-      for (var j = 0; j < outs.length; j++) {
-          ret += '"' + outs[j] + '"';
-          if ((j + 1) < outs.length) {
-              ret += ', ';
-          }
-      }
-    }
-    ret += ']';
-    ret += '\n}'
-    if ((i + 2) < test_cases_array.length) {
-      ret += ',';
-    }
-  }
-  ret += '\n] ';
-  return ret;
-}
-
-// Funcao chamada pelo iTarefa para receber a nota do aluno na atividade
-// O retorno é um valor entre 0.0 e 1.0
-function getEvaluation () {
-  // var strContent = getAnswer(); alert('./ivprogh/js/getEvaluation(): aqui! ' + strContent);
-  alert('./ivprogh/js/getEvaluation(): aqui! ');
-  if (iLMparameters.iLM_PARAM_SendAnswer == 'false') {
-    // A chamada do método abaixo é obrigatoria!
-    // Observe que a chamada parte do iLM para o iTarefa
-    //parent.getEvaluationCallback(window.studentGrade);
-
-    runCodeAssessment();
-  }
-}
-
-
-var testCases = null;
-var settingsDataTypes = null;
-var settingsCommands = null;
-var settingsFunctions = null;
-var algorithm_in_ilm = null;
-var previousContent = null;
-
-// Funcao para que o iMA leia os dados da atividade fornecidos pelo iTarefa
-function getiLMContent () {
-
-  // O parametro "iLM_PARAM_Assignment" fornece o URL do endereço que deve ser
-  // requisitado via AJAX para a captura dos dados da atividade
-  $.get(iLMparameters.iLM_PARAM_Assignment, function (data) {
-    if (iLMparameters.iLM_PARAM_SendAnswer == 'false') {
-      previousContent = data;
-      prepareActivityToStudent(data);
-    } else {
-
-    }
-  });
-}
-
-function prepareActivityToStudent (ilm_cont) {
-  var content = JSON.parse(ilm_cont.split('\n::algorithm::')[0]);
-  testCases = content.testcases;
-  settingsDataTypes = content.settings_data_types;
-  settingsCommands = content.settings_commands;
-  settingsFunctions = content.settings_functions;
-  algorithm_in_ilm = ilm_cont.split('\n::algorithm::')[1].split('\n::logs::')[0];
-
-  window.program_obj.functions = JSON.parse(algorithm_in_ilm).functions;
-  window.program_obj.globals = JSON.parse(algorithm_in_ilm).globals;
-  renderAlgorithm();
-}
-
-// Funcao para organizar se para criacao, visualizacao ou resolucao de atividade
-function prepareEnvironment () {
-  if ((iLMparameters.iLM_PARAM_AssignmentURL == "true") && (iLMparameters.iLM_PARAM_SendAnswer == "true")) {
-    prepareActivityCreation();
-  }
-}
-
-$(document).ready(function() {
-
-  // Se iLM_PARAM_SendAnswer for false, entao trata-se de resolucao de atividade,
-  // portanto, a "DIV" de resolucao é liberada
-  if (iLMparameters.iLM_PARAM_SendAnswer == 'false') {
-    //$('.resolucao').css("display","block");
-    getiLMContent();
-
-
-    $( document ).ready(function() {
-      $('.div_to_body').mousemove(function(e) {
-          trackingMatrix.push(adCoords(e, 0));
-      });
-
-      $('.div_to_body').click(function(e) {
-          trackingMatrix.push(adCoords(e, 1));                    
-      });
-
-    });
-
-  } else {
-    // Caso nao esteja em modo de resolucao de atividade, a visualizacao no momento
-    // é para a elaboracao de atividade:
-    //$('.elaboracao').css("display","block");
-  }
-});
-
-// Funcao para preparar a interface para o professor criar atividade:
-function prepareActivityCreation () {
-
-  $('.add_accordion').addClass('accordion');
-
-  $('.default_visual_title').toggle();
-  $('.default_visual_title').append('<span>'+LocalizedStrings.getUI('text_teacher_algorithm')+'</span>');
-  $('.height_100').removeClass('height_100');
-  $('.main_title').remove();
-  $('.ui.accordion').addClass('styled');
-  
-  $('<div class="ui checkbox"><input type="checkbox" name="include_algo" class="include_algo" tabindex="0" class="hidden"><label>'+LocalizedStrings.getUI('text_teacher_algorithm_include')+'</label></div>').insertBefore('.content_margin');
-  
-  var cases_test_div = $('<div class="ui accordion styled"><div class="active title"><i class="dropdown icon"></i>'+LocalizedStrings.getUI('text_teacher_test_case')+'</div><div class="active content"></div></div>');
-
-  cases_test_div.insertBefore('.accordion');
-
-  var config_div = $('<div class="ui accordion styled"><div class="title"><i class="dropdown icon"></i>'+LocalizedStrings.getUI('text_teacher_config')+'</div><div class="content"></div></div>');
-
-  config_div.insertAfter(cases_test_div);
-
-  $('.ui.accordion').accordion();
-
-  $('.ui.checkbox').checkbox();
-
-  prepareTableSettings(config_div.find('.content'));
-
-  prepareTableTestCases(cases_test_div.find('.content'));
-}
-
-function prepareTableTestCases (div_el) {
-
-  var table_el = '<form name="test_cases"><table class="ui blue table"><thead><tr><th width="30px">#</th><th>'+LocalizedStrings.getUI('text_teacher_test_case_input')+'</th><th>'+LocalizedStrings.getUI('text_teacher_test_case_output')+'</th><th width="80px">'+LocalizedStrings.getUI('text_teacher_test_case_actions')+'</th></tr></thead>'
-      + '<tbody class="content_cases"></tbody></table></form>';
-
-  div_el.append(table_el);
-
-  div_el.append('<button class="ui teal labeled icon button button_add_case"><i class="plus icon"></i>'+LocalizedStrings.getUI('text_teacher_test_case_add')+'</button>');
-
-  $('.button_add_case').on('click', function(e) {
-    addTestCase();
-  });
-
-}
-
-var hist = false;
-
-function addTestCase () {
-  var new_row = $('<tr><td class="counter"></td><td class="expandingArea"><textarea rows="1" name="input" class="text_area_input"></textarea></td><td class="expandingArea"><textarea rows="1" name="output" class="text_area_output"></textarea></td><td class="btn_actions"><div class="ui button_remove_case"><i class="red icon times large"></i></div></td></tr>');
-  $('.content_cases').append(new_row);
-
-  new_row.find('.button_remove_case').click(function(e) {
-    new_row.remove();
-    updateTestCaseCounter();
-  });
-
-  $('textarea').on('input', function(e) {
-    var lines = $(this).val().split('\n').length;
-    $(this).attr('rows', lines);
-  });
-  
-  updateTestCaseCounter();
-
-   $('.text_area_output').keydown(function(e) {
-    var code = e.keyCode || e.which;
-    if (code == 9 && $(this).closest("tr").is(":last-child")) {
-      hist = true;
-      addTestCase();
-    }
-   });
-   if (!hist) {
-    $( ".content_cases tr:last" ).find('.text_area_input').focus();
-   } else {
-    hist = false;
-   }
-}
-
-function updateTestCaseCounter () {
-  var i = 1;
-  $( ".content_cases" ).find('tr').each(function() {
-    $( this ).find('.counter').text(i);
-    i ++;
-  });
-}
-
-function prepareTableSettings (div_el) {
-  div_el.append('<h4 class="ui header">'+LocalizedStrings.getUI('text_teacher_data_types')+'</h4>');
-  div_el.append('<form name="settings_data_types"><div class="ui stackable five column grid">'
-    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="integer_data_type" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('integer')+'</label></div></div>'
-    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="real_data_type" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('real')+'</label></div></div>'
-    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="text_data_type" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text')+'</label></div></div>'
-    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="boolean_data_type" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('boolean')+'</label></div></div>'
-    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="void_data_type" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('void')+'</label></div></div>'
-    +'</div></form>');
-
-
-  div_el.append('<h4 class="ui header">'+LocalizedStrings.getUI('text_teacher_commands')+'</h4>');
-  div_el.append('<form name="settings_commands"><div class="ui stackable three column grid">'
-    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_read" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_read_var')+'</label></div></div>'
-    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_write" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_write_var')+'</label></div></div>'
-    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_comment" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_comment')+'</label></div></div>'
-    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_attribution" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_attribution')+'</label></div></div>'
-    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_functioncall" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_functioncall')+'</label></div></div>'
-    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_iftrue" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_iftrue')+'</label></div></div>'
-    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_repeatNtimes" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_repeatNtimes')+'</label></div></div>'
-    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_while" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_whiletrue')+'</label></div></div>'
-    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_dowhile" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_dowhiletrue')+'</label></div></div>'
-    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_switch" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_switch')+'</label></div></div>'
-    +'</div></form>');
-
-  div_el.append('<h4 class="ui header">'+LocalizedStrings.getUI('text_teacher_functions')+'</h4>');
-  div_el.append('<form name="settings_functions"><div class="ui stackable one column grid">'
-    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="functions_creation" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_teacher_create_functions')+'</label></div></div>'
-    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="functions_move" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_teacher_create_movement_functions')+'</label></div></div>'
-    +'</div></form>');
-
-  $('.ui.checkbox').checkbox();
-
-
-}
-
-function getTrackingLogs () {
-  var ret = "";
-  for (var i = 0; i < trackingMatrix.length; i++) {
-    ret += "\n" + trackingMatrix[i][0] + "," + trackingMatrix[i][1] + "," + trackingMatrix[i][2];
-    if (trackingMatrix[i][2] === 1) {
-      ret += ',"' + trackingMatrix[i][3] + '"';
-    }
-  }
-  return ret;
-}
-
-// Tracking mouse movements
-var trackingMatrix = [];
-
-function adCoords(e, code){
-  var x = e.pageX; 
-  var y = e.pageY;
-  if (code === 1) {
-    return [x, y, code, e.target.classList['value']];
-  } else {
-    return [x, y, code];
-  }
-}
-
-$( document ).ready(function() {
-
-  if (inIframe()) {
-    orderIcons();
-  }
-
-});
-
-function orderIcons() {
-  $('.ui.one.column.doubling.stackable.grid.container').css('display', 'none');
-  $('.only_in_frame').css('display', 'block');
-  
-}
-
-
-function inIframe () {
-  try {
-    return window.self !== window.top;
-  } catch (e) {
-    return true;
-  }
-}

+ 138 - 0
ivprogh/js/io/domConsole.js

@@ -0,0 +1,138 @@
+import $ from 'jquery';
+
+export class DOMConsole {
+
+  static get USER () {
+    return 0;
+  }
+
+  static get INFO () {
+    return 1;
+  }
+
+  static get ERR () {
+    return 2;
+  }
+
+  constructor (elementID) {
+    this.input = null;
+    this.needInput = false;
+    this.termDiv = null;
+    this.anyKey = false;
+    this.parent = $(elementID);
+    this.setup();
+    this.inputListeners = [];
+  }
+
+  setup () {
+    this._setupDom();
+    this._setupEvents();
+  }
+
+  _setupEvents () {
+    this.input.on("keydown", (event) => {
+      if (!this.needInput) {
+        event.preventDefault();
+        return;
+      }
+      const keyCode = event.which;
+      if (keyCode === 13 || this.anyKey) {
+        let text = this.input.val();
+        text = text.replace('[\n\r]+', '');
+        this.notifyListeners(text);
+        this.write(text);
+        this.input.val("");
+      }
+    });
+  }
+
+  _setupDom () {
+    this.termDiv = $("<div></div>");
+    this.termDiv.addClass("ivprog-term-div");
+    this.input = $('<input text="type">')
+    this.input.addClass("ivprog-term-input");
+    this.termDiv.append(this.input);
+    this.parent.append(this.termDiv);
+  }
+
+  notifyListeners (text) {
+    this.inputListeners.forEach(resolve => resolve(text));
+    this.inputListeners.splice(0, this.inputListeners.length);
+    this.hideInput();
+    this.anyKey = false;
+  }
+
+  write (text) {
+    this._appendText(text, DOMConsole.USER);
+  }
+
+  info (text) {
+    this._appendText(text, DOMConsole.INFO);
+  }
+
+  err (text) {
+    this._appendText(text, DOMConsole.ERR);
+  }
+
+  _appendText (text, type) {
+    const divClass = this.getClassForType(type);
+    const textDiv = $("<div></div>");
+    textDiv.addClass(divClass);
+    textDiv.append(text);
+    textDiv.insertBefore(this.input);
+    this.scrollTerm();
+  }
+
+  scrollTerm () {
+    this.termDiv.animate({
+      scrollTop: this.termDiv.prop('scrollHeight')
+    }, 0);
+  }
+
+  getClassForType (type) {
+    switch (type) {
+      case DOMConsole.USER:
+        return "ivprog-term-userText";
+      case DOMConsole.INFO:
+        return "ivprog-term-info";
+      case DOMConsole.ERR:
+        return "ivprog-term-error";
+    }
+  }
+
+  dispose () {
+    this.parent.off();
+    this.input.off();
+    this.input = null;
+    this.parent.empty();
+  }
+
+  showInput () {
+    this.needInput = true;
+    this.input.show();
+    this.input.focus();
+  }
+
+  hideInput () {
+    this.needInput = false;
+    this.input.hide();
+  }
+
+  requestInput (callback, anyKey = false) {
+    this.inputListeners.push(callback);
+    this.anyKey = anyKey;
+    this.showInput();
+  }
+
+  sendOutput (text) {
+    text.split("\n").forEach(t => {
+      t = t.replace(/\t/g,'&#9;');
+      this.write(t)
+    });
+  }
+
+  clear () {
+    this.input.parent().children().not(this.input).remove();
+    this.input.val("");
+  }
+}

+ 37 - 0
ivprogh/js/io/domInput.js

@@ -0,0 +1,37 @@
+import {Input} from './input';
+import $ from 'jquery';
+
+export class DOMInput extends Input{
+
+  constructor (element) {
+    super();
+    this.el = $(element);
+    this.listeners = [];
+    this.setupEvents();
+  }
+
+  setupEvents () {
+    this.el.on('keydown', (e) => {
+      const code = e.keyCode || e.which;
+      if (code === 13) {
+        let text = this.el.val();
+        text = text.replace('[\n\r]+', '');
+        this.notifyInput(text);
+        this.el.val('');
+      }
+    });
+  }
+
+  requestInput (callback) {
+    this.listeners.push(callback);
+    this.el.focus();
+  }
+
+  notifyInput (text) {
+    this.listeners.forEach(resolve => {
+      resolve(text);
+    })
+    this.listeners.splice(0, this.listeners.length);
+  }
+
+}

+ 21 - 0
ivprogh/js/io/domOutput.js

@@ -0,0 +1,21 @@
+import { Output } from './output';
+import $ from 'jquery';
+
+export class DOMOutput extends Output {
+
+  constructor (selector) {
+    super();
+    this.el = $(selector);
+  }
+
+  sendOutput (text) {
+    text = text.replace("\n", '</br>');
+    text = text.replace(/\t/g,'&#9;');
+    const span = $('<span />').addClass('ivprog-io-output-text').html(text);
+    this.el.append(span);
+  }
+
+  clear () {
+    this.el.empty();
+  }
+}

+ 6 - 0
ivprogh/js/io/input.js

@@ -0,0 +1,6 @@
+export class Input {
+
+  requestInput (callback) {
+    throw new Error("Must be implemented");
+  }
+}

+ 6 - 0
ivprogh/js/io/output.js

@@ -0,0 +1,6 @@
+export class Output {
+
+  sendOutput (text) {
+    throw new Error("Must be implemented");
+  }
+}

+ 13 - 0
ivprogh/js/main.js

@@ -0,0 +1,13 @@
+import { runner } from './runner';
+import { initVisualUI } from './visualUI/functions';
+import { LocalizedStrings} from './services/localizedStringsService';
+import { i18nHelper } from "./services/i18nHelper";
+
+const i18n = i18nHelper.i18n
+
+export {
+  runner,
+  initVisualUI,
+  LocalizedStrings,
+  i18n
+}

+ 180 - 0
ivprogh/js/processor/compatibilityTable.js

@@ -0,0 +1,180 @@
+import { Types } from './../typeSystem/types';
+import { Operators } from './../ast/operators';
+import { MultiType } from '../typeSystem/multiType';
+
+function buildInfixAddTable () {
+  const table = [[], [], [], []];
+
+  table[Types.INTEGER.ord][Types.INTEGER.ord] = Types.INTEGER;
+  table[Types.INTEGER.ord][Types.REAL.ord] = Types.REAL;
+  table[Types.INTEGER.ord][Types.STRING.ord] = Types.STRING;
+
+  table[Types.REAL.ord][Types.INTEGER.ord] = Types.REAL;
+  table[Types.REAL.ord][Types.REAL.ord] = Types.REAL;
+  table[Types.REAL.ord][Types.STRING.ord] = Types.STRING;
+
+  table[Types.STRING.ord][Types.INTEGER.ord] = Types.STRING;
+  table[Types.STRING.ord][Types.REAL.ord] = Types.STRING;
+  table[Types.STRING.ord][Types.STRING.ord] = Types.STRING;
+  table[Types.STRING.ord][Types.BOOLEAN.ord] = Types.STRING;
+
+  return table;
+}
+
+function buildInfixMultiDivSubTable () {
+  const table = [[], [], [], []];
+
+  table[Types.INTEGER.ord][Types.INTEGER.ord] = Types.INTEGER;
+  table[Types.INTEGER.ord][Types.REAL.ord] = Types.REAL;
+
+  table[Types.REAL.ord][Types.INTEGER.ord] = Types.REAL;
+  table[Types.REAL.ord][Types.REAL.ord] = Types.REAL;
+
+  return table;
+}
+
+function buildInfixEqualityInequalityTable () {
+  const table = [[], [], [], []];
+
+  table[Types.INTEGER.ord][Types.INTEGER.ord] = Types.BOOLEAN;
+
+  table[Types.REAL.ord][Types.REAL.ord] = Types.BOOLEAN;
+
+  table[Types.BOOLEAN.ord][Types.BOOLEAN.ord] = Types.BOOLEAN;
+
+  table[Types.STRING.ord][Types.STRING.ord] = Types.BOOLEAN;
+
+  return table;
+}
+
+function buildInfixRelationalTable () {
+  const table = [[], [], [], []];
+
+  table[Types.INTEGER.ord][Types.INTEGER.ord] = Types.BOOLEAN;
+
+  table[Types.REAL.ord][Types.REAL.ord] = Types.BOOLEAN;
+
+  table[Types.STRING.ord][Types.STRING.ord] = Types.BOOLEAN;
+
+  return table;
+}
+
+function buildInfixAndOrTable () {
+  const table = [[], [], [], []];
+
+  table[Types.BOOLEAN.ord][Types.BOOLEAN.ord] = Types.BOOLEAN;
+
+  return table;
+}
+
+function buildInfixModTable () {
+  const table = [[], [], [], []];
+
+  table[Types.INTEGER.ord][Types.INTEGER.ord] = Types.INTEGER;
+
+  return table;
+}
+
+function buildUnarySumSubList () {
+  const list = [];
+
+  list[Types.INTEGER.ord] = Types.INTEGER;
+
+  list[Types.REAL.ord] = Types.REAL;
+
+  return list;
+}
+
+function buildUnaryNegList () {
+  const list = [];
+
+  list[Types.BOOLEAN.ord] = Types.BOOLEAN;
+
+  return list;
+}
+
+function buildInfixCompatibilityTable () {
+  const compatibilityMap = new WeakMap();
+  compatibilityMap.set(Operators.ADD, buildInfixAddTable());
+  compatibilityMap.set(Operators.SUB, buildInfixMultiDivSubTable());
+  compatibilityMap.set(Operators.MULT, buildInfixMultiDivSubTable());
+  compatibilityMap.set(Operators.DIV, buildInfixMultiDivSubTable());
+  compatibilityMap.set(Operators.EQ, buildInfixEqualityInequalityTable());
+  compatibilityMap.set(Operators.NEQ, buildInfixEqualityInequalityTable());
+  compatibilityMap.set(Operators.GE, buildInfixRelationalTable());
+  compatibilityMap.set(Operators.GT, buildInfixRelationalTable());
+  compatibilityMap.set(Operators.LE, buildInfixRelationalTable());
+  compatibilityMap.set(Operators.LT, buildInfixRelationalTable());
+  compatibilityMap.set(Operators.OR, buildInfixAndOrTable());
+  compatibilityMap.set(Operators.AND, buildInfixAndOrTable());
+  compatibilityMap.set(Operators.MOD, buildInfixModTable());
+  return compatibilityMap;
+}
+
+function buildUnaryCompatibilityTable () {
+  const compatibilityMap = new WeakMap();
+  compatibilityMap.set(Operators.ADD, buildUnarySumSubList());
+  compatibilityMap.set(Operators.SUB, buildUnarySumSubList());
+  compatibilityMap.set(Operators.NOT, buildUnaryNegList());
+  return compatibilityMap;
+}
+
+const infixMap = buildInfixCompatibilityTable();
+const unaryMap = buildUnaryCompatibilityTable();
+
+export function resultTypeAfterInfixOp (operator, leftExpressionType, rightExpressionType) {
+  try {
+    if(leftExpressionType instanceof MultiType && rightExpressionType instanceof MultiType) {
+      let newMulti = [];
+      for (let i = 0; i < leftExpressionType.types.length; i++) {
+        const element = leftExpressionType.types[i];
+        if(rightExpressionType.types.indexOf(element) !== -1) {
+          newMulti.push(element);
+        }
+      }
+      if(newMulti.length <= 0) {
+        return Types.UNDEFINED;
+      } else {
+        return new MultiType(newMulti)
+      }
+    } else if(leftExpressionType instanceof MultiType) {
+      if(leftExpressionType.isCompatible(rightExpressionType)) {
+        return rightExpressionType;
+      } else {
+        return Types.UNDEFINED;
+      }
+    } else if(rightExpressionType instanceof MultiType) {
+      if(rightExpressionType.isCompatible(leftExpressionType)) {
+        return leftExpressionType;
+      } else {
+        return Types.UNDEFINED;
+      }
+    }
+    const resultType = infixMap.get(operator)[leftExpressionType.ord][rightExpressionType.ord];
+    if (resultType === null || resultType === undefined) {
+      return Types.UNDEFINED
+    }
+    return resultType;
+  } catch (e) {
+    if (e instanceof TypeError) {
+      return Types.UNDEFINED;
+    } else {
+      throw e;
+    }
+  }
+}
+
+export function resultTypeAfterUnaryOp (operator, leftExpressionType) {
+  try {
+    if(leftExpressionType instanceof MultiType){
+      return leftExpressionType;
+    }
+    return unaryMap.get(operator)[leftExpressionType.ord];
+  } catch (e) {
+    if (e instanceof TypeError) {
+      return Types.UNDEFINED;
+    } else {
+      throw e;
+    } 
+  }
+}

+ 5 - 0
ivprogh/js/processor/context.js

@@ -0,0 +1,5 @@
+export const Context = Object.freeze({
+  BASE: Symbol('context:base'),
+  BREAKABLE: Symbol('context:breakable'),
+  FUNCTION: Symbol('context:function')
+});

+ 128 - 0
ivprogh/js/processor/definedFunctions.js

@@ -0,0 +1,128 @@
+import { LanguageService } from '../services/languageService';
+import {createInputFun, createOutputFun} from './lib/io';
+import {createLengthFun, createLowercaseFun,
+  createrCharAtFun, createSubstringFun,
+  createUppercaseFun} from './lib/strings';
+import {createMatrixColumnsFun, createMatrixLinesFun,
+  createNumElementsFun} from './lib/arrays';
+import {createCastBoolFun, createCastIntFun,
+  createCastRealFun, createCastStringFun,
+  createIsBoolFun, createIsIntFun,
+  createIsRealFun} from './lib/lang';
+import {createAbsFun, createCosFun,
+  createInvertFun, createLogFun,
+  createMaxFun, createMinFun,
+  createNegateFun, createPowFun,
+  createSinFun, createSqrtFun,
+  createTanFun} from './lib/math';
+
+function valueToKey (value, object) {
+  for (const key in object) {
+    if(object.hasOwnProperty(key)){
+      if (object[key] === value) {
+        return key;
+      }
+    }
+  }
+  return null;
+}
+
+function concatObjects (...objs) {
+  let result = {};
+  for (let i = 0; i < objs.length; i++) {
+    const obj = objs[i];
+    for(const key in obj) {
+      if(obj.hasOwnProperty(key)) {
+        result[key] = obj[key];
+      }
+    }
+  }
+  return result;
+}
+
+const libsObject = {
+  $mathLib: {
+    $sin: createSinFun(),
+    $cos: createCosFun(),
+    $tan: createTanFun(),
+    $sqrt: createSqrtFun(),
+    $pow: createPowFun(),
+    $log: createLogFun(),
+    $abs: createAbsFun(),
+    $negate: createNegateFun(),
+    $invert: createInvertFun(),
+    $max: createMaxFun(),
+    $min: createMinFun()
+  },
+  $ioLib: {
+    $read: createInputFun(),
+    $write: createOutputFun()
+  },
+  $strLib: {
+    $substring: createSubstringFun(),
+    $length: createLengthFun(),
+    $uppercase: createUppercaseFun(),
+    $lowercase: createLowercaseFun(),
+    $charAt: createrCharAtFun(),
+  },
+  $arrayLib: {
+    $numElements: createNumElementsFun(),
+    $matrixLines: createMatrixLinesFun(),
+    $matrixColumns: createMatrixColumnsFun()
+  },
+  $langLib: {
+    $isReal: createIsRealFun(),
+    $isInt: createIsIntFun(),
+    $isBool: createIsBoolFun(),
+    $castReal: createCastRealFun(),
+    $castInt: createCastIntFun(),
+    $castBool: createCastBoolFun(),
+    $castString: createCastStringFun()
+  }
+}
+
+const funcsObject = concatObjects(libsObject.$ioLib, libsObject.$langLib,
+  libsObject.$strLib, libsObject.$arrayLib);
+
+export const LanguageDefinedFunction = Object.freeze({
+  getMainFunctionName: () => LanguageService.getCurrentLangFuncs().main_function,
+  getInternalName: (localName) => {
+    if (localName.indexOf(".") !== -1) {
+      const names = localName.split(".");
+      const lib = valueToKey(names[0], LanguageService.getCurrentLangLibs());
+      const internalName = valueToKey(names[1], LanguageService.getCurrentLangFuncs());
+      if (lib === null || internalName === null) {
+        return null;
+      }
+      return lib + "." + internalName;
+    }
+    const funcName = valueToKey(localName, LanguageService.getCurrentLangFuncs());
+    if(funcName !== null) {
+      if(funcsObject[funcName]) {
+        return funcName;
+      }
+    }
+    return null;
+  },
+  getFunction: (internalName) => {
+    if (internalName.indexOf(".") !== -1) {
+      const names = internalName.split(".");
+      const libName = names[0];
+      const funName = names[1];
+      return libsObject[libName][funName];
+    }
+    return funcsObject[internalName];
+  },
+  getLocalName: (internalName) => {
+    if (internalName.indexOf(".") !== -1) {
+      const names = internalName.split(".");
+      const libName = LanguageService.getCurrentLangLibs()[names[0]];
+      const funName = LanguageService.getCurrentLangFuncs()[names[1]];
+      return `${libName}.${funName}`;
+    } else if (LanguageService.getCurrentLangFuncs()[internalName]) {
+      return LanguageService.getCurrentLangFuncs()[internalName];
+    } else { 
+      return internalName
+    }
+  }
+});

+ 398 - 0
ivprogh/js/processor/error/processorErrorFactory.js

@@ -0,0 +1,398 @@
+import { RuntimeError } from './runtimeError';
+import { SemanticError } from './semanticError';
+import { LocalizedStrings } from './../../services/localizedStringsService';
+import { Operators } from '../../ast/operators';
+
+function translateType (type, dim) {
+  switch (dim) {
+    case 0:
+      return LocalizedStrings.getUI(type);
+    default:
+      const transType = LocalizedStrings.getUI(type);
+      if(dim === 1)
+        return LocalizedStrings.getUI("vector_string", [transType])
+      else
+        return LocalizedStrings.getUI("matrix_string", [transType])
+  }
+}
+
+function translateOp (op) {
+  switch(op.ord) {
+    case Operators.AND.ord:
+    case Operators.OR.ord:
+    case Operators.NOT.ord:
+      return LocalizedStrings.getUI(op.value);
+    default:
+      return op.value;
+  }
+}
+
+export const ProcessorErrorFactory  = Object.freeze({
+  symbol_not_found_full: (id, sourceInfo) => {
+    if(sourceInfo) {
+      const context = [id, sourceInfo.line, sourceInfo.column];
+      return new SemanticError(LocalizedStrings.getError("symbol_not_found_full", context));
+    } else {
+      return ProcessorErrorFactory.symbol_not_found(id);
+    }
+  },
+  symbol_not_found: (id) => {
+    const context = [id];
+    return new SemanticError(LocalizedStrings.getError("symbol_not_found", context));
+  },
+  function_missing_full: (id, sourceInfo) => {
+    if(sourceInfo) {
+      const context = [id, sourceInfo.line, sourceInfo.column];
+      return new SemanticError(LocalizedStrings.getError("function_missing_full", context));
+    } else {
+      return ProcessorErrorFactory.function_missing(id);
+    }
+  },
+  function_missing: (id) => {
+    const context = [id];
+    return new SemanticError(LocalizedStrings.getError("function_missing", context));
+  },
+  main_missing: () => {
+    return new SemanticError(LocalizedStrings.getError("main_missing"));
+  },        // TODO: better urgent error message
+  array_dimension_not_int_full: (sourceInfo) => {
+    if(sourceInfo) {
+      const context = [sourceInfo.line];
+      return new SemanticError(LocalizedStrings.getError("array_dimension_not_int_full", context));
+    } else {
+      return ProcessorErrorFactory.array_dimension_not_int();
+    }
+  },
+  array_dimension_not_int: () => {
+    return new SemanticError(LocalizedStrings.getError("array_dimension_not_int"));
+  },
+  unknown_command_full: (sourceInfo)=> {
+    if(sourceInfo) {
+      const context = [sourceInfo.line];
+      return new RuntimeError(LocalizedStrings.getError("unknown_command_full", context));
+    } else {
+      return ProcessorErrorFactory.unknown_command();
+    }
+    
+  },
+  unknown_command: ()=> {
+    return new RuntimeError(LocalizedStrings.getError("unknown_command"));
+  },
+  incompatible_types_full: (type, dim, sourceInfo) => {
+    if(sourceInfo) {
+      const context = [translateType(type, dim), sourceInfo.line, sourceInfo.column];
+      return new SemanticError(LocalizedStrings.getError("incompatible_types_full", context));
+    } else {
+      return ProcessorErrorFactory.incompatible_types(type, dim);
+    }
+  },
+  incompatible_types: (type, dim) => {
+    const context = [translateType(type, dim)];
+    return new SemanticError(LocalizedStrings.getError("incompatible_types", context));
+  },
+  incompatible_types_array_full: (exp, type, dim, sourceInfo) => {
+    if(sourceInfo) {
+      const context = [exp, translateType(type, dim), sourceInfo.line, sourceInfo.column];
+      return new SemanticError(LocalizedStrings.getError("incompatible_types_array_full", context));
+    } else {
+      return ProcessorErrorFactory.incompatible_types_array(exp, type, dim);
+    }
+  },
+  incompatible_types_array: (exp, type, dim) => {
+    const context = [exp, translateType(type, dim)];
+    return new SemanticError(LocalizedStrings.getError("incompatible_types_array", context));
+  },
+  loop_condition_type_full: (sourceInfo) => {
+    if(sourceInfo) {
+      const context = [sourceInfo.line, sourceInfo.column];
+      return new SemanticError(LocalizedStrings.getError("loop_condition_type_full", context));
+    } else {
+      return ProcessorErrorFactory.loop_condition_type();
+    }
+  },
+  loop_condition_type: () => {
+    return new SemanticError(LocalizedStrings.getError("loop_condition_type"));
+  },
+  endless_loop_full: (sourceInfo) => {
+    if(sourceInfo) {
+      const context = [sourceInfo.line];
+      return new SemanticError(LocalizedStrings.getError("endless_loop_full", context));
+    } else {
+      return ProcessorErrorFactory.endless_loop();
+    }
+  },
+  endless_loop: () => {
+    return new SemanticError(LocalizedStrings.getError("endless_loop"));
+  },
+  for_condition_type_full: (sourceInfo) => {
+    if(sourceInfo) {
+      const context = [sourceInfo.line, sourceInfo.column];
+      return new SemanticError(LocalizedStrings.getError("for_condition_type_full", context));
+    } else {
+      return ProcessorErrorFactory.for_condition_type();
+    }
+  },
+  for_condition_type: () => {
+    return new SemanticError(LocalizedStrings.getError("for_condition_type"));
+  },
+  if_condition_type_full: (sourceInfo) => {
+    if(sourceInfo) {
+      const context = [sourceInfo.line, sourceInfo.column];
+      return new SemanticError(LocalizedStrings.getError("if_condition_type_full", context));
+    } else {
+      return ProcessorErrorFactory.if_condition_type();
+    }
+  },
+  if_condition_type: () => {
+    return new SemanticError(LocalizedStrings.getError("if_condition_type"));
+  },
+  invalid_global_var: () => {
+    return new RuntimeError(LocalizedStrings.getError("invalid_global_var"))
+  },
+  not_implemented: (id) => {
+    const context  = [id]
+    return new RuntimeError(LocalizedStrings.getError("not_implemented", context))
+  },
+  invalid_case_type_full: (exp, type, dim, sourceInfo) => {
+    if(sourceInfo) {
+      const context = [exp, translateType(type, dim), sourceInfo.line, sourceInfo.column];
+      return new SemanticError(LocalizedStrings.getError("invalid_case_type_full", context));
+    } else {
+      return ProcessorErrorFactory.invalid_case_type(exp, type, dim);
+    }
+  },
+  invalid_case_type: (exp, type, dim) => {
+    const context = [exp, translateType(type, dim)];
+    return new SemanticError(LocalizedStrings.getError("invalid_case_type", context));
+  },
+  void_in_expression_full: (id, sourceInfo) => {
+    if(sourceInfo) {
+      const context = [sourceInfo.line, sourceInfo.column, id];
+      return new SemanticError(LocalizedStrings.getError("void_in_expression_full", context));
+    } else {
+      return ProcessorErrorFactory.void_in_expression(id);
+    }
+  },
+  void_in_expression: (id) => {
+    const context = [id];
+    return new SemanticError(LocalizedStrings.getError("void_in_expression", context));
+  },
+  invalid_array_access_full: (id, sourceInfo) => {
+    if(sourceInfo) {
+      const context = [id, sourceInfo.line, sourceInfo.column];
+      return new SemanticError(LocalizedStrings.getError("invalid_array_access_full", context));
+    } else {
+      return ProcessorErrorFactory.invalid_array_access(id);
+    }
+  },
+  invalid_array_access: (id) => {
+    const context = [id];
+    return new SemanticError(LocalizedStrings.getError("invalid_array_access", context));
+  },
+  invalid_matrix_access_full: (id, sourceInfo) => {
+    if(sourceInfo) {
+      const context = [id, sourceInfo.line, sourceInfo.column];
+      return new SemanticError(LocalizedStrings.getError("invalid_matrix_access_full", context));
+    } else {
+      return ProcessorErrorFactory.invalid_matrix_access(id);
+    }
+  },
+  invalid_matrix_access: (id) => {
+    const context = [id];
+    return new SemanticError(LocalizedStrings.getError("invalid_matrix_access", context));
+  },
+  matrix_column_outbounds_full: (id, value, columns, sourceInfo) => {
+    if(sourceInfo) {
+      const context = [sourceInfo.line, value, id, columns];
+      return new RuntimeError(LocalizedStrings.getError("matrix_column_outbounds_full", context));
+    } else {
+      return ProcessorErrorFactory.matrix_column_outbounds(id, value, columns);
+    }
+  },
+  matrix_column_outbounds: (id, value, columns) => {
+    const context = [value, id, columns];
+    return new RuntimeError(LocalizedStrings.getError("matrix_column_outbounds", context));
+  },
+  matrix_line_outbounds_full: (id, value, lines, sourceInfo) => {
+    if(sourceInfo) {
+      const context = [sourceInfo.line, value, id, lines];
+      return new RuntimeError(LocalizedStrings.getError("matrix_line_outbounds_full", context));
+    } else {
+      return ProcessorErrorFactory.matrix_line_outbounds(id, value, lines);
+    }
+  },
+  matrix_line_outbounds: (id, value, lines) => {
+    const context = [value, id, lines];
+    return new RuntimeError(LocalizedStrings.getError("matrix_line_outbounds", context));
+  },
+  vector_line_outbounds_full: (id, value, lines, sourceInfo) => {
+    if(sourceInfo) {
+      const context = [sourceInfo.line, value, id, lines];
+      return new RuntimeError(LocalizedStrings.getError("vector_line_outbounds_full", context));
+    } else {
+      return ProcessorErrorFactory.vector_line_outbounds(id, value, lines);
+    }
+  },
+  vector_line_outbounds: (id, value, lines) => {
+    const context = [value, id, lines];
+    return new RuntimeError(LocalizedStrings.getError("vector_line_outbounds", context));
+  },
+  vector_not_matrix_full: (id, sourceInfo) => {
+    if(sourceInfo) {
+      const context = [sourceInfo.line, id];
+      return new RuntimeError(LocalizedStrings.getError("vector_not_matrix_full", context));
+    } else {
+      return ProcessorErrorFactory.vector_not_matrix(id);
+    }
+  },
+  vector_not_matrix: (id) => {
+    const context = [id];
+    return new RuntimeError(LocalizedStrings.getError("vector_not_matrix", context));
+  },
+  function_no_return: (id) => {
+    const context = [id];
+    return new SemanticError(LocalizedStrings.getError("function_no_return", context));
+  },
+  invalid_void_return_full: (id, type, dim, sourceInfo) => {
+    if(sourceInfo) {
+      const context = [sourceInfo.line, id, translateType(type, dim)];
+      return new SemanticError(LocalizedStrings.getError("invalid_void_return_full", context));
+    } else {
+      return ProcessorErrorFactory.invalid_void_return(id, type, dim);
+    }
+  },
+  invalid_void_return: (id, type, dim) => {
+    const context = [id, translateType(type, dim)];
+    return new SemanticError(LocalizedStrings.getError("invalid_void_return_full", context));
+  },
+  invalid_return_type_full: (id, type, dim, sourceInfo) => {
+    if(sourceInfo) {
+      const context = [sourceInfo.line, id, translateType(type, dim)];
+      return new SemanticError(LocalizedStrings.getError("invalid_return_type_full", context));
+    } else {
+      return ProcessorErrorFactory.invalid_return_type(id, type, dim);
+    }
+  },
+  invalid_return_type: (id, type, dim) => {
+    const context = [id, translateType(type, dim)];
+    return new SemanticError(LocalizedStrings.getError("invalid_return_type", context));
+  },
+  invalid_parameters_size_full: (id, expected, actual, sourceInfo) => {
+    if(sourceInfo) {
+      const context = [sourceInfo.line, id, expected, actual];
+      return new SemanticError(LocalizedStrings.getError("invalid_parameters_size_full", context));
+    } else {
+      return ProcessorErrorFactory.invalid_parameters_size(id, expected, actual);
+    }
+  },
+  invalid_parameters_size: (id, expected, actual) => {
+    const context = [id, expected, actual];
+    return new SemanticError(LocalizedStrings.getError("invalid_parameters_size", context));
+  },
+  invalid_parameter_type_full: (id, exp, sourceInfo) => {
+    if(sourceInfo) {
+      const context = [exp, id, sourceInfo.line];
+      return new SemanticError(LocalizedStrings.getError("invalid_parameter_type_full", context));
+    } else {
+      return ProcessorErrorFactory.invalid_parameter_type(id, exp);
+    }
+  },
+  invalid_parameter_type: (id, exp) => {
+    const context = [exp, id];
+    return new SemanticError(LocalizedStrings.getError("invalid_parameter_type_full", context));
+  },
+  invalid_ref_full: (id, exp, sourceInfo) => {
+    if(sourceInfo) {
+      const context = [exp, id , sourceInfo.line];
+      return new SemanticError(LocalizedStrings.getError("invalid_ref_full", context));
+    } else {
+      return ProcessorErrorFactory.invalid_ref(id, exp);
+    }
+  },
+  invalid_ref: (id, exp) => {
+    const context = [exp, id];
+    return new SemanticError(LocalizedStrings.getError("invalid_ref", context));
+  },
+  unexpected_break_command_full: (sourceInfo) => {
+    if(sourceInfo) {
+      const context = [sourceInfo.line];
+      return new RuntimeError(LocalizedStrings.getError("unexpected_break_command_full", context));
+    } else {
+      return ProcessorErrorFactory.unexpected_break_command();
+    }
+  },
+  unexpected_break_command: () => {
+    return new RuntimeError(LocalizedStrings.getError("unexpected_break_command"));
+  },
+  invalid_array_literal_type_full: (exp, sourceInfo) => {
+    if(sourceInfo) {
+      const context = [sourceInfo.line, exp];
+      return new RuntimeError(LocalizedStrings.getError("invalid_array_literal_type_full", context));
+    } else {
+      return ProcessorErrorFactory.invalid_array_literal_type(exp);
+    }
+  },
+  invalid_array_literal_type: (exp) => {
+    const context = [exp];
+    return new RuntimeError(LocalizedStrings.getError("invalid_array_literal_type", context));
+  },
+  invalid_array_literal_line_full: (expected, actual, sourceInfo) => {
+    if(sourceInfo) {
+      const context = [sourceInfo.line, expected, actual];
+      return new RuntimeError(LocalizedStrings.getError("invalid_array_literal_line_full", context));
+    } else {
+      return ProcessorErrorFactory.invalid_array_literal_type(expected, actual);
+    }
+  },
+  invalid_array_literal_line: (expected, actual) => {
+    const context = [expected, actual];
+    return new RuntimeError(LocalizedStrings.getError("invalid_array_literal_line", context));
+  },
+  invalid_array_literal_column_full: (expected, actual, sourceInfo) => {
+    if(sourceInfo) {
+      const context = [sourceInfo.line, expected, actual];
+      return new RuntimeError(LocalizedStrings.getError("invalid_array_literal_column_full", context));
+    } else {
+      return ProcessorErrorFactory.invalid_array_literal_column(expected, actual);
+    }
+  },
+  invalid_array_literal_column: (expected, actual) => {
+    const context = [expected, actual];
+    return new RuntimeError(LocalizedStrings.getError("invalid_array_literal_column", context));
+  },
+  invalid_unary_op_full: (opName, type, dim, sourceInfo) => {
+    if(sourceInfo) {
+      const context = [sourceInfo.line, translateOp(opName), translateType(type, dim)];
+      return new RuntimeError(LocalizedStrings.getError("invalid_unary_op_full", context));
+    } else {
+      return ProcessorErrorFactory.invalid_unary_op(opName, type, dim);
+    }
+  },
+  invalid_unary_op: (opName, type, dim) => {
+    const context = [translateOp(opName), translateType(type, dim)];
+    return new RuntimeError(LocalizedStrings.getError("invalid_unary_op", context));
+  },
+  invalid_infix_op_full: (opName, typeLeft, dimLeft, typeRight, dimRight,  sourceInfo) => {
+    if(sourceInfo) {
+      const context = [sourceInfo.line, translateOp(opName), translateType(typeLeft, dimLeft), translateType(typeRight, dimRight)];
+      return new RuntimeError(LocalizedStrings.getError("invalid_infix_op_full", context));
+    } else {
+      return ProcessorErrorFactory.invalid_infix_op(opName, typeLeft, dimLeft, typeRight, dimRight);
+    }
+  },
+  invalid_infix_op: (opName, typeLeft, dimLeft, typeRight, dimRight) => {
+    const context = [translateOp(opName), translateType(typeLeft, dimLeft), translateType(typeRight, dimRight)];
+    return new RuntimeError(LocalizedStrings.getError("invalid_infix_op", context));
+  },
+  array_dimension_not_positive_full: (sourceInfo) => {
+    if(sourceInfo) {
+      const context = [sourceInfo.line];
+      return new SemanticError(LocalizedStrings.getError("array_dimension_not_positive_full", context));
+    } else {
+      return ProcessorErrorFactory.array_dimension_not_positive();
+    }
+  },
+  array_dimension_not_positive: () => {
+    return new SemanticError(LocalizedStrings.getError("array_dimension_not_positive"));
+  }
+});

+ 8 - 0
ivprogh/js/processor/error/runtimeError.js

@@ -0,0 +1,8 @@
+export class RuntimeError extends Error {
+
+  constructor (...msg) {
+    super(...msg);
+    if(Error.captureStackTrace)
+      Error.captureStackTrace(this, RuntimeError);
+  }
+}

+ 8 - 0
ivprogh/js/processor/error/semanticError.js

@@ -0,0 +1,8 @@
+export class SemanticError extends Error {
+
+  constructor (...msg) {
+    super(...msg);
+    if(Error.captureStackTrace)
+      Error.captureStackTrace(this, SemanticError);
+  }
+}

+ 968 - 0
ivprogh/js/processor/ivprogProcessor.js

@@ -0,0 +1,968 @@
+import { Store } from './store/store';
+import { StoreObject } from './store/storeObject';
+import { StoreObjectArray } from './store/storeObjectArray';
+import { StoreObjectRef } from './store/storeObjectRef';
+import { Modes } from './modes';
+import { Context } from './context';
+import { Types } from './../typeSystem/types';
+import { Operators } from './../ast/operators';
+import { LanguageDefinedFunction } from './definedFunctions';
+import { resultTypeAfterInfixOp, resultTypeAfterUnaryOp } from './compatibilityTable';
+import * as Commands from './../ast/commands/';
+import * as Expressions from './../ast/expressions/';
+import { StoreObjectArrayAddress } from './store/storeObjectArrayAddress';
+import { StoreObjectArrayAddressRef } from './store/storeObjectArrayAddressRef';
+import { CompoundType } from './../typeSystem/compoundType';
+import { convertToString } from '../typeSystem/parsers';
+import { Config } from '../util/config';
+import Decimal from 'decimal.js';
+import { ProcessorErrorFactory } from './error/processorErrorFactory';
+import { RuntimeError } from './error/runtimeError';
+
+export class IVProgProcessor {
+
+  static get LOOP_TIMEOUT () {
+    return Config.loopTimeout;
+  }
+
+  static set LOOP_TIMEOUT (ms) {
+    Config.setConfig({loopTimeout: ms});
+  }
+
+  static get MAIN_INTERNAL_ID () {
+    return "$main";
+  }
+
+  constructor (ast) {
+    this.ast = ast;
+    this.globalStore = new Store("$global");
+    this.stores = [this.globalStore];
+    this.context = [Context.BASE];
+    this.input = null;
+    this.forceKill = false;
+    this.loopTimers = [];
+    this.output = null;
+  }
+
+  registerInput (input) {
+    if(this.input !== null)
+      this.input = null;
+    this.input = input;
+  }
+
+  registerOutput (output) {
+    if(this.output !== null)
+      this.output = null;
+    this.output = output;
+  }
+
+  checkContext(context) {
+    return this.context[this.context.length - 1] === context;
+  }
+
+  ignoreSwitchCases (store) {
+    if (store.mode === Modes.RETURN) {
+      return true;
+    } else if (store.mode === Modes.BREAK) {
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  prepareState () {
+    if(this.stores !== null) {
+      for (let i = 0; i < this.stores.length; i++) {
+        delete this.stores[i];
+      }
+      this.stores = null;
+    }
+    if(this.globalStore !== null)
+      this.globalStore = null;
+    this.globalStore = new Store("$global");
+    this.stores = [this.globalStore];
+    this.context = [Context.BASE];
+  }
+
+  interpretAST () {
+    this.prepareState();
+    this.initGlobal();
+    const mainFunc = this.findMainFunction();
+    if(mainFunc === null) {
+      throw ProcessorErrorFactory.main_missing();
+    }
+    return this.runFunction(mainFunc, [], this.globalStore);
+  }
+
+  initGlobal () {
+    if(!this.checkContext(Context.BASE)) {
+      throw ProcessorErrorFactory.invalid_global_var();
+    }
+    this.ast.global.forEach(decl => {
+      this.executeCommand(this.globalStore, decl).then(sto => this.globalStore = sto);
+    });
+  }
+
+  findMainFunction () {
+    return this.ast.functions.find(v => v.isMain);
+  }
+
+  findFunction (name) {
+    if(name.match(/^\$.+$/)) {
+      const fun = LanguageDefinedFunction.getFunction(name);
+      if(!!!fun) {
+        throw ProcessorErrorFactory.not_implemented(name);
+      }
+      return fun;
+    } else {
+      const val = this.ast.functions.find( v => v.name === name);
+      if (!!!val) {
+        // TODO: better error message;
+        throw ProcessorErrorFactory.function_missing(name);
+      }
+      return val;
+    }
+  }
+
+  runFunction (func, actualParameters, store) {
+    const funcName = func.isMain ? IVProgProcessor.MAIN_INTERNAL_ID : func.name;
+    let funcStore = new Store(funcName);
+    funcStore.extendStore(this.globalStore);
+    let returnStoreObject = null;
+    if(func.returnType instanceof CompoundType) {
+      if(func.returnType.dimensions > 1) {
+        returnStoreObject = new StoreObjectArray(func.returnType,-1,-1,[[]]);
+      } else {
+        returnStoreObject = new StoreObjectArray(func.returnType,-1,null,[]);
+      }
+    } else {
+      returnStoreObject = new StoreObject(func.returnType, null);
+    }
+    funcStore.insertStore('$', returnStoreObject);
+    const newFuncStore$ = this.associateParameters(func.formalParameters, actualParameters, store, funcStore);
+    return newFuncStore$.then(sto => {
+      this.context.push(Context.FUNCTION);
+      this.stores.push(sto);
+      return this.executeCommands(sto, func.variablesDeclarations)
+        .then(stoWithVars => this.executeCommands(stoWithVars, func.commands)).then(finalSto => {
+          this.stores.pop();
+          this.context.pop();
+          return finalSto;
+        });
+    });
+  }
+
+  associateParameters (formalList, actualList, callerStore, calleeStore) {
+    const funcName = calleeStore.name === IVProgProcessor.MAIN_INTERNAL_ID ? 
+      LanguageDefinedFunction.getMainFunctionName() : calleeStore.name;
+
+    if (formalList.length != actualList.length) {
+      throw ProcessorErrorFactory.invalid_parameters_size(funcName, formalList.length, actualList.length);
+    }
+    const promises$ = actualList.map(actualParameter => this.evaluateExpression(callerStore, actualParameter));
+    return Promise.all(promises$).then(values => {
+      for (let i = 0; i < values.length; i++) {
+        const stoObj = values[i];
+        const exp = actualList[i]
+        const formalParameter = formalList[i];
+        if(formalParameter.type.isCompatible(stoObj.type)) {
+          if(formalParameter.byRef && !stoObj.inStore) {
+            throw ProcessorErrorFactory.invalid_ref(funcName, exp.toString());
+          }
+
+          if(formalParameter.byRef) {
+            let ref = null;
+            if (stoObj instanceof StoreObjectArrayAddress) {
+              ref = new StoreObjectArrayAddressRef(stoObj);
+            } else {
+              ref = new StoreObjectRef(stoObj.id, callerStore);
+            }
+            calleeStore.insertStore(formalParameter.id, ref);
+          } else {
+            let realValue = this.parseStoreObjectValue(stoObj);
+            calleeStore.insertStore(formalParameter.id, realValue);
+          }
+        } else {
+          throw ProcessorErrorFactory.invalid_parameter_type(funcName, exp.toString());
+        }
+      }
+      return calleeStore;
+    });
+  }
+
+  executeCommands (store, cmds) {
+    // helper to partially apply a function, in this case executeCommand
+    const outerRef = this;
+    const partial = (fun, cmd) => (sto) => fun(sto, cmd);
+    return cmds.reduce((lastCommand, next) => {
+      const nextCommand = partial(outerRef.executeCommand.bind(outerRef), next);
+      return lastCommand.then(nextCommand);
+    }, Promise.resolve(store));
+  }
+
+  executeCommand (store, cmd) {
+
+    if(this.forceKill) {
+      return Promise.reject("FORCED_KILL!");
+    } else if (store.mode === Modes.PAUSE) {
+      return Promise.resolve(this.executeCommand(store, cmd));
+    } else if(store.mode === Modes.RETURN) {
+      return Promise.resolve(store);
+    } else if(this.checkContext(Context.BREAKABLE) && store.mode === Modes.BREAK) {
+      return Promise.resolve(store);
+    }
+
+    if (cmd instanceof Commands.Declaration) {
+      return this.executeDeclaration(store, cmd);
+    } else if (cmd instanceof Commands.ArrayIndexAssign) {
+      return this.executeArrayIndexAssign(store, cmd);
+    } else if (cmd instanceof Commands.Assign) {
+      return this.executeAssign(store, cmd);
+    } else if (cmd instanceof Commands.Break) {
+      return this.executeBreak(store, cmd);
+    } else if (cmd instanceof Commands.Return) {
+      return this.executeReturn(store, cmd);
+    } else if (cmd instanceof Commands.IfThenElse) {
+      return this.executeIfThenElse(store, cmd);
+    } else if (cmd instanceof Commands.While) {
+      return this.executeWhile(store, cmd);
+    } else if (cmd instanceof Commands.DoWhile) {
+      return this.executeDoWhile(store, cmd);
+    } else if (cmd instanceof Commands.For) {
+      return this.executeFor(store, cmd);
+    } else if (cmd instanceof Commands.Switch) {
+      return this.executeSwitch(store, cmd);
+    } else if (cmd instanceof Expressions.FunctionCall) {
+      
+      return this.executeFunctionCall(store, cmd);
+    } else if (cmd instanceof Commands.SysCall) {
+      return this.executeSysCall(store, cmd);
+    } else {
+      throw ProcessorErrorFactory.unknown_command(cmd.sourceInfo);
+    }
+  }
+
+  executeSysCall (store, cmd) {
+    const func = cmd.langFunc.bind(this);
+    return func(store, cmd);
+  }
+
+  executeFunctionCall (store, cmd) {
+    let func = null;
+    if(cmd.isMainCall) {
+      func = this.findMainFunction();
+    } else {
+      func = this.findFunction(cmd.id);
+    }
+    return this.runFunction(func, cmd.actualParameters, store)
+      .then(sto => {
+        if(!Types.VOID.isCompatible(func.returnType) && sto.mode !== Modes.RETURN) {
+          const funcName = func.name === IVProgProcessor.MAIN_INTERNAL_ID ? 
+            LanguageDefinedFunction.getMainFunctionName() : func.name;
+          return Promise.reject(ProcessorErrorFactory.function_no_return(funcName));
+        } else {
+          return store;
+        }
+      })
+  }
+
+  executeSwitch (store, cmd) {
+    this.context.push(Context.BREAKABLE);
+    const auxCaseFun = (promise, switchExp, aCase) => {
+      return promise.then( result => {
+        const sto = result.sto;
+        if (this.ignoreSwitchCases(sto)) {
+          return Promise.resolve(result);
+        } else if (result.wasTrue || aCase.isDefault) {
+          const $newSto = this.executeCommands(result.sto,aCase.commands);
+          return $newSto.then(nSto => {
+            return Promise.resolve({wasTrue: true, sto: nSto});
+          });
+        } else {
+          const $value = this.evaluateExpression(sto,
+            new Expressions.InfixApp(Operators.EQ, switchExp, aCase.expression));
+          return $value.then(vl => {
+            if (vl.value) {
+              const $newSto = this.executeCommands(result.sto,aCase.commands);
+              return $newSto.then(nSto => {
+                return Promise.resolve({wasTrue: true, sto: nSto});
+              });
+            } else {
+              return Promise.resolve({wasTrue: false, sto: sto});
+            }
+          });
+        }
+      });
+    }
+
+    try {
+      let breakLoop = false;
+      let $result = Promise.resolve({wasTrue: false, sto: store});
+      for (let index = 0; index < cmd.cases.length && !breakLoop; index++) {
+        const aCase = cmd.cases[index];
+        $result = auxCaseFun($result, cmd.expression, aCase);
+        $result.then( r => breakLoop = this.ignoreSwitchCases(r.sto));
+      }
+      return $result.then(r => {
+        this.context.pop();
+        if(r.sto.mode === Modes.BREAK) {
+          r.sto.mode = Modes.RUN;
+        }
+        return r.sto;
+      });
+    } catch (error) {
+      return Promise.reject(error);
+    }
+  }
+
+  executeFor (store, cmd) {
+    try {
+      //BEGIN for -> while rewrite
+      const initCmd = cmd.assignment;
+      const condition = cmd.condition;
+      const increment = cmd.increment;
+      const whileBlock = new Commands.CommandBlock([],
+        cmd.commands.concat(increment));
+      const forAsWhile = new Commands.While(condition, whileBlock);
+      //END for -> while rewrite
+      const newCmdList = [initCmd,forAsWhile];
+      return this.executeCommands(store, newCmdList);
+    } catch (error) {
+      return Promise.reject(error);
+    }
+  }
+
+  executeDoWhile (store, cmd) {
+    const outerRef = this;
+    try {
+      outerRef.loopTimers.push(Date.now());
+      outerRef.context.push(Context.BREAKABLE);
+      const $newStore = outerRef.executeCommands(store, cmd.commands);
+      return $newStore.then(sto => {
+        if(sto.mode === Modes.BREAK) {
+          outerRef.context.pop();
+          sto.mode = Modes.RUN;
+          outerRef.loopTimers.pop();
+          return sto;
+        }
+        const $value = outerRef.evaluateExpression(sto, cmd.expression);
+        return $value.then(vl => {
+          if (!vl.type.isCompatible(Types.BOOLEAN)) {
+            return Promise.reject(ProcessorErrorFactory.loop_condition_type_full(cmd.sourceInfo));
+          }
+          if (vl.value) {
+            outerRef.context.pop();
+            for (let i = 0; i < outerRef.loopTimers.length; i++) {
+              const time = outerRef.loopTimers[i];
+              if(Date.now() - time >= IVProgProcessor.LOOP_TIMEOUT) {
+                outerRef.forceKill = true;
+                return Promise.reject(ProcessorErrorFactory.endless_loop_full(cmd.sourceInfo));
+              }
+            }
+            return outerRef.executeCommand(sto, cmd);
+          } else {
+            outerRef.context.pop();
+            outerRef.loopTimers.pop();
+            return sto;
+          }
+        })
+      })
+    } catch (error) {
+      return Promise.reject(error);
+    }
+  }
+
+  executeWhile (store, cmd) {
+    const outerRef = this;
+    try {
+      outerRef.loopTimers.push(Date.now());
+      outerRef.context.push(Context.BREAKABLE);
+      const $value = outerRef.evaluateExpression(store, cmd.expression);
+      return $value.then(vl => {
+        if(vl.type.isCompatible(Types.BOOLEAN)) {
+          if(vl.value) {
+            const $newStore = outerRef.executeCommands(store, cmd.commands);
+            return $newStore.then(sto => {
+              outerRef.context.pop();
+              if (sto.mode === Modes.BREAK) {
+                outerRef.loopTimers.pop();
+                sto.mode = Modes.RUN;
+                return sto;
+              }
+              for (let i = 0; i < outerRef.loopTimers.length; i++) {
+                const time = outerRef.loopTimers[i];
+                if(Date.now() - time >= IVProgProcessor.LOOP_TIMEOUT) {
+                  outerRef.forceKill = true;
+                  return Promise.reject(ProcessorErrorFactory.endless_loop_full(cmd.sourceInfo));
+                }
+              }
+              return outerRef.executeCommand(sto, cmd);
+            });
+          } else {
+            outerRef.context.pop();
+            outerRef.loopTimers.pop();
+            return store;
+          }
+        } else {
+          return Promise.reject(ProcessorErrorFactory.loop_condition_type_full(cmd.sourceInfo));
+        }
+      })
+      
+    } catch (error) {
+      return Promise.reject(error);
+    }
+  }
+
+  executeIfThenElse (store, cmd) {
+    try {
+      const $value = this.evaluateExpression(store, cmd.condition);
+      return $value.then(vl => {
+        if(vl.type.isCompatible(Types.BOOLEAN)) {
+          if(vl.value) {
+            return this.executeCommands(store, cmd.ifTrue.commands);
+          } else if( cmd.ifFalse !== null){
+            if(cmd.ifFalse instanceof Commands.IfThenElse) {
+              return this.executeCommand(store, cmd.ifFalse);
+            } else {
+              return this.executeCommands(store, cmd.ifFalse.commands);
+            }
+          } else {
+            return Promise.resolve(store);
+          }
+        } else {
+          return Promise.reject(ProcessorErrorFactory.if_condition_type_full(cmd.sourceInfo));
+        }
+      });
+    } catch (error) {
+      return Promise.reject(error);
+    }
+  }
+
+  executeReturn (store, cmd) {
+    try {
+      const funcType = store.applyStore('$').type;
+      const $value = this.evaluateExpression(store, cmd.expression);
+      const funcName = store.name === IVProgProcessor.MAIN_INTERNAL_ID ? 
+        LanguageDefinedFunction.getMainFunctionName() : store.name;
+      return $value.then(vl => {
+
+        if(vl === null && funcType.isCompatible(Types.VOID)) {
+          return Promise.resolve(store);
+        }
+
+        if (vl === null || !funcType.isCompatible(vl.type)) {
+          const stringInfo = funcType.stringInfo();
+          const info = stringInfo[0];
+          return Promise.reject(ProcessorErrorFactory.invalid_return_type_full(funcName, info.type, info.dim, cmd.sourceInfo));
+        } else {
+          let realValue = this.parseStoreObjectValue(vl);
+          store.updateStore('$', realValue);
+          store.mode = Modes.RETURN;
+          return Promise.resolve(store);
+        }
+      });
+    } catch (error) {
+      return Promise.reject(error);
+    }
+  }
+
+  executeBreak (store, cmd) {
+    if(this.checkContext(Context.BREAKABLE)) {
+      store.mode = Modes.BREAK;
+      return Promise.resolve(store);
+    } else {
+      return Promise.reject(ProcessorErrorFactory.unexpected_break_command_full(cmd.sourceInfo));
+    }
+  }
+
+  executeAssign (store, cmd) {
+    try {
+      const $value = this.evaluateExpression(store, cmd.expression);
+      return $value.then( vl => {
+        let realValue = this.parseStoreObjectValue(vl);
+        store.updateStore(cmd.id, realValue) 
+        return store;
+      });
+    } catch (error) {
+      return Promise.reject(error);
+    }
+  }
+
+  executeArrayIndexAssign (store, cmd) {
+    const mustBeArray = store.applyStore(cmd.id);
+    if(!(mustBeArray.type instanceof CompoundType)) {
+      return Promise.reject(ProcessorErrorFactory.invalid_array_access_full(cmd.id, cmd.sourceInfo));
+    }
+    const line$ = this.evaluateExpression(store, cmd.line);
+    const column$ = this.evaluateExpression(store, cmd.column);
+    const value$ =  this.evaluateExpression(store, cmd.expression);
+    return Promise.all([line$, column$, value$]).then(results => {
+      const lineSO = results[0];
+      if(!Types.INTEGER.isCompatible(lineSO.type)) {
+        return Promise.reject(ProcessorErrorFactory.array_dimension_not_int_full(cmd.sourceInfo));
+      }
+      const line = lineSO.number;
+      const columnSO = results[1];
+      let column = null
+      if (columnSO !== null) {
+        if(!Types.INTEGER.isCompatible(columnSO.type)) {
+          return Promise.reject(ProcessorErrorFactory.array_dimension_not_int_full(cmd.sourceInfo));
+        }
+        column = columnSO.number;
+      }
+      const value = this.parseStoreObjectValue(results[2]);
+      if (line >= mustBeArray.lines) {
+        if(mustBeArray.isVector) {
+          return Promise.reject(ProcessorErrorFactory.vector_line_outbounds_full(cmd.id, line, mustBeArray.lines, cmd.sourceInfo));
+        } else {
+          return Promise.reject(ProcessorErrorFactory.matrix_line_outbounds_full(cmd.id, line, mustBeArray.lines, cmd.sourceInfo));
+        }
+      } else if (line < 0) {
+        throw ProcessorErrorFactory.array_dimension_not_positive_full(cmd.sourceInfo);
+      }
+      if (column !== null && mustBeArray.columns === null ){
+        return Promise.reject(ProcessorErrorFactory.vector_not_matrix_full(cmd.id, cmd.sourceInfo));
+      }
+      if(column !== null ) {
+        if (column >= mustBeArray.columns) {
+          return Promise.reject(ProcessorErrorFactory.matrix_column_outbounds_full(cmd.id, column,mustBeArray.columns, cmd.sourceInfo));
+        } else if (column < 0) {
+          throw ProcessorErrorFactory.array_dimension_not_positive_full(cmd.sourceInfo);
+        }
+      }
+
+      const newArray = Object.assign(new StoreObjectArray(null,null,null), mustBeArray);
+      if (column !== null) {
+        if (value.type instanceof CompoundType) {
+          const type = mustBeArray.type.innerType;
+          const stringInfo = type.stringInfo()
+          const info = stringInfo[0]
+          return Promise.reject(ProcessorErrorFactory.incompatible_types_full(info.type, info.dim, cmd.sourceInfo));
+        }
+        newArray.value[line].value[column] = value;
+        store.updateStore(cmd.id, newArray);
+      } else {
+        if(mustBeArray.columns !== null && value.type instanceof CompoundType) {
+          const type = mustBeArray.type;
+          const stringInfo = type.stringInfo()
+          const info = stringInfo[0]
+          const exp = cmd.expression.toString()
+          return Promise.reject(ProcessorErrorFactory.incompatible_types_array_full(exp,info.type, info.dim-1, cmd.sourceInfo));
+        }
+        newArray.value[line] = value;
+        store.updateStore(cmd.id, newArray);
+      }
+      return store;
+    });
+  }
+
+  executeDeclaration (store, cmd) {
+    try {
+      const $value = this.evaluateExpression(store, cmd.initial);
+      if(cmd instanceof Commands.ArrayDeclaration) {
+        const $lines = this.evaluateExpression(store, cmd.lines);
+        const $columns = cmd.columns === null ? null: this.evaluateExpression(store, cmd.columns);
+        return Promise.all([$lines, $columns, $value]).then(values => {
+          const lineSO = values[0];
+          if(!Types.INTEGER.isCompatible(lineSO.type)) {
+            return Promise.reject(ProcessorErrorFactory.array_dimension_not_int_full(cmd.sourceInfo));
+          }
+          const line = lineSO.number;
+          if(line < 0) {
+            throw ProcessorErrorFactory.array_dimension_not_positive_full(cmd.sourceInfo);
+          }
+          const columnSO = values[1];
+          let column = null
+          if (columnSO !== null) {
+            if(!Types.INTEGER.isCompatible(columnSO.type)) {
+              return Promise.reject(ProcessorErrorFactory.array_dimension_not_int_full(cmd.sourceInfo));
+            }
+            column = columnSO.number;
+            if(column < 0) {
+              throw ProcessorErrorFactory.array_dimension_not_positive_full(cmd.sourceInfo);
+            }
+          }
+          const value = values[2];
+          const temp = new StoreObjectArray(cmd.type, line, column, null);
+          store.insertStore(cmd.id, temp);
+          let realValue = value;
+          if (value !== null) {
+            if(value instanceof StoreObjectArrayAddress) {
+              if(value.type instanceof CompoundType) {
+                realValue = Object.assign(new StoreObjectArray(null,null,null), value.refValue);
+              } else {
+                realValue = Object.assign(new StoreObject(null,null), value.refValue);
+              }
+            }
+          } else {
+            realValue = new StoreObjectArray(cmd.type, line, column, [])
+            if(column !== null) {
+              for (let i = 0; i < line; i++) {
+                realValue.value.push(new StoreObjectArray(new CompoundType(cmd.type.innerType, 1), column, null, []));
+              }
+            }
+          }
+          realValue.readOnly = cmd.isConst;
+          store.updateStore(cmd.id, realValue);
+          return store;
+        });
+        
+      } else {
+        const temp = new StoreObject(cmd.type, null);
+        store.insertStore(cmd.id, temp);
+        return $value.then(vl => {
+          let realValue = vl;
+          if (vl !== null) {
+            if(vl instanceof StoreObjectArrayAddress) {
+              if(vl.type instanceof CompoundType) {
+                realValue = Object.assign(new StoreObjectArray(null,null,null), vl.refValue);
+              } else {
+                realValue = Object.assign(new StoreObject(null,null), vl.refValue);
+              }
+            }
+          } else {
+            realValue = new StoreObject(cmd.type,0);
+          }
+          realValue.readOnly = cmd.isConst;
+          store.updateStore(cmd.id, realValue);
+          return store;
+        });
+      }
+    } catch (e) {
+      return Promise.reject(e);
+    }
+  }
+
+   evaluateExpression (store, exp) {
+
+    if (exp instanceof Expressions.UnaryApp) {
+      return this.evaluateUnaryApp(store, exp);
+    } else if (exp instanceof Expressions.InfixApp) {
+      return this.evaluateInfixApp(store, exp);
+    } else if (exp instanceof Expressions.ArrayAccess) {
+      return this.evaluateArrayAccess(store, exp);
+    } else if (exp instanceof Expressions.VariableLiteral) {
+      return this.evaluateVariableLiteral(store, exp);
+    } else if (exp instanceof Expressions.IntLiteral) {
+      return this.evaluateLiteral(store, exp);
+    } else if (exp instanceof Expressions.RealLiteral) {
+      return this.evaluateLiteral(store, exp);
+    } else if (exp instanceof Expressions.BoolLiteral) {
+      return this.evaluateLiteral(store, exp);
+    } else if (exp instanceof Expressions.StringLiteral) {
+      return this.evaluateLiteral(store, exp);
+    } else if (exp instanceof Expressions.ArrayLiteral) {
+      return this.evaluateArrayLiteral(store, exp);
+    } else if (exp instanceof Expressions.FunctionCall) {
+      return this.evaluateFunctionCall(store, exp);
+    }
+    return Promise.resolve(null);
+  }
+
+  evaluateFunctionCall (store, exp) {
+    if(exp.isMainCall) {
+      return Promise.reject(ProcessorErrorFactory.void_in_expression_full(LanguageDefinedFunction.getMainFunctionName(), exp.sourceInfo));
+    }
+    const func = this.findFunction(exp.id);
+    if(Types.VOID.isCompatible(func.returnType)) {
+      // TODO: better error message
+      return Promise.reject(ProcessorErrorFactory.void_in_expression_full(exp.id, exp.sourceInfo));
+    }
+    const $newStore = this.runFunction(func, exp.actualParameters, store);
+    return $newStore.then( sto => {
+      if(sto.mode !== Modes.RETURN) {
+        return Promise.reject(new Error("The function that was called did not had a return command: "+exp.id));
+      }
+      const val = sto.applyStore('$');
+      if (val instanceof StoreObjectArray) {
+        return Promise.resolve(Object.assign(new StoreObjectArray(null,null,null,null,null), val));
+      } else {
+        return Promise.resolve(Object.assign(new StoreObject(null,null), val));
+      }
+    });
+  }
+
+  evaluateArrayLiteral (store, exp) {
+    const errorHelperFunction = (validationResult, exp) => {
+      const errorCode = validationResult[0];
+      switch(errorCode) {
+        case StoreObjectArray.WRONG_COLUMN_NUMBER: {
+          const columnValue = validationResult[1];
+          return Promise.reject(ProcessorErrorFactory.invalid_array_literal_column_full(arr.columns, columnValue, exp.sourceInfo));
+        }
+        case StoreObjectArray.WRONG_LINE_NUMBER: {
+          const lineValue = validationResult[1];
+          return Promise.reject(ProcessorErrorFactory.invalid_array_literal_line_full(arr.lines, lineValue, exp.sourceInfo));
+        }
+        case StoreObjectArray.WRONG_TYPE: {
+          let line = null;
+          let strExp = null;
+          if (validationResult.length > 2) {
+            line = validationResult[1];
+            const column = validationResult[2];
+            strExp = exp.value[line].value[column].toString()
+          } else {
+            line = validationResult[1];
+            strExp = exp.value[line].toString()
+          }
+          return Promise.reject(ProcessorErrorFactory.invalid_array_literal_type_full(strExp, exp.sourceInfo));            }
+      }
+    };
+    if(!exp.isVector) {
+      const $matrix = this.evaluateMatrix(store, exp.value);
+      return $matrix.then(list => {
+        const type = new CompoundType(list[0].type.innerType, 2);
+        const arr = new StoreObjectArray(type, list.length, list[0].lines, list);
+        const checkResult = arr.isValid;
+        if(checkResult.length == 0)
+          return Promise.resolve(arr);
+        else {
+          return errorHelperFunction(checkResult, exp);
+        }
+      });
+    } else {
+      return this.evaluateVector(store, exp.value).then(list => {
+        const type = new CompoundType(list[0].type, 1);
+        const stoArray = new StoreObjectArray(type, list.length, null, list);
+        const checkResult = stoArray.isValid;
+        if(checkResult.length == 0)
+          return Promise.resolve(stoArray);
+        else {
+          return errorHelperFunction(checkResult, exp);
+        }
+      });
+    }
+  }
+
+  evaluateVector (store, exps) {
+    return Promise.all(exps.map( exp => this.evaluateExpression(store, exp)));
+  }
+
+  evaluateMatrix (store, exps) {
+    return Promise.all(exps.map( vector => {
+      const $vector = this.evaluateVector(store, vector.value)
+      return $vector.then(list => {
+        const type = new CompoundType(list[0].type, 1);
+        return new StoreObjectArray(type, list.length, null, list)
+      });
+    } ));
+  }
+
+  evaluateLiteral (_, exp) {
+    return Promise.resolve(new StoreObject(exp.type, exp.value));
+  }
+
+  evaluateVariableLiteral (store, exp) {
+    try {
+      const val = store.applyStore(exp.id);
+      if (val instanceof StoreObjectArray) {
+        return Promise.resolve(Object.assign(new StoreObjectArray(null,null,null,null), val));
+      } else {
+        return Promise.resolve(Object.assign(new StoreObject(null,null), val));
+      }
+    } catch (error) {
+      return Promise.reject(error);
+    }
+  }
+
+  evaluateArrayAccess (store, exp) {
+    const mustBeArray = store.applyStore(exp.id);
+    if (!(mustBeArray.type instanceof CompoundType)) {
+      return Promise.reject(ProcessorErrorFactory.invalid_array_access_full(exp.id, exp.sourceInfo));
+    }
+    const $line = this.evaluateExpression(store, exp.line);
+    const $column = this.evaluateExpression(store, exp.column);
+    return Promise.all([$line, $column]).then(values => {
+      const lineSO = values[0];
+      const columnSO = values[1];
+      if(!Types.INTEGER.isCompatible(lineSO.type)) {
+        return Promise.reject(ProcessorErrorFactory.array_dimension_not_int_full(exp.sourceInfo));
+      }
+      const line = lineSO.number;
+      let column = null;
+      if(columnSO !== null) {
+        if(!Types.INTEGER.isCompatible(columnSO.type)) {
+          return Promise.reject(ProcessorErrorFactory.array_dimension_not_int_full(exp.sourceInfo));
+        }
+        column = columnSO.number;
+      }
+
+      if (line >= mustBeArray.lines) {
+        if(mustBeArray.isVector) {
+          return Promise.reject(ProcessorErrorFactory.vector_line_outbounds_full(exp.id, line, mustBeArray.lines, exp.sourceInfo));
+        } else {
+          return Promise.reject(ProcessorErrorFactory.matrix_line_outbounds_full(exp.id, line, mustBeArray.lines, exp.sourceInfo));
+        }
+      } else if (line < 0) {
+        throw ProcessorErrorFactory.array_dimension_not_positive_full(exp.sourceInfo);
+      }
+      if (column !== null && mustBeArray.columns === null ){
+        return Promise.reject(ProcessorErrorFactory.vector_not_matrix_full(exp.id, exp.sourceInfo));
+      }
+      if(column !== null ) {
+        if (column >= mustBeArray.columns) {
+          return Promise.reject(ProcessorErrorFactory.matrix_column_outbounds_full(exp.id, column,mustBeArray.columns, exp.sourceInfo));
+        } else if (column < 0) {
+          throw ProcessorErrorFactory.array_dimension_not_positive_full(exp.sourceInfo);
+        }
+        
+      }
+      return Promise.resolve(new StoreObjectArrayAddress(mustBeArray.id, line, column, store));
+    });
+  }
+
+  evaluateUnaryApp (store, unaryApp) {
+    const $left = this.evaluateExpression(store, unaryApp.left);
+    return $left.then( left => {
+      const resultType = resultTypeAfterUnaryOp(unaryApp.op, left.type);
+      if (Types.UNDEFINED.isCompatible(resultType)) {
+        const stringInfo = left.type.stringInfo();
+        const info = stringInfo[0];
+        return Promise.reject(ProcessorErrorFactory.invalid_unary_op_full(unaryApp.op, info.type, info.dim, unaryApp.sourceInfo));
+      }
+      switch (unaryApp.op.ord) {
+        case Operators.ADD.ord:
+          return new StoreObject(resultType, left.value);
+        case Operators.SUB.ord:
+          return new StoreObject(resultType, left.value.negated());
+        case Operators.NOT.ord:
+          return new StoreObject(resultType, !left.value);
+        default:
+          return Promise.reject(new RuntimeError('!!!Critical Invalid UnaryApp '+ unaryApp.op));
+      }
+    });
+  }
+
+  evaluateInfixApp (store, infixApp) {
+    const $left = this.evaluateExpression(store, infixApp.left);
+    const $right = this.evaluateExpression(store, infixApp.right);
+    return Promise.all([$left, $right]).then(values => {
+      const left = values[0];
+      const right = values[1];
+      const resultType = resultTypeAfterInfixOp(infixApp.op, left.type, right.type);
+      if (Types.UNDEFINED.isCompatible(resultType)) {
+        const stringInfoLeft = left.type.stringInfo();
+        const infoLeft = stringInfoLeft[0];
+        const stringInfoRight = right.type.stringInfo();
+        const infoRight = stringInfoRight[0];
+        return Promise.reject(ProcessorErrorFactory.invalid_infix_op_full(infixApp.op, infoLeft.type, infoLeft.dim,
+          infoRight.type,infoRight.dim,infixApp.sourceInfo));
+      }
+      let result = null;
+      switch (infixApp.op.ord) {
+        case Operators.ADD.ord: {
+          if(Types.STRING.isCompatible(left.type)) {
+            const rightStr = convertToString(right.value, right.type);
+            return new StoreObject(resultType, left.value + rightStr);
+          } else if (Types.STRING.isCompatible(right.type)) {
+            const leftStr = convertToString(left.value, left.type);
+            return new StoreObject(resultType, leftStr + right.value);
+          } else {
+            return new StoreObject(resultType, left.value.plus(right.value));
+          }
+        }
+        case Operators.SUB.ord:
+          return new StoreObject(resultType, left.value.minus(right.value));
+        case Operators.MULT.ord: {
+          result = left.value.times(right.value);
+          if(result.dp() > Config.decimalPlaces) {
+            result = new Decimal(result.toFixed(Config.decimalPlaces));
+          }
+          return new StoreObject(resultType, result);
+        }
+        case Operators.DIV.ord: {
+          if (Types.INTEGER.isCompatible(resultType))
+            result = left.value.divToInt(right.value);
+          else
+            result = left.value.div(right.value);
+          if(result.dp() > Config.decimalPlaces) {
+            result = new Decimal(result.toFixed(Config.decimalPlaces));
+          }
+          return new StoreObject(resultType, result);
+        }
+        case Operators.MOD.ord: {
+          result = left.value.modulo(right.value);
+          if(result.dp() > Config.decimalPlaces) {
+            result = new Decimal(result.toFixed(Config.decimalPlaces));
+          }
+          return new StoreObject(resultType, result);
+        }          
+        case Operators.GT.ord: {
+          if (Types.STRING.isCompatible(left.type)) {
+            result = left.value.length > right.value.length;
+          } else {
+            result = left.value.gt(right.value);
+          }
+          return new StoreObject(resultType, result);
+        }
+        case Operators.GE.ord: {
+          if (Types.STRING.isCompatible(left.type)) {
+            result = left.value.length >= right.value.length;
+          } else {
+            result = left.value.gte(right.value);
+          }
+          return new StoreObject(resultType, result);
+        }
+        case Operators.LT.ord: {
+          if (Types.STRING.isCompatible(left.type)) {
+            result = left.value.length < right.value.length;
+          } else {
+            result = left.value.lt(right.value);
+          }
+          return new StoreObject(resultType, result);
+        }
+        case Operators.LE.ord: {
+          if (Types.STRING.isCompatible(left.type)) {
+            result = left.value.length <= right.value.length;
+          } else {
+            result = left.value.lte(right.value);
+          }
+          return new StoreObject(resultType, result);
+        }
+        case Operators.EQ.ord: {
+          if (Types.INTEGER.isCompatible(left.type) || Types.REAL.isCompatible(left.type)) {
+            result = left.value.eq(right.value);
+          } else {
+            result = left.value === right.value;
+          }
+          return new StoreObject(resultType, result);
+        }
+        case Operators.NEQ.ord: {
+          if (Types.INTEGER.isCompatible(left.type) || Types.REAL.isCompatible(left.type)) {
+            result = !left.value.eq(right.value);
+          } else {
+            result = left.value !== right.value;
+          }
+          return new StoreObject(resultType, result);
+        }
+        case Operators.AND.ord:
+          return new StoreObject(resultType, left.value && right.value);
+        case Operators.OR.ord:
+          return new StoreObject(resultType, left.value || right.value);
+        default:
+          return Promise.reject(new RuntimeError('!!!Critical Invalid InfixApp '+ infixApp.op));
+      }
+    });
+  }
+
+  parseStoreObjectValue (vl) {
+    let realValue = vl;
+    if(vl instanceof StoreObjectArrayAddress) {      
+      if(vl.type instanceof CompoundType) {
+        switch(vl.type.dimensions) {
+          case 1: {
+            realValue = new StoreObjectArray(vl.type, vl.value);
+            break;
+          }
+          default: {
+            throw new RuntimeError("Three dimensional array address...");
+          }
+        }
+      } else {
+        realValue = new StoreObject(vl.type, vl.value);
+      }
+    }
+    return realValue;
+  }
+
+}

+ 58 - 0
ivprogh/js/processor/lib/arrays.js

@@ -0,0 +1,58 @@
+import { StoreObject } from '../store/storeObject';
+import * as Commands from './../../ast/commands';
+import { Types } from './../../typeSystem/types';
+import { toInt } from "./../../typeSystem/parsers";
+import { CompoundType } from '../../typeSystem/compoundType';
+import { Modes } from '../modes';
+
+/**
+ * num_elements
+ * matrix_lines
+ * matrix_columns
+ */
+
+export function createNumElementsFun () {
+  const numElementsFun = (sto, _) => {
+    const vector  = sto.applyStore("vector");
+    const temp = new StoreObject(Types.INTEGER, toInt(vector.lines));
+    sto.mode = Modes.RETURN;
+    return Promise.resolve(sto.updateStore("$", temp));
+  }
+
+  const block = new Commands.CommandBlock([],  [new Commands.SysCall(numElementsFun)]);
+  const func = new Commands.Function('$numElements', Types.INTEGER,
+    [new Commands.FormalParameter(new CompoundType(Types.ALL, 1), 'vector', false)],
+    block);
+  return func;
+ }
+
+export function createMatrixLinesFun () {
+  const matrixLinesFun = (sto, _) => {
+    const matrix  = sto.applyStore("matrix");
+    const temp = new StoreObject(Types.INTEGER, toInt(matrix.lines));
+    sto.mode = Modes.RETURN;
+    return Promise.resolve(sto.updateStore("$", temp));
+  }
+
+  const block = new Commands.CommandBlock([],  [new Commands.SysCall(matrixLinesFun)]);
+  const func = new Commands.Function('$matrixLines', Types.INTEGER,
+    [new Commands.FormalParameter(new CompoundType(Types.ALL, 2), 'matrix', false)],
+    block);
+  return func;
+ }
+
+export function createMatrixColumnsFun () {
+  const matrixColumnsFun = (sto, _) => {
+    const matrix  = sto.applyStore("matrix");
+    const temp = new StoreObject(Types.INTEGER, toInt(matrix.columns));
+    sto.mode = Modes.RETURN;
+    return Promise.resolve(sto.updateStore("$", temp));
+  }
+
+  const block = new Commands.CommandBlock([],  [new Commands.SysCall(matrixColumnsFun)]);
+  const func = new Commands.Function('$matrixColumns', Types.INTEGER,
+    [new Commands.FormalParameter(new CompoundType(Types.ALL, 2), 'matrix', false)],
+    block);
+  return func;
+ }
+ 

+ 57 - 0
ivprogh/js/processor/lib/io.js

@@ -0,0 +1,57 @@
+import { StoreObject } from './../store/storeObject';
+import * as Commands from './../../ast/commands';
+import {toInt, toString, toBool, toReal} from './../../typeSystem/parsers';
+import { Types } from './../../typeSystem/types';
+
+export function createOutputFun () {
+  const writeFunction = function (store, _) {
+    const val = store.applyStore('p1');
+    if(val.type.isCompatible(Types.INTEGER)) {
+      this.output.sendOutput(val.value.toString());
+    } else if (val.type.isCompatible(Types.REAL)) {
+      if (val.value.dp() <= 0) {
+        this.output.sendOutput(val.value.toFixed(1));  
+      } else {
+        this.output.sendOutput(val.value.toString());
+      }
+    } else {
+      this.output.sendOutput(val.value);
+    }
+    return Promise.resolve(store);
+  }
+  const block = new Commands.CommandBlock([], [new Commands.SysCall(writeFunction)]);
+  const func = new Commands.Function('$write', Types.VOID,
+    [new Commands.FormalParameter(Types.ALL, 'p1', false)],
+    block);
+  return func;
+}
+
+export function createInputFun () {
+  const readFunction = function (store, _) {
+    const request = new Promise((resolve, _) => {
+      this.input.requestInput(resolve);
+    });
+    return request.then(text => {
+      const typeToConvert = store.applyStore('p1').type;
+      let stoObj = null;
+      if (typeToConvert.isCompatible(Types.INTEGER)) {
+        const val = toInt(text);
+        stoObj = new StoreObject(Types.INTEGER, val);
+      } else if (typeToConvert.isCompatible(Types.REAL)) {
+        stoObj = new StoreObject(Types.REAL, toReal(text));
+      } else if (typeToConvert.isCompatible(Types.BOOLEAN)) {
+        stoObj = new StoreObject(Types.BOOLEAN, toBool(text));
+      } else if (typeToConvert.isCompatible(Types.STRING)) {
+        stoObj = new StoreObject(Types.STRING, toString(text));
+      }
+      this.loopTimers.splice(0,this.loopTimers.length)
+      store.updateStore('p1', stoObj);
+      return Promise.resolve(store);
+    });
+  }
+  const block = new Commands.CommandBlock([],  [new Commands.SysCall(readFunction)]);
+  const func = new Commands.Function('$read', Types.VOID,
+    [new Commands.FormalParameter(Types.ALL, 'p1', true)],
+    block);
+  return func;
+}

+ 188 - 0
ivprogh/js/processor/lib/lang.js

@@ -0,0 +1,188 @@
+import { StoreObject } from '../store/storeObject';
+import * as Commands from './../../ast/commands';
+import { Types } from './../../typeSystem/types';
+import { toReal, convertToString } from "./../../typeSystem/parsers";
+import { IVProgParser } from '../../ast/ivprogParser';
+import { RealLiteral, IntLiteral, BoolLiteral } from '../../ast/expressions';
+import { Modes } from '../modes';
+
+/**
+ * 
+ * is_real
+ * is_int
+ * is_bool
+ * cast_real
+ * cast_int
+ * cast_bool
+ * cast_string
+ */
+
+export function createIsRealFun () {
+  const isRealFun = (sto, _) => {
+    const str = sto.applyStore("str");
+    const parser = IVProgParser.createParser(str.value);
+    let result = false;
+    try {
+      const val = parser.parseTerm();
+      if (val instanceof RealLiteral) {
+        result = true;
+      }
+    } catch (error) { }
+    const temp = new StoreObject(Types.BOOLEAN, result);
+    sto.mode = Modes.RETURN;
+    return Promise.resolve(sto.updateStore("$", temp));
+  }
+
+  const block = new Commands.CommandBlock([],  [new Commands.SysCall(isRealFun)]);
+  const func = new Commands.Function('$isReal', Types.BOOLEAN,
+    [new Commands.FormalParameter(Types.STRING, 'str', false)],
+    block);
+  return func;
+}
+
+export function createIsIntFun () {
+  const isIntFun = (sto, _) => {
+    const str = sto.applyStore("str");
+    const parser = IVProgParser.createParser(str.value);
+    let result = false;
+    try {
+      const val = parser.parseTerm();
+      if (val instanceof IntLiteral) {
+        result = true;
+      }
+    } catch (error) { }
+    const temp = new StoreObject(Types.BOOLEAN, result);
+    sto.mode = Modes.RETURN;
+    return Promise.resolve(sto.updateStore("$", temp));
+  }
+
+  const block = new Commands.CommandBlock([],  [new Commands.SysCall(isIntFun)]);
+  const func = new Commands.Function('$isInt', Types.BOOLEAN,
+    [new Commands.FormalParameter(Types.STRING, 'str', false)],
+    block);
+  return func;
+}
+
+export function createIsBoolFun () {
+  const isBoolFun = (sto, _) => {
+    const str = sto.applyStore("str");
+    const parser = IVProgParser.createParser(str.value);
+    let result = false;
+    try {
+      const val = parser.parseTerm();
+      if (val instanceof BoolLiteral) {
+        result = true;
+      }
+    } catch (error) { }
+    const temp = new StoreObject(Types.BOOLEAN, result);
+    sto.mode = Modes.RETURN;
+    return Promise.resolve(sto.updateStore("$", temp));
+  }
+
+  const block = new Commands.CommandBlock([],  [new Commands.SysCall(isBoolFun)]);
+  const func = new Commands.Function('$isBool', Types.BOOLEAN,
+    [new Commands.FormalParameter(Types.STRING, 'str', false)],
+    block);
+  return func;
+}
+
+export function createCastRealFun () {
+  const castRealFun = (sto, _) => {
+    const val = sto.applyStore("val");
+    switch (val.type.ord) {
+      case Types.INTEGER.ord: {
+        const temp = new StoreObject(Types.REAL, toReal(val.number));
+        sto.mode = Modes.RETURN;
+        return Promise.resolve(sto.updateStore("$", temp));
+      }
+      case Types.STRING.ord: {
+        const parser = IVProgParser.createParser(val.value);
+        try {
+          const result = parser.parseTerm();
+          if (result instanceof RealLiteral) {
+            const temp = new StoreObject(Types.REAL, result.value);
+            sto.mode = Modes.RETURN;
+            return Promise.resolve(sto.updateStore("$", temp));
+          }
+        } catch (error) { 
+          return Promise.reject("cannot convert string to real");
+        }
+      }
+    }
+  }
+
+  const block = new Commands.CommandBlock([],  [new Commands.SysCall(castRealFun)]);
+  const func = new Commands.Function('$castReal', Types.REAL,
+    [new Commands.FormalParameter(Types.ALL, 'val', false)],
+    block);
+  return func;
+}
+
+export function createCastIntFun () {
+  const castIntFun = (sto, _) => {
+    const val = sto.applyStore("val");
+    switch (val.type.ord) {
+      case Types.REAL.ord: {
+        const temp = new StoreObject(Types.INTEGER, Math.floor(val.number));
+        sto.mode = Modes.RETURN;
+        return Promise.resolve(sto.updateStore("$", temp));
+      }
+      case Types.STRING.ord: {
+        const parser = IVProgParser.createParser(val.value);
+        try {
+          const result = parser.parseTerm();
+          if (result instanceof IntLiteral) {
+            const temp = new StoreObject(Types.INTEGER, result.value);
+            sto.mode = Modes.RETURN;
+            return Promise.resolve(sto.updateStore("$", temp));
+          }
+        } catch (error) { 
+          return Promise.reject("cannot convert string to real");
+        }
+      }
+    }
+  }
+
+  const block = new Commands.CommandBlock([],  [new Commands.SysCall(castIntFun)]);
+  const func = new Commands.Function('$castInt', Types.INTEGER,
+    [new Commands.FormalParameter(Types.ALL, 'val', false)],
+    block);
+  return func;
+}
+
+export function createCastBoolFun () {
+  const castBoolFun = (sto, _) => {
+    const str = sto.applyStore("str");
+    const parser = IVProgParser.createParser(str.value);
+    try {
+      const val = parser.parseTerm();
+      if (val instanceof BoolLiteral) {
+        const temp = new StoreObject(Types.BOOLEAN, val.value);
+        sto.mode = Modes.RETURN;
+        return Promise.resolve(sto.updateStore("$", temp));
+      }
+    } catch (error) { }
+    return Promise.reject("cannot convert " + str.value + " to boolean");
+  }
+
+  const block = new Commands.CommandBlock([],  [new Commands.SysCall(castBoolFun)]);
+  const func = new Commands.Function('$castBool', Types.BOOLEAN,
+    [new Commands.FormalParameter(Types.STRING, 'str', false)],
+    block);
+  return func;
+}
+
+export function createCastStringFun () {
+  const castStringFun = function (store, _) {
+    const val = store.applyStore('str');
+    let result = convertToString(val)
+    const temp = new StoreObject(Types.STRING, result);
+    sto.mode = Modes.RETURN;
+    return Promise.resolve(sto.updateStore("$", temp));
+  }
+  const block = new Commands.CommandBlock([], [new Commands.SysCall(castStringFun)]);
+  const func = new Commands.Function('$castString', Types.STRING,
+    [new Commands.FormalParameter(Types.ALL, 'str', false)],
+    block);
+  return func;
+}

+ 254 - 0
ivprogh/js/processor/lib/math.js

@@ -0,0 +1,254 @@
+import { StoreObject } from '../store/storeObject';
+import * as Commands from './../../ast/commands';
+import { Types } from './../../typeSystem/types';
+import { toReal } from "./../../typeSystem/parsers";
+import { Decimal } from 'decimal.js';
+import { MultiType } from '../../typeSystem/multiType';
+import { CompoundType } from '../../typeSystem/compoundType';
+import { Modes } from '../modes';
+import { Config } from '../../util/config';
+
+/**
+ * sin
+ * cos
+ * tan
+ * sqrt
+ * pow
+ * log
+ * abs
+ * negate
+ * invert
+ * max
+ * min
+ */
+
+function convertToRadians (degrees) {
+  return degrees.times(Decimal.acos(-1)).div(180);
+}
+
+export function createSinFun () {
+   const sinFun = (sto, _) => {
+     const x = sto.applyStore('x');
+     const angle = x.value.mod(360);
+     let result = null;
+     if(angle.eq(90)) {
+       result = new Decimal(1);
+     } else if (angle.eq(180)) {
+      result = new Decimal(0);
+     } else if (angle.eq(270)) {
+       result = new Decimal(-1);
+     } else {
+       result = Decimal.sin(convertToRadians(angle));
+     }
+     if(result.dp() > Config.decimalPlaces) {
+      result = new Decimal(result.toFixed(Config.decimalPlaces));
+    }
+     const temp = new StoreObject(Types.REAL, result);
+     sto.mode = Modes.RETURN;
+     return Promise.resolve(sto.updateStore('$', temp));
+   };
+
+  const block = new Commands.CommandBlock([],  [new Commands.SysCall(sinFun)]);
+  const func = new Commands.Function('$sin', Types.REAL,
+    [new Commands.FormalParameter(new MultiType([Types.INTEGER, Types.REAL]), 'x', false)],
+    block);
+  return func;
+}
+
+export function createCosFun () {
+  const cosFun = (sto, _) => {
+    const x = sto.applyStore('x');
+    const angle = x.value.mod(360);
+    let result = null;
+    if(angle.eq(90)) {
+      result = new Decimal(0);
+    } else if (angle.eq(180)) {
+      result = new Decimal(-1);
+    } else if (angle.eq(270)) {
+      result = new Decimal(0)
+    }
+    result = Decimal.cos(convertToRadians(angle));
+    if(result.dp() > Config.decimalPlaces) {
+      result = new Decimal(result.toFixed(Config.decimalPlaces));
+    }
+    const temp = new StoreObject(Types.REAL, result);
+    sto.mode = Modes.RETURN;
+    return Promise.resolve(sto.updateStore('$', temp));
+  };
+
+ const block = new Commands.CommandBlock([],  [new Commands.SysCall(cosFun)]);
+ const func = new Commands.Function('$cos', Types.REAL,
+   [new Commands.FormalParameter(new MultiType([Types.INTEGER, Types.REAL]), 'x', false)],
+   block);
+ return func;
+}
+
+export function createTanFun () {
+  const tanFun = (sto, _) => {
+    const x = sto.applyStore('x');
+    const angle = x.value.mod(360);
+    if(angle.eq(90) || angle.eq(270)) {
+      return Promise.reject("Tangent of "+x.value.toNumber()+"° is undefined.");
+    }
+    let result = Decimal.tan(convertToRadians(angle));
+    if(result.dp() > Config.decimalPlaces) {
+      result = new Decimal(result.toFixed(Config.decimalPlaces));
+    }
+    const temp = new StoreObject(Types.REAL, result);
+    sto.mode = Modes.RETURN;
+    return Promise.resolve(sto.updateStore('$', temp));
+  };
+
+ const block = new Commands.CommandBlock([],  [new Commands.SysCall(tanFun)]);
+ const func = new Commands.Function('$tan', Types.REAL,
+   [new Commands.FormalParameter(new MultiType([Types.INTEGER, Types.REAL]), 'x', false)],
+   block);
+ return func;
+}
+
+export function createSqrtFun () {
+  const sqrtFun = (sto, _) => {
+    const x = sto.applyStore('x');
+    let result = x.value.sqrt();
+    if(result.dp() > Config.decimalPlaces) {
+      result = new Decimal(result.toFixed(Config.decimalPlaces));
+    }
+    const temp = new StoreObject(Types.REAL, result);
+    sto.mode = Modes.RETURN;
+    return Promise.resolve(sto.updateStore('$', temp));
+  };
+
+ const block = new Commands.CommandBlock([],  [new Commands.SysCall(sqrtFun)]);
+ const func = new Commands.Function('$sqrt', Types.REAL,
+   [new Commands.FormalParameter(new MultiType([Types.INTEGER, Types.REAL]), 'x', false)],
+   block);
+ return func;
+}
+
+export function createPowFun () {
+  const powFun = (sto, _) => {
+    const x = sto.applyStore('x');
+    const y = sto.applyStore('y');
+    let result = x.value.pow(y.value);
+    if(result.dp() > Config.decimalPlaces) {
+      result = new Decimal(result.toFixed(Config.decimalPlaces));
+    }
+    const temp = new StoreObject(Types.REAL, result);
+    sto.mode = Modes.RETURN;
+    return Promise.resolve(sto.updateStore('$', temp));
+  };
+
+ const block = new Commands.CommandBlock([],  [new Commands.SysCall(powFun)]);
+ const func = new Commands.Function('$pow', Types.REAL,
+   [new Commands.FormalParameter(new MultiType([Types.INTEGER, Types.REAL]), 'x', false),
+    new Commands.FormalParameter(new MultiType([Types.INTEGER, Types.REAL]), 'y', false)],
+   block);
+ return func;
+}
+
+export function createLogFun () {
+  const logFun = (sto, _) => {
+    const x = sto.applyStore('x');
+    if (x.value.isNegative()) {
+      return Promise.reject("the value passed to log function cannot be negative");
+    }
+    let result = Decimal.log10(x.value);
+    if(result.dp() > Config.decimalPlaces) {
+      result = new Decimal(result.toFixed(Config.decimalPlaces));
+    }
+    const temp = new StoreObject(Types.REAL, result);
+    sto.mode = Modes.RETURN;
+    return Promise.resolve(sto.updateStore('$', temp));
+  };
+
+ const block = new Commands.CommandBlock([],  [new Commands.SysCall(logFun)]);
+ const func = new Commands.Function('$log', Types.REAL,
+   [new Commands.FormalParameter(new MultiType([Types.INTEGER, Types.REAL]), 'x', false)],
+   block);
+ return func;
+}
+
+export function createAbsFun () {
+  const absFun = (sto, _) => {
+    const x = sto.applyStore('x');
+    const result = x.value.abs();
+    const temp = new StoreObject(x.type, result);
+    sto.mode = Modes.RETURN;
+    return Promise.resolve(sto.updateStore('$', temp));
+  };
+
+ const block = new Commands.CommandBlock([],  [new Commands.SysCall(absFun)]);
+ const func = new Commands.Function('$abs', new MultiType([Types.INTEGER, Types.REAL]),
+   [new Commands.FormalParameter(new MultiType([Types.INTEGER, Types.REAL]), 'x', false)],
+   block);
+ return func;
+}
+
+export function createNegateFun () {
+  const negateFun = (sto, _) => {
+    const x = sto.applyStore('x');
+    const result = x.value.negated();
+    const temp = new StoreObject(x.type, result);
+    sto.mode = Modes.RETURN;
+    return Promise.resolve(sto.updateStore('$', temp));
+  };
+
+ const block = new Commands.CommandBlock([],  [new Commands.SysCall(negateFun)]);
+ const func = new Commands.Function('$negate', new MultiType([Types.INTEGER, Types.REAL]),
+   [new Commands.FormalParameter(new MultiType([Types.INTEGER, Types.REAL]), 'x', false)],
+   block);
+ return func;
+}
+
+export function createInvertFun () {
+  const invertFun = (sto, _) => {
+    const x = sto.applyStore('x');
+    let result = toReal(1).dividedBy(x.value);
+    if(result.dp() > Config.decimalPlaces) {
+      result = new Decimal(result.toFixed(Config.decimalPlaces));
+    }
+    const temp = new StoreObject(Types.REAL, result);
+    sto.mode = Modes.RETURN;
+    return Promise.resolve(sto.updateStore('$', temp));
+  };
+
+ const block = new Commands.CommandBlock([],  [new Commands.SysCall(invertFun)]);
+ const func = new Commands.Function('$invert', Types.REAL,
+   [new Commands.FormalParameter(new MultiType([Types.INTEGER, Types.REAL]), 'x', false)],
+   block);
+ return func;
+}
+
+export function createMaxFun () {
+  const maxFun = (sto, _) => {
+    const x = sto.applyStore('x');
+    const numbers = x.value.map(stoObj => stoObj.value);
+    const result = Decimal.max(...numbers);
+    const temp = new StoreObject(x.type.innerType, result);
+    sto.mode = Modes.RETURN;
+    return Promise.resolve(sto.updateStore('$', temp));
+  };
+ const paramType = new CompoundType(new MultiType([Types.INTEGER, Types.REAL]), 1);
+ const block = new Commands.CommandBlock([],  [new Commands.SysCall(maxFun)]);
+ const func = new Commands.Function('$max', new MultiType([Types.INTEGER, Types.REAL]),
+   [new Commands.FormalParameter(paramType, 'x', false)],
+   block);
+ return func;
+}
+
+export function createMinFun () {
+  const minFun = (sto, _) => {
+    const x = sto.applyStore('x');
+    const numbers = x.value.map(stoObj => stoObj.value);
+    const result = Decimal.min(...numbers);
+    const temp = new StoreObject(x.type.innerType, result);
+    sto.mode = Modes.RETURN;
+    return Promise.resolve(sto.updateStore('$', temp));
+  };
+ const paramType = new CompoundType(new MultiType([Types.INTEGER, Types.REAL]), 1);
+ const block = new Commands.CommandBlock([],  [new Commands.SysCall(minFun)]);
+ const func = new Commands.Function('$min', new MultiType([Types.INTEGER, Types.REAL]),
+   [new Commands.FormalParameter(paramType, 'x', false)],
+   block);
+ return func;
+}

+ 94 - 0
ivprogh/js/processor/lib/strings.js

@@ -0,0 +1,94 @@
+import { StoreObject } from '../store/storeObject';
+import * as Commands from './../../ast/commands';
+import { Types } from './../../typeSystem/types';
+import { toInt } from "./../../typeSystem/parsers";
+import { Modes } from '../modes';
+
+/*
+*  substring
+*  length
+*  uppercase
+*  lowercase
+*  charAt
+**/
+
+export function createSubstringFun () {
+  const substringFun = (sto, _) => {
+    const str = sto.applyStore("str");
+    const start = sto.applyStore("start");
+    const end = sto.applyStore("end");
+    const result = str.value.substring(start.value, end.value);
+    const temp = new StoreObject(Types.STRING, result);
+    sto.mode = Modes.RETURN;
+    return Promise.resolve(sto.updateStore("$", temp));
+  };
+
+  const block = new Commands.CommandBlock([],  [new Commands.SysCall(substringFun)]);
+  const func = new Commands.Function('$substring', Types.STRING,
+    [new Commands.FormalParameter(Types.STRING, 'str', false),
+    new Commands.FormalParameter(Types.INTEGER, 'start', false),
+    new Commands.FormalParameter(Types.INTEGER, 'end', false)],
+    block);
+  return func;
+}
+
+export function createLengthFun () {
+  const lengthFun = (sto, _) => {
+    const str = sto.applyStore("str");
+    const temp = new StoreObject(Types.INTEGER, toInt(str.value.length));
+    sto.mode = Modes.RETURN;
+    return Promise.resolve(sto.updateStore("$", temp));
+  }
+  const block = new Commands.CommandBlock([],  [new Commands.SysCall(lengthFun)]);
+  const func = new Commands.Function('$length', Types.INTEGER,
+    [new Commands.FormalParameter(Types.STRING, 'str', false)],
+    block);
+  return func;
+}
+
+export function createUppercaseFun () {
+  const uppercaseFun = (sto, _) => {
+    const str = sto.applyStore("str");
+    const temp = new StoreObject(Types.STRING, str.value.toUpperCase());
+    sto.mode = Modes.RETURN;
+    return Promise.resolve(sto.updateStore("$", temp));
+  }
+  const block = new Commands.CommandBlock([],  [new Commands.SysCall(uppercaseFun)]);
+  const func = new Commands.Function('$uppercase', Types.STRING,
+    [new Commands.FormalParameter(Types.STRING, 'str', false)],
+    block);
+  return func;
+}
+
+export function createLowercaseFun () {
+  const lowercaseFun = (sto, _) => {
+    const str = sto.applyStore("str");
+    const temp = new StoreObject(Types.STRING, str.value.toLowerCase());
+    sto.mode = Modes.RETURN;
+    return Promise.resolve(sto.updateStore("$", temp));
+  }
+  const block = new Commands.CommandBlock([],  [new Commands.SysCall(lowercaseFun)]);
+  const func = new Commands.Function('$lowercase', Types.STRING,
+    [new Commands.FormalParameter(Types.STRING, 'str', false)],
+    block);
+  return func;
+}
+
+export function createrCharAtFun () {
+  const charAtFun = (sto, _) => {
+    const str = sto.applyStore("str");
+    const idx = sto.applyStore("index");
+    if (idx.value.toNumber() < 0 || idx.value.toNumber() >= str.value.length) {
+      return Promise.reject(new Error("invalid string position"));
+    }
+    const temp = new StoreObject(Types.STRING, str.value.charAt(idx.value.toNumber()));
+    sto.mode = Modes.RETURN;
+    return Promise.resolve(sto.updateStore("$", temp));
+  }
+  const block = new Commands.CommandBlock([],  [new Commands.SysCall(charAtFun)]);
+  const func = new Commands.Function('$charAt', Types.STRING,
+    [new Commands.FormalParameter(Types.STRING, 'str', false),
+    new Commands.FormalParameter(Types.INTEGER, 'index', false)],
+    block);
+  return func;
+}

+ 6 - 0
ivprogh/js/processor/modes.js

@@ -0,0 +1,6 @@
+export const Modes = Object.freeze({
+  RETURN: Symbol('mode:return'),
+  BREAK: Symbol('mode:break'),
+  PAUSE: Symbol('mode:pause'),
+  RUN: Symbol('mode:run')
+});

+ 517 - 0
ivprogh/js/processor/semantic/semanticAnalyser.js

@@ -0,0 +1,517 @@
+import { ProcessorErrorFactory } from './../error/processorErrorFactory';
+import { LanguageDefinedFunction } from './../definedFunctions';
+import { LanguageService } from './../../services/languageService';
+import { ArrayDeclaration, While, For, Switch, Assign, Break, IfThenElse, Return, ArrayIndexAssign } from '../../ast/commands';
+import { InfixApp, UnaryApp, FunctionCall, IntLiteral, RealLiteral, StringLiteral, BoolLiteral, VariableLiteral, ArrayLiteral, ArrayAccess } from '../../ast/expressions';
+import { Literal } from '../../ast/expressions/literal';
+import { resultTypeAfterInfixOp, resultTypeAfterUnaryOp } from '../compatibilityTable';
+import { Types } from '../../typeSystem/types';
+import { CompoundType } from '../../typeSystem/compoundType';
+import { MultiType } from '../../typeSystem/multiType';
+
+export class SemanticAnalyser {
+
+  constructor(ast) {
+    this.ast = ast;
+    this.lexerClass = LanguageService.getCurrentLexer();
+    const lexer = new this.lexerClass(null);
+    this.literalNames = lexer.literalNames;
+    this.symbolMap = null;
+    this.currentFunction = null;
+  }
+
+  pushMap () {
+    if(this.symbolMap === null) {
+      this.symbolMap = {map:{}, next: null};
+    } else {
+      const n = {map:{}, next: this.symbolMap};
+      this.symbolMap = n;
+    }
+  }
+
+  popMap () {
+    if(this.symbolMap !== null) {
+      this.symbolMap = this.symbolMap.next;
+    }
+  }
+
+  insertSymbol (id, typeInfo) {
+    this.symbolMap.map[id] = typeInfo;
+  }
+
+  findSymbol (id, symMap) {
+    if(!symMap.map[id]) {
+      if(symMap.next) {
+        return this.findSymbol(id, symMap.next);
+      }
+      return null;
+    } else {
+      return symMap.map[id];
+    }
+  }
+
+  getMainFunction () {
+    return this.ast.functions.find(v => v.isMain);
+  }
+
+  findFunction (name) {
+    if(name.match(/^\$.+$/)) {
+      const fun = LanguageDefinedFunction.getFunction(name);
+      if(!!!fun) {
+        throw ProcessorErrorFactory.not_implemented(name);
+      }
+      return fun;
+    } else {
+      const val = this.ast.functions.find( v => v.name === name);
+      if (!!!val) {
+        return null;
+      }
+      return val;
+    }
+  }
+
+  analyseTree () {
+    const globalVars = this.ast.global;
+    this.pushMap();
+    this.assertDeclarations(globalVars);
+    const functions = this.ast.functions;
+    const mainFunc = functions.filter((f) => f.name === null);
+    if (mainFunc.length <= 0) {
+      throw ProcessorErrorFactory.main_missing();
+    }
+    for (let i = 0; i < functions.length; i++) {
+      const fun = functions[i];
+      this.assertFunction(fun);
+    }
+    return this.ast;
+  }
+
+  assertDeclarations (list) {
+    for (let i = 0; i < list.length; i++) {
+      this.assertDeclaration(list[i]);
+    }
+  }
+
+  assertDeclaration (declaration) {
+    if (declaration instanceof ArrayDeclaration) {
+      if(declaration.initial === null) {
+        const lineType = this.evaluateExpressionType(declaration.lines);
+        if (!lineType.isCompatible(Types.INTEGER)) {
+          throw ProcessorErrorFactory.array_dimension_not_int_full(declaration.sourceInfo);
+        }
+        if (declaration.columns !== null) {
+          const columnType = this.evaluateExpressionType(declaration.columns);
+          if (!columnType.isCompatible(Types.INTEGER)) {
+            throw ProcessorErrorFactory.array_dimension_not_int_full(declaration.sourceInfo);
+          }
+        }
+        this.insertSymbol(declaration.id, {id: declaration.id, lines: declaration.lines, columns: declaration.columns, type: declaration.type});
+        return;
+      }
+      this.evaluateArrayLiteral(declaration.id, declaration.lines, declaration.columns, declaration.type, declaration.initial);
+      this.insertSymbol(declaration.id, {id: declaration.id, lines: declaration.lines, columns: declaration.columns, type: declaration.type});
+
+    } else {
+      if(declaration.initial === null) {
+        this.insertSymbol(declaration.id, {id: declaration.id, type: declaration.type});
+        return;
+      }
+      const resultType = this.evaluateExpressionType(declaration.initial);
+      if(resultType instanceof MultiType) {
+        if(!resultType.isCompatible(declaration.type)) {
+          const stringInfo = declaration.type.stringInfo();
+          const info = stringInfo[0];
+          throw ProcessorErrorFactory.incompatible_types_full(info.type, info.dim, declaration.sourceInfo);
+        }
+        this.insertSymbol(declaration.id, {id: declaration.id, type: declaration.type})
+      } else if(!declaration.type.isCompatible(resultType)) {
+        const stringInfo = declaration.type.stringInfo();
+        const info = stringInfo[0];
+        throw ProcessorErrorFactory.incompatible_types_full(info.type, info.dim, declaration.sourceInfo);
+      } else {
+        this.insertSymbol(declaration.id, {id: declaration.id, type: declaration.type})
+      }
+    }
+  }
+
+  evaluateExpressionType (expression) {
+    if(expression instanceof UnaryApp) {
+      const op = expression.op;
+      const resultType = this.evaluateExpressionType(expression.left);
+      return resultTypeAfterUnaryOp(op, resultType);
+    } else if (expression instanceof InfixApp) {
+      const op = expression.op;
+      const resultTypeLeft = this.evaluateExpressionType(expression.left);
+      const resultTypeRight = this.evaluateExpressionType(expression.right);
+      return resultTypeAfterInfixOp(op, resultTypeLeft, resultTypeRight);
+    } else if (expression instanceof Literal) {
+      return this.evaluateLiteralType(expression);
+    } else if (expression instanceof FunctionCall) {
+      if (expression.isMainCall) {
+        throw ProcessorErrorFactory.void_in_expression_full(LanguageDefinedFunction.getMainFunctionName(), expression.sourceInfo);
+      }
+      const fun = this.findFunction(expression.id);
+      if(fun === null) {
+        throw ProcessorErrorFactory.function_missing_full(expression.id, expression.sourceInfo);
+      }
+      if (fun.returnType.isCompatible(Types.VOID)) {
+        throw ProcessorErrorFactory.void_in_expression_full(expression.id, expression.sourceInfo);
+      }
+      this.assertParameters(fun, expression.actualParameters);
+      return fun.returnType;
+    } else if (expression instanceof ArrayAccess) {
+      const arrayTypeInfo = this.findSymbol(expression.id, this.symbolMap);
+      if(arrayTypeInfo === null) {
+        throw ProcessorErrorFactory.symbol_not_found_full(expression.id, expression.sourceInfo);
+      }
+      if (!(arrayTypeInfo.type instanceof CompoundType)) {
+        throw ProcessorErrorFactory.invalid_array_access_full(expression.id, expression.sourceInfo);
+      }
+      const lineType = this.evaluateExpressionType(expression.line);
+      if (!lineType.isCompatible(Types.INTEGER)) {
+        throw ProcessorErrorFactory.array_dimension_not_int_full(expression.sourceInfo);
+      }
+      if (expression.column !== null) {
+        if (arrayTypeInfo.columns === null) {
+          throw ProcessorErrorFactory.invalid_matrix_access_full(expression.id, expression.sourceInfo);
+        }
+        const columnType = this.evaluateExpressionType(expression.column);
+        if(!columnType.isCompatible(Types.INTEGER)) {
+          throw ProcessorErrorFactory.array_dimension_not_int_full(expression.sourceInfo);
+        }
+      }
+      const arrType = arrayTypeInfo.type;
+      if(expression.column !== null) {
+        // indexing matrix
+        return arrType.innerType;
+      } else {
+        if(arrayTypeInfo.columns === null) {
+          return arrType.innerType;
+        }
+        return new CompoundType(arrType.innerType, 1);
+      }
+    }
+  }
+
+  evaluateLiteralType (literal) {
+    if(literal instanceof IntLiteral) {
+      return literal.type;
+    } else if (literal instanceof RealLiteral) {
+      return literal.type;
+    } else if (literal instanceof StringLiteral) {
+      return literal.type;
+    } else if (literal instanceof BoolLiteral) {
+      return literal.type;
+    } else if (literal instanceof VariableLiteral) {
+      const typeInfo = this.findSymbol(literal.id, this.symbolMap);
+      if(typeInfo === null) {
+        throw ProcessorErrorFactory.symbol_not_found_full(literal.id, literal.sourceInfo);
+      }
+      if (typeInfo.type instanceof CompoundType) {
+        return typeInfo.type;
+      }
+      return typeInfo.type;
+    } else {
+      console.warn("Evaluating type only for an array literal...");
+      let last = null;
+      if(literal.value.length === 1) {
+        last = this.evaluateExpressionType(literal.value[0]);
+      } else {
+        for (let i = 0; i < literal.value.length; i++) {
+          const e = this.evaluateExpressionType(literal.value[i]);
+          if(last === null) {
+            last = e;
+          } else if(!last.isCompatible(e)) {
+            const strInfo = last.stringInfo();
+            const info = strInfo[0];
+            const strExp = literal.toString();
+            throw ProcessorErrorFactory.incompatible_types_array_full(strExp,info.type, info.dim, literal.sourceInfo);
+          }
+        }
+      }
+      if(last instanceof CompoundType) {
+        return new CompoundType(last.innerType, last.dimensions + 1);
+      }
+      return new CompoundType(last, 1);
+    }
+  }
+
+  evaluateArrayLiteral (id, lines, columns, type, literal) {
+    if (literal instanceof ArrayLiteral) {
+      if (columns === null) {
+        // it's a vector...
+        const dimType = this.evaluateExpressionType(lines);
+        if (!dimType.isCompatible(Types.INTEGER)) {
+          throw ProcessorErrorFactory.array_dimension_not_int_full(literal.sourceInfo);
+        }
+        if ((lines instanceof IntLiteral)) {
+          if (!lines.value.eq(literal.value.length)) {
+            if(type.dimensions > 1) {
+              throw ProcessorErrorFactory.matrix_line_outbounds_full(id, literal.value.length, lines.values.toNumber(), literal.sourceInfo)
+            } else {
+              throw ProcessorErrorFactory.vector_line_outbounds_full(id, literal.value.length, lines.values.toNumber(), literal.sourceInfo)
+            }
+          } else if (line.value.isNeg()) {
+            throw ProcessorErrorFactory.array_dimension_not_positive_full(literal.sourceInfo);
+          }
+          
+        }
+        literal.value.reduce((last, next) => {
+          const eType = this.evaluateExpressionType(next);
+          if (!last.canAccept(eType)) {
+            const strInfo = last.stringInfo();invalid
+            const info = strInfo[0];
+            const strExp = literal.toString();
+            throw ProcessorErrorFactory.incompatible_types_array_full(strExp,info.type, info.dim, literal.sourceInfo);
+          }
+          return last;
+        }, type);
+        return true;
+      } else {
+        const dimType = this.evaluateExpressionType(columns);
+        if (!dimType.isCompatible(Types.INTEGER)) {
+          throw ProcessorErrorFactory.array_dimension_not_int_full(literal.sourceInfo);
+        }
+        if ((columns instanceof IntLiteral)) {
+          if (!columns.value.eq(literal.value.length)) {
+            if(type.dimensions > 1) {
+              throw ProcessorErrorFactory.matrix_column_outbounds_full(id, literal.value.length, columns.values.toNumber(), literal.sourceInfo)
+            } else {
+              throw ProcessorErrorFactory.invalid_matrix_access_full(id, literal.sourceInfo);
+            }
+          } else if (columns.value.isNeg()) {
+            throw ProcessorErrorFactory.array_dimension_not_positive_full(literal.sourceInfo);
+          }
+          
+        }
+        for (let i = 0; i < columns; i++) {
+          const anotherArray = literal.value[i];
+          this.evaluateArrayLiteral(id, lines, null, type, anotherArray)
+        }
+      }
+
+    } else {
+
+      const resultType = this.evaluateExpressionType(literal);
+      if (!(resultType instanceof CompoundType)) {
+        const strInfo = type.stringInfo();
+        const info = strInfo[0];
+        const strExp = literal.toString();
+        throw ProcessorErrorFactory.incompatible_types_array_full(strExp,info.type, info.dim, literal.sourceInfo);
+      }
+      if (!type.isCompatible(resultType)) {
+        const strInfo = type.stringInfo();
+        const info = strInfo[0];
+        const strExp = literal.toString();
+        throw ProcessorErrorFactory.incompatible_types_array_full(strExp,info.type, info.dim, literal.sourceInfo);
+      }
+      return true;
+    }
+  }
+
+  assertFunction (fun) {
+    this.pushMap();
+    this.currentFunction = fun;
+    fun.formalParameters.forEach(formalParam => {
+      if(formalParam.type instanceof CompoundType) {
+        if(formalParam.type.dimensions > 1) {
+          this.insertSymbol(formalParam.id, {id: formalParam.id, lines: -1, columns: -1, type: formalParam.type});
+        } else {
+          this.insertSymbol(formalParam.id, {id: formalParam.id, lines: -1, columns: null, type: formalParam.type});
+        }
+      } else {
+        this.insertSymbol(formalParam.id, {id: formalParam.id, type: formalParam.type});
+      }
+    })
+    this.assertDeclarations(fun.variablesDeclarations);
+    const optional = fun.returnType.isCompatible(Types.VOID);
+    const valid = this.assertReturn(fun, optional);
+    if (!valid) {
+      throw ProcessorErrorFactory.function_no_return(fun.name);
+    }
+    this.popMap();
+  }
+
+  assertReturn (fun, optional) {
+    return fun.commands.reduce(
+      (last, next) => this.checkCommand(fun.returnType, next, optional) || last, optional
+    );
+  }
+
+  checkCommand (type, cmd, optional) {
+    if (cmd instanceof While) {
+      const resultType = this.evaluateExpressionType(cmd.expression);
+      if (!resultType.isCompatible(Types.BOOLEAN)) {
+        throw ProcessorErrorFactory.loop_condition_type_full(cmd.sourceInfo);
+      }
+      this.checkCommands(type, cmd.commands, optional);
+      return false;
+    } else if (cmd instanceof For) {
+      this.checkCommand(type, cmd.assignment, optional);
+      const resultType = this.evaluateExpressionType(cmd.condition);
+      if (!resultType.isCompatible(Types.BOOLEAN)) {
+        throw ProcessorErrorFactory.for_condition_type_full(cmd.sourceInfo);
+      }
+      this.checkCommand(type, cmd.increment, optional);
+      this.checkCommands(type, cmd.commands, optional);
+      return false;
+    } else if (cmd instanceof Switch) {
+      const sType = this.evaluateExpressionType(cmd.expression);
+      let result = optional;
+      let hasDefault = false;
+      for (let i = 0; i < cmd.cases.length; i++) {
+        const aCase = cmd.cases[i];
+        if (aCase.expression !== null) {
+          const caseType = this.evaluateExpressionType(aCase.expression);
+          if (!sType.isCompatible(caseType)) {
+            const strInfo = sType.stringInfo();
+            const info = strInfo[0];
+            const strExp = aCase.expression.toString();
+            throw ProcessorErrorFactory.invalid_case_type_full(strExp, info.type, info.dim, aCase.sourceInfo);
+          }
+        } else {
+          hasDefault = true;
+        }
+        result = result && this.checkCommands(type, aCase.commands, result);        
+      }
+      return result && hasDefault;
+
+    } else if (cmd instanceof ArrayIndexAssign) {
+      const typeInfo = this.findSymbol(cmd.id, this.symbolMap);
+      if(typeInfo === null) {
+        throw ProcessorErrorFactory.symbol_not_found_full(cmd.id, cmd.sourceInfo);
+      }
+      if(!(typeInfo.type instanceof CompoundType)) {
+        throw ProcessorErrorFactory.invalid_array_access_full(cmd.id, cmd.sourceInfo);
+      }
+      const exp = cmd.expression;
+      const lineExp = cmd.line;
+      const lineType = this.evaluateExpressionType(lineExp);
+      if (!lineType.isCompatible(Types.INTEGER)) {
+        throw ProcessorErrorFactory.array_dimension_not_int_full(cmd.sourceInfo);
+      }
+      const columnExp = cmd.column;
+      if (typeInfo.columns === null && columnExp !== null) {
+        throw ProcessorErrorFactory.invalid_matrix_access_full(cmd.id, cmd.sourceInfo);
+      } else if (columnExp !== null) {
+        const columnType = this.evaluateExpressionType(columnExp);
+        if (!columnType.isCompatible(Types.INTEGER)) {
+          throw ProcessorErrorFactory.array_dimension_not_int_full(cmd.sourceInfo);
+        }
+      }
+      // exp can be a arrayLiteral, a single value exp or an array access
+      if(exp instanceof ArrayLiteral) {
+        this.evaluateArrayLiteral(cmd.id, typeInfo.lines, (columnExp ? typeInfo.columns : null), typeInfo.type, exp);
+      } else {
+        // cannot properly evaluate since type system is poorly constructed
+      }
+      return optional;
+    } else if (cmd instanceof Assign) {
+      const typeInfo = this.findSymbol(cmd.id, this.symbolMap);
+      if(typeInfo === null) {
+        throw ProcessorErrorFactory.symbol_not_found_full(cmd.id, cmd.sourceInfo);
+      }
+      const exp = cmd.expression;
+      if(exp instanceof ArrayLiteral) {
+        if(!(typeInfo.type instanceof CompoundType)) {
+          const stringInfo = typeInfo.type.stringInfo();
+          const info = stringInfo[0];
+          throw ProcessorErrorFactory.incompatible_types_full(info.type, info.dim, cmd.sourceInfo);
+        }
+        this.evaluateArrayLiteral(cmd.id, typeInfo.lines, typeInfo.columns, typeInfo.type, exp);
+      } else {
+        const resultType = this.evaluateExpressionType(exp);
+        if(!resultType.isCompatible(typeInfo.type)) {
+          const stringInfo = typeInfo.type.stringInfo();
+          const info = stringInfo[0];
+          throw ProcessorErrorFactory.incompatible_types_full(info.type, info.dim, cmd.sourceInfo);
+        }
+      }
+      return optional;
+    } else if (cmd instanceof Break) {
+      return optional;
+    } else if (cmd instanceof IfThenElse) {
+      const resultType = this.evaluateExpressionType(cmd.condition);
+      if (!resultType.isCompatible(Types.BOOLEAN)) {
+        throw ProcessorErrorFactory.if_condition_type_full(cmd.sourceInfo);
+      }
+      if(cmd.ifFalse instanceof IfThenElse) {
+        return this.checkCommands(type, cmd.ifTrue.commands, optional) && this.checkCommand(type, cmd.ifFalse, optional);
+      } else {
+        return this.checkCommands(type, cmd.ifTrue.commands, optional) && this.checkCommands(type, cmd.ifFalse.commands,optional);
+      }
+
+    } else if (cmd instanceof FunctionCall) {
+      let fun = null;
+      if (cmd.isMainCall) {
+        fun = this.getMainFunction();
+      } else {
+        fun = this.findFunction(cmd.id);
+      }
+      if(fun === null) {
+        throw ProcessorErrorFactory.function_missing_full(cmd.id, cmd.sourceInfo);
+      }
+      this.assertParameters(fun, cmd.actualParameters);
+      return optional;
+    } else if (cmd instanceof Return) {
+      const funcName = this.currentFunction.isMain ? LanguageDefinedFunction.getMainFunctionName() : this.currentFunction.name
+      if (cmd.expression === null && !type.isCompatible(Types.VOID)) {
+        const stringInfo = type.stringInfo();
+        const info = stringInfo[0];
+        throw ProcessorErrorFactory.invalid_void_return_full(funcName, info.type, info.dim, cmd.sourceInfo);
+      } else if (cmd.expression !== null) {
+        const resultType = this.evaluateExpressionType(cmd.expression);
+        if (!type.isCompatible(resultType)) {
+          const stringInfo = type.stringInfo();
+          const info = stringInfo[0];
+          throw ProcessorErrorFactory.invalid_return_type_full(funcName, info.type, info.dim, cmd.sourceInfo);
+        } else {
+          return true;
+        }
+      } else {
+        return true;
+      }
+    }
+  }
+
+  checkCommands (type, cmds, optional) {
+    return cmds.reduce(
+      (last, next) => this.checkCommand(type, next, optional) || last, optional
+    );
+  }
+
+  assertParameters (fun, actualParametersList) {
+    if (fun.formalParameters.length !== actualParametersList.length) {
+      throw ProcessorErrorFactory.invalid_parameters_size_full(fun.name, actualParametersList.length, fun.formalParameters.length, null);
+    }
+    for (let i = 0; i < actualParametersList.length; i++) {
+      const param = actualParametersList[i];
+      const formalParam = fun.formalParameters[i];
+      if(formalParam.byRef) {
+        if (!(param instanceof VariableLiteral || param instanceof ArrayAccess)) {
+          throw ProcessorErrorFactory.invalid_parameter_type_full(id, param.toString(), param.sourceInfo);
+        }
+      }
+      const resultType = this.evaluateExpressionType(param);
+      if(resultType instanceof MultiType && formalParam.type instanceof MultiType) {
+        let shared = 0
+        for (let j = 0; j < resultType.types.length; j++) {
+          const element = resultType.types[j];
+          if(formalParam.type.types.indexOf(element) !== -1) {
+            shared++;
+          }
+        }
+        if(shared <= 0) {
+          throw ProcessorErrorFactory.invalid_parameter_type_full(id, param.toString(), param.sourceInfo);
+        }
+      } else if (resultType instanceof MultiType) {
+        if(!resultType.isCompatible(formalParam.type)) {
+          throw ProcessorErrorFactory.invalid_parameter_type_full(id, param.toString(), param.sourceInfo);
+        }
+      } else if(!formalParam.type.isCompatible(resultType)) {
+        throw ProcessorErrorFactory.invalid_parameter_type_full(id, param.toString(), param.sourceInfo);
+      }
+
+    }
+  }
+}

+ 76 - 0
ivprogh/js/processor/store/store.js

@@ -0,0 +1,76 @@
+import { Modes } from './../modes';
+
+export class Store {
+
+  constructor(name) {
+    this.name = name;
+    this.store = {};
+    this.nextStore = null;
+    this.mode = Modes.RUN; 
+  }
+
+  extendStore (nextStore) {
+    this.nextStore = nextStore;
+  }
+
+  applyStore (id) {
+    if(!this.store[id]) {
+      if (this.nextStore !== null) {
+        return this.nextStore.applyStore(id);
+      } else {
+        // TODO: better error message
+        throw new Error(`Variable ${id} not found.`);
+      }
+    }
+    const val = this.store[id];
+    if (val.isRef) {
+      return val.getRefObj();
+    }
+    return this.store[id];
+  }
+
+  updateStore (id, stoObj) {
+    if(!this.store[id]) {
+      if(this.nextStore !== null) {
+        this.nextStore.updateStore(id, stoObj);
+        return this;
+      } else {
+        // TODO: better error message
+        throw new Error(`Variable ${id} not found.`);
+      }
+    } else {
+      const oldObj = this.store[id];
+      if(oldObj.readOnly) {
+        // TODO: better error message
+        throw new Error("Cannot change value of a read only variable: " + id);
+      }
+      if(oldObj.isRef) {
+        oldObj.updateRef(stoObj);
+        return this;
+      } else if(oldObj.isCompatible(stoObj)) {
+        stoObj.setID(id);
+        this.store[id] = Object.freeze(stoObj);
+        return this;
+      } else {
+        const oldType = oldObj.type;
+        const stoType = stoObj.type;
+        // TODO: better error message
+        throw new Error(`${oldType} is not compatible with type ${stoType} given`);
+      }
+    }
+  }
+
+  //In case of future use of ref, it needs to have a special function to update the storeRefObject
+  // and no the StoreObject refferenced by it
+  // updateStoreRef(id, stoObjAddress) {...}
+
+  insertStore (id, stoObj) {
+    if (this.store[id]) {
+      // TODO: better error message
+      throw new Error(`${id} is already defined`);
+    }
+    stoObj.setID(id);
+    this.store[id] = Object.freeze(stoObj);
+    return this;
+  }
+}

+ 54 - 0
ivprogh/js/processor/store/storeObject.js

@@ -0,0 +1,54 @@
+import Decimal from 'decimal.js';
+
+export class StoreObject {
+
+  constructor (type, value, readOnly = false) {
+    this._type = type;
+    this._value = value;
+    this._readOnly = readOnly;
+    this._id = null;
+  }
+
+  setID (id) {
+    this._id = id;
+  }
+
+  get id () {
+    return this._id;
+  }
+
+  get inStore () {
+    return this.id !== null;
+  }
+
+  get type () {
+    return this._type;
+  }
+
+  get value () {
+    return this._value;
+  }
+  
+  get number () {
+    if (this._value instanceof Decimal) {
+      return this._value.toNumber();
+    } else {
+      return null;
+    }
+  }
+
+  get readOnly () {
+    return this._readOnly;
+  }
+
+  set readOnly (value) {
+    this._readOnly = value;
+  }
+
+  isCompatible (another) {
+    if( another instanceof StoreObject) {
+      return this.type.isCompatible(another.type);
+    }
+    return false;
+  }
+}

+ 79 - 0
ivprogh/js/processor/store/storeObjectArray.js

@@ -0,0 +1,79 @@
+import { StoreObject } from './storeObject';
+
+export class StoreObjectArray extends StoreObject {
+
+  static get WRONG_LINE_NUMBER () {
+    return 1;
+  }
+
+  static get WRONG_TYPE () {
+    return 2;
+  }
+
+  static get WRONG_COLUMN_NUMBER () {
+    return 3;
+  }
+
+  constructor (type, lines, columns, value = null, readOnly = false) {
+    super(type, value, readOnly);
+    this._lines = lines;
+    this._columns = columns;
+  }
+
+  get lines () {
+    return this._lines;
+  }
+
+  get columns () {
+    return this._columns;
+  }
+
+  isCompatible (another) {
+    if(another instanceof StoreObject) {
+      if(((this.lines === -1 && another.lines > 0) ||
+        (this.lines === another.lines))) {
+          if ((this.columns === -1 && another.columns > 0) ||
+            (this.columns === another.columns)) {
+              return super.isCompatible(another);
+          }
+        }
+    }
+    return false;
+  }
+
+  get isVector () {
+    return this.type.dimensions === 1;
+  }
+
+  get isValid () {
+    if (this.value !== null) {
+      if( this.isVector) {
+        if(this.value.length !== this.lines) {
+          return [StoreObjectArray.WRONG_LINE_NUMBER, this.value.length];;
+        }
+        const mustBeNull = this.value.find(v => !this.type.canAccept(v.type) );
+        if(!!mustBeNull) {
+          return [StoreObjectArray.WRONG_TYPE, this.value.indexOf(mustBeNull)];;
+        }
+      }
+      return [];
+    } else {
+    if(this.lines !== this.value.length) {
+      return [StoreObjectArray.WRONG_LINE_NUMBER, this.value.length];
+    }
+    for (let i = 0; i < this.lines; i++) {
+      for (let j = 0; j < this.columns; j++) {
+        const arr = this.value[i];
+        if(arr.length !== this.columns) {
+          return [StoreObjectArray.WRONG_COLUMN_NUMBER, arr.length];
+        }
+        const mustBeNull = arr.find(v => !this.type.canAccept(v.type) );
+        if(!!mustBeNull) {
+          return [StoreObjectArray.WRONG_TYPE, i, arr.indexOf(mustBeNull)];
+        }            
+      }
+    }
+      return [];
+    }
+  }
+}

+ 101 - 0
ivprogh/js/processor/store/storeObjectArrayAddress.js

@@ -0,0 +1,101 @@
+import { StoreObject } from './storeObject';
+import { StoreObjectArray } from './storeObjectArray';
+import { CompoundType } from '../../typeSystem/compoundType';
+import { ProcessorErrorFactory } from '../error/processorErrorFactory';
+
+export class StoreObjectArrayAddress extends StoreObject {
+
+  constructor (refID, line, column, store) {
+    super(null, null, false);
+    this.refID = refID;
+    this.store = store;
+    this.line = line;
+    this.column = column;
+  }
+
+  get isRef () {
+    return false;
+  }
+
+  get inStore () {
+    return true;
+  }
+
+  get refValue () {
+    const refLine = this.store.applyStore(this.refID).value[this.line];
+    if(!refLine) {
+      if(this.getArrayObject().isVector) {
+        throw ProcessorErrorFactory.vector_line_outbounds(this.refID, this.line, this.getArrayObject().lines);
+      } else {
+        throw ProcessorErrorFactory.matrix_line_outbounds(this.refID, this.line, this.getArrayObject().lines);
+      }
+    }
+    if (this.column !== null) {
+      const refColumn = refLine.value[this.column];
+      if(!refColumn) {
+        if(this.getArrayObject().isVector) {
+          throw ProcessorErrorFactory.vector_not_matrix(this.refID);
+        } else {
+          throw ProcessorErrorFactory.matrix_column_outbounds(this.refID, this.column, this.getArrayObject().columns);
+        }
+      }
+      return refColumn;
+    }
+    return refLine;
+  }
+
+  get value () {
+    return this.refValue.value;
+  }
+
+  get type () {
+    return this.refValue.type;
+  }
+
+  get lines () {
+    if(!(this.type instanceof CompoundType)) {
+      return null;
+    }
+    return this.refValue.value.length;
+  }
+
+  get columns () {
+    switch (this.type.dimensions) {
+      case 2:
+        return this.refValue.value[0].value.length;
+      default:
+        return null;
+    }
+  }
+
+  getArrayObject () {
+    return this.store.applyStore(this.refID);
+  }
+
+  updateArrayObject (stoObj) {
+    const anArray =  this.getArrayObject();
+    const newArray = Object.assign(new StoreObjectArray(null,null,null), anArray);
+    if(!stoObj.type.isCompatible(this.type)) {
+      throw new Error(`Invalid operation: cannot assign the value given to ${this.refID}`);
+    } else if (this.type instanceof CompoundType && this.type.canAccept(stoObj.type)) {
+      throw new Error(`Invalid operation: cannot assign the value given to ${this.refID}`);
+    }
+    if (this.column !== null) {
+     newArray.value[this.line].value[this.column] = stoObj;
+     return newArray;
+    } else {
+     newArray.value[this.line] = stoObj;
+     return newArray;
+    }
+  }
+
+  isCompatible (another) {
+    if(this.type.isCompatible(another.type)) {
+      if(another.type instanceof CompoundType) {
+        return this.lines === another.lines && this.columns === another.columns;
+      } else {
+        this.refValue.isCompatible(another);
+      }
+    }
+  }
+}

+ 43 - 0
ivprogh/js/processor/store/storeObjectArrayAddressRef.js

@@ -0,0 +1,43 @@
+import { StoreObject } from './storeObject';
+import Decimal from 'decimal.js';
+
+export class StoreObjectArrayAddressRef extends StoreObject {
+
+  constructor (address) {
+    super(null, null, false);
+    this.address = address;
+  }
+
+  get isRef () {
+    return true;
+  }
+
+  get type () {
+    return this.address.type;
+  }
+
+  get value () {
+    return this.address.value;
+  }
+
+  get number () {
+    if (this.value instanceof Decimal) {
+      return this.value.toNumber();
+    } else {
+      return null;
+    }
+  }
+
+  getRefObj () {
+    return this.address.refValue;
+  }
+
+  updateRef (stoObj) {
+    const newArray = this.address.updateArrayObject(stoObj);
+    this.address.store.updateStore(this.address.refID, newArray);
+  }
+
+  isCompatible (another) {
+    return this.address.isCompatible(another);
+  }
+}

+ 43 - 0
ivprogh/js/processor/store/storeObjectRef.js

@@ -0,0 +1,43 @@
+import { StoreObject } from './storeObject';
+import Decimal from 'decimal.js';
+
+export class StoreObjectRef extends StoreObject {
+
+  constructor (refID, store) {
+    super(null, null, false);
+    this.refID = refID;
+    this.store = store;
+  }
+
+  get isRef () {
+    return true;
+  }
+
+  get type () {
+    return this.store.applyStore(this.refID).type;
+  }
+
+  get value () {
+    return this.store.applyStore(this.refID).value;
+  }
+
+  get number () {
+    if (this.value instanceof Decimal) {
+      return this.value.toNumber();
+    } else {
+      return null;
+    }
+  }
+
+  getRefObj () {
+    return this.store.applyStore(this.refID);
+  }
+
+  updateRef (stoObj) {
+    this.store.updateStore(this.refID, stoObj);
+  }
+
+  isCompatible (another) {
+    return this.store.applyStore(this.refID).isCompatible(another);
+  }
+}

+ 49 - 0
ivprogh/js/runner.js

@@ -0,0 +1,49 @@
+import { IVProgParser } from './ast/ivprogParser';
+import { IVProgProcessor } from './processor/ivprogProcessor';
+import {DOMConsole} from './io/domConsole';
+import { LanguageService } from './services/languageService';
+import { SemanticAnalyser } from './processor/semantic/semanticAnalyser';
+
+export function runner () {
+const ivprogLexer = LanguageService.getCurrentLexer();
+
+
+// const lexer = new ivprogLexer(new InputStream(input));
+// const stream = new CommonTokenStream(lexer);
+// stream.fill();
+// let i = 1;
+// let token = null;
+// while ((token = stream.LT(i)).type !== ivprogLexer.EOF && token.type !== ivprogLexer.WHITESPACE) {
+//     console.log(`${token.type}-${token.text}`);
+//     console.log('\n')
+//     i++;
+// }
+// const anaSin = new IVProgParser(input, ivprogLexer);
+const editor = new JsonEditor('#json-renderer', {});
+const domConsole = new DOMConsole("#console");
+// proc.interpretAST().then( sto => {
+//   console.log(sto.applyStore('a'));
+// }).catch(e => console.log(e));
+try {
+  $('#btn').click( () => {
+    const input = $('#input').val();
+    const analiser = new IVProgParser(input, ivprogLexer);
+    try {
+      const data = analiser.parseTree();
+      const semAna = new SemanticAnalyser(data);
+      const proc = new IVProgProcessor(semAna.analyseTree());
+      proc.registerInput(domConsole);
+      domConsole.clear();
+      proc.registerOutput(domConsole);
+      proc.interpretAST().then(sto => editor.load(sto.store))
+        .catch( e => {alert(e); console.log(e)});
+    } catch (error) {
+      alert(error);
+      console.log(error);
+    }
+    
+  });
+} catch(a) {
+  console.log(a);
+}
+}

+ 0 - 14
ivprogh/js/semantic/semantic-buttons.js

@@ -34,8 +34,6 @@ var button_ready = function() {
     .dropdown()
   ;
 
-  $('.program_signature_text').text(ivprogCore.i18n('program'));
-
   // Atualiza a tela do algoritmo
   //renderAlgorithm();
 
@@ -52,18 +50,6 @@ var button_ready = function() {
 
   });
 
-
-  //Sortable:
-  Sortable.create(listWithHandle, {
-    handle: '.glyphicon-move',
-    animation: 100,
-    ghostClass: 'ghost',
-    group: 'functions_divs_drag',
-    // onEnd: function (evt) {
-    //   updateSequenceFunctionHandler(evt.oldIndex, evt.newIndex);
-    // }
-  });
-
 };
 
 var mouseX;

+ 22 - 0
ivprogh/js/services/i18nHelper.js

@@ -0,0 +1,22 @@
+import line_i18n from "line-i18n";
+import { LocalizedStrings } from "./localizedStringsService";
+
+const StringTypes = line_i18n.StringTypes;
+
+export const i18nHelper = Object.freeze({
+  i18n: (identifier) => {
+    var opts = identifier.split(':');
+    var type = opts[0].toLowerCase();
+    var id = opts[1];
+    if (StringTypes.ERROR === type) {
+      return LocalizedStrings.getError(id);
+    } else if (StringTypes.MESSAGE === type) {
+      return LocalizedStrings.getMessage(id); 
+    } else if (StringTypes.UI === type) {
+      return LocalizedStrings.getUI(id);
+    } else {
+      console.warn("A string has been passed to the i18n helper function that was not in the form type:id -> " + identifier);
+      return LocalizedStrings.getString(identifier, type);
+    }
+  }
+});

+ 40 - 0
ivprogh/js/services/languageService.js

@@ -0,0 +1,40 @@
+import Lexers from './../../grammar/';
+import line_i18n from 'line-i18n';
+
+// This is for LanguageService with localStorage
+// const DEFAULT_LANG = "pt";
+
+class LanguageServiceExtended extends line_i18n.LanguageServiceNoLS {
+
+  constructor () {
+    super(iLMparameters.lang);
+  }
+
+  getCurrentLexer () {
+    const langInfo = Lexers[this.getLang()];
+    if(langInfo === null || langInfo === undefined) {
+      return Lexers[this.getDefaultLang()].lexer;
+    } else {
+      return langInfo.lexer;
+    }
+  }
+
+  getCurrentLangFuncs () {
+    const langInfo = Lexers[this.getLang()];
+    if(langInfo === null || langInfo === undefined) {
+      return Lexers[this.getDefaultLang()].langFuncs;
+    } else {
+      return langInfo.langFuncs;
+    }
+  }
+
+  getCurrentLangLibs () {
+    const langInfo = Lexers[this.getLang()];
+    if(langInfo === null || langInfo === undefined) {
+      return Lexers[this.getDefaultLang()].langLibs;
+    }
+    return langInfo.langLibs;
+  }
+}
+
+export const LanguageService  = new LanguageServiceExtended();

+ 0 - 0
ivprogh/js/services/localizedStringsService.js


Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff