(**
** Lattakia Compiler
** Columbia University COMS-4115
** Programming Languages and Translators
** Authors:
** Wael Salloum
** Heba ElFardy
** Katherine Scott
**)
open Ast 
open LatticeCreation
open SemanticAnalysis
open Evaluate
open PrintLattice

let testMode = false;;

let _ =
(* Lexical Analysis *)
  let lexbuf = Lexing.from_channel stdin in
(* Syntactic Analysis *)
  let latticeAndEnv = Latparser.lattice Scanner.token lexbuf in
  let env = snd latticeAndEnv in
  let lattice = createNewLatFromLatEnvTuple(latticeAndEnv, env.namesOfCurrLat)  in 
	if testMode then
		print_endline ("\n\t>>>>> Parser Output <<<<<\n" ^ (PrintLattice.toString lattice {printEnv.options with doProcessSymbolTable = false; doAnnotateTypes=false}));

(* Semantic Analysis *)
	let (lattice, latticeType) = SemanticAnalysis.analyzeSemantics lattice in
	if testMode then print_endline ("\n\t>>>>> Semantic Output <<<<<\n" ^ (PrintLattice.toString lattice {printEnv.options with doProcessSymbolTable=true; doAnnotateTypes=true}));
	print_endline (if List.length env.errorTable != 0 then ("\n\t>>>>> Errors <<<<<\n"^(stringOfErrorTable env.errorTable)) else ""
	);
	if (match latticeType with 
		| (MismatchType, _) -> print_endline("Semantic Analysis >> Error: Type Mismatch: "^(PrintLattice.dataStructTypeToString latticeType)); true
		| (UnresolvedType, _) -> 	if testMode then print_endline("Semantic Analysis >> Ambiguity: Unresolved Type: "^(PrintLattice.dataStructTypeToString latticeType)); false
		| (x, y) -> 	if testMode then print_endline("Semantic Analysis >> Succeeded! Lattice Type: "^(PrintLattice.dataStructTypeToString latticeType)); false
	) then () else (*Continue*) 

		if (List.length env.errorTable) > 0 then () else (
	(* Execution (The Interpreter) *)
		let exprValue = Evaluate.eval lattice in
	(* Output *)
		PrintLattice.printEnv.options <- {processCode=false; doProcessSymbolTable = false; doAnnotateTypes=false};
	  let result = gs (PrintLattice.processExprValue exprValue) "FATAL ERROR: COULD NOT EVALUATE THE LATTICE!" in
	  print_endline (	(if testMode then "\n\t>>>>> Final Output <<<<<\n" else "")^ result ^ "\n")
	)
	
	
	
	
	
	
