# MacroCosmos

## Working Draft, 1 Αυγούστου 2003

Συγγραφείς
  Νικόλαος Χριστόπουλος
Έκδοση 0.1
  1/8/2003, Νικόλαος Χριστόπουλος

Copyright © 2003 MacroCosmos project. All rights reserved.

## Περίληψη

Αυτό το έγγραφο περιγράφει το έργο 'MacroCosmos'. Πρόκειται για το πρότυπο αυτού του έργου. Το έργο MacroCosmos περιλαμβάνει μια γλώσσα προγραμματισμού, και ένα σύνολο από προκαθορισμένα αρχεία ορισμών. Η γλώσσα αυτή έχει σκοπό να αυτοκαθορίζεται ανάλογα τις απαιτήσεις του χρήστη κατά την διάρκεια της εκτέλεσης της.

## Γιατί χρειαζόμαστε ένα νέο εργαλείο

Πολλές φορές έχουμε προσέξει πόσο παρόμοια είναι διάφορα κείμενα και κώδικες, είτε αυτά είναι document markup languages, είτε γλώσσες προγραμματισμού.

Παράδειγμα σε 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 έχει ως στόχους:

1. Ο κάθε χρήστης να χρησιμοποιεί το συντακτικό που προτιμά για να γράψει ένα έγγραφο ή κώδικα
2. Ο κάθε χρήστης να επεκτίνει το συντακτικό που προτιμά κατά την κρίση του χωρίς να χρειάζεται γι' αυτό να περιορίζεται σε κάποιο πρότυπο ή στα όριο του προϊόντος που στοχεύει το έγγραφο/κώδικας
3. Από το αρχικό έγγραφο/κώδικα να βγαίνει αποτέλεσμα σε όλα τα υποστηριζόμενα αποτελέσματα
4. Με δύο αρχεία ορισμών να μπορεί να γίνετε μετατροπή από την μια μορφή σε μια άλλή, είτε αυτή είναι μια ήδη υπάρχουσα είτε αυτή είναι ένα συντακτικό που προκαθορίστηκε
5. Να μην υπάρχει κανένας περιορισμός συμβόλων. Δηλαδή όλα τα σύμβολα που θα χρησιμοποιηθούν να μπορούν να επανακαθοριστούν
6. Το συντακτικό θα πρέπει να είναι ευκολονόητο και δυναμικό, έτσι ώστε να μπορεί να αλλάξει απο τον χρήστη εύκολα

Εάν αυτοί οι στόχοι πραγματοποιηθούν, ο χρήστης θα μπορεί - μεταξύ των άλλων - να κάνει με εύκολο τρόπο τα παρακάτω:

- Να γράφει ένα κείμενο στο συντακτικό που προτιμά (ή επεκταμένο ανάλογα την περίπτωση) και αυτό να μετατρέπεται με σωστό και δομημένο τρόπο, σε LaTeX, TeX, TexInfo, *roff, HTML, XML, SGML, RTF, plain text, POD, BB-Code, PDF, DVI, PNG, BMP, C (data), BASIC (data), PASCAL (data), κ.λπ.
- Να φτιάχνει ψευδο-compilers με έξοδο στην γλώσσα της αρέσκιας του είτε αυτή λέγετε Assembly, είτε Pascal, είτε απ' ευθείας machine language. Έτσι για παράδειγμα θα μπορεί να γράφει shell scripts με εντολές BASIC τα οποία θα μετατρέπονται σε εντολές bash και τέλος θα εκτελούνται
- Να φτιάχνει ψευδο-compilers με έξοδο υψηλότερου επιπέδου αποτελέσματα π.χ. απο Assembly σε C βασιζόμενο στις επαναλήψεις του κώδικα ή σε δυναμικά συνδεόμενο κώδικα που θα έχει φτιάξει σε άλλη γλώσσα
- Να φτιάχνει documentation στο source code χρησιμοποιόντας συντακτικό της αρέσκειας του. Δηλαδή μπορεί να γράφει τα σχόλια σε javadoc συντακτικό αλλά να πάρει το αποτέλεσμα και σε doxygen

## Προβλήματα των υπάρχοντων εργαλείων

Τα περισσότερα από αυτά που αναφέρω, υπάρχουν σε ξεχωριστά πακέτα, π.χ. xml->latex, yacc/lex κ.λπ. Τα προβλήματα που έχουν τα ήδη έτοιμα πακέτα έχουν ως εξής:

1. Κάθε ένα παρ' ότι μπορεί να κάνει παρόμοια δουλειά με ένα άλλο έχει διαφορετικό συντακτικό. Αυτό απαιτεί τελικά από τον χρήστη, αρκετό ανούσιο χρόνο, ώστε να μάθει το συντατικό αυτών
2. Πολλά απο αυτά είναι φτιαγμένα σε γλώσσα προγραμματισμού που για πολλούς χρήστες αυτό είναι μεγάλο πρόβλημα είτε γιατί δεν έχουν σκοπό να μάθουν την συγκεκριμένη γλώσσα για να διορθώσουν ένα μικροπρόβλημα (π.χ. lisp) είτε γιατί πρέπει να ασχοληθούν με χιλιάδες γραμμές C κώδικα, είτε γιατί είναι απλοί χρήστες και δεν έχουν ιδέα από προγραμματισμό
3. Όλα αυτά τα εργαλεία είναι φτιαγμένα το καθένα σε ότι βόλευε τον προγραμματιστή τους με αποτέλεσμα να έχουμε μια "παρδαλή" συλλογή όπου απαιτούνται υπερβολικά πολλές και άχρηστες γνώσεις για την χρήση και την ρύθμιση του κάθε ενός απο αυτά
4. Σχεδόν σε όλες τις περιπτώσεις η επέκταση ή η προσαρμογή στις επιλογές του χρήστη ένος τέτοιου εργαλείου, χρειάζεται γνώσεις του κώδικα του, ο οποίος μπορεί να υπερβαίνει κατά πολύ τις μερικές χιλιάδες γραμμές, ή κάποιας γλώσσας η οποία είναι είτε δυσκολονόητη είτε απλά μη αρεστή στο χρήστη, είτε ο χρήστης να μην είναι προγραμματιστής, είτε αυτό να είναι αδύνατο λόγο σχεδιασμού
5. Συνήθως αυτά τα εργαλεία λειτουργούν αποκλειστικά για από ή/και προς αποκλειστικά συγκεκριμένες μορφές, πράγμα που καθιστά την εργασία που έχει ήδη γίνει ουσιαστικά μην επαναχρησιμοποιήσιμη. Έτσι για παράδειγμα ένα πρόγραμμα που μετατρέπει απο TeX σε HTML παρ' ότι έχει ήδη έτοιμο τον κώδικα για την επεξεργασία των TeX αρχείων, αυτός ο κώδικας ουσιαστικά δεν μπορεί να χρησιμοποιηθεί (ή απλά είναι χρονοβόρα και πολύπλοκη η διαδικασία να μεταφερθεί σε άλλο έργο) για την παραγωγή SGML αρχείων.

## Προδιαγραφές

Όλα τα σύμβολα μπορούν να επανακαθορίζονται, αυτό θα γίνετε με αντίστοιχη εντολή. Πρέπει όμως να υπάρχουν τα προκαθορισμένα.

Βασικά προκαθορισμένα σύμβολα, '`@`' εντολές μακρόκοσμου.

Μέσα στα τμήματα κώδικα του macrocosmos, δηλαδή τμήματα που έχουν δηλωθεί με κάποια εντολή '@-κάτι' ισχύουν τα παρακάτω σύμβολα, '`\`' ειδικός χαρακτήρας, '`${x}`' η τιμή της μεταβλητής x.

### Macros

Τα 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

### Macros και regular expressions

Όπως είδαμε μπορούμε να ορίσουμε μάκρος τα οποία ορίζονται απο την αρχή και απο το τέλος του κειμένου. Αυτό πρέπει να μπορούμε να το κάνουμε και με regular expressions.

    @remac {[A-Za-z0-9_]+}{x}{\n}
    ...
    @eom

Τίθετε όμως το εξής πρόβλημα. Ενώ μέχρι τώρα το πρώτο και τελευταίο μέρος του κειμένου αντικαθήστατο απο τα περιεχόμενα του μάκρο, αυτή την φορά μπορεί να θέλουμε να αντικατασταθεί μόνο το εσωτερικό κείμενο διότι το expression μπορεί να αναφέρει μεγάλο μέρος του κειμένου που θέλουμε να παραμείνει απείραχτο.

    @iremac {[A-Za-z0-9_]+}{x}{\n}
    ...
    @eom

### Code

Εκτός τα μάκρος πρέπει να έχουμε και μια βασική συλλογή από δυνατότητες. Όπως, μεταβλητές, εντολές επαναλήψεων, συναρτήσεις κ.α. Αυτές πρέπει να δηλώνονται μέσα σε τμήματα που ορίζονται απο τις εντολές '`@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}

### Άλλες εντολές

@echo
  Τυπώνει τις παραμέτρους του
@set
  Ορίζει τιμή σε μια μεταβλητή
@push
  Αποθηκεύει μια μεταβλητή στη stack
@pop
  Επαναφέρει μια μεταβλητή από τη stack
@store
  Αποθηκεύει μια μεταβλητή σε μια λίστα
@printlist
  Τυπώνει μια λίστα
@conf
  Ορίζει την τιμή σε μια μεταβλητή συστήματος του macrocosmos

### Μεταβλητές συστήματος

case
  Για case != 0 τότε οι συγκρίσεις των string γίνονται με ignore case
symbols
  Επανακαθορισμός των συμβόλων

### Μακρο-βιότης - Μικρό μακρό-κοσμος

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