UPN Rechner (mit Stack)

Übersicht BlitzBasic Codearchiv

Neue Antwort erstellen

Eingeproggt

Betreff: UPN Rechner (mit Stack)

BeitragFr, Jan 15, 2010 16:30
Antworten mit Zitat
Benutzer-Profile anzeigen
Schönen, grauen, öden Winternachmittag!

Heut auf der Uni wurden wir 2 Stunden lang belehrt wie man arithmetische Ausdrücke parsen könnte - höchst interessant aber klarerweise recht aufwendig (Leute mit Erfahrungen im Bereich Skriptsprachen wissen was ich meine - ihr könnt euch ja auch ein BB Beispiel dazu hier ansehen)
Währenddessen kam mir wieder in den Sinn wie einfach es doch im Vergleich dazu ist, einen UPN-Rechner zu schreiben - und hier ist er Smile
Ist mit runde 100 Zeilen ja recht handlich.

BlitzBasic: [AUSKLAPPEN]
;Beispiel / Benutzereingabe
Local in$
Repeat
in$=Input("Eingabe: ")
If in$="" Then Exit
ProcessUPN(in$)
Forever
End

;Hauptfunktion
Function ProcessUPN(in$)
;Vars
Local space
Local element$
in$=Trim(in$)+" "

stack_flush()
;Start
Repeat
;linkestes Element heraus schneiden...
space=Instr(in$," ")
element$=Left(in$,space-1)
;...und verarbeiten
If element$=Int(element$) Or Instr(element$,".")>0 Then
;Element ist eine Zahl
stack_push(Float(element$))
Else
;Element ist ein Operator
Calc(element$)
EndIf

in$=Right(in$,Len(in$)-space)
If in$="" Then Exit
Forever
;Ausgabe
PrintUPN()
End Function

;Führt die Berechnung je nach operation durch unter Verwendung des Stacks
;Erweiterungen wie zB Sin / Cos durch einfaches Ergänzen der Select-Case-Abfrage möglich
Function Calc(operator$)
Local result#
Local a#,b#
Select operator$
Case "+"
;Elemente in umgekehrter Reihenfolge vom Stack holen
b#=stack_pop()
a#=stack_pop()
;Ergebnis berechnen
result#=a+b
Case "-"
b#=stack_pop()
a#=stack_pop()
result#=a-b
Case "/"
b#=stack_pop()
a#=stack_pop()
result#=a/b
Case "*"
b#=stack_pop()
a#=stack_pop()
result#=a*b
Default
;Wenn keine bekannte Operation angegeben wird
RuntimeError(operator$+" ist keine gültige Operation")
End Select
;Ergebnis auf Stack schreiben
stack_push(result#)
End Function

;Inhalt des UPN-Stacks ausgeben (Achtung, Stack wird dabei geleert - nur für Endergebnis gedacht!)
Function PrintUPN()
While Not stack_empty
Print stack_pop#()
Wend
End Function

;Minimal-Implementierung eines (Float-)Stacks
Type stack
Field val#
End Type
Global stack_empty=True

Function stack_push(var#)
Local stack.stack=New stack
stack\val#=var#
stack_empty=False
End Function

Function stack_pop#()
Local stack.stack=Last stack
If stack=Null Then
RuntimeError("Keine Elemente mehr auf Stack")
EndIf
Local ret#=stack\val#
Delete stack
If First stack=Null Then
stack_empty=True
EndIf
Return ret#
End Function

Function stack_flush()
Delete Each stack
stack_empty=True
End Function


Den dazu benötigte Stack hab ich mit Types realisiert - kann man sich ja herausnehmen falls man in brauchen sollte.

[EDIT 13.7.2010: Ich räume mein Archiv auf und dieser Screenshot fiel der Aktion zum Opfer... es gibt ohnehin nicht viel zu sehen]

mfG, Christoph.
Gewinner des BCC 18, 33 und 65 sowie MiniBCC 9
  • Zuletzt bearbeitet von Eingeproggt am Di, Jul 13, 2010 0:11, insgesamt einmal bearbeitet

count-doku

BeitragFr, Jan 15, 2010 18:11
Antworten mit Zitat
Benutzer-Profile anzeigen
Hi,


einfach genial einfach.


mfg,
count-doku

Neue Antwort erstellen


Übersicht BlitzBasic Codearchiv

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group