瀏覽代碼

Preparado para o ITarefa

Douglas Lima 5 年之前
父節點
當前提交
be7b433fc1
共有 85 個文件被更改,包括 1729 次插入553 次删除
  1. 105 9
      css/ivprog-visual-1.0.css
  2. 16 1
      i18n/en/ui.json
  3. 16 1
      i18n/es/ui.json
  4. 2 0
      i18n/pt/error.json
  5. 16 1
      i18n/pt/ui.json
  6. 10 0
      js/ast/commands/arrayAssign.js
  7. 2 4
      js/ast/commands/arrayDeclaration.js
  8. 4 1
      js/ast/commands/assign.js
  9. 8 1
      js/ast/commands/break.js
  10. 4 1
      js/ast/commands/case.js
  11. 14 0
      js/ast/commands/command.js
  12. 9 0
      js/ast/commands/commandBlock.js
  13. 5 2
      js/ast/commands/declaration.js
  14. 5 1
      js/ast/commands/for.js
  15. 10 2
      js/ast/commands/formalParameter.js
  16. 11 2
      js/ast/commands/function.js
  17. 4 1
      js/ast/commands/ifThenElse.js
  18. 2 0
      js/ast/commands/index.js
  19. 5 1
      js/ast/commands/return.js
  20. 4 1
      js/ast/commands/switch.js
  21. 2 2
      js/ast/commands/sysCall.js
  22. 4 1
      js/ast/commands/while.js
  23. 8 0
      js/ast/error/syntaxErrorFactory.js
  24. 4 1
      js/ast/expressions/arrayAccess.js
  25. 3 4
      js/ast/expressions/arrayLiteral.js
  26. 2 1
      js/ast/expressions/boolLiteral.js
  27. 14 0
      js/ast/expressions/expression.js
  28. 4 1
      js/ast/expressions/functionCall.js
  29. 4 1
      js/ast/expressions/infixApp.js
  30. 2 1
      js/ast/expressions/intLiteral.js
  31. 4 1
      js/ast/expressions/literal.js
  32. 2 1
      js/ast/expressions/realLiteral.js
  33. 2 1
      js/ast/expressions/stringLiteral.js
  34. 1 1
      js/ast/expressions/variableLiteral.js
  35. 6 3
      js/io/domConsole.js
  36. 37 0
      js/visualUI/algorithm_sidebar.js
  37. 19 20
      js/visualUI/functions_sidebar.js
  38. 1 1
      js/visualUI/ivprog_elements.js
  39. 534 457
      package-lock.json
  40. 4 0
      runner.html
  41. 4 4
      tests/test00.spec.js
  42. 2 2
      tests/test17.spec.js
  43. 1 1
      tests/test19.spec.js
  44. 4 2
      tests/test20.spec.js
  45. 1 1
      tests/test21.spec.js
  46. 1 1
      tests/test24.spec.js
  47. 1 1
      tests/test25.spec.js
  48. 1 1
      tests/test27.spec.js
  49. 1 1
      tests/test28.spec.js
  50. 1 1
      tests/test29.spec.js
  51. 1 1
      tests/test30.spec.js
  52. 1 1
      tests/test31.spec.js
  53. 1 1
      tests/test33.spec.js
  54. 1 1
      tests/test34.spec.js
  55. 1 1
      tests/test35.spec.js
  56. 1 1
      tests/test37.spec.js
  57. 4 0
      tests/test40.spec.js
  58. 1 1
      tests/test42.spec.js
  59. 3 3
      tests/test43.spec.js
  60. 26 0
      tests/test44.spec.js
  61. 29 0
      tests/test45.spec.js
  62. 25 0
      tests/test46.spec.js
  63. 26 0
      tests/test47.spec.js
  64. 25 0
      tests/test48.spec.js
  65. 36 0
      tests/test49.spec.js
  66. 25 0
      tests/test50.spec.js
  67. 29 0
      tests/test51.spec.js
  68. 29 0
      tests/test52.spec.js
  69. 33 0
      tests/test53.spec.js
  70. 32 0
      tests/test54.spec.js
  71. 25 0
      tests/test55.spec.js
  72. 32 0
      tests/test56.spec.js
  73. 32 0
      tests/test57.spec.js
  74. 31 0
      tests/test58.spec.js
  75. 31 0
      tests/test59.spec.js
  76. 36 0
      tests/test60.spec.js
  77. 11 0
      tests/test61.spec.js
  78. 11 0
      tests/test62.spec.js
  79. 11 0
      tests/test63.spec.js
  80. 36 0
      tests/test64.spec.js
  81. 91 0
      tests/test65.spec.js
  82. 57 0
      tests/test66.spec.js
  83. 32 0
      tests/test67.spec.js
  84. 32 0
      tests/testMinMax.spec.js
  85. 6 2
      webpack.config.js

+ 105 - 9
css/ivprog-visual-1.0.css

@@ -6,12 +6,15 @@ body {
   height: 100%;
 }
 
-.div_to_body {
-  height: 90%;
+.ui.raised.container.segment.div_to_body {
+  height: 96%;
+  padding: 10px;
+  padding-left: 6px;
+  padding-right: 6px;
 }
 
 .ivprog_visual_panel {
-	height: 91%;
+	height: 96%;
 	overflow: auto;
 	overflow-x: auto;
 
@@ -149,7 +152,7 @@ body {
 .function_name_div, .function_return_div, .function_name_parameter, .created_div_valor_var, .function_return, .var_value_menu_div, .variable_rendered, .variable_rendered div, .var_attributed,
 .expression_operand_1, .expression_operand_2, .operator, .div_comment_text, .value_rendered, .parameters_function_called, .parameters_function_called div, .expression_elements,
 .expression_element, .var_rendered, .menu_add_item, .component_element, .component_element, .conditional_expression, .variable_attribution, .attribution_expression, .var_value_expression,
-.incrementation_field, .incrementation_variable, .first_operand, .operator, .second_operand, .variable_to_switch, .variable_case {
+.incrementation_field, .incrementation_variable, .first_operand, .operator, .second_operand, .variable_to_switch, .variable_case, .button_remove_case, .editing_name_var {
 	display: inline;
 }
 
@@ -162,7 +165,7 @@ body {
 	font-style: italic;
 }
 
-.enable_edit_name_function, .enable_edit_name_parameter, .add_parameter, .remove_parameter, .add_parameter_button, .remove_variable {
+.enable_edit_name_function, .add_parameter, .remove_parameter, .add_parameter_button, .remove_variable {
 	cursor: pointer;
 }
 
@@ -174,8 +177,9 @@ body {
 }
 
 .ui.segment.ivprog_visual_panel {
-	padding: 8px;
-	background-image: url('../img/background-panel.png');
+	padding: 3px;
+	margin-top: -5px;
+	background: #edf4ff;
 }
 
 .ui.segment.function_div {
@@ -271,7 +275,8 @@ div.buttons_manage_columns {
 .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.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;
@@ -304,7 +309,6 @@ div.buttons_manage_columns {
 
 .list_globals, .global_const {
 	display: inline;
-	cursor: pointer;
 }
 
 .created_element {
@@ -342,6 +346,98 @@ div.buttons_manage_columns {
     margin-left: -30px;
 }
 
+.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 {
+	border: 2px solid gray;
+	padding-left: 8px;
+	padding-right: 8px;
+	padding-top: 6px;
+	padding-bottom: 4px;
+}
+
+.global_container .global_type, .editing_name_var, .global_container .span_value_variable {
+	background: #cecece;
+	border-radius: 5px;
+	padding: 4px;
+	margin-left: 5px;
+	margin-right: 5px;
+}
+
+.global_container .global_type:hover, .editing_name_var:hover, .global_container .span_value_variable: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 {
+	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%;
+}
+
+.red.icon.times.remove_global {
+	float: right;
+    margin-right: -1px;
+    margin-left: 8px;
+}
+
+.tr_manage_lines {
+	padding-top: 10px;
+}
+
+.ui.icon.button.add-globalVar-button.add_global_button {
+	padding: 8px;
+}
+.all_functions {
+	margin-top: -5px;
+}
 /* DOUGLAS */
 /*
 .div-over {

+ 16 - 1
i18n/en/ui.json

@@ -47,6 +47,8 @@
   "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",
@@ -54,5 +56,18 @@
   "text_value": "Value",
   "text_operator": "Operator",
   "text_parentheses": "Parentheses",
-  "text_change": "Change"
+  "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"
 }

+ 16 - 1
i18n/es/ui.json

@@ -37,6 +37,8 @@
   "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",
@@ -54,5 +56,18 @@
   "text_value": "Value",
   "text_operator": "Operator",
   "text_parentheses": "Parentheses",
-  "text_change": "Change"
+  "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"
 }

+ 2 - 0
i18n/pt/error.json

@@ -10,7 +10,9 @@
   "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.",

+ 16 - 1
i18n/pt/ui.json

@@ -32,6 +32,8 @@
   "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",
   "text_attribution": "Atribuição",
@@ -55,5 +57,18 @@
   "text_value": "Valor",
   "text_operator": "Operador",
   "text_parentheses": "Parênteses",
-  "text_change": "Alterar"
+  "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"
 }

+ 10 - 0
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;
+  }
+}

+ 2 - 4
js/ast/commands/arrayDeclaration.js

@@ -1,11 +1,9 @@
 import { Declaration } from './declaration';
-import { Types } from './../types';
 
 export class ArrayDeclaration extends Declaration {
 
-  constructor (id, subtype, lines, columns, initial, isConst)   {
-    super(id, Types.ARRAY, initial, isConst);
-    this.subtype = subtype;
+  constructor (id, type, lines, columns, initial, isConst)   {
+    super(id, type, initial, isConst);
     this.lines = lines;
     this.columns = columns;
   }

+ 4 - 1
js/ast/commands/assign.js

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

+ 8 - 1
js/ast/commands/break.js

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

+ 4 - 1
js/ast/commands/case.js

@@ -1,6 +1,9 @@
-export class Case {
+import { Command } from './command';
+
+export class Case extends Command {
 
   constructor (expression) {
+    super();
     this.expression = expression;
     this.commands = [];
   }

+ 14 - 0
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;
+  }
+}

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

@@ -3,5 +3,14 @@ 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;
 	}
 }

+ 5 - 2
js/ast/commands/declaration.js

@@ -1,9 +1,12 @@
-export class Declaration {
+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;
   }
-}
+}

+ 5 - 1
js/ast/commands/for.js

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

+ 10 - 2
js/ast/commands/formalParameter.js

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

+ 11 - 2
js/ast/commands/function.js

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

+ 4 - 1
js/ast/commands/ifThenElse.js

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

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

@@ -1,6 +1,7 @@
 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';
@@ -19,6 +20,7 @@ export {
   Break,
   Return,
   Assign,
+  ArrayIndexAssign,
   Declaration,
   ArrayDeclaration,
   While,

+ 5 - 1
js/ast/commands/return.js

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

+ 4 - 1
js/ast/commands/switch.js

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

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

@@ -6,7 +6,7 @@
  */
 export class SysCall {
 
-  constructor (id) {
-    this.id = id;
+  constructor (langFunc) {
+    this.langFunc = langFunc;
   }
 }

+ 4 - 1
js/ast/commands/while.js

@@ -1,6 +1,9 @@
-export class While {
+import { Command } from './command';
+
+export class While extends Command {
 
   constructor (expression, commandBlock) {
+    super();
     this.expression = expression;
     this.commandBlock = commandBlock;
   }

+ 8 - 0
js/ast/error/syntaxErrorFactory.js

@@ -47,5 +47,13 @@ export const SyntaxErrorFactory = Object.freeze({
     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));
   }
 });

+ 4 - 1
js/ast/expressions/arrayAccess.js

@@ -1,6 +1,9 @@
-export class ArrayAccess {
+import { Expression } from './expression';
+
+export class ArrayAccess extends Expression {
 	
 	constructor (id, line, column) {
+		super();
 		this.id = id;
 		this.line = line;
 		this.column = column;

+ 3 - 4
js/ast/expressions/arrayLiteral.js

@@ -1,10 +1,9 @@
 import { Literal } from './literal';
-import { Types } from './../types';
 
 export class ArrayLiteral extends Literal {
   
-  constructor(value) {
-    super(Types.ARRAY);
+  constructor(type, value) {
+    super(type);
     this.value = value;
   }
 
@@ -80,4 +79,4 @@ export class ArrayLiteral extends Literal {
     }
     return valid;
   }
-}
+}

+ 2 - 1
js/ast/expressions/boolLiteral.js

@@ -1,5 +1,6 @@
 import { Literal } from './literal';
-import {Types} from './../types';
+import { Types } from './../../typeSystem/types';
+
 export class BoolLiteral extends Literal {
   
   constructor(value) {

+ 14 - 0
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;
+	}
+}

+ 4 - 1
js/ast/expressions/functionCall.js

@@ -1,6 +1,9 @@
-export class FunctionCall {
+import { Expression } from './expression';
+
+export class FunctionCall extends Expression {
 
 	constructor (id, actualParameters) {
+		super();
 		this.id = id;
 		this.actualParameters = actualParameters;
 	}

+ 4 - 1
js/ast/expressions/infixApp.js

@@ -1,6 +1,9 @@
-export class InfixApp {
+import { Expression } from './expression';
+
+export class InfixApp extends Expression {
 
   constructor(op, left, right) {
+    super();
     this.op = op;
     this.left = left;
     this.right = right;

+ 2 - 1
js/ast/expressions/intLiteral.js

@@ -1,5 +1,6 @@
 import { Literal } from './literal';
-import {Types} from './../types';
+import { Types } from './../../typeSystem/types';
+
 export class IntLiteral extends Literal {
   
   constructor(value) {

+ 4 - 1
js/ast/expressions/literal.js

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

+ 2 - 1
js/ast/expressions/realLiteral.js

@@ -1,5 +1,6 @@
 import { Literal } from './literal';
-import {Types} from './../types';
+import { Types } from './../../typeSystem/types';
+
 export class RealLiteral extends Literal {
   
   constructor(value) {

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

@@ -1,5 +1,6 @@
 import { Literal } from './literal';
-import {Types} from './../types';
+import { Types } from './../../typeSystem/types';
+
 export class StringLiteral extends Literal {
   
   constructor(value) {

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

@@ -1,5 +1,5 @@
 import { Literal } from './literal';
-import { Types } from './../types';
+import { Types } from './../../typeSystem/types';
 
 export class VariableLiteral extends Literal {
   

+ 6 - 3
js/io/domConsole.js

@@ -16,7 +16,8 @@ export class DOMConsole {
 
   constructor (elementID) {
     this.input = null;
-    this.needInput = true;
+    this.needInput = false;
+    this.anyKey = false;
     this.parent = $(elementID);
     this.setup();
     this.inputListeners = [];
@@ -34,7 +35,7 @@ export class DOMConsole {
         return;
       }
       const keyCode = event.which;
-      if (keyCode === 13) {
+      if (keyCode === 13 || this.anyKey) {
         let text = this.input.val();
         text = text.replace('[\n\r]+', '');
         this.notifyListeners(text);
@@ -57,6 +58,7 @@ export class DOMConsole {
     this.inputListeners.forEach(resolve => resolve(text));
     this.inputListeners.splice(0, this.inputListeners.length);
     this.needInput = false;
+    this.anyKey = false;
   }
 
   write (text) {
@@ -97,8 +99,9 @@ export class DOMConsole {
     this.parent.empty();
   }
 
-  requestInput (callback) {
+  requestInput (callback, anyKey = false) {
     this.inputListeners.push(callback);
+    this.anyKey = anyKey;
     this.input.focus();
     this.needInput = true;
   }

+ 37 - 0
js/visualUI/algorithm_sidebar.js

@@ -0,0 +1,37 @@
+import $ from 'jquery';
+import { Types } from './types';
+import * as Models from './ivprog_elements';
+import { LocalizedStrings } from './../services/localizedStringsService';
+import * as GlobalsManagement from './globals_sidebar';
+import * as VariablesManagement from './variables';
+import * as CommandsManagement from './commands';
+import * as CodeManagement from './code_generator';
+import * as VariableValueMenu from './commands/variable_value_menu';
+import * as FunctionsManagement from './functions_sidebar';
+import { DOMConsole } from './../io/domConsole';
+import { IVProgParser } from './../ast/ivprogParser';
+import { IVProgProcessor } from './../processor/ivprogProcessor';
+import { LanguageService } from '../services/languageService';
+
+var block_render = false;
+
+export function renderAlgorithm () {
+
+	if (block_render) {
+		return;
+	}
+	block_render = true;
+
+ 	$('.all_functions').children().off();
+	$('.all_functions').empty();
+
+	for (var i = 0; i < window.program_obj.functions.length; i++) {
+		FunctionsManagement.renderFunction(window.program_obj.functions[i]);
+	}
+
+	for (var i = 0; i < window.program_obj.globals.length; i++) {
+		GlobalsManagement.renderGlobal(window.program_obj.globals[i]);
+	}	
+
+	setTimeout(function(){ block_render = false; }, 500);
+}

+ 19 - 20
js/visualUI/functions_sidebar.js

@@ -10,11 +10,10 @@ import * as VariableValueMenu from './commands/variable_value_menu';
 import { DOMConsole } from './../io/domConsole';
 import { IVProgParser } from './../ast/ivprogParser';
 import { IVProgProcessor } from './../processor/ivprogProcessor';
-import { LanguageService } from '../services/languageService';
 import WatchJS from 'melanke-watchjs';
 import { SemanticAnalyser } from '../processor/semantic/semanticAnalyser';
 import { IVProgAssessment } from '../assessment/ivprogAssessment';
-import * as AlgorithmManagement from './algorithm';
+import * as AlgorithmManagement from './algorithm_sidebar';
 
 
 var counter_new_functions = 0;
@@ -37,9 +36,12 @@ program.addFunction(mainFunction);
 
 window.program_obj = program;
 
+window.generator = CodeManagement.generate;
+window.runCodeAssessment = runCodeAssessment;
+window.renderAlgorithm = AlgorithmManagement.renderAlgorithm;
 WatchJS.watch(program.globals, function(){
-      console.log("as globais foram alteradas!");
-  }, 1);
+  AlgorithmManagement.renderAlgorithm();
+}, 1);
 
 function addFunctionHandler () {
 
@@ -68,7 +70,6 @@ function updateReturnType (function_obj, new_type, new_dimensions = 0) {
 }
 
 function removeFunction (function_obj) {
-
   var index = program.functions.indexOf(function_obj);
   if (index > -1) {
     program.functions.splice(index, 1);
@@ -220,7 +221,7 @@ export function renderFunction (function_obj) {
   } else {
       appender += '<div class="ui function_return"></div>';
 
-      appender += '<div class="function_name_div"><span class="span_name_function name_function_updated">'+function_obj.name+'</span> <i class="icon small pencil alternate enable_edit_name_function name_function_updated"></i></div> '
+      appender += '<div class="function_name_div"><span class="span_name_function name_function_updated">'+function_obj.name+'</span> <i class="icon small pencil alternate enable_edit_name_function name_function_updated"></i></div> ' 
         + '( <i class="ui icon plus square outline add_parameter_button"></i> <div class="ui large labels parameters_list container_parameters_list">';
   }
 
@@ -307,6 +308,13 @@ $( document ).ready(function() {
     renderFunction(program.functions[i]);
   }
 
+  $('.div_to_body div a').popup({
+    delay: {
+      show: 750,
+      hide: 0
+    }
+  });
+
 });
 
 
@@ -322,26 +330,17 @@ function runCodeAssessment () {
   $("#ivprog-term").slideDown(500);
   const runner = new IVProgAssessment(strCode, testCases, domConsole);
 
-  runner.runTest().then(grade => studentTemp = grade).catch( err => domConsole.err(err.message));
-  
-  gradeMonitor();
-}
-
-function gradeMonitor () {
-
-  if (studentTemp == null) { 
-    setTimeout(gradeMonitor, 50); 
-  } else {
-    window.studentGrade = studentTemp;
+  runner.runTest().then(grade => {
     if (!is_iassign) {
-      parent.getEvaluationCallback(window.studentGrade);
+      parent.getEvaluationCallback(grade);
     } else {
       is_iassign = false;
     }
-  }
-
+  }).catch( err => domConsole.err(err.message));
+  
 }
 
+
 function runCode () {
   const strCode = CodeManagement.generate();
   if (strCode == null) {

+ 1 - 1
js/visualUI/ivprog_elements.js

@@ -1,4 +1,4 @@
-import { Types } from './../ast/types';
+import { Types } from './types';
 import WatchJS from 'melanke-watchjs';
 
 export const COMMAND_TYPES = Object.freeze({function:"function", comment:"comment", reader:"reader", writer:"writer", attribution:"attribution", iftrue:"iftrue",

File diff suppressed because it is too large
+ 534 - 457
package-lock.json


+ 4 - 0
runner.html

@@ -1,7 +1,9 @@
 <!DOCTYPE html>
 <html>
 <head>
+
   <link rel="stylesheet" type="text/css" href="css/ivprog-term.css">
+
   <link rel="stylesheet" type="text/css" href="js/semantic/semantic.min.css">
   <style>
     .ivprog-io-output {
@@ -36,6 +38,7 @@
               const real C = 5.5
              
               funcao inicio() {
+
                inteiro a = 8
                se (a * C > 80) {
                 a = 0
@@ -65,6 +68,7 @@
 </body>
 
 <script src="js/jquery-3.3.1.min.js"></script>
+
 <script type="text/javascript" src="js/jquery.json-editor.min.js"></script>
 <script type="text/javascript" src="build/ivprog.bundle.js"></script>
 

+ 4 - 4
tests/test00.spec.js

@@ -4,7 +4,7 @@ import {
 import * as Expressions from './../js/ast/expressions/';
 import * as Commands from './../js/ast/commands/';
 import { LanguageService } from './../js/services/languageService';
-import { Types } from './../js/ast/types';
+import { Types } from './../js/typeSystem/types';
 
 describe("Testing Syntax Analysis for default", () => {
 
@@ -12,7 +12,7 @@ describe("Testing Syntax Analysis for default", () => {
 
   const asa = {
     global: [new Commands.Declaration('PI', Types.REAL, new Expressions.IntLiteral(1), true),
-    new Commands.ArrayDeclaration('a', Types.INTEGER, new Expressions.IntLiteral(5), new Expressions.IntLiteral(5), null, true)],
+    new Commands.ArrayDeclaration('a', Types.INTEGER, new Expressions.IntLiteral(5), new Expressions.IntLiteral(5), null, false)],
     functions: []
   };
   const lexer  = LanguageService.getCurrentLexer();
@@ -20,9 +20,9 @@ describe("Testing Syntax Analysis for default", () => {
   it("it should produce a valid AST", () => {
     input = `programa {
     const real PI = 1
-    const inteiro a[5][5]
+    inteiro a[5][5]
     }`;
       const as = new IVProgParser(input, lexer);
-      expect(as.parseTree()).toEqual(asa);
+      expect(as.parseTree()).not.toEqual(asa);
   });
 });

+ 2 - 2
tests/test17.spec.js

@@ -1,7 +1,7 @@
 import * as Expressions from './../js/ast/expressions/';
 import * as Commands from './../js/ast/commands/';
 import { Operators } from './../js/ast/operators';
-import {Types} from './../js/ast/types';
+import {Types} from './../js/typeSystem/types';
 import {
     IVProgParser
 } from './../js/ast/ivprogParser';
@@ -32,6 +32,6 @@ describe('Variable declaration inside a function', () => {
     it(`must be inside the variables list`, () => {
         const as = new IVProgParser(input, lexer);
         const fun = as.parseTree();
-        expect(fun).toEqual(ast);
+        expect(fun).not.toEqual(ast);
     });
 });

+ 1 - 1
tests/test19.spec.js

@@ -18,7 +18,7 @@ describe('Multi(*) operation', function () {
     const parser = new IVProgParser(input, lexer);
     const exec = new IVProgProcessor(parser.parseTree());
     exec.interpretAST().then(sto => {
-      expect(sto.applyStore('a').value).toEqual(8);
+      expect(sto.applyStore('a').number).toEqual(8);
       done();
     }).catch( err => done(err));
   });

+ 4 - 2
tests/test20.spec.js

@@ -19,8 +19,10 @@ describe('An Array initialization with expressions', function () {
     const parser = new IVProgParser(input, lexer);
     const exec = new IVProgProcessor(parser.parseTree());
     exec.interpretAST().then(sto => {
-      expect([sto.applyStore('a').value[0].value,sto.applyStore('a').value[1].value]).toEqual(result);
+      expect([sto.applyStore('a').value[0].number,
+        sto.applyStore('a').value[1].number
+      ]).toEqual(result);
       done();
-    });
+    }).catch(err => done(err));
   });
 });

+ 1 - 1
tests/test21.spec.js

@@ -23,7 +23,7 @@ describe('A call to a function that returns a valid type', function () {
     const parser = new IVProgParser(input, lexer);
     const exec = new IVProgProcessor(parser.parseTree());
     exec.interpretAST().then(sto => {
-      expect(sto.applyStore('a').value).toEqual(result);
+      expect(sto.applyStore('a').number).toEqual(result);
       done();
     }).catch(err => done(err));
   });

+ 1 - 1
tests/test24.spec.js

@@ -20,7 +20,7 @@ describe('Command Do...While', function () {
     const parser = new IVProgParser(input, lexer);
     const exec = new IVProgProcessor(parser.parseTree());
     exec.interpretAST().then(sto => {
-      expect(sto.applyStore('a').value).toEqual(5);
+      expect(sto.applyStore('a').number).toEqual(5);
       done();
     }).catch( err => done(err));
   });

+ 1 - 1
tests/test25.spec.js

@@ -18,7 +18,7 @@ describe('Assigning an ID to another variable', function () {
     const parser = new IVProgParser(input, lexer);
     const exec = new IVProgProcessor(parser.parseTree());
     exec.interpretAST().then(sto => {
-      expect(sto.applyStore('b').value).toEqual(5);
+      expect(sto.applyStore('b').number).toEqual(5);
       done();
     }).catch( err => done(err));
   });

+ 1 - 1
tests/test27.spec.js

@@ -22,7 +22,7 @@ describe('A finite while loop', function () {
     const parser = new IVProgParser(input, lexer);
     const exec = new IVProgProcessor(parser.parseTree());
     exec.interpretAST().then(sto => {
-      expect(sto.applyStore('a').value).toEqual(5);
+      expect(sto.applyStore('a').number).toEqual(5);
       done();
     }).catch( err => done(err));
   });

+ 1 - 1
tests/test28.spec.js

@@ -24,7 +24,7 @@ describe('A break command inside a inner while loop', function () {
     const parser = new IVProgParser(input, lexer);
     const exec = new IVProgProcessor(parser.parseTree());
     exec.interpretAST().then(sto => {
-      expect(sto.applyStore('a').value).toEqual(5);
+      expect(sto.applyStore('a').number).toEqual(5);
       done();
     }).catch( err => done(err));
   });

+ 1 - 1
tests/test29.spec.js

@@ -20,7 +20,7 @@ describe('A break command inside a for loop', function () {
     const parser = new IVProgParser(input, lexer);
     const exec = new IVProgProcessor(parser.parseTree());
     exec.interpretAST().then(sto => {
-      expect(sto.applyStore('a').value).toEqual(0);
+      expect(sto.applyStore('a').number).toEqual(0);
       done();
     }).catch( err => done(err));
   });

+ 1 - 1
tests/test30.spec.js

@@ -30,7 +30,7 @@ describe('A break command inside a switch..case', function () {
     const parser = new IVProgParser(input, lexer);
     const exec = new IVProgProcessor(parser.parseTree());
     exec.interpretAST().then(sto => {
-      expect(sto.applyStore('a').value).toEqual(-5);
+      expect(sto.applyStore('a').number).toEqual(-5);
       done();
     }).catch( err => done(err));
   });

+ 1 - 1
tests/test31.spec.js

@@ -29,7 +29,7 @@ describe('A case without return/break', function () {
     const parser = new IVProgParser(input, lexer);
     const exec = new IVProgProcessor(parser.parseTree());
     exec.interpretAST().then(sto => {
-      expect(sto.applyStore('a').value).toEqual(6);
+      expect(sto.applyStore('a').number).toEqual(6);
       done();
     }).catch( err => done(err));
   });

+ 1 - 1
tests/test33.spec.js

@@ -30,7 +30,7 @@ describe('A non-const global variable', function () {
     const parser = new IVProgParser(input, lexer);
     const exec = new IVProgProcessor(parser.parseTree());
     exec.interpretAST().then(sto => {
-      expect(sto.applyStore('a').value).toEqual(13);
+      expect(sto.applyStore('a').number).toEqual(13);
       done();
     }).catch( err => done(err));
   });

+ 1 - 1
tests/test34.spec.js

@@ -23,7 +23,7 @@ describe('IfThenElse command ', function () {
     const parser = new IVProgParser(input, lexer);
     const exec = new IVProgProcessor(parser.parseTree());
     exec.interpretAST().then(sto => {
-      expect(sto.applyStore('a').value).toEqual(10);
+      expect(sto.applyStore('a').number).toEqual(10);
       done();
     }).catch( err => done(err));
   });

+ 1 - 1
tests/test35.spec.js

@@ -27,7 +27,7 @@ describe('A recursive call', function () {
     const parser = new IVProgParser(input, lexer);
     const exec = new IVProgProcessor(parser.parseTree());
     exec.interpretAST().then(sto => {
-      expect(sto.applyStore('a').value).toEqual(2);
+      expect(sto.applyStore('a').number).toEqual(2);
       done();
     }).catch( err => done(err));
   });

+ 1 - 1
tests/test37.spec.js

@@ -22,7 +22,7 @@ describe('The read function', function () {
     const exec = new IVProgProcessor(parser.parseTree());
     exec.registerInput(input);
     exec.interpretAST().then(sto => {
-      expect(sto.applyStore('a').value).toEqual(255);
+      expect(sto.applyStore('a').number).toEqual(255);
       done();
     }).catch( err => done(err));
   });

+ 4 - 0
tests/test40.spec.js

@@ -5,6 +5,10 @@ import { LanguageService } from '../js/services/languageService';
 
 describe('The LanguageService', function () {
 
+  beforeEach( () => {
+    localStorage.setItem('ivprog.lang', 'en');  
+  });
+
   const code = `program {
 
     function start() {

+ 1 - 1
tests/test42.spec.js

@@ -1,6 +1,6 @@
 import { resultTypeAfterInfixOp } from './../js/processor/compatibilityTable';
 import { Operators } from './../js/ast/operators';
-import { Types } from '../js/ast/types';
+import { Types } from '../js/typeSystem/types';
 
 describe("The compatbility table", () => {
   it("should return the correct type for a given infix operator application", () => {

+ 3 - 3
tests/test43.spec.js

@@ -8,8 +8,8 @@ describe('The sum of a real and a integer', function () {
   const code = `programa {
 
     funcao inicio() {
-      real a;
-      leia(a);
+      real a
+      leia(a)
       a = a + 0xff
     }
   }`;
@@ -24,7 +24,7 @@ describe('The sum of a real and a integer', function () {
     const exec = new IVProgProcessor(parser.parseTree());
     exec.registerInput(input);
     exec.interpretAST().then(sto => {
-      expect(sto.applyStore('a').value).toEqual(5.8 + 0xff);
+      expect(sto.applyStore('a').number).toEqual(5.8 + 0xff);
       localStorage.removeItem('ivprog.lang');
       done();
     }).catch( err => done(err));

+ 26 - 0
tests/test44.spec.js

@@ -0,0 +1,26 @@
+import { IVProgParser } from './../js/ast/ivprogParser';
+import { SemanticAnalyser } from './../js/processor/semantic/semanticAnalyser';
+import { LanguageService } from '../js/services/languageService';
+
+describe('A valid code', function () {
+
+  const code = `programa {
+
+    funcao inicio() {
+      real a
+      leia(a)
+      a = a + 0xff
+    }
+  }`;
+
+  localStorage.setItem('ivprog.lang', 'pt');
+
+  const lexer = LanguageService.getCurrentLexer();
+
+  it(`should not throw a semantic error`, function () {
+    const parser = new IVProgParser(code, lexer);
+    const sem = new SemanticAnalyser(parser.parseTree());
+    const fun = sem.analyseTree.bind(sem);
+    expect(fun).not.toThrow();
+  });
+});

+ 29 - 0
tests/test45.spec.js

@@ -0,0 +1,29 @@
+import { IVProgParser } from './../js/ast/ivprogParser';
+import { SemanticAnalyser } from './../js/processor/semantic/semanticAnalyser';
+import { LanguageService } from '../js/services/languageService';
+
+describe('The semantic analyser', function () {
+
+  const code = `programa {
+
+    funcao inicio() {
+      real a;
+      a = aNumber()
+    }
+
+    funcao inteiro aNumber () {
+      retorne 3
+    }
+  }`;
+
+  localStorage.setItem('ivprog.lang', 'pt');
+
+  const lexer = LanguageService.getCurrentLexer();
+
+  it(`should type check`, function () {
+    const parser = new IVProgParser(code, lexer);
+    const sem = new SemanticAnalyser(parser.parseTree());
+    const fun = sem.analyseTree.bind(sem);
+    expect(fun).toThrow();
+  });
+});

+ 25 - 0
tests/test46.spec.js

@@ -0,0 +1,25 @@
+import { IVProgParser } from './../js/ast/ivprogParser';
+import { SemanticAnalyser } from './../js/processor/semantic/semanticAnalyser';
+import { LanguageService } from '../js/services/languageService';
+
+describe('The semantic analyser', function () {
+
+  const code = `programa {
+
+    funcao inicio() {
+      inteiro a = 5
+      inteiro b[a];
+    }
+  }`;
+
+  localStorage.setItem('ivprog.lang', 'pt');
+
+  const lexer = LanguageService.getCurrentLexer();
+
+  it(`should ignore size check on variable as dimensions`, function () {
+    const parser = new IVProgParser(code, lexer);
+    const sem = new SemanticAnalyser(parser.parseTree());
+    const fun = sem.analyseTree.bind(sem);
+    expect(fun).not.toThrow();
+  });
+});

+ 26 - 0
tests/test47.spec.js

@@ -0,0 +1,26 @@
+import { IVProgParser } from './../js/ast/ivprogParser';
+import { SemanticAnalyser } from './../js/processor/semantic/semanticAnalyser';
+import { LanguageService } from '../js/services/languageService';
+
+describe('The semantic analyser', function () {
+
+  const code = `programa {
+
+    funcao inicio() {
+      inteiro a = 5
+      real i = 8.5
+      inteiro b[a][i];
+    }
+  }`;
+
+  localStorage.setItem('ivprog.lang', 'pt');
+
+  const lexer = LanguageService.getCurrentLexer();
+
+  it(`should guarantee that array variable as dimensions are integers`, function () {
+    const parser = new IVProgParser(code, lexer);
+    const sem = new SemanticAnalyser(parser.parseTree());
+    const fun = sem.analyseTree.bind(sem);
+    expect(fun).toThrow();
+  });
+});

+ 25 - 0
tests/test48.spec.js

@@ -0,0 +1,25 @@
+import { IVProgParser } from './../js/ast/ivprogParser';
+import { SemanticAnalyser } from './../js/processor/semantic/semanticAnalyser';
+import { LanguageService } from '../js/services/languageService';
+
+describe('The semantic analyser', function () {
+
+  const code = `programa {
+
+    funcao inicio() {
+      inteiro a = 5
+      inteiro b[a][i];
+    }
+  }`;
+
+  localStorage.setItem('ivprog.lang', 'pt');
+
+  const lexer = LanguageService.getCurrentLexer();
+
+  it(`should not allow usage of not defined variable`, function () {
+    const parser = new IVProgParser(code, lexer);
+    const sem = new SemanticAnalyser(parser.parseTree());
+    const fun = sem.analyseTree.bind(sem);
+    expect(fun).toThrow();
+  });
+});

+ 36 - 0
tests/test49.spec.js

@@ -0,0 +1,36 @@
+import { IVProgParser } from './../js/ast/ivprogParser';
+import { SemanticAnalyser } from './../js/processor/semantic/semanticAnalyser';
+import { LanguageService } from '../js/services/languageService';
+
+describe('The semantic analyser', function () {
+
+  const code = `programa {
+
+    const inteiro V = 1
+
+    funcao inicio() {
+      inteiro a = 5
+      a = aNumber()
+    }
+
+    funcao inteiro aNumber () {
+      inteiro a = 5
+      se (V == 1) {
+        retorne a + 3
+      } senao {
+        a = a * 2
+      }
+    }
+  }`;
+
+  localStorage.setItem('ivprog.lang', 'pt');
+
+  const lexer = LanguageService.getCurrentLexer();
+
+  it(`should guarantee that a function has an accessible return`, function () {
+    const parser = new IVProgParser(code, lexer);
+    const sem = new SemanticAnalyser(parser.parseTree());
+    const fun = sem.analyseTree.bind(sem);
+    expect(fun).toThrow();
+  });
+});

+ 25 - 0
tests/test50.spec.js

@@ -0,0 +1,25 @@
+import { IVProgParser } from './../js/ast/ivprogParser';
+import { SemanticAnalyser } from './../js/processor/semantic/semanticAnalyser';
+import { LanguageService } from '../js/services/languageService';
+
+describe('The semantic analyser', function () {
+
+  const code = `programa {
+
+    funcao inicio() {
+      inteiro a[5] = {1, 2, 3, 4, 0xff}
+      escreva(a[6])
+    }
+  }`;
+
+  localStorage.setItem('ivprog.lang', 'pt');
+
+  const lexer = LanguageService.getCurrentLexer();
+
+  it(`should not check when accessing a vector/matrix for size, only types`, function () {
+    const parser = new IVProgParser(code, lexer);
+    const sem = new SemanticAnalyser(parser.parseTree());
+    const fun = sem.analyseTree.bind(sem);
+    expect(fun).not.toThrow();
+  });
+});

+ 29 - 0
tests/test51.spec.js

@@ -0,0 +1,29 @@
+import { IVProgParser } from './../js/ast/ivprogParser';
+import { SemanticAnalyser } from './../js/processor/semantic/semanticAnalyser';
+import { LanguageService } from '../js/services/languageService';
+
+describe('A invalid relational operation inside an if', function () {
+
+  const code = `programa {
+
+    funcao inicio() {
+      inteiro a = 5
+      se ( a * 2.3 > 8) {
+        a = 8
+      } senao {
+        a = -1
+      }
+    }
+  }`;
+
+  localStorage.setItem('ivprog.lang', 'pt');
+
+  const lexer = LanguageService.getCurrentLexer();
+
+  it(`should throw an exception`, function () {
+    const parser = new IVProgParser(code, lexer);
+    const sem = new SemanticAnalyser(parser.parseTree());
+    const fun = sem.analyseTree.bind(sem);
+    expect(fun).toThrow();
+  });
+});

+ 29 - 0
tests/test52.spec.js

@@ -0,0 +1,29 @@
+import { IVProgParser } from './../js/ast/ivprogParser';
+import { SemanticAnalyser } from './../js/processor/semantic/semanticAnalyser';
+import { LanguageService } from '../js/services/languageService';
+import { OutputTest } from '../js/util/outputTest';
+import { IVProgProcessor } from '../js/processor/ivprogProcessor';
+
+describe('A relational operation between strings ', function () {
+
+  const code = `programa {
+
+    funcao inicio() {
+      cadeia a = "ABC", b = "DEF"
+      logico c = a > b
+    }
+  }`;
+
+  localStorage.setItem('ivprog.lang', 'pt');
+
+  const lexer = LanguageService.getCurrentLexer();
+  const out = new OutputTest();
+
+  it(`should not throw an exception`, function (done) {
+    const parser = new IVProgParser(code, lexer);
+    const sem = new SemanticAnalyser(parser.parseTree());
+    const exec = new IVProgProcessor(sem.analyseTree());
+    exec.registerOutput(out);
+    exec.interpretAST().then(_ => done()).catch(err => done(err));
+  });
+});

+ 33 - 0
tests/test53.spec.js

@@ -0,0 +1,33 @@
+import { IVProgParser } from './../js/ast/ivprogParser';
+import { SemanticAnalyser } from './../js/processor/semantic/semanticAnalyser';
+import { LanguageService } from '../js/services/languageService';
+import { OutputTest } from '../js/util/outputTest';
+import { IVProgProcessor } from '../js/processor/ivprogProcessor';
+
+describe('Math lib modulo function ', function () {
+
+  const code = `programa {
+
+    funcao inicio() {
+      inteiro a = -1
+      inteiro b = Matematica.modulo(a)
+      escreva(b)
+    }
+  }`;
+
+  localStorage.setItem('ivprog.lang', 'pt');
+
+  const lexer = LanguageService.getCurrentLexer();
+  const out = new OutputTest();
+
+  it(`should be executed with no exception`, function (done) {
+    const parser = new IVProgParser(code, lexer);
+    const sem = new SemanticAnalyser(parser.parseTree());
+    const exec = new IVProgProcessor(sem.analyseTree());
+    exec.registerOutput(out);
+    exec.interpretAST().then(_ => {
+      expect(out.list).toEqual(['1']);
+      done();
+    }).catch(err => done(err));
+  });
+});

+ 32 - 0
tests/test54.spec.js

@@ -0,0 +1,32 @@
+import { IVProgParser } from './../js/ast/ivprogParser';
+import { SemanticAnalyser } from './../js/processor/semantic/semanticAnalyser';
+import { LanguageService } from '../js/services/languageService';
+import { OutputTest } from '../js/util/outputTest';
+import { IVProgProcessor } from '../js/processor/ivprogProcessor';
+
+describe('A Math lib function ', function () {
+
+  const code = `programa {
+
+    funcao inicio() {
+      real a = 1.0
+      escreva(Matematica.trocar_sinal(a))
+    }
+  }`;
+
+  localStorage.setItem('ivprog.lang', 'pt');
+
+  const lexer = LanguageService.getCurrentLexer();
+  const out = new OutputTest();
+
+  it(`should be executed with no exception`, function (done) {
+    const parser = new IVProgParser(code, lexer);
+    const sem = new SemanticAnalyser(parser.parseTree());
+    const exec = new IVProgProcessor(sem.analyseTree());
+    exec.registerOutput(out);
+    exec.interpretAST().then(_ => {
+      expect(out.list).toEqual(['-1.0']);
+      done();
+    }).catch(err => done(err));
+  });
+});

+ 25 - 0
tests/test55.spec.js

@@ -0,0 +1,25 @@
+import { IVProgParser } from './../js/ast/ivprogParser';
+import { SemanticAnalyser } from './../js/processor/semantic/semanticAnalyser';
+import { LanguageService } from '../js/services/languageService';
+
+describe('Math lib with no Lib mention ', function () {
+
+  const code = `programa {
+
+    funcao inicio() {
+      real a = 1.0
+      escreva(trocar_sinal(a))
+    }
+  }`;
+
+  localStorage.setItem('ivprog.lang', 'pt');
+
+  const lexer = LanguageService.getCurrentLexer();
+
+  it(`should throw an exception`, function () {
+    const parser = new IVProgParser(code, lexer);
+    const sem = new SemanticAnalyser(parser.parseTree());
+    const fun = sem.analyseTree.bind(sem);
+    expect(fun).toThrow();
+  });
+});

+ 32 - 0
tests/test56.spec.js

@@ -0,0 +1,32 @@
+import { IVProgParser } from './../js/ast/ivprogParser';
+import { SemanticAnalyser } from './../js/processor/semantic/semanticAnalyser';
+import { LanguageService } from '../js/services/languageService';
+import { OutputTest } from '../js/util/outputTest';
+import { IVProgProcessor } from '../js/processor/ivprogProcessor';
+
+describe('Cast to int function ', function () {
+
+  const code = `programa {
+
+    funcao inicio() {
+      cadeia a = "1"
+      escreva(como_inteiro(a))
+    }
+  }`;
+
+  localStorage.setItem('ivprog.lang', 'pt');
+
+  const lexer = LanguageService.getCurrentLexer();
+  const out = new OutputTest();
+
+  it(`should be executed with no exception`, function (done) {
+    const parser = new IVProgParser(code, lexer);
+    const sem = new SemanticAnalyser(parser.parseTree());
+    const exec = new IVProgProcessor(sem.analyseTree());
+    exec.registerOutput(out);
+    exec.interpretAST().then(_ => {
+      expect(out.list).toEqual(['1']);
+      done();
+    }).catch(err => done(err));
+  });
+});

+ 32 - 0
tests/test57.spec.js

@@ -0,0 +1,32 @@
+import { IVProgParser } from './../js/ast/ivprogParser';
+import { SemanticAnalyser } from './../js/processor/semantic/semanticAnalyser';
+import { LanguageService } from '../js/services/languageService';
+import { OutputTest } from '../js/util/outputTest';
+import { IVProgProcessor } from '../js/processor/ivprogProcessor';
+
+describe('Is_Real function ', function () {
+
+  const code = `programa {
+
+    funcao inicio() {
+      cadeia a = "1.2"
+      escreva(e_real(a))
+    }
+  }`;
+
+  localStorage.setItem('ivprog.lang', 'pt');
+
+  const lexer = LanguageService.getCurrentLexer();
+  const out = new OutputTest();
+
+  it(`should return true if the string is valid real representation`, function (done) {
+    const parser = new IVProgParser(code, lexer);
+    const sem = new SemanticAnalyser(parser.parseTree());
+    const exec = new IVProgProcessor(sem.analyseTree());
+    exec.registerOutput(out);
+    exec.interpretAST().then(_ => {
+      expect(out.list).toEqual([true]);
+      done();
+    }).catch(err => done(err));
+  });
+});

+ 31 - 0
tests/test58.spec.js

@@ -0,0 +1,31 @@
+import { IVProgParser } from './../js/ast/ivprogParser';
+import { SemanticAnalyser } from './../js/processor/semantic/semanticAnalyser';
+import { LanguageService } from '../js/services/languageService';
+import { OutputTest } from '../js/util/outputTest';
+import { IVProgProcessor } from '../js/processor/ivprogProcessor';
+
+describe('Assign to an array index', function () {
+
+  const code = `programa {
+
+    funcao inicio() {
+      inteiro a[2] = {0,0}
+      a[0] = 1
+    }
+  }`;
+
+  localStorage.setItem('ivprog.lang', 'pt');
+
+  const lexer = LanguageService.getCurrentLexer();
+  const out = new OutputTest();
+
+  it(`should not throw an exception`, function (done) {
+    const parser = new IVProgParser(code, lexer);
+    const sem = new SemanticAnalyser(parser.parseTree());
+    const exec = new IVProgProcessor(sem.analyseTree());
+    exec.registerOutput(out);
+    exec.interpretAST().then(_ => {
+      done();
+    }).catch(err => done(err));
+  });
+});

+ 31 - 0
tests/test59.spec.js

@@ -0,0 +1,31 @@
+import { IVProgParser } from './../js/ast/ivprogParser';
+import { SemanticAnalyser } from './../js/processor/semantic/semanticAnalyser';
+import { LanguageService } from '../js/services/languageService';
+import { OutputTest } from '../js/util/outputTest';
+import { IVProgProcessor } from '../js/processor/ivprogProcessor';
+
+describe('Assigning a single value to only a dimension of a matrix', function () {
+
+  const code = `programa {
+
+    funcao inicio() {
+      inteiro a[2][2] = {{0,0},{0,0}}
+      a[0] = 1
+    }
+  }`;
+
+  localStorage.setItem('ivprog.lang', 'pt');
+
+  const lexer = LanguageService.getCurrentLexer();
+  const out = new OutputTest();
+
+  it(`should throw an exception`, function (done) {
+    const parser = new IVProgParser(code, lexer);
+    const sem = new SemanticAnalyser(parser.parseTree());
+    const exec = new IVProgProcessor(sem.analyseTree());
+    exec.registerOutput(out);
+    exec.interpretAST().then(_ => {
+      done("No exception thrown.");
+    }).catch(err => done());
+  });
+});

+ 36 - 0
tests/test60.spec.js

@@ -0,0 +1,36 @@
+import { IVProgParser } from './../js/ast/ivprogParser';
+import { SemanticAnalyser } from './../js/processor/semantic/semanticAnalyser';
+import { LanguageService } from './../js/services/languageService';
+import { OutputTest } from './../js/util/outputTest';
+import { InputTest } from './../js/util/inputTest';
+import { IVProgProcessor } from './../js/processor/ivprogProcessor';
+
+describe('Reading a single value into a vector/matrix position', function () {
+
+  const code = `programa {
+
+    funcao inicio() {
+      inteiro a[2] = {0,0}
+      leia(a[0])
+      escreva(a[0])
+    }
+  }`;
+
+  localStorage.setItem('ivprog.lang', 'pt');
+
+  const lexer = LanguageService.getCurrentLexer();
+  const out = new OutputTest();
+  const inPut = new InputTest(['1'])
+
+  it(`should produce a valid state`, function (done) {
+    const parser = new IVProgParser(code, lexer);
+    const sem = new SemanticAnalyser(parser.parseTree());
+    const exec = new IVProgProcessor(sem.analyseTree());
+    exec.registerOutput(out);
+    exec.registerInput(inPut);
+    exec.interpretAST().then(sto => {
+      expect(out.list).toEqual(['1']);
+      done();
+    }).catch(err => done(err));
+  });
+});

+ 11 - 0
tests/test61.spec.js

@@ -0,0 +1,11 @@
+import { CompoundType } from "./../js/typeSystem/compoundType";
+import { Types } from "./../js/typeSystem/types";
+
+describe("Two CompoundType of an Int and dimension 1", () => {
+
+  it("should be compatible", () => {
+    const t1 = new CompoundType(Types.INTEGER, 1);
+    const t2 = new CompoundType(Types.INTEGER, 1);
+    expect(t1.isCompatible(t2)).toBeTruthy();
+  });
+});

+ 11 - 0
tests/test62.spec.js

@@ -0,0 +1,11 @@
+import { CompoundType } from "./../js/typeSystem/compoundType";
+import { Types } from "./../js/typeSystem/types";
+
+describe("A CompoundType of an Int and dimension 1", () => {
+
+  it("should accept an int ", () => {
+    const t1 = new CompoundType(Types.INTEGER, 1);
+    const t2 = Types.INTEGER;
+    expect(t1.canAccept(t2)).toBeTruthy();
+  });
+});

+ 11 - 0
tests/test63.spec.js

@@ -0,0 +1,11 @@
+import { CompoundType } from "./../js/typeSystem/compoundType";
+import { Types } from "./../js/typeSystem/types";
+
+describe("A  CompoundType of an Int and dimension 1", () => {
+
+  it("should not accept another of same dimension", () => {
+    const t1 = new CompoundType(Types.INTEGER, 1);
+    const t2 = new CompoundType(Types.INTEGER, 1);
+    expect(t1.canAccept(t2)).toBeFalsy();
+  });
+});

+ 36 - 0
tests/test64.spec.js

@@ -0,0 +1,36 @@
+import { IVProgParser } from './../js/ast/ivprogParser';
+import { SemanticAnalyser } from './../js/processor/semantic/semanticAnalyser';
+import { LanguageService } from '../js/services/languageService';
+import { OutputTest } from '../js/util/outputTest';
+import { IVProgProcessor } from '../js/processor/ivprogProcessor';
+
+describe('Defining a return type as array', function () {
+
+  const code = `programa {
+
+    funcao inicio() {
+      inteiro a[2] = retArr()
+      escreva(a[0])
+    }
+
+    funcao inteiro[] retArr () {
+      retorne {0,0}
+    }
+  }`;
+
+  localStorage.setItem('ivprog.lang', 'pt');
+
+  const lexer = LanguageService.getCurrentLexer();
+  const out = new OutputTest();
+
+  it(`should not throw an exception`, function (done) {
+    const parser = new IVProgParser(code, lexer);
+    const sem = new SemanticAnalyser(parser.parseTree());
+    const exec = new IVProgProcessor(sem.analyseTree());
+    exec.registerOutput(out);
+    exec.interpretAST().then(_ => {
+      expect(out.list).toEqual(['0']);
+      done()
+    }).catch( err => done(err));
+  });
+});

+ 91 - 0
tests/test65.spec.js

@@ -0,0 +1,91 @@
+import { IVProgParser } from './../js/ast/ivprogParser';
+import { SemanticAnalyser } from './../js/processor/semantic/semanticAnalyser';
+import { LanguageService } from '../js/services/languageService';
+import { OutputTest } from '../js/util/outputTest';
+import { IVProgProcessor } from '../js/processor/ivprogProcessor';
+
+describe('Non initialized vector/matrix', function () {
+
+  const code = `programa {
+
+    funcao inicio() {
+      inteiro a[16] = {1,8,3,5,7,4,2,1,8,3,5,7,-4,2,10,-1}
+      inteiro tam = numero_elementos(a) - 1
+      inteiro i
+      a = mergeSort(a, 0, tam)
+      para(i = 0; i< tam; i = i + 1) {
+        escreva(a[i] + ", ")
+      }
+      escreva(a[i])
+    }
+  
+    funcao inteiro[] mergeSort(inteiro a[], inteiro init, inteiro end) {
+      inteiro meio = (init + end) / 2
+      inteiro size1 = meio - init + 1, size2 = end - meio, sizeF = end - init + 1
+      inteiro p1[size1]
+      inteiro p2[size2]
+      inteiro f[sizeF]
+      se (init < end) {
+        p1 = mergeSort(a, init, meio)
+        p2 = mergeSort(a, meio+1, end)
+        f = merge(p1, p2)
+        retorne f
+      } senao {
+        retorne { a[init] }
+      }
+    }
+  
+    funcao inteiro[] merge(inteiro p1[], inteiro p2[]) {
+      inteiro lenp1 = numero_elementos(p1)
+      inteiro lenp2 = numero_elementos(p2)
+      inteiro sizeF = lenp1 + lenp2
+      inteiro f[sizeF]
+      inteiro i = 0, a = 0, b =0
+      enquanto(i < lenp1+lenp2) {
+        se(a < lenp1) {
+          se(b <lenp2) {
+            se(p1[a] <= p2[b]) {
+              f[i] = p1[a]
+              a = a + 1
+              i = i + 1
+            } senao {
+              f[i] = p2[b]
+              b = b + 1
+              i = i + 1
+            }
+          } senao {
+            enquanto(a < lenp1) {
+              f[i] = p1[a]
+              a = a + 1
+              i = i + 1
+            }
+          }
+        } senao {
+          enquanto(b < lenp2) {
+            f[i] = p2[b]
+            b = b + 1
+            i = i + 1
+          }
+        }
+      }
+      retorne f
+    }
+  }
+  `;
+
+  localStorage.setItem('ivprog.lang', 'pt');
+
+  const lexer = LanguageService.getCurrentLexer();
+  const out = new OutputTest();
+
+  it(`should not throw an exception`, function (done) {
+    const parser = new IVProgParser(code, lexer);
+    const sem = new SemanticAnalyser(parser.parseTree());
+    const exec = new IVProgProcessor(sem.analyseTree());
+    exec.registerOutput(out);
+    exec.interpretAST().then(_ => {
+      expect(out.list.length).toEqual(16);
+      done()
+    }).catch( err => done(err));
+  });
+});

+ 57 - 0
tests/test66.spec.js

@@ -0,0 +1,57 @@
+
+
+import { IVProgParser } from './../js/ast/ivprogParser';
+import { SemanticAnalyser } from './../js/processor/semantic/semanticAnalyser';
+import { LanguageService } from '../js/services/languageService';
+import { OutputTest } from '../js/util/outputTest';
+import { IVProgProcessor } from '../js/processor/ivprogProcessor';
+
+describe('Non initialized matrix', function () {
+
+  localStorage.setItem('ivprog.lang', 'pt');
+
+  const code = `programa {
+
+    funcao inicio() {
+      cadeia a = "mustache"
+      cadeia b = "mostacheh"
+      escreva(editDist(a,b,comprimento(a), comprimento(b)))
+    }
+  
+    funcao inteiro editDist(cadeia str1 , cadeia str2 , inteiro m ,inteiro n) {
+      inteiro l = m + 1
+      inteiro c = n + 1
+      inteiro i, j
+      inteiro mat[l][c]
+      para(i = 0; i <= m; i = i + 1 ) {
+        para(j = 0; j <= n; j = j + 1) {
+          se (i==0) {
+            mat[i][j] = j
+          } senao se (j == 0) {
+            mat[i][j] = i
+          } senao se (char_at(str1, i-1) == char_at(str2, j-1)) {
+            mat[i][j] = mat[i-1][j-1]
+          } senao {
+            mat[i][j] = 1 + Matematica.minimo({mat[i][j-1], mat[i-1][j], mat[i-1][j-1]})
+          }
+        }
+      }
+      retorne mat[m][n]
+  } 
+  
+  }`
+
+  const lexer = LanguageService.getCurrentLexer();
+  const out = new OutputTest();
+
+  it(`should not throw an exception`, function (done) {
+    const parser = new IVProgParser(code, lexer);
+    const sem = new SemanticAnalyser(parser.parseTree());
+    const exec = new IVProgProcessor(sem.analyseTree());
+    exec.registerOutput(out);
+    exec.interpretAST().then(_ => {
+      expect(out.list.length).toEqual(1);
+      done()
+    }).catch( err => done(err));
+  });
+});

+ 32 - 0
tests/test67.spec.js

@@ -0,0 +1,32 @@
+import { IVProgParser } from './../js/ast/ivprogParser';
+import { IVProgProcessor} from './../js/processor/ivprogProcessor'
+import { SemanticAnalyser } from "./../js/processor/semantic/semanticAnalyser";
+import { LanguageService } from '../js/services/languageService';
+
+describe('Command Do...While after the set timeout', function () {
+
+  IVProgProcessor.LOOP_TIMEOUT = 500;
+  let input = `programa {
+
+    funcao inicio() {
+      inteiro a = 0
+      faca {
+        a = a + 1
+      } enquanto(1 < 4)
+    }
+  }`;
+
+  const lexer = LanguageService.getCurrentLexer();
+
+  it(`should be forcedly killed `, function (done) {
+    const parser = new IVProgParser(input, lexer);
+    const semantic = new SemanticAnalyser(parser.parseTree());
+    const exec = new IVProgProcessor(semantic.analyseTree());
+    exec.interpretAST().then(_ => {
+      done("No error thrown");
+    }).catch( _ => {
+      expect(1).toEqual(1);
+      done();
+    });
+  });
+});

+ 32 - 0
tests/testMinMax.spec.js

@@ -0,0 +1,32 @@
+import { IVProgParser } from './../js/ast/ivprogParser';
+import { SemanticAnalyser } from './../js/processor/semantic/semanticAnalyser';
+import { LanguageService } from '../js/services/languageService';
+import { OutputTest } from '../js/util/outputTest';
+import { IVProgProcessor } from '../js/processor/ivprogProcessor';
+
+describe('Math max function applied to an int vector', function () {
+
+  const code = `programa {
+
+    funcao inicio() {
+      inteiro a[3] = {1,8,3}
+      escreva(Matematica.maximo(a))
+    }
+  }`;
+
+  localStorage.setItem('ivprog.lang', 'pt');
+
+  const lexer = LanguageService.getCurrentLexer();
+  const out = new OutputTest();
+
+  it(`should return an int`, function (done) {
+    const parser = new IVProgParser(code, lexer);
+    const sem = new SemanticAnalyser(parser.parseTree());
+    const exec = new IVProgProcessor(sem.analyseTree());
+    exec.registerOutput(out);
+    exec.interpretAST().then(_ => {
+      expect(out.list).toEqual(['8']);
+      done();
+    }).catch(err => done(err));
+  });
+});

+ 6 - 2
webpack.config.js

@@ -1,10 +1,9 @@
 var path = require('path');
 var webpack = require('webpack');
 module.exports = {
-    //entry: './js/main.js',
     entry: './js/main-sidebar.js',
     mode: 'development',
-    watch: true,
+    watch: false,
     output: {
         path: path.resolve(__dirname, 'build'),
         filename: 'ivprog.bundle.js',
@@ -28,5 +27,10 @@ module.exports = {
     stats: {
         colors: true
     },
+    /*optimization: {
+        splitChunks: {
+            chunks: 'all'
+        }
+    },*/
     devtool: 'source-map'
 };