Module: Sym

Defined in:
lib/sym.rb

Defined Under Namespace

Classes: Handle

Class Method Summary collapse

Class Method Details

.block(lang, code) ⇒ Object



70
# File 'lib/sym.rb', line 70

def self.block(lang, code) = request({ "op" => "exec", "lang" => lang, "code" => code })

.c_call(lib_fn, args, ret = "int", argtypes = []) ⇒ Object



73
# File 'lib/sym.rb', line 73

def self.c_call(lib_fn, args, ret = "int", argtypes = []) = request({ "op" => "call", "lang" => "c", "target" => lib_fn, "args" => args, "ret" => ret, "argtypes" => argtypes })

.call(lang, target, args = []) ⇒ Object



68
# File 'lib/sym.rb', line 68

def self.call(lang, target, args = []) = request({ "op" => "call", "lang" => lang, "target" => target, "args" => unwrap(args) })

.closeObject



75
76
77
78
79
80
# File 'lib/sym.rb', line 75

def self.close
  return unless @stdin
  begin; request({ "op" => "shutdown" }); rescue; end
  begin; @stdin.close; rescue; end
  @stdin = nil
end

.ensure_hostObject



32
33
34
35
36
# File 'lib/sym.rb', line 32

def self.ensure_host
  return if @stdin
  @stdin, @stdout, @wait = Open3.popen2("python3", File.join(root, "bridge", "stdio_host.py"))
  at_exit { close }
end

.get(key) ⇒ Object



71
# File 'lib/sym.rb', line 71

def self.get(key) = request({ "op" => "get", "key" => key })

.import(lang, target) ⇒ Object



67
# File 'lib/sym.rb', line 67

def self.import(lang, target) = request({ "op" => "import", "lang" => lang, "target" => target })

.new_obj(lang, target, args = []) ⇒ Object



69
# File 'lib/sym.rb', line 69

def self.new_obj(lang, target, args = []) = request({ "op" => "new", "lang" => lang, "target" => target, "args" => unwrap(args) })

.request(msg) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/sym.rb', line 38

def self.request(msg)
  ensure_host
  @next_id += 1
  msg["id"] = @next_id
  @stdin.puts(JSON.generate(msg))
  @stdin.flush
  loop do
    line = @stdout.gets or raise "sym host died"
    resp = JSON.parse(line) rescue next
    next unless resp["id"] == @next_id
    raise "sym: #{resp["error"]}" unless resp["ok"]
    return wrap(resp["value"])
  end
end

.rootObject



18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/sym.rb', line 18

def self.root
  return ENV["SYM_HOME"] if ENV["SYM_HOME"] && File.directory?(File.join(ENV["SYM_HOME"], "bridge"))
  home = File.join(Dir.home, ".sym")
  return home if File.directory?(File.join(home, "bridge"))
  d = File.expand_path(File.dirname(__FILE__))
  5.times do
    return d if File.directory?(File.join(d, "bridge"))
    d = File.dirname(d)
  end
  core = `python3 -c "import sym_lang, os; print(os.path.join(os.path.dirname(sym_lang.__file__), 'core'))" 2>/dev/null`.strip
  return core if !core.empty? && File.directory?(File.join(core, "bridge"))
  raise "sym: no Sym found (pip install sym-lang, or set SYM_HOME)"
end

.set(key, value) ⇒ Object



72
# File 'lib/sym.rb', line 72

def self.set(key, value) = request({ "op" => "set", "key" => key, "value" => value })

.unwrap(args) ⇒ Object



63
64
65
# File 'lib/sym.rb', line 63

def self.unwrap(args)
  args.map { |a| a.is_a?(Handle) ? a.tag : a }
end

.wrap(v) ⇒ Object



53
54
55
56
57
58
59
60
61
# File 'lib/sym.rb', line 53

def self.wrap(v)
  if v.is_a?(Hash) && v["__sym__"] == "handle"
    Handle.new(v)
  elsif v.is_a?(Array)
    v.map { |x| wrap(x) }
  else
    v
  end
end