Kirjautuminen

Haku

Tehtävät

Koodivinkit: Brainfuck-tulkki QB:lle

Kirjoittaja: KemXy

Kirjoitettu: 23.10.2006 – 23.10.2006

Piti itselläkin väsätä jonkinlainen brainfuck-tulkki alkuksi C:lle, mutta toteutin yksinkertaisen version myös QBasicille.

Tulkki yrittää lukea oletuksena ohjelman tiedostosta 'ohjelma.txt', mutta pitäisi sen myös ottaa suoritettavan ohjelmatiedoston myös komentoriviparametrina.

Tein tuon melko pikaisesti ja väsyneenä, joten virheitä voi olla enkä ole jaksanut isommin testailla. Tuskin kovin suuria bf-ohjelmia tuolla voi tulkkailla. En ollutkaan pitkään pitkään aikaan koskenut mihinkään basiciin, joten en kaikkia hienouksia millään muista ja koodi voi siksi olla paikoin aika kankeaa.

No kuitenkin, tehkää tällä mitä lystäätte...

' Yksinkertainen QBasic-Brainfuck-tulkki
' Käyttö: Lukee oletuksena ohjelman tiedostosta ohjelma.txt
'         Suoritettavan ohjelman voi antaa myös komentoriviltä
'         (kun on ensin kääntänyt ohjelman) seuraavasti:
'         BF [ohjelma]
' Esim:   BF ohjelma2.txt
' Korjattavaa:
'         * mahdollisesti merkkien kysyminen
'         * tuki usealle tiedostolle

DECLARE SUB AjaOhjelma (ohjelma AS STRING)
DECLARE FUNCTION TarkistaOhjelma% (ohjelma AS STRING)
DECLARE FUNCTION LueTiedosto$ (tiedostonNimi AS STRING)
DECLARE SUB TulostaOhje ()
DECLARE FUNCTION KelpoMerkki% (merkki AS STRING)

DIM SHARED muisti(30000) AS INTEGER
DIM SHARED p AS INTEGER
DIM SHARED virhe AS INTEGER
DIM SHARED tulostepuskuri AS STRING

DIM tiedosto AS STRING
DIM ohjelma AS STRING
DIM krp AS STRING

ON ERROR GOTO Virheenkasittelija


tulostepuskuri = ""
p = 0
virhe = 0
tiedosto = "ohjelma.txt"


CLS

' Mahdollisen komentoriviparametrin lukeminen
IF COMMAND$ <> "" THEN tiedosto = COMMAND$

' Luetaan ohjelma tiedostosta
ohjelma = LueTiedosto(tiedosto)

' Tarkistetaan onko sulkuvirheitä
IF TarkistaOhjelma(ohjelma) <> 1 THEN
    PRINT "Virhe! Ohjelmassa " + tiedosto + " on syntaksivirhe!"
    END
END IF

' Suoritetaan ohjelma
AjaOhjelma (ohjelma)

'Lopetetaan
END


' Virheenkäsittelyä tiedoston lukemisen epäonnistumisen varalta.
Virheenkasittelija:

IF virhe = 1 THEN
    PRINT "Virhe! Tiedoston " + tiedosto + " lukeminen ei onnistunut."
    TulostaOhje
    END
ELSE
    PRINT "Virhe! Homma vaan kusee jossain!"
    TulostaOhje
    END
END IF
END

' Ajetaan parametrina annettu bf-ohjelma.
SUB AjaOhjelma (ohjelma AS STRING)

    DIM i AS INTEGER
    DIM sulut AS INTEGER
    DIM merkki AS STRING

    ' Nollataan muisti ja osoitin
    FOR i = 0 TO 29999
        muisti(i) = 0
    NEXT i
    p = 0

    i = 0
    sulut = 0

    ' Käydään ohjelma läpi nollamerkkiin asti.
    DO WHILE MID$(ohjelma, i + 1, 1) <> "0"
        SELECT CASE MID$(ohjelma, i + 1, 1)

            CASE "<": p = p - 1
            CASE ">": p = p + 1
            CASE "+": muisti(p) = muisti(p) + 1
            CASE "-": muisti(p) = muisti(p) - 1
            CASE ".":
                tulostepuskuri = tulostepuskuri + CHR$(muisti(p))
                CLS
                PRINT tulostepuskuri
            CASE ",":
                INPUT merkki
                muisti(p) = ASC(merkki)
            CASE "[":
                IF muisti(p) = 0 THEN
                    sulut = 1
                    DO WHILE sulut <> 0
                        i = i + 1
                        IF MID$(ohjelma, i + 1, 1) = "[" THEN sulut = sulut + 1
                        IF MID$(ohjelma, i + 1, 1) = "]" THEN sulut = sulut - 1
                    LOOP
                END IF
            CASE "]":
                IF muisti(p) <> 0 THEN
                    sulut = 1
                    DO WHILE sulut <> 0
                        i = i - 1
                        IF MID$(ohjelma, i + 1, 1) = "[" THEN sulut = sulut - 1
                        IF MID$(ohjelma, i + 1, 1) = "]" THEN sulut = sulut + 1
                    LOOP
                END IF
        END SELECT

        ' Seuraava kohta
        i = i + 1
    LOOP

END SUB

' Tarkistaa onko parametrina annettu merki bf-kieleen kuuluva.
' Palauttaa 1 jos kelpoinen, muutoin 0
FUNCTION KelpoMerkki% (merkki AS STRING)
    IF merkki = "<" OR merkki = ">" OR merkki = "+" OR merkki = "-" OR merkki = "." OR merkki = "," OR merkki = "[" OR merkki = "]" THEN
        KelpoMerkki% = 1
    ELSE
        KelpoMerkki% = 0
    END IF
END FUNCTION

' Lukee parametrina annetun tiedoston ja palauttaa siitä puretun ohjelman merkkijonona.
FUNCTION LueTiedosto$ (tiedostonNimi AS STRING)
    DIM rivi AS STRING
    DIM i AS INTEGER
    DIM ohj AS STRING
    DIM merkki AS STRING

    ' Asetetaan virhe-muuttuja, jotta virheen sattuessa osataan käsitellä se oikein.
    virhe = 1

    ' Tyhjennetään puskuri
    ohj = ""

    ' Avataan tiedosto ja luetaan viimeiseen merkkiin.
    OPEN tiedostonNimi FOR INPUT AS #1
    DO WHILE NOT EOF(1)
        LINE INPUT #1, rivi
        FOR i = 0 TO LEN(rivi) - 1
            ' Jos merkki on kelpoinen, lisätään se ohjelmaan.
            merkki = MID$(rivi, i + 1, 1)
            IF KelpoMerkki(merkki) = 1 THEN
                ohj = ohj + merkki
            END IF
        NEXT i
    LOOP

    ' Lisätään nolla loppuun merkkaamaan ohjelman loppua.
    ohj = ohj + "0"
    CLOSE #1
    LueTiedosto = ohj
    virhe = 0
END FUNCTION

' Tarkistaa ohjelman sulkuvirheiden varalta.
' Palauttaa 1 jos ohjelmassa ei virheitä, muutoin 0.
FUNCTION TarkistaOhjelma% (ohjelma AS STRING)
    DIM i AS INTEGER
    DIM merkki AS STRING
    DIM sulut AS INTEGER

    ' Käydään ohjelma läpi ja lasketaan sulut.
    sulut = 0
    FOR i = 0 TO LEN(ohjelma)
        IF MID$(ohjelma, i + 1, 1) = "[" THEN sulut = sulut + 1
        IF MID$(ohjelma, i + 1, 1) = "]" THEN sulut = sulut - 1
    NEXT i

    IF sulut <> 0 THEN
        TarkistaOhjelma = 0
    ELSE
        TarkistaOhjelma = 1
    END IF
END FUNCTION

SUB TulostaOhje
    PRINT "Brainfuck-tulkki v. 1.0 (Mika K. 2006)"
    PRINT "Toiminta: bf [ohjelma]"
END SUB

Kommentit

tgunner [24.10.2006 13:19:18]

Lainaa #

Jee, nyt löytyy sisennykset.

Juhko [27.10.2006 14:54:07]

Lainaa #

Itsekin olen tällaista suunnitellut, mutta kun en osaa :P

Dude [30.09.2007 10:13:46]

Lainaa #

Mitä brainfuckilla tekee? Tämä on mun eka viesti Puppy linuxilla.

Koodi123 [30.01.2019 16:24:02]

Lainaa #

Lisää tietoa Brainfuckista löytyy täältä ja Wikipediasta.

Kirjoita kommentti

Muista lukea kirjoitusohjeet.
Tietoa sivustosta