gasm.tcl
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 namespace grammar::me::cpu::gasm {}
00012
00013
00014
00015
00016 ret ::grammar::me::cpu::gasm::begin (type g , type n , optional mode =okfail , optional note ={)} {
00017 variable gas
00018 array unset gas *
00019
00020 # (Re)initialize the assmebler state, create the framework nodes
00021 # upon which we will hang all instructions on.
00022
00023 set gas(mode) $mode
00024 set gas(node) $n
00025 set gas(grap) $g
00026 array set gas {last {} cond always}
00027
00028 Nop $note ; /Label entry ; /Clear
00029 if {$mode eq "okfail"} {
00030 Nop Exit'OK ; /Label exit/ok ; /Clear
00031 Nop Exit'FAIL ; /Label exit/fail ; /Clear
00032 } elseif {$mode eq "halt"} {
00033 Cmd icf_halt ; /Label exit/return ; /Clear
00034 } else {
00035 Cmd icf_ntreturn ; /Label exit/return ; /Clear
00036 }
00037
00038 /At entry
00039 return
00040 }
00041
00042 ret ::grammar::me::cpu::gasm::done (__ type t) {
00043 variable gas
00044
00045 # Save the framework nodes in a grammar tree and shut the
00046 # assembler down.
00047
00048 $t set $gas(node) gas::entry $gas(_entry)
00049
00050 if {$gas(mode) eq "okfail"} {
00051 $t set $gas(node) gas::exit::ok $gas(_exit/ok)
00052 $t set $gas(node) gas::exit::fail $gas(_exit/fail)
00053 } else {
00054 $t set $gas(node) gas::exit $gas(_exit/return)
00055 }
00056
00057 # Remember the node in the grammar tree which is responsible for
00058 # this entry point.
00059
00060 $gas(grap) node set $gas(_entry) expr $gas(node)
00061
00062 array unset gas *
00063 return
00064 }
00065
00066 ret ::grammar::me::cpu::gasm::lift (type t , type dst __ , type src) {
00067
00068 $t set $dst gas::entry [$t get $src gas::entry]
00069 $t set $dst gas::exit::ok [$t get $src gas::exit::ok]
00070 $t set $dst gas::exit::fail [$t get $src gas::exit::fail]
00071 return
00072 }
00073
00074 ret ::grammar::me::cpu::gasm::state () {
00075 variable gas
00076 return [array get gas]
00077 }
00078
00079 ret ::grammar::me::cpu::gasm::state! (type s) {
00080 variable gas
00081 array set gas $s
00082 }
00083
00084 ret ::grammar::me::cpu::gasm::Inline (type t , type node , type label) {
00085 variable gas
00086
00087 set gas(_${label}/entry) [$t get $node gas::entry]
00088 set gas(_${label}/exit/ok) [$t get $node gas::exit::ok]
00089 set gas(_${label}/exit/fail) [$t get $node gas::exit::fail]
00090
00091 __Link $gas(_${label}/entry) $gas(cond)
00092 /At ${label}/exit/ok
00093 return
00094 }
00095
00096 ret ::grammar::me::cpu::gasm::Cmd (type cmd , type args) {
00097 variable gas
00098
00099 # Add a new instruction, and link it to the anchor. The created
00100 # instruction becomes the new anchor.
00101
00102 upvar 0 gas(grap) g gas(last) anchor gas(cond) cond
00103
00104 set node [$g node insert]
00105 $g node set $node instruction $cmd
00106 $g node set $node arguments $args
00107
00108 if {$anchor ne ""} {__Link $node $cond}
00109
00110 set anchor $node
00111 set cond always
00112 return
00113 }
00114
00115 ret ::grammar::me::cpu::gasm::Bra () {
00116 Cmd .BRA
00117 }
00118
00119 ret ::grammar::me::cpu::gasm::Nop (optional text ={)} {
00120 Cmd .NOP $text
00121 }
00122
00123 proc ::grammar::me::cpu::gasm::Note {text} {
00124 Cmd .C $text
00125 }
00126
00127 proc ::grammar::me::cpu::gasm::Jmp {label} {
00128 variable gas
00129 __Link $gas(_$label) $gas(cond)
00130 return
00131 }
00132
00133 proc ::grammar::me::cpu::gasm::Exit {} {
00134 variable gas
00135 if {$gas(mode) eq "okfail"} {
00136 __Link $gas(_exit/$gas(cond)) $gas(cond)
00137 } else {
00138 __Link $gas(_exit/return) always
00139 }
00140 return
00141 }
00142
00143 ret ::grammar::me::cpu::gasm::Who (type label) {
00144 variable gas
00145 return $gas(_$label)
00146 }
00147
00148 ret ::grammar::me::cpu::gasm::__Link (type to , type cond) {
00149 variable gas
00150 upvar 0 gas(grap) g gas(last) anchor
00151
00152 set arc [$g arc insert $anchor $to]
00153 $g arc set $arc condition $cond
00154 return
00155 }
00156
00157 ret ::grammar::me::cpu::gasm::/Label (type name) {
00158 variable gas
00159 set gas(_$name) $gas(last)
00160 return
00161 }
00162
00163 ret ::grammar::me::cpu::gasm::/Clear () {
00164 variable gas
00165 set gas(last) {}
00166 set gas(cond) always
00167 return
00168 }
00169
00170 ret ::grammar::me::cpu::gasm::/Ok () {
00171 variable gas
00172 set gas(cond) ok
00173 return
00174 }
00175
00176 ret ::grammar::me::cpu::gasm::/Fail () {
00177 variable gas
00178 set gas(cond) fail
00179 return
00180 }
00181
00182 ret ::grammar::me::cpu::gasm::/At (type name) {
00183 variable gas
00184 set gas(last) $gas(_$name)
00185 set gas(cond) always
00186 return
00187 }
00188
00189 ret ::grammar::me::cpu::gasm::/CloseLoop () {
00190 variable gas
00191 $gas(grap) node set $gas(last) LOOP .
00192 return
00193 }
00194
00195
00196
00197
00198 namespace grammar::me::cpu::gasm {
00199 namespace export begin done lift state state!
00200 namespace export Inline Cmd Bra Nop Note Jmp Exit Who
00201 namespace export /Label /Clear /Ok /Fail /At /CloseLoop
00202 }
00203
00204
00205
00206
00207 package provide grammar::me::cpu::gasm 0.1
00208