Commits

ccorrodi committed 31ec016

new module Util, update command parsing

- The util.ml module contains general functions, such as string manipulation
functions (currently, there is only a regex replace function).
- In rules, leading tabs are removed from the command (only one), and readded
when printed in the make database format. The command section on the other
hand is parsed and stored as is (with all the leading tabs).

Comments (0)

Files changed (7)

 Parser
 Lexer
 Main
+Util
 module L = List
 module S = Str
 module P = Pervasives
+module U = Util
 
 (** {2 Types} *)
 (** The command type represents a command that make runs. *)
   indent_num 1 s
 
 (** {2 String / Type Conversion} *)
-(** Convert a string to a command. *)
+(** Convert a string to a command. Remove one leading tab character. *)
 let s_to_command (s : string) : command =
+(*   S.global_replace (S.regexp "^\t*") "" s *)
+  U.re_replace "^\t" "" s
+
+(** Convert a string to a command without removing tabs. *)
+let s_to_raw_command (s : string) : command =
   s
 
 (** Convert a command to a string. *)
     else
       ""
   in
-  let commands = String.concat "\n" r.r_commands in
+  (* TODO: add tabs in here *)
+  (* TODO: also only remove one tab (or so) in the parser *)
+  let tabcommands = L.map ((^) "\t") r.r_commands in
+  let commands = String.concat "\n" tabcommands in
+(*   let commands = String.concat "\n" (L.map ((^) "\t" r.r_commands)) in *)
   Printf.sprintf "%s%s%s\n%s" targets colon deps commands
 
 (** Convert a dependency to a string. *)
 
   String.concat "\n" (L.map debug_var d.d_variables)
 
+(** Return a string containing the rule section of the given databse, including
+    all information from the rule type. *)
 let pp_ast_rules (d : database) : string =
   let debug_rule (r : rule) : string =
     let next =
 (** Convert a given command string to command type. *)
 val s_to_command : string -> command
 
+(** Convert a string to a command without removing tabs. *)
+val s_to_raw_command : string -> command
+
 (** Convert a given variable origin string (see s_origin_* strings) to
     variable_origin type. *)
 val s_to_var_origin : string -> variable_origin
 
   ()
 
-
 (** Process the makefile database given as argument. *)
 let _ =
   if Array.length (Sys.argv) == 1 then
   | [] ->
       ""
 
+(** Generate the list of commands that should be executed when building target
+    `target'. *)
+let ast_to_command_list_string
+    (a : A.ast)
+    (t : string) (* target *)
+    : string =
+  "TODO"
+
 (** {2 Debug} *)
 let debug_ast (a : A.ast) : unit =
   Printf.printf "%s" (A.pp_ast a)
   module A = Ast
   module S = Str
   module L = List
-
-  let previous_rule : A.rule option ref = ref None
 %}
 
 %token VARSEP DIRSEP RULESEP FILESEP FINISHED
 in_command:
   | COMMAND in_command {
     (* TODO: multiline commands should be merged in one command *)
-    let command = A.s_to_command $1 in
+    let command = A.s_to_raw_command $1 in
     command :: $2
   }
   | VARSEP {
 
 in_rules:
   | rule in_rules {
-    begin
-      match !previous_rule with
-      | None -> ()
-      | Some previous_rule ->
-          (*
-            TODO: this may or may not work as intended. Maybe we need to link
-            the rules in ocamlmake.ml's post process method.
-          previous_rule.A.r_next := Some rule;
-          *)
-          ()
-    end;
     $1 :: $2
   }
   | COMMENT in_rules {
       (* TODO *)
       ~deps:prereqs
       ~commands:$3
-      ~num:0
+      ~num:(L.length targets)
       ~terminal:false
       ~in_use:false
   }
+(** General utility functions
+
+    @file main.ml
+    @author Claudio Corrodi
+    *)
+
+module S = Str
+
+(** {2 String Manipulation} *)
+(** replace all substrings in target that match regex with repl *)
+let re_replace (regex: string) (repl: string) (target: string) : string =
+  S.global_replace (S.regexp regex) repl target