diff options
Diffstat (limited to 'src')
13 files changed, 66 insertions, 37 deletions
diff --git a/src/main/java/org/zwobble/couscous/MapBackedProject.java b/src/main/java/org/zwobble/couscous/MapBackedProject.java index 5fc0395..e452bb8 100644 --- a/src/main/java/org/zwobble/couscous/MapBackedProject.java +++ b/src/main/java/org/zwobble/couscous/MapBackedProject.java @@ -2,6 +2,7 @@ package org.zwobble.couscous; import java.util.Map; +import org.zwobble.couscous.ast.ClassName; import org.zwobble.couscous.interpreter.values.ConcreteType; import com.google.common.collect.ImmutableMap; @@ -12,7 +13,7 @@ public class MapBackedProject implements Project { } public static class Builder { - private final ImmutableMap.Builder<String, ConcreteType<?>> classes; + private final ImmutableMap.Builder<ClassName, ConcreteType<?>> classes; private Builder() { classes = ImmutableMap.builder(); @@ -28,14 +29,14 @@ public class MapBackedProject implements Project { } } - private Map<String, ConcreteType<?>> classes; + private Map<ClassName, ConcreteType<?>> classes; - public MapBackedProject(Map<String, ConcreteType<?>> classes) { + public MapBackedProject(Map<ClassName, ConcreteType<?>> classes) { this.classes = classes; } @Override - public ConcreteType<?> findClass(String name) { + public ConcreteType<?> findClass(ClassName name) { return classes.get(name); } } diff --git a/src/main/java/org/zwobble/couscous/Project.java b/src/main/java/org/zwobble/couscous/Project.java index 86299ca..b1edb22 100644 --- a/src/main/java/org/zwobble/couscous/Project.java +++ b/src/main/java/org/zwobble/couscous/Project.java @@ -1,7 +1,8 @@ package org.zwobble.couscous; +import org.zwobble.couscous.ast.ClassName; import org.zwobble.couscous.interpreter.values.ConcreteType; public interface Project { - ConcreteType<?> findClass(String name); + ConcreteType<?> findClass(ClassName name); } diff --git a/src/main/java/org/zwobble/couscous/ast/ClassName.java b/src/main/java/org/zwobble/couscous/ast/ClassName.java new file mode 100644 index 0000000..7358cf7 --- /dev/null +++ b/src/main/java/org/zwobble/couscous/ast/ClassName.java @@ -0,0 +1,18 @@ +package org.zwobble.couscous.ast; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Value; + +@Value +@AllArgsConstructor(access=AccessLevel.PRIVATE) +public class ClassName { + public static ClassName of(String qualifiedName) { + return new ClassName( + qualifiedName, + qualifiedName.substring(qualifiedName.lastIndexOf(".") + 1)); + } + + String qualifiedName; + String simpleName; +} diff --git a/src/main/java/org/zwobble/couscous/ast/ClassNode.java b/src/main/java/org/zwobble/couscous/ast/ClassNode.java index 77480b5..f1cbcc2 100644 --- a/src/main/java/org/zwobble/couscous/ast/ClassNode.java +++ b/src/main/java/org/zwobble/couscous/ast/ClassNode.java @@ -30,17 +30,16 @@ public class ClassNode implements Node { } public ClassNode build() { - return new ClassNode(name, methods.build()); + return new ClassNode(ClassName.of(name), methods.build()); } } - String name; + ClassName name; @Singular List<MethodNode> methods; - public String getLocalName() { - // TODO Stronger notion of class names? Should look up the terminology - return name.substring(name.lastIndexOf(".") + 1); + public String getSimpleName() { + return name.getSimpleName(); } @Override diff --git a/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java b/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java index 96e2e4c..235566f 100644 --- a/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java +++ b/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java @@ -9,17 +9,17 @@ import static java.util.Arrays.asList; import lombok.Value; -@Value +@Value(staticConstructor="staticMethodCall") public class StaticMethodCallNode implements ExpressionNode { public static StaticMethodCallNode staticMethodCall(String className, String methodName, ExpressionNode... arguments) { - return new StaticMethodCallNode(className, methodName, asList(arguments)); + return staticMethodCall(className, methodName, asList(arguments)); } public static StaticMethodCallNode staticMethodCall(String className, String methodName, List<ExpressionNode> arguments) { - return new StaticMethodCallNode(className, methodName, arguments); + return staticMethodCall(ClassName.of(className), methodName, arguments); } - String className; + ClassName className; String methodName; List<ExpressionNode> arguments; 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 d22562c..d0024de 100644 --- a/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java +++ b/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java @@ -7,6 +7,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import org.zwobble.couscous.ast.AssignmentNode; +import org.zwobble.couscous.ast.ClassName; import org.zwobble.couscous.ast.ClassNode; import org.zwobble.couscous.ast.ExpressionNode; import org.zwobble.couscous.ast.ExpressionStatementNode; @@ -69,7 +70,7 @@ public class PythonCodeGenerator { .map(PythonCodeGenerator::generateFunction) .collect(Collectors.toList()); - val pythonClass = pythonClass(classNode.getLocalName(), pythonBody); + val pythonClass = pythonClass(classNode.getSimpleName(), pythonBody); return pythonModule(ImmutableList.copyOf(Iterators.concat( imports, @@ -82,8 +83,8 @@ public class PythonCodeGenerator { .map(name -> pythonImport(name)); } - private static Set<String> findReferencedClasses(ClassNode classNode) { - val imports = ImmutableSet.<String>builder(); + private static Set<ClassName> findReferencedClasses(ClassNode classNode) { + val imports = ImmutableSet.<ClassName>builder(); NodeVisitors.visitAll(classNode, new NodeVisitorWithEmptyDefaults() { @Override public void visit(StaticMethodCallNode staticMethodCall) { @@ -209,7 +210,7 @@ public class PythonCodeGenerator { @Override public PythonExpressionNode visit(StaticMethodCallNode staticMethodCall) { val className = staticMethodCall.getClassName(); - val moduleParts = asList(className.split(Pattern.quote("."))); + val moduleParts = asList(className.getQualifiedName().split(Pattern.quote("."))); val module = foldLeft( moduleParts, @@ -218,7 +219,7 @@ public class PythonCodeGenerator { val classReference = pythonAttributeAccess( module, - className.substring(className.lastIndexOf(".") + 1)); + className.getSimpleName()); val methodReference = pythonAttributeAccess( classReference, diff --git a/src/main/java/org/zwobble/couscous/backends/python/PythonCompiler.java b/src/main/java/org/zwobble/couscous/backends/python/PythonCompiler.java index a54f037..67e24cc 100644 --- a/src/main/java/org/zwobble/couscous/backends/python/PythonCompiler.java +++ b/src/main/java/org/zwobble/couscous/backends/python/PythonCompiler.java @@ -5,6 +5,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.List; +import org.zwobble.couscous.ast.ClassName; import org.zwobble.couscous.ast.ClassNode; import static java.util.Arrays.asList; @@ -25,15 +26,15 @@ public class PythonCompiler { for (val classNode : classes) { compileClass(classNode); } - writeClass("java.lang.Integer", + writeClass(ClassName.of("java.lang.Integer"), "class Integer(object):\n" + " def parseInt(value):\n" + " return int(value)" ); } - private Path pathForClass(String className) { - return root.resolve(className.replace(".", File.separator) + ".py"); + private Path pathForClass(ClassName className) { + return root.resolve(className.getQualifiedName().replace(".", File.separator) + ".py"); } private void compileClass(ClassNode classNode) { @@ -41,7 +42,7 @@ public class PythonCompiler { } @SneakyThrows - private void writeClass(String name, String contents) { + private void writeClass(ClassName name, String contents) { val path = pathForClass(name); Files.createDirectories(path.getParent()); Files.write(path, asList(contents)); diff --git a/src/main/java/org/zwobble/couscous/backends/python/PythonSerializer.java b/src/main/java/org/zwobble/couscous/backends/python/PythonSerializer.java index 9c82b5d..be53faa 100644 --- a/src/main/java/org/zwobble/couscous/backends/python/PythonSerializer.java +++ b/src/main/java/org/zwobble/couscous/backends/python/PythonSerializer.java @@ -166,7 +166,7 @@ public class PythonSerializer implements PythonNodeVisitor { writer.writeStatement(() -> { writer.writeKeyword("import"); writer.writeSpace(); - writer.writeIdentifier(importNode.getName()); + writer.writeIdentifier(importNode.getName().getQualifiedName()); }); } diff --git a/src/main/java/org/zwobble/couscous/backends/python/ast/PythonImportNode.java b/src/main/java/org/zwobble/couscous/backends/python/ast/PythonImportNode.java index 2d38004..d8b97ad 100644 --- a/src/main/java/org/zwobble/couscous/backends/python/ast/PythonImportNode.java +++ b/src/main/java/org/zwobble/couscous/backends/python/ast/PythonImportNode.java @@ -1,12 +1,17 @@ package org.zwobble.couscous.backends.python.ast; +import org.zwobble.couscous.ast.ClassName; import org.zwobble.couscous.backends.python.ast.visitors.PythonNodeVisitor; import lombok.Value; @Value(staticConstructor="pythonImport") public class PythonImportNode implements PythonStatementNode { - String name; + public static PythonImportNode pythonImport(String name) { + return pythonImport(ClassName.of(name)); + } + + ClassName name; @Override public void accept(PythonNodeVisitor visitor) { diff --git a/src/main/java/org/zwobble/couscous/interpreter/Environment.java b/src/main/java/org/zwobble/couscous/interpreter/Environment.java index 5e6e231..0c226d1 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/Environment.java +++ b/src/main/java/org/zwobble/couscous/interpreter/Environment.java @@ -4,6 +4,7 @@ import java.util.Map; import java.util.Optional; import org.zwobble.couscous.Project; +import org.zwobble.couscous.ast.ClassName; import org.zwobble.couscous.ast.VariableDeclaration; import org.zwobble.couscous.ast.VariableNode; import org.zwobble.couscous.interpreter.values.ConcreteType; @@ -46,7 +47,7 @@ public class Environment { put(variable.getDeclaration().getId(), value); } - public ConcreteType<?> findClass(String className) { + public ConcreteType<?> findClass(ClassName className) { // TODO: handle missing classes return project.findClass(className); } diff --git a/src/main/java/org/zwobble/couscous/interpreter/Interpreter.java b/src/main/java/org/zwobble/couscous/interpreter/Interpreter.java index 0c36d91..10153c8 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/Interpreter.java +++ b/src/main/java/org/zwobble/couscous/interpreter/Interpreter.java @@ -4,6 +4,7 @@ import java.util.List; import java.util.stream.Collectors; import org.zwobble.couscous.Project; +import org.zwobble.couscous.ast.ClassName; import org.zwobble.couscous.ast.ExpressionNode; import org.zwobble.couscous.interpreter.values.InterpreterValue; @@ -22,7 +23,7 @@ public class Interpreter { this.project = project; } - public InterpreterValue run(String className, String methodName, List<InterpreterValue> arguments) { + public InterpreterValue run(ClassName className, String methodName, List<InterpreterValue> arguments) { val argumentExpressions = arguments .stream() .<ExpressionNode>map(argument -> literal(argument.toPrimitiveValue().get())) 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 b2abd2b..04156d5 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java +++ b/src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java @@ -5,6 +5,7 @@ import java.util.Map; import java.util.function.BiFunction; import java.util.stream.Collectors; +import org.zwobble.couscous.ast.ClassName; import org.zwobble.couscous.ast.ClassNode; import org.zwobble.couscous.interpreter.Arguments; import org.zwobble.couscous.interpreter.Environment; @@ -27,9 +28,9 @@ public class ConcreteType<T> { ImmutableMap.builder(); private final ImmutableMap.Builder<String, StaticMethodValue> staticMethods = ImmutableMap.builder(); - private final String name; + private final ClassName name; - public Builder(String name) { + public Builder(ClassName name) { this.name = name; } @@ -75,12 +76,12 @@ public class ConcreteType<T> { staticMethods); } - private String name; + private ClassName name; private Map<String, MethodValue<T>> methods; private Map<String, StaticMethodValue> staticMethods; public ConcreteType( - String name, + ClassName name, Map<String, MethodValue<T>> methods, Map<String, StaticMethodValue> staticMethods) { this.name = name; @@ -88,16 +89,16 @@ public class ConcreteType<T> { this.staticMethods = staticMethods; } - public String getName() { + public ClassName getName() { return name; } public static <T> ConcreteType.Builder<T> builder(TypeReference reference) { - return new Builder<>(reference.getName()); + return builder(reference.getName()); } public static <T> ConcreteType.Builder<T> builder(String name) { - return new Builder<>(name); + return new Builder<>(ClassName.of(name)); } @SuppressWarnings("unchecked") @@ -131,7 +132,7 @@ public class ConcreteType<T> { } public TypeReference getReference() { - return typeRef(name); + return typeRef(name.getQualifiedName()); } @Override diff --git a/src/test/java/org/zwobble/couscous/tests/backends/python/PythonMethodRunner.java b/src/test/java/org/zwobble/couscous/tests/backends/python/PythonMethodRunner.java index cd15b24..73c1c52 100644 --- a/src/test/java/org/zwobble/couscous/tests/backends/python/PythonMethodRunner.java +++ b/src/test/java/org/zwobble/couscous/tests/backends/python/PythonMethodRunner.java @@ -43,8 +43,8 @@ public class PythonMethodRunner implements MethodRunner { .map(PythonSerializer::serialize) .iterator()); - val program = "from " + classNode.getName() + " import " + classNode.getLocalName() + - ";print(repr(" + classNode.getLocalName() + "." + methodName + "(" + argumentsString + ")))"; + val program = "from " + classNode.getName().getQualifiedName() + " import " + classNode.getSimpleName() + + ";print(repr(" + classNode.getSimpleName() + "." + methodName + "(" + argumentsString + ")))"; val process = new ProcessBuilder("python3.4", "-c", program) .directory(directoryPath.toFile()) |
