nodes: 0, module; 1, function_definition; 2, function_name:stanc; 3, parameters; 4, block; 5, default_parameter; 6, default_parameter; 7, default_parameter; 8, default_parameter; 9, default_parameter; 10, default_parameter; 11, default_parameter; 12, expression_statement; 13, if_statement; 14, if_statement; 15, if_statement; 16, comment:# bytes, going into C++ code; 17, expression_statement; 18, if_statement; 19, comment:# add trailing /; 20, expression_statement; 21, expression_statement; 22, comment:# set to False; 23, expression_statement; 24, if_statement; 25, expression_statement; 26, if_statement; 27, expression_statement; 28, if_statement; 29, delete_statement; 30, expression_statement; 31, expression_statement; 32, expression_statement; 33, return_statement; 34, identifier:file; 35, None; 36, identifier:charset; 37, string; 38, identifier:model_code; 39, None; 40, identifier:model_name; 41, string:"anon_model"; 42, identifier:include_paths; 43, None; 44, identifier:verbose; 45, False; 46, identifier:obfuscate_model_name; 47, True; 48, comment:"""Translate Stan model specification into C++ code.
  
      Parameters
      ----------
      file : {string, file}, optional
          If filename, the string passed as an argument is expected to
          be a filename containing the Stan model specification.
  
          If file, the object passed must have a 'read' method (file-like
          object) that is called to fetch the Stan model specification.
  
      charset : string, 'utf-8' by default
          If bytes or files are provided, this charset is used to decode.
  
      model_code : string, optional
          A string containing the Stan model specification. Alternatively,
          the model may be provided with the parameter `file`.
  
      model_name: string, 'anon_model' by default
          A string naming the model. If none is provided 'anon_model' is
          the default. However, if `file` is a filename, then the filename
          will be used to provide a name.
  
      include_paths: list of strings, optional
          Paths for #include files defined in Stan code.
  
      verbose : boolean, False by default
          Indicates whether intermediate output should be piped to the
          console. This output may be useful for debugging.
  
      obfuscate_model_name : boolean, True by default
          If False the model name in the generated C++ code will not be made
          unique by the insertion of randomly generated characters.
          Generally it is recommended that this parameter be left as True.
  
      Returns
      -------
      stanc_ret : dict
          A dictionary with the following keys: model_name, model_code,
          cpp_code, and status. Status indicates the success of the translation
          from Stan code into C++ code (success = 0, error = -1).
  
      Notes
      -----
      C++ reserved words and Stan reserved words may not be used for
      variable names; see the Stan User's Guide for a complete list.
      
      The `#include` method follows a C/C++ syntax `#include foo/my_gp_funs.stan`.
      The method needs to be at the start of the row, no whitespace is allowed.
      After the included file no whitespace or comments are allowed.
      `pystan.experimental`(PyStan 2.18) has a `fix_include`-function to clean the `#include`
      statements from the `model_code`. 
      Example: 
      `from pystan.experimental import fix_include`
      `model_code = fix_include(model_code)`
  
      See also
      --------
      StanModel : Class representing a compiled Stan model
      stan : Fit a model using Stan
  
      References
      ----------
      The Stan Development Team (2013) *Stan Modeling Language User's
      Guide and Reference Manual*.  <http://mc-stan.org/>.
  
      Examples
      --------
      >>> stanmodelcode = '''
      ... data {
      ...   int<lower=0> N;
      ...   real y[N];
      ... }
      ...
      ... parameters {
      ...   real mu;
      ... }
      ...
      ... model {
      ...   mu ~ normal(0, 10);
      ...   y ~ normal(mu, 1);
      ... }
      ... '''
      >>> r = stanc(model_code=stanmodelcode, model_name = "normal1")
      >>> sorted(r.keys())
      ['cppcode', 'model_code', 'model_cppname', 'model_name', 'status']
      >>> r['model_name']
      'normal1'
  
      """; 49, boolean_operator; 50, block; 51, boolean_operator; 52, block; 53, comparison_operator:file is not None; 54, block; 55, assignment; 56, comparison_operator:include_paths is None; 57, block; 58, elif_clause; 59, assignment; 60, assignment; 61, assignment; 62, identifier:obfuscate_model_name; 63, comment:# Make the model name depend on the code.; 64, block; 65, assignment; 66, not_operator; 67, comment:# use default 'unknown file name'; 68, block; 69, else_clause; 70, assignment; 71, comparison_operator:result['status'] == -1; 72, comment:# EXCEPTION_RC is -1; 73, block; 74, elif_clause; 75, subscript; 76, call; 77, call; 78, call; 79, identifier:result; 80, string_content:utf-8; 81, identifier:file; 82, identifier:model_code; 83, raise_statement; 84, comparison_operator:file is None; 85, comparison_operator:model_code is None; 86, raise_statement; 87, identifier:file; 88, None; 89, if_statement; 90, identifier:model_code_bytes; 91, call; 92, identifier:include_paths; 93, None; 94, expression_statement; 95, call; 96, block; 97, identifier:include_paths; 98, list_comprehension; 99, identifier:include_paths_bytes; 100, list_comprehension; 101, identifier:allow_undefined; 102, False; 103, expression_statement; 104, identifier:model_name_bytes; 105, call; 106, call; 107, expression_statement; 108, comment:# use only the filename, used only for debug printing; 109, block; 110, identifier:result; 111, call; 112, subscript; 113, unary_operator; 114, expression_statement; 115, if_statement; 116, expression_statement; 117, raise_statement; 118, comparison_operator:result['status'] == 0; 119, comment:# SUCCESS_RC is 0; 120, block; 121, identifier:result; 122, string; 123, attribute; 124, argument_list; 125, attribute; 126, argument_list; 127, attribute; 128, argument_list; 129, call; 130, identifier:file; 131, None; 132, identifier:model_code; 133, None; 134, call; 135, call; 136, block; 137, else_clause; 138, attribute; 139, argument_list; 140, assignment; 141, identifier:isinstance; 142, argument_list; 143, expression_statement; 144, call; 145, for_in_clause; 146, call; 147, for_in_clause; 148, assignment; 149, attribute; 150, argument_list; 151, identifier:isinstance; 152, argument_list; 153, assignment; 154, expression_statement; 155, attribute; 156, argument_list; 157, identifier:result; 158, string; 159, integer:1; 160, assignment; 161, identifier:PY2; 162, comment:# fix problem with unicode in error message in PY2; 163, block; 164, assignment; 165, call; 166, subscript; 167, integer:0; 168, expression_statement; 169, string_content:msg; 170, identifier:result; 171, identifier:update; 172, dictionary; 173, identifier:result; 174, identifier:update; 175, dictionary; 176, identifier:result; 177, identifier:update; 178, dictionary; 179, identifier:ValueError; 180, argument_list; 181, identifier:ValueError; 182, argument_list; 183, identifier:isinstance; 184, argument_list; 185, try_statement; 186, block; 187, identifier:model_code; 188, identifier:encode; 189, string; 190, identifier:include_paths; 191, list; 192, identifier:include_paths; 193, identifier:string_types; 194, assignment; 195, attribute; 196, argument_list; 197, identifier:path; 198, identifier:include_paths; 199, attribute; 200, argument_list; 201, identifier:path; 202, identifier:include_paths; 203, identifier:model_name; 204, parenthesized_expression; 205, identifier:model_name; 206, identifier:encode; 207, string; 208, identifier:file; 209, identifier:string_types; 210, identifier:filename_bytes; 211, string; 212, assignment; 213, attribute; 214, identifier:stanc; 215, identifier:model_code_bytes; 216, identifier:model_name_bytes; 217, identifier:allow_undefined; 218, identifier:filename_bytes; 219, identifier:include_paths_bytes; 220, string_content:status; 221, identifier:msg; 222, subscript; 223, expression_statement; 224, identifier:error_msg; 225, call; 226, identifier:ValueError; 227, argument_list; 228, identifier:result; 229, string; 230, call; 231, pair; 232, pair; 233, pair; 234, concatenated_string; 235, string:"Model file missing and empty model_code."; 236, identifier:file; 237, identifier:string_types; 238, block; 239, except_clause; 240, expression_statement; 241, string_content:utf-8; 242, call; 243, identifier:include_paths; 244, list; 245, attribute; 246, identifier:join; 247, identifier:path; 248, string:""; 249, identifier:path; 250, identifier:encode; 251, string; 252, binary_operator:model_name + '_' +
              hashlib.md5(model_code_bytes).hexdigest(); 253, string_content:ascii; 254, string_content:unknown file name; 255, identifier:filename_bytes; 256, call; 257, identifier:pystan; 258, identifier:_api; 259, identifier:result; 260, string; 261, assignment; 262, attribute; 263, argument_list; 264, identifier:error_msg; 265, string_content:status; 266, attribute; 267, argument_list; 268, string; 269, identifier:model_name; 270, string; 271, identifier:model_code; 272, string; 273, identifier:include_paths; 274, string:"Specify stan model with `file` or `model_code`, "; 275, string:"not both."; 276, with_statement; 277, block; 278, assignment; 279, attribute; 280, argument_list; 281, identifier:include_paths; 282, identifier:os; 283, identifier:path; 284, string_content:utf-8; 285, binary_operator:model_name + '_'; 286, call; 287, attribute; 288, argument_list; 289, string_content:msg; 290, identifier:msg; 291, call; 292, string:"Failed to parse Stan model '{}'. Error message:\n{}"; 293, identifier:format; 294, identifier:model_name; 295, identifier:msg; 296, identifier:logger; 297, identifier:debug; 298, call; 299, string_content:model_name; 300, string_content:model_code; 301, string_content:include_paths; 302, with_clause; 303, block; 304, expression_statement; 305, raise_statement; 306, identifier:model_code; 307, call; 308, attribute; 309, identifier:abspath; 310, string; 311, identifier:model_name; 312, string; 313, attribute; 314, argument_list; 315, subscript; 316, identifier:encode; 317, string; 318, attribute; 319, argument_list; 320, attribute; 321, argument_list; 322, with_item; 323, expression_statement; 324, call; 325, attribute; 326, argument_list; 327, identifier:os; 328, identifier:path; 329, string_content:.; 330, string_content:_; 331, call; 332, identifier:hexdigest; 333, call; 334, unary_operator; 335, string_content:utf-8; 336, identifier:msg; 337, identifier:encode; 338, string; 339, string; 340, string:"Successfully parsed Stan model '{}'."; 341, identifier:format; 342, identifier:model_name; 343, as_pattern; 344, assignment; 345, attribute; 346, argument_list; 347, identifier:file; 348, identifier:read; 349, attribute; 350, argument_list; 351, attribute; 352, argument_list; 353, integer:1; 354, string_content:ascii; 355, string_content:replace; 356, call; 357, as_pattern_target; 358, identifier:model_code; 359, call; 360, identifier:logger; 361, identifier:critical; 362, string:"Unable to read file specified by `file`."; 363, identifier:hashlib; 364, identifier:md5; 365, identifier:model_code_bytes; 366, attribute; 367, identifier:split; 368, identifier:file; 369, attribute; 370, argument_list; 371, identifier:f; 372, attribute; 373, argument_list; 374, identifier:os; 375, identifier:path; 376, identifier:io; 377, identifier:open; 378, identifier:file; 379, string; 380, keyword_argument; 381, identifier:f; 382, identifier:read; 383, string_content:rt; 384, identifier:encoding; 385, identifier:charset
code: def stanc(file=None, charset='utf-8', model_code=None, model_name="anon_model",
            include_paths=None, verbose=False, obfuscate_model_name=True):
      """Translate Stan model specification into C++ code.
  
      Parameters
      ----------
      file : {string, file}, optional
          If filename, the string passed as an argument is expected to
          be a filename containing the Stan model specification.
  
          If file, the object passed must have a 'read' method (file-like
          object) that is called to fetch the Stan model specification.
  
      charset : string, 'utf-8' by default
          If bytes or files are provided, this charset is used to decode.
  
      model_code : string, optional
          A string containing the Stan model specification. Alternatively,
          the model may be provided with the parameter `file`.
  
      model_name: string, 'anon_model' by default
          A string naming the model. If none is provided 'anon_model' is
          the default. However, if `file` is a filename, then the filename
          will be used to provide a name.
  
      include_paths: list of strings, optional
          Paths for #include files defined in Stan code.
  
      verbose : boolean, False by default
          Indicates whether intermediate output should be piped to the
          console. This output may be useful for debugging.
  
      obfuscate_model_name : boolean, True by default
          If False the model name in the generated C++ code will not be made
          unique by the insertion of randomly generated characters.
          Generally it is recommended that this parameter be left as True.
  
      Returns
      -------
      stanc_ret : dict
          A dictionary with the following keys: model_name, model_code,
          cpp_code, and status. Status indicates the success of the translation
          from Stan code into C++ code (success = 0, error = -1).
  
      Notes
      -----
      C++ reserved words and Stan reserved words may not be used for
      variable names; see the Stan User's Guide for a complete list.
      
      The `#include` method follows a C/C++ syntax `#include foo/my_gp_funs.stan`.
      The method needs to be at the start of the row, no whitespace is allowed.
      After the included file no whitespace or comments are allowed.
      `pystan.experimental`(PyStan 2.18) has a `fix_include`-function to clean the `#include`
      statements from the `model_code`. 
      Example: 
      `from pystan.experimental import fix_include`
      `model_code = fix_include(model_code)`
  
      See also
      --------
      StanModel : Class representing a compiled Stan model
      stan : Fit a model using Stan
  
      References
      ----------
      The Stan Development Team (2013) *Stan Modeling Language User's
      Guide and Reference Manual*.  <http://mc-stan.org/>.
  
      Examples
      --------
      >>> stanmodelcode = '''
      ... data {
      ...   int<lower=0> N;
      ...   real y[N];
      ... }
      ...
      ... parameters {
      ...   real mu;
      ... }
      ...
      ... model {
      ...   mu ~ normal(0, 10);
      ...   y ~ normal(mu, 1);
      ... }
      ... '''
      >>> r = stanc(model_code=stanmodelcode, model_name = "normal1")
      >>> sorted(r.keys())
      ['cppcode', 'model_code', 'model_cppname', 'model_name', 'status']
      >>> r['model_name']
      'normal1'
  
      """
      if file and model_code:
          raise ValueError("Specify stan model with `file` or `model_code`, "
                           "not both.")
      if file is None and model_code is None:
          raise ValueError("Model file missing and empty model_code.")
      if file is not None:
          if isinstance(file, string_types):
              try:
                  with io.open(file, 'rt', encoding=charset) as f:
                      model_code = f.read()
              except:
                  logger.critical("Unable to read file specified by `file`.")
                  raise
          else:
              model_code = file.read()
  
      # bytes, going into C++ code
      model_code_bytes = model_code.encode('utf-8')
  
      if include_paths is None:
          include_paths = [os.path.abspath('.')]
      elif isinstance(include_paths, string_types):
          include_paths = [include_paths]
      # add trailing /
      include_paths = [os.path.join(path, "") for path in include_paths]
      include_paths_bytes = [path.encode('utf-8') for path in include_paths]
  
      # set to False
      allow_undefined = False
  
      if obfuscate_model_name:
          # Make the model name depend on the code.
          model_name = (
              model_name + '_' +
              hashlib.md5(model_code_bytes).hexdigest())
  
      model_name_bytes = model_name.encode('ascii')
  
      if not isinstance(file, string_types):
          # use default 'unknown file name'
          filename_bytes  = b'unknown file name'
      else:
          # use only the filename, used only for debug printing
          filename_bytes = os.path.split(file)[-1].encode('utf-8')
  
      result = pystan._api.stanc(model_code_bytes, model_name_bytes,
                                 allow_undefined, filename_bytes, 
                                 include_paths_bytes,
                                )
      if result['status'] == -1:  # EXCEPTION_RC is -1
          msg = result['msg']
          if PY2:
              # fix problem with unicode in error message in PY2
              msg = msg.encode('ascii', 'replace')
          error_msg = "Failed to parse Stan model '{}'. Error message:\n{}".format(model_name, msg)
          raise ValueError(error_msg)
      elif result['status'] == 0:  # SUCCESS_RC is 0
          logger.debug("Successfully parsed Stan model '{}'.".format(model_name))
      del result['msg']
      result.update({'model_name': model_name})
      result.update({'model_code': model_code})
      result.update({'include_paths' : include_paths})
      return result