@DaveS
Nach dem Fehlschlag vom Einstieg in die Programmierung mit SQL- Datenbank (hatte ich mir nach den Versprechungen von Microsoft im Anfängerlehrgang einfacher vorgestellt!) hatte ich zur Übung einen einfachen programmierbaren Taschenrechner mit UPN (Bekannt von HP-Rechnern) programmiert. Dieser Taschenrechner funktioniert inzwischen schon recht gut und muß nur noch bereinigt werden.
Ich möchte jetzt einen zweiten programmierbaren Taschenrechner zur Übung programmieren. Er soll einen Stack (X-, Y-, Z-, T- und LastX-Register), Speicher-Register für Daten R(0) bis R(999) und einen Programmspeicher (0000 bis 9999 mit je 3 Bytes) haben.
Mein jetziger Taschenrechner kann nur mit Double im Stack rechnen, hat einen Programmspeicher (000 bis 999 mit je 1 Byte) und hat die wichtigsten Funktionen wie +, -,*, /, ^, RUN, STOP, SST, BST.
Der Arbeitsspeicher wird bei meinem ersten Taschenrechner durch diese Klasse bereitgestellt:
Public Class Memory
Protected Shared _X As Double Usw.
Der Datenaustausch erfolgt über:
Public Shared Property X() Usw.
End Class Die Befehle und die Befehlsdecodierung werden über diese Klasse bereitgestellt:
Public Class Command
Public Shared Sub Multiply()
Memory.LastX = Memory.X
Memory.X = Memory.Y * Memory.X
Call StackDown()
Memory.MakeStackUp = True
End Sub ...
End Class Alle Befehle sind darin immer als Public Shared Sub bzw. Function in dieser Class enthalten.
Die Form Public Class Taschenrechner enthält den Code für die Tastatur-Buttons und die Anzeige in TextBoxen. Ist alles möglichst einfach gehalten…
Jetzt zur Aufgabe: Es wäre sehr schön, wenn die Register, ähnlich wie Variant, verschiedene Datentypen enthalten könnten. Mein jetziger Entwurf sieht folgende Lösung vor:
Byte 0 vom Register enthält die Information welcher Datentyp vorliegt:
Dim Typ As Byte Ab Byte 1 enthält ein Register die Daten As:
Long, Double, Decimal, Complex, String, Vektor2, Vektor3 , Date Der Code ist wie folgt geplant:
Memory.X.Typ=1
Memory.X.IntegerVar = 25
Memory.Y=Memory.X oder
Memory.X = Multiply(Memory.Y, Memory.X) wird z.B. 19 00 00 im Programmspeicher
Der programmierbare Befehl lautet:
Public Shared Function Multiply(X As RegisterVariant, Y As RegisterVariant) As _
RegisterVariant dann
Select Case mit X.Typ und Y.Typ Der Aufruf der eigentlichen Rechenfunktionen erfolgt mit Überladen. Das kann der Compiler ja leicht am Datentyp beim Aufruf zuordnen.
So kann der zweite Taschenrechner mit seinen Funktionen “gefüllt” werden.
Tja, das ist eine ganze Menge Überlegung drin. Union wäre günstig gewesen. Was nun? Ich brauche eine Idee.
Ich kann das Ganze auch einfach mit Structure programmieren und verschwendeten Speicherplatz in jedem Register in Kauf nehmen... |