diff options
3 files changed, 30 insertions, 14 deletions
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 023d257..067e826 100644 --- a/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java +++ b/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java @@ -1,5 +1,6 @@ package org.zwobble.couscous.backends.python; +import java.util.List; import java.util.stream.Collectors; import org.zwobble.couscous.ast.AssignmentNode; @@ -159,17 +160,25 @@ public class PythonCodeGenerator { if (isPrimitive(methodCall.getReceiver())) { val isStringLength = methodCall.getReceiver().getType().equals(StringValue.REF) && methodCall.getMethodName() == "length"; + val isSubstring = methodCall.getReceiver().getType().equals(StringValue.REF) && + methodCall.getMethodName() == "substring"; if (isStringLength) { return pythonCall( pythonVariableReference("len"), asList(generateExpression(methodCall.getReceiver()))); + } else if (isSubstring) { + return pythonCall( + pythonAttributeAccess( + generateExpression(methodCall.getReceiver()), + "__getitem__"), + asList(pythonCall( + pythonVariableReference("slice"), + generateArguments(methodCall)))); } else { throw new UnsupportedOperationException(); } } else { - val arguments = methodCall.getArguments().stream() - .map(PythonCodeGenerator::generateExpression) - .collect(Collectors.toList()); + val arguments = generateArguments(methodCall); return pythonCall( pythonAttributeAccess( generateExpression(methodCall.getReceiver()), @@ -178,6 +187,13 @@ public class PythonCodeGenerator { } } + private List<PythonExpressionNode> generateArguments( + MethodCallNode methodCall) { + return methodCall.getArguments().stream() + .map(PythonCodeGenerator::generateExpression) + .collect(Collectors.toList()); + } + @Override public PythonExpressionNode visit(StaticMethodCallNode staticMethodCall) { throw new UnsupportedOperationException(); diff --git a/src/test/java/org/zwobble/couscous/tests/BackendEvalTests.java b/src/test/java/org/zwobble/couscous/tests/BackendEvalTests.java index c6b7ba2..0554025 100644 --- a/src/test/java/org/zwobble/couscous/tests/BackendEvalTests.java +++ b/src/test/java/org/zwobble/couscous/tests/BackendEvalTests.java @@ -5,6 +5,7 @@ import org.zwobble.couscous.ast.ExpressionNode; import org.zwobble.couscous.ast.TernaryConditionalNode; import org.zwobble.couscous.values.IntegerValue; import org.zwobble.couscous.values.PrimitiveValue; +import org.zwobble.couscous.values.StringValue; import static java.util.Arrays.asList; import static org.junit.Assert.assertEquals; @@ -45,5 +46,15 @@ public abstract class BackendEvalTests { assertEquals(value(5), result); } + @Test + public void canCallMethodWithArgumentsOnBuiltin() { + val result = evalExpression(methodCall( + literal("hello"), + "substring", + asList(literal(1), literal(4)), + StringValue.REF)); + assertEquals(value("ell"), result); + } + protected abstract PrimitiveValue evalExpression(ExpressionNode expression); } diff --git a/src/test/java/org/zwobble/couscous/tests/interpreter/EvaluatorTests.java b/src/test/java/org/zwobble/couscous/tests/interpreter/EvaluatorTests.java index fab65ef..ab134f4 100644 --- a/src/test/java/org/zwobble/couscous/tests/interpreter/EvaluatorTests.java +++ b/src/test/java/org/zwobble/couscous/tests/interpreter/EvaluatorTests.java @@ -58,17 +58,6 @@ public class EvaluatorTests extends BackendEvalTests { } @Test - public void canCallMethodWithArgumentsOnBuiltin() { - val result = eval(emptyEnvironment(), - methodCall( - literal("hello"), - "substring", - asList(literal(1), literal(4)), - StringValue.REF)); - assertEquals(new StringInterpreterValue("ell"), result); - } - - @Test public void errorIfMethodDoesNotExist() { val exception = assertThrows(NoSuchMethod.class, () -> eval(emptyEnvironment(), |
