Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

condicional e atribuição #46

Open
wants to merge 1 commit into
base: assignment
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
<className>Parser</className>
<symbolsName>SymbolConstants</symbolsName>
<symbolsInterface>true</symbolsInterface>
<expectedConflicts>1</expectedConflicts>
<!-- Makes CUP generate xleft/xright handles for accessing Location objects for symbol start/end inside actions. -->
<locations>true</locations>
</configuration>
Expand Down
35 changes: 20 additions & 15 deletions src/main/cup/parser.cup
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,9 @@ terminal PLUS, MINUS, TIMES, DIV, UMINUS;
terminal AND, OR;
terminal LPAREN, RPAREN;
terminal COMMA, SEMICOLON;
terminal VAR, EQ, COLON;
terminal VAR, EQ, COLON, ATTR;
terminal LET, IN;
terminal IF, THEN, ELSE;

non terminal Exp program;
non terminal Exp exp;
Expand All @@ -62,6 +63,7 @@ precedence left AND;
precedence left PLUS, MINUS;
precedence left TIMES, DIV;
precedence left UMINUS;
precedence left ATTR;

start with program;

Expand All @@ -70,20 +72,23 @@ program ::=
;

exp ::=
exp:x PLUS exp:y {: RESULT = new ExpBinOp(loc(xxleft,yxright), ExpBinOp.Op.PLUS, x, y); :}
| exp:x MINUS exp:y {: RESULT = new ExpBinOp(loc(xxleft,yxright), ExpBinOp.Op.MINUS, x, y); :}
| exp:x TIMES exp:y {: RESULT = new ExpBinOp(loc(xxleft,yxright), ExpBinOp.Op.TIMES, x, y); :}
| exp:x DIV exp:y {: RESULT = new ExpBinOp(loc(xxleft,yxright), ExpBinOp.Op.DIV, x, y); :}
| exp:x AND exp:y {: RESULT = new ExpBinOp(loc(xxleft,yxright), ExpBinOp.Op.AND, x, y); :}
| exp:x OR exp:y {: RESULT = new ExpBinOp(loc(xxleft,yxright), ExpBinOp.Op.OR, x, y); :}
| LITINT:x {: RESULT = new ExpInt(loc(xxleft,xxright), x); :}
| LITREAL:x {: RESULT = new ExpReal(loc(xxleft,xxright), x); :}
| LITBOOL:x {: RESULT = new ExpBool(loc(xxleft,xxright), x); :}
| MINUS:m exp:x {: RESULT = new ExpNegate(loc(mxleft,xxright), x); :} %prec UMINUS
| ID:f LPAREN exps:x RPAREN:r {: RESULT = new ExpCall(loc(fxleft,rxright), f, x); :}
| var:v {: RESULT = new ExpVar(loc(vxleft,vxright), v); :}
| LET:l decs:ds IN exp:b {: RESULT = new ExpLet(loc(lxleft,bxright), ds, b); :}
| LPAREN:l expseq:es RPAREN:r {: RESULT = new ExpSeq(loc(lxleft,rxright), es); :}
exp:x PLUS exp:y {: RESULT = new ExpBinOp(loc(xxleft,yxright), ExpBinOp.Op.PLUS, x, y); :}
| exp:x MINUS exp:y {: RESULT = new ExpBinOp(loc(xxleft,yxright), ExpBinOp.Op.MINUS, x, y); :}
| exp:x TIMES exp:y {: RESULT = new ExpBinOp(loc(xxleft,yxright), ExpBinOp.Op.TIMES, x, y); :}
| exp:x DIV exp:y {: RESULT = new ExpBinOp(loc(xxleft,yxright), ExpBinOp.Op.DIV, x, y); :}
| exp:x AND exp:y {: RESULT = new ExpBinOp(loc(xxleft,yxright), ExpBinOp.Op.AND, x, y); :}
| exp:x OR exp:y {: RESULT = new ExpBinOp(loc(xxleft,yxright), ExpBinOp.Op.OR, x, y); :}
| LITINT:x {: RESULT = new ExpInt(loc(xxleft,xxright), x); :}
| LITREAL:x {: RESULT = new ExpReal(loc(xxleft,xxright), x); :}
| LITBOOL:x {: RESULT = new ExpBool(loc(xxleft,xxright), x); :}
| MINUS:m exp:x {: RESULT = new ExpNegate(loc(mxleft,xxright), x); :} %prec UMINUS
| ID:f LPAREN exps:x RPAREN:r {: RESULT = new ExpCall(loc(fxleft,rxright), f, x); :}
| var:v {: RESULT = new ExpVar(loc(vxleft,vxright), v); :}
| LET:l decs:ds IN exp:b {: RESULT = new ExpLet(loc(lxleft,bxright), ds, b); :}
| LPAREN:l expseq:es RPAREN:r {: RESULT = new ExpSeq(loc(lxleft,rxright), es); :}
| var:v ATTR exp:y {: RESULT = new ExpAssign(loc(vxleft,yxright), v, y); :}
| IF:i exp:x THEN exp:y {: RESULT = new ExpIf(loc(ixleft,yxright), x, y, null); :}
| IF:i exp:x THEN exp:y ELSE exp:z {: RESULT = new ExpIf(loc(ixleft,yxright), x, y, z); :}
;

exps ::=
Expand Down
48 changes: 48 additions & 0 deletions src/main/java/absyn/ExpAssign.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package absyn;

import com.sun.org.apache.xpath.internal.operations.Variable;
import env.Env;
import javaslang.collection.Tree;
import parse.Loc;
import types.Type;
import static semantic.SemanticHelper.typeMismatch;
import types.UNIT;

/**
* Created by aluno on 13/03/2017.
*/

public class ExpAssign extends Exp{

public final Var var;
public final Exp exp;

public ExpAssign(Loc loc, Var var, Exp exp) {
super(loc);
this.var = var;
this.exp = exp;
}

@Override
public Tree.Node<String> toTree() {
return Tree.of(annotateType("ExpAssign"),
var.toTree(),
exp.toTree());
}

@Override
protected Type semantic_(Env env) {
Type Tipovar = var.semantic(env);
Type Tipoexp = exp.semantic(env);

if (!Tipoexp.is(Tipovar))
throw typeMismatch(exp.loc, Tipoexp, Tipovar);

return Tipovar;
}


}



69 changes: 69 additions & 0 deletions src/main/java/absyn/ExpIf.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package absyn;

import com.sun.org.apache.xpath.internal.operations.Variable;
import env.Env;
import javaslang.collection.Tree;
import parse.Loc;
import types.BOOL;
import types.Type;
import static semantic.SemanticHelper.typeMismatch;
import types.UNIT;

/**
* Created by aluno on 13/03/2017.
*/

public class ExpIf extends Exp{

public final Exp exp1;
public final Exp exp2;
public final Exp exp3;

public ExpIf(Loc loc, Exp exp1, Exp exp2, Exp exp3) {
super(loc);
this.exp1 = exp1;
this.exp2 = exp2;
this.exp3 = exp3;
}

@Override
public Tree.Node<String> toTree() {
if (!(exp3 == null)){
return Tree.of(annotateType("ExpAssign"),
exp1.toTree(),
exp2.toTree(),
exp3.toTree());
}
return Tree.of(annotateType("ExpAssign"),
exp1.toTree(),
exp2.toTree());
}

@Override
protected Type semantic_(Env env) {
Type Tipoexp1 = exp1.semantic(env);

if (!(Tipoexp1.is(BOOL.T))){
throw typeMismatch(exp1.loc, Tipoexp1, BOOL.T);
}

Type Tipoexp2 = exp2.semantic(env);

if (exp3 == null){
if (!(Tipoexp2.is(UNIT.T))){
throw typeMismatch(exp2.loc, Tipoexp2, UNIT.T);
}
return UNIT.T;
}
else {
Type Tipoexp3 = exp3.semantic(env);
if (!(Tipoexp3.is(UNIT.T))){
throw typeMismatch(exp3.loc, Tipoexp3, UNIT.T);
}
return UNIT.T;
}
}
}



10 changes: 7 additions & 3 deletions src/main/jflex/lexer.jflex
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,12 @@ id = [a-zA-Z][a-zA-Z0-9_]*
{litreal} { return tok(LITREAL, yytext()); }
{litbool} { return tok(LITBOOL, yytext()); }

var { return tok(VAR); }
let { return tok(LET); }
in { return tok(IN); }
var { return tok(VAR); }
let { return tok(LET); }
in { return tok(IN); }
if { return tok(IF); }
then { return tok(THEN); }
else { return tok(ELSE); }

{id} { return tok(ID, yytext().intern()); }

Expand All @@ -95,5 +98,6 @@ in { return tok(IN); }
";" { return tok(SEMICOLON); }
":" { return tok(COLON); }
"=" { return tok(EQ); }
":=" { return tok(ATTR);}

. { throw error(Loc.loc(locLeft()), "unexpected char '%s'", yytext()); }
57 changes: 41 additions & 16 deletions src/test/java/Test/SemantTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ private Type runSemantic(String input) throws Exception {
private void trun(String input, Type type) {
try {
softly.assertThat(runSemantic(input))
.as("%s", input)
.isEqualTo(type);
.as("%s", input)
.isEqualTo(type);
}
catch (Exception e) {
e.printStackTrace();
Expand All @@ -37,9 +37,9 @@ private void trun(String input, Type type) {

private void erun(String input, String message) throws IOException {
softly.assertThatThrownBy(() -> runSemantic(input))
.as("%s", input)
.isInstanceOf(CompilerError.class)
.hasToString(message);
.as("%s", input)
.isInstanceOf(CompilerError.class)
.hasToString(message);
}

@Rule
Expand All @@ -55,17 +55,17 @@ public void testLiterals() throws Exception {
@Test
public void testFunctionCall() throws Exception {
erun("fat(9)",
"error.CompilerError: 1/1-1/7 undefined function 'fat'");
"error.CompilerError: 1/1-1/7 undefined function 'fat'");
erun("fat(g(), h())",
"error.CompilerError: 1/5-1/8 undefined function 'g'");
"error.CompilerError: 1/5-1/8 undefined function 'g'");
trun("print_int(123)",
UNIT.T);
UNIT.T);
erun("print_int(true)",
"error.CompilerError: 1/11-1/15 type mismatch: found bool but expected int");
"error.CompilerError: 1/11-1/15 type mismatch: found bool but expected int");
erun("print_int(123, true, f())",
"error.CompilerError: 1/22-1/25 undefined function 'f'");
"error.CompilerError: 1/22-1/25 undefined function 'f'");
erun("print_int()",
"error.CompilerError: 1/1-1/12 too few arguments in call to 'print_int'");
"error.CompilerError: 1/1-1/12 too few arguments in call to 'print_int'");
}

@Test
Expand All @@ -78,15 +78,40 @@ public void testSequence() throws Exception {
@Test
public void testSimpleVariableAndLet() throws Exception {
erun("x",
"error.CompilerError: 1/1-1/2 undefined variable 'x'");
"error.CompilerError: 1/1-1/2 undefined variable 'x'");
trun("let var x: int = 10 in x",
INT.T);
INT.T);
trun("let var x = 0.56 in x",
REAL.T);
REAL.T);
erun("let var x: int = 3.4 in x",
"error.CompilerError: 1/18-1/21 type mismatch: found real but expected int");
"error.CompilerError: 1/18-1/21 type mismatch: found real but expected int");
erun("(let var x = 5 in print_int(x); x)",
"error.CompilerError: 1/33-1/34 undefined variable 'x'");
"error.CompilerError: 1/33-1/34 undefined variable 'x'");
}

@Test
public void testAttr() throws Exception {
trun ("let var x : int = 0 in x := 2 ",
INT.T);
trun ("let var x = 0 in x := 2 ",
INT.T);
erun ("let var x : real = 2.5 in x := 2 ",
"error.CompilerError: 1/32-1/33 type mismatch: found int but expected real");
erun ("let var x : int = 2 in x := 2.5 ",
"error.CompilerError: 1/29-1/32 type mismatch: found real but expected int");
}

@Test
public void testCond() throws Exception {
trun ("if true then () ",
UNIT.T);
trun ("if true then (2+2;print_int(4)) ",
UNIT.T);
erun ("if false then false ",
"error.CompilerError: 1/15-1/20 type mismatch: found bool but expected unit");
erun ("if false then false else true ",
"error.CompilerError: 1/26-1/30 type mismatch: found bool but expected unit");
erun ("if false then false else ",
"error.CompilerError: 1/26-1/26 Syntax error at ''");
}
}