diff options
Diffstat (limited to 'src')
11 files changed, 63 insertions, 38 deletions
diff --git a/src/main/java/org/zwobble/couscous/ast/CallableNode.java b/src/main/java/org/zwobble/couscous/ast/CallableNode.java deleted file mode 100644 index 6d6fc7b..0000000 --- a/src/main/java/org/zwobble/couscous/ast/CallableNode.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.zwobble.couscous.ast; - -import java.util.List; - -public interface CallableNode extends Node { - List<FormalArgumentNode> getArguments(); - List<StatementNode> getBody(); -} diff --git a/src/main/java/org/zwobble/couscous/ast/ConstructorNode.java b/src/main/java/org/zwobble/couscous/ast/ConstructorNode.java index fab931b..a25a993 100644 --- a/src/main/java/org/zwobble/couscous/ast/ConstructorNode.java +++ b/src/main/java/org/zwobble/couscous/ast/ConstructorNode.java @@ -6,7 +6,7 @@ import org.zwobble.couscous.ast.visitors.NodeTransformer; import java.util.Collections; import java.util.List; -public class ConstructorNode implements CallableNode { +public class ConstructorNode implements Node { public static final ConstructorNode DEFAULT = constructor(Collections.emptyList(), Collections.emptyList()); public static ConstructorNode constructor( diff --git a/src/main/java/org/zwobble/couscous/ast/MethodNode.java b/src/main/java/org/zwobble/couscous/ast/MethodNode.java index 967b2b1..c201047 100644 --- a/src/main/java/org/zwobble/couscous/ast/MethodNode.java +++ b/src/main/java/org/zwobble/couscous/ast/MethodNode.java @@ -11,7 +11,7 @@ import java.util.function.Function; import static org.zwobble.couscous.util.ExtraLists.eagerMap; -public class MethodNode implements CallableNode { +public class MethodNode implements Node { public static Builder staticMethod(String name) { return builder(name).isStatic(true); } @@ -140,8 +140,8 @@ public class MethodNode implements CallableNode { return returnType; } - public List<StatementNode> getBody() { - return body.get(); + public Optional<List<StatementNode>> getBody() { + return body; } public MethodSignature signature() { diff --git a/src/main/java/org/zwobble/couscous/ast/structure/NodeStructure.java b/src/main/java/org/zwobble/couscous/ast/structure/NodeStructure.java index 2424bbe..f1f37a6 100644 --- a/src/main/java/org/zwobble/couscous/ast/structure/NodeStructure.java +++ b/src/main/java/org/zwobble/couscous/ast/structure/NodeStructure.java @@ -3,6 +3,7 @@ package org.zwobble.couscous.ast.structure; import org.zwobble.couscous.ast.*; import org.zwobble.couscous.ast.visitors.NodeMapper; +import java.util.Collection; import java.util.function.Predicate; import java.util.stream.Stream; @@ -158,7 +159,7 @@ public class NodeStructure { return concatStreams( methodNode.getAnnotations().stream(), methodNode.getArguments().stream(), - methodNode.getBody().stream()); + methodNode.getBody().map(Collection::stream).orElse(Stream.empty())); } @Override diff --git a/src/main/java/org/zwobble/couscous/backends/csharp/CsharpSerializer.java b/src/main/java/org/zwobble/couscous/backends/csharp/CsharpSerializer.java index 37147ed..3cfcd33 100644 --- a/src/main/java/org/zwobble/couscous/backends/csharp/CsharpSerializer.java +++ b/src/main/java/org/zwobble/couscous/backends/csharp/CsharpSerializer.java @@ -265,7 +265,7 @@ public class CsharpSerializer implements NodeVisitor { writer.writeSpace(); writer.writeIdentifier(method.getName()); writeFormalArguments(method.getArguments()); - writeBlock(method.getBody()); + writeBlock(method.getBody().get()); }); } 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 2aafcca..08ecba4 100644 --- a/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java +++ b/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java @@ -166,7 +166,7 @@ public class PythonCodeGenerator { Iterable<String> argumentNames = Iterables.concat( method.isStatic() ? Collections.<String>emptyList() : list("self"), explicitArgumentNames); - List<PythonStatementNode> pythonBody = generateStatements(method.getBody()); + List<PythonStatementNode> pythonBody = generateStatements(method.getBody().get()); return pythonFunctionDefinition(Names.toUniqueName(method.signature()), ImmutableList.copyOf(argumentNames), new PythonBlock(pythonBody)); } diff --git a/src/main/java/org/zwobble/couscous/interpreter/Executor.java b/src/main/java/org/zwobble/couscous/interpreter/Executor.java index 60f7d9c..8ba263c 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/Executor.java +++ b/src/main/java/org/zwobble/couscous/interpreter/Executor.java @@ -15,18 +15,50 @@ import static org.zwobble.couscous.interpreter.Evaluator.eval; import static org.zwobble.couscous.interpreter.Evaluator.evalCondition; public class Executor implements StatementNodeMapper<Optional<InterpreterValue>> { - public static InterpreterValue callMethod(Environment environment, CallableNode method, Optional<InterpreterValue> thisValue, PositionalArguments arguments) { - Environment innerEnvironment = buildEnvironment(environment, method, thisValue, arguments); - return exec(innerEnvironment, method.getBody()) + public static InterpreterValue callMethod( + Environment environment, + MethodNode method, + Optional<InterpreterValue> thisValue, + PositionalArguments actualArguments) + { + List<StatementNode> body = method.getBody().orElseThrow(() -> new RuntimeException("Cannot call abstract method")); + return callMethod(environment, method.getArguments(), body, thisValue, actualArguments); + } + + public static InterpreterValue callConstructor( + Environment environment, + ConstructorNode constructor, + Optional<InterpreterValue> thisValue, + PositionalArguments actualArguments) + { + return callMethod(environment, constructor.getArguments(), constructor.getBody(), thisValue, actualArguments); + } + + private static InterpreterValue callMethod( + Environment environment, + List<FormalArgumentNode> formalArguments, + List<StatementNode> statements, + Optional<InterpreterValue> thisValue, + PositionalArguments actualArguments) + { + Environment innerEnvironment = buildEnvironment(environment, formalArguments, statements, thisValue, actualArguments); + return exec(innerEnvironment, statements) .orElse(UnitInterpreterValue.UNIT); } - private static Environment buildEnvironment(final Environment environment, final CallableNode method, Optional<InterpreterValue> thisValue, PositionalArguments arguments) { + private static Environment buildEnvironment( + Environment environment, + List<FormalArgumentNode> formalArguments, + List<StatementNode> statements, + Optional<InterpreterValue> thisValue, + PositionalArguments arguments) + { + // TODO use map with multiple iterables final org.zwobble.couscous.interpreter.StackFrameBuilder stackFrame = new StackFrameBuilder(); - for (int index = 0; index < method.getArguments().size(); index++) { - stackFrame.declare(method.getArguments().get(index), arguments.get(index)); + for (int index = 0; index < formalArguments.size(); index++) { + stackFrame.declare(formalArguments.get(index), arguments.get(index)); } - findDeclarations(method.getBody()).forEach(declaration -> stackFrame.declare(declaration)); + findDeclarations(statements).forEach(declaration -> stackFrame.declare(declaration)); return environment.withStackFrame(thisValue, stackFrame.build()); } 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 98036f1..19a6039 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java +++ b/src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java @@ -99,7 +99,7 @@ public class ConcreteType { field -> field)); MethodValue constructor = new MethodValue( getArgumentTypes(classNode.getConstructor().getArguments()), - (environment, arguments) -> Executor.callMethod( + (environment, arguments) -> Executor.callConstructor( environment, classNode.getConstructor(), Optional.of(arguments.getReceiver()), diff --git a/src/test/java/org/zwobble/couscous/tests/frontends/java/ExpressionReadingTests.java b/src/test/java/org/zwobble/couscous/tests/frontends/java/ExpressionReadingTests.java index 6f9df81..2f59e57 100644 --- a/src/test/java/org/zwobble/couscous/tests/frontends/java/ExpressionReadingTests.java +++ b/src/test/java/org/zwobble/couscous/tests/frontends/java/ExpressionReadingTests.java @@ -90,7 +90,7 @@ public class ExpressionReadingTests { " return " + expression + ";" + "}"); - ReturnNode returnNode = (ReturnNode) classNode.getMethods().get(0).getBody().get(0); + ReturnNode returnNode = (ReturnNode) classNode.getMethods().get(0).getBody().get().get(0); assertEquals( fieldAccess( thisReference(TypeName.of("com.example.Example")), @@ -116,7 +116,7 @@ public class ExpressionReadingTests { " return " + expression + ";" + "}"); - ReturnNode returnNode = (ReturnNode) classNode.getMethods().get(0).getBody().get(0); + ReturnNode returnNode = (ReturnNode) classNode.getMethods().get(0).getBody().get().get(0); assertEquals( fieldAccess( TypeName.of("com.example.Example"), @@ -145,7 +145,7 @@ public class ExpressionReadingTests { "public String loop() {" + " return loop();" + "}"); - ReturnNode returnNode = (ReturnNode) classNode.getMethods().get(0).getBody().get(0); + ReturnNode returnNode = (ReturnNode) classNode.getMethods().get(0).getBody().get().get(0); assertEquals( methodCall( @@ -173,7 +173,7 @@ public class ExpressionReadingTests { "public static String loop() {" + " return loop();" + "}"); - ReturnNode returnNode = (ReturnNode) classNode.getMethods().get(0).getBody().get(0); + ReturnNode returnNode = (ReturnNode) classNode.getMethods().get(0).getBody().get().get(0); assertEquals( staticMethodCall( @@ -319,7 +319,7 @@ public class ExpressionReadingTests { " return name = \"blah\";" + "}"); - ReturnNode returnNode = (ReturnNode) classNode.getMethods().get(0).getBody().get(0); + ReturnNode returnNode = (ReturnNode) classNode.getMethods().get(0).getBody().get().get(0); assertEquals( assign( fieldAccess( @@ -338,7 +338,7 @@ public class ExpressionReadingTests { " return value = 4;" + "}"); - ReturnNode returnNode = (ReturnNode) classNode.getMethods().get(0).getBody().get(0); + ReturnNode returnNode = (ReturnNode) classNode.getMethods().get(0).getBody().get().get(0); assertEquals( assign( fieldAccess( @@ -366,7 +366,7 @@ public class ExpressionReadingTests { MethodNode method = classNode.getMethods().get(0); FormalArgumentNode argument = method.getArguments().get(0); ExpressionStatementNode statement = (ExpressionStatementNode) - classNode.getMethods().get(0).getBody().get(0); + classNode.getMethods().get(0).getBody().get().get(0); assertEquals( assign( reference(argument), @@ -392,7 +392,7 @@ public class ExpressionReadingTests { MethodNode method = classNode.getMethods().get(0); FormalArgumentNode argument = method.getArguments().get(0); ExpressionStatementNode statement = (ExpressionStatementNode) - classNode.getMethods().get(0).getBody().get(0); + classNode.getMethods().get(0).getBody().get().get(0); assertEquals( assign( reference(argument), @@ -411,7 +411,7 @@ public class ExpressionReadingTests { FormalArgumentNode left = method.getArguments().get(0); FormalArgumentNode right = method.getArguments().get(1); ExpressionStatementNode statement = (ExpressionStatementNode) - classNode.getMethods().get(0).getBody().get(0); + classNode.getMethods().get(0).getBody().get().get(0); assertEquals( assign( reference(left), @@ -430,7 +430,7 @@ public class ExpressionReadingTests { FormalArgumentNode left = method.getArguments().get(0); FormalArgumentNode right = method.getArguments().get(1); ExpressionStatementNode statement = (ExpressionStatementNode) - classNode.getMethods().get(0).getBody().get(0); + classNode.getMethods().get(0).getBody().get().get(0); assertEquals( assign( reference(left), @@ -448,7 +448,7 @@ public class ExpressionReadingTests { MethodNode method = classNode.getMethods().get(0); FormalArgumentNode argument = method.getArguments().get(0); ExpressionStatementNode statement = (ExpressionStatementNode) - classNode.getMethods().get(0).getBody().get(0); + classNode.getMethods().get(0).getBody().get().get(0); assertEquals( assign( reference(argument), diff --git a/src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReaderTests.java b/src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReaderTests.java index 3c88424..454dda7 100644 --- a/src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReaderTests.java +++ b/src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReaderTests.java @@ -78,7 +78,7 @@ public class JavaReaderTests { assertEquals(TypeName.of("int"), argument.getType()); assertEquals(1, method.getArguments().size()); - ReturnNode returnNode = (ReturnNode)method.getBody().get(0); + ReturnNode returnNode = (ReturnNode)method.getBody().get().get(0); assertEquals(reference(argument), returnNode.getValue()); } @@ -297,7 +297,7 @@ public class JavaReaderTests { MethodNode method = classNode.getMethods().get(0); assertEquals( list(returns(boxInt(literal(1)))), - method.getBody()); + method.getBody().get()); } @Test diff --git a/src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReading.java b/src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReading.java index 408694c..f7d2c85 100644 --- a/src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReading.java +++ b/src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReading.java @@ -20,7 +20,7 @@ public class JavaReading { "}"; ClassNode classNode = readClass(javaClass); - ReturnNode returnStatement = (ReturnNode) classNode.getMethods().get(0).getBody().get(0); + ReturnNode returnStatement = (ReturnNode) classNode.getMethods().get(0).getBody().get().get(0); return returnStatement.getValue(); } @@ -44,7 +44,7 @@ public class JavaReading { static List<StatementNode> readStatements(String returnType, String statementsSource) { String javaClass = generateMethodSource(returnType, statementsSource); ClassNode classNode = readClass(javaClass); - return classNode.getMethods().get(0).getBody(); + return classNode.getMethods().get(0).getBody().get(); } static ClassNode readClass(String classBody) { |
