var vitesse_execution = 20; boucles_pour = new Array(); idlire = 1; var priorites = [ "π & variables", "outils", "^", "*/%", "+-" ]; var variables = [ "a", 0, "b", 0, "c", 0, "d", 0, "e", 0, "f", 0, "g", 0, "h", 0, "i", 0, "j", 0, "k", 0, "l", 0, "m", 0, "n", 0, "o", 0, "p", 0, "q", 0, "r", 0, "s", 0, "t", 0, "u", 0, "v", 0, "w", 0, "x", 0, "y", 0, "z", 0, "π", 3.141592653 ]; var v; function execution(langage_source, nb) { var j, e, result; if(nb == 0 || reset == 1) { nb = 0; reset = 0; pause = 0; process = 1; boucles_pour[0] = 1; execution_init(); result = compilation(langage_source); if(result == "failed") return "failed"; $('#executer').hide(); $('#pause').show(); reset_variables(); $("#saisie").cleditor()[0].disable(true); } instructions(nb, langage_source); } function instructions(nb, langage_source) { var quit = 0; for(v = nb; v < k; v++) { if(pause == 1) { $('#executer').unbind('click'); $('#executer').click(function() { execution(langage_source, nb + 1); }); pause = 0; return; } if(reset == 1) { process = 0; return; } switch(code[indices[v]]) { case "lire": display(""); lire_pending = 1; idlire++; return; break; case "afficher": var message; switch(code[indices[v] + 1]) { case "chaine": message = code[indices[v] + 2].substring(1, code[indices[v] + 2].length - 1); break; case "calcul": message = execute_calculs(code[indices[v] + 2], langage_source); break; case "variable": message = valeur_variable(code[indices[v] + 2]); break; } display(message); break; case "si": if(execute_condition(v, langage_source) == "false") { var si = 0, ti = 0; for(v = v + 1; ; v++) { if(((langage_source != 3 && si == 0 )|| (langage_source == 3 && ti == 0)) && (code[indices[v]] == "sinon" || code[indices[v]] == "fin_si" || code[indices[v]] == "fin_si_ou_boucle")) break; if(code[indices[v]] == "si") si++; if(code[indices[v]] == "fin_si") si--; if(code[indices[v]] == "si" || code[indices[v]] == "tant_que" || code[indices[v]] == "pour") ti++; if(code[indices[v]] == "fin_si_ou_boucle") ti--; } } break; case "sinon": var si = 0, ti = 0; for(v = v + 1; ; v++) { if(((langage_source != 3 && si == 0 ) || (langage_source == 3 && ti == 0)) && (code[indices[v]] == "fin_si_ou_boucle" || code[indices[v]] == "fin_si")) break; if(code[indices[v]] == "si") si++; if(code[indices[v]] == "fin_si") si--; if(code[indices[v]] == "si" || code[indices[v]] == "tant_que" || code[indices[v]] == "pour") ti++; if(code[indices[v]] == "fin_si_ou_boucle") ti--; } break; case "tant_que": if(execute_condition(v, langage_source) == "false") { var tant_que = 0, ti = 0; for(v = v + 1; ; v++) { if(((langage_source != 3 && tant_que == 0) || (langage_source == 3 && ti == 0)) && (code[indices[v]] == "fin_tant_que" || code[indices[v]] == "fin_si_ou_boucle")) break; if(code[indices[v]] == "tant_que") tant_que++; if(code[indices[v]] == "fin_tant_que") tant_que--; if(code[indices[v]] == "si" || code[indices[v]] == "tant_que" || code[indices[v]] == "pour") ti++; if(code[indices[v]] == "fin_si_ou_boucle") ti--; } } break; case "fin_tant_que": case "fin_si_ou_boucle": var tant_que = 0, ti = 0, mem = v; for(v = v - 2; ; v--) { if(((langage_source != 3 && tant_que == 0) || (langage_source == 3 && ti == 0)) && (code[indices[v + 1]] == "tant_que" || ((code[indices[v + 1]] == "si" || code[indices[v + 1]] == "pour") && langage_source == 3))) { if(code[indices[v + 1]] == "si") v = mem; break; } if(code[indices[v + 1]] == "tant_que") tant_que++; if(code[indices[v + 1]] == "fin_tant_que") tant_que--; if(code[indices[v + 1]] == "si" || code[indices[v + 1]] == "tant_que" || code[indices[v + 1]] == "pour") ti++; if(code[indices[v + 1]] == "fin_si_ou_boucle") ti--; } setTimeout("instructions(" + (v + 1) + ", " + langage_source + ")", vitesse_execution); quit = 1; break; case "pour": var new_pour = 0, a; for(a = 1; a < boucles_pour[0]; a++) { if(boucles_pour[a] == v) { new_pour = a; break; } } var num = new Array; switch(langage_source) { case 1: num[0] = 2; num[1] = 5; num[2] = 8; break; case 2: num[0] = 5; num[1] = 2; num[2] = 8; break; case 3: num[0] = 2; num[1] = 5; num[2] = 8; if(compte_caract(code[indices[v] + num[2]], "(") + 1 == compte_caract(code[indices[v] + num[2]], ")")) code[indices[v] + num[2]] = code[indices[v] + num[2]].substring(0, code[indices[v] + num[2]].length - 1); break; } var indice_var = cherche_variable(code[indices[v] + num[0]]); if(new_pour == 0) { variables[indice_var] = execute_calculs(code[indices[v] + num[1]], langage_source); boucles_pour[boucles_pour[0]] = v; boucles_pour[0]++; } else { if(variables[indice_var] < execute_calculs(code[indices[v] + num[2]], langage_source)) variables[indice_var]++; else { var pour = 0, ti = 0; for(v = v + 1; ; v++) { if(((langage_source != 3 && pour == 0) || (langage_source == 3 && ti == 0)) && (code[indices[v]] == "fin_pour" || code[indices[v]] == "fin_si_ou_boucle")) break; if(code[indices[v]] == "pour") pour++; if(code[indices[v]] == "fin_pour") pour--; if(code[indices[v]] == "si" || code[indices[v]] == "tant_que" || code[indices[v]] == "pour") ti++; if(code[indices[v]] == "fin_si_ou_boucle") ti--; } boucles_pour[new_pour] = -1; } } affiche_variable(indice_var - 1); break; case "fin_pour": var pour = 0; for(v = v - 2; ; v--) { if(pour == 0 && code[indices[v + 1]] == "pour") break; if(code[indices[v + 1]] == "pour") pour++; if(code[indices[v + 1]] == "fin_pour") pour--; } setTimeout("instructions(" + (v + 1) + ", " + langage_source + ")", vitesse_execution); quit = 1; break; case "variable": var indice_var = cherche_variable(code[indices[v] + 1]); if(code[indices[v] + 2] == "prend_la_valeur") variables[indice_var] = execute_calculs(code[indices[v] + 4], langage_source); else if(code[indices[v] + 2] == "∠") { var valeur = execute_calculs(code[indices[v] + 1], langage_source); variables[indice_var] = valeur; display(valeur); } else if(code[indices[v] + 2] == "→") { indice_var = cherche_variable(code[indices[v] + 4]); variables[indice_var] = execute_calculs(code[indices[v] + 1], langage_source); } affiche_variable(indice_var - 1); break; case "calcul": if(code[indices[v] + 2] == "∠") { var valeur = execute_calculs(code[indices[v] + 1], langage_source); display(valeur); } else if(code[indices[v] + 2] == "→") { var indice_var = cherche_variable(code[indices[v] + 4]); variables[indice_var] = execute_calculs(code[indices[v] + 1], langage_source); affiche_variable(indice_var - 1); } break; case "chaine": message = code[indices[v] + 1].substring(1, code[indices[v] + 1].length - 1); display(message); break; case "fin_programme": v = k; break; } if(quit == 1) break; } if(v == k) { display("Fin de l'exécution"); process = 0; $('#pause').hide(); $('#executer').show(); $("#saisie").cleditor()[0].disable(false); } } function lire(myvar, langage_source, nb, id) { var nombre = document.getElementById("lire" + id).value; $('#lire' + id).replaceWith('

' + nombre + '

'); if(detecte_nombre(nombre, 1) != "nombre" || nombre.length == 0) { display("Erreur : veuillez rentrer un nombre."); display(""); document.getElementById("lire" + idlire).focus(); idlire++; return; } var indice_var = cherche_variable(myvar); variables[indice_var] = nombre; affiche_variable(indice_var - 1); if(pause == 1) { $('#executer').hide(); $('#pause').show(); } pause = 0; lire_pending = 0; execution(langage_source, nb + 1); } function paused(langage_source, nb) { execution(langage_source, nb + 1); } function display(message) { $('#resultats').append('

' + message + '

'); } function affiche_variable(myvar) { $('#var_' + variables[myvar]).replaceWith("

" + variables[myvar].toUpperCase() + " = " + variables[myvar + 1] + "

"); } function execute_condition(v, langage_source) { var compil = new Array(), l; compil = compil_condition(v, langage_source); compil = simplifie_condition(compil, 1, compil[0]); for(l = 1; l < compil[0]; l++) { if(compil[l] == "true" || compil[l] == "false") return compil[l]; } } function compil_condition(v, langage_source) { var n; var compil = new Array(); compil[0] = 1; for(n = 1; indices[v] + n < indices[v + 1]; n++) { switch(code[indices[v] + n]) { case "calcul": if(compte_caract(code[indices[v] + n + 1], "(") > compte_caract(code[indices[v] + n + 1], ")")) { compil[compil[0]] = "("; compil[0]++; code[indices[v] + n + 1] = code[indices[v] + n + 1].substring(1, code[indices[v] + n + 1].length); } if(compte_caract(code[indices[v] + n + 1], "(") > compte_caract(code[indices[v] + n + 1], ")")) { compil[compil[0]] = "("; compil[0]++; code[indices[v] + n + 1] = code[indices[v] + n + 1].substring(1, code[indices[v] + n + 1].length); } if(compte_caract(code[indices[v] + n + 1], "(") < compte_caract(code[indices[v] + n + 1], ")")) { code[indices[v] + n + 1] = code[indices[v] + n + 1].substring(0, code[indices[v] + n + 1].length - 1); compil[compil[0]] = execute_calculs(code[indices[v] + n + 1], langage_source); compil[0]++; compil[compil[0]] = ")"; compil[0]++; } else { compil[compil[0]] = execute_calculs(code[indices[v] + n + 1], langage_source); compil[0]++; } if(compte_caract(code[indices[v] + n + 1], "(") < compte_caract(code[indices[v] + n + 1], ")")) { compil[compil[0]] = ")"; compil[0]++; code[indices[v] + n + 1] = code[indices[v] + n + 1].substring(0, code[indices[v] + n + 1].length - 1); } break; case "variable": compil[compil[0]] = valeur_variable(code[indices[v] + n + 1]); compil[0]++; break; case "et": compil[compil[0]] = "et"; compil[0]++; break; case "ou": compil[compil[0]] = "ou"; compil[0]++; break; case "signe": compil[compil[0]] = code[indices[v] + n + 1]; compil[0]++; break; } } return compil; } function simplifie_condition(compil, min, max) { /* // Gestion des parenthèses */ var j, l, parenthese; for(j = min; j < max; j++) { if(compil[j] == "(") { parenthese = 1; for(l = j + 1; l < max; l++) { if(compil[l] == "(") parenthese++; if(compil[l] == ")") parenthese--; if(parenthese == 0 && compil[l] == ")") { compil[j] = "rien"; compil[l] = "rien"; compil = simplifie_condition(compil, j + 1, l); break; } } } if(compil[j] == "<" || compil[j] == ">" || compil[j] == "=" || escape(compil[j]) == "%u2260" || escape(compil[j]) == "%u2264" || escape(compil[j]) == "%u2265") { var last = precedente_valeur(compil, j, 1); var next = prochaine_valeur(compil, j, 1); switch(compil[j]) { case "<": if(compil[last] < compil[next]) compil[j] = "true"; else compil[j] = "false"; break; case ">": if(compil[last] > compil[next]) compil[j] = "true"; else compil[j] = "false"; break; case "=": if(compil[last] == compil[next]) compil[j] = "true"; else compil[j] = "false"; break; } switch(escape(compil[j])) { case "%u2260": if(compil[last] != compil[next]) compil[j] = "true"; else compil[j] = "false"; break; case "%u2264": if(compil[last] <= compil[next]) compil[j] = "true"; else compil[j] = "false"; break; case "%u2265": if(compil[last] >= compil[next]) compil[j] = "true"; else compil[j] = "false"; break; } compil[last] = "rien"; compil[next] = "rien"; do { var operateur = -1, resultat = -1; for(var r = j - 1; r >= 1; r--) { if(operateur == -1 && (compil[r] == "et" || compil[r] == "ou")) operateur = r; if(operateur != -1 && resultat == -1 && (compil[r] == "true" || compil[r] == "false")) resultat = r; if(compil[r] == "(" || compil[r] == ")") break; } if(operateur != -1 && resultat != -1) { if(compil[operateur] == "et") { if(compil[j] == "true" && compil[resultat] == "true") compil[operateur] = "true"; else compil[operateur] = "false"; } else if(compil[operateur] == "ou") { if(compil[j] != compil[resultat] || compil[j] == "true") compil[operateur] = "true"; else compil[operateur] = "false"; } compil[j] = "rien"; compil[resultat] = "rien"; j = operateur; } } while(operateur != -1 && resultat != -1); } } return compil; } function execute_calculs(calcul, langage_source) { compil = new Array(); compil = compil_calculs(calcul, langage_source); compil = simplifie_calculs(compil, 2, compil[0], langage_source, calcul); for(j = 1; j < compil[0]; j++) { if(compil[j] != "rien" && compil[j] != "(" && compil[j] != ")" && compil[j] != "parenthese" && compil[j] != "outil" && compil[j] != "undefined") { return Math.round(compil[j + 1] * 10e8) / 10e8; } } return "erreur"; } function compil_calculs(calcul, langage_source) { var i, current, position = 0, longer, type; var compil = new Array(); compil[0] = 1; while(position < calcul.length) { type = "autre"; longer = -1; for(i = 0; i < calcul.substring(position, calcul.length).length; i++) { current = calcul.substring(position, calcul.length - i); if(detecte_calculs2(current, langage_source) == "calcul") { longer = calcul.length - i; break; } } if(i == calcul.substring(position, calcul.length).length + 1) alert("erreur"); if(detecte_nombre(calcul.substring(position, longer), 0) == "nombre") type = "nombre"; if(detecte_variable(calcul.substring(position, longer)) == "variable") type = "variable"; if(detecte_operation(calcul.substring(position, longer)) == "operation") type = "operation"; if(detecte_parenthese(calcul.substring(position, longer)) == "parenthese") type = "parenthese"; if(detecte_outils(calcul.substring(position, longer), langage_source) == "outils") type = "outils"; compil[compil[0]] = type; compil[compil[0] + 1] = calcul.substring(position, longer); compil[0] += 2; if(compil[compil[0] - 1] == "hasard") { compil[compil[0]] = "rien"; compil[compil[0] + 1] = "rien"; compil[0] += 2; } if(compil[compil[0] - 1] == "#ran") { compil[compil[0]] = compil[compil[0] - 2]; compil[compil[0] + 1] = compil[compil[0] - 1]; compil[compil[0] - 2] = "rien"; compil[compil[0] - 1] = "rien"; compil[0] += 2; } position = longer; } return compil; } function simplifie_calculs(calcul, min, max, langage_source, expression) { var j, l, parenthese, p, last, next; /* // Gestion des parenthèses */ for(j = min; j < max; j += 2) { if(compil[j] == "(" && compte_caract(expression, ")") > 0) { parenthese = 1; for(l = j + 2; l < max; l += 2) { if(compil[l] == "(") parenthese++; if(compil[l] == ")") parenthese--; if(parenthese == 0 && compil[l] == ")") { compil[j - 1] = "rien"; compil[j] = "rien"; compil[l - 1] = "rien"; compil[l] = "rien"; compil = simplifie_calculs(compil, j + 2, l - 1, langage_source, ""); break; } } } } /******************************************************************/ for(p = 0; p < 6; p++) { for(j = min; j < max; j += 2) { last = precedente_valeur(compil, j, 2); next = prochaine_valeur(compil, j, 2); switch(priorites[p]) { case "π & variables": if(escape(compil[j]) == "%u03C0") compil[j] = "π"; if(compil[j - 1] == "variable" || compil[j] == "π") { compil[j - 1] = "nombre"; compil[j] = valeur_variable(compil[j]); } break; case "outils": if(compil[j - 1] == "outils") { if(compil[next - 1] != "nombre" && compil[j] != "#ran") alert("erreur outils"); else { if(compil[j] == "racine_carrée") { compil[j - 1] = "rien"; compil[j] = "rien"; compil[next] = Math.sqrt(compil[next]); if(escape(compil[next]) == "NaN") alert("erreur domaine de définition racine carrée"); } if(compil[j] == "exp") { compil[j - 1] = "rien"; compil[j] = "rien"; compil[next] = Math.exp(compil[next]); } if(compil[j] == "ln") { compil[j - 1] = "rien"; compil[j] = "rien"; compil[next] = Math.log(compil[next]); if(escape(compil[next]) == "NaN") alert("erreur domaine de définition du logarithme népérien"); } if(compil[j] == "hasard" || compil[j] == "rand") { compil[j - 1] = "nombre"; compil[j] = Math.random(); compil[j + 1] = "operation"; compil[j + 2] = "*"; } if(compil[j] == "#ran") { compil[j - 1] = "nombre"; compil[j] = Math.random(); compil[last + 1] = "operation"; compil[last + 2] = "*"; } if(compil[j] == "partie_entière" || compil[j] == "int") { compil[j - 1] = "rien"; compil[j] = "rien"; compil[next] = Math.floor(compil[next]); } if(compil[j] == "partie_décimale" || compil[j] == "frac" || compil[j] == "fpart") { compil[j - 1] = "rien"; compil[j] = "rien"; compil[next] -= Math.floor(compil[next]); } if(compil[j] == "valeur_absolue" || compil[j] == "abs") { compil[j - 1] = "rien"; compil[j] = "rien"; compil[next] = Math.abs(compil[next]); } } } break; case "^": if(compil[j] == "^") { if(compil[last - 1] != "nombre" || compil[next - 1] != "nombre") alert("erreur ^"); else { compil[last] = Math.pow(compil[last], compil[next]); compil[j - 1] = "rien"; compil[j] = "rien"; compil[next - 1] = "rien"; compil[next] = "rien"; } } break; case "*/%": if(compil[j] == "*" || compil[j] == "/" || compil[j] == "%") { if(compil[last - 1] != "nombre" || compil[next - 1] != "nombre") alert("erreur */%"); else { switch(compil[j]) { case "*": compil[last] = compil[last] * compil[next]; break; case "/": compil[last] = compil[last] / compil[next]; break; case "%": compil[last] = compil[last] % compil[next]; break; } if(escape(compil[last]) == "NaN") alert("erreur */%"); if(escape(compil[last]) == "Infinity") alert("erreur division par 0"); compil[j - 1] = "rien"; compil[j] = "rien"; compil[next - 1] = "rien"; compil[next] = "rien"; } } break; case "+-": if(compil[j] == "+" || compil[j] == "-") { if(compil[next - 1] != "nombre") alert("erreur +-"); else { if(compil[last - 1] != "nombre") { if(compil[j] == "+") compil[next] = 1 * compil[next]; else compil[next] = - compil[next]; } else { if(compil[j] == "+") compil[last] = 1 * compil[last] + 1 * compil[next]; else compil[last] = compil[last] - compil[next]; compil[next - 1] = "rien"; compil[next] = "rien"; } compil[j - 1] = "rien"; compil[j] = "rien"; } } break; } } } return compil; } function detecte_calculs2(mot, langage_source) { mot = mot.toLowerCase(); if(detecte_nombre(mot, 0) == "nombre" || detecte_variable(mot) == "variable" || detecte_operation(mot) == "operation" || detecte_parenthese(mot) == "parenthese" || detecte_outils(mot, langage_source) == "outils" || escape(mot) == "%u03C0") return "calcul"; else return "undefined"; } function reset_variables() { var i; for(i = 0; i < 26; i++) variables[2 * i + 1] = 0; } function valeur_variable(myvar) { return variables[cherche_variable(myvar)]; } function cherche_variable(myvar) { var i; for(i = 0; i < 27; i++) { if(variables[2 * i] == myvar) return 2 * i + 1; } alert("variable inconnue"); } function prochaine_valeur(compil, j, pas) { var i; for(i = j + pas; i < compil[0]; i += pas) { if(compil[i] != "rien" && compil[i] != "true" && compil[i] != "false" && compil[i] != "et" && compil[i] != "ou" && compil[i] != "(" && compil[i] != ")" && compil[i] != "NaN") return i; } } function precedente_valeur(compil, j, pas) { var i; for(i = j - pas; i > 0; i -= pas) { if(compil[i] != "rien" && compil[i] != "true" && compil[i] != "false" && compil[i] != "et" && compil[i] != "ou" && compil[i] != "(" && compil[i] != ")" && compil[i] != "NaN") return i; } } function execution_init() { $('#resultats').replaceWith('
'); for(v = 0; v < 52; v += 2) $('#var_' + variables[v]).replaceWith("

"); } function compte_caract(chaine, type) { var i, nb = 0; for(i = 0; i < chaine.length; i++) { if(chaine.substring(i, i + 1) == type) nb++; } return nb; }