#!/bin/bash

shopt -s nullglob extglob
PATH=.:$PATH

# script de test pour le projet de compilation

# vous devez creer 5 repertoires :
# ou utiliser l'option -c
synt_cor=analyse_syntaxique/corrects
synt_incor=analyse_syntaxique/incorrects   
typ_cor=typage/corrects
typ_incor=typage/incorrects
gencode=generation_code
# Les deux premiers repertoires contiennent respectivement des fichiers .pas
# syntaxiquement corrects et incorrects

# Les deux suivants contiennent respectivement des fichiers .pas 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, le nom du compilateur, et le mode
# verbeux ou non.
# (-1 -2 -3 -12 -all -v1 -v2 -v3 -v12 -vall)

ext=.pas

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

echo "Test de $2"
echo

createdir()
{
mkdir -p $synt_cor $synt_incor $typ_cor $typ_incor $gencode
}

compile () {
if [[ $verbose != 0 ]]; then
  echo 
  echo Compile $compilo $1 $2
  $compilo $1 $2; 
else
  $compilo $1 $2 > /dev/null 2>&1;
fi;
}


# 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 $synt_incor/*$ext; do 
    echo -n ".";
    max=`expr $max + 1`;
    compile -parse-only $f;
    tmp=$?
    case $tmp in
	"0") 
	echo
	echo "ECHEC sur "$f" (devrait echouer)";;
	"1") score=`expr $score + 1`;;
	*) 	
	echo
	echo "ECHEC sur "$f" (pour une mauvaise raison : $tmp)";;
    esac
done
echo

# les tests corrects
echo -n "tests corrects "
for f in $synt_cor/*$ext $typ_cor/*$ext $gencode/*$ext; do 
    echo -n ".";
    max=`expr $max + 1`;
    compile -parse-only $f;
    tmp=$?
    case $tmp in
	"1") 
	echo
	echo "ECHEC sur "$f" (devrait reussir)";;
	"0") score=`expr $score + 1`;;
	*) 	
	echo
	echo "ECHEC sur "$f" (pour une mauvaise raison : $tmp)";;
    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 $typ_incor/*$ext; do 
    echo -n ".";
    max=`expr $max + 1`;
    compile -type-only $f;
    tmp=$?
    case $tmp in
	"0") 
	echo
	echo "ECHEC sur "$f" (devrait echouer)";;
	"1") score=`expr $score + 1`;;
	*) 	
	echo
	echo "ECHEC sur "$f" (pour une mauvaise raison : $tmp)";;
    esac
done
echo

# les tests corrects
echo -n "tests corrects "
for f in $typ_cor/*$ext; do 
    echo -n ".";
    max=`expr $max + 1`;
    compile -type-only $f;
    tmp=$?
    case $tmp in
	"1") 
	echo
	echo "ECHEC sur "$f" (devrait reussir)";;
	"0") score=`expr $score + 1`;;
	*) 	
	echo
	echo "ECHEC sur "$f" (pour une mauvaise raison : $tmp)";;
    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 $gencode/*$ext; do 
    echo -n "."
    vm=generation_code/`basename $f .pas`.vm
    rm -f $vm
    out=generation_code/`basename $f .pas`.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 $1 in
    "-v"*)
	verbose=1;;
    "-c")
        createdir;
        echo "Dossiers crees";
        exit 0;;
    *) ;;
esac

for d in $synt_cor $synt_incor $typ_cor $typ_incor $gencode; do
    if test ! -d $d; then
        echo "Un ou plusieurs des dossiers devant contenir les tests\
 est manquant. 
Utilisez $0 -c pour les creer"
        exit 1
    fi
done

case $option in
    "-"?([v])"1" )
        partie1;;
    "-"?([v])"2" )
        partie2;;
    "-"?([v])"3" )
        partie3;;
    "-"?([v])"12" )
        partie1;
        partie2;;
    "-"?([v])"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 "-12     : tester l'analyse syntaxique  et l'analyse semantique (typage)" 
        echo "-3      : tester la generation de code"
        echo "-all    : tester entierement le compilateur"
	echo "-v[1|2|3|12|all] : mode verbeux";;
esac
echo
