Τετάρτη 22 Ιουνίου 2016

Η ώρα της BASIC - Παράδειγμα από το 1964.

Σήμερα η ανάρτηση έχει να κάνει με την γλώσσα BASIC. Η Μ2000 έχει στοιχεία της BASIC και εδώ θα δούμε ένα πρόγραμμα από το εγχειρίδιο της πρώτης BASIC του 1964:


Εδώ με μερικές αλλαγές για να λειτουργήσει σωστά (δείτε ότι δεν έχουμε πολλές αλλαγές, μόνο η εντολή DATA πήγε στην αρχή (στη Μ2000 έχει σημασία που είναι), και στο τέλος μπήκε ένα IF που ελέγχει αν έχουμε στοιχεία ακόμα και αν ναι κάνει επιστροφή. Υποψιάζομαι ότι η παλιά Basic όταν δεν είχε στοιχεία, απλά τερμάτιζε! Επίσης υπήρχε ένα θέμα με τη ρίζα. Η Μ2000 δεν δέχεται όρισμα μηδέν ή αρνητικό. Όπως είναι γραμμένο στο εγχειρίδιο ο έλεγχος της D γίνεται αφού τρέξει η εντολή με τον υπολογισμό της ρίζας. Στη Μ2000 δεν μπορούμε να δώσουμε μηδέν άρα αλλάζουμε τη σειρά εντολών, και επιπλέον βάζουμε την συνάρτηση ABS() που δίνει το απόλυτο νούμερο (δηλαδή αφαιρεί το πρόσημο).

Δείτε τους αριθμούς γραμμών. Ο διορθωτής βάζει αυτόματα αριθμούς αν δει ότι η προηγούμενη γραμμή ξεκινάει με αριθμό (ανά παράγραφο ελέγχει όχι ανά γραμμή, οπότε σε αναδίπλωση λέξης, δεν έχουμε θέμα. Με F1 βάζουμε ή βγάζουμε την αναδίπλωση λέξης στον διορθωτή). Στη εικόνα κάτω έχω δώσει τις εντολές CLS, ROW-1 και μετά το EDIT B και άνοιξε έτσι ο διορθωτής:



\\ basic
  1 FORM 80,40
  2 DATA 1, -2, -3, 1, -4, 4, 1, 0, 2
  5 PRINT "QUADRATIC EQUATION"
  6 PRINT
10 READ A, B, C
20 LET D = B * B - 4 * A * C
30 LET S = - B / ( 2 * A )
40 IF D = 0 THEN GOTO 100
50 LET T = SQRT(ABS( D) ) / (2 * A)
60 IF D < 0 THEN GOTO 200
70 PRINT A, B, C, " TWO REAL ROOTS"
80 PRINT "ROOTS =";S+T, S-T
90 GOTO 300
100 PRINT A, B, C, " ONE ROOT"
110 PRINT "ROOT ="; S
120 GOTO 300
200 PRINT A, B, C, " COMPLEX ROOTS"
210 PRINT "REAL PART ="; S, " IMAGINARY PART ="; T
300 PRINT
310 IF NOT EMPTY THEN GOTO 10


Με λίγες αλλαγές έχουμε και το πάνω δεξιά πρόγραμμα της σελίδας τους εγχειριδίου του 1964
\\ LN() natural logarithm
\\ Log() base 10 logarithm
010 S=0
020 DEF FNL(X)=LN(X)/LN(10)
030 FOR I=1 TO 100
040 S+=FNL(I)
050 NEXT I
060 PRINT S/100
070 S=0
080 FOR I=1 TO 100
090 S+=LOG(I)
100 NEXT I
110 PRINT S/100



Σε Wine (Ubuntu Studio)

Σε πιο νέες εκδόσεις της Μ2000 μπορούμε να χρησιμοποιήσουμε αριθμό γραμμής αμέσως μετά το Then. Αν όμως το Goto γίνεται σε ετικέτα τότε πρέπει να χρησιμοποιηθεί το Goto. Σε αριθμούς γράφουμε εντολή ακριβώς δίπλα. Σε ετικέτες πχ αλφα:  δεν γράφουμε εντολή δίπλα, μόνο σημειώσεις με ' ή \
Οι αριθμοί μπορούν να έχουν μηδενικά στην αρχή. Πχ το 0010 είναι το 10 και το Goto 10 θα πάει σε αυτό. Η σειρά των αριθμών δεν παίζει ρόλο. Μπορούμε το 1000 να το έχουμε στην αρχή! Οι αριθμοί μπορεί να είναι από 00001 εως 99999. Αν δεν χρησιμοποιούμε την εντολή Ένθεση (Inline) που παρεμβάλει κώδικα μέσα σε μπλοκ κώδικα, τότε με την πρώτη χρήση Goto/Gosub (Προς/Διαμέσου) ο αριθμός, ή η ετικέτα, καταγράφεται, και την επόμενη φορά θα βρεθεί άμεσα (μέσω συνάρτησης κατακερματισμού και ειδική λίστας καταγραφής). Η λίστα καταστρέφεται στο πέρας εκτέλεσης του τμήματος/συνατησης, ή μετά από εντολή ένθεσης.

\\ basic
  1 FORM 80,40
  2 DATA 1, -2, -3, 1, -4, 4, 1, 0, 2
  5 PRINT "QUADRATIC EQUATION"
  6 PRINT
10 READ A, B, C
20 LET D = B * B - 4 * A * C
30 LET S = - B / ( 2 * A )
40 IF D = 0 THEN 100
50 LET T = SQRT(ABS( D) ) / (2 * A)
60 IF D < 0 THEN 200
70 PRINT A, B, C, " TWO REAL ROOTS"
80 PRINT "ROOTS =";S+T, S-T
90 GOTO 300
100 PRINT A, B, C, " ONE ROOT"
110 PRINT "ROOT ="; S
120 GOTO 300
200 PRINT A, B, C, " COMPLEX ROOTS"
210 PRINT "REAL PART ="; S, " IMAGINARY PART ="; T
300 PRINT
310 IF NOT EMPTY THEN 10


Επίσης μπορούμε να θέσουμε μερικούς διακόπτες για να έχουμε το For όπως στην Basic (πχ το For i=1 to 0 :   Print "ok": Next i δεν θα τρέξει γιατί το βήμα είναι 1, θετικό, και το πρόσημο τέλος-αρχή είναι 0-1= -1, αρνητικό. Ενώ εξ ορισμού το βήμα το χρησιμοποιεί η Μ2000 ως απόλυτο νούμερο και την κατεύθυνση την δίνουν τα νούμερα αρχή και τέλος.
Επίσης μπορούμε να ορίσουμε οι πίνακες να ορίζονται όπως στην Basic, όπου το DIM A(10) δίνει 11 στοιχεία, από 0 έως 10. Εδώ το +DIM δεν θα ισχύσει αν έχουμε δώσει BASE 1 (ή ΒΑΣΗ 1) όπου το DIM A(10) ή Πίνακας Α(10) θα δώσει στοιχεία από 1 έως 10 (ορισμένες basic έχουν το 1 ως βάση)
Set Switches "+FOR +DIM"
Θέσε Διακόπτες "+FOR +DIM"

Μπορούμε να βγαίνουμε με goto από For/Next (δηλαδή FOR χωρίς αγκύλες) αλλά πρέπει να γίνεται με το exit for. Η exit for αν έχει αριθμό ή λέξη μετά εκτελεί την έξοδο σωστά (ρυθμίζει τη στοίβα επιστροφής) και εκτελεί το Goto στον αριθμό ή στην ετικέτα που δείχνει η λέξη. Προσοχή αν δεν υπάρχει ο αριθμός ή η ετικέτα είναι σαν έξοδος από το τμήμα, δεν γίνεται επιστροφή λάθους.

Επίσης δείτε ότι η ετικέτα είναι σε δική της γραμμή μόνη της! Στις ετικέτες μπορούμε να βάλουμε μόνο σημειώσεις δίπλα με ' ή / χαρακτήρες στην αρχή.
Οι αριθμοί και οι ετικέτες αναζητούνται μια φορά και καταγράφονται. Αλλά μόνο στο σώμα ενός τμήματος ή μιας συνάρτησης. Σε ορισμούς τμημάτων και συναρτήσεων εντός τμήματος ή συνάρτησης αποφεύγουμε να βάζουμε ίδιες ετικέτες ή αριθμούς γραμμών γιατί ο διερμηνευτής στν αναζήτηση κοιτάει γραμμές δεν κοιτάει το που είναι αυτές, και οι ορισμοί είναι και αυτοί γραμμές του τμήματος.

Module TestThis {
      For j=1 to 3
            For i=1 to 10
                  If i=5 Then Exit For alfa
            Next
            Print "bad"
alfa:
            Print "ok"
      Next
      For j=1 to 3
            For i=1 to 10
                  If i=5 Then Exit For 100
            Next
            Print "bad"
100      Print "ok"
      Next
}
TestThis


Μπορούμε να χρησιμοποιούμε ρουτίνες και συναρτήσεις όπως στην BASIC γράφοντάς της στο τέλος του τμήματος ή της συνάρτησης που ανήκουν. Η κλήση της Alfa() γίνεται με όνομα ή με την Διαμέσου ή GOSUB.

Module TestThis {
      i=100
      Alfa(3)
      Gosub Alfa(3)
      Print @p(10)=3628800
      Print i=100
      Sub Alfa(x)
            Local i=x**2
            Print i, x
      End Sub
      Function p(i as long)
            If i<2 Then =1&: Exit Function
            =@p(i-1)*i
      End Function
}
TestThis

Οι συναρτήσεις που συνδέουμε στο τέλος καλούνται με το @ πριν. Δεν μπορούμε να τις περάσουμε με αναφορά και δεν έχουν δικό τους σωρό τιμών (όπως έχουν οι κανονικές και οι λάμδα).
Και οι ρουτίνες με παρενθέσεις και οι συναρτήσεις με @ έχουν αναδρομή. Όμως οι ρουτίνες με παρενθέσεις έχουν τεράστια δυνατότητα αναδρομή, και μπορούμε να το ορίσουμε, πχ με την Όριο.Αναδρομής 100000 βάζουμε το όριο στις 100 χιλιάδες κλήσεις. Οι συναρτήσεις έχουν περίπου 3500 βάθος κλήσεων.

Επίσης μια διαφορά αυτών των δομών Sub/End Sub και Function/End Function με τα τμήματα και τις κανονικές συναρτήσεις και τις λάμδα συναρτήσεις είναι ότι οι πρώτες έχουν θέαση κοινή με το τμήμα ή τη συνάρτηση που ανήκουν. Για το λόγο αυτό αν θέλουμε να ορίσουμε τοπικές μεταβλητές τις ορίζουμε με Local (ή Τοπικές ή Τοπική). Στην p() η i είναι τοπική και φτιάχνεται κάθε φορά που καλούμε αναδρομικά τη p() και διαγράφεται κάθε φορά που επιστρέφουμε από την συνάρτηση.

H GOSUB ;ή ΔΙΑΜΕΣΟΥ έχει και μια παραλλαγή για κλήση απλή ρουτίνας, με μια εντολή Επιστροφή στο τέλος, χωρίς να περάσουμε παραμέτρους (δίνουμε το όνομα ετικέτας ή τον αριθμό γραμμής).
Rem {
      Multiline Rem
      16bit Integer
      Try Long, Decimal, Currency, Double, Single
      Not try Boolean here.
}
DEF INTEGER K=10
WHILE K>0
      GOSUB 1000
      K--
END WHILE

END
1000 PRINT "K=";K, TYPE$(K)="Integer"
1010 RETURN



Υπάρχουν τα ON GOTO και ON GOSUB  (ΑΠΟ ΠΡΟΣ και ΑΠΟ ΔΙΑΜΕΣΟΥ)

Do
      X=Random(-3,4)
      Print X
      if x<=0 then Print "Exit now from block", X
      On X Goto 100, 200, 300
      Print "X>3", X
      Exit
      100 Print "ok 1" : Exit
      200 Print "ok 2" : Exit
      300 Print "ok 3" : Exit
Always
Print "finish"





Δεν υπάρχουν σχόλια:

Δημοσίευση σχολίου

You can feel free to write any suggestion, or idea on the subject.