Hobby Basic, ένας μικρός διερμηνευτής για την κονσόλα των Windows

Η επερχόμενη έκδοση 2.4.1 της Hobby BASIC ενισχύει τον continuation character, τον χαρακτήρα backslash (\), προσθέτοντας νέες δυνατότητες. Αυτή η φαινομενικά μικρή αλλά σημαντική επέκταση διαμορφώνει ριζικά τη σύνταξη της Hobby BASIC από εδώ και πέρα.

Παράδειγμα continuation character πριν την έκδοση 2.4.1:


Κώδικας:
print \
"hello"
Ισοδύναμο με: print "hello"

Ο περιορισμός στην προηγούμενη έκδοση:

Η γραμμή αμέσως μετά τον χαρακτήρα \ δεν μπορούσε να είναι κενή ούτε να περιέχει σχόλια - έπρεπε να συνεχίζει απευθείας την εντολή.

Παραδείγματα που προκαλούν σφάλμα σύνταξης:
Κώδικας:
print \
     ← κενή γραμμή
"hello"

Κώδικας:
print \
! Αυτό είναι σχόλιο
"hello"
Και τα δύο ισοδύναμα με: Syntax Error

Δεν είχα προβλέψει αυτή τη σύνταξη, παρόλο που είναι απολύτως λογική και αναμενόμενη από τους χρήστες.

Η νέα έκδοση 2.4.1 διορθώνει αυτή την παράλειψη. Ας δούμε το παράδειγμα ξανά:
Κώδικας:
print \            ! Συνέχιση στην επόμενη γραμμή
                   ! <-- Αυτό το κενό επιτρέπεται τώρα στην 2.4.1
"Καλημέρα κόσμε"   ! Η εντολή ολοκληρώνεται εδώ

Η διαφορά είναι σημαντική: προσφέρει μεγαλύτερη ευελιξία στον κώδικα και, κατ' επέκταση, στον προγραμματιστή, ενώ ταυτόχρονα βελτιώνει την αναγνωσιμότητα.


Line Continuation Support για την εντολή TIMES!


Η εντολή TIMES:
• Εκτελεί εντολές πολλές φορές σε μία γραμμή
• Χρησιμοποιεί τη μεταβλητή V3 ως μετρητή (zero-based: 0 έως n-1)
• Δέχεται πολλαπλές εντολές χωρισμένες με άνω κάτω τελεία :
• Κάνει inline loops χωρίς να χρειάζεται ξεχωριστή γραμμή για FOR/NEXT

Παράδειγμα:
Κώδικας:
times repeatCount  swap 0, 0, 80, 11, 0, 12 : title repeatCount-V3 : wait 120

Το παραπάνω ισοδυναμεί με:
Κώδικας:
FOR i = 0 TO repeatCount-1
    swap 0, 0, 80, 11, 0, 12
    title repeatCount-i
    wait 120
NEXT i

H TIMES δεν υποστήριζε continuation character. Με την έκδοση 2.4.1 μπορούμε να σπάμε τα loops σε πολλές γραμμές χρησιμοποιώντας τον χαρακτήρα backslash (\) !

Παλιά σύνταξη (έως 2.4.0):
Κώδικας:
times 10 print "Hello" : print "World" : wait 100

Ή ακόμα χειρότερα για nested loops:
Κώδικας:
times 5 times 5 print "X:", V3;" Y:", V3

Νέα σύνταξη (2.4.1):
Κώδικας:
times 10 \
 print "Hello" : \
 print "World" : \
 wait 100

Παραδείγματα της TIMES με continuation:


Test 1: Βασικό test με single line
Κώδικας:
times 3 print "Hello"
Output: Hello 3 φορές


Test 2: Multi-line με backslash
Κώδικας:
times 3 \
    print "Line 1" : \
    print "Line 2" : \
    print "Line 3"
Output:
Line 1
Line 2
Line 3
Line 1
Line 2
Line 3
Line 1
Line 2
Line 3



Test 3: Backslash μέσα σε quotes
Κώδικας:
times 2 \
    print "This has backslash \\ in string" : \
    print "Another with '\' quote"
Output: Να τυπώσει τα strings όπως είναι (δεν να θεωρηθεί continuation)


Test 4: Complex expressions με arithmetic
Κώδικας:
times 4 \
    x = V3 * 10 : \
    print "Iteration ", V3, " value ", x
Output:

Iteration 0 value 0
Iteration 1 value 10
Iteration 2 value 20
Iteration 3 value 30



Test 5: Nested commands με graphics
Κώδικας:
times 5 \
    color \
    RND(15), RND(15) : \
    paint V3*5, V3*5, 5, 5, -1, 1
Output: 5 διαφορετικά χρωματισμένα κουτιά


Test 6: Με κενή γραμμή continuation
Κώδικας:
times 3 \
    print "Start" : \
    \
    print "Middle" : \
    \
    print "End"
Output:

Start
Middle
End
Start
Middle
End
Start
Middle
End



Test 7: Πολλαπλά backslashes σε διαφορετικές γραμμές
Κώδικας:
times 2 \
    a = 1 : b = 2 : \
    \
    c = a + b : \
    \
    print "Sum = ", c : \
    \
    wait 100
Output:

Sum = 3
Sum = 3



Test 8: Backslash στο τέλος χωρίς κενό
Κώδικας:
times 3 print "Test"\
    : print "Continued"
Output:
Test
Continued
Test
Continued
Test
Continued



Test 9: Backslash με κενά και σχόλια
Κώδικας:
times 3 \

    ! Σχόλιο \

    print "Hello" : \

    print "World"
Output:
Hello
World
Hello
World
Hello
World



Test 10: Zero count
Κώδικας:
times 0 \
    print "This should not print"
print "Skipped"
Output: Μόνο Skipped


Προχωρημένα παραδείγματα της TIMES με continuation:


Nested TIMES
Κώδικας:
print "Nested TIMES test:"
times 2 \
    print "Outer ", V3, ":" : \
    times 3 \
        print "  Inner ", V3
inkey

Nested FOR/TIMES με Full Continuation Support

Κώδικας:
for \
    outer = 1 \
    to 3 \
    
    print "┌─ OUTER ITERATION ", outer, " ───────────────────────┐" : \
    
    for \
        middle = 1 \
        to 4 \
        
        print "│  Middle: ", middle, " " : \
        
        times \
            2 \
            
            print "│    Times[", V3, "] " : \
            
            if \
                V3 = 0 \
                then \
                    print "First " : \
                else \
                    print "Second" : \

        print "│"
        
    next \
    middle : \
    
    print "└──────────────────────────────────────────────┘" : \
    print  ! Blank line
    
next \
outer

Δυναμικός Υπολογισμός Μέσου Όρου Πινάκων
Κώδικας:
    forever#
    dim data[5,5].RND 10000
    data[].SIZE
    array_length = V0
   
    times array_length : \
        sum = 0 : \

        times 5 \
            value = data[V3,V3] : \
            sum = sum + value : \
            average = sum / 5 : \
            print "row ", V3, " average: ", average
 
    goto forever

Σε κάθε αναβάθμιση, προσπαθώ να κάνω τη σύνταξη της Hobby BASIC πιο ελεύθερη και ευέλικτη για τον προγραμματιστή, διατηρώντας παράλληλα τη λογική της και το βασικό BASIC-style. Το περιβάλλον είναι χτισμένο από το μηδέν σε 100% Win32 Assembly, με χειροποίητο parser, μηδέν εξαρτήσεις και απευθείας byte επεξεργασία.

Νέα Παραδείγματα στην έκδοση 2.4.1

Στην ενημέρωση 2.4.1 προστέθηκαν δύο νέα παραδείγματα:
  1. CIRCLES.BAS - Multiple Random Circles Generator
    Δημιουργεί τυχαίους κύκλους με διαφορετικά μεγέθη, χρώματα και θέσεις.
  2. EQUALIZER.BAS - Πλήρως παραμετροποιήσιμο Equalizer / VU Meter
    Προσομοίωση οπτικού equalizer με μπάρες που αντιδρούν σε τυχαίες τιμές.
Screenshots από την κονσόλα των Windows 11.



10 years of fun with Hobby BASIC.
 
Τελευταία επεξεργασία:
Καλά Χριστούγεννα σε όλους!

Μερικές προσωπικές σημειώσεις για την Hobby BASIC.

Η Hobby BASIC μπαίνει πλέον στη δεύτερη δεκαετία της.
Συνεχίζει να μεγαλώνει με νέα προγράμματα και παιχνίδια, εξελισσόμενα σιγά-σιγά με τον καιρό.
Κοιτώντας πίσω τα πρώτα projects που έγιναν για Windows XP και συγκρίνοντάς τα με αυτά που τρέχουν σε Windows 11, η πρόοδος φαίνεται πολύ πραγματική.

Η Hobby BASIC ποτέ δεν προοριζόταν να αντικαταστήσει μια καθημερινή γλώσσα προγραμματισμού — υπήρξε πάντα ένα προσωπικό project βασισμένο στο χόμπι μου. Προέκυψε από τον χρόνο που αφιέρωσα για να μάθω και να πειραματιστώ με assembly χρησιμοποιώντας τον
fasm, και παραμένει μια απλή BASIC-style γλώσσα με μερικά μοναδικά χαρακτηριστικά, σχεδιασμένη ειδικά για την κονσόλα των Windows.

Προσθήκες στην έκδοση 2.4.2

Προστέθηκαν δύο νέες εντολές για τον χειρισμό των διατάξεων, η SORT και η SUM, φτάνοντας έτσι τις 23 συνολικά.

Κώδικας:
    ! STRING ARRAYS (Strings only)
    !  a$[].FILE dpath$        - List dir contents (V0)
    !  a$[].FILE fpath$        - Read file lines (V0)
    !  a$[].SORT               - Sort array alphabetically

    ! STRING/INTEGER ARRAYS (Both types)
    !  a$[].ZERO               - Fill with zeros/empty strings
    !  a$[].SHUFFLE            - Shuffle array elements
    !  a$[].REVERSE            - Reverse element order
    !  a$[].COPY b$[]          - Copy b[] into a[]
    !  a$[].SWAP b$[]          - Swap contents with b[]
    !  a$[].DELETE idx [, ...] - Delete elements by index
    !  a$[].INSERT idx, v [...] - Insert values at index
    !  a$[].FIND x             - Find first index of value
    !  a$[].SIZE               - Return array dimensions
    !  a$[].OUT [indent]       - Print full array

    ! INTEGER ARRAYS (Integers only)
    !  a[].FILL value          - Fill with a value
    !  a[].RND max             - Fill with random values
    !  a[].SET start           - Fill with consecutive values
    !  a[].COUNT x             - Count occurrences (V0)
    !  a[].SUM                 - Sum of array values (V0)
    !  a[].MATCH x [...]       - 1 if match found, else 0
    !  a[].REPLACE a, b        - Replace a with b
    !  a[].ASSIGN b[] x [...]  - Store matches from b[]
    !  a[].COMPARE b[]         - Compare with b[] (V0)
    !  a[].SORTA               - Sort ascending

Παράδειγμα SORT – Αγγλικά:
Κώδικας:
    dim Α$[7] = "Commodore", "Amstrad", "Sinclair", "Atari  ", "Electron", "Dragon 32", "MSX"

    Α$[].SORT

    for i = 0 to SIZE(Α$[]) - 1
        print i+1, ". ", Α$[i]
    next
Output:
Amstrad
Atari
Commodore
Dragon 32
Electron
MSX
Sinclair


Υποστήριξη Wide χαρακτήρων – Ελληνικά:
Κώδικας:
dim A$[7] =  "Καπετάνιος", "Ανεμοστρόβιλος", "Σπιρτόζος", "Αστραπή", "Ενέργεια", "Δράκος", "Μαθητής"

A$[].SORT

for i = 0 to SIZE(A$[]) - 1
    print i+1, ". ", A$[i]
next
Output:
1. Ανεμοστρόβιλος
2. Αστραπή
3. Δράκος
4. Ενέργεια
5. Καπετάνιος
6. Μαθητής
7. Σπιρτόζος


➡ Η Hobby BASIC υποστηρίζει wide χαρακτήρες παντού, οπότε οι Ελληνικές λέξεις ταξινομούνται κανονικά αλφαβητικά.


Παράδειγμα SUM – Άθροισμα στοιχείων πίνακα
Κώδικας:
dim a[5] = 10, 20, 30, 40, 50

a[].SUM
total = V0

print "Το άθροισμα των στοιχείων είναι: ", total
Output:
Το άθροισμα των στοιχείων είναι: 150

Νέα παιχνίδια στην έκδοση 2.4.2


Το Football with Friends είναι ένα πιστό remake ενός παιχνιδιού της PuzzleScript, ξαναγραμμένο στην Hobby BASIC με ANSI γραφικά για την κονσόλα των Windows 11.

Θα χρειαστείς λίγη δεξιοτεχνία στα πόδια για να λύσεις αυτά τα ποδοσφαιρικά παζλ.
Συντονίστε τους συμπαίκτες σας για να πετύχετε το τέλειο γκολ, αλλά πρόσεχε να μην χαθεί η μπάλα στο χορτάρι!
Μπορείς να λύσεις όλα τα παζλ πριν ακουστεί το τελικό σφύριγμα;

Χαρακτηριστικά:
  • Γραφικά ANSI με 16 χρώματα
  • Ομαλή απεικόνιση με πλακίδια (8x8 pixels)
  • Ανανεώνονται μόνο τα πλακίδια που αλλάζουν
  • Μπορείς να αναιρέσεις κινήσεις με ιστορικό UNDO
  • Η μπάλα κινείται με ρεαλιστικό τρόπο
  • Οι παίκτες συνεργάζονται όταν βρίσκονται δίπλα ο ένας στον άλλον
  • Οι αντίπαλοι AI σουτάρουν ή πασάρουν ανάλογα με την κατάσταση
  • Σύστημα γκολ με νίκη ή ήττα ανάλογα με το αποτέλεσμα
  • Ήχοι για σουτ, γκολ και συγκρούσεις
Πηγαίος κώδικας: EXAMPLES\GAMES\WIN11\FOOTBALL.BAS
Γραφικά: Δημιουργήθηκαν με το DRAW, το ANSI σχεδιαστικό πρόγραμμα γραμμένο εξ ολοκλήρου στην Hobby BASIC
Screenshot: Από την κονσόλα των Windows 11



10 years of fun with Hobby BASIC.
 
Διαπιστώνω ότι σταδιακά αρχίζεις να προσθέτεις ευκολίες όμως με αυτές της Python. Η π.χ. κάτι παρόμοιο με το limit της Postgres, δηλαδή select * from mytable limit 10, το οποίο φέρνει μεχρι 10 εγγραφές. Αναφέρομαι στο time 3. Μ'αρέσει πολύ το αποτέλεσμα. Δεν την έχω χρησιμοποιήσει ως τώρα, αλλα δεν έχει σημασία, τη θαυμάζω ως πρότζεκτ. :)
 
Σωστά παρατήρησες, Rygar!

Η σύγκριση με Python δεν είναι τυχαία, είναι η κατεύθυνση. Μπράβο που το παρατήρησες. Στην Hobby BASIC προσπαθώ να διατηρήσω την απλότητα της BASIC με τη δύναμη μιας μοντέρνας γλώσσας. Με κάθε update, προσθέτω features που κάνουν τον κώδικα πιο συνοπτικό και εκφραστικό.

Πάντα όμως, σε τελική ανάλυση, η εξέλιξη είναι με βάση τις προσωπικές μου ανάγκες. Ξεκινάω πάντα από το τι μου αρέσει εμένα και πώς θα κάνω την συγγραφή των προγραμμάτων για εμένα ακόμα ευκολότερη, με όποιο αντίκτυπο έχει αυτό στην γλώσσα. Άλλωστε, προσωπικό project είναι.

Η Hobby BASIC 2.4.3 (που θα ανέβει σύντομα) φέρνει εκφραστική δύναμη που πριν απαιτούσε περισσότερες γραμμές κώδικα, χωρίς να θυσιάζει την απλότητα και την ευκολία μάθησης της κλασικής BASIC.

Σε ευχαριστώ, και θα χαρώ πραγματικά αν κάποια στιγμή βρεθούμε από κοντά να σου δείξω τα ενδότερα του διερμηνευτή.
 

Το πρώτο update του διερμηνευτή για το 2026.

Με το update αυτό, η Hobby BASIC 2.4.3 φέρνει εκφραστική δύναμη που πριν απαιτούσε πολλαπλές γραμμές κώδικα, χωρίς να θυσιάζει την απλότητα και την ευκολία της κλασικής BASIC. Επιπλέον, προστέθηκαν δύο νέες εντολές για τον χειρισμό διατάξεων: MIN και MAX.

Βασικά Παραδείγματα

Κώδικας:
! ΠΡΙΝ: Έμμεσα με μεταβλητές
a[].SUM
if V0 > 100 then print "Large total"

! ΜΕΤΑ: Απευθείας σε έκφραση
if a[].SUM > 100 then print "Large total"

! ΝΕΑ: MIN και MAX
print "Range:", a[].MAX - a[].MIN

Σε Συνθήκες

Κώδικας:
! ΠΡΙΝ: Πολλαπλές ενδιάμεσες μεταβλητές
data[].SUM
sum = V0
data[].MAX
max = V0
if sum > 50 and max < 20 then print "OK"

! ΜΕΤΑ: Όλα σε μία γραμμή
if data[].SUM > 50 and data[].MAX < 20 then print "OK"

! ΝΕΑ: Σε SELECT CASE
select case values[].MIN
    case < 0: print "Contains negatives"
    case > 100: print "All above 100"
endsel


Ανάγνωση Αρχείων

Κώδικας:
! ΠΡΙΝ: Δύο βήματα
dim lines$[1000]
lines$[].FILE path$
count = SIZE(lines$[]) - 1

! ΜΕΤΑ: Μία εντολή
count = lines$[].FILE path$  ! επιστρέφει τον αριθμό γραμμών

if count > 0 then print "Lines: ", count


Σύγκριση Διατάξεων

Κώδικας:
! ΠΡΙΝ: Μέσω συνάρτησης
COMPARE(a[], b[])
result = V0
if result = 1 then print "Equal"

! ΜΕΤΑ: Απευθείας ως συνθήκη
if a[].COMPARE b[] then print "Arrays are identical"

! ΝΕΑ: Συνδυασμοί
if a[].COMPARE b[] and a[].MAX < 100 then print "Valid"


Οι Νέες Προσθήκες: MIN και MAX

Κώδικας:
! Εύρεση εύρους τιμών
dim temps[7] = 15, 22, 18, 25, 20, 16, 24
range = temps[].MAX - temps[].MIN  ! 25 - 15 = 10

! Έλεγχος ορίων
if temps[].MAX > 30 then print "Heat warning!"
if temps[].MIN < 10 then print "Cold warning!"

! Με κενή διάταξη επιστρέφουν 0
dim empty[]
print empty[].MIN  ! 0
print empty[].MAX  ! 0

Η Hobby BASIC συνδυάζει τη νοσταλγία της εποχής 486, τη δύναμη των μοντέρνων γλωσσών, elegant design και assembly υλοποίηση.

Παρακάτω βλέπουμε ένα παράδειγμα που περιέχει:

• Low-level: Syscall, Stack ops
• High-level: Array methods, Subroutines
• Data types: Int arrays, String arrays, Stack arrays
• Math: Integer, Floating-point (FPU)
• Control flow: Conditions, Loops (times)
• I/O: Debug output, Color control
• Type conversion: Automatic int→string for FPU

Κώδικας:
! Hobby BASIC: Peak expressiveness

push -1,-2,-3               ! stack values
dim data[] = RND()%100, \      ! array with random init
            RND()%100, POW(2,8)

sub stats(arr[])               ! user subroutine
    syscall "kernel32","GetTickCount"  ! Windows API call
    debug("Ticks:",V0," Min:",arr[].MIN," Max:",arr[].MAX)
    rets arr[].SUM>100         ! array method in return
ends

if stats(data[])               ! subroutine as condition
    dim a[3] : a[].COPY stack[]   ! copy stack to regular array
    dim words$[] = "Alpha","Beta","Gamma"  ! string array
    color 12,0 : debug("SUM="+STR(data[].SUM)," Stack:",stack[V3])
    a[].REVERSE               ! reverse integer array
    words$[].REVERSE          ! reverse string array
    ! FPU string math: calculate average with floating point
    debug("Avg:",FDIV(STR(data[].SUM), STR(SIZE(data[]))))
    times 3 : debug(a[V3], "=", words$[V3]) ! parallel iteration
    inkey ! wait for any key press
endif

10 years of fun with Hobby BASIC.
 
Τελευταία επεξεργασία:
Σωστά παρατήρησες, Rygar!

Σε ευχαριστώ, και θα χαρώ πραγματικά αν κάποια στιγμή βρεθούμε από κοντά να σου δείξω τα ενδότερα του διερμηνευτή.
Εχω μεγάλη περιέργεια να το δω.
 
Πίσω
Μπλουζα