#!/bin/bash

shopt -s nullglob

# script de test pour le projet de compilation

# vous devez creer 5 repertoires :
#
# analyse_syntaxique/corrects   
# analyse_syntaxique/incorrects   
# typage/corrects
# typage/incorrects
# generation_code/

# Les deux premiers repertoires contiennent respectivement des fichiers .ml 
# syntaxiquement corrects et incorrects

# Les deux suivants contiennent respectivement des fichiers .ml bien et 
# mal typés (mais syntaxiquement corrects)

# Enfin, le dernier contient des fichiers corrects qui doivent pouvoir etre
# compiles par votre compilateur.

# Ce script de test prend en entree une option indiquant quelle etape
# du compilateur vous souhaitez tester et le nom du compilateur.


option=$1
compilo=$2
score=0
max=0

echo "Test de $2"
echo

compile () {
  $compilo $1 $2 > /dev/null 2>&1
}


# partie 1 : tests pour l'analyse syntaxique

partie1 () {

score=0
max=0

echo "Tests pour l'analyse syntaxique"

# les tests incorrects
echo -n "tests incorrects "
for f in analyse_syntaxique/incorrects/*.ml; do 
    echo -n ".";
    max=`expr $max + 1`;
    compile -parse-only $f; 
    case $? in
	"0") 
	echo
	echo "ECHEC sur "$f" (devrait echouer)";;
	"1") score=`expr $score + 1`;;
	*) 	
	echo
	echo "ECHEC sur "$f" (pour une mauvaise raison)";;
    esac
done
echo

# les tests corrects
echo -n "tests corrects "
for f in analyse_syntaxique/corrects/*.ml typage/incorrects/*.ml typage/corrects/*.ml generation_code/*.ml; do 
    echo -n ".";
    max=`expr $max + 1`;
    compile -parse-only $f;
    case $? in
	"1") 
	echo
	echo "ECHEC sur "$f" (devrait reussir)";;
	"0") score=`expr $score + 1`;;
	*) 	
	echo
	echo "ECHEC sur "$f" (pour une mauvaise raison)";;
    esac
done
echo

percent=`expr 100 \* $score / $max`; 

echo -n "Analyse syntaxique: $score/$max : $percent%"; }

# partie 2 : tests pour l'analyse semantique (typage)


partie2 () {
echo
echo "Tests pour l'analyse semantique (typage)"

score=0
max=0

# les tests incorrects
echo -n "tests incorrects "
for f in typage/incorrects/*.ml; do 
    echo -n ".";
    max=`expr $max + 1`;
    compile -type-only $f; 
    case $? in
	"0") 
	echo
	echo "ECHEC sur "$f" (devrait echouer)";;
	"1") score=`expr $score + 1`;;
	*) 	
	echo
	echo "ECHEC sur "$f" (pour une mauvaise raison)";;
    esac
done
echo

# les tests corrects
echo -n "tests corrects "
for f in typage/corrects/*.ml generation_code/*.ml; do 
    echo -n ".";
    max=`expr $max + 1`;
    compile -type-only $f;
    case $? in
	"1") 
	echo
	echo "ECHEC sur "$f" (devrait reussir)";;
	"0") score=`expr $score + 1`;;
	*) 	
	echo
	echo "ECHEC sur "$f" (pour une mauvaise raison)";;
    esac
done
echo

percent=`expr 100 \* $score / $max`; 

echo    "Analyse semantique (typage): $score/$max : $percent%"; }

# partie 3 : tests d'execution

partie3 () {

score_comp=0
score_out=0
score_test=0
max=0

echo
echo "Tests pour la generation de code"

for f in generation_code/*.ml; do 
    echo -n "."
    vm=generation_code/`basename $f .ml`.vm
    rm -f $vm
    out=generation_code/`basename $f .ml`.out
    max=`expr $max + 1`;
    if compile $f; then
	rm -f output;
	score_comp=`expr $score_comp + 1`;
	if vm $vm > output 2> /dev/null; then
	    score_out=`expr $score_out + 1`;
	    if cmp $out output; then
		score_test=`expr $score_test + 1`;	
	    else
		echo
		echo "ECHEC : mauvaise sortie pour $f"
	    fi
	else
		echo	    
		echo "ECHEC du code produit pour $f"
	fi
    else
	echo
	echo "ECHEC de la compilation sur $f (devrait reussir)"
    fi
done
echo

percent=`expr 100 \* $score / $max`; 

echo "Generation de code:";
percent=`expr 100 \* $score_comp / $max`; 
echo "Compilation : $score_comp/$max : $percent%";
percent=`expr 100 \* $score_out / $max`;
echo "Code produit : $score_out/$max : $percent%";
percent=`expr 100 \* $score_test / $max`;
echo "Comportement du code : $score_test/$max : $percent%";}


case $option in
    "-1" )
        partie1;;
    "-2" )
        partie2;;
    "-3" )
        partie3;;
    "-all" )
    	partie1;
    	partie2;
    	partie3;;
    * )
        echo "usage : $0 <option> <compilo>"
        echo "specifier une option parmi : "
        echo "-1      : tester l'analyse syntaxique" 
        echo "-2      : tester l'analyse semantique (typage)" 
        echo "-3      : tester la generation de code"
        echo "-all    : tester entierement le compilateur";;   
esac
echo
