Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some preprocessor cleanup #11365

Merged
merged 2 commits into from
Nov 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 14 additions & 2 deletions src/syntax/parser.ml
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,17 @@ open Globals
open DisplayTypes.DisplayMode
open DisplayPosition

type preprocessor_error =
| InvalidEnd
| InvalidElse
| InvalidElseif
| UnclosedConditional

type error_msg =
| Unexpected of token
| Duplicate_default
| Missing_semicolon
| Unclosed_conditional
| Preprocessor_error of preprocessor_error
| Unimplemented
| Missing_type
| Expected of string list
Expand Down Expand Up @@ -70,7 +76,13 @@ let error_msg = function
| Unexpected t -> "Unexpected "^(s_token t)
| Duplicate_default -> "Duplicate default"
| Missing_semicolon -> "Missing ;"
| Unclosed_conditional -> "Unclosed conditional compilation block"
| Preprocessor_error ppe ->
begin match ppe with
| UnclosedConditional -> "Unclosed conditional compilation block"
| InvalidEnd -> "Invalid #end"
| InvalidElse -> "Invalid #else"
| InvalidElseif -> "Invalid #elseif"
end
| Unimplemented -> "Not implemented for current platform"
| Missing_type -> "Missing type declaration"
| Expected sl -> "Expected " ^ (String.concat " or " sl)
Expand Down
82 changes: 37 additions & 45 deletions src/syntax/parserEntry.ml
Original file line number Diff line number Diff line change
Expand Up @@ -143,40 +143,45 @@ class condition_handler = object(self)

method private cond_if' (e : expr) =
conditional_expressions <- e :: conditional_expressions;
conditional_stack <- e :: conditional_stack
conditional_stack <- (e,false) :: conditional_stack

method cond_if (e : expr) =
self#cond_if' e;
depths <- 1 :: depths

method cond_else = match conditional_stack with
| e :: el ->
conditional_stack <- (self#negate e) :: el
method cond_else (p : pos) =
match conditional_stack with
| (_,true) :: _ ->
error (Preprocessor_error InvalidElse) p
| (e,false) :: el ->
conditional_stack <- (self#negate e,true) :: el
| [] ->
die "" __LOC__
error (Preprocessor_error InvalidElse) p

method cond_elseif (e : expr) =
self#cond_else;
method cond_elseif (e : expr) (p : pos) =
self#cond_else p;
self#cond_if' e;
match depths with
| [] -> die "" __LOC__
| [] ->
error (Preprocessor_error InvalidElseif) p
| depth :: depths' ->
depths <- (depth + 1) :: depths'

method cond_end =
method cond_end (p : pos) =
let rec loop d el =
if d = 0 then el
else loop (d - 1) (List.tl el)
in
match depths with
| [] -> die "" __LOC__
| [] ->
error (Preprocessor_error InvalidEnd) p
| depth :: depths' ->
conditional_stack <- loop depth conditional_stack;
depths <- depths'

method get_current_condition = match conditional_stack with
| e :: el ->
List.fold_left self#conjoin e el
| (e,_) :: el ->
List.fold_left self#conjoin e (List.map fst el)
| [] ->
(EConst (Ident "true"),null_pos)

Expand Down Expand Up @@ -224,7 +229,6 @@ let parse entry ctx code file =
code_ref := old_code;
)
in
let mstack = ref [] in
last_doc := None;
in_macro := Define.defined ctx Define.Macro;
Lexer.skip_header code;
Expand All @@ -237,6 +241,9 @@ let parse entry ctx code file =
let conds = new condition_handler in
let dbc = new dead_block_collector conds in
let sraw = Stream.from (fun _ -> Some (Lexer.sharp_token code)) in
let preprocessor_error ppe pos tk =
syntax_error (Preprocessor_error ppe) ~pos:(Some pos) sraw tk
in
let rec next_token() = process_token (Lexer.token code)

and process_token tk =
Expand All @@ -257,31 +264,19 @@ let parse entry ctx code file =
end;
next_token()
| Sharp "end" ->
(match !mstack with
| [] -> tk
| _ :: l ->
conds#cond_end;
mstack := l;
next_token())
conds#cond_end (snd tk);
next_token()
| Sharp "elseif" ->
(match !mstack with
| [] -> tk
| _ :: l ->
let _,(e,pe) = parse_macro_cond sraw in
conds#cond_elseif (e,pe);
dbc#open_dead_block pe;
mstack := l;
let tk = skip_tokens (pos tk) false in
process_token tk)
let _,(e,pe) = parse_macro_cond sraw in
conds#cond_elseif (e,pe) (snd tk);
dbc#open_dead_block pe;
let tk = skip_tokens (pos tk) false in
process_token tk
| Sharp "else" ->
(match !mstack with
| [] -> tk
| _ :: l ->
conds#cond_else;
dbc#open_dead_block (pos tk);
mstack := l;
let tk = skip_tokens (pos tk) false in
process_token tk)
conds#cond_else (snd tk);
dbc#open_dead_block (pos tk);
let tk = skip_tokens (pos tk) false in
process_token tk
| Sharp "if" ->
process_token (enter_macro true (snd tk))
| Sharp "error" ->
Expand All @@ -302,10 +297,9 @@ let parse entry ctx code file =

and enter_macro is_if p =
let tk, e = parse_macro_cond sraw in
(if is_if then conds#cond_if else conds#cond_elseif) e;
(if is_if then conds#cond_if e else conds#cond_elseif e p);
let tk = (match tk with None -> Lexer.token code | Some tk -> tk) in
if is_true (eval ctx e) then begin
mstack := p :: !mstack;
tk
end else begin
dbc#open_dead_block (pos e);
Expand All @@ -315,24 +309,23 @@ let parse entry ctx code file =
and skip_tokens_loop p test tk =
match fst tk with
| Sharp "end" ->
conds#cond_end;
conds#cond_end (snd tk);
dbc#close_dead_block (pos tk);
Lexer.token code
| Sharp "elseif" when not test ->
dbc#close_dead_block (pos tk);
let _,(e,pe) = parse_macro_cond sraw in
conds#cond_elseif (e,pe);
conds#cond_elseif (e,pe) (snd tk);
dbc#open_dead_block pe;
skip_tokens p test
| Sharp "else" when not test ->
conds#cond_else;
conds#cond_else (snd tk);
dbc#close_dead_block (pos tk);
dbc#open_dead_block (pos tk);
skip_tokens p test
| Sharp "else" ->
conds#cond_else;
conds#cond_else (snd tk);
dbc#close_dead_block (pos tk);
mstack := snd tk :: !mstack;
Lexer.token code
| Sharp "elseif" ->
dbc#close_dead_block (pos tk);
Expand All @@ -348,7 +341,7 @@ let parse entry ctx code file =
| Sharp s ->
sharp_error s (pos tk)
| Eof ->
syntax_error Unclosed_conditional ~pos:(Some p) sraw tk
preprocessor_error UnclosedConditional p tk
| _ ->
skip_tokens p test

Expand All @@ -362,7 +355,6 @@ let parse entry ctx code file =
) in
try
let l = entry s in
(match !mstack with p :: _ -> syntax_error Unclosed_conditional ~pos:(Some p) sraw () | _ -> ());
let was_display_file = !in_display_file in
restore();
Lexer.restore old;
Expand Down
9 changes: 9 additions & 0 deletions tests/misc/projects/Issue11208/Main.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
function main() {
#if false
trace("?");
#else
trace("!");
#else
trace("...");
#end
}
1 change: 1 addition & 0 deletions tests/misc/projects/Issue11208/compile-fail.hxml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--main Main
1 change: 1 addition & 0 deletions tests/misc/projects/Issue11208/compile-fail.hxml.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Main.hx:6: characters 2-7 : Invalid #else