def to_value(a)
  return "(S #{a.value})" unless Array===a.value
  sofar="(L ["
  first=true
  until a.empty
    sofar << "," if !first
    first = false
    sofar << to_value(a.value[0])
    a = a.value[1]
  end
  sofar << "])"
  sofar
end

def outputn s
  output s
  output "\n" if s[-1] != "\n"
end

def to_engine(source, pp_sep)
  outputn to_eager_str(Ops["version"].ways[0].impl.call)

  _, input_mode = lex(source)

  case input_mode
  when :raw_mode
    possible_input_formats = ["a",["a","b"]]
    finish = "rawInputSelector"
    input = "rawInput"
  when :raw_line_mode
    possible_input_formats = ["a\nb",["a\nb","a\nb"]]
    finish = "rawLineInputSelector"
    input = "rawLineInput"
  else
    if !does_source_use_input(source)
      possible_input_formats = [""]
      finish = nil
      input = "undefined"
    else
      possible_input_formats = ["1","1 1","1 1\n1",["1 1\n1","1 1\n1"],"a","a\nb",["a\nb","a\nb"],""]
      finish = "autoInputSelector"
      input = "input"
    end
  end

  output_inds = []
  offset = 0
  possible_input_formats.each.with_index{|fake_input, i|
    begin
      ir3, ir3_ind = gen_graph(source, fake_input, pp_sep: pp_sep)
      to_engine_main(ir3,offset,input)
      output_inds << ir3_ind + offset
      offset += ir3.size
    rescue IogiiError => e
      outputn "Data #{to_value(str_to_lazy_list(e.message).const)} \"[char]\""
      outputn "Op \"error\" [#{offset}] 0 \"int\""
      output_inds << offset + 1
      offset += 2
    end
  }

  outputn "Op #{finish.inspect} #{output_inds.inspect} 0 \"\"" if finish

end

def to_engine_main(ir3, offset, input)
  ir3.each{|node|
    if node.way.name == "data"
      outputn "Data #{to_value(node.way.impl.call.const)} #{type_and_rank_to_str(node.type,node.rank).inspect}"
    else
      name = node.way.name
      name = input if name == "input"

      outputn "Op #{name.inspect} #{node.args.map{|i|i+offset}.inspect} #{node.zip_level} #{type_and_rank_to_str(node.type,node.rank).inspect}"
    end
  }
end

def does_source_use_input(source)
  $input_checked = false
  begin
    gen_graph(source, "", ast_cb: ->_,_{ return $input_checked })
  rescue IogiiError => e
  end
  $input_checked
end
