Seite 2 von 3

Verfasst: 16.04.2008 19:46
von STARGÅTE
habs mir mal angesehen:
WIKI

im prinzip schon fast, wie ich dachte, die "Befehle" sind nur noch einzelne Bytes.
Es wird also viel mit goto gearbeitet, wobei das mehr als Pointer aufgefasst werden sollte, sodass bei einer IF abfrage die Abfrage selber irgendwo steht und der Code wenn es wahr ist an einer ander position.
Zahlen usw. werden dann komplett als LONG/FLOAT/DOUBLE ... gespeichert.

Im Bytecode sollte also nirgends mehr ein "FindString" auftauchen, um irgendwas zu suchen, was ja lange dauert.

Mein Code würde dann vllt so aussehen: (wobei hier alles Ausgeschrieben ist, was nachher Zeichen sind)

Code: Alles auswählen

0001 IF__ 0010 0020 0030
0010 GLEI 0011 0012
0011 GET_ 0001
0012 GET_ 0002 
0020 SET_ 0001 0001
0030 END_
meine 4Stelligen Zahlen wären dann LONGs im Speicher und auch die Befehle wäre LONGs.
Sodass die 1. LONG gelesen wird, wenn diese Zahl für "IF" steht, werden 3 weitere "gehe zu" LONGs gelesen (Aussage, Wahr, Falsch)

werde mich heute mal ransetzten und gucken wie gut das geht...

Verfasst: 16.04.2008 20:00
von NicTheQuick
Im Grunde ist das einfachste Konzept folgendes:

Code: Alles auswählen

If MeineVar = DeineVar
  MeineVar = 2
EndIf
wird zu

Code: Alles auswählen

IF, VAR "MeineVar", EQUAL, VAR "DeineVar", VAR "MeineVar", EQUAL, LONG "2", ENDIF
und das wird zu

Code: Alles auswählen

IF(EQUAL(VAR "MeineVar", VAR "DeineVar"), SET(VAR "MeineVar", LONG "2"), NOTHING)
und das ist dann deine Baumstruktur, die du rekursiv gebaut hat. IF,
EQUAL, VAR, SET, LONG und NOTHING sind alles Konstanten vom selben
Typ, für die entweder keine (NOTHING), einer (VAR, LONG), zwei (EQUAL,
SET) oder drei (IF) Parameter festgelegt sind. Mehr wären natürlich auch
möglich.
Deswegen kannst du das dann alles auch einfach aneinander reihen:

Code: Alles auswählen

IF, EQUAL, VAR "MeineVar", VAR "MeineVar", SET, VAR "MeineVar", LONG "2", NOTHING
Dann rufst du zuerst die IF-Procedure auf. Diese liest dann EQUAL und ruft
dann die EQUAL-Procedure auf, die dann die beiden VAR liest und die
dazugehörigen Werte, dann vergleicht und zurückgibt, damit IF da
weiterarbeiten kann, wo EQUAL aufgehört hat.
Ich hab selbst letztens einen Parser gebastelt und da hat sich diese
Vorgehensweise bewährt, weil es einfach keine Probleme damit geben
kann. Nicht umsonst wird es so im Informatikstudium beigebracht.

Verfasst: 16.04.2008 20:07
von STARGÅTE
und den Inhalt der Variablen sollte der mit im Bytecode drinne stecken (also zB am ende, einfach aneinander gereiht). und beim Ausführen des Codes, wirde dann an der jeweiligen GET SET stelle auf den Pointer der in den ByteCode verweist zugegriffe, oder sollte das "außerhalb" liegen bleiben, in dem fall in PB und dann die Pointer bei SET GET angeben wo die Inhalten im Speicher stehen (aber halt im Speicher des Programms was den Code ausführt.)

Verfasst: 16.04.2008 20:13
von NicTheQuick
Naja, das bleibt dir überlassen. Für eine Skriptsprache würde sich wohl
beides lohnen. Schleifenvariablen für For-Next-Schleifen initialisierst du selbst
und schreibst sie zum Beispiel ans Ende. Werte, die dir das andere Programm
übergibt, könntest du als Pointer behalten und entsprechenden manipulieren
oder du kopierst den Wert, weil er nicht manipuliert werden soll. Das bleibt
dir überlassen. Je nachdem wie umfangreich du das ganze machen willst.

Verfasst: 16.04.2008 20:14
von Hroudtwolf
Variablen-Definitionswerte kannst du in einer Datasection des Bytecodes unterbringen und bei Scriptstart in den Speicher als ganzes Laden lassen.
So brauchst du im Bytecode keinen Collector akquirieren um an Werte zu kommen sondern brauchst nur Offsets im Bytecode speichern.
Diese Offsets sind dann while Runtime + der Adresse der DataSection im RAM immer die Adressen der Variablen-Werte.

So mach ich das seit einer Weile in einer VM.

MfG

Wolf

Verfasst: 16.04.2008 20:21
von ZeHa
Konstanten stehen natürlich direkt im Bytecode, Variablen dagegen nur als Adresse.

Daher ist es auch üblich, für ein und dieselbe Operation mehrere Opcodes zu definieren. Wenn Du in Assembler programmierst, benutzt Du z.B. immer CMP als Vergleich, aber CMP hat im Maschinencode nicht generell den gleichen Bytewert, sondern es gibt sozusagen ein "CMP addr, const" und ein "CMP addr, addr". Anstatt also statt CMP z.B. den Wert 43 zu verwenden, verwendest Du z.B. für den ersten Fall eine 43 und für den zweiten eine 44.

Wenn Dein Interpreter nun eine 43 einliest, liest er zwei weitere Werte ein und interpretiert den ersten als Adresse, holt den Wert und vergleicht ihn mit dem zweiten Wert. Bei der 44 interpretiert er eben beide Werte als Adresse.


EDIT: Auch für unterschiedliche Datentypen ist das so, z.B. kann es ein "CMP addr, long const" geben oder ein "CMP addr, short const" etc, aber das ist dann etwas aufwendiger. Für 'ne einfache Skriptsprache würde ich einfach generell mit 32-bit-Werten arbeiten, denn auf 'nem 32-bit-Rechner braucht ein Byte und ein Short ebenfalls 32 bit. Du mußt jedoch natürlich Ganzzahl von Float unterscheiden, halt je nachdem wie krass Deine Skriptsprache werden soll.

Natürlich kannst Du auch nur einen einzigen Opcode verwenden und alles andere live entscheiden, das wird aber immer langsamer sein.

Verfasst: 16.04.2008 20:27
von STARGÅTE
ok danke für die infos

Verfasst: 16.04.2008 20:41
von X0r
Servus,

Dein Interpreter funktioniert leider noch nicht richtig.
Irgendwie erinnert mich das an einen gewissen "Alwin"... :wink:
Bei einer Betaversion muss man mit Bugs und fehlenden Funktionen rechnen.

Einfache Matheops führt er nicht durch.

Code:

decl var;
$var=2;
$var=$var+3;
Debug($var);
Kommt dann in der nächsten Version(falls es eine nächste gibt).


Das hier führt in einer Endlosschleife:
Code:
decl var;
$var=2;
for($var=1;$var<20;$var++){
Debug($var)
}
Debug($var)
Ich nehme daher an dass du keinen Lexer einsetzt.
Wurde ja bereits indirekt erwähnt.
Also den String on the Fly durchkämst. Das ist nicht besonders beeindruckend.
Das ist Ansichtssache. So lange etwas funktioniert(wenns fertig ist), ists mir egal, wie es gemacht ist.
Ich habe bisher noch nicht die Zeit gefunden, mich mit lexikalischer Analyse zu befassen. Sicher, jemand hatte hier ja mal was für PB geschrieben. Aber kopieren und dann leicht abändern ... :roll:

Verfasst: 16.04.2008 20:52
von Hroudtwolf
Bei einer Betaversion muss man mit Bugs und fehlenden Funktionen rechnen.
http://de.wikipedia.org/wiki/Entwicklun ... ta-Version

Verfasst: 16.04.2008 20:57
von X0r
Schon klasse, dieses Wikipedia. Aber mehr als "nicht exakt definiert" sagts mir auch nicht. :lol: