diff --git a/LMJ.mli b/LMJ.mli index 4142cf3..a66f4cd 100644 --- a/LMJ.mli +++ b/LMJ.mli @@ -30,8 +30,13 @@ and binop = | OpAdd (** Binary operator [+]. *) | OpSub (** Binary operator [-]. *) | OpMul (** Binary operator [*]. *) + | OpLt (** Binary operator [<]. *) + | OpEq (** Binary operator [==]. *) | OpLt (** Binary operator [<]. *) + | OpGt (** Binary operator [>]. *) + | OpAnd (** Binary operator [&&]. *) + | OpOr (** BInary operator [||]. *) and unop = UOpNot (** Unary operator [!]. *) diff --git a/README.md b/README.md index e4a3f7f..4417c6a 100644 --- a/README.md +++ b/README.md @@ -82,3 +82,5 @@ git checkout master make ``` +The branch `ast_typed` has an abstract syntax tree decorated with type information. This tree is produced by the typechecker and it can be useful if you want to augment `MiniJava`. + diff --git a/TMJ.mli b/TMJ.mli index 65182e1..3f01e64 100644 --- a/TMJ.mli +++ b/TMJ.mli @@ -26,7 +26,10 @@ and binop = LMJ.binop = | OpSub | OpMul | OpLt + | OpEq + | OpGt | OpAnd + | OpOr and unop = LMJ.unop = UOpNot diff --git a/lexer.mll b/lexer.mll index 3735afa..3a04c52 100644 --- a/lexer.mll +++ b/lexer.mll @@ -29,7 +29,10 @@ rule get_token = parse | '-' { MINUS } | '*' { TIMES } | "&&" { AND } + | "||" { OR } | "<" { LT } + | "==" { EQ } + | ">" { GT } | '(' { LPAREN } | ')' { RPAREN } | '[' { LBRACKET } diff --git a/mj2c.ml b/mj2c.ml index 3202acb..eca0885 100644 --- a/mj2c.ml +++ b/mj2c.ml @@ -300,7 +300,10 @@ let binop2c | OpSub -> fprintf out "-" | OpMul -> fprintf out "*" | OpLt -> fprintf out "<" + | OpEq -> fprintf out "==" + | OpGt -> fprintf out ">" | OpAnd -> fprintf out "&&" + | OpOr -> fprintf out "||" (** [type2c out typ] transpiles the type [typ] to C on the output channel [out]. *) let type2c diff --git a/parser.mly b/parser.mly index 468d755..70c62d8 100644 --- a/parser.mly +++ b/parser.mly @@ -8,7 +8,8 @@ %token INTEGER BOOLEAN %token IDENT %token CLASS PUBLIC STATIC VOID MAIN STRING EXTENDS RETURN -%token PLUS MINUS TIMES NOT LT AND +%token PLUS MINUS TIMES NOT LT AND EQ +%token PLUS MINUS TIMES NOT LT GT AND OR %token COMMA SEMICOLON %token ASSIGN %token LPAREN RPAREN LBRACKET RBRACKET LBRACE RBRACE @@ -17,8 +18,9 @@ %token IF ELSE WHILE %token EOF +%left OR %left AND -%nonassoc LT +%nonassoc LT GT %left PLUS MINUS %left TIMES %nonassoc NOT @@ -146,7 +148,10 @@ raw_expression: | MINUS { OpSub } | TIMES { OpMul } | LT { OpLt } +| EQ { OpEq } +| GT { OpGt } | AND { OpAnd } +| OR { OpOr } instruction: | b = block @@ -164,6 +169,10 @@ instruction: | IF LPAREN c = expression RPAREN i1 = instruction ELSE i2 = instruction { IIf (c, i1, i2) } +// if sans else +| IF LPAREN c = expression RPAREN i1 = instruction // ce qu'on lit + { IIf (c, i1, IBlock([])) } // ce qu'on reconnait + | WHILE LPAREN c = expression RPAREN i = instruction { IWhile (c, i) } diff --git a/printTMJ.ml b/printTMJ.ml index 6710309..9f0fb25 100644 --- a/printTMJ.ml +++ b/printTMJ.ml @@ -23,8 +23,14 @@ let binop out = function fprintf out "*" | OpLt -> fprintf out "<" + | OpEq -> + fprintf out "==" + | OpGt -> + fprintf out ">" | OpAnd -> fprintf out "&&" + | OpOr -> + fprintf out "||" (** [expr out e], [expr0 out e], ..., [expr6 out e] print the expression [e] on the output channel [out]. [expr] is a synonym for [expr6]. @@ -103,7 +109,8 @@ and expr5 out e = match e.raw_expression with expr4 out e and expr6 out e = match e.raw_expression with - | EBinOp ((OpLt | OpAnd) as op, e1, e2) -> + | EBinOp ((OpLt | OpAnd | OpEq) as op, e1, e2) -> + | EBinOp ((OpLt | OpGt | OpAnd | OpOr) as op, e1, e2) -> fprintf out "%a %a %a" expr6 e1 binop op diff --git a/print_ast.ml b/print_ast.ml index b1beb17..e33cb1c 100644 --- a/print_ast.ml +++ b/print_ast.ml @@ -79,8 +79,14 @@ let print_binop out = function fprintf out "OpMul" | OpLt -> fprintf out "OpLt" + | OpEq -> + fprintf out "OpEq" + | OpGt -> + fprintf out "OpGt" | OpAnd -> fprintf out "OpAnd" + | OpOr -> + fprintf out "OpOr" (** [print_expression prefix out e] prints the expression [e] on the output channel [out]. [prefix] is the string already printed just before [e]. *) diff --git a/print_tokens.ml b/print_tokens.ml index 5ed84f4..e4b3e2d 100644 --- a/print_tokens.ml +++ b/print_tokens.ml @@ -52,8 +52,14 @@ let print_token show_loc out = function fprintf out "NOT" | LT -> fprintf out "LT" + | EQ -> + fprintf out "EQ" + | GT -> + fprintf out "GT" | AND -> fprintf out "AND" + | OR -> + fprintf out "OR" | COMMA -> fprintf out "COMMA" | SEMICOLON -> diff --git a/test/good/TestEq b/test/good/TestEq new file mode 100755 index 0000000..6b1777f Binary files /dev/null and b/test/good/TestEq differ diff --git a/test/good/TestEq.c b/test/good/TestEq.c new file mode 100644 index 0000000..a1e50a9 --- /dev/null +++ b/test/good/TestEq.c @@ -0,0 +1,23 @@ +/* +class TestEq { + public static void main(String[] args) { + if (1 == 1) System.out.println(42); + else System.out.println(0); + } +} +*/ +#include +#include +#include "tgc.h" +#pragma GCC diagnostic ignored "-Wpointer-to-int-cast" +#pragma GCC diagnostic ignored "-Wint-to-pointer-cast" +struct array { int* array; int length; }; +tgc_t gc; +int main(int argc, char *argv[]) { + tgc_start(&gc, &argc); + if ((1 == 1)) printf("%d\n", 42); + else printf("%d\n", 0); + tgc_stop(&gc); + + return 0; +} diff --git a/test/good/TestEq.java b/test/good/TestEq.java new file mode 100644 index 0000000..d6fa137 --- /dev/null +++ b/test/good/TestEq.java @@ -0,0 +1,6 @@ +class TestEq { + public static void main(String[] args){ + if(1==1) System.out.println(42); + else System.out.println(0); + } +} \ No newline at end of file diff --git a/test/good/TestGt.java b/test/good/TestGt.java new file mode 100644 index 0000000..d22168f --- /dev/null +++ b/test/good/TestGt.java @@ -0,0 +1,6 @@ +class TestGt { + public static void main(String[] args){ + if(2>1) System.out.println(42); + else System.out.println(0); + } +} \ No newline at end of file diff --git a/test/good/TestOr.java b/test/good/TestOr.java new file mode 100644 index 0000000..acb7145 --- /dev/null +++ b/test/good/TestOr.java @@ -0,0 +1,6 @@ +class TestOr { + public static void main(String[] args) { + if(true || false) System.out.println(42); + else System.out.println(0); + } +} \ No newline at end of file diff --git a/typechecking.ml b/typechecking.ml index 452bcd5..f167cb0 100644 --- a/typechecking.ml +++ b/typechecking.ml @@ -173,7 +173,10 @@ and typecheck_expression (cenv : class_env) (venv : variable_env) (vinit : S.t) | OpSub | OpMul -> TypInt, TypInt | OpLt -> TypInt, TypBool + | OpEq -> TypInt, TypBool + | OpGt -> TypInt, TypBool | OpAnd -> TypBool, TypBool + | OpOr -> TypBool, TypBool in let e1' = typecheck_expression_expecting cenv venv vinit instanceof expected e1 in let e2' = typecheck_expression_expecting cenv venv vinit instanceof expected e2 in