atarionline.pl ABC czyli Atari Basic Compiler - Forum Atarum

Jeśli chcesz wziąć udział w dyskusjach na forum - zaloguj się. Jeżeli nie masz loginu - poproś o członkostwo.

  • :
  • :

Vanilla 1.1.4 jest produktem Lussumo. Więcej informacji: Dokumentacja, Forum.

    • 1:
       
      CommentAuthormgr_inz_rafal
    • CommentTime12 Oct 2012 zmieniony
     
    Hej,
    Parę miesięcy temu, podczas pisania Biednego Psa Antoniego zakiełkowała we mnie myśl, żeby napisać kompilator Basica na PC. No i właśnie kilka(naście) ostatnich wieczorów spędziłem nad Flexem i Bisonem tworząc szkielet parsera oraz zalążek generatora kodu ASM.

    Działa to tak, że program wciąga listing w BASIC i wypluwa kod w .asm, który za pomocą MADS przerabiamy na .xex i odpalamy :)

    Co w bieżącej wersji:
    1. Obsługa wyrażeń arytmetycznych
    2. Obsługa "PRINT wyrażenie_arytmetyczne"
    3. Obsługa "GOTO wyrażenie_arytmetyczne"

    Czyli bez problemu skompilujemy sobie program w stylu:
    10 PRINT (2 + 3) * 4
    20 PRINT
    30 PRINT 1 + 2 + 3 * (4 + 5 + 6) / (444.3 + 0.0001)
    40 GOTO (5 + 5) * 2

    Wynik działania poniżej:


    Wszystkie obliczenia dokonywane są przez Atari - kompilator nic nie optymalizuje. Ogólnie to zacząłem od podejścia takiego, że parser dokonuje obliczeń, ale różnica w wynikach operacji na liczbach zmiennoprzecinkowych zmusiła mnie do zmiany drogi ze względu na chęć utrzymania maksymalnej kompatybilności z Atari Basic. Choć trochę szkoda, bo dawało to niezłego speeda, np. taka linijka:
    PRINT "4 + 12 * 4 * (3 + 13) = "; 4 + 12 * 4 * (3 + 13)

    powodowała, że w .xex lądował od razu string takiej postaci:
    dta c"4 + 12 * 4 * (3 + 13) = 772"

    A teraz w to miejsce wygeneruje się pełno kodu operującego na FR0 :(

    Mniejsza o to, kiedyś może będzie opcja wymuszenia działania na liczbach całkowitych dla programów, które nie korzystają z floating-point.

    Wątek zakładam z trzech powodów:
    1) Aby się pochwalić :>
    2) Aby mieć miejsce, gdzie będę zadawał dziwne pytania o to jak coś zrobić w ASM, jeśli nie znajdę tego w opisie procedur systemowych
    3) Aby poznać Waszą opinię na temat kompilatora (ale to już po tym, gdy będę miał coś, co nada się do opublikowania).

    Kolejny krok:
    Zmienne nietablicowe.
    • 2: CommentAuthorgorgh
    • CommentTime12 Oct 2012
     
    • 3: CommentAuthorbob_er
    • CommentTime12 Oct 2012
     
    A myślałeś nad tym, by na PC zapisywać kod basicowy w postaci stokenizowanej?
    Tudzież, by była to opcja.
    Choć w sposób asmowy (jaki masz obecnie), to może być dużo szybsze.
  1.  
    @bob_er
    Właściwie to nie. Od początku planowałem robić bezpośrednio asma.

    Nie znam nawet za bardzo tematu basicowego tokenizowania. Czy zapis listingu do pliku BAS to nie jest właśnie to?
    • 5:
       
      CommentAuthortdc
    • CommentTime12 Oct 2012 zmieniony
     
    Ogólnie fajnie, jak się postarasz to może to będzie dobry konkurent dla Action! :P
    (w sensie wydajności, bo procedur tu nie będzie i wielu innych cennych rzeczy)
    • 6:
       
      CommentAuthorpirx
    • CommentTime12 Oct 2012
     
    Zarąbiste!

    Czy celem jest kompilowanie starych programów w atari basic?

    Bo jeśli nie, to może warto zastanowić się nad porzuceniem nr linii, labelkami jak w TBXL, procedurami / funkcjami.

    W grach zmienny przecinek można wyeliminować / zasymulować na kilku intach a systemowe floaty są b. wolne - kompilacja dramatycznie nie poprawi sytuacji.

    Piszę to, bo chyba brakuje takiego języczka, w którym możnaby usiąść i w wieczór zakodować prototyp - miał być Atalan, ale jakoś nie wychodzi z wieku embrionalnego. CC65 to inna liga. Action! jest super, ale jak już się w nim długo siedzi i wie, co można a co nie.
    • 7:
       
      CommentAuthorxeen
    • CommentTime12 Oct 2012
     
    co znaczy : cc65 to inna liga?
    • 8:
       
      CommentAuthortdc
    • CommentTime12 Oct 2012
     
    @pirx, no i koniecznie niech procedury mają parametry bo w TBXL nie mają i sam na własnej skórze odczułem że to fatalny brak...
  2.  

    tdc:

    bo procedur tu nie będzie i wielu innych cennych rzeczy

    tdc:

    no i koniecznie niech procedury mają parametry
    Póki co, żeby nie paść ofiarą feature creep, celem jest kompatybilność tylko i wyłącznie z czystym Atari Basic.

    pirx:

    Czy celem jest kompilowanie starych programów w atari basic?
    Tak szczerze, to moim celem jest dobra zabawa przy tym projekcie :)

    pirx:

    Bo jeśli nie, to może warto zastanowić się nad porzuceniem nr linii, labelkami jak w TBXL, procedurami / funkcjami.
    Tak jak pisałem wyżej, na razie Atari Basic, żeby się nie zagrzebać. Zresztą, praktyka pokazuje, że jeśli zrobi się dobry szkielet kompilatora, to dodawanie kolejnych funkcji to raczej betka, no chyba, że myślimy np. o polimormiźmie, ale do tego nie zmierzam :) Jeśli starczy mi sił na dobrą implementację arytmetyki, tablic, ideksowania tablic dowolnymi wyrażeniami, to już potem można sobie mnożyć różne pętle, ify, elsy, procedury, labelki...

    pirx:

    W grach zmienny przecinek można wyeliminować / zasymulować na kilku intach a systemowe floaty są b. wolne - kompilacja dramatycznie nie poprawi sytuacji.
    No właśnie wiem, że obliczenia FP "ssają". Wstępnie myślałem, aby w przyszłości ukraść procedury FP z bodajże Turbo Basica - tam to działało chyba trochę szybciej. Ale fakt, symulacja na intach jest ciekawa - robiło się takie rzeczy w midletach na pierwsze telefony z Javą, bo tam wcale nie było float ;)

    Podsumowując: na razie małe kroczki i tylko Atari Basic. Pracy wbrew pozorom jest dużo, bo np. taki program jak powyżej generuje ok. 14 zmiennych tymczasowych, które na razie nie są optymalizowane i zaśmiecają pamięć "na zawsze". Z powodzeniem mógłbym przez weekend dorobić obsługę GRAPHICS, PLOT, DRAWTO, USR, itp. itd., ale najpierw chcę dopracować fundament.
    • 10:
       
      CommentAuthortdc
    • CommentTime12 Oct 2012
     
    Mną się nie przejmuj bo ja nie jestem zainteresowany praktycznym wykorzystaniem tego. Ale chętnie zobaczę jak działa, jakie ma osiągi oraz jak się temat będzie rozwijał.
  3.  

    tdc:

    Ale chętnie zobaczę jak działa, jakie ma osiągi
    Na pewno GOTO będzie szybsze ;-)
    • 12:
       
      CommentAuthorpirx
    • CommentTime13 Oct 2012
     
    >mgr_inz_rafal
    >Tak szczerze, to moim celem jest dobra zabawa przy tym projekcie :)

    I tak trzymaj, to najważniejsze!!!!!!!!11!!!oneone

    >xeen
    >co znaczy : cc65 to inna liga?

    10 K=5
    20 ?"Ala ma ";K;" kotow":K=K+1:G.20

    Nie mam zainstalowanego i skonfigurowanego CC65, a z palca nie napiszę wersji w tym języku, ale myślę, że widzisz, o co mi chodzi. By napisać programik tego rodzaju trzeba wiedzieć, jakie biblioteki załączyć, itp. Generalnie chodzi mi o otoczkę kodu, która jest ważna dla komputera, a nie dla człowieka. Atalan to ideał, bo w nim praktycznie każdy znak jest ważny dla człowieka. W BASICU numery linii są takim elementem wymuszonym przez maszynę.
    • 13:
       
      CommentAuthortdc
    • CommentTime14 Oct 2012
     
    @mgr_inz_rafal
    He he, a ile teraz czasu goto zajmuje? tak z ciekawości pytam, 5 ramek ?;)
    • 14:
       
      CommentAuthorxeen
    • CommentTime16 Oct 2012
     
    >10 K=5
    >20 ?"Ala ma ";K;" kotow":K=K+1:G.20

    >Nie mam zainstalowanego i skonfigurowanego CC65, a z >palca nie napiszę wersji w tym języku, ale myślę, że >widzisz, o co mi chodzi. By napisać programik tego >rodzaju trzeba wiedzieć, jakie biblioteki załączyć, itp. >Generalnie chodzi mi o otoczkę kodu, która jest ważna dla >komputera, a nie dla człowieka. Atalan to ideał, bo w nim >praktycznie każdy znak jest ważny dla człowieka. W BASICU >numery linii są takim elementem wymuszonym przez maszynę.

    generalnie się nie zgadzam, ale rozumiem o co Ci chodzi :)
    • 15: CommentAuthorilmenit
    • CommentTime17 Oct 2012 zmieniony
     
    10 K=5
    20 ?"Ala ma ";K;" kotow":K=K+1:G.20

    Nie mam zainstalowanego i skonfigurowanego CC65, a z palca nie napiszę wersji w tym języku, ale myślę, że widzisz, o co mi chodzi. By napisać programik tego rodzaju trzeba wiedzieć, jakie biblioteki załączyć, itp. Generalnie chodzi mi o otoczkę kodu, która jest ważna dla komputera, a nie dla człowieka. Atalan to ideał, bo w nim praktycznie każdy znak jest ważny dla człowieka. W BASICU numery linii są takim elementem wymuszonym przez maszynę.



    A tutaj trzeba wiedzieć, dlaczego znak zapytania wypisuje coś na ekran, jaka jest składnia języka, dlaczego łącznik jest za pomocą średnika, że dwukropek oddziela instrukcje, co znaczy G kropka.

    Nie wiem, czy to znacznie prostsze od:

    #include <stdio.h>

    void main(void)
    {
    int k=5;
    for(;;) printf("Ala ma %d kotow",k++);
    }

    W jednym i w drugim przypadku potrzebna jest podstawowa znajomość języka.
    • 16:
       
      CommentAuthorpirx
    • CommentTime17 Oct 2012 zmieniony
     
    Hej! Dla wyjaśnienia - ja wcale nie uważam, że CC65 jest niedobre, wręcz przeciwnie. Uważam tylko, że to znacznie bardziej skomplikowane (zaawansowane) narzędzie od BASICa. Coś jak piła łańcuchowa i siekiera. Ja akurat szukałem dla siebie takiego małego toporka :]

    Konkretnie z tego przykładu chodzi mi o początek:
    #include <stdio.h>
    void main(void)

    Taka rozbiegówka...

    Kuuurcze, może jednak wezmę piłę łańcuchową?
    • 17:
       
      CommentAuthormgr_inz_rafal
    • CommentTime19 Oct 2012 zmieniony
     
    Pytanie do znawców asemblera.

    Małe wprowadzenie: Każdą napotkaną w źródle liczbę muszę potraktować funkcją AFP, która wymaga tekstu ATASCII gdzieś w pamięci. Adres początku bufora należy wstawić do INBUFF.

    Moje pierwsze podejście było takie: Jak napotkasz liczbę, to dodaj taką linijkę (backslashe dodane przez Forum):
    fp75a dta c'444.3#'
    a gdzieś wcześniej:
    lda <fp75a
    sta INBUFF
    lda >fp75a
    sta INBUFF+1

    Wszystko oczywiście działa, ale pomyślałem naiwnie, że po co mi aż tyle linijek "dta" dla każdej liczby, skoro mogę zapisywać napotkane ATASCII do jakiegoś konkretnego, stałego bufora, np. od C0 do CA.
    Po krótkiej implementacji na jaw wyszła naiwność, bo proste "dta c'444.3#'" zamieniło mi się w 6 par LDA/STA, co pewnie zajmuje jeszcze więcej miejsca w .xex.

    Wróciłem więc do koncepcji pierwotnej, ale coś mi nie daje spokoju :) Konkretnie to, że AFP wykonuje się dość długo. Dlatego też - UWAGA - zadaję pytanie:
    1. Czy metoda z "dta -> sta INBUFF -> jsr AFP" jest Waszym zdaniem optymalna?

    I pytanie dodatkowe:
    1. Czy ktoś posiada może przypadkiem funkcję AFP przepisaną na C albo na jakiś pseudokod? :) Mógłbym wtedy 6 bajtów każdej liczby FP wyznaczać w czasie kompilacji.

    A na razie mam szatański plan, aby podczas kompilacji odpalać emulator z prostym xex-em, który obliczy mi to co chcę :>
    • 18: CommentAuthorrudla
    • CommentTime19 Oct 2012
     
    If you are using MADS, try using .FL directive.

    pi .fl 3.1415926535897932384626433832795 ; 40 03 14 15 92 65

    No additional conversion should be necessary, you may use FLD0R or FLD1R functions.
    • 19:
       
      CommentAuthormgr_inz_rafal
    • CommentTime19 Oct 2012 zmieniony
     
    @rudla
    Tchx, that looks like something I was looking for :) Will try the implementation in the evening.

    -----
    OK, tried it. Works perfect!
    • 20:
       
      CommentAuthormgr_inz_rafal
    • CommentTime23 Oct 2012 zmieniony
     
    Jest mały postęp, dodałem obsługę zmiennych liczbowych. Dzięki temu spokojnie kompilujemy taki kod:
    10 A = 3.4
    20 A = A + (A - (0.90 * A) / 17.54)
    30 PRINT A
    40 GOTO 20
    Efekt poniżej na obrazku.
    • 21: CommentAuthorLCD
    • CommentTime27 Oct 2012
     
    No niezle! Chcialem przypomniec ze Boriel zajmuje sie tez pisaniem kompilera BASICa który ma w przyszlosci obslugiwac Atari:
    ->link<-
    Jak na razie wersja dla ZX'a juz bardzo dobrze pracuje i powstalo kilka niezlych gier:
    ->link<-
  4.  

    LCD:

    Chcialem przypomniec ze Boriel zajmuje sie tez pisaniem kompilera BASICa
    Przypomnieć, a właściwie to uświadomić :) Nie wiedziałem wcześniej o tym projekcie.

    Szczerze mówiąc, to nawet nie próbowałem badać tematu - po prostu zacząłem sobie od nowa :) Ale Wiki Boriela chętnie poczytam.
    • 23:
       
      CommentAuthormgr_inz_rafal
    • CommentTime27 Oct 2012 zmieniony
     
    A tak na marginesie... Poniżej efekt uruchomienia programu z postu #20 w BASICu. Liczby są przycięte do 10 znaków.

    Z jednej strony chciałbym być maksymalnie kompatybilny z BASIC, a z drugiej szkoda mi sztucznie ograniczać mojego PRINTa. Czy ktoś zna jakieś uzasadnienie, dlaczego BASIC tak przycina liczby?
    • 24: CommentAuthorwieczor
    • CommentTime27 Oct 2012
     
    A nie zauważyłeś nic charakterystycznego zwłaszcza po wypisaniu ich na ekranie? :) Wszystkie mają max 10 znaków :)
    • 25: CommentAuthorrudla
    • CommentTime27 Oct 2012
     
    It's hard to know for sure, but if the routine does rounding (not just ignores last digit), it would probably hide some computation inaccuracies from user.
    • 26:
       
      CommentAuthormgr_inz_rafal
    • CommentTime27 Oct 2012 zmieniony
     
    @wieczór
    Zauważyłem - i dlatego właśnie pytam :) Czy ograniczenie do 10 znaków ma jakiś ukryty sens, czy po prostu komuś tak się podobało.

    Zastanawiam się, czy też powinienem tak przycinać? I pewnie będę musiał, bo przypuszczam, że istnieją gry/programy w BASIC, które korzystają z tej, nazwijmy to, cechy.

    @rudla
    It seems that computation is done correctly, since the numbers in both programs (ASM and BASIC) are equal after several iterations. The console output in BASIC seems to be limited to 10 chars, however.
    • 27: CommentAuthormono
    • CommentTime27 Oct 2012
     
    ->link<- sekcja "Format liczb zmiennoprzecinkowych".
  5.  
    Czy Atari Basic zeruje pamieć przydzielaną na tablice przez DIM/COM? Z doświadczenia wynika, że niezainicjowana tablica to same zera, ale wolę dopytać :)
    • 29: CommentAuthormono
    • CommentTime31 Oct 2012
     
    Nie zeruje. Prosty test:
    DIM T$(20):T$(20)="":? T$

    pokaże cały śmietnik.
    Oczywiście jeśli zrobisz to na świeżo włączonym atari, jako pierwsze polecenie (os zeruje pamięć podczas zimnego startu), możesz dostać same zera w stringu, ale to o niczym nie świadczy.
    Drugi test:
    DIM T$(50):T$="ALA MA KOTA A KOT MA ALE":NEW
    DIM T(20):? T(0)

    pokaże już śmieci, bo wcześniej w miejscu tablicy numerycznej znajdował się string.
  6.  
    Super, dzięki.
    To oszczędzi mi parę cykli :)
    • 31:
       
      CommentAuthormgr_inz_rafal
    • CommentTime31 Oct 2012 zmieniony
     
    OK, uwinąłem się trochę z tymi tablicami i mam świeży, wieczorny wypiek :)

    Można już kompilować coś takiego:
    10 X = 1000
    20 Y = 10
    30 DIM ARR(X / Y)
    40 ARR(50 + 50) = 666
    50 BAR = 25
    60 PRINT ARR(BAR * 4)


    Wynik:
    • 32:
       
      CommentAuthorxeen
    • CommentTime31 Oct 2012
     
    awsome!
    • 33:
       
      CommentAuthormgr_inz_rafal
    • CommentTime31 Oct 2012 zmieniony
     
    Dobra, to wrzucam jeszcze jeden update i idę szykować znicze :)

    Można już sobie zagnieżdżać tablice w wyrażeniach arytmetycznych, razem ze zmiennymi i stałymi, np.:
    5 DIM C(100)
    6 DUPA = 9
    10 DIM A(10)
    20 DIM B(10)
    21 B(2) = 3
    22 B(9) = 100 - (101 - B(2))
    23 C(66) = 5
    25 PRZEMYSLAW = DUPA - 7
    30 A(C(66)) = 10
    40 B(A(2 + B(B(B(B(PRZEMYSLAW) - 1) * B(B(DUPA)))))) = 666
    50 PRINT B(A(C(66))) / (B(2) - 1)


    I wynik:


    PS. Następny krok to trochę optymalizacji, bo mi się .xex za duży generuje. A potem wyrażenia warunkowe na liczbach, co pozwoli na zaprogramowanie prostych pętli i myślę, że będę mógł opublikować jakąś bardzo pierwszą wersję compilera.
    • 34: CommentAuthormono
    • CommentTime31 Oct 2012 zmieniony
     
    Zerknij może na to: ->link<- bo się okaże, że programy po kompilacji nie działają "poprawnie" :P
    Szczególnie polecam 1^44 i 2^44 oraz CHR$(34)=CHR$(35) (identycznie jest oidp z STR$).
  7.  
    Dzięki mono za czujność. Jak wiadomo, diabeł tkwi w szczegółach :)

    Potęgowanie zrobię za pomocą OS, więc będzie działać tak samo "dobrze" jak w Atari Basic.

    Natomiast o porównywaniu CHR$ nie wiedziałem, więc pewnie potrzebna będzie jakaś opcja kompilacji typu "--keep-bugs-for-compatibility" :)
    • 36:
       
      CommentAuthorjhusak
    • CommentTime1 Nov 2012
     
    Staję w obronie wszystkich Przemysławów!
    • 37:
       
      CommentAuthorjhusak
    • CommentTime1 Nov 2012 zmieniony
     
    Tak nawiasem mówiąc, to zbytnie rozrastanie się kodu pod 6502 to powszechna bolączka wszelkich kompilatorów, dlatego tak popularne są interpretery na ten procesor. Składnia i bajtkody rozpoznawane podczas wprowadzania kodu, potem już czysta interpretacja odpowiednich kodów.

    Narzut wbrew pozorom akceptowalny, a jakie długie programy można pisać :)

    Szczytem jest intepreter stosowany w SO i Basic wczesnych komputerów Apple: ->link<-

    Dla 6502, aby uzyskać sensowny kod wynikowy, trzeba mieć język, który łatwo wpisuje się w ten model.

    Polecam świetny artykuł - spis: ->link<-
    • 38: CommentAuthormono
    • CommentTime2 Nov 2012
     
    ? ASC("")
  8.  
    @jhusak
    Fakt, trochę RISCowy ten 6502... Mogli się pokusić chociażby o obsługę MOV :)

    Ale na chwilę obecną wydaje mi się, że rozrastanie da się opanować. Kod asemblerowy najbardziej rośnie w takich testowych programach, jak zaprezentowałem parę postów wyżej - na co dzień (dobry) programista raczej nie pisze takich kwasów. Zresztą już teraz widzę i przeczuwam, że wielkość będę mógł ściąć ~4 krotnie tworząc procedury i robiąc JSR, a nie po prostu sadzić powtarzające się ciągi LDA/STA/LDA/STA.

    Polecenia typu POKE, GRAPHICS, PLOT, SOUND raczej wiele asemblera nie wygenerują.
    • 40: CommentAuthorbob_er
    • CommentTime3 Nov 2012
     
    ale drawto może :)
    właśnie - zrobisz swojego drawa i plota (szybszego) czy oprzesz się na systemowym?
  9.  
    @bob_er
    A nie ma gdzieś tam w OS gotowego DRAWTO? :)

    Na początek chcę tylko w miarę dobrze odwzorować BASIC, później będę chciał optymalizować to co się da, np. obliczenia FP czy też inne funkcje, dla których przez 40 lat powstały lepsze odpowiedniki niż te w Atari OS.
    • 42: CommentAuthormono
    • CommentTime7 Nov 2012
     
    • 43:
       
      CommentAuthorMaW
    • CommentTime7 Nov 2012
     
    XIO #18 ?
  10.  
    Dzięki za info i linki. Jak już dojdę do grafiki, to pewnie zacznę dalej drążyć temat.
  11.  
    Ale, póki co... Pod "nieobecność" AtariOnline.pl dorobiłem do kompilatora instrukcję warunkową (IF...THEN) i pojawił mi się problem z "branch out of range".

    Jakiś czas temu w wątku o Biednym Psie mono podsunął mi rozwiązanie:

    mono:

    Zamiast beq,bpl,bcc,itd. używaj odpowiednich makr jeq,jpl,jcc,itd. To zrobi kod (np. dla jeq gdzieśtam):
    bne *+5
    jmp gdzieśtam


    W imię zasady, że chcę rozumieć to co piszę, prosiłbym o wyjaśnienie o co chodzi z tą gwiazdką przy bne i dlaczego +5?
    • 46: CommentAuthormono
    • CommentTime7 Nov 2012
     
    * oznacza bieżący pc, czyli miejsce ulokowania bne. a +5 ponieważ bne na 2 bajty, a jmp 3. Polecam gorąco tabelki na końcu ->link<-
    • 47:
       
      CommentAuthormgr_inz_rafal
    • CommentTime9 Nov 2012 zmieniony
     
    JEQ spisuje się świetnie. Tzn. trochę dostałem rykoszetem, bo MADS jeśli może to generuje krótki skok, a jeśli nie może to długi. A muszę dokładnie wiedzieć jakie są adresy poszczególnych linijek w ASM (tzn. wiedzieć, jaki skok wygeneruje JEQ), żeby móc kompilować GOTO bez dodatkowego przebiegu... Stosunkowo trudno było to obliczyć w czasie kompilacji, dlatego na razie zawsze sadzę BNE *+5, żeby mieć pewność, że na skoki zjadam stałą liczbę bajtów.

    W każdym bądź razie oto efekt ostatnich paru dni spędzonych nad obsługą wyrażeń warunkowych.

    Program #1 - różne kombinacje większości, mniejszości, itp.:
    5 DIM KONGO(30)
    6 KONGO(20) = 3
    10 IF KONGO(20) - 1 < KONGO(10 + 2 * 5) THEN PRINT KONGO(20) - 2
    20 IF 2 < 2 THEN PRINT 2
    30 IF 2 < 1 THEN PRINT 3
    40 IF 2 > 3 THEN PRINT 4
    50 IF 2 > 2 THEN PRINT 5
    60 IF 2 > 1 THEN PRINT 6
    70 IF 2 >= 3 THEN PRINT 7
    80 IF 2 >= 2 THEN PRINT 8
    90 IF 2 >= 1 THEN PRINT 9
    100 IF 2 <= 3 THEN PRINT 10
    110 IF 2 <= 2 THEN PRINT 11
    120 IF 2 <= 1 THEN PRINT 12
    130 IF 2 = 3 THEN PRINT 13
    140 IF 2 = 2 THEN PRINT 14
    150 IF 2 = 1 THEN PRINT 15
    160 IF 2 <> 3 THEN PRINT 16
    170 IF 2 <> 2 THEN PRINT 17
    180 IF 2 <> 1 THEN PRINT 18
    200 GOTO 10
    1000 PRINT 666

    Myk z KONGO() wprowadzony po to, aby sprowokować konieczność długiego skoku.

    Wynik:


    Program #2 - IFy zagnieżdżone:
    10 KASZANKA = 100
    20 WIDELEC = 200
    30 PRINT WIDELEC
    40 IF KASZANKA > 10 THEN IF WIDELEC > 10 THEN WIDELEC = 2
    50 PRINT WIDELEC
    60 IF KASZANKA > 10 THEN IF WIDELEC > 10 THEN WIDELEC = 666
    70 PRINT WIDELEC


    Wynik:


    No i program #3 pokazujący, że już tylko mały kroczek dzieli nas od prawdziwego FORa :)
    10 MACIEREWICZ = 2
    20 PRINT MACIEREWICZ
    30 MACIEREWICZ = MACIEREWICZ + 3
    40 IF MACIEREWICZ < 31 THEN GOTO 20


    Wynik:


    A teraz dobranoc, idę pograć w Tappera ;)
    • 48:
       
      CommentAuthormgr_inz_rafal
    • CommentTime13 Nov 2012 zmieniony
     
    Dziś mam pytanie do ludzi doświadczonych w Atari Basic...

    ...OK, sorry, nie było pytania - już czaję :)

    Pętle dostępne wkrótce :)
    • 49:
       
      CommentAuthorpirx
    • CommentTime13 Nov 2012
     
    >A muszę dokładnie wiedzieć jakie są adresy poszczególnych linijek w ASM (tzn. wiedzieć, jaki skok wygeneruje JEQ), żeby móc kompilować GOTO bez dodatkowego przebiegu...

    Hej! Ale po co znać adres? Nie lepiej byłoby skakać do labelki w rodzaju
    line100
    line110
    line120
    line130
    jeśli miałoby być tak bardzo basicowo?
  12.  
    @pirx
    Spoko, już temat ogarnąłem w taki właśnie sposób. Skok do następnej linijki (jeśli IF nie jest spełniony) jest robiony po labelce.

    Niestety to rozwiązanie nie działa dla wyrażeń (np. GOTO X * 10), bo ich wartość nie jest znana w czasie kompilacji i nie wiadomo do jakiej labelki zrobić JMP. Dlatego też zwykłe GOTO musiałem trochę bardziej zakombinować.