Warning: this is an htmlized version!
The original is here, and
the conversion rules are here.
# «.variables»		(to "variables")
# «.variables_print»	(to "variables_print")
# «.building_strings»	(to "building_strings")
# «.file_functions»	(to "file_functions")
# «.top_level»		(to "top_level")
# «.run_»		(to "run_")
# «.Xprims_support»	(to "Xprims_support")
# «.Xprims»		(to "Xprims")



#%%%%
#
# «variables»  (to ".variables")
#
#%%%%

# Lists:
set FIPprims_used {}
set SFprims_used {}
set Fprims_used {}
set Hprims_used {}

# Arrays:
#   word_action
#   prim_code
#   prim_status

# Strings:
set asm_code {}
set asm_defs {}
set C_defs {}
set FIPprims_code {}
set SFprims_code {}
set Fprims_code {}
set Hprims_code {}
set SF_TO_F_code {}

# (find-node "(nasm)Section 5.4" "extern _printf")
# (find-node "(nasm)Section 5.5" "global _main")
# The section is ".data" because we want the crim code read-write.
#
set asm_headers {%macro dwhl 1.nolist
	db (%1) >> 8
	db (%1) & 0xFF
%endmacro
%macro dwhla 1.nolist
	db ((%1)-_f0) >> 8
	db ((%1)-_f0) & 0xFF
%endmacro
SECTION .data
global _f0
_f0:
}



#%%%%
#
# «variables_print»  (to ".variables_print")
#
#%%%%

proc putsvars {args} {
  foreach varname $args {
    puts $varname:
    catch {puts [uplevel #0 set $varname]}
  }
}
proc print_vars {} {
  uplevel #0 {
    catch {parray prim_status}
    catch {parray word_action}
    catch {parray prim_code}
  }
  putsvars FIPprims_used SFprims_used Fprims_used Hprims_used
  # Strings:
  putsvars asm_code asm_defs C_defs
  putsvars FIPprims_code SFprims_code Fprims_code Hprims_code
}



#%%%%
#
# Functions to build strings for the
# "define"s, "switch"s, externs and arrays
#
#%%%%

# «building_strings»  (to ".building_strings")

proc define%02X {word n} {global C_defs asm_defs
  append   C_defs [format  "#define %-16s 0x%02X\n" $word $n]
  append asm_defs [format "%%define %-16s 0x%02X\n" $word $n]
}
proc define%04X {word n} {global C_defs asm_defs
  append   C_defs [format  "#define %-16s 0x%04X\n" $word $n]
  append asm_defs [format "%%define %-16s 0x%04X\n" $word $n]
}

# This function "prepares" the following vars:
# C_defs asm_defs
# H_LAST FIP_LAST SF_LAST F_LAST
# Hprims_code FIPprims_code Fprims_code SF_TO_F_code
#
proc set_final_prim_data {} { uplevel #0 {
  set n [expr 0xFF]
  foreach word $Hprims_used {
    set prim_opcode($word) $n; define%02X $word $n; incr n -1
    append Hprims_code "case $word: $prim_code($word)"
  }
  define%02X H_LAST [expr $n+1]
  
  set n [expr 0xFFFF]
  foreach word $FIPprims_used {
    set prim_opcode($word) $n; define%04X $word $n; incr n -1
    append FIPprims_code "case $word: $prim_code($word)"
  }
  define%02X FIP_LAST [expr $n+1]
  
  set n [expr 0xFF]
  foreach word $SFprims_used {
    set prim_opcode($word) $n; define%02X $word $n; incr n -1
    append SF_TO_F_code "[string range $word 1 end], "
  }
  define%02X SF_LAST [expr $n+1]
  set n [expr ($n<<8)|255]
  foreach word $Fprims_used {
    set prim_opcode($word) $n; define%04X $word $n; incr n -1
    append Fprims_code "case $word: $prim_code($word)"
  }
  define%04X F_LAST [expr $n+1]
}}




#%%%%
#
# File functions (generic, asm-specific and C-specific)
#
#%%%%

# «file_functions»  (to ".file_functions")
proc readfile {fname} { exec cat $fname }
proc writefile {fname str} {
  if {$fname=="-"} { puts -nonewline $str; return }
  set ch [open $fname w]; puts -nonewline $ch $str; close $ch
}

proc doasmfilestuff {fnameout} { global asm_headers asm_defs asm_code
  writefile $fnameout $asm_headers$asm_defs$asm_code
}
proc doCfilestuff {fnamein fnameout} {
  set s [readfile $fnamein]
  set tail {}
  while {[regexp {^(.*)/\*-- (.*) --\*/(.*)$} $s -> a b c]} {
    set tail "/*--{ $b }--*/\n  [uplevel #0 $b]$c$tail"
    set s $a
  }
  writefile $fnameout $s$tail
}




#%%%%
#
# top-level functions 
#
#%%%%

# «top_level»  (to ".top_level")

proc run {args} { global word_action
  foreach word $args {
    uplevel #0 $word_action($word)
  }
}

proc tick {word} { global asm_code word_action
  set nasmname [nasmify $word]
  append asm_code "ADR_$nasmname:\n"
  set word_action($word) "append asm_code \"\\tdwhla ADR_$nasmname\\n\""
}



#%%%%
#
# main "run_" functions
# (used for compiling "db"s)
#
#%%%%

# «run_»  (to ".run_")

proc assert_used {listvar word} {global $listvar prim_status
  if {![info exists prim_status($word)] || $prim_status($word)==""} {
    lappend $listvar $word
    set prim_status($word) USED
  }
}

proc run_Hprim {word} {global asm_code
  assert_used Hprims_used $word
  append asm_code "\tdb $word\n"
}
proc run_SFprim {sfword} {global asm_code
  regexp {^S(F_.*)$} $sfword -> fword
  assert_used  Fprims_used $fword
  assert_used SFprims_used $sfword
  append asm_code "\tdb $sfword\n"
}
proc run_Fprim {word} {global asm_code
  assert_used Fprims_used $word
  append asm_code "\tdwhl $word\n"
}
# Every FIPprim declared is treated as used, and there is no db'ing
# for them; so, no run_FIPprim.

proc run_Fadr {word} {global asm_code
  append asm_code "\tdwhla $word\n"
}



#%%%%
#
# Support for the high-level defining functions
#
#%%%%

# «Xprims_support»  (to ".Xprims_support")

proc nasmify {str} {
  if {$str==""} { error "Tried to nasmify the null string" }
  set re {[A-Za-z]}
  set nasmstr {}
  foreach c [split $str {}] {
    if {[regexp {[0-9A-Za-z_]} $c]} {
      append nasmstr $c
    } else {
      scan $c "%c" ord
      append nasmstr [format "x%02x" $ord]
    }
  }
  return $nasmstr
}

proc has_space {str} { expr {[string first " " $str]!=-1} }
proc nasm_namep {str} { regexp {^[0-9A-Za-z_]+$} $str }

# A function to reorder lists of arguments in a certain way.
# Args with spaces are considered as the def for the preceding args. 
# Also select the first arg which is a valid nasm name.
# Example:
#   untitled1 {? a b c {1 + 2} * && { hello }}
#          -> {a {? a b c} {1 + 2}
#              {} {* &&} { hello }}
#
proc bigreorder {list} {
  set names {}
  set nasmname {}
  set result {}
  foreach arg $list {
    if {[has_space $arg]} {
      if {$names==""} {
	error "a def was not preceded by any names: [list $arg]"
      }
      lappend result $nasmname $names $arg
      set names {}
      set nasmname {}
    } else {
      if {$nasmname=="" && [nasm_namep $arg]} {
	set nasmname $arg
      }
      lappend names $arg
    }
  }
  if {$names!=""} {
    error "there were names not followed by a def: $names"
  }
  return $result
}

proc bigreorder_nasm {list} {
  set result {}
  foreach {nasmname othernames def} [bigreorder $list] {
    if {$nasmname==""} { set nasmname [nasmify [lindex $othernames 0]] }
    lappend result $nasmname $othernames $def
  }
  return $result
}

# puts [bigreorder {? a b c {1 + 2} * && { hello }}]
# puts [bigreorder {? a b c {1 + 2} * && { hello } quux faz}]
# puts [bigreorder {? a b c {1 + 2} { hello } quux}]




#%%%%
#
# High-level functions to define primitives
#
#%%%%

# «Xprims»  (to ".Xprims")

proc FIPprims {args} { global word_action prim_code
  foreach {nasmname othernames def} [bigreorder_nasm $args] {
    set prim_code(FIP_$nasmname) $def
    assert_used FIPprims_used FIP_$nasmname
  }
}
proc Fprims {args} { global word_action prim_code
  foreach {nasmname othernames def} [bigreorder_nasm $args] {
    set prim_code(F_$nasmname) $def
    foreach word $othernames {
      set word_action($word)   [list run_Fprim F_$nasmname]
      set word_action(F_$word) [list run_Fprim F_$nasmname]
    }
  }
}
proc SFprims {args} { global word_action prim_code
  foreach {nasmname othernames def} [bigreorder_nasm $args] {
    set prim_code(F_$nasmname) $def
    foreach word $othernames {
      set word_action($word)    [list run_SFprim SF_$nasmname]
      set word_action(SF_$word) [list run_SFprim SF_$nasmname]
      set word_action(F_$word)  [list run_Fprim   F_$nasmname]
    }
  }
}
proc Hprims {args} { global word_action prim_code
  foreach {nasmname othernames def} [bigreorder_nasm $args] {
    set prim_code(H_$nasmname) $def
    foreach word $othernames {
      set word_action($word)  [list run_Hprim H_$nasmname]
      set word_action($word:) [list run_Hprim H_$nasmname]
    }
  }
}






#  Local Variables:
#  coding:               no-conversion
#  ee-anchor-format:     "«%s»"
#  ee-charset-indicator: "Ñ"
#  End: