From 30d2215800deafbdcfb134f1356777ec0139bb7a Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Thu, 1 Oct 2015 21:49:18 +0100 Subject: Use normal method call exec in interpreter entry point --- .../org/zwobble/couscous/values/ConcreteType.java | 59 +++++++++++++++++++++- 1 file changed, 57 insertions(+), 2 deletions(-) (limited to 'src/main/java/org/zwobble/couscous/values') diff --git a/src/main/java/org/zwobble/couscous/values/ConcreteType.java b/src/main/java/org/zwobble/couscous/values/ConcreteType.java index db5209e..6aea1db 100644 --- a/src/main/java/org/zwobble/couscous/values/ConcreteType.java +++ b/src/main/java/org/zwobble/couscous/values/ConcreteType.java @@ -5,14 +5,23 @@ import java.util.Map; import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import org.zwobble.couscous.Project; +import org.zwobble.couscous.ast.ClassNode; +import org.zwobble.couscous.ast.MethodNode; import org.zwobble.couscous.interpreter.Arguments; +import org.zwobble.couscous.interpreter.Environment; import org.zwobble.couscous.interpreter.NoSuchMethod; import org.zwobble.couscous.interpreter.UnexpectedValueType; import org.zwobble.couscous.interpreter.WrongNumberOfArguments; import com.google.common.collect.ImmutableMap; +import static java.util.stream.Collectors.toMap; +import static org.zwobble.couscous.interpreter.Executor.exec; + import lombok.val; public class ConcreteType { @@ -47,15 +56,61 @@ public class ConcreteType { return new ConcreteType(name, methods.build(), staticMethods.build()); } } + + public static ConcreteType fromNode(ClassNode classNode) { + val staticMethods = classNode.getMethods() + .stream() + .filter(method -> method.isStatic()) + .collect(toMap( + method -> method.getName(), + method -> { + Supplier>> argumentTypes = () -> method.getArguments() + .stream() + .>map(arg -> arg.getType()) + .collect(Collectors.toList()); + return new StaticMethodValue(argumentTypes, arguments -> { + val environment = buildEnvironment(method, arguments); + + for (val statement : method.getBody()) { + val result = exec(environment, statement); + if (result.isPresent()) { + return result.get(); + } + } + return UnitValue.UNIT; + }); + })); + return new ConcreteType( + classNode.getName(), + ImmutableMap.of(), + staticMethods); + } + + private static Environment buildEnvironment( + final MethodNode method, + Arguments arguments) { + + val stackFrame = IntStream.range(0, method.getArguments().size()) + .boxed() + .collect(toMap( + index -> method.getArguments().get(index).getId(), + index -> arguments.get(index))); + return new Environment(new Project() { + @Override + public ConcreteType findClass(String name) { + throw new UnsupportedOperationException(); + } + }, stackFrame); + } private String name; private Map> methods; - private ImmutableMap staticMethods; + private Map staticMethods; public ConcreteType( String name, Map> methods, - ImmutableMap staticMethods) { + Map staticMethods) { this.name = name; this.methods = methods; this.staticMethods = staticMethods; -- cgit v1.2.3