Το έπιασα ζεστά το θέμα και μέχρι στιγμής έχω φτιάξει το σύστημα που σαρώνει τον κώδικα και βγάζει σε ένα αντικείμενο CodeBlock το κώδικα όπως φαίνεται παρακάτω. Θέλει δουλειά για να υποστηρίζω όλη τη πολύπλοκη δομή της Μ2000. Ο διαχωρισμός σε αναγνωριστικά, τιμές αριθμητικές, τιμές αλφαριθμητικές και σύμβολα είναι σημαντικός. Επίσης γράφονται και τα απαιτούμενα άλματα, καθώς και που κλείνει μια παρένθεση και που κλείνει μια αγκύλη.
Module Alfa {
X=10
alfa:
if X>1 Then
x--
if x>2 and x<5 then print x
goto alfa
end if
print "ok"
}
Call Alfa
0 1 171 Identifier: MODULE id (0)
1 8 161 Identifier: ALFA id (1)
2 14 140 START BRACKET (end bracket: 41)
3 13 0
4 17 161 Identifier: X id (2)
5 18 14 = symbol id (2)
6 19 100 10 Double numliteral (0)
7 20 0
8 24 20 Label alfa
9 28 0
10 32 171 Identifier: IF id (3)
11 35 161 Identifier: X id (2)
12 36 14 > symbol id (7)
13 37 100 1 Double numliteral (2)
14 39 10 Identifier: THEN skip to 36 id (4)
15 42 0
16 47 161 Identifier: X id (2)
17 48 18 -- symbol id (124)
18 49 0
19 54 171 Identifier: IF id (3)
20 57 161 Identifier: X id (2)
21 58 14 > symbol id (7)
22 59 100 2 Double numliteral (3)
23 61 171 Identifier: AND id (5)
24 65 161 Identifier: X id (2)
25 66 14 < symbol id (4)
26 67 100 5 Double numliteral (4)
27 69 10 Identifier: THEN skip to 31 id (4)
28 74 171 Identifier: PRINT id (6)
29 80 161 Identifier: X id (2)
30 80 0
31 85 111 Identifier: GOTO id (7)
32 90 161 Identifier: alfa id (8)
33 93 0
34 97 171 Identifier: END id (9)
35 101 171 Identifier: IF id (3)
36 102 0
37 106 171 Identifier: PRINT id (6)
38 112 15 "ok" strliteral (5)
39 115 0
40 118 141 END BRACKET (start bracket: 3)
41 118 0
42 121 171 Identifier: CALL id (10)
43 126 161 Identifier: ALFA id (1)
44 129 0
Number Literals: 4
String Literals: 1
Identifiers: 11
Labels : 1
Η πρώτη στήλη είναι η θέση στο πίνακα του κώδικα, ξεκινάει από το 0. Εδώ δεν έχουμε δένδρο τύπου AST, αλλά πίνακα με συνολικά 10 Bytes ανά θέση. Το δεύτερο νούμερο είναι η θέση στο κείμενο του προγράμματος. Το χρειαζόμαστε και για μηνύματα λάθους, και για να δείχνουμε το κώδικα όταν τρέχει σε φάση ελέγχου. Το τρίτο νούμερο είναι ο τύπος της εγγραφής-εντολής. Το τέταρτο νούμερο είναι είναι ένα βοgθητικό που αν χρειάζεται μας δείχνει το άλμα που μπορούμε να κάνουμε. Το πέμπτο νούμερο (ή τελευταίο τέταρτο σε κάποιες γραμμές, επειδή το προηγούμενο δεν χρησιμοποιείται) δείχνει την "μνήμη" που καταγράφεται, ή ένα όνομα (αναγνωριστικό) ή ένα αλφαριθμητικό ή ένας αριθμός. Οι αριθμοί σώνονται με το τύπο που δίνουμε.
Στο τέλος έχουμε μια λίστα αριθμών. Εδώ μας λέει ότι ο κώδικας είχε 4 αριθμούς, ένα
αλφαριθμητικό, 11 αναγνωριστικά (γνωστά/άγνωστα) και μια ετικέτα.
Το κείμενο του κώδικα μπαίνει στην αρχή σε ένα αντικείμενο Document, και αυτό λειτουργεί όπως περίπου και στον χρωματιστή κώδικα στον διορθωτή της Μ2000, με τη διαφορά ότι εδώ δεν μας ενδιαφέρουν τα χρώματα αλλά ο τύπος. Γίνεται πάρα πολύ γρήγορα. Η Μ2000 χρωματίζει χιλιάδες γραμμές κώδικα σε κλάσμα δευτερολέπτου, με συνολικά πάνω από 1000 αναγνωριστικά - ελληνικά και αγγλικά, επειδή χρησιμοποιεί πίνακες κατακερματισμού με O(1) στην αναζήτηση. Εδώ όμως έχουμε και ένα δεύτερο πέρασμα στο χρωματισμένο κώδικα για να γραφτεί ο πίνακας. Για το σκοπό αυτό χρησιμοποιώ μια στοίβα που γράφω ορισμένα στοιχεία που πρέπει να ελέγχω. Έτσι αν στον παραπάνω κώδικα δεν βάλουμε το END IF, θα μείναι στη στοίβα το Then. Δείτε ότι υπάρχει ένα φωλιασμένο IF που έχει την Then αλλά δεν έχει END IF επειδή έχει εντολή μετά το Then. Επειδή δεν κοιτάει μπροστά το σύστημα, ο έλεγχος γίνεται στην αλλαγή γραμμής, και βλέπει τι είχε τελευταίο και τι απόσταση είχε από το τέλος γραμμής (δεν συμπεριλαμβάνονται οι σημειώσεις). Αν δει λοιπόν ότι είχε το THEN τότε θα το αφαιρέσει. Αυτό το κοίταγμα, έγινε και στο πρώτο Then, αλλά εκεί έκανε το σύστημα κάτι ωραίο, το σημάδεψε για να μην το ενοχλήσει ξανά (αφού βρήκε ότι ήταν ακριβώς μια εντολή πίσω από την αλλαγή γραμμής).
Το πρόγραμμα τρέχει στο "παλιό" ή "τωρινό" διερμηνευτή. Ακόμα δεν έχω φτιάξει την εκτέλεση του κώδικα από τον πίνακα. Έχει αρκετή δουλειά για να βρω όλες τις περιπτώσεις, να τεκμηριώσω ότι γράφονται στο πίνακα σωστά και μετά έχω ένα δεύτερο μεγάλο σκέλος, να φτιάξω όλες τις εντολές να δέχονται παραμέτρους από τον κώδικα στο πίνακα και όχι όπως τώρα που εκτελούν τον κώδικα απ' ευθείας από το κείμενο! Για εκπαιδευτικούς σκοπούς αυτή η "παλιά" πρακτική, δεν είναι πρόβλημα. Αλλά αν φτιαχτεί όπως σκέφτηκα, θα κερδίσω σε ταχύτητα, υπολογίζω πως θα κερδίσω σε αναλογία 1/200. Δηλαδή θα χρειάζεται 200 φορές λιγότερο χρόνο εκτέλεσης, από τη σημερινή υλοποίηση!
Αφού τελειώσω με το πίνακα, θα τον μαζέψω, δηλαδή θα αφαιρέσω από την αρχή τις γραμμές με το 0. Τώρα τις έχω για να καταλαβαίνω το κώδικα (διαφορετικά θα ήταν ένα μπέρδεμα...)
Δεν υπάρχουν σχόλια:
Δημοσίευση σχολίου
You can feel free to write any suggestion, or idea on the subject.