-
Notifications
You must be signed in to change notification settings - Fork 29
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
Introducing some structure for model method bodies #3571
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2346,7 +2346,7 @@ public Object visitField_declaration(JmlParser.Field_declarationContext ctx) { | |
|
||
@Override | ||
public SLExpression visitMethod_declaration(JmlParser.Method_declarationContext ctx) { | ||
if (ctx.method_body() == null) { | ||
if (ctx.method_body == null) { | ||
return new SLExpression(tb.tt()); | ||
} | ||
|
||
|
@@ -2363,15 +2363,14 @@ public SLExpression visitMethod_declaration(JmlParser.Method_declarationContext | |
ParserRuleContext equal = JmlFacade.parseExpr(ctx.IDENT() + paramsString); | ||
Object a = accept(equal); | ||
|
||
SLExpression body = accept(ctx.method_body().expression()); | ||
SLExpression body = accept(ctx.method_body); | ||
SLParameters params = visitParameters(ctx.param_list()); | ||
SLExpression apply = lookupIdentifier(ctx.IDENT().getText(), null, params, ctx); | ||
|
||
var forbiddenHeapVar = services.getTypeConverter().getHeapLDT().getHeap(); | ||
boolean applyContainsHeap = TermUtil.contains(apply.getTerm(), forbiddenHeapVar); | ||
boolean bodyContainsHeap = TermUtil.contains(body.getTerm(), forbiddenHeapVar); | ||
|
||
|
||
if (!applyContainsHeap && bodyContainsHeap) { | ||
// NOT (no heap in applies --> no heap in body) | ||
raiseError(ctx, "Heap used in a `no_state` method."); | ||
|
@@ -2380,6 +2379,40 @@ public SLExpression visitMethod_declaration(JmlParser.Method_declarationContext | |
return termFactory.eq(apply, body); | ||
} | ||
|
||
@Override | ||
public SLExpression visitMbody_return(JmlParser.Mbody_returnContext ctx) { | ||
return accept(ctx.expression()); | ||
mattulbrich marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
@Override | ||
public SLExpression visitMbody_block(JmlParser.Mbody_blockContext ctx) { | ||
resolverManager.pushLocalVariablesNamespace(); | ||
List<Pair<LogicVariable, Term>> substList = new ArrayList<>(); | ||
for (JmlParser.Mbody_varContext varCtx : ctx.mbody_var()) { | ||
String name = varCtx.IDENT().getText(); | ||
SLExpression expr = accept(varCtx.expression()); | ||
Term term = expr.getTerm(); | ||
LogicVariable logVar = new LogicVariable(new Name(name), term.sort()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What happens on a name clash?
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah. This is currently allowed. You can write It would be nicer to ensure:
It is not required technically, and everything is welldefined in either case. But it would violate Java principles. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will add this. |
||
substList.add(new Pair<>(logVar, term)); | ||
resolverManager.putIntoTopLocalVariablesNamespace(ImmutableList.of(logVar), | ||
javaInfo.getKeYJavaType(term.sort())); | ||
} | ||
SLExpression stmExpr = accept(ctx.mbody_statement()); | ||
Term term = stmExpr.getTerm(); | ||
for (Pair<LogicVariable, Term> lv : substList.reversed()) { | ||
term = tb.subst(lv.first, lv.second, term); | ||
} | ||
resolverManager.popLocalVariablesNamespace(); | ||
return new SLExpression(term); | ||
} | ||
|
||
@Override | ||
public SLExpression visitMbody_if(JmlParser.Mbody_ifContext ctx) { | ||
SLExpression cond = accept(ctx.getChild(ParserRuleContext.class, 0)); | ||
SLExpression then = accept(ctx.getChild(ParserRuleContext.class, 1)); | ||
SLExpression elze = accept(ctx.getChild(ParserRuleContext.class, 2)); | ||
return new SLExpression(tb.ife(cond.getTerm(), then.getTerm(), elze.getTerm())); | ||
} | ||
|
||
@Override | ||
public Object visitHistory_constraint(JmlParser.History_constraintContext ctx) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we reached a point in which we should rather rewrite the lexer w/o using modes for top-level and expr-mode.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if these modes are really necessary in the lexer.
Yes one could name a variable "ensures", and write
ensures ensures > 4;
. But this is fully confusing.I would be in favour of allowing backticks in these cases for turning keywords into identifiers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I did this, I came from the
jmllang
lexer/parser (Java+JML in ANTLR), where I used this heavily.The advantage is, that the error messages are a little bit better. ("Expected identifier" vs "Expected identifier, ensures, requires, ... "). But the price is a complicated lexer.
I would now get rid of it, and introduce a grammar rule:
I would keep modes for Strings & Co.
Do we not have (proposed) backticks for JavaDL escape of complete terms?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe, don't know. Was that not
(* ... *)
?Actually I even actively avoid
ensures ensures > 4;
to be legal.Escaping the identifier ensures seems like a natural thing to do.
Languages like SMT, SQL, ... have support for this, with explicit escapes.
(I had it in ivil, too. It was a simple addition to the parser.)
While it is a discussion worth having, it is beyond this PR that will have to accommodate to the current parser framework; and does so with not so much extra overhead.
(Just that an extra ")" leads back to toplevel mode if that is enabled -- this condition might probably even be dropped, but I wanted to be conservative.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not so complicated: #3572
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apparently we do not show these long "expected ....." lists anyway in our syntax error to string conversion anyway, so this may work well (eventually).