Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
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
2 changes: 2 additions & 0 deletions Alunos.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Marcos Vinicius Oliveira Souza
João Pedro Lonczynski
2 changes: 1 addition & 1 deletion doc/eplan-compiler.tex
Original file line number Diff line number Diff line change
Expand Up @@ -1526,7 +1526,7 @@ \section{Análise semântica}
% \begin{pygmented}[]
% // declarações
% Dec(Loc loc) // classe abstrata
% VarDec(Loc loc, Symbol name, Symbol type, Exp init)
% VarDec(Loc loc, Symbol name, Symbol type, Exp body)

% // variáveis
% Var(Loc loc) // classe abstrata
Expand Down
134 changes: 104 additions & 30 deletions src/main/cup/parser.cup
Original file line number Diff line number Diff line change
Expand Up @@ -51,21 +51,34 @@ terminal LET, IN;
terminal ASSIGN;
terminal IF, THEN, ELSE;
terminal TYPE;

non terminal Exp program;
non terminal Exp exp;
non terminal List<Exp> exps, expsRest;
non terminal List<Exp> expseq, expseqRest;
non terminal DecVar decvar;
non terminal DecType dectype;
terminal EQT, NEQ, LT, LE, GT, GE;
terminal WHILE, DO, BREAK;
terminal FUNCTION;
terminal LBRACK, RBRACK, AT;
terminal LBRACE, RBRACE;
terminal DOT;

non terminal Exp program;
non terminal Exp exp;
non terminal List<Exp> exps, expsRest;
non terminal List<Exp> expseq, expseqRest;
non terminal DecVar decvar;
non terminal DecType dectype;
non terminal DecFunction decfunc;
non terminal List<DecType> dectypes;
non terminal List<Dec> decs;
non terminal List<Dec> decs_beg_with_variable, decs_beg_with_type;
non terminal Var var;
non terminal Ty ty;
non terminal List<Dec> decs;
non terminal List<Dec> decs_beg_with_variable, decs_beg_with_type, decs_beg_with_func;
non terminal Var var;
non terminal Ty ty;
non terminal Parameter parameter;
non terminal List<Parameter> parameters, parametersRest;
non terminal List<DecFunction> decfuncs;
non terminal ParameterWithExp parameterexp;
non terminal List<ParameterWithExp> parameterexps, parameterexpsRest;

precedence left OR;
precedence left AND;
precedence nonassoc EQT, NEQ, LT, LE, GT, GE;
precedence left PLUS, MINUS;
precedence left TIMES, DIV;
precedence left UMINUS;
Expand All @@ -78,23 +91,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 EQT exp:y {: RESULT = new ExpBinOp(loc(xxleft,yxright), ExpBinOp.Op.EQT, x, y); :}
| exp:x NEQ exp:y {: RESULT = new ExpBinOp(loc(xxleft,yxright), ExpBinOp.Op.NEQ, x, y); :}
| exp:x LT exp:y {: RESULT = new ExpBinOp(loc(xxleft,yxright), ExpBinOp.Op.LT, x, y); :}
| exp:x LE exp:y {: RESULT = new ExpBinOp(loc(xxleft,yxright), ExpBinOp.Op.LE, x, y); :}
| exp:x GT exp:y {: RESULT = new ExpBinOp(loc(xxleft,yxright), ExpBinOp.Op.GT, x, y); :}
| exp:x GE exp:y {: RESULT = new ExpBinOp(loc(xxleft,yxright), ExpBinOp.Op.GE, 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); :}
| WHILE:w exp:t DO exp:b {: RESULT = new ExpWhile(loc(wxleft,bxright), t, b); :}
| BREAK:b {: RESULT = new ExpBreak(loc(bxleft,bxright)); :}
| AT:a ID:id LBRACK exps:e RBRACK:r {: RESULT = new ExpArray(loc(axleft,rxright),id,e); :}
| AT:a ID:id LBRACE parameterexps:f RBRACE:r{: RESULT = new ExpRecord(loc(axleft,rxright),id,f); :}
;

exps ::=
Expand Down Expand Up @@ -134,23 +157,74 @@ dectypes ::=
decs ::=
decs_beg_with_variable:ds {: RESULT = ds; :}
| decs_beg_with_type:ds {: RESULT = ds; :}
| decs_beg_with_func: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_func:ds {: RESULT = ds.prepend(d); :}
;

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_func: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:x LBRACK exp:e RBRACK:r {: RESULT = new VarSubscript(loc(xxleft,rxright), x, e); :}
| var:x DOT ID:id {: RESULT = new VarField(loc(xxleft,idxright), x, id); :}
;

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

parameter ::=
ID:n COLON ID:t {: RESULT = new Parameter(loc(nxleft,txright),n,t); :}
;

parameters ::=
/* empty */ {: RESULT = List.empty(); :}
| parameter:p parametersRest:ps {: RESULT = ps.prepend(p); :}
;

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

parameterexp ::=
ID:n EQ exp:e {: RESULT = new ParameterWithExp(loc(nxleft,exright),n,e); :}
;

parameterexps ::=
/* empty */ {: RESULT = List.empty(); :}
| parameterexp:p parameterexpsRest:ps {: RESULT = ps.prepend(p); :}
;

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

decfunc ::=
FUNCTION:f ID:n LPAREN parameters:p RPAREN COLON ID:t EQ exp:b {: RESULT = new DecFunction(loc(fxleft,bxright),n,p,t,b); :}
| FUNCTION:f ID:n LPAREN parameters:p RPAREN EQ exp:b {: RESULT = new DecFunction(loc(fxleft,bxright),n,p,null,b); :}
;

decfuncs ::=
decfunc:d {: RESULT = List.of(d); :}
| decfunc:d decfuncs:ds {: RESULT = ds.prepend(d); :}
;

decs_beg_with_func ::=
decfuncs:d {: RESULT = List.of(new DecFunctionMutual(loc(dxleft,dxright), d)); :}
| decfuncs:d decs_beg_with_variable:ds {: RESULT = ds.prepend(new DecFunctionMutual(loc(dxleft,dxright), d)); :}
| decfuncs:d decs_beg_with_type:ds {: RESULT = ds.prepend(new DecFunctionMutual(loc(dxleft,dxright), d)); :}
;
2 changes: 1 addition & 1 deletion src/main/java/absyn/Dec.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ public Dec(Loc loc) {
}

// Do semantic analysis of the declaraction
public abstract void semantic(Env env);
public abstract Type semantic(Env env);

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

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

public class DecFunction extends AST {

public final String name;
public final List<Parameter> parameters;
public final String typeName;
public final Exp body;

public DecFunction(Loc loc, String name, List parameters, String typeName, Exp body) {
super(loc);
this.name = name;
this.parameters = parameters;
this.typeName = typeName;
this.body = body;
}

@Override
public Tree.Node<String> toTree() {
return Tree.of("DecFunction: " + name,
Tree.of("Parameters", parameters.map(Parameter::toTree)),
Tree.of(typeName == null ? "" : typeName),
body.toTree()
);
}

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

import env.Env;
import javaslang.collection.List;
import javaslang.collection.Tree;
import parse.Loc;
import semantic.SemanticHelper;
import types.FUNCTION;
import types.Type;
import types.UNIT;


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 Type semantic(Env env) {
for (DecFunction d : decs) {
List<Type> t_params = d.parameters.map(p -> p.semantic(env));

Type t_result = UNIT.T;
if (d.typeName != null) {
t_result = env.tenv.get(d.typeName);
if (t_result == null) {
throw SemanticHelper.undefined(d.loc, "type", d.name);
}
}

env.venv.put(d.name, new FUNCTION(t_result, t_params));
}
for (DecFunction d : decs) {
env.venv.beginScope();

FUNCTION func = (FUNCTION) env.venv.get(d.name);
List<Type> t_params = func.formals;
List<Parameter> parameters = d.parameters;

while (!parameters.isEmpty()) {
env.venv.put(parameters.head().name, t_params.head());
parameters = parameters.tail();
t_params = t_params.tail();
}

Type t_body = d.body.semantic(env);
if (!t_body.is(func.result))
throw SemanticHelper.functionTypeMismatch(d.loc, func.result, t_body);
env.venv.endScope();
}
return null;
}
}
39 changes: 25 additions & 14 deletions src/main/java/absyn/DecTypeMutual.java
Original file line number Diff line number Diff line change
@@ -1,28 +1,39 @@
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 class DecTypeMutual extends Dec {

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

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

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

}
@Override
public Type 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;
}
return null;
}
}
3 changes: 2 additions & 1 deletion src/main/java/absyn/DecVar.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public Tree.Node<String> toTree() {
}

@Override
public void semantic(Env env) {
public Type semantic(Env env) {
Type t_init = init.semantic(env);
Type t_var = t_init;
if (typeName != null) {
Expand All @@ -42,5 +42,6 @@ public void semantic(Env env) {
t_var = t_typeName;
}
env.venv.put(name, t_var);
return t_init;
}
}
Loading