Compilers-PA1

Introduction

This assignment asks you to write a short Cool program. The purpose is to acquaint you with the Cool language and to give you experience with some of the tools used in the course.A machine with only a single stack for storage is a stack machine. Consider the following very primitive language for programming a stack machine:

CommandMeaning
intpush the integer int on the stack
+push a ‘+’ on the stack
spush an ‘s’ on the stack
eevaluate the top of the stack (see below)
ddisplay contents of the stack
xstop

The ‘d’ command simply prints out the contents of the stack, one element per line, beginning with the top of the stack. The behavior of the ‘e’ command depends on the contents of the stack when ‘e’ is issued:

• If ‘+’ is on the top of the stack, then the ‘+’ is popped off the stack, the following two integers are popped and added, and the result is pushed back on the stack.

• If ‘s’ is on top of the stack, then the ‘s’ is popped and the following two items are swapped on the stack.

• If an integer is on top of the stack or the stack is empty, the stack is left unchanged.

Some tips about COOL-lang

First of all, it’s crucial to thoroughly read Sections 6 to 10 of the Cool manual and analyze the provided examples.

What’s more, if a method contains multiple statements,it is recommended to enclosed them in “{}” so that the code can be written in a more CPP-style manner.

Solution

According to the PA1 and the provided examples, obviously, the stack can be implemented as a head-insertion linked list by modifying the file “examples/list.cl”.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class List {

isNil() : Bool { true };

head() : String { { abort(); ""; } };

tail() : List { { abort(); self; } };

cons(i : String) : List {
(new Cons).init(i, self)
};

};

class Cons inherits List {

car : String; -- The element in this list cell

cdr : List; -- The rest of the list

isNil() : Bool { false };

head() : String { car };

tail() : List { cdr };

init(i : String, rest : List) : List {
{
car <- i;
cdr <- rest;
self;
}
};

};

Then, we need a method which could determine whether this machine needs to stop.

1
2
3
4
5
isFinish(str : String ) : Bool {
if str = "x" then false
else true
fi
};

We also need a method to display contents of the stack

1
2
3
4
5
6
7
8
9
10
print_list(l : List) : Object {
if l.isNil() then 0 else
if l.head()="#" then 0
else {
out_string(l.head());
out_string("\n");
print_list(l.tail());
}
fi fi
};

The most important thing is the “evaluate” method

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
evaluate(sta : List): List {
{
if sta.head() = "+" then {
sta <- sta.tail();
a <- transfer.a2i_aux(sta.head());
sta <- sta.tail();
b <- transfer.a2i_aux(sta.head());
sta <- sta.tail();
sta <- sta.cons(transfer.i2a_aux(a+b));
}
else if sta.head() = "s" then {
sta <- sta.tail();
s1 <- sta.head();
sta <- sta.tail();
s2 <- sta.head();
sta <- sta.tail();
sta <- sta.cons(s1);
sta <- sta.cons(s2);
}
else 0
fi fi;
sta;
}
};

note:

this is a pop operation

1
2
a <- transfer.a2i_aux(sta.head());
sta <- sta.tail();

this is a push operation

1
sta <- sta.cons(transfer.i2a_aux(a+b));

Finally, combining these methods in the main function

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
main(): Object {
{
out_string("> ");
input <- in_string();
stack <- stack.cons("#");
while isFinish(input) loop
{
if input = "d" then print_list(stack) else
if input = "e" then stack <- evaluate(stack) else
stack <- stack.cons(input) --int,+ or s
fi fi;
out_string("> ");
input <- in_string();
}
pool;
}
};

Here are all source code