Copyright © 2003 MacroCosmos project. All rights reserved.
Αυτό το έγγραφο περιγράφει το έργο 'MacroCosmos'. Πρόκειται για το πρότυπο αυτού του έργου. Το έργο MacroCosmos περιλαμβάνει μια γλώσσα προγραμματισμού, και ένα σύνολο από προκαθορισμένα αρχεία ορισμών. Η γλώσσα αυτή έχει σκοπό να αυτοκαθορίζεται ανάλογα τις απαιτήσεις του χρήστη κατά την διάρκεια της εκτέλεσης της.
Πολλές φορές έχουμε προσέξει πόσο παρόμοια είναι διάφορα κείμενα και κώδικες, είτε αυτά είναι document markup languages, είτε γλώσσες προγραμματισμού.
| LaTeX | \chapter{Τίτλος κεφάλαιο} |
| DocBook | <chapter>Τίτλος κεφάλαιο</chapter> |
| HTML | <h1>Τίτλος κεφάλαιο</h1> |
| BASIC | FOR i=1 TO 6 STEP 2 |
| C/C++/Java/etc | for ( i = 1; i <= 6; i += 2 ) |
| x86 Assembly | mov cx, 1 @loop: ... add cx, 2 cmp cx, 6 jle loop |
Εκτός από τα παραπάνω, μάκρος για την απλούστευση της συγγραφής κειμένου ή κώδικα είναι απαραίτητα, πράγμα που δεν υποστηρίζεται απο πολλά εργαλεία, σε άλλα είναι μειωμένων δυνατοτήτων και σε άλλα δυσκολόχρηστα. Ποιός δεν θα ήθελε να έχει ένα preprocessor για HTML; Το TeX έχει macros αλλά ποιός δεν θα προτιμούσε κάτι πιο συνηθισμένο σαν της C ή αν είναι συνηθισμένος σε TeX τότε TeX macros σε HTML;
Η ιδέα του macrocosmos έχει ως στόχους:
Εάν αυτοί οι στόχοι πραγματοποιηθούν, ο χρήστης θα μπορεί - μεταξύ των άλλων - να κάνει με εύκολο τρόπο τα παρακάτω:
Τα περισσότερα από αυτά που αναφέρω, υπάρχουν σε ξεχωριστά πακέτα, π.χ. xml->latex, yacc/lex κ.λπ. Τα προβλήματα που έχουν τα ήδη έτοιμα πακέτα έχουν ως εξής:
Όλα τα σύμβολα μπορούν να επανακαθορίζονται, αυτό θα γίνετε με αντίστοιχη εντολή. Πρέπει όμως να υπάρχουν τα προκαθορισμένα.
Βασικά προκαθορισμένα σύμβολα, '@' εντολές μακρόκοσμου.
Μέσα στα τμήματα κώδικα του macrocosmos, δηλαδή τμήματα που έχουν δηλωθεί με κάποια εντολή '@-κάτι' ισχύουν τα παρακάτω σύμβολα, '\' ειδικός χαρακτήρας, '${x}' η τιμή της μεταβλητής x.
Τα macros είναι το πιο βασικό τμήμα του έργου αυτού.
@macro <h1>
\\chapter{
@eom
@macro </h1>
@eom
Στο παραπάνω παράδειγμα δηλώνουμε δύο macros. Το πρώτο λέγετε <h1>. Το όνομα των μάκρο μπορεί να είναι οποιαδήποτε σειρά χαρακτήρων πλην των '{' και '\n'. Αλλά και αυτά θα πρέπει να μπορούν να χρησιμοποιηθούν με την χρήση του ειδικού χαρακτήρα '\'.
Το σύμβολο '{' δηλώνει την αρχή των παραμέτρων. Ο χαρακτήρας ';' διαχωρίζει τις παραμέτρους και το σύμβολο '}', το τέλος αυτών. Οι μεταβλητές μέσα στο μάκρο πρέπει να δηλώνονται με το '$' όπου πρέπει να ακολουθεί ένα τμήμα με το όνομα της μεταβλητής '{x}'.
@macro chap{x}
\\chapter{${x}}
@eom
Επίσης θα πρέπει να είναι ικανό να δηλώσουμε και το τέλος του κειμένου.
@macro <h1>{x}</h1>
\\chapter{${x}}
@eom
Αν ο ορισμός του μάκρο γίνετε χωρίς ορισμό τέλους, τότε η αντικατάσταση πρέπει να γίνει όταν έχουν πλήρη ορισμό στο κείμενο π.χ. 'chap{Ένας τίτλος}'. Στην περίπτωση που ορίζεται το τέλος του μάκρο τότε θα πρέπει να αντικαταστήσουμε το κείμενο που περικλείεται στον ορισμό π.χ. '<h1>Ένας Τίτλος</h1>'. Παρατηρούμε δηλαδή ότι στην πρώτη περίπτωση η χρήση των '{}' απαιτήται ενώ στην δεύτερη όχι. Στην περίπτωση που δεν έχουμε παράμετρους τα '{}' είναι άχρηστα.
@macro chap{x}
\\chapter{${x}}
@eom
@macro <h1>{x}</h1>
\\chapter{${x}}
@eom
<h1>Chapter #1</h1>
chap{Chapter #2}
Αποτέλεσμα
\chapter{Chapter #1}
\chapter{Chapter #2}
Η εκτέλεση των μάκρο πρέπει να γίνετε αμέσως μετά τον ορισμό (δηλαδή από το '@eom') και μόνο στο παρακάτω κείμενο. Έτσι έχουμε την δυνατότητα να φτιάχνουμε πιο σύνθετα μάκρος.
@macro X 1/(1-SQR(1/(c-a))) @eom @macro Y z = m/g * (X)/3 @eom Y
z = m/g * (1/(1-SQR(1/(c-a))))/3
Εναλακτικά το όνομα του μάκρο πρέπει να δηλώνετε σε 3 μέρη. Το κάθε μέρος δηλώνετε ως τμήμα που περικλείεται απο τα '{}'.
@macro {<h1>}{x}{</h1>}
...
@eom
Όπως είδαμε μπορούμε να ορίσουμε μάκρος τα οποία ορίζονται απο την αρχή και απο το τέλος του κειμένου. Αυτό πρέπει να μπορούμε να το κάνουμε και με regular expressions.
@remac {[A-Za-z0-9_]+}{x}{\n}
...
@eom
Τίθετε όμως το εξής πρόβλημα. Ενώ μέχρι τώρα το πρώτο και τελευταίο μέρος του κειμένου αντικαθήστατο απο τα περιεχόμενα του μάκρο, αυτή την φορά μπορεί να θέλουμε να αντικατασταθεί μόνο το εσωτερικό κείμενο διότι το expression μπορεί να αναφέρει μεγάλο μέρος του κειμένου που θέλουμε να παραμείνει απείραχτο.
@iremac {[A-Za-z0-9_]+}{x}{\n}
...
@eom
Εκτός τα μάκρος πρέπει να έχουμε και μια βασική συλλογή από δυνατότητες. Όπως, μεταβλητές, εντολές επαναλήψεων, συναρτήσεις κ.α. Αυτές πρέπει να δηλώνονται μέσα σε τμήματα που ορίζονται απο τις εντολές '@code' και '@eoc'.
Το 'code' πρέπει να έχει την δυνατότητα να δουλέψει με ότι γλώσσα θέλει ο χρήστης π.χ. perl, php, κ.λπ.
...
@code{perl}
print 1;
@eoc
Αυτό είναι εύκολο, αρκεί να μπορούμε να έχουμε και μια επικοινωνία. Στο stdin του κώδικα πρέπει να στέλνουμε το κείμενο που ακολουθεί το @eoc ενώ στο stdout επιστρέφει το επεξεργασμένο κείμενο, το οποίο για τον macrocosmo είναι η συνέχεια του κειμένου.
Πέρα απο τον default τρόπο πρέπει να έχουμε την δυνατότητα να μεταφέρουμε κείμενα απο και προς μεταβλητές. Αυτό θα πρέπει να γίνετε με τα < και >.
...
@code{sbasic<${x}>${y}}
lninput stdin_str
print "Είμαι το y και αυτή είναι η τιμή του χ", stdin_str
@eoc
...
Πολλές φορές είναι πιο εύκολο για εμάς να ορίζουμε τις μεταβλητές με απλή αντικατάσταση αντί να τα μεταφέρουμε μεσω stdin/out.
...
@code{sbasic>${y}}
print "Είμαι το y και αυτή είναι η τιμή του χ", ${x}
@eoc
...
@echo{${y}}
Συνήθως ως μακρο-κώδικα εννοούμε κάτι το τελείως διαφορετικό από ότι χρειάζεται τώρα να δηλώσουμε, την μίξη κώδικα και μάκρο.
@macro chap{x}
@code{php<${x}}
...
@eoc
@eom
Σ' αυτή την περίπτωση ο κώδικας πρέπει να εκτελείτε σε κάθε σημείο που το μάκρο αντικαταστεί το κείμενο. Ο κώδικας αυτός έχει επαφή μόνο με τα δεδομένα του αντίστοιχου μάκρο και όχι ολόκληρου του κείμενου. Το αποτέλεσμα του κώδικα είναι και ο κώδικας του μάκρο.
@macro chap{x}
@code{php}
echo "\\chapter{${x}}\n";
@eoc
@eom
chap{x}
TODO: Περιγραφή των μάκρο rules, classes και subclasses. Αντίστοιχα και macros σε μεταβλητές με visibility μόνο στο parent macro.
@rule{<!--; -->; comment}
@rule{<head>; </head>; header}
@rule{<body*>; </body>; body}
@macro.comment{text}
Αυτό εδώ είναι comment χωρίς class-γονέα
@eom
@macro.header.comment{text}
Αυτό εδώ είναι comment του header
@eom
@macro.body.comment{text}
Αυτό εδώ είναι comment του body
<<EOF
@macro X
...και αυτό εδώ μάκρο με κύκλο ζωής μέσα στο parent macro...
@eom
${text}
EOF
Αλλά θα έπρεπε να γράφετε και έτσι
@macro {X}{x}{}
...και αυτό εδώ, επίσης, μάκρο με κύκλο ζωής μέσα στο parent macro...
@eom
@eom
TODO: Περιγραφή των πακέτων και του κύκλου ζωής τους, εκτέλεση μακρο-πακέτου ανά class ή subclass, επαναφορά και μίξη
@include... @require... @import... @exclude... @revert...
TODO: Περιγραφή σύνθετης δομής, εκεί όπου ο πρώην μακρόκοσμος είναι μικρο-κοσμος. Με απλά λόγια όλα τα προηγούμενα πως θα λειτουργούν ως καθορισμένο υποσύνολο ενος νέου πακέτου.
@import "html2latex.mcs" as html
@import "latex2pod.mcs" as latex
@macro {<html>}{x}{</html>}
html{<${x}>${y}}
latex{<${y}>${z}}
${z}
@eom