Skip to content
This repository has been archived by the owner on Jul 28, 2019. It is now read-only.

Commit

Permalink
feature: Add 'apply' function
Browse files Browse the repository at this point in the history
  • Loading branch information
juanibiapina committed Sep 8, 2016
1 parent adf6e0a commit 9e0851a
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/main/java/marco/lang/error/TypeError.java
Expand Up @@ -3,7 +3,7 @@
import marco.lang.MarcoObject;

public class TypeError extends Error {
public TypeError(Class expected, MarcoObject value, String fileName, int line) {
public TypeError(Class expected, MarcoObject value, String fileName, Integer line) {
super(fileName, line, "Expected " + expected.getName() + " but got a " + value.getClass().getName());
}
}
18 changes: 18 additions & 0 deletions src/main/java/marco/lang/functions/functions/apply.java
@@ -0,0 +1,18 @@
package marco.lang.functions.functions;

import marco.lang.MarcoNativeBlock;
import marco.lang.MarcoObject;
import marco.lang.MarcoRunnable;
import marco.runtime.Cast;
import marco.runtime.Environment;
import marco.runtime.ListHelper;

public class apply extends MarcoNativeBlock {
@Override
public MarcoObject invoke(Environment closure, Environment dynamic) {
MarcoRunnable runnable = Cast.toRunnable(closure.lookUp("runnable"), getFileName(), getStartLine());
MarcoObject args = closure.lookUp("args");

return runnable.invoke(dynamic, ListHelper.toJavaList(args));
}
}
2 changes: 1 addition & 1 deletion src/main/java/marco/runtime/Cast.java
Expand Up @@ -5,7 +5,7 @@
import marco.lang.*;

public class Cast {
public static MarcoRunnable toRunnable(MarcoObject value, String fileName, int line) {
public static MarcoRunnable toRunnable(MarcoObject value, String fileName, Integer line) {
if (value instanceof MarcoRunnable) {
return (MarcoRunnable) value;
} else {
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/marco/runtime/TopLevelEnvironment.java
Expand Up @@ -14,6 +14,7 @@
import marco.lang.functions.booleans._not;
import marco.lang.functions.control_flow._while;
import marco.lang.functions.docstrings.doc;
import marco.lang.functions.functions.apply;
import marco.lang.functions.functions.function;
import marco.lang.functions.functions.function_question;
import marco.lang.functions.hash_maps.hash_map;
Expand Down Expand Up @@ -43,6 +44,7 @@ public TopLevelEnvironment(MarcoRuntime runtime) {
private void loadNativeBindings() {
def("function", new MarcoFunction(this, Arrays.asList("formal", "body"), new function()));
def("function?", new MarcoFunction(this, Arrays.asList("v"), new function_question()));
def("apply", new MarcoFunction(this, Arrays.asList("runnable", "args"), new apply()));

def("true", MarcoBoolean.TRUE);
def("false", MarcoBoolean.FALSE);
Expand Down
18 changes: 18 additions & 0 deletions src/test/groovy/tests/marco/lang/functions/functions/apply.groovy
@@ -0,0 +1,18 @@
package tests.marco.lang.functions.functions

import helpers.MarcoSpecification

class apply extends MarcoSpecification {
def "applying a function without arguments"() {
given:
eval(/ (def :f (function [] { 1 })) /)

expect:
eval(/ (apply f []) /) == eval(/ 1 /)
}

def "applying a function to a list of arguments"() {
expect:
eval(/ (apply + [1 2]) /) == eval(/ 3 /)
}
}

0 comments on commit 9e0851a

Please sign in to comment.