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

Tp #51

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open

Tp #51

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
6 changes: 6 additions & 0 deletions Grupo.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Trabalho da Disciplina de Construção de Compiladores I - BCC328

Alunos:

Breno Nunes de Sena Keller - 14.1.4010
Débora Nasser Diniz - 14.1.4307
113 changes: 92 additions & 21 deletions src/main/cup/parser.cup
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,17 @@ terminal String LITBOOL;
terminal String ID;
terminal PLUS, MINUS, TIMES, DIV, UMINUS;
terminal AND, OR;
terminal LPAREN, RPAREN;
terminal LESS, LESSEG, MORE, MOREEG, EQUALS, DIF;
terminal LPAREN, RPAREN, LBRACKET, RBRACKET, LBRACE, RBRACE, AT, DOT;
terminal COMMA, SEMICOLON;
terminal VAR, EQ, COLON;
terminal LET, IN;
terminal ASSIGN;
terminal IF, THEN, ELSE;
terminal TYPE;
terminal BREAK;
terminal WHILE, DO;
terminal FUNCTION;

non terminal Exp program;
non terminal Exp exp;
Expand All @@ -60,12 +64,19 @@ non terminal DecVar decvar;
non terminal DecType dectype;
non terminal List<DecType> dectypes;
non terminal List<Dec> decs;
non terminal List<Dec> decs_beg_with_variable, decs_beg_with_type;
non terminal List<Dec> decs_beg_with_variable, decs_beg_with_type, decs_beg_with_function;
non terminal Var var;
non terminal Ty ty;
non terminal List<Param> params, paramsRest;
non terminal Param param;
non terminal DecFunction decfunction;
non terminal List<DecFunction> decfunctions;
non terminal List<ParamAssign> paramsAssign, paramsAssignRest;
non terminal ParamAssign paramAssign;

precedence left OR;
precedence left AND;
precedence left EQUALS, DIF, LESS, LESSEG, MORE, MOREEG;
precedence left PLUS, MINUS;
precedence left TIMES, DIV;
precedence left UMINUS;
Expand All @@ -78,23 +89,33 @@ 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); :}
| var:v ASSIGN exp:e {: RESULT = new ExpAssign(loc(vxleft,exright), v, e); :}
| 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); :}
| IF:i exp:t THEN exp:a ELSE exp:b {: RESULT = new ExpIf(loc(ixleft,bxright), t, a, b); :}
| IF:i exp:t THEN exp:a {: RESULT = new ExpIf(loc(ixleft,axright), t, a, null); :}
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); :}
| exp:x LESS exp:y {: RESULT = new ExpBinOp(loc(xxleft,yxright), ExpBinOp.Op.LESS, x, y); :}
| exp:x LESSEG exp:y {: RESULT = new ExpBinOp(loc(xxleft,yxright), ExpBinOp.Op.LESSEG, x, y); :}
| exp:x MORE exp:y {: RESULT = new ExpBinOp(loc(xxleft,yxright), ExpBinOp.Op.MORE, x, y); :}
| exp:x MOREEG exp:y {: RESULT = new ExpBinOp(loc(xxleft,yxright), ExpBinOp.Op.MOREEG, x, y); :}
| exp:x EQUALS exp:y {: RESULT = new ExpBinOp(loc(xxleft,yxright), ExpBinOp.Op.EQUALS, x, y); :}
| exp:x DIF exp:y {: RESULT = new ExpBinOp(loc(xxleft,yxright), ExpBinOp.Op.DIF, 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); :}
| var:v ASSIGN exp:e {: RESULT = new ExpAssign(loc(vxleft,exright), v, e); :}
| 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); :}
| IF:i exp:t THEN exp:a ELSE exp:b {: RESULT = new ExpIf(loc(ixleft,bxright), t, a, b); :}
| IF:i exp:t THEN exp:a {: RESULT = new ExpIf(loc(ixleft,axright), t, a, null); :}
| BREAK:x {: RESULT = new ExpBreak(loc(xxleft,xxright)); :}
| WHILE:i exp:t DO exp:a {: RESULT = new ExpWhile(loc(ixleft,axright), t, a); :}
| AT:i ID:id LBRACKET exps:x RBRACKET:r {: RESULT = new ExpArray(loc(ixleft,rxright),id, x); :}
| AT:i ID:id LBRACE paramsAssign:p RBRACE:r{: RESULT = new ExpRecord(loc(ixleft,rxright),id, p); :}
;

exps ::=
Expand Down Expand Up @@ -134,23 +155,73 @@ dectypes ::=
decs ::=
decs_beg_with_variable:ds {: RESULT = ds; :}
| decs_beg_with_type:ds {: RESULT = ds; :}
| decs_beg_with_function:ds {: RESULT = ds; :}
;

decs_beg_with_variable ::=
decvar:d {: RESULT = List.of(d); :}
| decvar:d decs_beg_with_variable:ds {: RESULT = ds.prepend(d); :}
| decvar:d decs_beg_with_type:ds {: RESULT = ds.prepend(d); :}
| decvar:d decs_beg_with_function:ds {: RESULT = ds.prepend(d); :}
;

decs_beg_with_function ::=
decfunctions:d {: RESULT = List.of(new DecFunctionMutual(loc(dxleft,dxright), d)); :}
| decfunctions:d decs_beg_with_variable:ds {: RESULT = ds.prepend(new DecFunctionMutual(loc(dxleft,dxright), d)); :}
| decfunctions:d decs_beg_with_type:ds {: RESULT = ds.prepend(new DecFunctionMutual(loc(dxleft,dxright), d)); :}
;

decfunctions::=
decfunction:d {: RESULT = List.of(d); :}
| decfunction:d decfunctions:ds {: RESULT = ds.prepend(d); :}
;

decfunction ::=
FUNCTION:f ID:id LPAREN params:p RPAREN COLON ID:r EQ exp:e {: RESULT = new DecFunction(loc(fxleft,exright), id, p, r, e); :}
;

decs_beg_with_type ::=
dectypes:dt {: RESULT = List.of(new DecTypeMutual(loc(dtxleft,dtxright), dt)); :}
| dectypes:dt decs_beg_with_variable:ds {: RESULT = ds.prepend(new DecTypeMutual(loc(dtxleft,dtxright), dt)); :}
| dectypes:dt decs_beg_with_function:ds {: RESULT = ds.prepend(new DecTypeMutual(loc(dtxleft,dtxright), dt)); :}
;

var ::=
ID:v {: RESULT = new VarSimple(loc(vxleft,vxright), v); :}
ID:v {: RESULT = new VarSimple(loc(vxleft,vxright), v); :}
| var:v LBRACKET exp:e RBRACKET:r {: RESULT = new VarSubscript(loc(vxleft,rxright), v, e); :}
| var:v DOT ID:id {: RESULT = new VarField(loc(vxleft,idxright), v, id); :}
;

ty ::=
ID:id {: RESULT = new TyName(loc(idxleft,idxright), id); :}
ID:id {: RESULT = new TyName(loc(idxleft,idxright), id); :}
| LBRACKET:l ID:id RBRACKET:r {: RESULT = new TyArray(loc(lxleft,rxright), id); :}
| LBRACE:l params:p RBRACE:r {: RESULT = new TyRecord(loc(lxleft,rxright), p); :}
;

param ::=
ID:id COLON ID:type {: RESULT = new Param(loc(idxleft,typexright),id,type); :}
;

params ::=
/* empty */ {: RESULT = List.empty(); :}
| param:p paramsRest:ps {: RESULT = ps.prepend(p); :}
;

paramsRest ::=
/* empty */ {: RESULT = List.empty(); :}
| COMMA param:p paramsRest:ps {: RESULT = ps.prepend(p); :}
;

paramAssign ::=
ID:id EQ exp:e {: RESULT = new ParamAssign(loc(idxleft,exright), id, e); :}
;

paramsAssign ::=
/* empty */ {: RESULT = List.empty(); :}
| paramAssign:p paramsAssignRest:ps {: RESULT = ps.prepend(p); :}
;

paramsAssignRest ::=
/* empty */ {: RESULT = List.empty(); :}
| COMMA paramAssign:p paramsAssignRest:ps {: RESULT = ps.prepend(p); :}
;
32 changes: 32 additions & 0 deletions src/main/java/absyn/DecFunction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package absyn;

import env.Env;
import javaslang.collection.List;
import javaslang.collection.Tree;
import parse.Loc;

public class DecFunction extends AST {
public final String name;
public final List<Param> params;
public final String returnType;
public final Exp exp;

public DecFunction(Loc loc, String name, List<Param> params, String returnType, Exp exp) {
super(loc);
this.name = name;
this.params = params;
this.returnType = returnType;
this.exp = exp;
}

@Override
public Tree.Node<String> toTree() {
List<Tree.Node<String>> children = List.of(Tree.of(name));
for (Param p : params) {
children = children.append(p.toTree());
}
children = children.append(Tree.of(returnType));
children = children.append(exp.toTree());
return Tree.of("DecFunction", children);
}
}
67 changes: 67 additions & 0 deletions src/main/java/absyn/DecFunctionMutual.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package absyn;

import env.Env;
import error.CompilerError;
import javaslang.collection.List;
import javaslang.collection.Tree;
import parse.Loc;
import types.*;

import static semantic.SemanticHelper.typeMismatch;
import static semantic.SemanticHelper.undefined;

public class DecFunctionMutual extends Dec {

public final List<DecFunction> decs;

public DecFunctionMutual(Loc loc, List<DecFunction> decs) {
super(loc);
this.decs = decs;
}

@Override
public Tree.Node<String> toTree() {
return Tree.of("DecFunctionMutual", decs.map(DecFunction::toTree));
}

@Override
public void semantic(Env env) {
for (DecFunction f : decs) {
List<Type> t_params = List.of();
for (Param p : f.params) {
Type t = env.tenv.get(p.nameType);
if (t == null) {
throw undefined(p.loc, "type", p.nameType);
}
t_params = t_params.append(t);
}

Type t_result = UNIT.T;
if (f.returnType != null) {
t_result = env.tenv.get(f.returnType);
if (t_result == null) {
throw undefined(f.loc, "type", f.returnType);
}
}
env.venv.put(f.name, new FUNCTION(t_result, t_params));
}
for (DecFunction f : decs) {
FUNCTION function = (FUNCTION) env.venv.get(f.name);
List<Type> t_params = function.formals;

env.venv.beginScope();
List<Param> ps = f.params;
while (!ps.isEmpty()) {
env.venv.put(ps.head().name, t_params.head());
ps = ps.tail();
t_params = t_params.tail();
}

Type t_body = f.exp.semantic(env);
if (!t_body.is(function.result)) {
typeMismatch(f.exp.loc, t_body, function.result);
}
env.venv.endScope();
}
}
}
38 changes: 25 additions & 13 deletions src/main/java/absyn/DecTypeMutual.java
Original file line number Diff line number Diff line change
@@ -1,28 +1,40 @@
package absyn;

import env.Env;
import error.CompilerError;
import javaslang.collection.List;
import javaslang.collection.Tree;
import parse.Loc;
import semantic.SemanticHelper;
import types.NAME;
import types.Type;

public class DecTypeMutual extends Dec {

public final List<DecType> decs;
public final List<DecType> decs;

public DecTypeMutual(Loc loc, List<DecType> decs) {
super(loc);
this.decs = decs;
}
public DecTypeMutual(Loc loc, List<DecType> decs) {
super(loc);
this.decs = decs;
}

@Override
public Tree.Node<String> toTree() {
return Tree.of("DecTypeMutual", decs.map(DecType::toTree));
}
@Override
public Tree.Node<String> toTree() {
return Tree.of("DecTypeMutual", decs.map(DecType::toTree));
}

@Override
public void semantic(Env env) {

}
@Override
public void semantic(Env env) {
for (DecType d : decs) {
env.tenv.put(d.name, new NAME(d.name));
}
for (DecType d : decs) {
Type t = d.ty.semantic(env);
Type tName = env.tenv.get(d.name);
if (!(tName instanceof NAME)) {
throw new CompilerError("bug!!!!!!");
}
((NAME) tName).binding = t;
}
}
}
53 changes: 53 additions & 0 deletions src/main/java/absyn/ExpArray.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package absyn;

import env.Env;
import error.CompilerError;
import javaslang.collection.List;
import javaslang.collection.Tree;
import parse.Loc;
import types.ARRAY;
import types.Type;

import static semantic.SemanticHelper.typeMismatch;
import static semantic.SemanticHelper.undefined;

public class ExpArray extends Exp {

public final String typeName;
public final List<Exp> exp;

public ExpArray(Loc loc, String typeName, List<Exp> exp) {
super(loc);
this.typeName = typeName;
this.exp = exp;
}

@Override
public Tree.Node<String> toTree() {
List<Tree.Node<String>> children = List.of();
children = children.append(Tree.of(typeName));
for (Exp e : exp) {
children = children.append(e.toTree());
}
return Tree.of("ExpArray", children);
}

@Override
protected Type semantic_(Env env) {
Type type = env.tenv.get(typeName);
if (type == null) {
throw undefined(loc, "type", typeName);
}
if (!(type.actual() instanceof ARRAY)) {
throw new CompilerError("type mismatch: found " + type.toString() + " but expected array");
}
ARRAY array = (ARRAY) type.actual();
for (Exp e : exp) {
Type t = e.semantic(env);
if (!(t.is(array.type.actual()))) {
throw typeMismatch(loc, t, array.type);
}
}
return type;
}
}
Loading