# -*- tcl -*- # ### ### ### ######### ######### ######### ## Package description ## (struct::)Graph based ME Assembler, for use in grammar ## translations. # ### ### ### ######### ######### ######### ## Requisites namespace eval grammar::me::cpu::gasm {} # ### ### ### ######### ######### ######### ## Implementation proc ::grammar::me::cpu::gasm::begin {g n {mode okfail} {note {}}} { variable gas array unset gas * # (Re)initialize the assmebler state, create the framework nodes # upon which we will hang all instructions on. set gas(mode) $mode set gas(node) $n set gas(grap) $g array set gas {last {} cond always} Nop $note ; /Label entry ; /Clear if {$mode eq "okfail"} { Nop Exit'OK ; /Label exit/ok ; /Clear Nop Exit'FAIL ; /Label exit/fail ; /Clear } elseif {$mode eq "halt"} { Cmd icf_halt ; /Label exit/return ; /Clear } else { Cmd icf_ntreturn ; /Label exit/return ; /Clear } /At entry return } proc ::grammar::me::cpu::gasm::done {__ t} { variable gas # Save the framework nodes in a grammar tree and shut the # assembler down. $t set $gas(node) gas::entry $gas(_entry) if {$gas(mode) eq "okfail"} { $t set $gas(node) gas::exit::ok $gas(_exit/ok) $t set $gas(node) gas::exit::fail $gas(_exit/fail) } else { $t set $gas(node) gas::exit $gas(_exit/return) } # Remember the node in the grammar tree which is responsible for # this entry point. $gas(grap) node set $gas(_entry) expr $gas(node) array unset gas * return } proc ::grammar::me::cpu::gasm::lift {t dst __ src} { $t set $dst gas::entry [$t get $src gas::entry] $t set $dst gas::exit::ok [$t get $src gas::exit::ok] $t set $dst gas::exit::fail [$t get $src gas::exit::fail] return } proc ::grammar::me::cpu::gasm::state {} { variable gas return [array get gas] } proc ::grammar::me::cpu::gasm::state! {s} { variable gas array set gas $s } proc ::grammar::me::cpu::gasm::Inline {t node label} { variable gas set gas(_${label}/entry) [$t get $node gas::entry] set gas(_${label}/exit/ok) [$t get $node gas::exit::ok] set gas(_${label}/exit/fail) [$t get $node gas::exit::fail] __Link $gas(_${label}/entry) $gas(cond) /At ${label}/exit/ok return } proc ::grammar::me::cpu::gasm::Cmd {cmd args} { variable gas # Add a new instruction, and link it to the anchor. The created # instruction becomes the new anchor. upvar 0 gas(grap) g gas(last) anchor gas(cond) cond set node [$g node insert] $g node set $node instruction $cmd $g node set $node arguments $args if {$anchor ne ""} {__Link $node $cond} set anchor $node set cond always return } proc ::grammar::me::cpu::gasm::Bra {} { Cmd .BRA } proc ::grammar::me::cpu::gasm::Nop {{text {}}} { Cmd .NOP $text } proc ::grammar::me::cpu::gasm::Note {text} { Cmd .C $text } proc ::grammar::me::cpu::gasm::Jmp {label} { variable gas __Link $gas(_$label) $gas(cond) return } proc ::grammar::me::cpu::gasm::Exit {} { variable gas if {$gas(mode) eq "okfail"} { __Link $gas(_exit/$gas(cond)) $gas(cond) } else { __Link $gas(_exit/return) always } return } proc ::grammar::me::cpu::gasm::Who {label} { variable gas return $gas(_$label) } proc ::grammar::me::cpu::gasm::__Link {to cond} { variable gas upvar 0 gas(grap) g gas(last) anchor set arc [$g arc insert $anchor $to] $g arc set $arc condition $cond return } proc ::grammar::me::cpu::gasm::/Label {name} { variable gas set gas(_$name) $gas(last) return } proc ::grammar::me::cpu::gasm::/Clear {} { variable gas set gas(last) {} set gas(cond) always return } proc ::grammar::me::cpu::gasm::/Ok {} { variable gas set gas(cond) ok return } proc ::grammar::me::cpu::gasm::/Fail {} { variable gas set gas(cond) fail return } proc ::grammar::me::cpu::gasm::/At {name} { variable gas set gas(last) $gas(_$name) set gas(cond) always return } proc ::grammar::me::cpu::gasm::/CloseLoop {} { variable gas $gas(grap) node set $gas(last) LOOP . return } # ### ### ### ######### ######### ######### ## Interfacing namespace eval grammar::me::cpu::gasm { namespace export begin done lift state state! namespace export Inline Cmd Bra Nop Note Jmp Exit Who namespace export /Label /Clear /Ok /Fail /At /CloseLoop } # ### ### ### ######### ######### ######### ## Ready package provide grammar::me::cpu::gasm 0.1