Update TP04

This commit is contained in:
augustin64 2024-10-21 23:10:10 +02:00
parent 0651175da6
commit fcf4e29532
29 changed files with 576 additions and 40 deletions

View File

@ -3,24 +3,19 @@ LAB4 (simple code generation), MIF08 / CAP 2022-23
# Authors
YOUR NAME HERE
Augustin LUCAS
# Contents
TODO for STUDENTS : Say a bit about the code infrastructure ...
# Test design
TODO: explain your tests
# Design choices
TODO: explain your choices. How did you implement boolean not? Did you implement an extension?
Booleans are implemented as integers behind the scenes, but type-checking before compilation disables any casting mechanism.
As for the previous lab, the Fortran-like for-loop extension has been implemented.
# Known bugs
TODO: Bugs and limitations.
# Checklists
A check ([X]) means that the feature is implemented
@ -28,30 +23,30 @@ and *tested* with appropriate test cases.
## Code generation
- [ ] Number Atom
- [ ] Boolean Atom
- [ ] Id Atom
- [ ] Additive expression
- [ ] Multiplicative expression
- [ ] UnaryMinus expression
- [ ] Or expression
- [ ] And expression
- [ ] Equality expression
- [ ] Relational expression (! many cases -> many tests)
- [ ] Not expression
- [x] Number Atom
- [x] Boolean Atom
- [x] Id Atom
- [x] Additive expression
- [x] Multiplicative expression
- [x] UnaryMinus expression
- [x] Or expression
- [x] And expression
- [x] Equality expression
- [x] Relational expression (! many cases -> many tests)
- [x] Not expression
## Statements
- [ ] Prog, assignements
- [ ] While
- [ ] Cond Block
- [ ] If
- [ ] Nested ifs
- [ ] Nested whiles
- [x] Prog, assignements
- [x] While
- [x] Cond Block
- [x] If
- [x] Nested ifs
- [x] Nested whiles
## Allocation
- [ ] Naive allocation
- [ ] All in memory allocation
- [x] Naive allocation
- [x] All in memory allocation
- [ ] Massive tests of memory allocation

View File

@ -15,19 +15,21 @@ class AllInMemAllocator(Allocator):
after: List[Instruction] = []
new_args: List[Operand] = []
s_index = 0
for arg in old_instr.args():
for arg in old_instr.defined():
if isinstance(arg, Temporary):
s_index += 1
if arg in old_instr.used(): # needs to be read first
before.append(RiscV.ld(
S[s_index], arg.get_alloced_loc()
))
if arg in old_instr.defined(): # needs to be stored after
after.append(RiscV.sd(
S[s_index], arg.get_alloced_loc()
S[3], arg.get_alloced_loc()
))
new_args.append(S[s_index])
new_args.append(S[3])
else:
new_args.append(arg)
for i, arg in enumerate(old_instr.used(), 1):
if isinstance(arg, Temporary):
before.append(RiscV.ld(
S[i], arg.get_alloced_loc()
))
new_args.append(S[i])
else:
new_args.append(arg)

View File

@ -283,7 +283,7 @@ class MiniCCodeGen3AVisitor(MiniCVisitor):
print(Trees.toStringTree(ctx.stat_block(), [], self._parser))
# ltest <- fresh_label()
loop_test = self._current_function.fdata.fresh_label("loop_test")
loop_test = self._current_function.fdata.fresh_label("while_test")
# lendwhile <- fresh_label()
end_while = self._current_function.fdata.fresh_label("end_while")
# code.addLabel(ltest)
@ -329,3 +329,79 @@ class MiniCCodeGen3AVisitor(MiniCVisitor):
for stat in ctx.stat():
self._current_function.add_comment(Trees.toStringTree(stat, [], self._parser))
self.visit(stat)
def visitForStat(self, ctx) -> None:
def immediate_to_tmp(op):
if not isinstance(op, Operands.Immediate):
return op
new_op = self._current_function.fdata.fresh_tmp()
self._current_function.add_instruction(
RiscV.li(new_op, op))
return new_op
from_t = immediate_to_tmp(self.visit(ctx.expr(0)))
to_t = immediate_to_tmp(self.visit(ctx.expr(1)))
stride = Operands.Immediate(1)
if len(ctx.expr()) > 2:
stride = self.visit(ctx.expr(2))
stride = immediate_to_tmp(stride)
name = ctx.ID().getText()
if name not in self._symbol_table:
raise MiniCInternalError(
"Variable {} has not been declared before for loop".format(name))
variable = self._symbol_table[name] # variable acting as counter
for_test = self._current_function.fdata.fresh_label("forF_test")
end_for = self._current_function.fdata.fresh_label("end_forF")
body_for = self._current_function.fdata.fresh_label("body_forF")
neg_stride = self._current_function.fdata.fresh_label("neg_stride_forF")
counter = self._current_function.fdata.fresh_tmp() # real counter not affected by var. changes
# counter <- from
self._current_function.add_instruction(
RiscV.mv(counter, from_t))
#* for_test:
# var <- counter
# bge 0 stride neg_stride
# (positive stride here)
# ble counter to end_for
# j body
self._current_function.add_label(for_test)
self._current_function.add_instruction(
RiscV.mv(variable, counter))
self._current_function.add_instruction(
RiscV.conditional_jump(
neg_stride, Operands.ZERO,
Condition(MiniCParser.GTEQ), stride
))
self._current_function.add_instruction(
RiscV.conditional_jump(
end_for, counter,
Condition(MiniCParser.GTEQ), to_t
))
self._current_function.add_instruction(
RiscV.jump(body_for))
#* neg_stride:
# bl to counter end_for
self._current_function.add_label(neg_stride)
self._current_function.add_instruction(
RiscV.conditional_jump(
end_for, to_t,
Condition(MiniCParser.GTEQ), counter
))
#* body:
# <body>
# counter <- counter + stride
# j for_test
self._current_function.add_label(body_for)
self.visit(ctx.stat_block())
self._current_function.add_instruction(
RiscV.add(counter, counter, stride))
self._current_function.add_instruction(
RiscV.jump(for_test))
#* end_for:
self._current_function.add_label(end_for)

View File

@ -0,0 +1,10 @@
#include "printlib.h"
int main() {
println_bool(true + false);
return 0;
}
// EXITCODE 2
// EXPECTED
// In function main: Line 4 col 15: invalid type for additive operands: boolean and boolean

View File

@ -0,0 +1,16 @@
#include "printlib.h"
int main() {
bool x, y;
if (x <= y) {
println_string("ok");
}
return 0;
}
// SKIP TEST EXPECTED
// EXITCODE 2
// EXPECTED
// In function main: Line 6 col 6: invalid type for non numeric type: boolean

View File

@ -0,0 +1,14 @@
#include "printlib.h"
int main() {
int x, y;
x = 5;
y = 0;
println_int(x/0);
return 0;
}
// SKIP TEST EXPECTED
// EXECCODE 1
// EXPECTED
// Division by 0

View File

@ -0,0 +1,15 @@
#include "printlib.h"
int main() {
int x, y;
if (x != 0) {
y = 12;
} else {
y = -3;
}
println_int(y);
return 0;
}
// EXPECTED
// -3

View File

@ -0,0 +1,27 @@
#include "printlib.h"
int main() {
int num, result, i;
int prev1, prev2, tmp;
result = -1;
num = 15;
if (num < 2) {
result = num;
} else {
prev1 = 1;
prev2 = 0;
for i=2 to num {
tmp = prev1;
prev1 = prev1 + prev2;
prev2 = tmp;
}
result = prev1+prev2;
}
println_int(result);
return 0;
}
// SKIP TEST EXPECTED
// EXPECTED
// 610

View File

@ -0,0 +1,16 @@
#include "printlib.h"
int main() {
int x, y;
if (x) {
y = 5;
}
println_int(y);
return 0;
}
// SKIP TEST EXPECTED
// EXITCODE 2
// EXPECTED
// In function main: Line 6 col 2: invalid type for non boolean as condition: integer

View File

@ -0,0 +1,15 @@
#include "printlib.h"
int main() {
int x;
int y;
while (x < 5000) {
y = x+1;
x = y+1;
}
println_int(x);
return 0;
}
// EXPECTED
// 5000

View File

@ -0,0 +1,19 @@
#include "printlib.h"
int main() {
int x, y;
x = 5;
y = 3;
println_int(x%y);
println_int((-x)%y);
y = 0;
println_int(x%y);
return 0;
}
// SKIP TEST EXPECTED
// EXECCODE 1
// EXPECTED
// 2
// -2
// Division by 0

View File

@ -0,0 +1,12 @@
#include "printlib.h"
int main() {
int x, y;
x = 12;
y = 5;
println_int(x*y);
return 0;
}
// EXPECTED
// 60

View File

@ -0,0 +1,33 @@
#include "printlib.h"
int main() {
if (true) {
if (false) {
println_int(-1);
} else {
println_int(1);
}
} else {
println_int(-1);
}
if (false) {
if (false) {
println_int(-1);
} else {
println_int(-1);
}
} else {
if (true) {
println_int(2);
} else {
println_int(-1);
}
}
return 0;
}
// EXPECTED
// 1
// 2

View File

@ -0,0 +1,25 @@
#include "printlib.h"
int main() {
int x, y, z;
while (x < 12) {
while (x < 25) {
x = x+2;
}
}
println_int(x);
x = 0;
while (x < 5) {
x = x+1;
y = y+x;
while (z < 3) {
z = z+y;
}
}
println_int(z);
return 0;
}
// EXPECTED
// 26
// 3

View File

@ -0,0 +1,14 @@
#include "printlib.h"
int main() {
bool x, y;
x = true;
y = false;
println_bool(!x);
println_bool(!y);
return 0;
}
// EXPECTED
// 0
// 1

View File

@ -0,0 +1,11 @@
#include "printlib.h"
int main() {
println_int(!(12+2));
return 0;
}
// SKIP TEST EXPECTED
// EXITCODE 2
// EXPECTED
// In function main: Line 4 col 14: invalid type for NOT: only boolean allowed: integer

View File

@ -0,0 +1,12 @@
#include "printlib.h"
int main() {
bool x, y;
x = true;
y = false;
println_bool(x || y);
return 0;
}
// EXPECTED
// 1

View File

@ -0,0 +1,14 @@
#include "printlib.h"
int main() {
int x, y;
println_bool(true);
println_bool(y+2);
return 0;
}
// SKIP TEST EXPECTED
// EXITCODE 2
// EXPECTED
// In function main: Line 7 col 2: invalid type for println_bool statement: integer

View File

@ -0,0 +1,14 @@
#include "printlib.h"
int main() {
int x, y;
println_float(15.0);
println_float(y+2);
return 0;
}
// SKIP TEST EXPECTED
// EXITCODE 2
// EXPECTED
// In function main: Line 7 col 2: invalid type for println_float statement: integer

View File

@ -0,0 +1,35 @@
#include "printlib.h"
int main() {
println_bool(1 < 2);
println_bool(1 < 1);
println_bool(2 < 1);
println_bool(1 <= 2);
println_bool(1 <= 1);
println_bool(2 <= 1);
println_bool(1 > 2);
println_bool(1 > 1);
println_bool(2 > 1);
println_bool(1 >= 2);
println_bool(1 >= 1);
println_bool(2 >= 1);
return 0;
}
// EXPECTED
// 1
// 0
// 0
// 1
// 1
// 0
// 0
// 0
// 1
// 0
// 1
// 1

View File

@ -0,0 +1,13 @@
#include "printlib.h"
int main() {
int x;
while (x < 12) {
x = x+2;
}
println_int(x);
return 0;
}
// EXPECTED
// 12

View File

@ -0,0 +1,17 @@
#include "printlib.h"
int main() {
int x, y;
while (x) {
y = 5;
x = x+1;
}
println_int(y);
return 0;
}
// SKIP TEST EXPECTED
// EXITCODE 2
// EXPECTED
// In function main: Line 6 col 2: invalid type for non boolean as condition: integer

View File

@ -0,0 +1,32 @@
#include "printlib.h"
int main() {
int x, y;
int zero, trois;
trois = 3;
// simple loop
for x=zero to trois {
y = y+3;
}
println_int(y);
println_int(x);
// inversed loop
for x=5 to 1 by -2 {
println_int(x);
}
// empty loop
for x=5 to 0 {
println_int(-1);
}
return 0;
}
// SKIP TEST EXPECTED
// EXPECTED
// 9
// 3
// 5
// 3

View File

@ -0,0 +1,18 @@
#include "printlib.h"
int main() {
int i, count;
for i=0 to 6 {
for i=0 to 6 {
count = count + 1;
}
}
println_int(count);
return 0;
}
// SKIP TEST EXPECTED
// EXPECTED
// 36

View File

@ -0,0 +1,17 @@
#include "printlib.h"
int main() {
int x, y;
float fl;
fl = 12.0;
for x=fl to 3 {
y = y+3;
}
return 0;
}
// SKIP TEST EXPECTED
// EXITCODE 2
// EXPECTED
// In function main: Line 8 col 2: invalid type for non-integer from value: float

View File

@ -0,0 +1,17 @@
#include "printlib.h"
int main() {
int x, y;
float fl;
fl = 12.0;
for fl=0 to 3 {
y = y+3;
}
return 0;
}
// SKIP TEST EXPECTED
// EXITCODE 2
// EXPECTED
// In function main: Line 8 col 2: invalid type for non-integer for loop counter: float

View File

@ -0,0 +1,15 @@
#include "printlib.h"
int main() {
int x, y;
for x=0 to 3 by 1.0 {
y = y+3;
}
return 0;
}
// SKIP TEST EXPECTED
// EXITCODE 2
// EXPECTED
// In function main: Line 6 col 2: invalid type for non-integer stride value: float

View File

@ -0,0 +1,17 @@
#include "printlib.h"
int main() {
int x, y;
float fl;
fl = 12.0;
for x=0 to fl {
y = y+3;
}
return 0;
}
// SKIP TEST EXPECTED
// EXITCODE 2
// EXPECTED
// In function main: Line 8 col 2: invalid type for non-integer to value: float

View File

@ -0,0 +1,15 @@
#include "printlib.h"
int main() {
int x, y;
for undef=0 to 3 {
y = y+3;
}
return 0;
}
// SKIP TEST EXPECTED
// EXITCODE 2
// EXPECTED
// In function main: Line 6 col 2: Undefined variable undef