Skip to content

Commit 40600e3

Browse files
authored
Refactoring (#94)
1 parent cbd7dad commit 40600e3

File tree

3 files changed

+61
-58
lines changed

3 files changed

+61
-58
lines changed

src/cppo_eval.ml

+59-56
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,8 @@ let rec eval_bool env (x : bool_expr) =
349349
type globals = {
350350
call_loc : Cppo_types.loc;
351351
(* location used to set the value of
352-
__FILE__ and __LINE__ global variables *)
352+
__FILE__ and __LINE__ global variables;
353+
also used in the expansion of CONCAT *)
353354

354355
mutable buf : Buffer.t;
355356
(* buffer where the output is written *)
@@ -381,7 +382,13 @@ type globals = {
381382
(* mapping from extension ID to pipeline command *)
382383
}
383384

384-
385+
(* [preserving_enable_loc g action] saves [g.enable_loc], runs [action()],
386+
then restores [g.enable_loc]. The result of [action()] is returned. *)
387+
let preserving_enable_loc g action =
388+
let enable_loc0 = !(g.enable_loc) in
389+
let result = action() in
390+
g.enable_loc := enable_loc0;
391+
result
385392

386393
let parse ~preserve_quotations file lexbuf =
387394
let lexer_env = Cppo_lexer.init ~preserve_quotations file lexbuf in
@@ -552,65 +559,63 @@ let rec include_file g loc rel_file env =
552559
and expand_list ?(top = false) g env l =
553560
List.fold_left (expand_node ~top g) env l
554561

555-
and expand_node ?(top = false) g env0 (x : node) =
556-
match x with
557-
`Ident (loc, name, actuals) ->
562+
(* [expand_ident] is the special case of [expand_node] where the node is
563+
an identifier [`Ident (loc, name, actuals)]. *)
564+
and expand_ident ~top g env0 loc name (actuals : actuals) =
558565

559-
let def = find_opt name env0 in
560-
let g =
561-
if top && def <> None || g.call_loc == dummy_loc then
562-
{ g with call_loc = loc }
563-
else g
564-
in
566+
(* Test whether there exists a definition for the macro [name]. *)
567+
let def = find_opt name env0 in
568+
match def with
569+
| None ->
570+
(* There is no definition for the macro [name], so this is not
571+
a macro application after all. Transform it back into text,
572+
and process it. *)
573+
expand_list g env0 (text loc name actuals)
574+
| Some def ->
575+
expand_macro_application ~top g env0 loc name actuals def
565576

566-
let enable_loc0 = !(g.enable_loc) in
577+
(* [expand_macro_application] is the special case of [expand_ident] where
578+
it turns out that the identifier [name] is a macro. *)
579+
and expand_macro_application ~top g env0 loc name actuals def =
567580

568-
if def <> None then (
569-
g.require_location := true;
581+
let g =
582+
if top || g.call_loc == dummy_loc then
583+
{ g with call_loc = loc }
584+
else g
585+
in
570586

571-
if not g.show_exact_locations then (
572-
(* error reports will point more or less to the point
573-
where the code is included rather than the source location
574-
of the macro definition *)
575-
maybe_print_location g (fst loc);
576-
g.enable_loc := false
577-
)
578-
);
587+
preserving_enable_loc g @@ fun () ->
579588

580-
let env =
581-
match def with
589+
g.require_location := true;
582590

583-
| None ->
584-
(* There is no definition for the macro [name], so this is not
585-
a macro application after all. Transform it back into text,
586-
and process it. *)
587-
expand_list g env0 (text loc name actuals)
588-
589-
| Some (EDef (_loc, formals, body, env)) ->
590-
(* There is a definition for the macro [name], so this is a
591-
macro application. *)
592-
check_arity loc name formals actuals;
593-
(* Extend the macro's captured environment [env] with bindings of
594-
formals to actuals. Each actual captures the environment [env0]
595-
that exists here, at the macro application site. *)
596-
let env = bind_many formals (loc, actuals, env0) env in
597-
(* Process the macro's body in this extended environment. *)
598-
let (_ : env) = expand_node g env body in
599-
(* Continue with our original environment. *)
600-
env0
591+
if not g.show_exact_locations then (
592+
(* error reports will point more or less to the point
593+
where the code is included rather than the source location
594+
of the macro definition *)
595+
maybe_print_location g (fst loc);
596+
g.enable_loc := false
597+
);
601598

602-
in
599+
let EDef (_loc, formals, body, env) = def in
600+
(* Check that this macro is applied to a correct number of arguments. *)
601+
check_arity loc name formals actuals;
602+
(* Extend the macro's captured environment [env] with bindings of
603+
formals to actuals. Each actual captures the environment [env0]
604+
that exists here, at the macro application site. *)
605+
let env = bind_many formals (loc, actuals, env0) env in
606+
(* Process the macro's body in this extended environment. *)
607+
let (_ : env) = expand_node g env body in
603608

604-
if def = None then
605-
g.require_location := false
606-
else
607-
g.require_location := true;
609+
g.require_location := true;
608610

609-
(* restore initial setting *)
610-
g.enable_loc := enable_loc0;
611+
(* Continue with our original environment. *)
612+
env0
611613

612-
env
614+
and expand_node ?(top = false) g env0 (x : node) =
615+
match x with
613616

617+
| `Ident (loc, name, actuals) ->
618+
expand_ident ~top g env0 loc name actuals
614619

615620
| `Def (loc, name, formals, body)->
616621
g.require_location := true;
@@ -668,19 +673,18 @@ and expand_node ?(top = false) g env0 (x : node) =
668673
expand_list g env0 l
669674

670675
| `Stringify x ->
671-
let enable_loc0 = !(g.enable_loc) in
676+
preserving_enable_loc g @@ fun () ->
672677
g.enable_loc := false;
673678
let buf0 = g.buf in
674679
let local_buf = Buffer.create 100 in
675680
g.buf <- local_buf;
676681
ignore (expand_node g env0 x);
677682
stringify buf0 (Buffer.contents local_buf);
678683
g.buf <- buf0;
679-
g.enable_loc := enable_loc0;
680684
env0
681685

682686
| `Capitalize (x : node) ->
683-
let enable_loc0 = !(g.enable_loc) in
687+
preserving_enable_loc g @@ fun () ->
684688
g.enable_loc := false;
685689
let buf0 = g.buf in
686690
let local_buf = Buffer.create 100 in
@@ -691,10 +695,10 @@ and expand_node ?(top = false) g env0 (x : node) =
691695
(* stringify buf0 (Buffer.contents local_buf); *)
692696
Buffer.add_string buf0 s ;
693697
g.buf <- buf0;
694-
g.enable_loc := enable_loc0;
695698
env0
699+
696700
| `Concat (x, y) ->
697-
let enable_loc0 = !(g.enable_loc) in
701+
preserving_enable_loc g @@ fun () ->
698702
g.enable_loc := false;
699703
let buf0 = g.buf in
700704
let local_buf = Buffer.create 100 in
@@ -707,7 +711,6 @@ and expand_node ?(top = false) g env0 (x : node) =
707711
let s = concat g.call_loc xs ys in
708712
Buffer.add_string buf0 s;
709713
g.buf <- buf0;
710-
g.enable_loc := enable_loc0;
711714
env0
712715

713716
| `Line (loc, opt_file, n) ->

src/cppo_lexer.mll

+1-1
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ and directive e = parse
223223
{ let xs = [] in
224224
DEF (long_loc e, id, xs) }
225225

226-
(* #def is identical to #define, except it does not set [e.directive],
226+
(* #def is identical to #define, except it does not set [e.in_directive],
227227
so backslashes and newlines do not receive special treatment. The
228228
end of the macro definition must be explicitly signaled by #enddef. *)
229229
| blank* "def" dblank1 (ident as id) "("

src/cppo_types.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ let warning loc s =
146146

147147
let dummy_loc = (Lexing.dummy_pos, Lexing.dummy_pos)
148148

149-
let node_loc node =
149+
let node_loc (node : node) : loc =
150150
match node with
151151
| `Ident (loc, _, _)
152152
| `Def (loc, _, _, _)

0 commit comments

Comments
 (0)