210 lines
4.2 KiB
Plaintext
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 |