Chcę zrobić nowy, ściśle typowany, obiektowy język funkcji-makr - obiektową nakładkę na dowolny język, używany do tej pory. Zastosowania komercyjne i w szkołach - jak najbardziej ;-). Wymyśliłem nawet nazwę - Appes, zbitka słów apes (małpy) i application. A czemu te małpy? Bo zmienne będą zaczynały się od małpy: @zmienna1. Pomysł jest taki, że pisze się makra-funkcje, z użyciem zmiennych, w języku w miarę naturalnym, a kompilator rozwija je rekurencujnie aż dojdzie do instrukcji #napis, która generuje napis na wyjściu programu. Można generować napisy w dowolnym języku, bo to zwykłe są zwykłe teksty. Tak więc program może sam się skompilować, jeśłi rekurencyjnie wywołując funkcje-makra zejdzie do poziomu asemblera i jeśli jako #napisy będziemy generować kod maszynowy. Ja w przykładach generował będę kod w C. Można nawet w Fortranie, czy przysłowiowym Cobolu ;-).
Wypadałoby napisać kompletny program Hello World w Appesie. Nieliczne słowa kluczowe zaczynają się od podkreślenia:
_code definiuje funkcję-makro, która może zawierać wywołania innych funkcji-makr albo polecenia generowania kodu #.
_use CPrintf; // wywołaj funkcję-makro _code _use CPrintf{}, wygeneruje tu @includa
start; // wywołaj funkcję-makro _code start{}, wygeneruje tu nagłowek funkcji języka C main() i nawias klamrowy {.
przywitaj sie;
stop z sukcesem
_code _use CPrintf
{
#include <stdio.h> // ciało makra. Tu generujemy kod w C, ale możemy też wywoływać inne funkcje-makra ze @zmiennymi
}
_code start
{
#int main();
#{
}
_code przywitaj sie
{
#printf("Hello World!\n");
}
_code stop z sukcesem
{
# return 0;
#}
}
w ogólności wywołanie funkcji-makr:
_use Int cena1;
_use StosInt stos1;
wrzuć @cena1 na stos liczb @stos1
sprowadza się do rozwinięcia (albo wywołania jako funkcja, żeby kod się nie rozdął) funkcji-makra:
_code wrzuć Int @liczba na StosInt @stos
{
//... wywołania innych funkcji-makr ze zmiennymi i/lub generowanie kodu wynikowego
}
Typy rozróżniamy od zmiennych i innych fragmentów kodu programu po dużej literze na początku wyrazu.
Zgodnie z przyjętą przeze mnie konwencją definiujemy typy i zmienne za pomocą słowa kluczowego _use. Np:
_use Osoba // wygeneruje się definicja struct Osoba w języku C, wg ciała funkcji-makra poniżej.
_code _use Osoba
{
#struct Osoba
#{
#char *imie;
#int osoba;
#};
}
analogicznie:
_use Osoba @osoba1
_code _use Osoba @var
{
#struct Osoba @@@var; // tutaj @@@var oznacza nazwe bez małpy parametru aktualnego w wywołaniu funkcji-makra, czyli osoba1.
// @@var oznaczałoby @osoba1, ale tutaj musimy pozbyć się @ z przodu, dlatego jest @@@var.
}
To na razie tyle, będę pisał więcej wkrótce.