FestivAlgo/execution.js

953 lines
23 KiB
JavaScript

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("<input onkeypress='if(event.keyCode == 13) lire(\"" + code[indices[v] + (langage_source == 2 ? 3 : 2)] + "\", " + langage_source + ", " + v + ", " + idlire + ");' autofocus size='7' maxlength='10' id='lire" + idlire + "' placeholder='" + code[indices[v] + (langage_source == 2 ? 3 : 2)].toUpperCase() + " =' required rows='1' cols='5'>");
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] == "&ang;")
{
var valeur = execute_calculs(code[indices[v] + 1], langage_source);
variables[indice_var] = valeur;
display(valeur);
}
else if(code[indices[v] + 2] == "&rarr;")
{
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] == "&ang;")
{
var valeur = execute_calculs(code[indices[v] + 1], langage_source);
display(valeur);
}
else if(code[indices[v] + 2] == "&rarr;")
{
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("<span id='fin_execution'>Fin de l'exécution</span>");
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('<p>' + nombre + '</p>');
if(detecte_nombre(nombre, 1) != "nombre" || nombre.length == 0)
{
display("<span id='fin_execution'>Erreur : veuillez rentrer un nombre.</span>");
display("<input onkeypress='if(event.keyCode == 13) lire(\"" + code[indices[v] + (langage_source == 2 ? 3 : 2)] + "\", " + langage_source + ", " + v + ", " + idlire + ");' autofocus size='7' maxlength='10' id='lire" + idlire + "' placeholder='" + code[indices[v] + (langage_source == 2 ? 3 : 2)].toUpperCase() + " =' required rows='1' cols='5'>");
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('<p>' + message + '</p>');
}
function affiche_variable(myvar) {
$('#var_' + variables[myvar]).replaceWith("<p class='vars' id='var_" + variables[myvar] + "'>" + variables[myvar].toUpperCase() + " = " + variables[myvar + 1] + "</p>");
}
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 "&pi; & variables":
if(escape(compil[j]) == "%u03C0")
compil[j] = "&pi;";
if(compil[j - 1] == "variable" || compil[j] == "&pi;")
{
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('<div id="resultats"></div>');
for(v = 0; v < 52; v += 2)
$('#var_' + variables[v]).replaceWith("<p class='vars' id='var_" + variables[v] + "'></p>");
}
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;
}