User:Marinus/Brainfuck interpreters
Jump to navigation
Jump to search
These are some Brainfuck implementations that I wrote in various esoteric languages. All of them have unlimited memory (i.e. not constrained by the interpreter itself), and they all use the same input rules as DBFI, i.e. <program>!<input>.
DUP
(cells the size of the DUP implementation's cells)
[ i;;'+=[ m;;1+m;: ][ i;;'-=[ m;;1-m;: ][ i;;'>=[ m;1+m: ][ i;;'<=[ m;1-m: ][ i;;'.=[ m;;, ][ i;;',=[ `m;: ][ i;;91=[ m;;0=[ 1d: i;1+i: [d;][ i;;91=[ d;1+d: ][i;;93=[ d;1-d: ][]?]? i;1+i: ]# i;1-i: ][]? ][ i;;93=[ m;;[ 1d: i;1-i: [d;][ i;;93=[ d;1+d: ][i;;91=[ d;1-d: ][]?]? i;1-i: ]# i;1+i: ][]? ] []?]?]?]?]?]?]?]? i;1+i: ]s: 0i:[i;1-;'!=0=][`i;:i;1+i:]# i;1+m:0i:[i;;][s;!]#
Gibberish
(infinitely large cells)
[0gt1[eucuy91afd]gw0] 1[ en u[+]0gc fq nt[gb[g0p1pce1agt1pf2pgrb]ecgb]c eu[-]0gc fq nt[gb[g0p1pce1sgt1pf2pgrb]ecgb]c eu[<]0gc fq nt[gb[e1s]ecgb]c eu[>]0gc fq nt[gb[e1ag1p0peyfdt[gb0t1[eucuy91afd]gwecgb]c]ecgb]c eu[.]0gc fq nt[gb[g0p1pcteq]ecgb]c eu[,]0gc fq nt[gb[gb0pengtrb]ecgb]c eu 91a9m1a fq nt[gb[g0p1pcf0qn]ec91a9m1agtecgb]c eu 91a9m3a fq nt[gb[g0p1pcf0qn]ec91a9m3agtec[gw]cgb]c [!]0gc fqn ]gw fc
HaPyLi
(cells the size of the Whitespace implementation's cells)
import "stdlib/base.hpl" def read-pgm(*buffer) = (if (== (read-char *buffer) '!') (set *buffer 0) (++ (read-pgm (++ *buffer)))) def inline read-pgm() = (alloc (++ (read-pgm (ref 0)))) var mp = 0 var memsize = 0 def inline getmem(addr) = (ref (ref 0) addr) def inline setmem(addr val) = (set (ref 0) addr val) def inline left() = (set mp (-- (ref mp))) def inline right() = (do (set mp (++ (ref mp))) (if (>= (ref mp) (ref memsize)) (do (set memsize (++ (ref memsize))) (setmem (ref mp) 0)) 0)) def inline inc() = (setmem (ref mp) (++ (getmem (ref mp)))) def inline dec() = (setmem (ref mp) (-- (getmem (ref mp)))) def inline inp() = (setmem (ref mp) (read-char)) def inline out() = (print-char (getmem (ref mp))) var program = 0 var ip = 0 def inline readpgm() = (set program (read-pgm)) def loopahead(depth) = let curchr = (ref (ref program) (++ (ref ip))) in (if (== depth 0) 0 (do (set ip (++ (ref ip))) (if (== curchr '[') (loopahead (++ depth)) (if (== curchr ']') (loopahead (-- depth)) (loopahead depth))))) def loopback(depth) = let curchr = (ref (ref program) (-- (ref ip))) in (if (== depth 0) 0 (do (set ip (-- (ref ip))) (if (== curchr '[') (loopback (-- depth)) (if (== curchr ']') (loopback (++ depth)) (loopback depth))))) def inline step() = let curchr = (ref (ref program) (ref ip)) in (do (if (== curchr '+') (inc) (if (== curchr '-') (dec) (if (== curchr '>') (right) (if (== curchr '<') (left) (if (== curchr '.') (out) (if (== curchr ',') (inp) (if (and (== curchr '[') (== 0 (getmem (ref mp)))) (loopahead 1) (if (and (== curchr ']') (!= 0 (getmem (ref mp)))) (loopback 1) (if (== curchr 0) (end) 0)))))))))) def run() = (do (step) (set ip (++ (ref ip))) (run)) def main() = (do (readpgm) (run))
Pointy
(8-bit cells)
;;; Brainfuck interpreter in Pointy ;;; 8 bit cells. [0-255] ;;; Input format: program!input ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CPY 0 0 ; Zero cell for unconditional jump ; Read program upto ! ; Program storage: 10.... CPY 10 2 ; Program starts at cell #10 LBL readcmd INP 1 ; if character=!, stop reading CPY *1 4 CPY 33 5 LBL check_end DEC 4 maybe_end DEC 5 store_char DEC 0 check_end LBL maybe_end DEC 5 read_done LBL store_char ; figure out which command it is, then store it ; 0=end 1=+ 2=- 3=< 4=> 5=, 6=. 7=[ 8=] ; +? CPY *1 4 CPY 43 5 ; 43=+ LBL check_inc DEC 4 maybe_inc DEC 5 not_inc DEC 0 check_inc LBL maybe_inc DEC 5 store_inc LBL not_inc ; -? CPY *1 4 CPY 45 5 ; 45=- LBL check_dec DEC 4 maybe_dec DEC 5 not_dec DEC 0 check_dec LBL maybe_dec DEC 5 store_dec LBL not_dec ; >? CPY *1 4 CPY 62 5 ; 62=> LBL check_next DEC 4 maybe_next DEC 5 not_next DEC 0 check_next LBL maybe_next DEC 5 store_next LBL not_next ; <? CPY *1 4 CPY 60 5 ; 60=< LBL check_prev DEC 4 maybe_prev DEC 5 not_prev DEC 0 check_prev LBL maybe_prev DEC 5 store_prev LBL not_prev ; ,? CPY *1 4 CPY 44 5 ; 44=, LBL check_inp DEC 4 maybe_inp DEC 5 not_inp DEC 0 check_inp LBL maybe_inp DEC 5 store_inp LBL not_inp ; .? CPY *1 4 CPY 46 5 ; 46=. LBL check_out DEC 4 maybe_out DEC 5 not_out DEC 0 check_out LBL maybe_out DEC 5 store_out LBL not_out ; [? CPY *1 4 CPY 91 5 ; 91=[ LBL check_loopbegin DEC 4 maybe_loopbegin DEC 5 not_loopbegin DEC 0 check_loopbegin LBL maybe_loopbegin DEC 5 store_loopbegin LBL not_loopbegin ; ]? CPY *1 4 CPY 93 5 ; 93=] LBL check_loopend DEC 4 maybe_loopend DEC 5 not_loopend DEC 0 check_loopend LBL maybe_loopend DEC 5 store_loopend LBL not_loopend ; it is apparently not a command, so skip it and read the next one DEC 0 readcmd ; store commands in memory LBL store_inc CPY 1 *2 DEC 0 store_done LBL store_dec CPY 2 *2 DEC 0 store_done LBL store_prev CPY 3 *2 DEC 0 store_done LBL store_next CPY 4 *2 DEC 0 store_done LBL store_inp CPY 5 *2 DEC 0 store_done LBL store_out CPY 6 *2 DEC 0 store_done LBL store_loopbegin CPY 7 *2 DEC 0 store_done LBL store_loopend CPY 8 *2 LBL store_done ; read next command INC 2 DEC 0 readcmd LBL read_done ; reached the end of the commands ; store end-of-program, 2 is now MP CPY 0 *2 INC 2 CPY 10 3 ; 3 = IP ; run current command LBL step CPY **3 4 DEC 4 end ; 0 DEC 4 do_inc ; 1 DEC 4 do_dec ; 2 DEC 4 do_prev ; 3 DEC 4 do_next ; 4 DEC 4 do_inp ; 5 DEC 4 do_out ; 6 DEC 4 do_loopbegin ; 7 DEC 4 do_loopend ; 8 LBL step_end INC 3 DEC 0 step ; + LBL do_inc ; increase, if = 256 then set to zero INC *2 CPY **2 4 CPY 256 5 LBL check_overflow DEC 4 maybe_overflow DEC 5 step_end DEC 0 check_overflow LBL maybe_overflow DEC 5 handle_overflow DEC 0 step_end LBL handle_overflow CPY 0 *2 ; set to zero DEC 0 step_end ; - LBL do_dec ; decrease, if already zero then set to 255 DEC *2 handle_underflow DEC 0 step_end LBL handle_underflow CPY 255 *2 DEC 0 step_end ; < LBL do_prev DEC 2 mem_underflow DEC 0 step_end ; > LBL do_next INC 2 DEC 0 step_end ; , LBL do_inp INP *2 DEC 0 step_end ; . LBL do_out OUT **2 DEC 0 step_end ; [ LBL do_loopbegin ; don't jump if not zero CPY **2 4 DEC 4 mem_zero DEC 0 step_end LBL mem_zero ; find matching ] CPY 0 6 ; 6 = depth LBL loop_scan_ahead INC 3 ; ip++ ; if [ (7) increase depth CPY **3 4 CPY 7 5 LBL loopfwd_check_inc DEC 4 loopfwd_maybe_inc DEC 5 loopfwd_no_inc DEC 0 loopfwd_check_inc LBL loopfwd_maybe_inc DEC 5 loopfwd_inc LBL loopfwd_no_inc ; if ] (8) decrease depth CPY **3 4 CPY 8 5 LBL loopfwd_check_dec DEC 4 loopfwd_maybe_dec DEC 5 loopfwd_no_dec DEC 0 loopfwd_check_dec LBL loopfwd_maybe_dec DEC 5 loopfwd_dec LBL loopfwd_no_dec ; it is neither try next one DEC 0 loop_scan_ahead ; increase depth LBL loopfwd_inc INC 6 DEC 0 loop_scan_ahead ; decrease depth, jump back into main routine if 0 LBL loopfwd_dec DEC 6 step_end DEC 0 loop_scan_ahead ; [ LBL do_loopend ; only jump if not zero CPY **2 4 DEC 4 step_end ; find matching [ CPY 0 6 ; 6 = depth LBL loop_scan_back DEC 3 ip_underflow ; if ] (8) increase depth CPY **3 4 CPY 8 5 LBL loopback_check_inc DEC 4 loopback_maybe_inc DEC 5 loopback_no_inc DEC 0 loopback_check_inc LBL loopback_maybe_inc DEC 5 loopback_inc LBL loopback_no_inc ; if [ (7) decrease depth CPY **3 4 CPY 7 5 LBL loopback_check_dec DEC 4 loopback_maybe_dec DEC 5 loopback_no_dec DEC 0 loopback_check_dec LBL loopback_maybe_dec DEC 5 loopback_dec LBL loopback_no_dec ; neither, try previous one DEC 0 loop_scan_back ; increase depth LBL loopback_inc INC 6 DEC 0 loop_scan_back ; decrease depth, jump back into main routine if 0 LBL loopback_dec DEC 6 step_end DEC 0 loop_scan_ahead LBL ip_underflow OUT 73 DEC 0 underflow LBL mem_underflow OUT 77 LBL underflow OUT 80 OUT 60 OUT 48 OUT 10 LBL end
SADOL
(8-bit cells)
:p$0:z;0@=0=z"1!(2]pz:z;0:m$10:i0:j0@-#p-01i(2 ?=#pi"1+:#mj%+#mj1,3256?=#pi"1-:#mj%-#mj1,3256 ?=#pi"1<:j-j1?=#pi"1>(2:j+j1?=0<j#m-01]m00?=#p i"1,:#mj'1;0?=#pi"1.!'2#mj?&=0#mj=#pi"1[(4:d1: i+i1@d(2?=#pi"1[:d+d1?=#pi"1]:d-d10:i+i1:i-i1? &=0=0#mj=#pi"1](4:d1:i-i1@d(2?=#pi"1[:d-d1?=#p i"1]:d+d10:i-i1:i+i10:i+i1
Unreadable
(infinitely large cells)
'""""'""""'""""""'""'"""'""'""'""'""'""'""'""'""'""'"""'""""'""""""'"""'""""""""""'"""""'""""""""'"" """"""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""" """""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"""" """"'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"""""""'"""'"" ""'""""""'"""""""'""'"""'"""""""'"""'""""'""""""'""'"""'""'"""""""'""'"""'""""""'"""'""""""""""'"""" '""""""'""'""'""'"""'""'"""""""'""'"""'""""'""""""'""'""'"""'""'""'""'""'""'""'""'""'""'"""'"""""'"" """""'"""""""'""'""'"""'""""'""""""'""'""'""'""'"""'"""""""'"""""""'""'""'"""'""""'"""""""""'""""""" "'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"""""""" '""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""' """"""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'" """""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"""""""'""'""'""'""' """'"""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""" """'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"""""" ""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""" "'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"""""""" '""""""""'""""""""'"""""""'""'""'""'""'"""'"""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"" """"""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""" """""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"""" """"'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""" """'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"""""" ""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""" "'""""""""'"""""""'""'""'""'""'"""'"""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'" """""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"" """"""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""" """""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"""" """"'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""" """'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"""""""'""'""'" "'""'"""'"""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""' """"""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'" """""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"" """"""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""" """""'""""""""'"""""""'""'""'""'""'"""'"""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"""""" ""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""" "'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"""""""" '""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""' """"""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"""""""'""'""'""'""'"""'"""""""""'""" """""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"""" """"'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""" """'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"""""" ""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""" "'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"""""""" '""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""' """"""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'" """""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"" """"""'""""""""'"""""""'""'""'""'""'"""'"""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""" """'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"""""" ""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""" "'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"""""""" '""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""' """"""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'" """""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"" """"""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""" """""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"""""""'""'"" '""'""'"""'"""'"""""""""'"""""""'"""""""'""'""'""'"""'""""'""""""'""'""'""'""'""'"""'"""'"""""'""""" ""'""'""'""'""'""'"""'""""'""""""'""'""'"""'""""""""'"""""""'""'""'"""'""""'""""""'""'""'""'""'"""'" """"""'"""""""'""'""'"""'"""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"" """"""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""" """""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"""" """"'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""" """'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"""""" ""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""" "'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"""""""" '""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""' """"""""'""""""""'""""""""'""""""""'""""""""'""""""""'"""""""'""'""'""'""'"""'"""""""""'""""""""'""" """""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"""" """"'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""" """'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"""""" ""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""" "'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"""""""" '""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""' """"""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'" """""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"" """"""'""""""""'""""""""'"""""""'""'""'""'""'"""'"""'""""""'""'""'""'""'""'"""'""'"""""""'""'""'""'" "'""'"""'""""""'""'""'""'""'""'"""'""""""""'"""""""'""'""'""'""'""'"""'"""'"""""""""'"""""""'""""""" '""'""'""'"""'"""'""""'""""""'""'""'""'""'""'"""'"""'"""""'"""""""'""'""'""'""'""'"""'""""'""""""'"" '""'"""'""'"""""""'""'""'"""'""""'""""""'""'""'""'""'"""'"""""""'"""""""'""'""'"""'"""""""""'""""""" "'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"""""""" '""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""' """"""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'" """""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"" """"""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""" """""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"""" """"'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""" """'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"""""" ""'""""""""'"""""""'""'""'""'""'"""'"""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""' """"""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'" """""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"" """"""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""" """""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"""" """"'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""" """'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"""""" ""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""" "'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'""""""""'"""""""'""'""'""' ""'"""'"""'""""""'""'""'""'""'""'"""'""""""""'"""""""'""'""'""'""'""'"""'""""""'""'""'""'""'""'"""'" "'"""""""'""'""'""'""'""'"""'"'"""""""'"""""""'""'""'""'"""'""""""'"""""""'""'""'""'"""'""""""""""'" """""'""'""'""'"""'""""""""'"""""""'""'""'""'"""'""""""'""'""'""'"""'""'"""""""'""'""'""'"""'""""""' """""""'""'""'""'"""'""""""""'"""""""'"""""""'""'""'""'"""'""""""'"""""""'""'""'""'"""'""'"""""""'"" """""'""'""'""'"""'""""""'""'""'"""'""'"""""""'""'""'"""