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: