diff --git a/src/main/java/com/annimon/ownlang/modules/std/std.java b/src/main/java/com/annimon/ownlang/modules/std/std.java index 470be66..eb21870 100644 --- a/src/main/java/com/annimon/ownlang/modules/std/std.java +++ b/src/main/java/com/annimon/ownlang/modules/std/std.java @@ -26,6 +26,7 @@ public final class std implements Module { Functions.set("thread", new std_thread()); Functions.set("sync", new std_sync()); Functions.set("try", new std_try()); + Functions.set("default", new std_default()); // Numbers Functions.set("toHexString", NumberFunctions::toHexString); diff --git a/src/main/java/com/annimon/ownlang/modules/std/std_default.java b/src/main/java/com/annimon/ownlang/modules/std/std_default.java new file mode 100644 index 0000000..68819bf --- /dev/null +++ b/src/main/java/com/annimon/ownlang/modules/std/std_default.java @@ -0,0 +1,38 @@ +package com.annimon.ownlang.modules.std; + +import com.annimon.ownlang.lib.Arguments; +import com.annimon.ownlang.lib.ArrayValue; +import com.annimon.ownlang.lib.Function; +import com.annimon.ownlang.lib.MapValue; +import com.annimon.ownlang.lib.Types; +import com.annimon.ownlang.lib.Value; + +public final class std_default implements Function { + + @Override + public Value execute(Value... args) { + Arguments.check(2, args.length); + if (isEmpty(args[0])) { + return args[1]; + } + return args[0]; + } + + private boolean isEmpty(Value value) { + if (value == null || value.raw() == null) { + return true; + } + switch (value.type()) { + case Types.NUMBER: + return (value.asInt() == 0); + case Types.STRING: + return (value.asString().isEmpty()); + case Types.ARRAY: + return ((ArrayValue) value).size() == 0; + case Types.MAP: + return ((MapValue) value).size() == 0; + default: + return false; + } + } +} \ No newline at end of file diff --git a/src/test/resources/modules/std/default.own b/src/test/resources/modules/std/default.own new file mode 100644 index 0000000..375aa33 --- /dev/null +++ b/src/test/resources/modules/std/default.own @@ -0,0 +1,19 @@ +use "std" + +def testDefaultNumber() { + assertEquals(123, default(0, 123)) +} + +def testDefaultString() { + assertEquals("123", default("", "123")) +} + +def testDefaultNull() { + use "java" + assertEquals("not null", default(null, "not null")) +} + +def testOperatorOverloading() { + def `?:`(a, b) = default(a, b) + assertEquals("not null", "" ?: "not null") +}