From b69c8f7c8e2c16aade681ceaae046456a5ef2a85 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Wed, 6 Jan 2016 08:31:13 +0000 Subject: Partially implement method overloading --- .../org/zwobble/couscous/ast/MethodCallNode.java | 4 ++ .../java/org/zwobble/couscous/ast/MethodNode.java | 8 ++++ .../org/zwobble/couscous/ast/MethodSignature.java | 44 ++++++++++++++++++++++ .../zwobble/couscous/ast/StaticMethodCallNode.java | 4 ++ .../backends/python/PythonCodeGenerator.java | 11 ++++-- .../zwobble/couscous/interpreter/Interpreter.java | 1 + .../couscous/interpreter/MethodSignature.java | 38 ------------------- .../zwobble/couscous/interpreter/NoSuchMethod.java | 2 + .../couscous/interpreter/values/ConcreteType.java | 17 ++------- 9 files changed, 75 insertions(+), 54 deletions(-) create mode 100644 src/main/java/org/zwobble/couscous/ast/MethodSignature.java delete mode 100644 src/main/java/org/zwobble/couscous/interpreter/MethodSignature.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java b/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java index f65a9ae..ba50f17 100644 --- a/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java +++ b/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java @@ -111,6 +111,10 @@ public class MethodCallNode implements ExpressionNode { public TypeName getType() { return type; } + + public MethodSignature signature() { + return new MethodSignature(methodName, eagerMap(arguments, argument -> argument.getType())); + } @Override public T accept(ExpressionNodeMapper visitor) { diff --git a/src/main/java/org/zwobble/couscous/ast/MethodNode.java b/src/main/java/org/zwobble/couscous/ast/MethodNode.java index 5763b11..86ae649 100644 --- a/src/main/java/org/zwobble/couscous/ast/MethodNode.java +++ b/src/main/java/org/zwobble/couscous/ast/MethodNode.java @@ -6,6 +6,8 @@ import org.zwobble.couscous.ast.visitors.NodeMapper; import java.util.List; import java.util.function.Function; +import static org.zwobble.couscous.util.ExtraLists.eagerMap; + public class MethodNode implements CallableNode { public static Builder staticMethod(String name) { return builder(name).isStatic(true); @@ -116,6 +118,12 @@ public class MethodNode implements CallableNode { return body; } + public MethodSignature signature() { + return new MethodSignature( + name, + eagerMap(arguments, argument -> argument.getType())); + } + public MethodNode mapBody(Function, List> function) { return new MethodNode(annotations, isStatic, name, arguments, function.apply(body)); } diff --git a/src/main/java/org/zwobble/couscous/ast/MethodSignature.java b/src/main/java/org/zwobble/couscous/ast/MethodSignature.java new file mode 100644 index 0000000..fb2dc64 --- /dev/null +++ b/src/main/java/org/zwobble/couscous/ast/MethodSignature.java @@ -0,0 +1,44 @@ +package org.zwobble.couscous.ast; + +import java.util.List; +import java.util.Objects; + +public class MethodSignature { + private String name; + private List arguments; + + public MethodSignature(String name, List arguments) { + this.name = name; + this.arguments = arguments; + } + + public String getName() { + return name; + } + + public List getArguments() { + return arguments; + } + + @Override + public String toString() { + return "MethodSignature(" + + "name='" + name + '\'' + + ", arguments=" + arguments + + ')'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + MethodSignature that = (MethodSignature) o; + return Objects.equals(name, that.name) && + Objects.equals(arguments, that.arguments); + } + + @Override + public int hashCode() { + return Objects.hash(name, arguments); + } +} diff --git a/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java b/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java index 7c3b90b..1309c6e 100644 --- a/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java +++ b/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java @@ -81,6 +81,10 @@ public class StaticMethodCallNode implements ExpressionNode { public TypeName getType() { return type; } + + public MethodSignature signature() { + return new MethodSignature(methodName, eagerMap(arguments, argument -> argument.getType())); + } @Override public T accept(ExpressionNodeMapper visitor) { diff --git a/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java b/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java index 2320a5a..95f8b9e 100644 --- a/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java +++ b/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java @@ -140,7 +140,7 @@ public class PythonCodeGenerator { method.isStatic() ? Collections.emptyList() : asList("self"), explicitArgumentNames); List pythonBody = generateStatements(method.getBody()); - return pythonFunctionDefinition(method.getName(), ImmutableList.copyOf(argumentNames), new PythonBlock(pythonBody)); + return pythonFunctionDefinition(toName(method.signature()), ImmutableList.copyOf(argumentNames), new PythonBlock(pythonBody)); } private static List generateStatements(List statements) { @@ -233,7 +233,7 @@ public class PythonCodeGenerator { PrimitiveMethodGenerator primitiveMethodGenerator = PrimitiveMethods.getPrimitiveMethod(methodCall.getReceiver().getType(), methodCall.getMethodName()).get(); return primitiveMethodGenerator.generate(receiver, arguments); } else { - return pythonCall(pythonAttributeAccess(receiver, methodCall.getMethodName()), arguments); + return pythonCall(pythonAttributeAccess(receiver, toName(methodCall.signature())), arguments); } } @@ -241,7 +241,8 @@ public class PythonCodeGenerator { public PythonExpressionNode visit(StaticMethodCallNode staticMethodCall) { TypeName className = staticMethodCall.getClassName(); PythonVariableReferenceNode classReference = pythonVariableReference(className.getSimpleName()); - PythonAttributeAccessNode methodReference = pythonAttributeAccess(classReference, staticMethodCall.getMethodName()); + PythonAttributeAccessNode methodReference = + pythonAttributeAccess(classReference, toName(staticMethodCall.signature())); List arguments = generateExpressions(staticMethodCall.getArguments()); return PrimitiveMethods.getPrimitiveStaticMethod(className, staticMethodCall.getMethodName()) @@ -292,6 +293,10 @@ public class PythonCodeGenerator { } } + public static String toName(MethodSignature signature) { + return signature.getName() + "_" + signature.getArguments().size(); + } + private static boolean isPrimitive(ExpressionNode value) { return PrimitiveMethods.isPrimitive(value.getType()); } diff --git a/src/main/java/org/zwobble/couscous/interpreter/Interpreter.java b/src/main/java/org/zwobble/couscous/interpreter/Interpreter.java index b506fdf..da84de0 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/Interpreter.java +++ b/src/main/java/org/zwobble/couscous/interpreter/Interpreter.java @@ -3,6 +3,7 @@ package org.zwobble.couscous.interpreter; import java.util.List; import java.util.Optional; +import org.zwobble.couscous.ast.MethodSignature; import org.zwobble.couscous.ast.TypeName; import org.zwobble.couscous.interpreter.values.ConcreteType; import org.zwobble.couscous.interpreter.values.InterpreterValue; diff --git a/src/main/java/org/zwobble/couscous/interpreter/MethodSignature.java b/src/main/java/org/zwobble/couscous/interpreter/MethodSignature.java deleted file mode 100644 index 708bc9a..0000000 --- a/src/main/java/org/zwobble/couscous/interpreter/MethodSignature.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.zwobble.couscous.interpreter; - -import org.zwobble.couscous.ast.TypeName; - -import java.util.List; -import java.util.Objects; - -public class MethodSignature { - private String name; - private List arguments; - - public MethodSignature(String name, List arguments) { - this.name = name; - this.arguments = arguments; - } - - @Override - public String toString() { - return "MethodSignature(" + - "name='" + name + '\'' + - ", arguments=" + arguments + - ')'; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - MethodSignature that = (MethodSignature) o; - return Objects.equals(name, that.name) && - Objects.equals(arguments, that.arguments); - } - - @Override - public int hashCode() { - return Objects.hash(name, arguments); - } -} diff --git a/src/main/java/org/zwobble/couscous/interpreter/NoSuchMethod.java b/src/main/java/org/zwobble/couscous/interpreter/NoSuchMethod.java index 1bb934e..734c254 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/NoSuchMethod.java +++ b/src/main/java/org/zwobble/couscous/interpreter/NoSuchMethod.java @@ -1,5 +1,7 @@ package org.zwobble.couscous.interpreter; +import org.zwobble.couscous.ast.MethodSignature; + public final class NoSuchMethod extends InterpreterException { private static final long serialVersionUID = 1L; private MethodSignature signature; diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java b/src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java index 536aeb3..6abb56c 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java +++ b/src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java @@ -3,16 +3,13 @@ package org.zwobble.couscous.interpreter.values; import java.util.*; import java.util.function.BiFunction; import java.util.stream.Collectors; -import org.zwobble.couscous.ast.ClassNode; -import org.zwobble.couscous.ast.FormalArgumentNode; -import org.zwobble.couscous.ast.MethodNode; -import org.zwobble.couscous.ast.TypeName; + +import org.zwobble.couscous.ast.*; import org.zwobble.couscous.interpreter.*; import org.zwobble.couscous.util.Casts; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import static java.util.stream.Collectors.toMap; -import static org.zwobble.couscous.util.ExtraLists.eagerMap; public class ConcreteType { @@ -74,7 +71,7 @@ public class ConcreteType { Map methods = classNode.getMethods() .stream() .filter(method -> !method.isStatic()) - .collect(toMap(method -> signature(method), method -> { + .collect(toMap(method -> method.signature(), method -> { List argumentTypes = getArgumentTypes(method.getArguments()); return new MethodValue(argumentTypes, (environment, arguments) -> { return Executor.callMethod(environment, method, Optional.of(arguments.getReceiver()), arguments.getPositionalArguments()); @@ -83,7 +80,7 @@ public class ConcreteType { Map staticMethods = classNode.getMethods() .stream() .filter(method -> method.isStatic()) - .collect(toMap(method -> signature(method), method -> { + .collect(toMap(method -> method.signature(), method -> { List argumentTypes = getArgumentTypes(method.getArguments()); return new StaticMethodValue(argumentTypes, (environment, arguments) -> { return Executor.callMethod(environment, method, Optional.empty(), arguments); @@ -92,12 +89,6 @@ public class ConcreteType { return new ConcreteType(classNode.getName(), classNode.getSuperTypes(), fields, constructor, methods, staticMethods); } - private static MethodSignature signature(MethodNode method) { - return new MethodSignature( - method.getName(), - eagerMap(method.getArguments(), argument -> argument.getType())); - } - private static List getArgumentTypes(List arguments) { return arguments.stream().map(arg -> arg.getType()).collect(Collectors.toList()); } -- cgit v1.2.3