Statistics: |
|
|
000002| This program is free software; you can redistribute it and / or modify
000003| it under the terms of the GNU General Public License as published by
000004| the Free Software Foundation; version 3 of the License.
000005|
000006| This program is distributed in the hope that it will be useful,
000007| but WITHOUT ANY WARRANTY; without even the implied warranty of
000008| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
000009| GNU General Public License for more details.
000010|
000011| Jtemplate initialization and launching of program
000012|
000013| @author Tony BenBrahim < tony.benbrahim at gmail.com >
000014|
000015| *)
000016|
000017| open Lexer
000018| open Parser
000019| open Lexing
000020| open Ast
000021| open Filename_util
000022| open RuntimeError
000023| open Environment
000024| open Analysis
000025| open Ast_info
000026|
000027| let _ =
000028| (**
000029| Registers script arguments (arguments following the script file)
000030| @param args a list of string arguments
000031| @env runtime environment
000032| @return unit
000033| *)
000034| (*[2]*)let register_args args env =
000035| (*[2]*)let h = Hashtbl.create 1
000036| in (*[2]*)let rec loop = function
000037| | (n,[]) ->
000038| (*[2]*)Hashtbl.add h "length" (RIntegerValue(n));
000039| (*[2]*)Environment.set_value env (RMapValue(h, ArraySubtype)) (GlobalVar(0, 0))
000040| | (ind,arg::tl) -> (*[2]*)Hashtbl.add h (string_of_int ind) (RStringValue(arg)); (*[2]*)loop (ind+1,tl)
000041| in (*[2]*)loop (0,args);
000042| (* parse command line arguments *)
000043| in (*[2]*)let show_parse_tree = ref false and args_list = ref [] and print_version = ref false
000044| in (*[2]*)let _ = Arg.parse
000045| [("-parsetree", Arg.Unit (fun () -> (*[2]*)show_parse_tree := true), "print the parse tree and symbols before executing the program");
000046| ("-version", Arg.Unit (fun () -> (*[0]*)print_version := true), "print the version and exit")
000047| ] (fun arg -> (*[2]*)args_list:= (arg::!args_list)) ("jtemplate [-p] scriptfile [scriptargs...]" ^
000048| "scriptfile the script file to execute, read from stdin if missing\n"^"scriptargs... optional script arguments, separated by a space")
000049| in (*[2]*)let _ = (if !print_version then ((*[0]*)print_string "Jtemplate 0.8\n"; (*[0]*)exit(0)) else (*[2]*)())
000052| | [] -> (*[0]*)"-"
000054| (* generate parsing AST *)
000055| in (*[2]*)let ast = try
000056| (*[2]*)if filename ="-" then (*[0]*)Parser_util.parse stdin "stdin"
000058| (*[2]*)let resolved_filename=resolve_filename (Unix.getcwd()) filename
000059| in (*[2]*)Unix.chdir (Filename.dirname resolved_filename);
000060| (*[2]*)Parser_util.parse_filename (resolved_filename)
000061| )
000062| with ParseException(_) as ex ->
000063| (*[0]*)RuntimeError.display_error ex ("", 0);
000064| (*[0]*)exit(2)
000066| in (*[2]*)let (ast, env) =
000067| try (*[2]*)Analysis.analyze ast
000068| with
000069| | RuntimeError.FatalExit(_) -> (*[0]*)exit(2)
000071| (*[0]*)RuntimeError.display_error ex ("", 0);
000072| (*[0]*)exit(2)
000074| in (*[2]*)let _ = (if !show_parse_tree then
000075| ((*[2]*)AstInfo.print_ast ast; (*[2]*)print_name_info env)
000076| else
000077| (*[0]*)())
000079| (* create a runtime environment *)
000080| (*[2]*)let renv ={
000081| heap = Array.make env.num_globals (- 1, RUndefined);
000082| stackframes = Array.make (env.max_depth + 1) [||];
000083| closure_vars = None;
000084| gnames = Array.of_list env.names;
000085| current_line = ("", 0);
000086| callstack = Stack.create ();
000087| skip_callstack_pop = false;
000088| }
000089| (* copy library definitions to runtimwe environment *)
000090| in (*[2]*)let _ = Library.register_for_runtime env renv
000091| in (*[2]*)let _ = register_args args renv
000092| (* interpret runtime AST *)
000093| in (*[2]*)try
000094| (*[2]*)Interpreter.interpret renv ast
000095| with
000096| | RuntimeError.FatalExit _ -> (*[0]*)exit(1)
000098| (*[0]*)RuntimeError.display_error ex renv.current_line;
000099| (*[0]*)Stack.iter (fun loc -> (*[0]*)let (file, line) = loc in
000100| (*[0]*)print_string ("\tCalled from " ^ file ^ " line " ^ (string_of_int line))) renv.callstack;
000101| (*[0]*)exit(1)