|
@@ -104,6 +104,25 @@ and eval_binop_exprs ctx e1 e2 =
|
|
|
| TString s, (TVersion _ as v2) -> (parse_version s (snd e1), v2)
|
|
|
| v1, v2 -> (v1, v2)
|
|
|
|
|
|
+class dead_block_collector = object(self)
|
|
|
+ val dead_blocks = DynArray.create ()
|
|
|
+ val mutable current_block = []
|
|
|
+
|
|
|
+ method open_dead_block (p : pos) =
|
|
|
+ current_block <- {p with pmin = p.pmax} :: current_block
|
|
|
+
|
|
|
+ method close_dead_block (p : pos) = match current_block with
|
|
|
+ | [] ->
|
|
|
+ error (Custom "Internal error: Trying to close dead block that's not open") p;
|
|
|
+ | p0 :: pl ->
|
|
|
+ current_block <- pl;
|
|
|
+ DynArray.add dead_blocks ({p0 with pmax = p.pmin})
|
|
|
+
|
|
|
+ method get_dead_blocks =
|
|
|
+ assert(current_block = []);
|
|
|
+ DynArray.to_list dead_blocks
|
|
|
+end
|
|
|
+
|
|
|
(* parse main *)
|
|
|
let parse ctx code file =
|
|
|
let old = Lexer.save() in
|
|
@@ -135,6 +154,7 @@ let parse ctx code file =
|
|
|
error (Custom line) p
|
|
|
in
|
|
|
|
|
|
+ let dbc = new dead_block_collector in
|
|
|
let sraw = Stream.from (fun _ -> Some (Lexer.sharp_token code)) in
|
|
|
let rec next_token() = process_token (Lexer.token code)
|
|
|
|
|
@@ -155,12 +175,23 @@ let parse ctx code file =
|
|
|
| _ :: l ->
|
|
|
mstack := l;
|
|
|
next_token())
|
|
|
- | Sharp "else" | Sharp "elseif" ->
|
|
|
+ | Sharp "elseif" ->
|
|
|
+ (match !mstack with
|
|
|
+ | [] -> tk
|
|
|
+ | _ :: l ->
|
|
|
+ let _,(_,pe) = parse_macro_cond sraw in
|
|
|
+ dbc#open_dead_block pe;
|
|
|
+ mstack := l;
|
|
|
+ let tk = skip_tokens (pos tk) false in
|
|
|
+ process_token tk)
|
|
|
+ | Sharp "else" ->
|
|
|
(match !mstack with
|
|
|
| [] -> tk
|
|
|
| _ :: l ->
|
|
|
+ dbc#open_dead_block (pos tk);
|
|
|
mstack := l;
|
|
|
- process_token (skip_tokens (snd tk) false))
|
|
|
+ let tk = skip_tokens (pos tk) false in
|
|
|
+ process_token tk)
|
|
|
| Sharp "if" ->
|
|
|
process_token (enter_macro (snd tk))
|
|
|
| Sharp "error" ->
|
|
@@ -185,22 +216,36 @@ let parse ctx code file =
|
|
|
if is_true (eval ctx e) then begin
|
|
|
mstack := p :: !mstack;
|
|
|
tk
|
|
|
- end else
|
|
|
+ end else begin
|
|
|
+ dbc#open_dead_block (pos e);
|
|
|
skip_tokens_loop p true tk
|
|
|
+ end
|
|
|
|
|
|
and skip_tokens_loop p test tk =
|
|
|
match fst tk with
|
|
|
| Sharp "end" ->
|
|
|
+ dbc#close_dead_block (pos tk);
|
|
|
Lexer.token code
|
|
|
- | Sharp "elseif" | Sharp "else" when not test ->
|
|
|
+ | Sharp "elseif" when not test ->
|
|
|
+ dbc#close_dead_block (pos tk);
|
|
|
+ let _,(_,pe) = parse_macro_cond sraw in
|
|
|
+ dbc#open_dead_block pe;
|
|
|
+ skip_tokens p test
|
|
|
+ | Sharp "else" when not test ->
|
|
|
+ dbc#close_dead_block (pos tk);
|
|
|
+ dbc#open_dead_block (pos tk);
|
|
|
skip_tokens p test
|
|
|
| Sharp "else" ->
|
|
|
+ dbc#close_dead_block (pos tk);
|
|
|
mstack := snd tk :: !mstack;
|
|
|
Lexer.token code
|
|
|
| Sharp "elseif" ->
|
|
|
+ dbc#close_dead_block (pos tk);
|
|
|
enter_macro (snd tk)
|
|
|
| Sharp "if" ->
|
|
|
- skip_tokens_loop p test (skip_tokens p false)
|
|
|
+ dbc#open_dead_block (pos tk);
|
|
|
+ let tk = skip_tokens p false in
|
|
|
+ skip_tokens_loop p test tk
|
|
|
| Sharp ("error" | "line") ->
|
|
|
skip_tokens p test
|
|
|
| Sharp s ->
|
|
@@ -225,7 +270,7 @@ let parse ctx code file =
|
|
|
restore();
|
|
|
Lexer.restore old;
|
|
|
if was_display_file then
|
|
|
- ParseDisplayFile(l,List.rev !syntax_errors)
|
|
|
+ ParseDisplayFile(l,List.rev !syntax_errors,dbc#get_dead_blocks)
|
|
|
else begin match List.rev !syntax_errors with
|
|
|
| [] -> ParseSuccess l
|
|
|
| error :: errors -> ParseError(l,error,errors)
|
|
@@ -288,4 +333,4 @@ let parse_expr_string com s p error inl =
|
|
|
match parse_string com (head ^ s ^ ";}") p error inl with
|
|
|
| ParseSuccess data -> ParseSuccess(extract_expr data)
|
|
|
| ParseError(data,error,errors) -> ParseError(extract_expr data,error,errors)
|
|
|
- | ParseDisplayFile(data,errors) -> ParseDisplayFile(extract_expr data,errors)
|
|
|
+ | ParseDisplayFile(data,errors,dead) -> ParseDisplayFile(extract_expr data,errors,dead)
|