summaryrefslogtreecommitdiffstats
path: root/perl_checker.src/parser_helper.ml
diff options
context:
space:
mode:
Diffstat (limited to 'perl_checker.src/parser_helper.ml')
-rw-r--r--perl_checker.src/parser_helper.ml119
1 files changed, 75 insertions, 44 deletions
diff --git a/perl_checker.src/parser_helper.ml b/perl_checker.src/parser_helper.ml
index c97c51d..ed89c8d 100644
--- a/perl_checker.src/parser_helper.ml
+++ b/perl_checker.src/parser_helper.ml
@@ -5,7 +5,8 @@ open Printf
let bpos = -1, -1
let raw_pos2pos(a, b) = !Info.current_file, a, b
-let pos_range (_, (space, (a1, b1))) (_, (_, (a2, b2))) = space, ((if a1 = -1 then a2 else a1), (if b2 = -1 then b1 else b2))
+let pos_range (_, (_, (a1, b1))) (_, (_, (a2, b2))) = raw_pos2pos((if a1 = -1 then a2 else a1), (if b2 = -1 then b1 else b2))
+let sp_pos_range (_, (space, (a1, b1))) (_, (_, (a2, b2))) = space, ((if a1 = -1 then a2 else a1), (if b2 = -1 then b1 else b2))
let get_pos (_, (_, pos)) = raw_pos2pos pos
let var_dollar_ = Deref(I_scalar, Ident(None, "_", raw_pos2pos bpos))
let var_STDOUT = Deref(I_star, Ident(None, "STDOUT", raw_pos2pos bpos))
@@ -39,19 +40,29 @@ let string_of_Ident = function
| Ident(Some fq, s, _) -> fq ^ "::" ^ s
| _ -> internal_error "string_of_Ident"
+let from_scalar (e, _) =
+ match e with
+ | Deref(I_scalar, ident) -> ident
+ | _ -> internal_error "from_scalar"
+
+let from_array (e, _) =
+ match e with
+ | Deref(I_array, ident) -> ident
+ | _ -> internal_error "from_array"
-let msg_with_pos (start, end_) msg = Info.pos2sfull_current start end_ ^ msg
-let die_with_pos raw_pos msg = failwith (msg_with_pos raw_pos msg)
-let warn raw_pos msg = prerr_endline (msg_with_pos raw_pos msg)
+let msg_with_rawpos (start, end_) msg = Info.pos2sfull_current start end_ ^ msg
+let die_with_rawpos raw_pos msg = failwith (msg_with_rawpos raw_pos msg)
+let warn raw_pos msg = prerr_endline (msg_with_rawpos raw_pos msg)
-let die_rule msg = die_with_pos (Parsing.symbol_start(), Parsing.symbol_end()) msg
+let die_rule msg = die_with_rawpos (Parsing.symbol_start(), Parsing.symbol_end()) msg
let warn_rule msg = warn (Parsing.symbol_start(), Parsing.symbol_end()) msg
let debug msg = if true then prerr_endline msg
-let warn_too_many_space start = warn (start, start) "you should have only one space here"
-let warn_no_space start = warn (start, start) "you should have a space here"
-let warn_cr start = warn (start, start) "you should not have a carriage-return (\\n) here"
-let warn_space start = warn (start, start) "you should not have a space here"
+let warn_verb pos msg = if not !Flags.quiet then warn (pos, pos) msg
+let warn_too_many_space start = warn_verb start "you should have only one space here"
+let warn_no_space start = warn_verb start "you should have a space here"
+let warn_cr start = warn_verb start "you should not have a carriage-return (\\n) here"
+let warn_space start = warn_verb start "you should not have a space here"
let rec prio_less = function
| P_paren_wanted prio1, prio2
@@ -161,7 +172,7 @@ let sp_cr(_, (spaces, (start, _))) =
| Space_none -> ()
| Space_0
| Space_1
- | Space_n -> warn (start, start) "you should have a carriage-return (\\n) here"
+ | Space_n -> warn_verb start "you should have a carriage-return (\\n) here"
| Space_cr -> ()
let sp_same (_, (spaces1, _) as ter1) (_, (spaces2, _) as ter2) =
@@ -169,8 +180,11 @@ let sp_same (_, (spaces1, _) as ter1) (_, (spaces2, _) as ter2) =
else if spaces2 <> Space_0 then sp_p ter1
let check_word_alone (word, _) =
- let s = string_of_Ident word in
- if s = "time" || s = "wantarray" then die_rule (sprintf "please use %s() instead of %s" s s);
+ (match word with
+ | Ident(None, ("time" as f), _)
+ | Ident(None, ("wantarray" as f), _) ->
+ die_rule (sprintf "please use %s() instead of %s" f f)
+ | _ -> ());
word
let check_parenthesized_first_argexpr word ((_, e), (_, (start, _)) as ex) =
@@ -181,26 +195,22 @@ let check_parenthesized_first_argexpr word ((_, e), (_, (start, _)) as ex) =
| e' :: l ->
if is_parenthesized e' then
if want_space then
- if l = [] then sp_n(ex) else die_with_pos (start, start) "can't handle this nicely"
+ if l = [] then sp_n(ex) else die_with_rawpos (start, start) "can't handle this nicely"
else
- if l = [] then sp_0(ex) else die_with_pos (start, start) "you must not have a space here"
+ if l = [] then sp_0(ex) else die_with_rawpos (start, start) "you must not have a space here"
| _ ->
if word = "time" then die_rule "please use time() instead of time";
sp_p(ex)
let check_foreach (s, (_, pos)) = if s = "for" then warn pos "write \"foreach\" instead of \"for\""
let check_for (s, (_, pos)) = if s = "foreach" then warn pos "write \"for\" instead of \"foreach\""
+let check_MULT_is_x (s, _) = if s <> "x" then die_rule "syntax error"
+let check_my (s, _) = if s <> "my" then die_rule "syntax error"
-let check_package t =
- if str_ends_with !Info.current_file ".pm" then
- match t with
- | Package _ :: _ -> ()
- | _ -> warn (0, 0) (sprintf "module %s does not have \"package xxxx;\" on its first line" !Info.current_file)
-
-let check_my op para (_, pos) =
+let check_my_our op para (_, pos) =
match op, para with
- | "=", [List [My _]; Ident(None, "undef", _)] -> warn pos "no need to initialize variable, it's done by default"
- | "=", [List [My _]; List[]] ->
+ | "=", [List [My_our _]; Ident(None, "undef", _)] -> warn pos "no need to initialize variable, it's done by default"
+ | "=", [List [My_our _]; List[]] ->
if Info.is_on_same_line_current pos then warn pos "no need to initialize variables, it's done by default"
| _ -> ()
@@ -212,7 +222,7 @@ let check_block_sub (l, (_, (_, end_)) as ter_lines) (_, (space, _) as ter_BRACK
sp_p ter_BRACKET_END ;
if space <> Space_cr then
- (if l <> [] && last l = Semi_colon then warn (end_, end_) "spurious \";\" before closing block")
+ (if l <> [] && last l = Semi_colon then warn_verb end_ "spurious \";\" before closing block")
)
let check_block_ref (l, (_, (_, end_)) as ter_lines) (_, (space, _) as ter_BRACKET_END) =
@@ -221,42 +231,63 @@ let check_block_ref (l, (_, (_, end_)) as ter_lines) (_, (space, _) as ter_BRACK
else sp_same ter_lines ter_BRACKET_END ;
if space <> Space_cr then
- (if l <> [] && last l = Semi_colon then warn (end_, end_) "spurious \";\" before closing block")
-
+ (if l <> [] && last l = Semi_colon then warn_verb end_ "spurious \";\" before closing block")
-let to_Ident ((fq, name), (_, pos)) = Ident(fq, name, raw_pos2pos pos)
-let to_Raw_string (s, (_, pos)) = Raw_string(s, raw_pos2pos pos)
-
-let op prio s (_, both) = prio, (((), both), s)
-let op_p prio s e = sp_p e ; op prio s e
-
-let call_op((prio, (prev_ter, op)), ter, para) =
- sp_same prev_ter ter ;
- check_my op para (snd ter);
- prio, Call_op(op, para)
+let check_my_our_paren (((comma_closed, _), _), _) =
+ if not comma_closed then die_rule "syntax error"
let rec only_one (l, (spaces, pos)) =
match l with
| [List l'] -> only_one (l', (spaces, pos))
| [e] -> e
- | [] -> die_with_pos pos "you must give one argument"
- | _ -> die_with_pos pos "you must give only one argument"
+ | [] -> die_with_rawpos pos "you must give one argument"
+ | _ -> die_with_rawpos pos "you must give only one argument"
let only_one_in_List ((_, e), both) =
match e with
| List l -> only_one(l, both)
| _ -> e
-
-let array_ident_to_hash_ident (e, (_, pos)) =
- match e with
- | Deref(I_array, e) -> Deref(I_hash, e)
- | _ -> die_with_pos pos "internal error (array_ident_to_hash_ident)"
let to_List = function
| [e] -> e
| l -> List l
-let sub_declaration (name, proto) body = Sub_declaration(name, proto, body)
+let deref_arraylen e = Call(Ident(None, "int", raw_pos2pos bpos), [Deref(I_array, e)])
+let to_Ident ((fq, name), (_, pos)) = Ident(fq, name, raw_pos2pos pos)
+let to_Raw_string (s, (_, pos)) = Raw_string(s, raw_pos2pos pos)
+let to_Local ((_, e), (_, pos)) =
+ let l =
+ match e with
+ | List[List l] -> l
+ | _ -> [e]
+ in
+ let local_vars, local_exprs = fpartition (function
+ | Deref(I_star, Ident(None, ident, _)) ->
+ Some(I_star, ident)
+ | Deref(I_scalar, Ident _)
+ | Deref(I_array, Ident _)
+ | Deref(I_star, Ident _)
+ | Deref_with(I_hash, Ident _, _)
+ | Deref_with(I_hash, Deref(I_scalar, _), _)
+ | Deref_with(I_hash, Deref_with(I_hash, Ident _, _), _)
+ | Deref_with(I_hash, Deref_with(I_hash, Deref(I_scalar, Ident _), _), _) ->
+ None
+ | _ -> die_with_rawpos pos "bad argument to \"local\""
+ ) l in
+ if local_vars = [] then Call_op("local", local_exprs)
+ else if local_exprs = [] then My_our("local", local_vars, raw_pos2pos pos)
+ else die_with_rawpos pos "bad argument to \"local\""
+
+let op prio s (_, both) = prio, (((), both), s)
+let op_p prio s e = sp_p e ; op prio s e
+
+let call_op((prio, (prev_ter, op)), ter, para) =
+ sp_same prev_ter ter ;
+ check_my_our op para (snd ter);
+ prio, Call_op(op, para)
+
+let sub_declaration (name, proto) body = Sub_declaration(name, proto, Block body)
+let anonymous_sub body = Anonymous_sub (Block body)
let call(e, para) =
(match e with