Witam. Od nie dawna piszę prostą grę w Delphi. Chciałbym napisać do niej banalny silnik mojego własnego języka interpretowanego. W jaki sposób mógłbym to napisać aby program czytając z pliku tekstowego rozumiał proste komendy (bez argumentów, lub max 1), i wykonywał czynności do nich przypisane?
Musisz sobie zadac pytanie czy kod ma byc kompilowany do jezyka posredniego, do kodu maszynowego (bytecode) czy po prostu interpretowany linia po linii.
W ostatnim przypadku nie potrzeba wiele filozofii jesli chcesz postawic na prostote.
repeat
s:=lines.strings[i];
rozbijnawyrazy(s);//rozbij, twoja funkcja
if wyraz[0]='showmessage' then showmessage(wyraz[1]);
inc(i);
until i>=lines.count-1;
Tak, miałby to być bardzo prosty tekst interpretowany linia po linii. Jednak czy mógłbyś mi bardziej wytłumaczyć jak użyć metody podanej przez Ciebie?
Podaj przykład tego Twojego "języka".
Zapewne każda komenda składa się z początku i końca, może to być spacja; (średnik) i to co pomiędzy interpretujesz. Może to być kolejna linijka w tekście.
Wszystko sprowadza się do wyciągania pojedynczych wyrazów/linijek tekstu i wykonywaniu tego co mówią.
Tak więc, proszę o przykład który działałby w ten sposób. Mam komponent Memo do którego wczytuje wcześniej napisany 'skrypt'. Silnik działa w ten sposób że wtedy kiedy ja zadecyduje, interpretuje wcześniej wczytany kod z Memo linia po linii, zważając na ustalone przeze mnie komendy. Już nie chcę żadnych argumentów. Po prostu proszę o kod banalnego programu.
Kodu nie dostaniesz. Ale wskazowki tak:
Przyjmijmy ze skladnia takiego jezyka jest nastepujaca:
Plik test.txt:
set str1 "ala ma kota"
set str2 "kot ma ale"
set str3 str1 + str2
set x 10
inc x 30
log "dziala! " + str3 + "x: " + x
Idac pokolei:
1. Pobierz kolejna linie skryptu
2. Rozdziel na slowa z uwzglednieniem ", +, itd (znaki lacznosci)
3. Jesli pierwszy parametr to :
SET
- ustaw zmienna - parametr2 o wartości parametr3
INC
- zwieksz zawartosc zmiennej parametr2 o wartosc parametr3 (jesli parametr3 nie istnieje to zwieksz o 1)
LOG
- dodaj do jakiejs konsolki parametr2
Nie jest to jezyk kompletny w sensie maszyny turinga. Nie jest to jednak taka typowa analiza leksykalna. Analiza leksykalna opiera sie na tym ze musisz caly skrypt rozdzielic na pojedyncze 'tokeny'. Wtedy kolejne bloki typu begin/end opieraja sie na skokach... Piszac swoj kompilator na pewno docenisz zalety z analizy leksykalnej z prawdziwego zdarzenia.
Ale nie wiem jaka w tym filozofia ? Musisz troszke pomyslec, a jak dobrze pomyslisz to zrobisz porzadny jezyk skryptowy. Jezeli nie potrafisz operowac na ciagach znakow to musisz zajrzec do kursu. Pewnych rzeczy nie przeskoczysz.
Dzięki za odpowiedź. Ja wpadłem na pomysł aby zrobić to w bardzo prosty sposób.
begin
begin
repeat
wyraz:=Memo1.Lines.Strings[i];
if wyraz='showmessage' then showmessage('test')
else if wyraz='exit' then Form1.Close
else if wyraz='test' then showmessage('test 1')
else if wyraz='' then exit
else exit;
inc(i);
until
i=100;
end;
i:=0;
end;
Jednak kiedy klikam button wykonuje komendy tylko za pierwszym razem przez to że nie wiem jak na końcu wyzerować wartość zmiennej 'i'. Zresztą spójrz w kod będziesz wiedzieć o co mi chodzi.
#EDIT:
Poradziłem sobie z tym w ten sposób:
begin
begin
repeat
s:=Memo1.Lines.Count;
wyraz:=Memo1.Lines.Strings[i];
if wyraz='showmessage' then showmessage('test')
else if wyraz='exit' then Form1.Close
else if wyraz='test' then showmessage('test 1')
else exit;
i:=i+1;
until
i=s;
end;
i:=0;
end;
#EDIT:
Jeszcze mam jedno pytanie, jak w instrukcji warunkowej sprawdzić tylko część wartości zmiennej. Na przykład miałbym zmienną 'punkty_zycia=10' i chciałbym żeby Delphi sprawdzał do na przykład 10 znaku. Dzięki temu mógłbym odczytać wartość (tutaj jest to 10) i użyć jej do własnych potrzeb. Czytałem gdzieś na 4p o stringach ale nie znalazłem odpowiedzi na moje pytanie.
Jeżeli dobrze zrozumiałem i chodzi Tobie o string to Copy(JakisString, 1, IleZnakow);
Dzięki, poradziłem sobie.