Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
AndT
Anmeldungsdatum: 02.04.2007 Beiträge: 481
|
Verfasst am: 26.07.2007, 10:51 Titel: Kann man einen Basicinterpreter in FB programmieren? |
|
|
Die Überschrifft sagt schon alles.
Also ich möchte versuchen einen Interpreter zu schreiben der einfache Befehle wie
DO..LOOP, PRINT, INPUT, GOTO, IF beherscht.
Er soll 64 Variablen speichern können.
Mehr verlange ich auch nicht.
Nur das Problem:
Wie lässt sich sowas umsetzen oder ist es sogar mit wenig aufwand möglich FB komplett zu interpretieren? _________________ Bis irgendwann...  |
|
Nach oben |
|
 |
Eternal_pain

Anmeldungsdatum: 08.08.2006 Beiträge: 1783 Wohnort: BW/KA
|
Verfasst am: 26.07.2007, 11:04 Titel: |
|
|
ich stelle mir das gar nicht mal so kompliziert vor... aber vielleicht denke ich mir das ganze auch nur zu einfach...
Ich wuerde es so angehen;
die zu interpretierende Datei oeffnen, und dann auseinandernehmen...
alles faengt mit einem Befehl an... dann folgen evtl. Parameter.. das ganze muss man auseinandernehmen und der function uebergeben....
wenn man es wie in C/C++ angehen wuerde, wuerde es unter umstaenden das ganze sogar noch vereinfachen, weil jede Zeile, bzw Befehlszeile mit einem ";" aufhoert... _________________
 |
|
Nach oben |
|
 |
AndT
Anmeldungsdatum: 02.04.2007 Beiträge: 481
|
Verfasst am: 26.07.2007, 11:19 Titel: |
|
|
Danke für die schnelle Antwort
Der Loader hab ich schon fertig
Code: |
sub _zprint (text as String)
print
locate ,40-len(text)/2
print text
end sub
sub LeftProgramm
_ZPrint "*** Das Programm wird jetzt beendet ***"
close #1
_Zprint "Zum beenden bitte jetzt eine Taste druecken . . ."
color 7
sleep
system
end sub
sub _Freememprint
_zprint "Freier Speicher = "+str(fre/1024)+" kb"
end sub
' Einstellungen
const as string _version = "0.01 testing"
const as integer MaxCode = 640000
const as integer StandardFarbe = 7
const as integer EventFarbe = 15
const as integer LowMemDect=300000
' Programm
color StandardFarbe
_zprint "*** AndT's Basic Interpreter Version " + _Version + " ***"
_Freememprint
if fre/1024 < LowMemDect then color EventFarbe:_zprint "Hinweis: Speicherprobleme!":color StandardFarbe
open command for input as #1
IF lof(1)= 0 then color eventfarbe :_zprint "Fehler : Datei nicht gefunden oder vorhanden :o":_Zprint "Syntax : eb.exe Dateineme" : LeftProgramm
dim as string Dateigroese
if lof(1) < 1024 then Dateigroese= str(lof(1))+" byte" else Dateigroese= str(lof(1)/1024)+" kb"
if lof(1) > 1000000 then Dateigroese = str(lof(1)/(1024*1024))+ " mb"
_zprint "Dateigrösse ("+command+") = "+Dateigroese
color EventFarbe
_zprint "** Lade **"
color standardFarbe
_zprint "Initalisiere die Datei..."
dim as integer CodeNrs
dim as string dummy
do
input #1,dummy
If CodeNrs < MaxCode Then
codenrs+=1
else
color EventFarbe :
_zPrint "Fehler : Der Code ist zu komplex!":
_zPrint "Der Code wird bei <<<<<"+dummy+">>>>> (Zeile" + str (CodeNrs)+") einfach abgeschnitten!":
color standardfarbe:
exit do
end if
loop until eof(1)
_zprint "Datei initalisiert."
close #1
_zprint "Programm wird in den Speicher geladen...."
dim as string Code(1 to CodeNrs)
dim as integer CodeNr
open command for input as #1
for CodeNr= 1 to CodeNrs
input #1,Code(CodeNr)
Next
color EventFarbe
_zprint "*** Laden abgeschlossen ***"
color StandardFarbe
close #1
_Freememprint
sleep
_zprint "" |
kann man das so stehen lassen? _________________ Bis irgendwann...  |
|
Nach oben |
|
 |
Eternal_pain

Anmeldungsdatum: 08.08.2006 Beiträge: 1783 Wohnort: BW/KA
|
Verfasst am: 26.07.2007, 11:25 Titel: |
|
|
kein Problem
ist eigentlich keine schlechte Idee es selbt mal zu versuchen, einen simplen Interpreter zu basteln... _________________
 |
|
Nach oben |
|
 |
csde_rats

Anmeldungsdatum: 07.01.2007 Beiträge: 2292 Wohnort: Zwischen Sessel und Tastatur
|
|
Nach oben |
|
 |
Eternal_pain

Anmeldungsdatum: 08.08.2006 Beiträge: 1783 Wohnort: BW/KA
|
Verfasst am: 26.07.2007, 11:33 Titel: |
|
|
Zitat: | Das Prinzip
Das Prinzip eines Interpreters, einer ScriptEngine, ist simpel. Ein Script wird von der ersten Zeile an Zeile für Zeile interpretiert und ausgeführt. Der Knackpunkt ist dabei die ZEILE. Jede Zeile muß "zerpflückt" und analysiert werden. Je nach Ergebnis erfolgt dann die Reaktion, d.h. die Ausführung einer oder mehrerer Routinen die diesen Befehl beschreiben. Die Art, Weise und der Aufwand der betrieben werden muß um eine Zeile zu analysieren, hängt vom Syntax und Befehlsumfang der Sprache ab.
|
was ich damit meinte auch wenn ich mich nicht so gut ausgedrueckt habe
Edit:
Hab den Source erst jetzt gesehen
Sieht schon ganz nett aus, aber es sieht so aus als wolltest das komplette Script speichern ? waere es nicht sinnvoller es stueck fuer stueck auseinander zu nehmen und zu verarbeiten ? _________________
 |
|
Nach oben |
|
 |
csde_rats

Anmeldungsdatum: 07.01.2007 Beiträge: 2292 Wohnort: Zwischen Sessel und Tastatur
|
|
Nach oben |
|
 |
Mao
Anmeldungsdatum: 25.09.2005 Beiträge: 4409 Wohnort: /dev/hda1
|
Verfasst am: 26.07.2007, 11:55 Titel: |
|
|
Man kann natürlich auf der einen Seite den Weg wählen, einen "einfachen" Scriptsprachen-Interpreter zu entwickeln. Auf der anderen Seite kann man das aber auch komplexer machen und über das Script/den Source mehrmals "drüberfahren", in verschiedenen Stufen. So behält man sich die Möglichkeit vor, eine ASM-Ausgabe drumherum zu bauen.
Für die ersten Versuche würd ich aber ersteres empfehlen, ist wenn man was funktionelles haben will, auch alles andere als leicht. (PHP und Perl z.B., auch "nur" Scriptsprachen)
Vielleicht hilft dir auch eine der beiden Einsendungen zum QB-Wettbewerb beim Thema "Interpreterbau": Zur Aufgabe. _________________ Eine handvoll Glück reicht nie für zwei.
--
 |
|
Nach oben |
|
 |
AndT
Anmeldungsdatum: 02.04.2007 Beiträge: 481
|
Verfasst am: 26.07.2007, 11:59 Titel: |
|
|
Ich hab mir gedacht, erst den kompletten Code zu laden und dann auseinaneder zunehmen und auszuführen.
Sonst müsste er ja jede einzene Zeile laden und ausführen, was der Performance nicht gerade zugute kommt
Im Arbeitsspeicher geht das ja schneller. Die gleiche Engine hab ich ja schon in meinem Easybasic http://forum.qbasic.at/viewtopic.php?t=4470 eingesetzt.
Nur irgendwie hat mir das noch nicht so ganz gefallen und das Projekt eingestellt.
Naja dann habe ich mir gedacht ich schreib das nochmal und löse es diesmal richtig  _________________ Bis irgendwann...  |
|
Nach oben |
|
 |
Mao
Anmeldungsdatum: 25.09.2005 Beiträge: 4409 Wohnort: /dev/hda1
|
Verfasst am: 26.07.2007, 12:02 Titel: |
|
|
FB ist z.B. komplett in FB selbst geschrieben.
Was beweißt, dass ein Interpreter auf jeden möglich ist.
Das mit Zeile laden, danach auseinander nehmen, Zeile laden, ... sollte nicht das Problem sein. _________________ Eine handvoll Glück reicht nie für zwei.
--
 |
|
Nach oben |
|
 |
Eternal_pain

Anmeldungsdatum: 08.08.2006 Beiträge: 1783 Wohnort: BW/KA
|
Verfasst am: 26.07.2007, 12:06 Titel: |
|
|
ich glaube das tut der performance keinen abbruch.
Das ganze wuerde ich aehnlich handhaben wie verschiedene meiner getHTTP versuchen...
man empfaengt einen block(string) von x bytes und uebergibt ihn einer funktion... der block wird abgearbeitet, zB bis zu einem Zeilenbruch bzw bis zum letzten Zeilenbruch oder nicht abgeschlossenen Befehl (wie zB bei HTML Tags) der Rest wird behalten... _________________
 |
|
Nach oben |
|
 |
csde_rats

Anmeldungsdatum: 07.01.2007 Beiträge: 2292 Wohnort: Zwischen Sessel und Tastatur
|
Verfasst am: 26.07.2007, 12:06 Titel: |
|
|
In dem Tutorial ist z.B. die eigentliche Interpreterschleife nicht sehr effektiv:
Code: | FOR L = 0 TO 39
FOR B = 0 TO 5
IF BEFEHL$(B) = LEFT$(UCASE$(SCRIPT$(L)), LEN(BEFEHL$(B))) THEN Ergebnis = B: EXIT FOR ELSE Ergebnis = 6
NEXT
[...]
NEXT |
In Zeile 2 wird nämlich Zeile 3 sooft ausgeführt, wie groß die Anzahl der Befehle ist, also bei einer richtigen Sprache 400-800 (schätz ich mal)! Dieser Interpreter wäre also sehr langsam... _________________ If hilfreicher_Beitrag then klick(location.here)
Klick |
|
Nach oben |
|
 |
AndT
Anmeldungsdatum: 02.04.2007 Beiträge: 481
|
Verfasst am: 26.07.2007, 12:11 Titel: |
|
|
Mal sehn was draus wird  _________________ Bis irgendwann...  |
|
Nach oben |
|
 |
Mao
Anmeldungsdatum: 25.09.2005 Beiträge: 4409 Wohnort: /dev/hda1
|
Verfasst am: 26.07.2007, 12:17 Titel: |
|
|
@csderats:
Du unterschätzt die Leistungsfähigkeit von selbst relativ alten Computern.
Zudem sind Script- und Programmiersprachen zumeist in Module aufgeteilt. Das heißt, es bräuchten nur die eingebundenen Module am Anfang in den Speicher geladen werden (inklusive deren "Befehle") und diese List überprüft. _________________ Eine handvoll Glück reicht nie für zwei.
--
 |
|
Nach oben |
|
 |
AndT
Anmeldungsdatum: 02.04.2007 Beiträge: 481
|
Verfasst am: 26.07.2007, 13:04 Titel: |
|
|
Ich hab den Code inzwischen schon eine erkennungroutine gegeben
(Einfach das hier dranhängen )
Code: |
DIM AS STRING Befehl ,TmpBefehl, Anhang,Char,Ausgabe
DIM AS Integer CursPos,Rec
CodeNr=0 ' Zeile resetten
color eventfarbe
_zprint "*** Programm gestartet ***"
DO
cmd=0
Befehl=""
Anhang=""
Char=""
CodeNr+=1
Befehl=Code(CodeNr)
print "Debug: Befehl=";Befehl
For CursPos=1 to Len(Befehl)
TmpBefehl+=lcase (MID(Befehl,CursPos,1))
If TmpBefehl = "print" Then CMD=1:exit for
If TmpBefehl = "input" Then CMD=2:exit for
IF TmpBefehl = "do" THEN CMD=3:exit for
If TmpBefehl = "loop" THEN CMD=4:exit for
Next
TmpBefehl=""
' Print Befehl
If CMD= 1 then
Print "Print erkannt!"
end if
IF CMD= 2 then
Print "Input erkannt!"
end if
If CMD= 3 then
Print "Do erkannt!"
end if
If CMD= 4 then
Print "Loop erkannt!"
end if
If CMD = 0 then
Print "Befehl nicht erkannt (Zeile): ";CodeNr
end if
LOOP until CodeNr=CodeNrs
|
_________________ Bis irgendwann...  |
|
Nach oben |
|
 |
Mao
Anmeldungsdatum: 25.09.2005 Beiträge: 4409 Wohnort: /dev/hda1
|
Verfasst am: 26.07.2007, 13:07 Titel: |
|
|
Ohoh...
Schau dir mal SELECT CASE an.  _________________ Eine handvoll Glück reicht nie für zwei.
--
 |
|
Nach oben |
|
 |
AndT
Anmeldungsdatum: 02.04.2007 Beiträge: 481
|
Verfasst am: 26.07.2007, 13:15 Titel: |
|
|
so passts besser oder?
Code: |
select case cmd
case 1
Print "Print erkannt!"
case 2
Print "Input erkannt!"
case 3
Print "Do erkannt!"
case 4
Print "Loop erkannt!"
case 0
Print "Befehl nicht erkannt (Zeile): ";CodeNr
end select |
_________________ Bis irgendwann...  |
|
Nach oben |
|
 |
Eternal_pain

Anmeldungsdatum: 08.08.2006 Beiträge: 1783 Wohnort: BW/KA
|
Verfasst am: 26.07.2007, 13:17 Titel: |
|
|
das gleiche kann ma auch noch mit TmpBefehl machen  _________________
 |
|
Nach oben |
|
 |
csde_rats

Anmeldungsdatum: 07.01.2007 Beiträge: 2292 Wohnort: Zwischen Sessel und Tastatur
|
Verfasst am: 26.07.2007, 13:29 Titel: |
|
|
Anderer Vorschlag: CMD enthält 0 bei ungültigen Befehl, und 1 bei gültigen. dass sähe dann so aus:
Code: |
' Befehl validieren
If TmpBefehl = "print" Then CMD=1:exit for
If TmpBefehl = "input" Then CMD=1:exit for
IF TmpBefehl = "do" THEN CMD=1:exit for
If TmpBefehl = "loop" THEN CMD=1:exit for
Next
TmpBefehl=""
If CMD = 1 then
Print TmpBefehl + "erkannt!"
else
Print "Befehl nicht erkannt (Zeile): ";CodeNr
end if
LOOP until CodeNr=CodeNrs |
_________________ If hilfreicher_Beitrag then klick(location.here)
Klick |
|
Nach oben |
|
 |
AndT
Anmeldungsdatum: 02.04.2007 Beiträge: 481
|
Verfasst am: 26.07.2007, 13:41 Titel: |
|
|
Cmd soll die ID für den Befehl sein.
Also nicht
/// Edit:
Print "Geht schon"
Code: |
DIM AS STRING Befehl ,TmpBefehl, Anhang,Char,Ausgabe
DIM AS Integer CursPos,Rec,CursPos2
CodeNr=0 ' Zeile resetten
color eventfarbe
_zprint "*** Programm gestartet ***"
DO
cmd=0
Befehl=""
Anhang=""
Char=""
CodeNr+=1
Befehl=Code(CodeNr)
print "Debug: Befehl=";Befehl
For CursPos=1 to Len(Befehl)
TmpBefehl+=lcase (MID(Befehl,CursPos,1))
Select Case TmpBefehl
case "print"
CMD=1
exit for
case "input"
CMD=2
exit for
case "do"
CMD=3
exit for
case "loop"
CMD=4
exit for
end select
Next
TmpBefehl=""
select case cmd
' Print
case 1
DO
curspos+=1
If MID(Befehl,curspos,1) = """" Then
If Rec=1 then Rec=0:Exit do
end if
IF MID(Befehl,curspos,1) = """" Then Rec=1:curspos+=1
If Rec=1 then Ausgabe+=MID(Befehl,curspos,1)
LOOP
Print Ausgabe
' Input
case 2
Print "Input erkannt!"
case 3
Print "Do erkannt!"
case 4
Print "Loop erkannt!"
case 0
Print "Befehl nicht erkannt (Zeile): ";CodeNr
end select
LOOP until CodeNr=CodeNrs |
_________________ Bis irgendwann... 
Zuletzt bearbeitet von AndT am 26.07.2007, 13:59, insgesamt einmal bearbeitet |
|
Nach oben |
|
 |
|