@@ -349,7 +349,8 @@ let rec eval_bool env (x : bool_expr) =
349
349
type globals = {
350
350
call_loc : Cppo_types .loc ;
351
351
(* 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 *)
353
354
354
355
mutable buf : Buffer .t ;
355
356
(* buffer where the output is written *)
@@ -381,7 +382,13 @@ type globals = {
381
382
(* mapping from extension ID to pipeline command *)
382
383
}
383
384
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
385
392
386
393
let parse ~preserve_quotations file lexbuf =
387
394
let lexer_env = Cppo_lexer. init ~preserve_quotations file lexbuf in
@@ -552,65 +559,63 @@ let rec include_file g loc rel_file env =
552
559
and expand_list ?(top = false ) g env l =
553
560
List. fold_left (expand_node ~top g) env l
554
561
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 ) =
558
565
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
565
576
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 =
567
580
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
570
586
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 () ->
579
588
580
- let env =
581
- match def with
589
+ g.require_location := true ;
582
590
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
+ );
601
598
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
603
608
604
- if def = None then
605
- g.require_location := false
606
- else
607
- g.require_location := true ;
609
+ g.require_location := true ;
608
610
609
- (* restore initial setting *)
610
- g.enable_loc := enable_loc0;
611
+ (* Continue with our original environment. *)
612
+ env0
611
613
612
- env
614
+ and expand_node ?(top = false ) g env0 (x : node ) =
615
+ match x with
613
616
617
+ | `Ident (loc , name , actuals ) ->
618
+ expand_ident ~top g env0 loc name actuals
614
619
615
620
| `Def (loc , name , formals , body )->
616
621
g.require_location := true ;
@@ -668,19 +673,18 @@ and expand_node ?(top = false) g env0 (x : node) =
668
673
expand_list g env0 l
669
674
670
675
| `Stringify x ->
671
- let enable_loc0 = ! (g.enable_loc) in
676
+ preserving_enable_loc g @@ fun () ->
672
677
g.enable_loc := false ;
673
678
let buf0 = g.buf in
674
679
let local_buf = Buffer. create 100 in
675
680
g.buf < - local_buf;
676
681
ignore (expand_node g env0 x);
677
682
stringify buf0 (Buffer. contents local_buf);
678
683
g.buf < - buf0;
679
- g.enable_loc := enable_loc0;
680
684
env0
681
685
682
686
| `Capitalize (x : node ) ->
683
- let enable_loc0 = ! (g.enable_loc) in
687
+ preserving_enable_loc g @@ fun () ->
684
688
g.enable_loc := false ;
685
689
let buf0 = g.buf in
686
690
let local_buf = Buffer. create 100 in
@@ -691,10 +695,10 @@ and expand_node ?(top = false) g env0 (x : node) =
691
695
(* stringify buf0 (Buffer.contents local_buf); *)
692
696
Buffer. add_string buf0 s ;
693
697
g.buf < - buf0;
694
- g.enable_loc := enable_loc0;
695
698
env0
699
+
696
700
| `Concat (x , y ) ->
697
- let enable_loc0 = ! (g.enable_loc) in
701
+ preserving_enable_loc g @@ fun () ->
698
702
g.enable_loc := false ;
699
703
let buf0 = g.buf in
700
704
let local_buf = Buffer. create 100 in
@@ -707,7 +711,6 @@ and expand_node ?(top = false) g env0 (x : node) =
707
711
let s = concat g.call_loc xs ys in
708
712
Buffer. add_string buf0 s;
709
713
g.buf < - buf0;
710
- g.enable_loc := enable_loc0;
711
714
env0
712
715
713
716
| `Line (loc , opt_file , n ) ->
0 commit comments