Ticket #210: 0012-Added-support-for-OCaml.-Added-support-for-Haskell-n.patch

File 0012-Added-support-for-OCaml.-Added-support-for-Haskell-n.patch, 13.1 kB (added by f_k, 1 year ago)

Adds support for OCaml and improved support for Haskell comments.

  • a/ext/ohcount_native/generator.rb

    old new  
    5252      metafont = LineCommentMonoglot.new("metafont", "%"); 
    5353      metapost = LineCommentMonoglot.new("metapost", "%"); 
    5454      objective_c = CMonoglot.new("objective_c", '//',             [e('/*'), e('*/')], true,  false) 
     55      ocaml = CMonoglot.new("ocaml",                  nil, nil, false,  false) 
    5556      pascal = CMonoglot.new("pascal",           '//',             ['{','}'],          true,  true, {:no_escape_dquote => true, :no_escape_squote => true}) 
    5657      perl = CMonoglot.new("perl",               '#',              ['^=\\\\w+', '^=cut[ \t]*\\\\n'],  true,  true) 
    5758      phplanguage = CMonoglot.new("php",         ['//', '#'],             [e('/*'), e('*/')], true,  true, {:polyglot_name => 'phplanguage'}) 
     
    122123        metafont, 
    123124        metapost, 
    124125        objective_c, 
     126        ocaml , 
    125127        pascal , 
    126128        perl , 
    127129        pike , 
  • a/ext/ohcount_native/ragel_parser.c

    old new  
    4141#include "metapost_with_tex_parser.h" 
    4242#include "mxml_parser.h" 
    4343#include "objective_c_parser.h" 
     44#include "ocaml_parser.h" 
    4445#include "pascal_parser.h" 
    4546#include "perl_parser.h" 
    4647#include "phphtml_parser.h" 
     
    115116  { "metapost_with_tex", parse_mptex }, 
    116117  { "mxml", parse_mxml }, 
    117118  { "objective_c", parse_objective_c }, 
     119  { "ocaml", parse_ocaml }, 
    118120  { "pascal", parse_pascal }, 
    119121  { "perl", parse_perl }, 
    120122  { "php", parse_phtml }, 
  • a/ext/ohcount_native/ragel_parsers/haskell.rl

    old new  
    4444    } 
    4545  } 
    4646 
     47  action haskell_comment_nc_res { nest_count = 0; } 
     48  action haskell_comment_nc_inc { nest_count++; } 
     49  action haskell_comment_nc_dec { nest_count--; } 
     50 
    4751  # TODO: |-- is not a comment 
    4852  haskell_line_comment = '--' [^>] @{ fhold; } @comment nonnewline*; 
    49   haskell_block_comment = 
    50     '{-' @comment ( 
     53  haskell_nested_block_comment = 
     54    '{-' >haskell_comment_nc_res @comment ( 
    5155      newline %{ entity = INTERNAL_NL; } %haskell_ccallback 
    5256      | 
    5357      ws 
     58      | 
     59      '{-' @haskell_comment_nc_inc @comment 
     60      | 
     61      '-}' @haskell_comment_nc_dec @comment 
    5462      | 
    5563      (nonnewline - ws) @comment 
    56     )* :>> '-}'
    57   haskell_comment = haskell_line_comment | haskell_block_comment; 
     64    )* :>> ('-}' when { nest_count == 0 }) @comment
     65  haskell_comment = haskell_line_comment | haskell_nested_block_comment; 
    5866 
    5967  haskell_char = '\'' @code ([^\r\n\f'\\] | '\\' nonnewline) '\''; 
    6068  haskell_dq_str = 
     
    104112  ) { 
    105113  init 
    106114 
     115  int nest_count = 0; 
     116 
    107117  %% write init; 
    108118  cs = (count) ? haskell_en_haskell_line : haskell_en_haskell_entity; 
    109119  %% write exec; 
  • /dev/null

    old new  
     1/************************* Required for every parser *************************/ 
     2#ifndef RAGEL_OCAML_PARSER 
     3#define RAGEL_OCAML_PARSER 
     4 
     5#include "ragel_parser_macros.h" 
     6 
     7// the name of the language 
     8const char *OCAML_LANG = "ocaml"; 
     9 
     10// the languages entities 
     11const char *ocaml_entities[] = { 
     12  "space", "comment", "string", "any" 
     13}; 
     14 
     15// constants associated with the entities 
     16enum { 
     17  OCAML_SPACE = 0, OCAML_COMMENT, OCAML_STRING, OCAML_ANY 
     18}; 
     19 
     20/*****************************************************************************/ 
     21 
     22%%{ 
     23  machine ocaml; 
     24  write data; 
     25  include common "common.rl"; 
     26 
     27  # Line counting machine 
     28 
     29  action ocaml_ccallback { 
     30    switch(entity) { 
     31    case OCAML_SPACE: 
     32      ls 
     33      break; 
     34    case OCAML_ANY: 
     35      code 
     36      break; 
     37    case INTERNAL_NL: 
     38      std_internal_newline(OCAML_LANG) 
     39      break; 
     40    case NEWLINE: 
     41      std_newline(OCAML_LANG) 
     42    } 
     43  } 
     44   
     45  action ocaml_comment_nc_res { nest_count = 0; } 
     46  action ocaml_comment_nc_inc { nest_count++; } 
     47  action ocaml_comment_nc_dec { nest_count--; } 
     48 
     49  ocaml_nested_block_comment =  
     50    '(*' >ocaml_comment_nc_res @comment ( 
     51      newline %{ entity = INTERNAL_NL; } %ocaml_ccallback 
     52      | 
     53      ws 
     54      | 
     55      '(*' @ocaml_comment_nc_inc @comment 
     56      | 
     57      '*)' @ocaml_comment_nc_dec @comment 
     58      | 
     59      (nonnewline - ws) @comment 
     60    )* :>> ('*)' when { nest_count == 0 }) @comment; 
     61 
     62  ocaml_comment = ocaml_nested_block_comment; 
     63  ocaml_string = '"' @code ([^\r\n\f"\\] | '\\' nonnewline)* '"'; 
     64 
     65 
     66  ocaml_line := |* 
     67    spaces          ${ entity = OCAML_SPACE; } => ocaml_ccallback; 
     68    ocaml_comment; 
     69    ocaml_string; 
     70    newline         ${ entity = NEWLINE;      } => ocaml_ccallback; 
     71    ^space          ${ entity = OCAML_ANY;   } => ocaml_ccallback; 
     72  *|; 
     73 
     74  # Entity machine 
     75 
     76  action ocaml_ecallback { 
     77    callback(OCAML_LANG, ocaml_entities[entity], cint(ts), cint(te)); 
     78  } 
     79 
     80  ocaml_entity := 'TODO:'; 
     81}%% 
     82 
     83/************************* Required for every parser *************************/ 
     84 
     85/* Parses a string buffer with Objective Caml code. 
     86 * 
     87 * @param *buffer The string to parse. 
     88 * @param length The length of the string to parse. 
     89 * @param count Integer flag specifying whether or not to count lines. If yes, 
     90 *   uses the Ragel machine optimized for counting. Otherwise uses the Ragel 
     91 *   machine optimized for returning entity positions. 
     92 * @param *callback Callback function. If count is set, callback is called for 
     93 *   every line of code, comment, or blank with 'lcode', 'lcomment', and 
     94 *   'lblank' respectively. Otherwise callback is called for each entity found. 
     95 */ 
     96void parse_ocaml(char *buffer, int length, int count, 
     97  void (*callback) (const char *lang, const char *entity, int start, int end) 
     98  ) { 
     99  init 
     100 
     101  int nest_count = 0; 
     102 
     103  %% write init; 
     104  cs = (count) ? ocaml_en_ocaml_line : ocaml_en_ocaml_entity; 
     105  %% write exec; 
     106 
     107  // if no newline at EOF; callback contents of last line 
     108  if (count) { process_last_line(OCAML_LANG) } 
     109} 
     110 
     111#endif 
     112 
     113/*****************************************************************************/ 
  • a/lib/ohcount/detector.rb

    old new  
    172172    '.m'    => :matlab_or_objective_c, 
    173173    '.mf'   => 'metafont', 
    174174    '.mk'   => 'make', 
     175    '.ml'   => "ocaml", 
     176    '.mli'  => "ocaml", 
    175177    '.mm'   => "objective_c", 
    176178    '.mp'   => 'metapost_with_tex', 
    177179    '.mxml' => 'mxml', 
  • a/lib/ohcount/sloc_info.rb

    old new  
    7373      'metapost'      => {:nice_name => 'MetaPost'         , :category => 1}, 
    7474      'mxml'          => {:nice_name => 'Flex'             , :category => 1}, 
    7575      'objective_c'   => {:nice_name => 'Objective C'      , :category => 0}, 
     76      'ocaml'         => {:nice_name => 'Objective Caml'   , :category => 0}, 
    7677      'pascal'        => {:nice_name => 'Pascal'           , :category => 0}, 
    7778      'perl'          => {:nice_name => 'Perl'             , :category => 0}, 
    7879      'php'           => {:nice_name => 'PHP'              , :category => 0}, 
  • /dev/null

    old new  
     1(** documentation *) 
     2print_string "Hello world!\n";; 
     3(**/**) 
     4(* extra comment *) 
     5 
     6(* multiline 
     7   comment*) 
     8 
     9(* recursion in (* a 
     10   comment *) to complicate things *) 
  • /dev/null

    old new  
  • /dev/null

    old new  
     1{- 
     2{- 3 lines of comments total! -} 
     3-} 
  • /dev/null

    old new  
  • /dev/null

    old new  
  • /dev/null

    old new  
     1(** documentation *) 
     2(**/**) 
     3(* extra comment *) 
     4(* multiline 
     5comment*) 
     6(* recursion in (* a 
     7comment *) to complicate things *) 
  • /dev/null

    old new  
     1    {- 
     2      {- 3 lines of comments total! -} 
     3 
     4    -} 
     5 
  • /dev/null

    old new  
     1(** documentation *) 
     2print_string "Hello world!\n";; 
     3(**/**) 
     4(* extra comment *) 
     5 
     6(* multiline 
     7   comment*) 
     8 
     9(* recursion in (* a 
     10   comment *) to complicate things *) 
  • a/test/unit/detector_test.rb

    old new  
    6767    assert_equal "ebuild", do_detect("foo.ebuild") 
    6868    assert_equal "ebuild", do_detect("foo.eclass") 
    6969    assert_equal "eiffel", do_detect("eiffel.e") 
     70    assert_equal "ocaml", do_detect("ocaml.ml") 
    7071  end 
    7172 
    7273  def test_upper_case_extensions 
  • a/test/unit/haskell_test.rb

    old new  
    1616        def test_comprehensive_with_carriage_returns 
    1717                verify_parse("haskell2.hs") 
    1818        end 
     19         
     20        def test_comprehensive_with_nested_comments 
     21                verify_parse("haskell3.hs") 
     22        end 
    1923end 
    2024 
    2125                 
  • /dev/null

    old new  
     1require File.dirname(__FILE__) + '/../test_helper' 
     2 
     3class Ohcount::OcamlTest < Ohcount::Test 
     4  def test_regular_comments 
     5    lb = [Ohcount::LanguageBreakdown.new("ocaml", "", "(* comment *)", 0)] 
     6    assert_equal lb, Ohcount::parse(" (* comment *)", "ocaml") 
     7  end 
     8 
     9  def test_comprehensive 
     10    verify_parse("ocaml.ml") 
     11  end 
     12end