ソースを参照

Relatório de aluno por exercício

Igor 5 年 前
コミット
c0f1bc9bda
100 ファイル変更83251 行追加1 行削除
  1. 3 1
      .gitignore
  2. 0 0
      alunos.php
  3. 7 0
      css/bootstrap.min.css
  4. 1 0
      css/octicons.min.css
  5. 170 0
      css/style.css
  6. 118 0
      curso.php
  7. 207 0
      functions.php
  8. 91 0
      index.php
  9. 54220 0
      ivprog_contexto/build/ivprog.bundle.js
  10. 1 0
      ivprog_contexto/build/ivprog.bundle.js.map
  11. 71 0
      ivprog_contexto/css/ivprog-term.css
  12. 863 0
      ivprog_contexto/css/ivprog-visual-1.0.css
  13. 86 0
      ivprog_contexto/i18n/en/error.json
  14. 9 0
      ivprog_contexto/i18n/en/index.js
  15. 3 0
      ivprog_contexto/i18n/en/message.json
  16. 135 0
      ivprog_contexto/i18n/en/ui.json
  17. 86 0
      ivprog_contexto/i18n/es/error.json
  18. 9 0
      ivprog_contexto/i18n/es/index.js
  19. 3 0
      ivprog_contexto/i18n/es/message.json
  20. 140 0
      ivprog_contexto/i18n/es/ui.json
  21. 117 0
      ivprog_contexto/i18n/i18n-database.json
  22. 9 0
      ivprog_contexto/i18n/index.js
  23. 86 0
      ivprog_contexto/i18n/pt/error.json
  24. 9 0
      ivprog_contexto/i18n/pt/index.js
  25. 3 0
      ivprog_contexto/i18n/pt/message.json
  26. 142 0
      ivprog_contexto/i18n/pt/ui.json
  27. BIN
      ivprog_contexto/img/background-panel.png
  28. 122 0
      ivprog_contexto/index.html
  29. 1491 0
      ivprog_contexto/js/Sortable.js
  30. 92 0
      ivprog_contexto/js/assessment/ivprogAssessment.js
  31. 47 0
      ivprog_contexto/js/ast/ASA.txt
  32. 10 0
      ivprog_contexto/js/ast/commands/arrayAssign.js
  33. 10 0
      ivprog_contexto/js/ast/commands/arrayDeclaration.js
  34. 10 0
      ivprog_contexto/js/ast/commands/assign.js
  35. 8 0
      ivprog_contexto/js/ast/commands/break.js
  36. 18 0
      ivprog_contexto/js/ast/commands/case.js
  37. 14 0
      ivprog_contexto/js/ast/commands/command.js
  38. 16 0
      ivprog_contexto/js/ast/commands/commandBlock.js
  39. 12 0
      ivprog_contexto/js/ast/commands/declaration.js
  40. 13 0
      ivprog_contexto/js/ast/commands/doWhile.js
  41. 16 0
      ivprog_contexto/js/ast/commands/for.js
  42. 17 0
      ivprog_contexto/js/ast/commands/formalParameter.js
  43. 32 0
      ivprog_contexto/js/ast/commands/function.js
  44. 11 0
      ivprog_contexto/js/ast/commands/ifThenElse.js
  45. 37 0
      ivprog_contexto/js/ast/commands/index.js
  46. 10 0
      ivprog_contexto/js/ast/commands/return.js
  47. 10 0
      ivprog_contexto/js/ast/commands/switch.js
  48. 12 0
      ivprog_contexto/js/ast/commands/sysCall.js
  49. 18 0
      ivprog_contexto/js/ast/commands/while.js
  50. 8 0
      ivprog_contexto/js/ast/error/syntaxError.js
  51. 70 0
      ivprog_contexto/js/ast/error/syntaxErrorFactory.js
  52. 24 0
      ivprog_contexto/js/ast/expressions/arrayAccess.js
  53. 87 0
      ivprog_contexto/js/ast/expressions/arrayLiteral.js
  54. 15 0
      ivprog_contexto/js/ast/expressions/boolLiteral.js
  55. 14 0
      ivprog_contexto/js/ast/expressions/expression.js
  56. 36 0
      ivprog_contexto/js/ast/expressions/functionCall.js
  57. 23 0
      ivprog_contexto/js/ast/expressions/index.js
  58. 18 0
      ivprog_contexto/js/ast/expressions/infixApp.js
  59. 15 0
      ivprog_contexto/js/ast/expressions/intLiteral.js
  60. 9 0
      ivprog_contexto/js/ast/expressions/literal.js
  61. 15 0
      ivprog_contexto/js/ast/expressions/realLiteral.js
  62. 14 0
      ivprog_contexto/js/ast/expressions/stringLiteral.js
  63. 14 0
      ivprog_contexto/js/ast/expressions/unaryApp.js
  64. 14 0
      ivprog_contexto/js/ast/expressions/variableLiteral.js
  65. 1182 0
      ivprog_contexto/js/ast/ivprogParser.js
  66. 35 0
      ivprog_contexto/js/ast/operators.js
  67. 22 0
      ivprog_contexto/js/ast/sourceInfo.js
  68. 500 0
      ivprog_contexto/js/iassign-integration-functions.js
  69. 139 0
      ivprog_contexto/js/io/domConsole.js
  70. 37 0
      ivprog_contexto/js/io/domInput.js
  71. 21 0
      ivprog_contexto/js/io/domOutput.js
  72. 6 0
      ivprog_contexto/js/io/input.js
  73. 6 0
      ivprog_contexto/js/io/output.js
  74. 2 0
      ivprog_contexto/js/jquery-3.3.1.min.js
  75. 18706 0
      ivprog_contexto/js/jquery-ui.js
  76. 119 0
      ivprog_contexto/js/jquery.json-editor.min.js
  77. 13 0
      ivprog_contexto/js/main.js
  78. 213 0
      ivprog_contexto/js/processor/compatibilityTable.js
  79. 5 0
      ivprog_contexto/js/processor/context.js
  80. 128 0
      ivprog_contexto/js/processor/definedFunctions.js
  81. 398 0
      ivprog_contexto/js/processor/error/processorErrorFactory.js
  82. 8 0
      ivprog_contexto/js/processor/error/runtimeError.js
  83. 8 0
      ivprog_contexto/js/processor/error/semanticError.js
  84. 1051 0
      ivprog_contexto/js/processor/ivprogProcessor.js
  85. 58 0
      ivprog_contexto/js/processor/lib/arrays.js
  86. 47 0
      ivprog_contexto/js/processor/lib/io.js
  87. 188 0
      ivprog_contexto/js/processor/lib/lang.js
  88. 254 0
      ivprog_contexto/js/processor/lib/math.js
  89. 94 0
      ivprog_contexto/js/processor/lib/strings.js
  90. 6 0
      ivprog_contexto/js/processor/modes.js
  91. 544 0
      ivprog_contexto/js/processor/semantic/semanticAnalyser.js
  92. 97 0
      ivprog_contexto/js/processor/store/store.js
  93. 54 0
      ivprog_contexto/js/processor/store/storeObject.js
  94. 79 0
      ivprog_contexto/js/processor/store/storeObjectArray.js
  95. 101 0
      ivprog_contexto/js/processor/store/storeObjectArrayAddress.js
  96. 43 0
      ivprog_contexto/js/processor/store/storeObjectArrayAddressRef.js
  97. 43 0
      ivprog_contexto/js/processor/store/storeObjectRef.js
  98. 49 0
      ivprog_contexto/js/runner.js
  99. 4 0
      ivprog_contexto/js/semantic/.versions
  100. 0 0
      ivprog_contexto/js/semantic/LICENSE

+ 3 - 1
.gitignore

@@ -33,4 +33,6 @@ Thumbs.db
 !.vscode/settings.json
 !.vscode/tasks.json
 !.vscode/launch.json
-!.vscode/extensions.json
+!.vscode/extensions.json
+
+./cursos/

+ 0 - 0
alunos.php


ファイルの差分が大きいため隠しています
+ 7 - 0
css/bootstrap.min.css


ファイルの差分が大きいため隠しています
+ 1 - 0
css/octicons.min.css


+ 170 - 0
css/style.css

@@ -0,0 +1,170 @@
+.ivprog-container {
+	-webkit-box-shadow: 0px 0px 31px -5px rgba(0,0,0,0.75);
+-moz-box-shadow: 0px 0px 31px -5px rgba(0,0,0,0.75);
+box-shadow: 0px 0px 31px -5px rgba(0,0,0,0.75);
+border-radius: 4px;
+padding-top: 0.3rem;
+}
+footer.container {
+	margin-top: 1%;
+}
+.jumbotron.ivprogh-desc {
+	padding-bottom: 0.5rem;
+	margin-bottom: 1rem;
+}
+.text-reduced {
+	font-size: 96%;
+	margin-bottom: 0.5rem;
+}
+h1 {
+	margin-bottom: 0;
+}
+.col-md-3.item {
+	padding: 1em;
+    background: #007bff;
+    color: white;
+    margin: 1em;
+    border-radius: .5em;
+    text-align: center;
+    border: 1px groove;
+    cursor: pointer;
+} 
+.col-md-3.item .octicon {
+	font-size: 3em;
+}
+.col-md-3.item h4 {
+	font-size: 1.4em;
+	margin-top: 0.6em;
+}
+.row.thumbs-ivprog {
+	margin-top: 1em;
+}
+.row.thumbs-ivprog-download .item {
+	background-color: #5a6570;
+	border: 2px groove;
+}
+.col-md-3.item:hover {
+    background-color: #03396c;
+}
+.col-md-3.item hr {
+    background: white;
+}
+.btn.btn-primary .octicon {
+	font-size: 1.5em;
+	margin-right: 0.5em;
+}
+.download-ivprog {
+    font-size: 1.3em;
+}
+.div-button {
+	text-align: center;
+	padding-top: 2.5em;
+}
+.div-button .span-version {
+	display: block;
+	font-size: 98%;
+}
+.my-4 .octicon-history {
+	font-size: 1em;
+}
+.row.thumbs-ivprog-download {
+    padding-bottom: 3em;
+}
+
+.history-ivprog-version {
+	display: block;
+	font-size: 1em;
+	font-weight: bold;
+	margin-top: -.5em;
+	margin-bottom: .5em;
+}
+.history-ivprog-time {
+    background-color: gray;
+    padding: .4em;
+    border-radius: .4em;
+}
+footer.container {
+	margin-bottom: 1em;
+}
+.example-large-div {
+	background-color: #0bbf4a;
+	border-radius: .8em;
+	margin-top: 0.5em;
+}
+
+.example-large-div .container .embed-responsive {
+	border-radius: .5em;
+	margin-top: 1em;
+}
+
+.text-count-example {
+	font-size: 1.5em;
+    color: white;
+    text-shadow: 2px 2px gray;
+    font-weight: 600;
+    margin-bottom: .3em;
+    padding-top: .3em;
+    padding-bottom: .2em;
+    cursor: pointer;
+}
+.example-large-div .text-reduced {
+	color: #06065a;
+    font-size: 1.1em;
+    text-indent: 1em;
+}
+.text-count-example .octicon {
+	text-shadow: none;
+    font-weight: normal;
+    font-size: .9em;
+    margin-right: .1em;
+}
+.container.text-center .btn {
+	margin: .5em;
+}
+.container.example-large-div.autoeval-descript {
+	background-color: #538564;
+    color: white;
+    padding: .2em;
+    padding-left: 1em;
+    font-size: 1.1em;
+    border-radius: .3em;
+}
+.container.example-large-div.autoeval-descript .pointer {
+	cursor:pointer;
+}
+.container.example-large-div.autoeval-descript span {
+	font-size: 1.2em;
+	margin-right: .2em;
+}
+#area-autoeval-descript {
+	padding-left: 2em;
+    padding-top: 1em;
+    padding-right: 2em;
+    padding-bottom: 1em;
+}
+button.btn.btn-primary.show-solution {
+    float: right;
+    margin-right: 1em;
+}
+.ivprogh-title-download {
+	color: #03396c;
+}
+.ivprogh-title-download .octicon {
+	font-size: 1em;
+}
+.table.about-auto-eval {
+	border: 2px solid white;
+}
+.box-download {
+	background: #efefef;
+    border-radius: .5em;
+}
+.distinct-container {
+	margin-top: 2em;
+	margin-bottom: 2em;
+}
+.zoom-images {
+	width: 10em;
+	cursor: zoom-in;
+	height: 5.5em !important;
+}

+ 118 - 0
curso.php

@@ -0,0 +1,118 @@
+<?php
+
+require 'functions.php';
+
+$cursos = listarCursos();
+
+$alunos = listarAlunos($_GET['curso']);
+
+$exercicios = listarExercicios($_GET['curso']);
+
+?>
+<!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>ivprog_log_analysis</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="./">ivprog_log_analysis - Ambiente de análise dos logs do 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="./" title=""></a>
+          </li>
+          </ul>
+      </div>
+    </nav>
+
+    <main role="main">
+      <div class="jumbotron ivprogh-desc">
+        <div class="container">
+          <?= instrucoes() ?>
+        </div>
+      </div>
+
+
+      <div class="container ivprog-container" style="padding: 3em; margin-top: 3em;">
+        <form action="process.php" method="get" novalidate>
+
+          <div class="form-group row">
+            <label for="inputname" class="col-sm-2 col-form-label">Curso:</label>
+            <div class="col-sm-10">
+              <select class="form-control" id="inputname" name="curso">
+                <?php
+                  for ($i = 0; $i < count($cursos); $i++) {
+                    echo "<option" . ($cursos[$i] == $_GET['curso']?" selected":"") . ">" . $cursos[$i] . "</option>";
+                  }
+                ?>
+              </select>
+            </div>
+          </div>
+
+          <div class="form-group row">
+            <label for="inputaluno" class="col-sm-2 col-form-label">Aluno:</label>
+            <div class="col-sm-10">
+              <select class="form-control" id="inputaluno" name="aluno">
+                <option>Todos</option>
+                <?php
+                  for ($i = 0; $i < count($alunos); $i++) {
+                    echo "<option value='$alunos[$i]'>" . str_replace('_', ' ', $alunos[$i]) . "</option>";
+                  }
+                ?>
+              </select>
+            </div>
+        </div>
+
+      <div class="form-group row">
+            <label for="inputexercicio" class="col-sm-2 col-form-label">Exercício:</label>
+            <div class="col-sm-10">
+              <select class="form-control" id="inputexercicio" name="exercicio">
+                <option value="Todos">Todos</option>
+                <?php
+                  for ($i = 0; $i < count($exercicios); $i++) {
+                    echo "<option value='$exercicios[$i]'>" . str_replace('_', ' ', $exercicios[$i]) . "</option>";
+                  }
+                ?>
+              </select>
+            </div>
+        </div>
+
+      <div class="form-group row">
+          <div class="offset-sm-2 col-sm-10">
+            <button type="button" class="btn btn-secondary" onclick="window.history.back();">Voltar</button>
+            <button type="submit" class="btn btn-primary">Continuar</button>
+            <span class="reported" style="color: green; font-size: 120%;"></span>
+            <span class="error" style="color: red; font-size: 120%;"></span>
+          </div>
+        </div>
+
+        </form>
+      </div>
+
+
+      <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.bundle.min.js"></script>
+
+
+    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/octicons/3.5.0/octicons.min.css">
+  </body>
+</html>

+ 207 - 0
functions.php

@@ -0,0 +1,207 @@
+<?php
+
+function listarCursos () {
+  $dir    = 'cursos';
+  $files1 = scandir($dir);
+
+  $cursos = array();
+
+  for ($i = 0; $i < count($files1); $i++) {
+  	if ($files1[$i] == "." || $files1[$i] == "..") continue;
+  	array_push($cursos, $files1[$i]);
+  }
+  return $cursos;
+}
+
+function qualVersaoDoIVProg ($arquivo) {
+	$handle = fopen("temp/" . $arquivo, "r");
+	$menu = false;
+
+	if ($handle) {
+	    while (($line = fgets($handle)) !== false) {
+	        if ( strpos($line, "fluid") !== false) {
+  				$menu = true;
+  				break;
+  			}
+	    }
+	    fclose($handle);
+	} else {
+	    echo "ERRO AO LER O ARQUIVO";
+	}
+
+	if ($menu) {
+		return "menu";
+	} else {
+		return "contexto";
+	}
+}
+
+function pegarLogsDoAluno ($curso, $aluno, $exercicio) {
+	$zip = new ZipArchive;
+	$dir    = 'cursos/' . $curso;
+  	$files1 = scandir($dir);
+  	$nomes  = array();
+  	
+  	if (count($files1) < 3) {
+  		return null;
+  	}
+
+  	for ($i = 0; $i < count($files1); $i++) {
+  		if ($files1[$i] == "." || $files1[$i] == "..") continue;
+  		if ( strpos($files1[$i], $aluno) !== false ) {
+  			array_push($nomes, $files1[$i]);
+  		}
+  	}
+
+  	for ($i = 0; $i < count($nomes); $i++) {
+  		if ($nomes[$i] == "." || $nomes[$i] == "..") continue;
+  		$res = $zip->open($dir . '/' . $nomes[$i]);
+		if ($res === TRUE) {
+		  $zip->extractTo('temp/');
+		  $zip->close();
+		}
+  	}
+
+  	$dir    = 'temp';
+  	$files1 = scandir($dir);
+  	
+  	if (count($files1) < 3) {
+  		return null;
+  	}
+
+  	$arquivo = "";
+
+  	for ($i = 0; $i < count($files1); $i++) {
+  		if ($files1[$i] == "." || $files1[$i] == "..") continue;
+  		if ( strpos($files1[$i], $exercicio) !== false) {
+  			$arquivo = $files1[$i];
+  		} else {
+  			unlink($dir . '/' . $files1[$i]);
+  		}
+  	}
+
+  	return $arquivo;
+}
+
+function pegarLogsDoAlunoComoString ($arquivo) {
+	$handle = fopen("temp/" . $arquivo, "r");
+	$inicio = false;
+	$string_final = "";
+	if ($handle) {
+	    while (($line = fgets($handle)) !== false) {
+	        if ( strpos($line, "::logs::") !== false) {
+  				$inicio = true;
+  				continue;
+  			}
+  			if ($inicio) {
+  				$ex = explode(",", $line);
+  				if (count($ex) > 3) {
+  					$string_final .= $ex[1] . "," . $ex[2] . ",1,0\\n";
+  				}
+  			}
+	    }
+	    fclose($handle);
+	} else {
+	    echo "ERRO AO LER O ARQUIVO";
+	}
+
+	return $string_final;
+}
+
+function listarAlunos ($curso) {
+
+	$dir    = 'cursos/' . $curso;
+  	$files1 = scandir($dir);
+  	$nomes  = array();
+  	
+  	if (count($files1) < 3) {
+  		return null;
+  	}
+
+  	for ($i = 0; $i < count($files1); $i++) {
+  		if ($files1[$i] == "." || $files1[$i] == "..") continue;
+  		$ex = explode("-", $files1[$i]);
+  		
+  		$ja_existe = false;
+  		for ($j = 0; $j < count($nomes); $j ++) {
+  			if ($nomes[$j] == $ex[2]) {
+  				$ja_existe = true;
+  				break;
+  			}
+  		}
+
+  		if (!$ja_existe) {
+  			array_push($nomes, $ex[2]);
+  		}
+  	}
+
+  	return $nomes;
+}
+
+function listarExercicios ($curso) {
+	$zip = new ZipArchive;
+
+	$dir    = 'cursos/' . $curso;
+  	$files1 = scandir($dir);
+  	$exercicios  = array();
+  	
+  	if (count($files1) < 3) {
+  		return null;
+  	}
+
+  	for ($i = 0; $i < count($files1); $i++) {
+  		if ($files1[$i] == "." || $files1[$i] == "..") continue;
+  		$res = $zip->open($dir . '/' . $files1[$i]);
+		if ($res === TRUE) {
+		  $zip->extractTo('temp/');
+		  $zip->close();
+		}
+  	}
+
+  	$dir    = 'temp';
+  	$files1 = scandir($dir);
+  	
+  	if (count($files1) < 3) {
+  		return null;
+  	}
+
+  	for ($i = 0; $i < count($files1); $i++) {
+  		if ($files1[$i] == "." || $files1[$i] == "..") continue;
+
+	  	$exp = explode("-", $files1[$i]);
+	  	$fi = "";
+	  	for ($j = 0; $j < count($exp) - 2; $j++) {
+	  		$fi .= $exp[$j];
+	  		if ($j < (count($exp) - 3)) {
+	  			$fi .= "-";
+	  		}
+	  	}
+
+	  	$ja_existe = false;
+	  	for ($j = 0; $j < count($exercicios); $j++) {
+	  		if ($exercicios[$j] == $fi) {
+	  			$ja_existe = true;
+	  			break;
+	  		}
+	  	}
+
+	  	if (!$ja_existe) {
+	  		array_push($exercicios, $fi);
+	  	}
+
+	  	unlink($dir . '/' . $files1[$i]);
+  	}
+  	return $exercicios;
+}
+
+function instrucoes () {
+
+	return "<p class='text-reduced'>
+            <b>Instruções para inserir novos logs para análise:</b> 
+            <p>Em primeiro lugar, crie uma nova pasta no diretório cursos/, com o nome do curso que você pretende analisar.
+                Em seguida, insira nessa pasta recém-criada todos os arquivos .zip que foram gerados pelo iTarefa com os dados dos alunos.</p>
+            <p><b>Atenção!</b> Não altere nem o nome do arquivo gerado pelo iTarefa, pois o sistema segue o mesmo padrão.</p>
+          </p>";
+}
+
+?>

+ 91 - 0
index.php

@@ -0,0 +1,91 @@
+<?php
+
+require 'functions.php';
+
+$cursos = listarCursos();
+$encontrou = count($cursos) > 2;
+
+?>
+<!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>ivprog_log_analysis</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="./">ivprog_log_analysis - Ambiente de análise dos logs do 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="./" title=""></a>
+          </li>
+          </ul>
+      </div>
+    </nav>
+
+    <main role="main">
+      <div class="jumbotron ivprogh-desc">
+        <div class="container">
+          <?= instrucoes() ?>
+        </div>
+      </div>
+
+
+      <div class="container ivprog-container" style="padding: 3em; margin-top: 3em;">
+        <form action="process.php" method="get" novalidate>
+          <div class="form-group row">
+            <label for="inputname" class="col-sm-2 col-form-label">Curso:</label>
+            <div class="col-sm-10">
+              <select class="form-control" id="inputname" name="curso" <?= ($encontrou?"":"disabled") ?> >
+                <?php
+
+                  if ($encontrou) {
+                    for ($i = 0; $i < count($cursos); $i++) {
+                      echo "<option>" . $cursos[$i] . "</option>";
+                    }
+                  } else {
+                    echo "<option> Nenhum curso foi encontrado </option>";
+                  }
+                ?>
+              </select>
+            </div>
+        </div>
+      
+      <div class="form-group row">
+          <div class="offset-sm-2 col-sm-10">
+            <button type="button" class="btn btn-secondary" disabled="">Voltar</button>
+            <button type="submit" class="btn btn-primary" <?= ($encontrou?"":"disabled") ?>>Continuar</button>
+            <span class="reported" style="color: green; font-size: 120%;"></span>
+            <span class="error" style="color: red; font-size: 120%;"></span>
+          </div>
+        </div>
+
+        </form>
+      </div>
+
+
+      <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.bundle.min.js"></script>
+
+
+    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/octicons/3.5.0/octicons.min.css">
+  </body>
+</html>

ファイルの差分が大きいため隠しています
+ 54220 - 0
ivprog_contexto/build/ivprog.bundle.js


ファイルの差分が大きいため隠しています
+ 1 - 0
ivprog_contexto/build/ivprog.bundle.js.map


+ 71 - 0
ivprog_contexto/css/ivprog-term.css

@@ -0,0 +1,71 @@
+.ivprog-term-div {
+  background-color: black;
+  width: 100%;
+  height: 12rem;
+  overflow-y: scroll;
+}
+
+.ivprog-term-userText {
+  color: white;
+}
+
+.ivprog-term-info {
+  color: green;
+}
+
+.ivprog-term-error {
+  color: red;
+}
+
+.ivprog-term-input {
+  font-family: 'Courier New', Courier, monospace;
+  font-weight: 500;
+  background-color: inherit;
+  border: 0;
+  color: white;
+}
+
+.ivprog-term-div > .ivprog-term-input, .ivprog-term-div > .ivprog-term-userText,
+.ivprog-term-div > .ivprog-term-info, .ivprog-term-div, .ivprog-term-error {
+  padding-left: 20px;
+}
+
+#ivprog-term {
+  border: 1px solid gray;
+  background: black;
+  margin-top: -30px;
+  position: relative;
+  padding: 5px;
+}
+#ivprog-term i {
+  margin-left: 5px;
+  cursor: pointer;
+}
+.div_toggle_console {
+  cursor: pointer;
+}
+.ivprog-term-active {
+  box-shadow: 0 0 5px rgba(81, 203, 238, 1) !important;
+  border: 3px solid rgba(81, 203, 238, 1) !important;
+}
+
+.ivprog-term-div {
+  overflow:scroll;
+}
+
+.ivprog-term-div::-webkit-scrollbar {
+    width: 12px;
+}
+ 
+.ivprog-term-div::-webkit-scrollbar-track {
+    -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); 
+    -webkit-border-radius: 10px;
+    border-radius: 10px;
+}
+ 
+.ivprog-term-div::-webkit-scrollbar-thumb {
+    -webkit-border-radius: 10px;
+    border-radius: 10px;
+    background: green;
+    -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.5); 
+}

+ 863 - 0
ivprog_contexto/css/ivprog-visual-1.0.css

@@ -0,0 +1,863 @@
+html {
+  height: 100%;
+}
+
+body {
+  height: 100%;
+}
+
+.ui.raised.container.segment.div_to_body {
+  height: 92%;
+  padding: 10px;
+  padding-left: 6px;
+  padding-right: 6px;
+  background-color: #1279c6;
+}
+
+.ivprog_visual_panel {
+	height: 96%;
+	overflow: auto;
+	overflow-x: auto;
+}
+
+.ivprog_textual_code {
+	width: 100%;
+	min-height: 500px;
+	resize: none;
+	background-color: white;
+}
+
+.main_title h2 {
+	margin: 0;
+	color: white;
+}
+.main_title span {
+	font-size: 80%;
+	font-style: italic;
+}
+.ivprog_format_info {
+	cursor: pointer;
+	margin-left: 10px;
+}
+.ivprog_visual_panel {
+	border: 2px solid #A0A0A0;
+	background-color: red;
+}
+
+.ui.container.main_title {
+	float: left;
+	width: 200px;
+}
+.ui.container.content_margin {
+	margin-top: 10px;
+}
+.content_margin .content_sub_margin {
+	display: inline; 
+    margin-left: 34%;
+	margin-top: 50px;
+}
+.ui.icon.menu.center.aligned.container {
+	width: 438px;
+	margin-top: -10px;
+}
+
+.ghost {
+  opacity: .5;
+  background: #C8EBFB;
+}
+
+/* editor visual: **/
+
+.function_signature_div,
+.function_close_div {
+	font-weight: bold;
+	color: black;
+}
+.ui.selection.data_types_dropdown.visible.dropdown>.text:not(.default),
+.ui.selection.parameter_data_types_dropdown.visible.dropdown>.text:not(.default) {
+	font-weight: bold;
+}
+.ui.selection.data_types_dropdown.dropdown,
+.ui.selection.parameter_data_types_dropdown.dropdown {
+	padding-bottom: 0;
+}
+
+.ui.fluid.dropdown.data_types_dropdown {
+	display: inline;
+	width: 150px;
+	border: none;
+	background: none;
+}
+
+.ui.fluid.dropdown.parameter_data_types_dropdown {
+	display: inline;
+	border: none;
+	background: none;
+}
+
+.ui.fluid.dropdown.data_types_dropdown.selection .dropdown.icon,
+.ui.fluid.dropdown.parameter_data_types_dropdown.selection .dropdown.icon {
+	font-size: 1em;
+}
+
+.function_close_div {
+	margin-left: 20px;
+}
+
+.command_div {
+	margin-left: 16px;
+}
+
+.function_draggable_div {
+	width: 16px;
+	float: left;
+}
+
+.function_draggable_div img {
+	margin-bottom: -4px;
+	margin-left: -2px;
+}
+
+.input_name_function{
+	min-width: 50px;
+}
+
+.text_attr_receives {
+	margin-left: 20px;
+	margin-right: 20px;
+}
+
+.menu_operations {
+	margin-left: 10px;
+	margin-right: 10px;
+}
+
+.case_commands_block {
+	/*border: 1px solid red;*/
+}
+
+.context_menu {
+	display: inline;
+	float: right; 
+	margin-right: 25px;
+	margin-top: -4px;
+}
+
+.case_div {
+	border: 1px solid gray;
+	margin-left: 30px;
+	padding-left: 5px;
+	margin-top: 5px;
+}
+
+.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,
+.all_elements_write, .container_var_element_control, .inline_add_command, .restart_expression, .div_parent_handler, .div_drag_writer {
+	display: inline;
+}
+
+.conditional_comands_block {
+	min-height: 10px;
+}
+
+.div_comment_text {
+	min-width: 100px;
+	font-style: italic;
+}
+
+.enable_edit_name_function, .add_parameter, .remove_parameter, .add_parameter_button, .remove_variable {
+	cursor: pointer;
+}
+
+[contenteditable="true"]:active,
+[contenteditable="true"]:focus,
+[contenteditable="true"]:hover {
+	border: 1px dashed #000;
+	background: white;
+}
+
+.ui.segment.ivprog_visual_panel {
+	padding: 3px;
+	margin-top: -5px;
+	background: white;
+}
+
+.ui.segment.function_div {
+	padding: 5px;
+	margin: 0;
+	margin-bottom: 5px;
+	background-color: #bddbff;
+}
+
+.ui.button.add_function_button,
+.ui.button.add_variable_button,
+.ui.button.add_command_button {
+	padding: 8px;
+	margin: 0;
+}
+
+.glyphicon-move {
+  cursor: move;
+  cursor: -webkit-grabbing;
+}
+
+.glyphicon.glyphicon-move {
+	float: left;
+}
+
+.remove_function_button, .minimize_function_button, .add_var_top_button, .add_command_top_button {
+	float: right;
+}
+
+.ui.icon.button.remove_function_button,
+.ui.icon.button.minimize_function_button {
+	background: none;
+	padding: 0;
+	margin-top: 12px;
+}
+
+.ui.segment.variables_list_div,
+.ui.segment.commands_list_div {
+	padding: 5px;
+	margin: 0;
+	margin-left: 30px;
+	width: calc(100% - 30px);
+	background-color: #f9f9f9;
+	min-height: 30px;
+}
+
+.ui.segment.variables_list_div {
+	margin-top: 5px;
+}
+
+.ui.labeled.icon.button.add_variable_button,
+.ui.labeled.icon.button.add_command_button {
+	
+}
+
+.program_signature {
+	font-weight: bold;
+	margin: -3px 0 10px -5px;
+}
+
+.program_final {
+	font-weight: bold;
+	margin: 5px 0 0 -5px;
+}
+
+.parameters_list {
+	display: inline;
+}
+
+.parameter_type {
+	margin-left: 10px;
+    margin-right: 15px;
+}
+
+.function_return .dropdown .icon, .parameter_type .dropdown .icon {
+	margin-left: 6px;
+}
+.tabela_var {
+	display: inline;
+}
+.buttons_manage_columns i, .tr_manage_lines i {
+	cursor: pointer;
+	display: inline;
+}
+div.buttons_manage_columns {
+	display: inline;
+}
+.tr_manage_lines {
+	text-align: center;
+}
+.div_valor_var {
+	display: inline;
+}
+.ui.comment span {
+	font-style: italic;
+}
+.ui.comment, .ui.reader, .ui.writer, .ui.attribution, .ui.iftrue, .ui.repeatNtimes, .ui.whiletrue, .ui.dowhiletrue, .ui.switch, .ui.functioncall,
+.ui.return {
+	padding: 5px;
+	margin: 5px;
+	background: #f7f2c9;
+    border: 2px solid #4d4be3;
+    border-radius: 0.25em;
+    box-shadow: 1px 1px;
+}
+.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;
+}
+
+.function_signature_div {
+	min-height: 40px;
+	padding-top: 8px;
+}
+
+.move_function {
+	margin-top: 9px;
+}
+
+.div_start_minimize_v {
+	float: right;
+	width: 22px; 
+	height: 10px;
+}
+
+.global_var {
+	margin-bottom: 7px;
+}
+
+.list_globals, .global_const {
+	display: inline;
+}
+
+.created_element {
+	position: absolute;
+	width: 50%;
+	z-index: 99999999;
+	opacity: .8;
+	cursor: move;
+}
+
+.width-dynamic {
+	min-width: 100px;
+}
+
+.ui.icon.plus.square.outline.icon_add_item_to_writer {
+	margin-right: 10px;
+	margin-left: 10px;
+	cursor: pointer;
+}
+
+.button_remove_command, .button_refresh_attribution {
+	float: right;
+	cursor: pointer;
+}
+
+.expression_drag {
+	cursor: col-resize;
+	border: 2px gray solid;
+	display: inline;
+	width: 5px;
+}
+
+.ui.icon.red.exclamation.triangle.error_icon {
+	float: left;
+    margin-left: -1.6em;
+    z-index: 10;
+    position: absolute;
+    font-size: 1.5em;
+}
+
+.height_100 {
+  height: 100%;
+}
+
+.default_visual_title {
+  display: none;
+}
+
+.expandingArea textarea {
+	min-height: 30px;
+	resize: none;
+	padding: 5px;
+}
+
+.ui table .btn_actions {
+	text-align: center;
+}
+
+.button_remove_case {
+	cursor: pointer;
+	padding: 3px;
+}
+
+.ui.button_add_case {
+	margin-top: 10px;
+}
+.accordion {
+	margin: auto;
+}
+
+.global_container:hover, 
+.variable_container:hover {
+	border: 2px solid gray;
+	padding-left: 8px;
+	padding-right: 8px;
+	padding-top: 5px;
+	padding-bottom: 4px;
+}
+
+.ui.label.function_name_parameter:hover {
+	border: 2px solid gray;
+	padding: 5px 6px 5px 6px;
+}
+
+.ui.label.function_name_parameter {
+	padding: 7px 8px 7px 8px;
+}
+
+.global_container:hover,  .variable_container:hover {
+	margin-bottom:  4px !important;
+}
+
+.global_container .global_type, .editing_name_var, .global_container .span_value_variable,
+.variable_container .variable_type,  .variable_container .span_value_variable,
+.ui.dropdown.function_return, div.function_name_div_updated,
+.ui.dropdown.parameter_type, .parameter_div_edit {
+	background: #cecece;
+	border-radius: 5px;
+	padding: 4px;
+	margin-left: 5px;
+	margin-right: 5px;
+}
+.parameter_div_edit {
+	padding-bottom: 2px;
+	padding-top: 2px;
+}
+.ui.dropdown.parameter_type {
+
+}
+div.function_name_div_updated {
+	padding-top: 5px;
+	padding-bottom: 5px;
+	margin-right: 10px;
+}
+.function_name_div_updated .name_function_updated {
+	padding-left: 10px;
+    padding-right: 10px;
+}
+.variable_container .variable_type {
+	padding: 5px;
+	margin-left: 0;
+	margin-right: 3px;
+}
+
+.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;
+	color: #fff;
+	z-index: 999999;
+}
+
+.editing_name_var {
+	min-width: 40px;
+	padding-top: 3px;
+	padding-bottom: 3px;
+}
+
+.global_container .global_type:active, 
+.variable_container .variable_type:active,
+.ui.dropdown.function_return:active, 
+div.function_name_div_updated:active,
+.ui.dropdown.parameter_type:active {
+	background: #636363;
+	color: #fff;
+}
+
+.global_container i {
+	cursor: pointer;
+}
+
+.global_container .ui.icon.plus.square.outline, .global_container .ui.icon.minus.square.outline {
+	font-size: 120%;
+}
+
+.character_equals {
+	vertical-align: sub;
+    font-size: 150%;
+}
+
+.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 > .yellow.icon.times.remove_global, .variable_container:hover > .yellow.icon.times.remove_variable,
+.function_name_parameter:hover > .yellow.icon.times.remove_parameter {
+	opacity: 1;
+}
+
+.tr_manage_lines {
+	padding-top: 10px;
+}
+
+.ui.icon.button.add-globalVar-button.add_global_button {
+	padding: 7px;
+    margin-bottom: 4px;
+    padding-bottom: 9px;
+}
+.all_functions {
+	margin-top: -5px;
+}
+.only_in_frame {
+	position: absolute;
+    z-index: 9999;
+    width: 90px;
+    top: 5px;
+    left: 5px;
+    opacity: .6;
+}
+.only_in_frame:hover {
+	opacity: 1;
+}
+.only_in_frame:hover span {
+	display: block;
+}
+.only_in_frame span {
+	display: none;
+	margin-top: -5px;
+}
+.ui.container.main_title {
+	width: 85px;
+}
+.ui.label.global_container {
+	margin-bottom: 3px;
+}
+.ui.label.variable_container {
+	margin-bottom: 3px;
+}
+.created_div_valor_var {
+	display: inline-block;
+}
+.ui.dropdown.function_return {
+	padding-left: 15px;
+    padding-right: 15px;
+    margin-left: 10px;
+    margin-right: 10px;
+}
+.parethesis_function {
+	font-size: 120%;
+}
+
+.var_value_menu_div,
+.attribution .var_attributed,
+.component_element,
+.conditional_expression .expression_element,
+.menu_start_rendered,
+.attribution_expression .variable_attribution,
+.render_style_param,
+.attribution_expression .div_expression_st:not(:empty),
+.incrementation_field .incrementation_variable,
+.incrementation_field .first_operand:not(:empty),
+.incrementation_field .operator:not(:empty),
+.incrementation_field .second_operand:not(:empty) {
+	background: #e8e8e8;
+	border-radius: 5px;
+	min-width: 40px;
+	padding: 2px;
+    padding-left: 5px;
+    padding-right: 5px;
+    border: 1px solid gray;
+    box-shadow: 0 3px 3px 0 rgba(0, 0, 0, 0.2), 0 3px 3px 0 rgba(0, 0, 0, 0.19);
+    color: black;
+}
+.menu_start_rendered {
+	padding-left: 12px;
+}
+.menu_start_rendered i {
+	width: 1.5em;
+    margin-right: -1em;
+}
+.row_container:hover, .column_container:hover {
+	background: #cecece;
+}
+
+.column_container, .row_container {
+	border-radius: 4px;
+    border: 1px solid gray;
+    padding: 1px 2px 1px 2px;
+    background: #e8e8e8;
+
+    box-shadow: 0 3px 3px 0 rgba(0, 0, 0, 0.2), 0 3px 3px 0 rgba(0, 0, 0, 0.19);
+}
+
+.var_value_menu_div div i {
+	color: black;
+}
+
+.span_command_spec {
+	color: black;
+	font-weight: bold;
+	font-size: 110%;
+}
+
+.ui.comment.command_container .var_value_menu_div {
+	display: inline-block;
+	width: 93%;
+}
+
+.ui.comment.command_container .var_value_menu_div .variable_rendered,
+.ui.comment.command_container .var_value_menu_div .value_rendered {
+    width: 100%;
+    cursor: text;
+    font-style: italic;
+}
+
+.ui.comment.command_container .var_value_menu_div {
+	cursor: text;
+}
+
+.ui.comment.command_container .var_value_menu_div {
+	background: none;
+	border-radius: 0;
+    border: 0px solid gray;
+    box-shadow: none;
+    padding: 0px;
+    font-size: 110%;
+}
+.ui.comment.command_container .var_name,
+.ui.comment.command_container .value_rendered {
+	color: rgba(0,0,0,.6);
+}
+.ui.comment.command_container .var_value_menu_div input {
+    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_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;
+}
+.ui.segment:first-child {
+	margin-top: 1em !important;
+}
+div.ui.checkbox.transition.visible {
+	margin-bottom: 1em;
+}
+.var_menu_select_content_error {
+	background: #ff0000;
+    color: white !important;
+    border: 2px solid #3125ee;
+}
+.ui.comment:hover, .ui.reader:hover, .ui.writer:hover, .ui.attribution:hover, .ui.functioncall:hover,
+.ui.return:hover {
+    background: #f2e67f;
+}
+
+.ui.iftrue:hover, .ui.repeatNtimes:hover, .ui.whiletrue:hover, .ui.dowhiletrue:hover, .ui.switch:hover {
+	background: #c6c8f2;
+}
+
+.ui.iftrue, .ui.repeatNtimes, .ui.whiletrue, .ui.dowhiletrue, .ui.switch {
+    background: #787fe721;
+}
+.ui.popup.invalid-identifier {
+	background: #ff3232;
+    color: white;
+    font-weight: bold;
+    border: 1px solid black;
+}
+.ui.popup.invalid-identifier:before {
+	background: #ff3232;
+	border-right: 1px solid black;
+    border-bottom: 1px solid black;
+}
+.ui.popup.invalid-identifier i.ui.icon.inverted.exclamation.triangle.yellow {
+	margin-left: -.5em;
+    margin-right: .4em;
+}
+.ui.repeatNtimes.command_container .ui.block_commands, 
+.ui.whiletrue.command_container .ui.block_commands {
+	margin-top: .8em;
+}
+
+.ui.restart_expression {
+	margin-left: .4em;
+    cursor: pointer;
+    color: brown;
+}
+
+.div_parent_handler {
+	padding-top: 5px;
+    padding-bottom: 6px;
+    background: #7a7acf;
+    border-radius: 4px;
+}
+
+.div_parent_handler i.times {
+	margin-left: .3em;
+	cursor: pointer;
+}
+
+.div_parent_handler i.ellipsis {
+	cursor: move;
+}
+
+.div_parent_handler i.handler {
+	opacity: 0;
+}
+
+.div_parent_handler:hover i.handler {
+	opacity: 1;
+}
+
+.ui.block_commands {
+    min-height: 20px !important;
+    padding-top: 5px !important;
+}

+ 86 - 0
ivprog_contexto/i18n/en/error.json

@@ -0,0 +1,86 @@
+{
+  "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.",
+  "exceeded_input_request": "The amount of requests exceeded the amount of available inputs"
+}

+ 9 - 0
ivprog_contexto/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
ivprog_contexto/i18n/en/message.json

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

+ 135 - 0
ivprog_contexto/i18n/en/ui.json

@@ -0,0 +1,135 @@
+{
+  "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": "Relational 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",
+  "text_none_variable":"There is no declared variable",
+  "text_none_variable_instruction":"Create a new variable to use it",
+  "text_ivprog_description":"Interactive Visual Programming on the Internet",
+  "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": "Construct any logical condition",
+  "math": "Mathematic",
+  "text_t": "Text",
+  "inform_valid_name": "Inform a valid name!",
+  "inform_valid_content": "Enter some content!",
+  "inform_valid_expression": "Construct the logical condition!",
+  "inform_valid_name_duplicated": "This name is already in use by other function.",
+  "inform_valid_global_duplicated": "A global variable with this name already exists.",
+  "inform_valid_variable_duplicated" : "A local variable with this name already exists.",
+  "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",
+  "text_ivprog_version":"Version"
+}

+ 86 - 0
ivprog_contexto/i18n/es/error.json

@@ -0,0 +1,86 @@
+{
+  "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.",
+  "exceeded_input_request": "The amount of requests exceeded the amount of available inputs"
+}

+ 9 - 0
ivprog_contexto/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
ivprog_contexto/i18n/es/message.json

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

+ 140 - 0
ivprog_contexto/i18n/es/ui.json

@@ -0,0 +1,140 @@
+{
+  "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": "Relational 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",
+  "text_none_variable":"There is no declared variable",
+  "text_none_variable_instruction":"Create a new variable to use it",
+  "text_ivprog_description":"Interactive Visual Programming on the Internet",
+  "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": "Construct any logical condition",
+  "$sin": "sen",
+  "math": "Mathematic",
+  "text": "Text",
+  "arrangement": "Arrangement",
+  "conversion": "Conversion",
+  "math": "Mathematic",
+  "inform_valid_name": "Inform a valid name!",
+  "inform_valid_content": "Enter some content!",
+  "inform_valid_expression": "Construct the logical condition!",
+  "inform_valid_name_duplicated": "This name is already in use by other function.",
+  "inform_valid_global_duplicated": "A global variable with this name already exists.",
+  "inform_valid_variable_duplicated" : "A local variable with this name already exists.",
+  "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",
+  "text_ivprog_version":"Version"
+}

+ 117 - 0
ivprog_contexto/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
ivprog_contexto/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
+}

+ 86 - 0
ivprog_contexto/i18n/pt/error.json

@@ -0,0 +1,86 @@
+{
+  "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.",
+  "exceeded_input_request": "A quantidade de leituras requisitadas execedeu a quantidade de entradas disponíveis."
+}

+ 9 - 0
ivprog_contexto/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
ivprog_contexto/i18n/pt/message.json

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

+ 142 - 0
ivprog_contexto/i18n/pt/ui.json

@@ -0,0 +1,142 @@
+{
+  "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 Relacional",
+  "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",
+  "text_none_variable":"Nenhuma variável declarada",
+  "text_none_variable_instruction":"Antes de utilizar uma variável, é necessário criá-la",
+  "text_ivprog_description":"Programação Visual interativa na Internet",
+  "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": "Construir uma expressão lógica",
+  "$sin": "sen",
+  "math": "Matematica",
+  "text_t": "Texto",
+  "inform_valid_name": "Informe um nome válido!",
+  "inform_valid_content": "Informe o conteúdo!",
+  "inform_valid_expression": "Construa uma expressão lógica!",
+  "inform_valid_name_duplicated": "Este nome já está em uso por outra função!",
+  "inform_valid_global_duplicated": "Já existe uma variável global com o nome informado.",
+  "inform_valid_variable_duplicated" : "Já existe uma variável local com o nome informado.",
+  "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",
+  "text_ivprog_version":"Versão"
+}

BIN
ivprog_contexto/img/background-panel.png


+ 122 - 0
ivprog_contexto/index.html

@@ -0,0 +1,122 @@
+<!DOCTYPE html>
+<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">
+    <script src="js/jquery-3.3.1.min.js"></script>
+    <script src="js/iassign-integration-functions.js"></script>
+    <script src="build/ivprog.bundle.js"></script>
+    <script src="js/semantic/semantic.min.js"></script>
+    <script src="js/semantic/semantic-buttons.js"></script>
+
+    <script src="js/jquery-ui.js"></script>
+    <script src="js/Sortable.js"></script>
+    
+  </head>
+  <body>
+
+    <div class="ui height_100 add_accordion" id="ui_main_div">
+
+      <div class="title default_visual_title">
+        <i class="dropdown icon"></i>
+      </div>
+
+    <div class="content height_100">
+   
+      <div class="ui raised container segment div_to_body">
+
+        <div class="ui container main_title only_in_frame">
+          <h2>iVProg</h2>
+        </div>
+
+        <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 disabled">
+            <i class="upload icon"></i>
+          </a>
+          <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 disabled">
+            <i class="redo icon"></i>
+          </a>
+          <a class="item run_button">
+            <i class="play icon"></i>
+          </a>
+          <a class="item assessment assessment_button">
+            <i class="check icon"></i>
+          </a>
+          <!--<a class="item expand_button">
+            <i class="expand arrows alternate icon"></i>
+          </a>-->
+          <a class="item help_button">
+            <i class="help icon"></i>
+          </a>
+        </div>
+
+        <div class="ui one column container segment ivprog_visual_panel loading">
+
+          <div class="global_var">
+            <i class="icon plus circle purple add_global_button"></i>
+            <i class="icon circle white back"></i>
+
+            <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>
+
+          <div class="all_functions list-group" id="listWithHandle">
+
+          </div>
+
+
+          <div class="ui teal small labeled icon button add_function_button">
+            <data class="i18n" value="ui:btn_function">Function</data>
+            <i class="add icon"></i>
+          </div>
+          <div class="program_final"></div>
+
+        </div>
+
+
+        <div class="ui one column container segment ivprog_textual_panel loading" style="display: none;">
+          <textarea class="ivprog_textual_code" readonly></textarea>
+        </div>
+
+        <div id='ivprog-term' class="six column wide">
+          <div class="div_toggle_console"><i class="inverted terminal icon green button_toggle_console"></i></div>
+        </div>
+      </div>
+
+    </div>
+
+  </div>
+
+    <script>
+      $(document).ready(() => {
+        ivprogCore.LocalizedStrings.updateTagText();
+        ivprogCore.initVisualUI();
+        prepareEnvironment();
+      });
+    </script>
+
+  </body>
+</html>

ファイルの差分が大きいため隠しています
+ 1491 - 0
ivprog_contexto/js/Sortable.js


+ 92 - 0
ivprog_contexto/js/assessment/ivprogAssessment.js

@@ -0,0 +1,92 @@
+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(curr), 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( error => {
+      this.domConsole.err(`Execução do caso de teste ${name + 1} falhou!`);// try and show error messages through domconsole
+      this.domConsole.err(error.message);
+      return Promise.resolve(accumulator);
+    });
+  }
+
+  partialEvaluateTestCase (prog, inputList, outputList, name) {
+    return this.evaluateTestCase.bind(this, prog, inputList, outputList, name);
+  }
+
+  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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/js/ast/commands/break.js

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

+ 18 - 0
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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].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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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;
+  }
+}

ファイルの差分が大きいため隠しています
+ 1182 - 0
ivprog_contexto/js/ast/ivprogParser.js


+ 35 - 0
ivprog_contexto/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
ivprog_contexto/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;
+  }
+
+}

+ 500 - 0
ivprog_contexto/js/iassign-integration-functions.js

@@ -0,0 +1,500 @@
+// Função para ler parâmetros informados pelo iTarefa via URL
+// Apesar de não ser obrigatório, será muito útil para capturar os parâmetros
+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 parâmetros informados pelo iTarefa
+// Observe que para cada parâmetro, é 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
+//localStorage.setItem('ivprog.lang', iLMparameters.lang);
+
+// Função chamada pelo iTarefa quando o professor finaliza a criação da atividade
+// ou quando o aluno finaliza a resolução do exercício
+// O retorno é um JSON com os dados do exercício ou da resolução
+// Esse retorno será armazenado no banco de dados do Moodle, pelo iTarefa
+function getAnswer () {
+    // Se o parâmetro "iLM_PARAM_SendAnswer" for false,
+    // então trata-se de resolução 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, function(key, value) {
+            if (key == 'dom_object') {
+                return;
+            }
+            return value; 
+        });
+
+        contentToSend += '\n::logs::';
+        contentToSend += getTrackingLogs();
+
+        return contentToSend;
+
+    } else {
+        // Montar o retorno com a criação 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, function(key, value) {
+                
+                if (key == 'dom_object') {
+                    return;
+                }
+                return value; 
+            });
+        }
+
+        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;
+}
+
+// Função chamada pelo iTarefa para receber a nota do aluno na atividade
+// O retorno é um valor entre 0.0 e 1.0
+function getEvaluation () {
+    if (iLMparameters.iLM_PARAM_SendAnswer == 'false') {
+        // A chamada do método abaixo é obrigatória!
+        // 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;
+
+// Função para que o iMA leia os dados da atividade fornecidos pelo iTarefa
+function getiLMContent () {
+
+    // O parâmetro "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) {
+        // Aluno está trabalhando em alguma atividade:
+        if (iLMparameters.iLM_PARAM_SendAnswer == 'false') {
+            previousContent = data;
+            prepareActivityToStudent(data);
+        } else { // Professor está editando uma atividade:
+            previousContent = data;
+            prepareActivityToEdit(data);
+        }
+
+        window.block_render = false;
+        renderAlgorithm();
+    });
+}
+
+function prepareActivityToEdit (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;
+
+    for (var i = 0; i < testCases.length; i++) {
+        addTestCase(testCases[i]);
+    }
+
+    if (ilm_cont.split('\n::algorithm::')[1]) {
+        algorithm_in_ilm = ilm_cont.split('\n::algorithm::')[1].split('\n::logs::')[0];
+        $("input[name='include_algo']").prop('checked', true);
+        includePreviousAlgorithm();
+        renderAlgorithm();
+    }
+}
+
+function includePreviousAlgorithm () {
+    window.program_obj.functions = JSON.parse(algorithm_in_ilm).functions;
+    window.program_obj.globals = JSON.parse(algorithm_in_ilm).globals;
+
+    window.watchW.watch(window.program_obj.globals, function(){
+      if (window.insertContext) {
+        setTimeout(function(){ renderAlgorithm(); }, 300);
+        window.insertContext = false;
+      } else {
+        renderAlgorithm();
+      }
+    }, 1);
+
+    for (var i = 0; i < window.program_obj.functions.length; i ++) {
+        window.watchW.watch(window.program_obj.functions[i].parameters_list, function(){
+          if (window.insertContext) {
+            setTimeout(function(){ renderAlgorithm(); }, 300);
+            window.insertContext = false;
+          } else {
+            renderAlgorithm();
+          }
+        }, 1);
+
+        window.watchW.watch(window.program_obj.functions[i].variables_list, function(){
+          if (window.insertContext) {
+            setTimeout(function(){ renderAlgorithm(); }, 300);
+            window.insertContext = false;
+          } else {
+            renderAlgorithm();
+          }
+        }, 1);
+
+        if (window.program_obj.functions[i].is_main) {
+            window.program_obj.functions[i].name = LocalizedStrings.getUI("start");
+        }
+    }
+    window.watchW.watch(window.program_obj.functions, function(){
+      if (window.insertContext) {
+        setTimeout(function(){ renderAlgorithm(); }, 300);
+        window.insertContext = false;
+      } else {
+        renderAlgorithm();
+      }
+    }, 1);
+}
+
+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;
+
+    if (ilm_cont.split('\n::algorithm::')[1]) {
+        algorithm_in_ilm = ilm_cont.split('\n::algorithm::')[1].split('\n::logs::')[0];
+        includePreviousAlgorithm();
+    }
+    $('.assessment_button').removeClass('disabled');
+    renderAlgorithm();
+}
+
+// Função para organizar se para criação, visualização ou resolução 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, então trata-se de resolução de atividade,
+    // portanto, a "DIV" de resolução é 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 não esteja em modo de resolução de atividade, a visualização no momento
+        // é para a elaboração de atividade:
+        //$('.elaboracao').css("display","block");
+
+        // Se possuir o parâmetro iLMparameters.iLM_PARAM_Assignment, o professor
+        // está editando uma atividade:
+        if (iLMparameters.iLM_PARAM_Assignment) {
+            getiLMContent();
+        }
+    }
+
+    if (!testCases) {
+        $('.assessment_button').addClass('disabled');
+    }
+
+});
+
+// Função 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="content_margin"></div>').insertBefore($('.add_accordion').find('.content').find('.div_to_body'));
+
+    $('<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>').insertAfter('.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'));
+
+    if (inIframe()) {
+        $('.ui.styled.accordion').css('width', '96%');
+    }
+}
+
+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 (test_case = null) {
+    var new_row = null;
+    if (test_case) {
+        var text_row = '';
+
+        text_row += '<tr><td class="counter"></td><td class="expandingArea"><textarea rows="'+test_case.input.length+'" name="input" class="text_area_input">';
+
+        for (var i = 0; i < test_case.input.length; i ++) {
+            text_row += test_case.input[i];
+            if ((i + 1) < test_case.input.length) {
+                text_row += '\n';
+            }
+        }
+        
+        text_row += '</textarea></td><td class="expandingArea"><textarea rows="'+test_case.output.length+'" name="output" class="text_area_output">';
+
+        for (var i = 0; i < test_case.output.length; i ++) {
+            text_row += test_case.output[i];
+            if ((i + 1) < test_case.output.length) {
+                text_row += '\n';
+            }
+        }
+
+        text_row += '</textarea></td><td class="btn_actions"><div class="ui button_remove_case"><i class="red icon times large"></i></div></td></tr>';
+
+        new_row = $(text_row);
+    } else {
+        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();
+    });
+
+    new_row.find('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 (test_case == null) {
+        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][3] === 1) {
+            ret += ',' + trackingMatrix[i][3] + ',"' + trackingMatrix[i][4] + '"';
+        }
+    }
+    return ret;
+}
+
+// Tracking mouse movements
+var trackingMatrix = [];
+
+function adCoords(e, code){
+    var x = e.pageX; 
+    var y = e.pageY;
+    if (code === 1) {
+        return [new Date().getTime(), x, y, code, e.target.classList['value']];
+    } else {
+        return [x, y, code];
+    }
+}
+
+$( document ).ready(function() {
+
+    if (inIframe()) {
+        orderIcons();
+        orderWidth();
+    }
+    renderAlgorithm();
+});
+
+function orderWidth() {
+    $('.ui.raised.container.segment.div_to_body').css('width', '100%');
+    $('.ui.one.column.container.segment.ivprog_visual_panel').css('width', '100%');
+}
+
+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;
+    }
+}
+
+
+function full_screen() {
+    // check if user allows full screen of elements. This can be enabled or disabled in browser config. By default its enabled.
+    //its also used to check if browser supports full screen api.
+    if("fullscreenEnabled" in document || "webkitFullscreenEnabled" in document || "mozFullScreenEnabled" in document || "msFullscreenEnabled" in document) {
+        if(document.fullscreenEnabled || document.webkitFullscreenEnabled || document.mozFullScreenEnabled || document.msFullscreenEnabled) {
+            var element = document.getElementById("ui_main_div");
+            //requestFullscreen is used to display an element in full screen mode.
+            if("requestFullscreen" in element) {
+                element.requestFullscreen();
+            } 
+            else if ("webkitRequestFullscreen" in element) {
+                element.webkitRequestFullscreen();
+            } 
+            else if ("mozRequestFullScreen" in element) {
+                element.mozRequestFullScreen();
+            } 
+            else if ("msRequestFullscreen" in element) {
+                element.msRequestFullscreen();
+            }
+        }
+    } else {
+        $('.expand_button').addClass('disabled');
+    }
+}

+ 139 - 0
ivprog_contexto/js/io/domConsole.js

@@ -0,0 +1,139 @@
+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) {
+    const output = ""+text;
+    output.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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/js/io/input.js

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

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

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

ファイルの差分が大きいため隠しています
+ 2 - 0
ivprog_contexto/js/jquery-3.3.1.min.js


ファイルの差分が大きいため隠しています
+ 18706 - 0
ivprog_contexto/js/jquery-ui.js


ファイルの差分が大きいため隠しています
+ 119 - 0
ivprog_contexto/js/jquery.json-editor.min.js


+ 13 - 0
ivprog_contexto/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
+}

+ 213 - 0
ivprog_contexto/js/processor/compatibilityTable.js

@@ -0,0 +1,213 @@
+import { Types } from './../typeSystem/types';
+import { Operators } from './../ast/operators';
+import { MultiType } from '../typeSystem/multiType';
+import { Config } from '../util/config';
+
+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) {
+        if(Config.enable_type_casting) {
+          if(leftExpressionType.isCompatible(Types.INTEGER) || leftExpressionType.isCompatible(Types.REAL)) {
+            if(rightExpressionType.isCompatible(Types.INTEGER) || rightExpressionType.isCompatible(Types.REAL)) {
+              return new MultiType([Types.INTEGER, Types.REAL]);
+            }
+          }
+        }
+        return Types.UNDEFINED;
+      } else {
+        return new MultiType(newMulti)
+      }
+    } else if(leftExpressionType instanceof MultiType) {
+      if(leftExpressionType.isCompatible(rightExpressionType)) {
+        return rightExpressionType;
+      } else {
+        if(Config.enable_type_casting) {
+          if(leftExpressionType.isCompatible(Types.INTEGER) || leftExpressionType.isCompatible(Types.REAL)) {
+            if(rightExpressionType.isCompatible(Types.INTEGER) || rightExpressionType.isCompatible(Types.REAL)) {
+              return rightExpressionType;
+            }
+          }
+        }
+        return Types.UNDEFINED;
+      }
+    } else if(rightExpressionType instanceof MultiType) {
+      if(rightExpressionType.isCompatible(leftExpressionType)) {
+        return leftExpressionType;
+      } else {
+        if(Config.enable_type_casting) {
+          if(leftExpressionType.isCompatible(Types.INTEGER) || leftExpressionType.isCompatible(Types.REAL)) {
+            if(rightExpressionType.isCompatible(Types.INTEGER) || rightExpressionType.isCompatible(Types.REAL)) {
+              return leftExpressionType;
+            }
+          }
+        }
+        return Types.UNDEFINED;
+      }
+    }
+    const resultType = infixMap.get(operator)[leftExpressionType.ord][rightExpressionType.ord];
+    if (resultType === null || resultType === undefined) {
+      if(Config.enable_type_casting) {
+        if(leftExpressionType.isCompatible(Types.INTEGER) || leftExpressionType.isCompatible(Types.REAL)) {
+          if(rightExpressionType.isCompatible(Types.INTEGER) || rightExpressionType.isCompatible(Types.REAL)) {
+            if(operator === Operators.MOD) {
+              return Types.INTEGER;
+            } else if (operator.ord >= 5 && operator.ord <= 10){
+              return Types.BOOLEAN;
+            }
+          }
+        }
+      }
+      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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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);
+  }
+}

ファイルの差分が大きいため隠しています
+ 1051 - 0
ivprog_contexto/js/processor/ivprogProcessor.js


+ 58 - 0
ivprog_contexto/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;
+ }
+ 

+ 47 - 0
ivprog_contexto/js/processor/lib/io.js

@@ -0,0 +1,47 @@
+import { StoreObject } from './../store/storeObject';
+import * as Commands from './../../ast/commands';
+import {toInt, toString, toBool, toReal, convertToString} from './../../typeSystem/parsers';
+import { Types } from './../../typeSystem/types';
+
+export function createOutputFun () {
+  const writeFunction = function (store, _) {
+    const val = store.applyStore('p1');
+    this.output.sendOutput(convertToString(val.value, val.type));
+    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.trunc());
+      } 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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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')
+});

+ 544 - 0
ivprog_contexto/js/processor/semantic/semanticAnalyser.js

@@ -0,0 +1,544 @@
+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';
+import { Config } from '../../util/config';
+import { Store } from '../store/store';
+
+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) {
+    console.log(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) && !Config.enable_type_casting)
+        || (!declaration.type.isCompatible(resultType) && Config.enable_type_casting
+        && !Store.canImplicitTypeCast(declaration.type, 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) {
+      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.value.toNumber(), literal.sourceInfo)
+          } else {
+            throw ProcessorErrorFactory.vector_line_outbounds_full(id, literal.value.length, lines.value.toNumber(), literal.sourceInfo)
+          }
+        } else if (lines.value.isNeg()) {
+          throw ProcessorErrorFactory.array_dimension_not_positive_full(literal.sourceInfo);
+        }
+      }
+      if (columns === null) {
+        // it's a vector...
+        literal.value.reduce((last, next) => {
+          const eType = this.evaluateExpressionType(next);
+          if (!last.canAccept(eType)) {
+            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);
+          }
+          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)) {
+          const columnValue = literal.value[0].value.length;
+          if (!columns.value.eq(columnValue)) {
+            if(type.dimensions > 1) {
+              throw ProcessorErrorFactory.matrix_column_outbounds_full(id, literal.value.length, columns.value.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, columns, 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;
+    } */
+    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) && !Config.enable_type_casting)
+          || (!resultType.isCompatible(typeInfo.type) && Config.enable_type_casting
+          && !Store.canImplicitTypeCast(typeInfo.type, resultType))) {
+          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];
+      const id = formalParam.id;
+      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) {
+          if(Config.enable_type_casting && !formalParam.byRef) {
+            if(resultType.isCompatible(Types.INTEGER) || resultType.isCompatible(Types.REAL)) {
+              if(formalParam.type.isCompatible(Types.INTEGER) || formalParam.type.isCompatible(Types.REAL)) {
+                continue;
+              }
+            }
+          }
+          throw ProcessorErrorFactory.invalid_parameter_type_full(id, param.toString(), param.sourceInfo);
+        }
+      } else if (resultType instanceof MultiType) {
+        if(!resultType.isCompatible(formalParam.type)) {
+          if(Config.enable_type_casting && !formalParam.byRef) {
+            if(resultType.isCompatible(Types.INTEGER) || resultType.isCompatible(Types.REAL)) {
+              if(formalParam.type.isCompatible(Types.INTEGER) || formalParam.type.isCompatible(Types.REAL)) {
+                continue;
+              }
+            }
+          }
+          throw ProcessorErrorFactory.invalid_parameter_type_full(id, param.toString(), param.sourceInfo);
+        }
+      } else if(!formalParam.type.isCompatible(resultType)) {
+        if(Config.enable_type_casting && !formalParam.byRef) {
+          if (Store.canImplicitTypeCast(formalParam.type, resultType)) {
+            continue;
+          }
+        }
+        throw ProcessorErrorFactory.invalid_parameter_type_full(id, param.toString(), param.sourceInfo);
+      }
+
+    }
+  }
+}

+ 97 - 0
ivprog_contexto/js/processor/store/store.js

@@ -0,0 +1,97 @@
+import { Modes } from './../modes';
+import { Types } from "./../../typeSystem/types";
+import { StoreObject } from './storeObject';
+
+export class Store {
+
+  static canImplicitTypeCast (castType, sourceType) {
+    if (castType.isCompatible(Types.INTEGER) || castType.isCompatible(Types.REAL)) {
+      if (sourceType.isCompatible(Types.INTEGER) || sourceType.isCompatible(Types.REAL)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  static doImplicitCasting (castType, stoObj) {
+    if(!Store.canImplicitTypeCast(castType, stoObj.type)) {
+      throw new Error("!!!Critical error: attempted to type cast invalid types");
+    }
+    if(Types.INTEGER.isCompatible(castType)) {
+      return new StoreObject(castType, stoObj.value.trunc());
+    } else {
+      return new StoreObject(castType, stoObj.value);
+    }
+  }
+
+  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 {
+        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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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
ivprog_contexto/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);
+}
+}

+ 4 - 0
ivprog_contexto/js/semantic/.versions

@@ -0,0 +1,4 @@
+jquery@1.11.3_2
+meteor@1.1.6
+semantic:ui-css@2.0.7
+underscore@1.0.3

+ 0 - 0
ivprog_contexto/js/semantic/LICENSE


この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません