فهرست منبع

Merge branch 'visualui' of LInE/ivprog into master

igorfelix 5 سال پیش
والد
کامیت
ddce796361
100فایلهای تغییر یافته به همراه2717 افزوده شده و 818 حذف شده
  1. 0 0
      .gitignore
  2. 1 0
      .ima_version.json
  3. 0 0
      .vscode/launch.json
  4. 0 0
      .vscode/settings.json
  5. 31 0
      algoritmo.ivph
  6. 2017 537
      build/ivprog.bundle.js
  7. 1 1
      build/ivprog.bundle.js.map
  8. 0 0
      css/ivprog-term.css
  9. 102 18
      css/ivprog-visual-1.0.css
  10. 0 0
      grammar/en/ivprog.g4
  11. 0 0
      grammar/en/langFunctions.js
  12. 0 0
      grammar/en/langLibs.js
  13. 0 0
      grammar/es/ivprog.g4
  14. 0 0
      grammar/es/langFunctions.js
  15. 0 0
      grammar/es/langLibs.js
  16. 0 0
      grammar/index.js
  17. 0 0
      grammar/pt/ivprog.g4
  18. 0 0
      grammar/pt/langFunctions.js
  19. 0 0
      grammar/pt/langLibs.js
  20. 67 13
      i18n/en/error.json
  21. 0 0
      i18n/en/index.js
  22. 2 1
      i18n/en/message.json
  23. 11 3
      i18n/en/ui.json
  24. 88 2
      i18n/es/error.json
  25. 0 0
      i18n/es/index.js
  26. 2 1
      i18n/es/message.json
  27. 16 13
      i18n/es/ui.json
  28. 0 0
      i18n/i18n-database.json
  29. 0 0
      i18n/index.js
  30. 12 7
      i18n/pt/error.json
  31. 0 0
      i18n/pt/index.js
  32. 2 1
      i18n/pt/message.json
  33. 11 4
      i18n/pt/ui.json
  34. 0 0
      img/background-panel.png
  35. 58 60
      index.html
  36. 0 0
      ivprog.sublime-project
  37. 0 0
      js/Sortable.js
  38. 50 16
      js/assessment/ivprogAssessment.js
  39. 0 0
      js/ast/ASA.txt
  40. 0 0
      js/ast/commands/arrayAssign.js
  41. 0 0
      js/ast/commands/arrayDeclaration.js
  42. 0 0
      js/ast/commands/assign.js
  43. 0 0
      js/ast/commands/break.js
  44. 0 0
      js/ast/commands/case.js
  45. 0 0
      js/ast/commands/command.js
  46. 0 0
      js/ast/commands/commandBlock.js
  47. 0 0
      js/ast/commands/declaration.js
  48. 0 0
      js/ast/commands/doWhile.js
  49. 0 0
      js/ast/commands/for.js
  50. 0 0
      js/ast/commands/formalParameter.js
  51. 0 0
      js/ast/commands/function.js
  52. 0 0
      js/ast/commands/ifThenElse.js
  53. 0 0
      js/ast/commands/index.js
  54. 0 0
      js/ast/commands/return.js
  55. 0 0
      js/ast/commands/switch.js
  56. 0 0
      js/ast/commands/sysCall.js
  57. 0 0
      js/ast/commands/while.js
  58. 0 0
      js/ast/error/syntaxError.js
  59. 3 1
      js/ast/error/syntaxErrorFactory.js
  60. 0 0
      js/ast/expressions/arrayAccess.js
  61. 0 0
      js/ast/expressions/arrayLiteral.js
  62. 0 0
      js/ast/expressions/boolLiteral.js
  63. 0 0
      js/ast/expressions/expression.js
  64. 0 0
      js/ast/expressions/functionCall.js
  65. 0 0
      js/ast/expressions/index.js
  66. 0 0
      js/ast/expressions/infixApp.js
  67. 0 0
      js/ast/expressions/intLiteral.js
  68. 0 0
      js/ast/expressions/literal.js
  69. 0 0
      js/ast/expressions/realLiteral.js
  70. 1 1
      js/ast/expressions/stringLiteral.js
  71. 0 0
      js/ast/expressions/unaryApp.js
  72. 0 0
      js/ast/expressions/variableLiteral.js
  73. 12 3
      js/ast/ivprogParser.js
  74. 0 0
      js/ast/operators.js
  75. 0 0
      js/ast/sourceInfo.js
  76. 133 43
      js/iassign-integration-functions.js
  77. 2 1
      js/io/domConsole.js
  78. 0 0
      js/io/domInput.js
  79. 0 0
      js/io/domOutput.js
  80. 0 0
      js/io/input.js
  81. 0 0
      js/io/output.js
  82. 0 0
      js/jquery-3.3.1.min.js
  83. 0 0
      js/jquery-ui.js
  84. 0 0
      js/jquery.json-editor.min.js
  85. 9 2
      js/main.js
  86. 8 6
      js/processor/compatibilityTable.js
  87. 0 0
      js/processor/context.js
  88. 0 0
      js/processor/definedFunctions.js
  89. 38 54
      js/processor/error/processorErrorFactory.js
  90. 0 0
      js/processor/error/runtimeError.js
  91. 0 0
      js/processor/error/semanticError.js
  92. 9 10
      js/processor/ivprogProcessor.js
  93. 0 0
      js/processor/lib/arrays.js
  94. 1 1
      js/processor/lib/io.js
  95. 25 14
      js/processor/lib/lang.js
  96. 2 1
      js/processor/lib/math.js
  97. 0 0
      js/processor/lib/strings.js
  98. 0 0
      js/processor/modes.js
  99. 3 4
      js/processor/semantic/semanticAnalyser.js
  100. 0 0
      js/processor/store/store.js

+ 0 - 0
.gitignore


+ 1 - 0
.ima_version.json

@@ -0,0 +1 @@
+{ "version":"2019_03_01 12_50" }

+ 0 - 0
.vscode/launch.json


+ 0 - 0
.vscode/settings.json


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 31 - 0
algoritmo.ivph


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 2017 - 537
build/ivprog.bundle.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1 - 1
build/ivprog.bundle.js.map


+ 0 - 0
css/ivprog-term.css


+ 102 - 18
css/ivprog-visual-1.0.css

@@ -29,6 +29,7 @@ body {
 
 .main_title h2 {
 	margin: 0;
+	color: white;
 }
 .main_title span {
 	font-size: 80%;
@@ -153,7 +154,7 @@ body {
 .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 {
+.all_elements_write, .container_var_element_control, .inline_add_command, .restart_expression, .div_parent_handler, .div_drag_writer {
 	display: inline;
 }
 
@@ -279,11 +280,12 @@ div.buttons_manage_columns {
 }
 .ui.comment, .ui.reader, .ui.writer, .ui.attribution, .ui.iftrue, .ui.repeatNtimes, .ui.whiletrue, .ui.dowhiletrue, .ui.switch, .ui.functioncall,
 .ui.return {
-	border: 1px solid gray;
 	padding: 5px;
-	border-radius: 5px;
 	margin: 5px;
-	background: #f9f9f9;
+	background: #f7f2c9;
+    border: 2px solid #4d4be3;
+    border-radius: 0.25em;
+    box-shadow: 1px 1px;
 }
 .ui.repeatNtimes .separator_character {
 	margin-right: 10px;
@@ -353,7 +355,10 @@ div.buttons_manage_columns {
 
 .ui.icon.red.exclamation.triangle.error_icon {
 	float: left;
-    margin-left: -30px;
+    margin-left: -1.6em;
+    z-index: 10;
+    position: absolute;
+    font-size: 1.5em;
 }
 
 .height_100 {
@@ -642,12 +647,12 @@ div.function_name_div_updated:active,
 
 .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 {
+.ui.rail .icon.plus.circle, .ui.rail .icon.circle.back {
 	position: absolute;
 }
 .global_var .circle.add_global_button,
 .ui.add_var_context .icon.plus.circle,
-.inline_add_command .icon.plus.circle {
+.ui.rail .icon.plus.circle {
 	z-index: 10;
 	color: #bf80d4!important;
 	cursor: pointer;
@@ -655,14 +660,14 @@ div.function_name_div_updated:active,
 }
 .global_var i.back,
 .ui.add_var_context .icon.circle.back,
-.inline_add_command .icon.circle.back {
+.ui.rail .icon.circle.back {
 	z-index: 9;
 	color: white !important;
 }
 .ui.add_var_context{
 	margin-left: -4px;
 }
-.inline_add_command {
+.ui.rail {
 	color: #ab0054 !important;
 }
 
@@ -708,11 +713,11 @@ div.function_name_div_updated:active,
 	color: yellow;
 	font-size: 125%;
 }
-.inline_add_command .icon.plus.circle {
+.ui.rail .icon.plus.circle {
 	color: #ec9962 !important;
 }
-.inline_add_command .icon.plus.circle, 
-.inline_add_command .icon.circle.back,
+.ui.rail .icon.plus.circle, 
+.ui.rail .icon.circle.back,
 .ui.add_var_context .icon.plus.circle, 
 .ui.add_var_context .icon.circle.back,
 .global_var .icon.plus.circle, 
@@ -720,8 +725,13 @@ div.function_name_div_updated:active,
 	left: 1.8em !important;
 	margin-top: 1.5em !important;
 }
+
+.ui.rail .icon.plus.circle, 
+.ui.rail .icon.circle.back {
+	left: 1.3em !important;
+}
+
 .ui.icon.button.dropdown.menu_commands {
-    float: left;
     color: white;
     margin-left: -4px;
     padding: 8px;
@@ -768,11 +778,6 @@ div.function_name_div_updated:active,
 	opacity: 1 !important;
 }
 
-.command_container {
-    background: #e9dede !important;
-	border: 2px solid #e76060 !important;
-    border-radius: 0.25em !important;
-}
 .command_drag {
 	cursor: move;
 }
@@ -783,4 +788,83 @@ div.function_name_div_updated:active,
 .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.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;
+}
+
+.ghost_div {
+
+    height: 20px;
+    background-color: #ffffff;
+    margin: 5px;
+    border: 2px dotted #000000;
+    box-shadow: 1px 1px;
+    height: 28px;
 }

+ 0 - 0
grammar/en/ivprog.g4


+ 0 - 0
grammar/en/langFunctions.js


+ 0 - 0
grammar/en/langLibs.js


+ 0 - 0
grammar/es/ivprog.g4


+ 0 - 0
grammar/es/langFunctions.js


+ 0 - 0
grammar/es/langLibs.js


+ 0 - 0
grammar/index.js


+ 0 - 0
grammar/pt/ivprog.g4


+ 0 - 0
grammar/pt/langFunctions.js


+ 0 - 0
grammar/pt/langLibs.js


+ 67 - 13
i18n/en/error.json

@@ -10,26 +10,80 @@
   "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",
-  "invalid_parameters_size": "A quantidade de parâmetros fornecidos está incorreta. Esperava-se $0, encontrou-se $1",
-  "invalid_ref": "Você deve fornecer apenas um identificador como parâmetro",
-  "invalid_parameter_type": "O valor fornecido como parâmetro é do tipo $0, mas o tipo esperado é $1",
-  "unknown_command": "Erro interno crítico: Comando desconhecido encontrado",
-  "loop_condition_type": "A condição dos laços de repetição deve ser do tipo lógico",
-  "if_condition_type": "A condição de um comando se...senao deve ser do tipo lógico",
-  "invalid_return_type": "A função $0 deve retornar um tipo $1, ao invés de $1",
-  "unexpected_break_command": "Erro interno crítico: Comando pare encontrado fora do contexto de um laço/escolha..caso",
+  "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 $2 do laço de repetição deve ser do tipo lógico",
+  "loop_condition_type": "A condição $0 do laço 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 $2 do comando para(...) deve ser do tipo lógico",
+  "for_condition_type": "A condição de parada $0 do comando para(...) deve ser do tipo lógico",
+  "if_condition_type_full": "Erro na linha: $0, coluna $1: a condição $2 do comando se...senao deve ser do tipo lógico",
+  "if_condition_type": "A condição $0 do 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": "A função $0 não pode ser utilizada aqui pois seu tipo de retorno é vazio",
-  "invalid_array": "Expressão literal de Vetor/Mariz inválida",
+  "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",
-  "column_outbounds": "Número de colunas $0 é inválido para a matriz $1 que possui $2 colunas",
-  "line_outbounds": "Número de linhas $0 é invaálido para a matriz $1 que possui $2 linhas",
+  "invalid_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"
+  "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.",
+  "test_case_few_reads": "Caso de teste $0 falhou: ainda restam entradas!",
+  "test_case_failed": "Caso de teste $0 falhou: entradas:<$1>; saída esperada:<$2>; saída:<$3>",
+  "test_case_failed_exception": "Caso de teste $0 falhou: $1"
 }

+ 0 - 0
i18n/en/index.js


+ 2 - 1
i18n/en/message.json

@@ -1,3 +1,4 @@
 {
-  
+  "test_case_success": "Caso de teste $0: OK",
+  "test_case_duration": "Levou $0ms"
 }

+ 11 - 3
i18n/en/ui.json

@@ -44,7 +44,7 @@
   "text_code_switch": "switch",
   "text_code_case": "case",
   "text_logic_expression": "Logic Expression",
-  "text_arithmetic_expression": "Arithmetic Expression",
+  "text_arithmetic_expression": "Relational Expression",
   "text_iftrue": "If true then",
   "text_receives": "receives",
   "text_repeatNtimes": "Repeat N times",
@@ -78,6 +78,7 @@
   "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",
@@ -93,9 +94,15 @@
   "var_menu_select_var": "Select a var",
   "var_menu_select_all": "Select",
   "var_menu_select_function": "Select a function",
-  "expression_menu_select": "Select an expression",
+  "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",
@@ -123,5 +130,6 @@
   "$castReal": "to_real",
   "$castInt": "to_integer",
   "$castBool": "to_logic",
-  "$castString": "to_string"
+  "$castString": "to_string",
+  "text_ivprog_version":"Version"
 }

+ 88 - 2
i18n/es/error.json

@@ -1,3 +1,89 @@
 {
-  
-}
+  "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 $2 do laço de repetição deve ser do tipo lógico",
+  "loop_condition_type": "A condição $0 do laço 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 $2 do comando para(...) deve ser do tipo lógico",
+  "for_condition_type": "A condição de parada $0 do comando para(...) deve ser do tipo lógico",
+  "if_condition_type_full": "Erro na linha: $0, coluna $1: a condição $2 do comando se...senao deve ser do tipo lógico",
+  "if_condition_type": "A condição $0 do 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.",
+  "test_case_few_reads": "Caso de teste $0 falhou: ainda restam entradas!",
+  "test_case_failed": "Caso de teste $0 falhou: entradas:<$1>; saída esperada:<$2>; saída:<$3>",
+  "test_case_failed_exception": "Caso de teste $0 falhou: $1"
+}

+ 0 - 0
i18n/es/index.js


+ 2 - 1
i18n/es/message.json

@@ -1,3 +1,4 @@
 {
-  
+  "test_case_success": "Caso de teste $0: OK",
+  "test_case_duration": "Levou $0ms"
 }

+ 16 - 13
i18n/es/ui.json

@@ -35,10 +35,8 @@
   "text_comment": "Comment",
   "text_attribution": "Attribution",
   "text_if":"if",
-  "text_break":"break",
   "text_else":"else",
-  "text_return":"return",
-  "text_btn_return":"Return",
+  "text_break":"break",
   "text_for":"for",
   "text_code_while":"while",
   "text_code_do":"do",
@@ -46,10 +44,12 @@
   "text_code_switch": "switch",
   "text_code_case": "case",
   "text_logic_expression": "Logic Expression",
-  "text_arithmetic_expression": "Arithmetic Expression",
+  "text_arithmetic_expression": "Relational Expression",
   "text_iftrue": "If true then",
-  "text_repeatNtimes": "Repeat N times",
   "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",
@@ -72,12 +72,13 @@
   "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_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",
@@ -93,14 +94,15 @@
   "var_menu_select_var": "Select a var",
   "var_menu_select_all": "Select",
   "var_menu_select_function": "Select a function",
-  "expression_menu_select": "Select an expression",
-  "$sin": "sen",
-  "math": "Mathematic",
-  "text": "Text",
-  "arrangement": "Arrangement",
-  "conversion": "Conversion",
+  "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",
@@ -128,5 +130,6 @@
   "$castReal": "to_real",
   "$castInt": "to_integer",
   "$castBool": "to_logic",
-  "$castString": "to_string"
+  "$castString": "to_string",
+  "text_ivprog_version":"Version"
 }

+ 0 - 0
i18n/i18n-database.json


+ 0 - 0
i18n/index.js


+ 12 - 7
i18n/pt/error.json

@@ -26,14 +26,14 @@
   "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",
+  "loop_condition_type_full": "Erro na linha: $0, coluna $1: a condição $2 do laço de repetição deve ser do tipo lógico",
+  "loop_condition_type": "A condição $0 do laço 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",
+  "for_condition_type_full": "Erro na linha: $0, coluna $1: a condição de parada $2 do comando para(...) deve ser do tipo lógico",
+  "for_condition_type": "A condição de parada $0 do comando para(...) deve ser do tipo lógico",
+  "if_condition_type_full": "Erro na linha: $0, coluna $1: a condição $2 do comando se...senao deve ser do tipo lógico",
+  "if_condition_type": "A condição $0 do 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",
@@ -81,5 +81,10 @@
   "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."
+  "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.",
+  "test_case_few_reads": "Caso de teste $0 falhou: ainda restam entradas!",
+  "test_case_failed": "Caso de teste $0 falhou: entradas:<$1>; saída esperada:<$2>; saída:<$3>",
+  "test_case_failed_exception": "Caso de teste $0 falhou: $1",
+  "invalid_type_conversion": "O valor $0 não pode ser convertido para o tipo $1"
 }

+ 0 - 0
i18n/pt/index.js


+ 2 - 1
i18n/pt/message.json

@@ -1,3 +1,4 @@
 {
-  
+  "test_case_success": "Caso de teste $0: OK",
+  "test_case_duration": "Levou $0ms"
 }

+ 11 - 4
i18n/pt/ui.json

@@ -52,7 +52,7 @@
   "text_code_switch": "escolha",
   "text_code_case": "caso",
   "text_logic_expression": "Expressão Lógica",
-  "text_arithmetic_expression": "Expressão Aritmética",
+  "text_arithmetic_expression": "Expressão Relacional",
   "text_iftrue": "Se verdadeiro então",
   "text_repeatNtimes": "Repita N vezes",
   "text_receives": "recebe",
@@ -84,6 +84,7 @@
   "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",
@@ -99,10 +100,15 @@
   "var_menu_select_var": "Selecione uma variável",
   "var_menu_select_all": "Selecione",
   "var_menu_select_function": "Selecione uma função",
-  "expression_menu_select": "Selecione uma expressão",
-  "$sin": "sen",
+  "expression_menu_select": "Construir uma expressão lógica",
   "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",
@@ -130,5 +136,6 @@
   "$castReal": "como_real",
   "$castInt": "como_inteiro",
   "$castBool": "como_logico",
-  "$castString": "como_cadeia"
+  "$castString": "como_cadeia",
+  "text_ivprog_version":"Versão"
 }

+ 0 - 0
img/background-panel.png


+ 58 - 60
index.html

@@ -28,85 +28,83 @@
 
       <div class="title default_visual_title">
         <i class="dropdown icon"></i>
-        
       </div>
 
     <div class="content height_100">
    
-    <div class="ui container main_title only_in_frame">
-      <h2>iVProg</h2>
-      <span class="subtext" style="display: inline;">interactive coding</span>
-    </div>
+      <div class="ui raised container segment div_to_body">
 
-    <div class="ui raised container segment div_to_body">
-
-      <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 container main_title only_in_frame">
+          <h2>iVProg</h2>
+        </div>
 
-      <div class="ui one column container segment ivprog_visual_panel loading">
+        <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="global_var">
-          <i class="icon plus circle purple add_global_button"></i>
-          <i class="icon circle white back"></i>
+        <div class="ui one column container segment ivprog_visual_panel loading">
 
-          <div class="ui icon button add-globalVar-button add_global_button purple"><i class="icon superscript"></i></div>
+          <div class="global_var">
+            <i class="icon plus circle purple add_global_button"></i>
+            <i class="icon circle white back"></i>
 
-          <div class="list_globals" id="listGlobalsHandle"></div>
+            <div class="ui icon button add-globalVar-button add_global_button purple"><i class="icon superscript"></i></div>
 
-        </div>
+            <div class="list_globals" id="listGlobalsHandle"></div>
 
-        <div class="all_functions list-group" id="listWithHandle">
+          </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 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 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>
 

+ 0 - 0
ivprog.sublime-project


+ 0 - 0
js/Sortable.js


+ 50 - 16
js/assessment/ivprogAssessment.js

@@ -3,6 +3,11 @@ import { SemanticAnalyser } from "./../processor/semantic/semanticAnalyser";
 import { IVProgProcessor } from "./../processor/ivprogProcessor";
 import { InputTest } from "./../util/inputTest";
 import { OutputTest } from "./../util/outputTest";
+import * as LocalizedStringsService from "../services/localizedStringsService";
+import { Decimal } from 'decimal.js';
+import { Config } from "../util/config";
+
+const LocalizedStrings = LocalizedStringsService.getInstance();
 
 export class IVProgAssessment {
 
@@ -22,7 +27,7 @@ export class IVProgAssessment {
       const partialTests = this.testCases.map( (t, name) => {
         return this.partialEvaluateTestCase(new IVProgProcessor(validTree), t.input, t.output, name);
       });
-      const testResult = partialTests.reduce((acc, curr) => acc.then( v => curr(v)), Promise.resolve(0));
+      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
@@ -46,45 +51,74 @@ export class IVProgAssessment {
     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`);
+        outerThis.showErrorMessage('test_case_few_reads', name+1);
+        outerThis.showMessage('test_case_duration', millis);
         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`);
+        outerThis.showErrorMessage('test_case_failed', name + 1, inputList.join(','),
+          outputList.join(','), output.list.join(','));
+        outerThis.showMessage('test_case_duration', millis);
         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`);
+        outerThis.showErrorMessage('test_case_failed', name + 1, inputList.join(','),
+          outputList.join(','), output.list.join(','));
+        outerThis.showMessage('test_case_duration', millis);
         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`);
+          outerThis.showErrorMessage('test_case_failed', name + 1, inputList.join(','),
+            outputList.join(','), output.list.join(','));
+          outerThis.showMessage('test_case_duration', millis);
           return Promise.resolve(accumulator);
         } else {
-          outerThis.domConsole.info(`Caso de teste ${name + 1}: OK!`);
-          outerThis.domConsole.info(`Levou ${millis}ms`);
+          outerThis.showMessage('test_case_success', name + 1);
+          outerThis.showMessage('test_case_duration', millis);
           return Promise.resolve(accumulator + 1);
         }
       }
-    }).catch( _ => Promise.resolve(accumulator));
+    }).catch( error => {
+      outerThis.showErrorMessage('test_case_failed_exception', name + 1, error.message);
+      return Promise.resolve(accumulator);
+    });
   }
 
   partialEvaluateTestCase (prog, inputList, outputList, name) {
-    let partial = (accumulator) => this.evaluateTestCase(prog, inputList, outputList, name, accumulator)
-    partial = partial.bind(this);
-    return partial;
+    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]) {
+      let castNumberA = parseFloat(outValue);
+      if(!Number.isNaN(castNumberA)) {
+        let castNumberB = parseFloat(bList[i]);
+        if(Number.isNaN(castNumberB)) {
+          return false;
+        }
+        castNumberA = new Decimal(castNumberA);
+        castNumberB = new Decimal(castNumberB);
+        const decimalPlaces = Math.min(castNumberB.dp(), Config.decimalPlaces);
+        Decimal.set({ rounding: Decimal.ROUND_FLOOR});
+        castNumberA = new Decimal(castNumberA.toFixed(decimalPlaces));
+        castNumberB = new Decimal(castNumberB.toFixed(decimalPlaces));
+        const aEqualsB = castNumberA.eq(castNumberB);
+        Decimal.set({ rounding: Decimal.ROUND_HALF_UP});
+        if (!aEqualsB) {
+          return false;
+        }
+      } else if(outValue != bList[i]) {
         return false;
       }
     }
     return true;
   }
+
+  showErrorMessage (errorID, ...args) {
+    this.domConsole.err(LocalizedStrings.getError(errorID, args));
+  }
+
+  showMessage (msgID, ...args) {
+    this.domConsole.info(LocalizedStrings.getMessage(msgID, args));
+  }
 }

+ 0 - 0
js/ast/ASA.txt


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


+ 3 - 1
js/ast/error/syntaxErrorFactory.js

@@ -1,6 +1,8 @@
-import { LocalizedStrings } from './../../services/localizedStringsService';
+import * as LocalizedStringsService from './../../services/localizedStringsService';
 import { SyntaxError } from './syntaxError';
 
+const LocalizedStrings = LocalizedStringsService.getInstance();
+
 export const SyntaxErrorFactory = Object.freeze({
   extra_lines: () => new SyntaxError(LocalizedStrings.getError("extra_lines")),
   token_missing_one: (expected, token) => {

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


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


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


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


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


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


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


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


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


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


+ 1 - 1
js/ast/expressions/stringLiteral.js

@@ -9,6 +9,6 @@ export class StringLiteral extends Literal {
   }
 
   toString() {
-    return this.value;
+    return '"' + this.value + '"';
   }
 }

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


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


+ 12 - 3
js/ast/ivprogParser.js

@@ -725,6 +725,7 @@ export class IVProgParser {
     } else {
       this.pushScope(IVProgParser.COMMAND);
     }
+    const token = this.getToken();
     this.pos++;
     this.checkOpenParenthesis();
     this.pos++;
@@ -749,11 +750,16 @@ export class IVProgParser {
       } else {
         throw SyntaxErrorFactory.token_missing_list([this.lexer.literalNames[this.lexerClass.RK_IF], '{'], maybeIf);
       }
-      return new Commands.IfThenElse(logicalExpression, cmdBlocks, elseBlock);
+      this.popScope();
+      const cmd = new Commands.IfThenElse(logicalExpression, cmdBlocks, elseBlock);
+      cmd.sourceInfo = SourceInfo.createSourceInfo(token);
+      return cmd;
     }
     this.popScope();
 
-    return new Commands.IfThenElse(logicalExpression, cmdBlocks, null);
+    const cmd = new Commands.IfThenElse(logicalExpression, cmdBlocks, null);
+    cmd.sourceInfo = SourceInfo.createSourceInfo(token);
+    return cmd;
   }
 
   parseFor () {
@@ -777,6 +783,7 @@ export class IVProgParser {
 
   parseWhile () {
     this.pushScope(IVProgParser.BREAKABLE);
+    const token = this.getToken();
     this.pos++;
     this.checkOpenParenthesis();
     this.pos++;
@@ -788,7 +795,9 @@ export class IVProgParser {
     this.consumeNewLines();
     const cmdBlocks = this.parseCommandBlock();
     this.popScope();
-    return new Commands.While(logicalExpression, cmdBlocks);
+    const cmd = new Commands.While(logicalExpression, cmdBlocks);
+    cmd.sourceInfo = SourceInfo.createSourceInfo(token);
+    return cmd;
   }
 
   parseBreak () {

+ 0 - 0
js/ast/operators.js


+ 0 - 0
js/ast/sourceInfo.js


+ 133 - 43
js/iassign-integration-functions.js

@@ -30,7 +30,12 @@ function getAnswer () {
         // Montar o retorno com a resposta do aluno
         var contentToSend = previousContent.split("\n::algorithm::")[0];
         contentToSend += '\n::algorithm::\n';
-        contentToSend += JSON.stringify(window.program_obj);
+        contentToSend += JSON.stringify(window.program_obj, function(key, value) {
+            if (key == 'dom_object') {
+                return;
+            }
+            return value; 
+        });
 
         contentToSend += '\n::logs::';
         contentToSend += getTrackingLogs();
@@ -47,10 +52,17 @@ function getAnswer () {
 
         if ($("input[name='include_algo']").is(':checked')) {
             ret += '\n::algorithm::\n';
-            ret += JSON.stringify(window.program_obj);
+            ret += JSON.stringify(window.program_obj, function(key, value) {
+                
+                if (key == 'dom_object') {
+                    return;
+                }
+                return value; 
+            });
         }
 
         return ret;
+
     }
 }
 
@@ -115,27 +127,54 @@ 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 {
-
+        } else { // Professor está editando uma atividade:
+            previousContent = data;
+            prepareActivityToEdit(data);
         }
+
+        window.block_render = false;
+        renderAlgorithm();
     });
 }
 
-function prepareActivityToStudent (ilm_cont) {
+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];
-        window.program_obj.functions = JSON.parse(algorithm_in_ilm).functions;
-        window.program_obj.globals = JSON.parse(algorithm_in_ilm).globals;
+        $("input[name='include_algo']").prop('checked', true);
+        includePreviousAlgorithm();
+        renderAlgorithm();
+    }
+}
 
-        window.watchW.watch(window.program_obj.globals, function(){
+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;
@@ -144,26 +183,7 @@ function prepareActivityToStudent (ilm_cont) {
           }
         }, 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);
-        }
-        window.watchW.watch(window.program_obj.functions, function(){
+        window.watchW.watch(window.program_obj.functions[i].variables_list, function(){
           if (window.insertContext) {
             setTimeout(function(){ renderAlgorithm(); }, 300);
             window.insertContext = false;
@@ -171,6 +191,31 @@ function prepareActivityToStudent (ilm_cont) {
             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();
@@ -207,6 +252,12 @@ $(document).ready(function() {
         // 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) {
@@ -226,7 +277,9 @@ function prepareActivityCreation () {
     $('.main_title').remove();
     $('.ui.accordion').addClass('styled');
     
-    $('<div class="ui checkbox"><input type="checkbox" name="include_algo" class="include_algo" tabindex="0" class="hidden"><label>'+LocalizedStrings.getUI('text_teacher_algorithm_include')+'</label></div>').insertBefore('.content_margin');
+    $('<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>');
 
@@ -243,6 +296,10 @@ function prepareActivityCreation () {
     prepareTableSettings(config_div.find('.content'));
 
     prepareTableTestCases(cases_test_div.find('.content'));
+
+    if (inIframe()) {
+        $('.ui.styled.accordion').css('width', '96%');
+    }
 }
 
 function prepareTableTestCases (div_el) {
@@ -257,13 +314,39 @@ function prepareTableTestCases (div_el) {
     $('.button_add_case').on('click', function(e) {
         addTestCase();
     });
-
 }
 
 var hist = false;
 
-function addTestCase () {
-    var new_row = $('<tr><td class="counter"></td><td class="expandingArea"><textarea rows="1" name="input" class="text_area_input"></textarea></td><td class="expandingArea"><textarea rows="1" name="output" class="text_area_output"></textarea></td><td class="btn_actions"><div class="ui button_remove_case"><i class="red icon times large"></i></div></td></tr>');
+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) {
@@ -271,7 +354,7 @@ function addTestCase () {
         updateTestCaseCounter();
     });
 
-    $('textarea').on('input', function(e) {
+    new_row.find('textarea').on('input', function(e) {
         var lines = $(this).val().split('\n').length;
         $(this).attr('rows', lines);
     });
@@ -285,10 +368,12 @@ function addTestCase () {
             addTestCase();
         }
      });
-     if (!hist) {
-        $( ".content_cases tr:last" ).find('.text_area_input').focus();
-     } else {
-        hist = false;
+     if (test_case == null) {
+        if (!hist) {
+            $( ".content_cases tr:last" ).find('.text_area_input').focus();
+         } else {
+            hist = false;
+         }
      }
 }
 
@@ -340,8 +425,8 @@ function getTrackingLogs () {
     var ret = "";
     for (var i = 0; i < trackingMatrix.length; i++) {
         ret += "\n" + trackingMatrix[i][0] + "," + trackingMatrix[i][1] + "," + trackingMatrix[i][2];
-        if (trackingMatrix[i][2] === 1) {
-            ret += ',"' + trackingMatrix[i][3] + '"';
+        if (trackingMatrix[i][3] === 1) {
+            ret += ',' + trackingMatrix[i][3] + ',"' + trackingMatrix[i][4] + '"';
         }
     }
     return ret;
@@ -354,7 +439,7 @@ function adCoords(e, code){
     var x = e.pageX; 
     var y = e.pageY;
     if (code === 1) {
-        return [x, y, code, e.target.classList['value']];
+        return [new Date().getTime(), x, y, code, e.target.classList['value']];
     } else {
         return [x, y, code];
     }
@@ -364,14 +449,19 @@ $( 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');
-    
 }
 
 
@@ -385,7 +475,7 @@ function inIframe () {
 
 
 function full_screen() {
-     // check if user allows full screen of elements. This can be enabled or disabled in browser config. By default its enabled.
+    // 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) {

+ 2 - 1
js/io/domConsole.js

@@ -125,7 +125,8 @@ export class DOMConsole {
   }
 
   sendOutput (text) {
-    text.split("\n").forEach(t => {
+    const output = ""+text;
+    output.split("\n").forEach(t => {
       t = t.replace(/\t/g,'&#9;');
       this.write(t)
     });

+ 0 - 0
js/io/domInput.js


+ 0 - 0
js/io/domOutput.js


+ 0 - 0
js/io/input.js


+ 0 - 0
js/io/output.js


+ 0 - 0
js/jquery-3.3.1.min.js


+ 0 - 0
js/jquery-ui.js


+ 0 - 0
js/jquery.json-editor.min.js


+ 9 - 2
js/main.js

@@ -1,13 +1,20 @@
 import { runner } from './runner';
-import { initVisualUI } from './visualUI/functions';
-import { LocalizedStrings} from './services/localizedStringsService';
+import { initVisualUI, addFunctionChangeListener,
+  addGlobalChangeListener, removeFunctionListener,
+  removeGlobalListener } from './visualUI/functions';
+import * as LocalizedStringsService from './services/localizedStringsService';
 import { i18nHelper } from "./services/i18nHelper";
 
 const i18n = i18nHelper.i18n
+const LocalizedStrings = LocalizedStringsService.getInstance();
 
 export {
   runner,
   initVisualUI,
+  addFunctionChangeListener,
+  addGlobalChangeListener,
+  removeFunctionListener,
+  removeGlobalListener,
   LocalizedStrings,
   i18n
 }

+ 8 - 6
js/processor/compatibilityTable.js

@@ -127,12 +127,14 @@ export function resultTypeAfterInfixOp (operator, leftExpressionType, rightExpre
   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);
+      for (let i = 0; i < leftExpressionType.types.length; ++i) {
+        const typeA = leftExpressionType.types[i];
+        for(let j = 0; j < rightExpressionType.types.length; ++i) {
+          const typeB = rightExpressionType.types[j];
+          newMulti.push(resultTypeAfterInfixOp(operator, typeA, typeB));
         }
       }
+      newMulti = newMulti.filter(x => !x.isCompatible(Types.UNDEFINED));
       if(newMulti.length <= 0) {
         if(Config.enable_type_casting) {
           if(leftExpressionType.isCompatible(Types.INTEGER) || leftExpressionType.isCompatible(Types.REAL)) {
@@ -147,7 +149,7 @@ export function resultTypeAfterInfixOp (operator, leftExpressionType, rightExpre
       }
     } else if(leftExpressionType instanceof MultiType) {
       if(leftExpressionType.isCompatible(rightExpressionType)) {
-        return rightExpressionType;
+        return resultTypeAfterInfixOp(operator, rightExpressionType, rightExpressionType);
       } else {
         if(Config.enable_type_casting) {
           if(leftExpressionType.isCompatible(Types.INTEGER) || leftExpressionType.isCompatible(Types.REAL)) {
@@ -160,7 +162,7 @@ export function resultTypeAfterInfixOp (operator, leftExpressionType, rightExpre
       }
     } else if(rightExpressionType instanceof MultiType) {
       if(rightExpressionType.isCompatible(leftExpressionType)) {
-        return leftExpressionType;
+        return resultTypeAfterInfixOp(operator, leftExpressionType, leftExpressionType);
       } else {
         if(Config.enable_type_casting) {
           if(leftExpressionType.isCompatible(Types.INTEGER) || leftExpressionType.isCompatible(Types.REAL)) {

+ 0 - 0
js/processor/context.js


+ 0 - 0
js/processor/definedFunctions.js


+ 38 - 54
js/processor/error/processorErrorFactory.js

@@ -1,31 +1,8 @@
 import { RuntimeError } from './runtimeError';
 import { SemanticError } from './semanticError';
-import { LocalizedStrings } from './../../services/localizedStringsService';
-import { Operators } from '../../ast/operators';
+import * as  LocalizedStringsService from './../../services/localizedStringsService';
 
-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;
-  }
-}
+const LocalizedStrings = LocalizedStringsService.getInstance();
 
 export const ProcessorErrorFactory  = Object.freeze({
   symbol_not_found_full: (id, sourceInfo) => {
@@ -80,38 +57,39 @@ export const ProcessorErrorFactory  = Object.freeze({
   },
   incompatible_types_full: (type, dim, sourceInfo) => {
     if(sourceInfo) {
-      const context = [translateType(type, dim), sourceInfo.line, sourceInfo.column];
+      const context = [LocalizedStrings.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)];
+    const context = [LocalizedStrings.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];
+      const context = [exp, LocalizedStrings.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)];
+    const context = [exp, LocalizedStrings.translateType(type, dim)];
     return new SemanticError(LocalizedStrings.getError("incompatible_types_array", context));
   },
-  loop_condition_type_full: (sourceInfo) => {
+  loop_condition_type_full: (exp, sourceInfo) => {
     if(sourceInfo) {
-      const context = [sourceInfo.line, sourceInfo.column];
+      const context = [sourceInfo.line, sourceInfo.column, exp];
       return new SemanticError(LocalizedStrings.getError("loop_condition_type_full", context));
     } else {
-      return ProcessorErrorFactory.loop_condition_type();
+      return ProcessorErrorFactory.loop_condition_type(exp);
     }
   },
-  loop_condition_type: () => {
-    return new SemanticError(LocalizedStrings.getError("loop_condition_type"));
+  loop_condition_type: (exp) => {
+    const context = [exp];
+    return new SemanticError(LocalizedStrings.getError("loop_condition_type", context));
   },
   endless_loop_full: (sourceInfo) => {
     if(sourceInfo) {
@@ -124,27 +102,29 @@ export const ProcessorErrorFactory  = Object.freeze({
   endless_loop: () => {
     return new SemanticError(LocalizedStrings.getError("endless_loop"));
   },
-  for_condition_type_full: (sourceInfo) => {
+  for_condition_type_full: (exp, sourceInfo) => {
     if(sourceInfo) {
-      const context = [sourceInfo.line, sourceInfo.column];
+      const context = [sourceInfo.line, sourceInfo.column, exp];
       return new SemanticError(LocalizedStrings.getError("for_condition_type_full", context));
     } else {
-      return ProcessorErrorFactory.for_condition_type();
+      return ProcessorErrorFactory.for_condition_type(exp);
     }
   },
-  for_condition_type: () => {
-    return new SemanticError(LocalizedStrings.getError("for_condition_type"));
+  for_condition_type: (exp) => {
+    const context = [exp];
+    return new SemanticError(LocalizedStrings.getError("for_condition_type", context));
   },
-  if_condition_type_full: (sourceInfo) => {
+  if_condition_type_full: (exp, sourceInfo) => {
     if(sourceInfo) {
-      const context = [sourceInfo.line, sourceInfo.column];
+      const context = [sourceInfo.line, sourceInfo.column, exp];
       return new SemanticError(LocalizedStrings.getError("if_condition_type_full", context));
     } else {
-      return ProcessorErrorFactory.if_condition_type();
+      return ProcessorErrorFactory.if_condition_type(exp);
     }
   },
-  if_condition_type: () => {
-    return new SemanticError(LocalizedStrings.getError("if_condition_type"));
+  if_condition_type: (exp) => {
+    const context = [exp];
+    return new SemanticError(LocalizedStrings.getError("if_condition_type", context));
   },
   invalid_global_var: () => {
     return new RuntimeError(LocalizedStrings.getError("invalid_global_var"))
@@ -155,14 +135,14 @@ export const ProcessorErrorFactory  = Object.freeze({
   },
   invalid_case_type_full: (exp, type, dim, sourceInfo) => {
     if(sourceInfo) {
-      const context = [exp, translateType(type, dim), sourceInfo.line, sourceInfo.column];
+      const context = [exp, LocalizedStrings.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)];
+    const context = [exp, LocalizedStrings.translateType(type, dim)];
     return new SemanticError(LocalizedStrings.getError("invalid_case_type", context));
   },
   void_in_expression_full: (id, sourceInfo) => {
@@ -255,26 +235,26 @@ export const ProcessorErrorFactory  = Object.freeze({
   },
   invalid_void_return_full: (id, type, dim, sourceInfo) => {
     if(sourceInfo) {
-      const context = [sourceInfo.line, id, translateType(type, dim)];
+      const context = [sourceInfo.line, id, LocalizedStrings.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)];
+    const context = [id, LocalizedStrings.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)];
+      const context = [sourceInfo.line, id, LocalizedStrings.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)];
+    const context = [id, LocalizedStrings.translateType(type, dim)];
     return new SemanticError(LocalizedStrings.getError("invalid_return_type", context));
   },
   invalid_parameters_size_full: (id, expected, actual, sourceInfo) => {
@@ -362,26 +342,26 @@ export const ProcessorErrorFactory  = Object.freeze({
   },
   invalid_unary_op_full: (opName, type, dim, sourceInfo) => {
     if(sourceInfo) {
-      const context = [sourceInfo.line, translateOp(opName), translateType(type, dim)];
+      const context = [sourceInfo.line, LocalizedStrings.translateOp(opName), LocalizedStrings.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)];
+    const context = [LocalizedStrings.translateOp(opName), LocalizedStrings.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)];
+      const context = [sourceInfo.line, LocalizedStrings.translateOp(opName), LocalizedStrings.translateType(typeLeft, dimLeft), LocalizedStrings.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)];
+    const context = [LocalizedStrings.translateOp(opName), LocalizedStrings.translateType(typeLeft, dimLeft), LocalizedStrings.translateType(typeRight, dimRight)];
     return new RuntimeError(LocalizedStrings.getError("invalid_infix_op", context));
   },
   array_dimension_not_positive_full: (sourceInfo) => {
@@ -394,5 +374,9 @@ export const ProcessorErrorFactory  = Object.freeze({
   },
   array_dimension_not_positive: () => {
     return new SemanticError(LocalizedStrings.getError("array_dimension_not_positive"));
+  },
+  invalid_type_conversion: (value, type, dim) => {
+    const context = [value, LocalizedStrings.translateType(type, dim)];
+    return new RuntimeError(LocalizedStrings.getError("invalid_type_conversion", context));
   }
 });

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


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


+ 9 - 10
js/processor/ivprogProcessor.js

@@ -116,7 +116,6 @@ export class IVProgProcessor {
     } else {
       const val = this.ast.functions.find( v => v.name === name);
       if (!!!val) {
-        // TODO: better error message;
         throw ProcessorErrorFactory.function_missing(name);
       }
       return val;
@@ -139,13 +138,14 @@ export class IVProgProcessor {
     }
     funcStore.insertStore('$', returnStoreObject);
     const newFuncStore$ = this.associateParameters(func.formalParameters, actualParameters, store, funcStore);
+    const outerRef = this;
     return newFuncStore$.then(sto => {
       this.context.push(Context.FUNCTION);
       this.stores.push(sto);
       return this.executeCommands(sto, func.variablesDeclarations)
-        .then(stoWithVars => this.executeCommands(stoWithVars, func.commands)).then(finalSto => {
-          this.stores.pop();
-          this.context.pop();
+        .then(stoWithVars => outerRef.executeCommands(stoWithVars, func.commands)).then(finalSto => {
+          outerRef.stores.pop();
+          outerRef.context.pop();
           return finalSto;
         });
     });
@@ -209,7 +209,6 @@ export class IVProgProcessor {
   }
 
   executeCommand (store, cmd) {
-
     if(this.forceKill) {
       return Promise.reject("FORCED_KILL!");
     } else if (store.mode === Modes.PAUSE) {
@@ -232,10 +231,10 @@ export class IVProgProcessor {
       return this.executeReturn(store, cmd);
     } else if (cmd instanceof Commands.IfThenElse) {
       return this.executeIfThenElse(store, cmd);
-    } else if (cmd instanceof Commands.While) {
-      return this.executeWhile(store, cmd);
     } else if (cmd instanceof Commands.DoWhile) {
       return this.executeDoWhile(store, cmd);
+    } else if (cmd instanceof Commands.While) {
+      return this.executeWhile(store, cmd);
     } else if (cmd instanceof Commands.For) {
       return this.executeFor(store, cmd);
     } else if (cmd instanceof Commands.Switch) {
@@ -413,7 +412,7 @@ export class IVProgProcessor {
             return store;
           }
         } else {
-          return Promise.reject(ProcessorErrorFactory.loop_condition_type_full(cmd.sourceInfo));
+          return Promise.reject(ProcessorErrorFactory.loop_condition_type_full(cmd.expression.toString(), cmd.sourceInfo));
         }
       })
       
@@ -439,7 +438,7 @@ export class IVProgProcessor {
             return Promise.resolve(store);
           }
         } else {
-          return Promise.reject(ProcessorErrorFactory.if_condition_type_full(cmd.sourceInfo));
+          return Promise.reject(ProcessorErrorFactory.if_condition_type_full(cmd.condition.toString(), cmd.sourceInfo));
         }
       });
     } catch (error) {
@@ -456,6 +455,7 @@ export class IVProgProcessor {
       return $value.then(vl => {
 
         if(vl === null && funcType.isCompatible(Types.VOID)) {
+          store.mode = Modes.RETURN;
           return Promise.resolve(store);
         }
 
@@ -694,7 +694,6 @@ export class IVProgProcessor {
     }
     const func = this.findFunction(exp.id);
     if(Types.VOID.isCompatible(func.returnType)) {
-      // TODO: better error message
       return Promise.reject(ProcessorErrorFactory.void_in_expression_full(exp.id, exp.sourceInfo));
     }
     const $newStore = this.runFunction(func, exp.actualParameters, store);

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


+ 1 - 1
js/processor/lib/io.js

@@ -26,7 +26,7 @@ export function createInputFun () {
       let stoObj = null;
       if (typeToConvert.isCompatible(Types.INTEGER)) {
         const val = toInt(text);
-        stoObj = new StoreObject(Types.INTEGER, val);
+        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)) {

+ 25 - 14
js/processor/lib/lang.js

@@ -5,6 +5,8 @@ import { toReal, convertToString } from "./../../typeSystem/parsers";
 import { IVProgParser } from '../../ast/ivprogParser';
 import { RealLiteral, IntLiteral, BoolLiteral } from '../../ast/expressions';
 import { Modes } from '../modes';
+import { MultiType } from '../../typeSystem/multiType';
+import { ProcessorErrorFactory } from '../error/processorErrorFactory';
 
 /**
  * 
@@ -89,14 +91,16 @@ export function createIsBoolFun () {
 export function createCastRealFun () {
   const castRealFun = (sto, _) => {
     const val = sto.applyStore("val");
+    let value = val.value;
     switch (val.type.ord) {
       case Types.INTEGER.ord: {
-        const temp = new StoreObject(Types.REAL, toReal(val.number));
+        value = value.toNumber();
+        const temp = new StoreObject(Types.REAL, toReal(value));
         sto.mode = Modes.RETURN;
         return Promise.resolve(sto.updateStore("$", temp));
       }
       case Types.STRING.ord: {
-        const parser = IVProgParser.createParser(val.value);
+        const parser = IVProgParser.createParser(value);
         try {
           const result = parser.parseTerm();
           if (result instanceof RealLiteral) {
@@ -104,16 +108,17 @@ export function createCastRealFun () {
             sto.mode = Modes.RETURN;
             return Promise.resolve(sto.updateStore("$", temp));
           }
-        } catch (error) { 
-          return Promise.reject("cannot convert string to real");
-        }
+        } catch (error) { }
       }
     }
+    const typeStringInfoArray = Types.REAL.stringInfo();
+    const typeInfo = typeStringInfoArray[0];
+    return Promise.reject(ProcessorErrorFactory.invalid_type_conversion(value, typeInfo.type, typeInfo.dim));
   }
 
   const block = new Commands.CommandBlock([],  [new Commands.SysCall(castRealFun)]);
   const func = new Commands.Function('$castReal', Types.REAL,
-    [new Commands.FormalParameter(Types.ALL, 'val', false)],
+    [new Commands.FormalParameter(new MultiType([Types.INTEGER, Types.STRING]), 'val', false)],
     block);
   return func;
 }
@@ -121,14 +126,16 @@ export function createCastRealFun () {
 export function createCastIntFun () {
   const castIntFun = (sto, _) => {
     const val = sto.applyStore("val");
+    let value = val.value;
     switch (val.type.ord) {
       case Types.REAL.ord: {
-        const temp = new StoreObject(Types.INTEGER, Math.floor(val.number));
+        value = value.toNumber();
+        const temp = new StoreObject(Types.INTEGER, Math.floor(value));
         sto.mode = Modes.RETURN;
         return Promise.resolve(sto.updateStore("$", temp));
       }
       case Types.STRING.ord: {
-        const parser = IVProgParser.createParser(val.value);
+        const parser = IVProgParser.createParser(value);
         try {
           const result = parser.parseTerm();
           if (result instanceof IntLiteral) {
@@ -136,16 +143,17 @@ export function createCastIntFun () {
             sto.mode = Modes.RETURN;
             return Promise.resolve(sto.updateStore("$", temp));
           }
-        } catch (error) { 
-          return Promise.reject("cannot convert string to real");
-        }
+        } catch (error) { }
       }
     }
+    const typeStringInfoArray = Types.INTEGER.stringInfo();
+    const typeInfo = typeStringInfoArray[0];
+    return Promise.reject(ProcessorErrorFactory.invalid_type_conversion(value, typeInfo.type, typeInfo.dim));
   }
 
   const block = new Commands.CommandBlock([],  [new Commands.SysCall(castIntFun)]);
   const func = new Commands.Function('$castInt', Types.INTEGER,
-    [new Commands.FormalParameter(Types.ALL, 'val', false)],
+    [new Commands.FormalParameter(new MultiType([Types.REAL, Types.STRING]), 'val', false)],
     block);
   return func;
 }
@@ -153,7 +161,8 @@ export function createCastIntFun () {
 export function createCastBoolFun () {
   const castBoolFun = (sto, _) => {
     const str = sto.applyStore("str");
-    const parser = IVProgParser.createParser(str.value);
+    let value = str.value; 
+    const parser = IVProgParser.createParser(value);
     try {
       const val = parser.parseTerm();
       if (val instanceof BoolLiteral) {
@@ -162,7 +171,9 @@ export function createCastBoolFun () {
         return Promise.resolve(sto.updateStore("$", temp));
       }
     } catch (error) { }
-    return Promise.reject("cannot convert " + str.value + " to boolean");
+    const typeStringInfoArray = Types.BOOLEAN.stringInfo();
+    const typeInfo = typeStringInfoArray[0];
+    return Promise.reject(ProcessorErrorFactory.invalid_type_conversion(value, typeInfo.type, typeInfo.dim));
   }
 
   const block = new Commands.CommandBlock([],  [new Commands.SysCall(castBoolFun)]);

+ 2 - 1
js/processor/lib/math.js

@@ -173,8 +173,9 @@ export function createAbsFun () {
     const x = sto.applyStore('x');
     const result = x.value.abs();
     const temp = new StoreObject(x.type, result);
+    sto.updateStore('$', temp)
     sto.mode = Modes.RETURN;
-    return Promise.resolve(sto.updateStore('$', temp));
+    return Promise.resolve(sto);
   };
 
  const block = new Commands.CommandBlock([],  [new Commands.SysCall(absFun)]);

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


+ 0 - 0
js/processor/modes.js


+ 3 - 4
js/processor/semantic/semanticAnalyser.js

@@ -57,7 +57,6 @@ export class SemanticAnalyser {
   }
 
   findFunction (name) {
-    console.log(name);
     if(name.match(/^\$.+$/)) {
       const fun = LanguageDefinedFunction.getFunction(name);
       if(!!!fun) {
@@ -347,7 +346,7 @@ export class SemanticAnalyser {
     if (cmd instanceof While) {
       const resultType = this.evaluateExpressionType(cmd.expression);
       if (!resultType.isCompatible(Types.BOOLEAN)) {
-        throw ProcessorErrorFactory.loop_condition_type_full(cmd.sourceInfo);
+        throw ProcessorErrorFactory.loop_condition_type_full(cmd.expression.toString(), cmd.sourceInfo);
       }
       this.checkCommands(type, cmd.commands, optional);
       return false;
@@ -355,7 +354,7 @@ export class SemanticAnalyser {
       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);
+        throw ProcessorErrorFactory.for_condition_type_full(cmd.condition.toString(), cmd.sourceInfo);
       }
       this.checkCommand(type, cmd.increment, optional);
       this.checkCommands(type, cmd.commands, optional);
@@ -440,7 +439,7 @@ export class SemanticAnalyser {
     } else if (cmd instanceof IfThenElse) {
       const resultType = this.evaluateExpressionType(cmd.condition);
       if (!resultType.isCompatible(Types.BOOLEAN)) {
-        throw ProcessorErrorFactory.if_condition_type_full(cmd.sourceInfo);
+        throw ProcessorErrorFactory.if_condition_type_full(cmd.condition.toString(), cmd.sourceInfo);
       }
       if(cmd.ifFalse instanceof IfThenElse) {
         return this.checkCommands(type, cmd.ifTrue.commands, optional) && this.checkCommand(type, cmd.ifFalse, optional);

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


برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است