2011-12-18 15:04:21 +01:00

210 lines
4.2 KiB
Plaintext

!
! Implementation of a simple calculator in Triangle by
! - Alexander Constantin constant@rbg.informatik.tu-darmstadt.de
! - Nico Rottstädt rottstae@rbg.informatik.tu-darmstadt.de
!
! This is an excercise from A. Koch's Lecture "Optimierende Compiler",
! summer term 2006 at TU Darmstadt / Germany, course homepage (German):
! http://www.esa.informatik.tu-darmstadt.de/twiki/bin/view/Lectures/OptimierendeCompilerDe.html
!
let
! --------------
! String support
! --------------
type String ~ record
Str: array 80 of Char
end;
! Fill a string
proc readstring(var strg: String) ~
let
var chint: Char;
var length: Integer;
var testeol : Boolean;
var testeof : Boolean
in begin
length := 0;
eol(var testeol);
eof(var testeof);
while \ testeol /\ \ testeof do begin
get(var chint);
strg.Str[length] := chint;
length := length + 1;
eol(var testeol);
eof(var testeof);
end;
strg.Str[length-2] := '\';
end;
! Print a string
proc putstring(var strg: String) ~
let
var i: Integer
in begin
i := 0;
while \ (strg.Str[i] = '\') do begin
put(strg.Str[i]);
i := i + 1;
end;
end;
! Eliminate spaces in a string
proc removeSpacesFromString(var strg: String) ~
let
var counter : Integer;
var tmpArray : array 80 of Char;
var tmpCounter : Integer
in begin
counter := 0;
tmpCounter := 0;
while (strg.Str[counter] \= '\') do begin
if (strg.Str[counter] \= ' ') then
begin
tmpArray[tmpCounter] := strg.Str[counter];
tmpCounter := tmpCounter + 1;
end
else;
counter := counter + 1;
end;
tmpArray[tmpCounter] := strg.Str[counter]; ! copy \
strg.Str := tmpArray
end;
! ---------------
! Integer support
! ---------------
func isDigit(c:Char) : Boolean ~
(c = '0') \/ (c = '1') \/ (c = '2') \/ (c = '3') \/ (c = '4') \/
(c = '5') \/ (c = '6') \/ (c = '7') \/ (c = '8') \/ (c = '9');
! ord('0') = 48
! ...
! ord('9') = 57
func convertCharToInt(c:Char) : Integer ~
ord(c) - 48;
! maxInt = 32767
! bei char arrays die einen geoesseren Wert darstellen kommt es zum overflow
proc readInteger(term: array 80 of Char, var i: Integer, var result: Integer) ~
let
var isNegative : Boolean
in begin
result := 0;
isNegative := false;
if (term[i] = '-') then
begin
isNegative := true;
i := i + 1;
end
else;
while (isDigit(term[i])) do begin
result := result * 10;
result := result + convertCharToInt(term[i]);
i := i + 1;
end;
if (isNegative) then
result := 0 - result
else
end;
! ----------------
! Calculator stuff
! ----------------
! allowed two digit operations: +, -, *, /
func doOperation(op1 : Integer, op2 : Integer, operator : Char) : Integer ~
if operator = '+' then
op1 + op2
else if operator = '-' then
op1 - op2
else if operator = '*' then
op1 * op2
else if operator = '/' then
op1 / op2
else
0;
! rekursives Parsen
proc parse(term: array 80 of Char, var i: Integer, var result: Integer) ~
let
var operand1: Integer;
var operand2: Integer;
var operator: Char
in begin
if (term[i] = '(') then
begin
i := i + 1;
parse(term, var i, var operand1);
operator := term[i];
i := i + 1;
parse(term, var i, var operand2);
if (term[i] \= ')') then
begin
put('E');
put('R');
put('R');
put('O');
put('R');
puteol()
end
else
! do operation here
i := i + 1;
result := doOperation(operand1, operand2, operator);
end
else
begin
readInteger(term, var i, var result)
end;
end;
! Main Program - "Calculator"
! ---------------------------
var term : String;
var result : Integer;
var i : Integer
in begin
i := 0;
! Prompt ausgeben
put('T');
put('e');
put('r');
put('m');
put(':');
put(' ');
! Einlesen des Terms
readstring(var term);
removeSpacesFromString(var term);
! start parsing
parse(term.Str, var i, var result);
! output result
puteol();
putstring(var term);
put(' ');
put('=');
put(' ');
putint(result);
puteol()
end