Snap des modifications avant modifications des messages d'erreur.

This commit is contained in:
Mysaa 2022-10-04 22:14:21 +02:00
parent a6fb91fd78
commit 5d29c3805b
Signed by: Mysaa
GPG Key ID: 7054D5D6A90F084F
42 changed files with 781 additions and 36 deletions

View File

@ -1,4 +1,4 @@
MYNAME = JohnDoe
MYNAME = SamyAvrillon
PACKAGE = MiniC
# Example: stop at the first failed test:
# make PYTEST_OPTS=-x test

View File

@ -24,7 +24,8 @@ stat
: assignment SCOL
| if_stat
| while_stat
| print_stat
| print_stat
| for_stat
;
assignment: ID ASSIGN expr #assignStat;
@ -39,6 +40,7 @@ stat_block
while_stat: WHILE OPAR expr CPAR body=stat_block #whileStat;
for_stat: FOR OPAR (init_stat=assignment)? SCOL (cond=expr)? SCOL (loop_stat=assignment)? CPAR stat_block #forStat;
print_stat
: PRINTLN_INT OPAR expr CPAR SCOL #printlnintStat
@ -101,6 +103,7 @@ FALSE : 'false';
IF : 'if';
ELSE : 'else';
WHILE : 'while';
FOR : 'for';
RETURN : 'return';
PRINTLN_INT : 'println_int';
PRINTLN_BOOL : 'println_bool';

View File

@ -4,11 +4,14 @@ LAB3, MIF08 / CAP 2022-23
# Authors
TODO: YOUR NAME HERE
Samy Avrillon
Mostly you for the
# Contents
TODO for STUDENTS : Say a bit about the code infrastructure ...
Well ... You did the code infrastructure, so i have no interest in telling that it is bad. So ... Great infrastructure !
I think this part is for future work on MiniC, so i will not answer it (seriously).
# Howto
@ -21,12 +24,25 @@ You can select the files you want to test by using `make test TEST_FILES='TP03/*
# Test design
TODO: explain your tests. Do not repeat what test files already contain, just give the main objectives of the tests.
- «corrected» folder corresponds to the tests that i have changed from the base set (see Desing Choices below)
- «typeErrors» folder corresponds to tests of the error messages when using an operator/structure. Each *part* of the operator/structure is checked independently so we know for sure where the error comes from.
- ifClauseSyntax and whileClauseSyntax test the syntax of if and while clauses.
- floatDiv0, floatMod0, intDiv0 et intMod0 tests «Division by 0» errors.
- multidecl.c test multi-variables declarations.
- testOps.c test float and int arithmetics.
- forTests.c tests the execution of the for (C-like) loops.
# Design choices
TODO: explain your choices - explain the limitations of your implementation.
We will consider that when using an operator on two types with one of them illegal (for example, trying to multiply an int and a string), an error of type «type mismatch» will be raised instead of an «invalid type» one. This allows to check type equality before type validity.
The protocol to choosing an error message is as follows:
- If the operator requires its arguments to be of the same type, the first check is equality of the types of the operands. In case of error, an error of type «type mismatch» is raised with the types of the operands.
- If this check passed, the first argument type is checked, and if it is invalid, an error of type «invalid type» is raised **with only one type**
- If the operator can take arguments of different types, each type is checked, and in case of error, an error of type «invalid type» is raised with **type for each argument**.
In order to follow this protocol, two tests have been rewritten (and moved to the «student» directory): bad_type01.c and bad_type_bool_bool.c
# Known bugs
TODO: document any known bug and limitations. Did you do everything asked for? Did you implement an extension?
I think i did everything i was asked, and did not notice any bug.

View File

@ -19,11 +19,24 @@ class MiniCInterpretVisitor(MiniCVisitor):
def visitVarDecl(self, ctx) -> None:
# Initialise all variables in self._memory
type_str = ctx.typee().getText()
raise NotImplementedError()
typee = ctx.typee().getText()
names = self.visit(ctx.id_l())
val = 42
if(typee == "int"):
val = 0
elif(typee == "string"):
val = ""
elif(typee == "bool"):
val = False
elif(typee == "float"):
val = 0.0
for name in names:
self._memory[name] = val
def visitIdList(self, ctx) -> List[str]:
raise NotImplementedError()
l = self.visit(ctx.id_l())
l.append(ctx.ID().getText())
return l
def visitIdListBase(self, ctx) -> List[str]:
return [ctx.ID().getText()]
@ -43,7 +56,7 @@ class MiniCInterpretVisitor(MiniCVisitor):
return ctx.getText() == "true"
def visitIdAtom(self, ctx) -> MINIC_VALUE:
raise NotImplementedError()
return self._memory[ctx.getText()]
def visitStringAtom(self, ctx) -> str:
return ctx.getText()[1:-1] # Remove the ""
@ -119,8 +132,9 @@ class MiniCInterpretVisitor(MiniCVisitor):
else:
return lval / rval
elif ctx.myop.type == MiniCParser.MOD:
# TODO : interpret modulo
raise NotImplementedError()
if rval == 0:
raise MiniCRuntimeError("Division by 0")
return lval % rval
else:
raise MiniCInternalError(
"Unknown multiplicative operator '%s'" % ctx.myop)
@ -152,13 +166,36 @@ class MiniCInterpretVisitor(MiniCVisitor):
print(val)
def visitAssignStat(self, ctx) -> None:
raise NotImplementedError()
name = ctx.ID().getText()
val = self.visit(ctx.expr())
self._memory[name] = val
def visitIfStat(self, ctx) -> None:
raise NotImplementedError()
condval = self.visit(ctx.expr())
if(condval==True):
self.visit(ctx.then_block)
else:
if(ctx.else_block != None):
self.visit(ctx.else_block)
def visitWhileStat(self, ctx) -> None:
raise NotImplementedError()
condexpr = ctx.expr()
inexpr = ctx.body
while(self.visit(condexpr)==True):
self.visit(inexpr)
def visitForStat(self, ctx):
init_stat = ctx.init_stat
cond = ctx.cond
loop_stat = ctx.loop_stat
body = ctx.stat_block()
if(init_stat != None):
self.visit(init_stat)
while(True if cond==None else self.visit(cond)):
self.visit(body)
if(loop_stat != None):
self.visit(loop_stat)
# TOPLEVEL
def visitProgRule(self, ctx) -> None:

View File

@ -43,7 +43,12 @@ class MiniCTypingVisitor(MiniCVisitor):
# type declaration
def visitVarDecl(self, ctx) -> None:
raise NotImplementedError()
ttype = self.visit(ctx.typee())
ids = self.visit(ctx.id_l())
for i in ids:
if i in self._memorytypes:
self._raiseNonType(ctx,"Variable {} already declared".format(i))
self._memorytypes[i] = ttype
def visitBasicType(self, ctx):
assert ctx.mytype is not None
@ -51,14 +56,20 @@ class MiniCTypingVisitor(MiniCVisitor):
return BaseType.Integer
elif ctx.mytype.type == MiniCParser.FLOATTYPE:
return BaseType.Float
else: # TODO: same for other types
raise NotImplementedError()
if ctx.mytype.type == MiniCParser.STRINGTYPE:
return BaseType.String
elif ctx.mytype.type == MiniCParser.BOOLTYPE:
return BaseType.Boolean
else:
raise MiniCInternalError("Unknown type '%s'" % ctx.mytype)
def visitIdList(self, ctx) -> List[str]:
raise NotImplementedError()
l = self.visit(ctx.id_l())
l.append(ctx.ID().getText())
return l
def visitIdListBase(self, ctx) -> List[str]:
raise NotImplementedError()
return [ctx.ID().getText()]
# typing visitors for expressions, statements !
@ -73,7 +84,7 @@ class MiniCTypingVisitor(MiniCVisitor):
return BaseType.Float
def visitBooleanAtom(self, ctx):
raise NotImplementedError()
return BaseType.Boolean
def visitIdAtom(self, ctx):
try:
@ -91,29 +102,84 @@ class MiniCTypingVisitor(MiniCVisitor):
return self.visit(ctx.atom())
def visitOrExpr(self, ctx):
raise NotImplementedError()
fstT = self.visit(ctx.expr(0))
sndT = self.visit(ctx.expr(1))
if(fstT == sndT):
if(fstT == BaseType.Boolean):
return BaseType.Boolean
else:
self._raise(ctx,"boolean operator", fstT)
else:
self._assertSameType(ctx,"boolean operator", fstT,sndT)
def visitAndExpr(self, ctx):
raise NotImplementedError()
fstT = self.visit(ctx.expr(0))
sndT = self.visit(ctx.expr(1))
if(fstT == sndT):
if(fstT == BaseType.Boolean):
return BaseType.Boolean
else:
self._raise(ctx,"boolean operator", fstT)
else:
self._assertSameType(ctx,"boolean operator", fstT,sndT)
def visitEqualityExpr(self, ctx):
raise NotImplementedError()
fstT = self.visit(ctx.expr(0))
sndT = self.visit(ctx.expr(1))
if(fstT == sndT):
return BaseType.Boolean
else:
self._assertSameType(ctx,"equality operator", fstT,sndT)
def visitRelationalExpr(self, ctx):
raise NotImplementedError()
fstT = self.visit(ctx.expr(0))
sndT = self.visit(ctx.expr(1))
if(fstT == sndT):
if(fstT in [BaseType.Float, BaseType.Integer]):
return BaseType.Boolean
else:
self._raise(ctx, "comparaison operator", fstT)
else:
self._assertSameType(ctx,"comparaison operator", fstT,sndT)
def visitAdditiveExpr(self, ctx):
assert ctx.myop is not None
raise NotImplementedError()
fstT = self.visit(ctx.expr(0))
sndT = self.visit(ctx.expr(1))
if(fstT == sndT):
if(fstT in [BaseType.Float, BaseType.Integer]):
return fstT
elif (fstT == BaseType.String and ctx.myop.type == MiniCParser.PLUS):
return BaseType.String
else:
self._raise(ctx, "additive operands", fstT)
else:
self._assertSameType(ctx,"additive operator", fstT,sndT)
def visitMultiplicativeExpr(self, ctx):
raise NotImplementedError()
fstT = self.visit(ctx.expr(0))
sndT = self.visit(ctx.expr(1))
if(fstT == sndT):
if(not fstT in [BaseType.Float, BaseType.Integer]):
self._raise(ctx, "multiplicative operands", fstT)
else:
return fstT
else:
self._assertSameType(ctx,"multiplicative operator", fstT,sndT)
def visitNotExpr(self, ctx):
raise NotImplementedError()
fstT = self.visit(ctx.expr())
if(fstT == BaseType.Boolean):
return BaseType.Boolean
else:
self._raise(ctx,"not operator", fstT)
def visitUnaryMinusExpr(self, ctx):
raise NotImplementedError()
fstT = self.visit(ctx.expr())
if(fstT in [BaseType.Integer,BaseType.Float]):
return fstT
else:
self._raise(ctx,"minus operator", fstT)
# visit statements
@ -130,7 +196,7 @@ class MiniCTypingVisitor(MiniCVisitor):
def visitPrintlnboolStat(self, ctx):
etype = self.visit(ctx.expr())
if etype != BaseType.Boolean:
self._raise(ctx, 'println_int statement', etype)
self._raise(ctx, 'println_bool statement', etype)
def visitPrintlnstringStat(self, ctx):
etype = self.visit(ctx.expr())
@ -138,10 +204,35 @@ class MiniCTypingVisitor(MiniCVisitor):
self._raise(ctx, 'println_string statement', etype)
def visitAssignStat(self, ctx):
raise NotImplementedError()
theid = ctx.ID().getText()
ttyp = self.visit(ctx.expr())
if(not theid in self._memorytypes):
self._raiseNonType(ctx,"Undefined variable {}".format(theid))
if(self._memorytypes[theid] != ttyp):
self._assertSameType(ctx,theid, self._memorytypes[theid],ttyp)
def visitWhileStat(self, ctx):
raise NotImplementedError()
cond = self.visit(ctx.expr())
if(cond != BaseType.Boolean):
self._raise(ctx, "while condition", cond)
self.visit(ctx.body)
def visitIfStat(self, ctx):
raise NotImplementedError()
cond = self.visit(ctx.expr())
if(cond != BaseType.Boolean):
self._raise(ctx, "if condition", cond)
self.visit(ctx.then_block)
if(ctx.else_block != None):
self.visit(ctx.else_block)
def visitForStat(self, ctx):
if(ctx.init_stat != None):
self.visit(ctx.init_stat)
if(ctx.cond != None):
cond = self.visit(ctx.cond)
if(cond != BaseType.Boolean):
self._raise(ctx, "for condition", cond)
if(ctx.loop_stat != None):
self.visit(ctx.loop_stat)
self.visit(ctx.stat_block())

View File

@ -11,4 +11,4 @@ int main(){
// EXITCODE 2
// EXPECTED
// In function main: Line 8 col 6: invalid type for multiplicative operands: integer and string
// In function main: Line 8 col 6: type mismatch for multiplicative operator: integer and string

View File

@ -6,4 +6,4 @@ int main(){
}
// EXITCODE 2
// EXPECTED
// In function main: Line 4 col 14: invalid type for additive operands: boolean and boolean
// In function main: Line 4 col 14: invalid type for additive operands: boolean

View File

@ -0,0 +1,16 @@
#include "printlib.h"
int main(){
float x,y,z;
x = 42.0;
y = 0.0;
z = x/y;
println_float(z);
return 0;
}
// EXPECTED
// EXITCODE 1
// Division by 0

View File

@ -0,0 +1,16 @@
#include "printlib.h"
int main(){
float x,y,z;
x = 42.0;
y = 0.0;
z = x%y;
println_float(z);
return 0;
}
// EXPECTED
// EXITCODE 1
// Division by 0

View File

@ -0,0 +1,32 @@
#include "printlib.h"
int main(){
int x;
x = 0;
for(;x<4;){
println_int(x);
x = x+1;
}
x = 69;
for(x=42;false;){
}
println_int(x);
for(x = 100;x>=4;x = x/2){
println_int(x+4);
}
return 0;
}
// EXITCODE 0
// EXPECTED
// 0
// 1
// 2
// 3
// 42
// 104
// 54
// 29
// 16
// 10

View File

@ -0,0 +1,34 @@
#include "printlib.h"
int main(){
int x,y,z;
x = 0;
y = 0;
if(x==1)
println_string("pif");
else{
println_string("paf");
}
if(y==0){
println_string("paf");
}else
println_string("pif");
if(x!=y){
println_string("pif");
}else{
println_string("paf");
}
if(0==0)
println_string("paf");
else
println_string("pif");
return 0;
}
// EXPECTED
// paf
// paf
// paf
// paf

View File

@ -0,0 +1,16 @@
#include "printlib.h"
int main(){
int x,y,z;
x = 42;
y = 0;
z = x/y;
println_int(z);
return 0;
}
// EXITCODE 1
// EXPECTED
// Division by 0

View File

@ -0,0 +1,16 @@
#include "printlib.h"
int main(){
int x,y,z;
x = 42;
y = 0;
z = x%y;
println_int(z);
return 0;
}
// EXITCODE 1
// EXPECTED
// Division by 0

View File

@ -0,0 +1,14 @@
#include "printlib.h"
int main(){
int x,y,z,a,b,c;
string s,d;
float v,u,k,n;
bool t,w,p;
println_int(x);
return 0;
}
// EXPECTED
// 0

View File

@ -0,0 +1,40 @@
#include "printlib.h"
int main(){
int x,y,z;
float a,b,c;
x = 42;
y = 69;
a = 42.0;
b = 69.0;
z = y-x;
println_int(z);
c = b-a;
println_float(c);
y = 690;
z = y/x;
println_int(z);
c = a/12.0;
println_float(c);
z = y % x;
println_int(z);
c = b % a;
println_float(c);
z = -x;
println_int(z);
c = -b;
println_float(c);
return 0;
}
// EXPECTED
// 27
// 27.00
// 16
// 3.50
// 18
// 27.00
// -42
// -69.00

View File

@ -0,0 +1,17 @@
#include "printlib.h"
int main(){
int x;
if (true) {
x = 42;
} else {
x = true;
}
return 0;
}
// EXITCODE 2
// EXPECTED
// In function main: Line 9 col 8: type mismatch for x: integer and boolean

View File

@ -0,0 +1,14 @@
#include "printlib.h"
int main(){
int x;
for(x = 0;x<10;x = x+1){
println_int(false);
}
return 0;
}
// EXITCODE 2
// EXPECTED
// In function main: Line 7 col 8: invalid type for println_int statement: boolean

View File

@ -0,0 +1,14 @@
#include "printlib.h"
int main(){
int x;
for(x = 0;x+10;x = x+1){
println_int(x);
}
return 0;
}
// EXITCODE 2
// EXPECTED
// In function main: Line 6 col 4: invalid type for for condition: integer

View File

@ -0,0 +1,14 @@
#include "printlib.h"
int main(){
int x;
for(x = 0 + false;x<10;x = x+1){
println_int(x);
}
return 0;
}
// EXITCODE 2
// EXPECTED
// In function main: Line 6 col 12: type mismatch for additive operator: integer and boolean

View File

@ -0,0 +1,14 @@
#include "printlib.h"
int main(){
int x;
for(x = 0;x<10;x = false){
println_int(x);
}
return 0;
}
// EXITCODE 2
// EXPECTED
// In function main: Line 6 col 19: type mismatch for x: integer and boolean

View File

@ -0,0 +1,17 @@
#include "printlib.h"
int main(){
int x;
if (true) {
x = true;
}else {
x = 42;
}
return 0;
}
// EXITCODE 2
// EXPECTED
// In function main: Line 7 col 8: type mismatch for x: integer and boolean

View File

@ -0,0 +1,21 @@
#include "printlib.h"
int main(){
int x;
bool a;
if (a) {
}
if (true) {
}
if (x) {
}
return 0;
}
// EXITCODE 2
// EXPECTED
// In function main: Line 13 col 4: invalid type for if condition: integer

View File

@ -0,0 +1,14 @@
#include "printlib.h"
int main(){
int x,y;
bool a,b;
x = x + y;
x = a - b;
return 0;
}
// EXITCODE 2
// EXPECTED
// In function main: Line 8 col 8: invalid type for additive operands: boolean

View File

@ -0,0 +1,14 @@
#include "printlib.h"
int main(){
int x,y;
bool a,b;
a = a && b;
a = x && y;
return 0;
}
// EXITCODE 2
// EXPECTED
// In function main: Line 8 col 8: invalid type for boolean operator: integer

View File

@ -0,0 +1,14 @@
#include "printlib.h"
int main(){
int x,y;
bool a,b;
a = x < y;
x = a > b;
return 0;
}
// EXITCODE 2
// EXPECTED
// In function main: Line 8 col 8: invalid type for comparaison operator: boolean

View File

@ -0,0 +1,16 @@
#include "printlib.h"
int main(){
int x,y;
float z,t;
bool a,b;
x = -y;
z = -t;
a = -b;
return 0;
}
// EXITCODE 2
// EXPECTED
// In function main: Line 10 col 8: invalid type for minus operator: boolean

View File

@ -0,0 +1,14 @@
#include "printlib.h"
int main(){
int x,y;
bool a,b;
x = x * y;
x = a * b;
return 0;
}
// EXITCODE 2
// EXPECTED
// In function main: Line 8 col 8: invalid type for multiplicative operands: boolean

View File

@ -0,0 +1,14 @@
#include "printlib.h"
int main(){
int y;
bool a,b;
a = !b;
a = !y;
return 0;
}
// EXITCODE 2
// EXPECTED
// In function main: Line 8 col 8: invalid type for not operator: integer

View File

@ -0,0 +1,14 @@
#include "printlib.h"
int main(){
int x,y;
bool a,b;
a = a || b;
a = x || y;
return 0;
}
// EXITCODE 2
// EXPECTED
// In function main: Line 8 col 8: invalid type for boolean operator: integer

View File

@ -0,0 +1,14 @@
#include "printlib.h"
int main(){
bool x;
string a;
println_bool(x);
println_bool(a);
return 0;
}
// EXITCODE 2
// EXPECTED
// In function main: Line 8 col 4: invalid type for println_bool statement: string

View File

@ -0,0 +1,14 @@
#include "printlib.h"
int main(){
float x;
string a;
println_float(x);
println_float(a);
return 0;
}
// EXITCODE 2
// EXPECTED
// In function main: Line 8 col 4: invalid type for println_float statement: string

View File

@ -0,0 +1,14 @@
#include "printlib.h"
int main(){
int x;
string a;
println_int(x);
println_int(a);
return 0;
}
// EXITCODE 2
// EXPECTED
// In function main: Line 8 col 4: invalid type for println_int statement: string

View File

@ -0,0 +1,14 @@
#include "printlib.h"
int main(){
string x;
bool a;
println_string(x);
println_string(a);
return 0;
}
// EXITCODE 2
// EXPECTED
// In function main: Line 8 col 4: invalid type for println_string statement: boolean

View File

@ -0,0 +1,16 @@
#include "printlib.h"
int main(){
int x,y;
float z,t;
bool a,b;
x = x + y;
z = z - t;
a = x + t;
return 0;
}
// EXITCODE 2
// EXPECTED
// In function main: Line 10 col 8: type mismatch for additive operator: integer and float

View File

@ -0,0 +1,14 @@
#include "printlib.h"
int main(){
int x;
bool a,b;
a = a && b;
a = x && b;
return 0;
}
// EXITCODE 2
// EXPECTED
// In function main: Line 8 col 8: type mismatch for boolean operator: integer and boolean

View File

@ -0,0 +1,22 @@
#include "printlib.h"
int main(){
int x,y;
float z,t;
bool a,b;
a = x < y;
a = x <= y;
b = x > y;
a = x >= y;
a = z > t;
b = z >= t;
a = z < t;
a = z <= t;
b = x <= t;
return 0;
}
// EXITCODE 2
// EXPECTED
// In function main: Line 16 col 8: type mismatch for comparaison operator: integer and float

View File

@ -0,0 +1,20 @@
#include "printlib.h"
int main(){
int x,y;
float z,t;
string s,v;
bool a,b;
bool c;
c = (x==y);
c = (z!=t);
c = (s==v);
c = (a!=b);
c = (t==y);
return 0;
}
// EXITCODE 2
// EXPECTED
// In function main: Line 14 col 9: type mismatch for equality operator: float and integer

View File

@ -0,0 +1,16 @@
#include "printlib.h"
int main(){
int x,y;
float z,t;
bool a,b;
x = x * y;
z = z * t;
a = x * t;
return 0;
}
// EXITCODE 2
// EXPECTED
// In function main: Line 10 col 8: type mismatch for multiplicative operator: integer and float

View File

@ -0,0 +1,14 @@
#include "printlib.h"
int main(){
int x;
bool a,b;
a = a || b;
a = x || b;
return 0;
}
// EXITCODE 2
// EXPECTED
// In function main: Line 8 col 8: type mismatch for boolean operator: integer and boolean

View File

@ -0,0 +1,21 @@
#include "printlib.h"
int main(){
int x;
bool a;
while (a) {
}
while (false) {
}
while (x) {
}
return 0;
}
// EXITCODE 2
// EXPECTED
// In function main: Line 13 col 4: invalid type for while condition: integer

View File

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

View File

@ -7,3 +7,5 @@ DIGIT : [0-9] ;
LETTER : [A-Za-z] ;
ID : LETTER (LETTER | DIGIT)* ; // match idents
WS : [ \t\r\n]+ -> skip ; // skip spaces, tabs, newlines
OPENP : '(';
ENDP : ')';