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

Trabalho prático #50

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
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