mirror of
https://github.com/aNNiMON/Own-Programming-Language-Tutorial.git
synced 2024-09-20 08:44:20 +03:00
При оптимизации не учитывались FunctionValue и аргументы функции по умолчанию
This commit is contained in:
parent
e08f1d3df9
commit
35f859ade3
@ -12,8 +12,8 @@ import com.annimon.ownlang.parser.ast.Statement;
|
|||||||
*/
|
*/
|
||||||
public final class UserDefinedFunction implements Function {
|
public final class UserDefinedFunction implements Function {
|
||||||
|
|
||||||
private final Arguments arguments;
|
public final Arguments arguments;
|
||||||
private final Statement body;
|
public final Statement body;
|
||||||
|
|
||||||
public UserDefinedFunction(Arguments arguments, Statement body) {
|
public UserDefinedFunction(Arguments arguments, Statement body) {
|
||||||
this.arguments = arguments;
|
this.arguments = arguments;
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package com.annimon.ownlang.parser.optimization;
|
package com.annimon.ownlang.parser.optimization;
|
||||||
|
|
||||||
|
import com.annimon.ownlang.lib.Types;
|
||||||
|
import com.annimon.ownlang.lib.UserDefinedFunction;
|
||||||
import com.annimon.ownlang.lib.Value;
|
import com.annimon.ownlang.lib.Value;
|
||||||
import com.annimon.ownlang.parser.ast.*;
|
import com.annimon.ownlang.parser.ast.*;
|
||||||
import static com.annimon.ownlang.parser.visitors.VisitorUtils.isValue;
|
import static com.annimon.ownlang.parser.visitors.VisitorUtils.isValue;
|
||||||
@ -160,9 +162,12 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Node visit(FunctionDefineStatement s, T t) {
|
public Node visit(FunctionDefineStatement s, T t) {
|
||||||
|
final Arguments newArgs = new Arguments();
|
||||||
|
boolean changed = visit(s.arguments, newArgs, t);
|
||||||
|
|
||||||
final Node body = s.body.accept(this, t);
|
final Node body = s.body.accept(this, t);
|
||||||
if (body != s.body) {
|
if (changed || body != s.body) {
|
||||||
return new FunctionDefineStatement(s.name, s.arguments, consumeStatement(body));
|
return new FunctionDefineStatement(s.name, newArgs, consumeStatement(body));
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -359,6 +364,13 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Node visit(ValueExpression s, T t) {
|
public Node visit(ValueExpression s, T t) {
|
||||||
|
if ( (s.value.type() == Types.FUNCTION) && (s.value.raw() instanceof UserDefinedFunction) ) {
|
||||||
|
final UserDefinedFunction function = (UserDefinedFunction) s.value.raw();
|
||||||
|
final UserDefinedFunction accepted = visit(function, t);
|
||||||
|
if (accepted != function) {
|
||||||
|
return new ValueExpression(accepted);
|
||||||
|
}
|
||||||
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -386,6 +398,36 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public UserDefinedFunction visit(UserDefinedFunction s, T t) {
|
||||||
|
final Arguments newArgs = new Arguments();
|
||||||
|
boolean changed = visit(s.arguments, newArgs, t);
|
||||||
|
|
||||||
|
final Node body = s.body.accept(this, t);
|
||||||
|
if (changed || body != s.body) {
|
||||||
|
return new UserDefinedFunction(newArgs, consumeStatement(body));
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
protected boolean visit(final Arguments in, final Arguments out, T t) {
|
||||||
|
boolean changed = false;
|
||||||
|
for (Argument argument : in) {
|
||||||
|
final Expression valueExpr = argument.getValueExpr();
|
||||||
|
if (valueExpr == null) {
|
||||||
|
out.addRequired(argument.getName());
|
||||||
|
} else {
|
||||||
|
final Node expr = valueExpr.accept(this, t);
|
||||||
|
if (expr != valueExpr) {
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
out.addOptional(argument.getName(), (Expression) expr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
protected Statement consumeStatement(Node node) {
|
protected Statement consumeStatement(Node node) {
|
||||||
if (node instanceof Statement) {
|
if (node instanceof Statement) {
|
||||||
return (Statement) node;
|
return (Statement) node;
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
package com.annimon.ownlang.parser.optimization;
|
package com.annimon.ownlang.parser.optimization;
|
||||||
|
|
||||||
|
import com.annimon.ownlang.lib.UserDefinedFunction;
|
||||||
import com.annimon.ownlang.lib.Value;
|
import com.annimon.ownlang.lib.Value;
|
||||||
import com.annimon.ownlang.lib.Variables;
|
import com.annimon.ownlang.lib.Variables;
|
||||||
import com.annimon.ownlang.parser.ast.Accessible;
|
import com.annimon.ownlang.parser.ast.Accessible;
|
||||||
import com.annimon.ownlang.parser.ast.Argument;
|
import com.annimon.ownlang.parser.ast.Argument;
|
||||||
|
import com.annimon.ownlang.parser.ast.Arguments;
|
||||||
import com.annimon.ownlang.parser.ast.AssignmentExpression;
|
import com.annimon.ownlang.parser.ast.AssignmentExpression;
|
||||||
import com.annimon.ownlang.parser.ast.ContainerAccessExpression;
|
import com.annimon.ownlang.parser.ast.ContainerAccessExpression;
|
||||||
import com.annimon.ownlang.parser.ast.DestructuringAssignmentStatement;
|
import com.annimon.ownlang.parser.ast.DestructuringAssignmentStatement;
|
||||||
|
import com.annimon.ownlang.parser.ast.Expression;
|
||||||
import com.annimon.ownlang.parser.ast.ForeachArrayStatement;
|
import com.annimon.ownlang.parser.ast.ForeachArrayStatement;
|
||||||
import com.annimon.ownlang.parser.ast.ForeachMapStatement;
|
import com.annimon.ownlang.parser.ast.ForeachMapStatement;
|
||||||
import com.annimon.ownlang.parser.ast.FunctionDefineStatement;
|
import com.annimon.ownlang.parser.ast.FunctionDefineStatement;
|
||||||
@ -81,15 +84,6 @@ public class VariablesGrabber extends OptimizationVisitor<Map<String, VariableIn
|
|||||||
return super.visit(s, t);
|
return super.visit(s, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Node visit(FunctionDefineStatement s, Map<String, VariableInfo> t) {
|
|
||||||
for (Argument argument : s.arguments) {
|
|
||||||
final String variableName = argument.getName();
|
|
||||||
t.put(variableName, variableInfo(t, variableName));
|
|
||||||
}
|
|
||||||
return super.visit(s, t);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Node visit(MatchExpression s, Map<String, VariableInfo> t) {
|
public Node visit(MatchExpression s, Map<String, VariableInfo> t) {
|
||||||
for (MatchExpression.Pattern pattern : s.patterns) {
|
for (MatchExpression.Pattern pattern : s.patterns) {
|
||||||
@ -137,6 +131,20 @@ public class VariablesGrabber extends OptimizationVisitor<Map<String, VariableIn
|
|||||||
return super.visit(s, t);
|
return super.visit(s, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean visit(Arguments in, Arguments out, Map<String, VariableInfo> t) {
|
||||||
|
for (Argument argument : in) {
|
||||||
|
final String variableName = argument.getName();
|
||||||
|
final VariableInfo var = variableInfo(t, variableName);
|
||||||
|
final Expression expr = argument.getValueExpr();
|
||||||
|
if (expr != null && isValue(expr)) {
|
||||||
|
var.value = ((ValueExpression) expr).value;
|
||||||
|
}
|
||||||
|
t.put(variableName, var);
|
||||||
|
}
|
||||||
|
return super.visit(in, out, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private VariableInfo variableInfo(Map<String, VariableInfo> t, final String variableName) {
|
private VariableInfo variableInfo(Map<String, VariableInfo> t, final String variableName) {
|
||||||
|
Loading…
Reference in New Issue
Block a user