Subtext

Zarutian 4. september: Subtext [L1 ] is a visual programming language and environment, but that doesn't tell the whole story so follow that link to get more info.

First rough draft of possible implemention in Tcl:

  • a node is a autonamed variable, possible traced
  • a function is several nodes
  # not tested yet
  array set the_data_array {}
  array set the_prog_array {}

  proc get-value {identifier} {
    variable the_data_array
    variable the_prog_array

    set from_storage [set the_prog_array($identifier)]
    if {[lindex $from_storage 0] == "data"} {
      return [set the_data_array($identifier)]
    }
    if {[lindex $from_storage 0] == "function"} {
      set incoming_links [lindex $from_storage 2]
      set outgoing_links [lindex $from_storage 3]
      set program        [lindex $from_storage 4]

      # check if any incoming nodes changed:
      set recaculate false
      foreach link $incoming_links {
        set link_identifier [lindex $link 0]
        set old_value       [lindex $link 1]
        if {$old_value != [set the_data_array($link_identifier)]} {
          set recaculate true
          break
        }
      }
      if {$recaculate} {
        set vars_and_values [list]
        set counter 0
        foreach link $incoming_links {
          set link_identifier [lindex $link 0]
          lappend vars_and_values "input[incr counter]"
          lappend vars_and_values [set the_data_array($link_identifier)]
        }
        array_multiset [eval_with [set the_data_array($program)] $vars_and_values] the_data_array $outgoing_links
      }
    }
  }
  proc array_multiset {values arrayname indexes} {
    # this proc returns nothing but has write sideeffects on the array $arrayname
    upvar $arrayname thearray
    #checking that arrayname is indeed an array
    if {![array exists thearray]} {
      error "arrayname must refer to an array"
    }
    set value_index 0
    set value_index_max [llength $values]
    foreach index $indexes {
      set thearray($index) [lindex $values $value_index]
    }
  }
  proc eval_with {script vars_and_values} {
    multiset $vars_and_values
    # to prevent possible security hole
    # the script below reffers to the first
    # parameter of the procedure with [lindex [info level 0] 1]
    # instead of $script because script might been set in
    # the muliset call
    return [eval [lindex [info level 0] 1]]
  }
  proc multiset {vars_and_values} {
    foreach {var value} {
      upvar $var tmp
      set $tmp $value
    }
  }