unit interpreteur;
(* Interpreteur Basic de PetitBasic. *)

interface

uses instructions;

type    TYPE_ERREUR_INTERPRETEUR =
	(
		INTERPRETEUR_OKAY,
		PROGRAMME_FINIE,	(* pseudo-erreur *)

		PAS_ASSEZ_MEMOIRE,
		DIVISION_PAR_ZERO,
		CONCATENATION_TROP_LONGUE,

		INPUT_ATTEND_ENTIER,
		INPUT_ATTEND_REEL,
		INPUT_ATTEND_CHAINE,

		LIGNE_PAS_TROUVE,
		OVERFLOW_PILE_GOSUB,
		UNDERFLOW_PILE_GOSUB,
		OVERFLOW_PILE_WHILE,
		UNDERFLOW_PILE_WHILE,
		OVERFLOW_PILE_FOR_TO,
		UNDERFLOW_PILE_FOR_TO
	);

var	erreur_interpreteur	: TYPE_ERREUR_INTERPRETEUR;

procedure	initialise_interpreteur;
procedure	termine_interpreteur;
procedure 	explique_erreur_interpreteur (ligne : string);

implementation

uses lignes, variables;

var	initialise	: boolean;

procedure initialise_interpreteur;
(* Initialise l'interpr‚teur, c'est … dire initialise son environnement. *)

begin
	initialise := true;
	initialise_gestionnaire_lignes;
	initialise_gestionnaire_variables;
end;

procedure termine_interpreteur;
(* Termine l'interpr‚teur, libŠre la m‚moire si n‚cessaire, les donn‚es non
 * sauvegard‚es sont perdues.
 *)

begin
	if not initialise then begin
		writeln('Erreur Interne: Interpreteur non initialis‚!');
		halt;
	end else begin
		initialise := false;
		termine_gestionnaire_lignes;
		termine_gestionnaire_variables;
	end;
end;

procedure explique_erreur_interpreteur (ligne : string);
(* En cas d'erreur, donne explique l'erreur, cette proc‚dure doit ˆtre
 * appel‚ dans le contexte de l'erreur.
 *)

const	LISTE_EXPLICATIONS : array [1..14] of string =
	(
		'Programme termin‚!',
		'Pas assez de m‚moire!',
		'Division par z‚ro!',
		'Concat‚nation trop longue (au maximum 255 caractŠres)!',

		'Attend un entier!',
		'Attend un r‚el!',
		'Attend une chaine!',

		'Ligne pas trouv‚!',
		'D‚bordement de la pile d''appel gosub!',
		'Instruction return sans gosub!',
		'D‚bordement de la pile d''appel while!',
		'Instruction wend sans while!',
		'D‚bordement de la pile d''appel for to!',
		'Instruction next sans for to!'
	);

begin
	if length(ligne) > 0 then begin
		write('Erreur Interpreteur: ');
		writeln(LISTE_EXPLICATIONS[ord(erreur_interpreteur)]);
		writeln(ligne);
	end;
end;

begin
	initialise := false;
end.