<commit_before>require 'fy'
require 'fy/codegen'
{
  Translator
  un_op_translator_holder
  un_op_translator_framework
  bin_op_translator_holder
  bin_op_translator_framework
} = require 'gram'
module = @

# ###################################################################################################
trans = new Translator
trans.trans_skip =
  indent : true
  dedent : true
  eol    : true

# trans.trans_value = {}
trans.trans_token =
  comment : (v)-> "//" + v.substr 1
deep = (ctx, node)->
  list = []
  # if node.mx_hash.deep?
  #   node.mx_hash.deep = '0' if node.mx_hash.deep == false # special case for deep=0
  #   value_array = (node.value_array[pos] for pos in node.mx_hash.deep.split ',')
  # else
  #   value_array = node.value_array
  
  
  value_array = node.value_array
  for v,k in value_array
    if trans.trans_skip[v.mx_hash.hash_key]?
      # LATER
      if node.mx_hash.eol_pass and v.mx_hash.hash_key == 'eol'
        list.push "\n"
    else if fn = trans.trans_token[v.mx_hash.hash_key]
      list.push fn v.value
    # else if trans.trans_value[v.mx_hash.hash_key]?
      # list.push v.value
    else if /^proxy_/.test v.mx_hash.hash_key
      list.push v.value
    else
      list.push ctx.translate v
  if delimiter = node.mx_hash.delimiter
    delimiter = ' ' if delimiter == "'[SPACE]'"
    list = [ list.join(delimiter) ]
  list

trans.translator_hash['value']  = translate:(ctx, node)->node.value
trans.translator_hash['deep']   = translate:(ctx, node)->
  list = deep ctx, node
  list.join('')
trans.translator_hash['block']   = translate:(ctx, node)->
  list = deep ctx, node
  make_tab list.join(''), '  '
# ###################################################################################################
#    bin_op
# ###################################################################################################

do ()->
  holder = new bin_op_translator_holder
  for v in bin_op_list = "+ - * /".split ' '
    holder.op_list[v]  = new bin_op_translator_framework "($1$op$2)"
    v = v+"="
    holder.op_list[v]  = new bin_op_translator_framework "($1$op$2)"

  for v in bin_op_list = "= == != < <= > >=".split ' '
    holder.op_list[v]  = new bin_op_translator_framework "($1$op$2)"
  trans.translator_hash['bin_op'] = translate:(ctx, node)->
    op = node.value_array[1].value
    if op in ['or', 'and']
      # needs type inference
      [a,_skip,b] = node.value_array
      a_tr = ctx.translate a
      b_tr = ctx.translate b
      
      if !a.mx_hash.type? or !b.mx_hash.type?
        throw new Error "can't translate op=#{op} because type inference can't detect type of arguments"
      if !a.mx_hash.type.eq b.mx_hash.type
        # не пропустит type inference
        ### !pragma coverage-skip-block ###
        throw new Error "can't translate op=#{op} because type mismatch #{a.mx_hash.type} != #{b.mx_hash.type}"
      switch a.mx_hash.type.toString()
        when 'int'
          return "(#{a_tr}|#{b_tr})"
        when 'bool'
          return "(#{a_tr}||#{b_tr})"
        else
          # не пропустит type inference
          ### !pragma coverage-skip-block ###
          throw new Error "op=#{op} doesn't support type #{a.mx_hash.type}"
    
    holder.translate ctx, node
# ###################################################################################################
#    pre_op
# ###################################################################################################
holder = new un_op_translator_holder
holder.mode_pre()
for v in un_op_list = "~ + - !".split ' '
  holder.op_list[v]  = new un_op_translator_framework "$op$1"

holder.op_list["not"]  = new un_op_translator_framework "!$1"
holder.op_list["void"] = new un_op_translator_framework "null"

for v in un_op_list = "typeof new delete".split ' '
  holder.op_list[v]  = new un_op_translator_framework "($op $1)"
trans.translator_hash['pre_op'] = holder

# ###################################################################################################
#    post_op
# ###################################################################################################
holder = new un_op_translator_holder
holder.mode_post()
for v in un_op_list = ["++", '--']
  holder.op_list[v]  = new un_op_translator_framework "($1$op)"
trans.translator_hash['post_op'] = holder

# ###################################################################################################
#    str
# ###################################################################################################

trans.translator_hash['string_interpolated'] = translate:(ctx, node)->
  if node.value_array[0].value_array.length > 1
    start = ctx.translate node.value_array[0]
  else
    start = node.value_array[0].value.replace '#{', '"+'
  start +
    (ctx.translate node.value_array[1]) +
    (node.value_array[2].value.replace '}', '+"').replace '#{', '"+'<commit_msg>Translator: refactor string interpolation<commit_after>require 'fy'
require 'fy/codegen'
{
  Translator
  un_op_translator_holder
  un_op_translator_framework
  bin_op_translator_holder
  bin_op_translator_framework
} = require 'gram'
module = @

# ###################################################################################################
trans = new Translator
trans.trans_skip =
  indent : true
  dedent : true
  eol    : true

# trans.trans_value = {}
trans.trans_token =
  comment : (v)-> "//" + v.substr 1
deep = (ctx, node)->
  list = []
  # if node.mx_hash.deep?
  #   node.mx_hash.deep = '0' if node.mx_hash.deep == false # special case for deep=0
  #   value_array = (node.value_array[pos] for pos in node.mx_hash.deep.split ',')
  # else
  #   value_array = node.value_array
  
  
  value_array = node.value_array
  for v,k in value_array
    if trans.trans_skip[v.mx_hash.hash_key]?
      # LATER
      if node.mx_hash.eol_pass and v.mx_hash.hash_key == 'eol'
        list.push "\n"
    else if fn = trans.trans_token[v.mx_hash.hash_key]
      list.push fn v.value
    # else if trans.trans_value[v.mx_hash.hash_key]?
      # list.push v.value
    else if /^proxy_/.test v.mx_hash.hash_key
      list.push v.value
    else
      list.push ctx.translate v
  if delimiter = node.mx_hash.delimiter
    delimiter = ' ' if delimiter == "'[SPACE]'"
    list = [ list.join(delimiter) ]
  list

trans.translator_hash['value']  = translate:(ctx, node)->node.value
trans.translator_hash['deep']   = translate:(ctx, node)->
  list = deep ctx, node
  list.join('')
trans.translator_hash['block']   = translate:(ctx, node)->
  list = deep ctx, node
  make_tab list.join(''), '  '
# ###################################################################################################
#    bin_op
# ###################################################################################################

do ()->
  holder = new bin_op_translator_holder
  for v in bin_op_list = "+ - * /".split ' '
    holder.op_list[v]  = new bin_op_translator_framework "($1$op$2)"
    v = v+"="
    holder.op_list[v]  = new bin_op_translator_framework "($1$op$2)"

  for v in bin_op_list = "= == != < <= > >=".split ' '
    holder.op_list[v]  = new bin_op_translator_framework "($1$op$2)"
  trans.translator_hash['bin_op'] = translate:(ctx, node)->
    op = node.value_array[1].value
    if op in ['or', 'and']
      # needs type inference
      [a,_skip,b] = node.value_array
      a_tr = ctx.translate a
      b_tr = ctx.translate b
      
      if !a.mx_hash.type? or !b.mx_hash.type?
        throw new Error "can't translate op=#{op} because type inference can't detect type of arguments"
      if !a.mx_hash.type.eq b.mx_hash.type
        # не пропустит type inference
        ### !pragma coverage-skip-block ###
        throw new Error "can't translate op=#{op} because type mismatch #{a.mx_hash.type} != #{b.mx_hash.type}"
      switch a.mx_hash.type.toString()
        when 'int'
          return "(#{a_tr}|#{b_tr})"
        when 'bool'
          return "(#{a_tr}||#{b_tr})"
        else
          # не пропустит type inference
          ### !pragma coverage-skip-block ###
          throw new Error "op=#{op} doesn't support type #{a.mx_hash.type}"
    
    holder.translate ctx, node
# ###################################################################################################
#    pre_op
# ###################################################################################################
holder = new un_op_translator_holder
holder.mode_pre()
for v in un_op_list = "~ + - !".split ' '
  holder.op_list[v]  = new un_op_translator_framework "$op$1"

holder.op_list["not"]  = new un_op_translator_framework "!$1"
holder.op_list["void"] = new un_op_translator_framework "null"

for v in un_op_list = "typeof new delete".split ' '
  holder.op_list[v]  = new un_op_translator_framework "($op $1)"
trans.translator_hash['pre_op'] = holder

# ###################################################################################################
#    post_op
# ###################################################################################################
holder = new un_op_translator_holder
holder.mode_post()
for v in un_op_list = ["++", '--']
  holder.op_list[v]  = new un_op_translator_framework "($1$op)"
trans.translator_hash['post_op'] = holder

# ###################################################################################################
#    str
# ###################################################################################################

trans.translator_hash['string_interpolated'] = translate:(ctx, node)->
  first_child = node.value_array[0]
  start = if first_child.value_array.length > 1 \
    then ctx.translate first_child              \
    else first_child.value.replace '#{', '"+'
  start +
  mid = ctx.translate node.value_array[1]
  end = (node.value_array[2].value.replace '}', '+"').replace '#{', '"+'
  start + mid + end
{'fraction_non_alphanumeric': 0.3012781497261108, 'fraction_numerical': 0.003854737269222966, 'mean_word_length': 4.037812979049566, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5129257', 'n_tokens_mistral': 3115, 'n_tokens_neox': 3057, 'n_words': 620}