 
 dsl_fn = (name) ->
   result = (args...) ->
-    new dsl.type.f name, (process_arg arg for arg in args)...
+    new dsl.type.f name, (process_arg arg for arg in args)
   result.type = 'i'
   result.fn_name = name
-  result.values = [name]
+  result.value = name
   # TODO this will break f.bind() etc.
   result.__proto__ = new dsl.type.i
 

#  s: string
#  i: identifier
#  o: jsonable object
create_type n, dsl.type for n in "pfqi"

dsl.type.f::to_target_string = ->
  [name, args...] = @values
  "#{name}(#{(a.to_target_string() for a in args).join ','})"

dsl.type.f::to_js_string = ->
  [name, args...] = @values
  "#{name}(#{(a.to_js_string() for a in args).join ','})"

dsl.type.q::to_target_string = ->
  @values.join ','

dsl.type.q::to_js_string = ->
  "q(#{(@values.map JSON.stringify).join ', '})"

# numbers, strings, jsonable objects, and booleans use json serialization
dsl.type.p::to_js_string =
dsl.type.p::to_target_string = ->
  JSON.stringify @values[0]

create_type n, dsl.type.p for n in "nsbo"

dsl.type.TRUE = new dsl.type.b true
dsl.type.FALSE = new dsl.type.b false

# Graphite doesn't support escaped quotes in strings, so avoid including any if possible.
dsl.type.s::to_target_string = ->
  s = @values[0]
  if s.indexOf('"') >= 0 or s.indexOf("'") < 0
    quoteChar = "'"
  else
    quoteChar = '"'
  quoteChar + s.replace(quoteChar, "\\#{quoteChar}") + quoteChar

dsl.type.i::to_target_string = dsl.type.s::to_target_string
dsl.type.i::to_js_string = ->
  @values[0]

dsl.type.o::to_target_string = ->
  objects = to_string_context.objects ?= []
  i = objects.length
  objects.push @values[0]
  "param('objects',#{i})"

process_arg = (arg) ->

dsl_type = ->
dsl = type: dsl_type

create_type = (n, parent, f) ->
  t = (args...) ->
    @type = n
    f.apply @, args
  t.prototype = new parent
  dsl_type[n] = t

