From b02da847e5bd3d8d4de72cb5ea2b3dd683788c16 Mon Sep 17 00:00:00 2001 From: mikera Date: Thu, 22 Feb 2024 19:37:50 +0000 Subject: [PATCH] Compiler optimisation for short do forms --- .../main/java/convex/core/lang/Compiler.java | 21 ++++++++++++------- .../java/convex/core/lang/CompilerTest.java | 4 ++-- .../java/convex/core/lang/ContextTest.java | 10 +++++---- .../java/convex/core/lang/ParamTestEvals.java | 2 +- .../java/convex/core/lang/ParamTestJuice.java | 2 +- 5 files changed, 24 insertions(+), 15 deletions(-) diff --git a/convex-core/src/main/java/convex/core/lang/Compiler.java b/convex-core/src/main/java/convex/core/lang/Compiler.java index 04ab9dd9e..a7c1af0fa 100644 --- a/convex-core/src/main/java/convex/core/lang/Compiler.java +++ b/convex-core/src/main/java/convex/core/lang/Compiler.java @@ -494,12 +494,7 @@ private static Context compileList(AList list, Context context) { if (head instanceof Symbol) { Symbol sym = (Symbol) head; - if (sym.equals(Symbols.DO)) { - context = context.compileAll(list.next()); - if (context.isExceptional()) return context; - Do op = Do.create((AVector>) context.getResult()); - return context.withResult(Juice.COMPILE_NODE, op); - } + if (sym.equals(Symbols.DO)) return compileDo(list,context); if (sym.equals(Symbols.LET)) return compileLet(list, context, false); @@ -787,7 +782,19 @@ private static Context compileDef(AList list, Context context) { return context.withResult(Juice.COMPILE_NODE, op); } - + private static Context compileDo(AList list, Context context){ + list=list.next(); // advance past "do" + if (list==null) return context.withResult(Juice.COMPILE_NODE,Constant.NULL); + + context = context.compileAll(list); + if (context.isExceptional()) return context; + AVector> ops=context.getResult(); + + if (list.count()==1) return context.withResult(Juice.COMPILE_NODE, ops.get(0)); + + Do op = Do.create(ops); + return context.withResult(Juice.COMPILE_NODE, op); + } /** diff --git a/convex-core/src/test/java/convex/core/lang/CompilerTest.java b/convex-core/src/test/java/convex/core/lang/CompilerTest.java index 01fb256cc..27a678449 100644 --- a/convex-core/src/test/java/convex/core/lang/CompilerTest.java +++ b/convex-core/src/test/java/convex/core/lang/CompilerTest.java @@ -106,8 +106,8 @@ public void testConstants() { @Test public void testDo() { assertNull(eval("(do)")); assertEquals(1L,evalL("(do 2 1)")); - assertEquals(1L,evalL("(do *depth*)")); // Adds one level to initial depth - assertEquals(2L,evalL("(do (do *depth*))")); + assertEquals(1L,evalL("(do 2 *depth*)")); // Adds one level to initial depth + assertEquals(0L,evalL("(do (do *depth*))")); // single entry 'do's get compiled out } @Test public void testMinCompileRegression() throws IOException { diff --git a/convex-core/src/test/java/convex/core/lang/ContextTest.java b/convex-core/src/test/java/convex/core/lang/ContextTest.java index 19a4b9588..113408b1e 100644 --- a/convex-core/src/test/java/convex/core/lang/ContextTest.java +++ b/convex-core/src/test/java/convex/core/lang/ContextTest.java @@ -113,8 +113,10 @@ public void testDepth() { Context c=context(); assertEquals(0L,c.getDepth()); assertEquals(0L,evalL("*depth*")); - assertEquals(1L,evalL("(do *depth*)")); - assertEquals(2L,evalL("(do (do *depth*))")); + + // note: we need to stop single entry dos getting compiled out to see this effect of depth + assertEquals(1L,evalL("(do :foo *depth*)")); + assertEquals(2L,evalL("(do :foo (do :bar *depth*))")); // functions should add one level of depth assertEquals(1L,evalL("((fn [] *depth*))")); // invoke only @@ -122,7 +124,7 @@ public void testDepth() { // In compiler unquote assertEquals(2L,evalL("~*depth*")); // compile, unquote - assertEquals(3L,evalL("~(do *depth*)")); // compile+ unquote + do + assertEquals(3L,evalL("~(do :foo *depth*)")); // compile+ unquote + do // in custom expander assertEquals(2L,evalL("(expand :foo (fn [x e] *depth*))")); // in expand, invoke @@ -145,7 +147,7 @@ public void testDepthLimit() { assertNull(c.execute(comp("(do)")).getResult()); // Shouldn't be possible to execute any Op beyond max depth - assertDepthError(c.execute(comp("(do *depth*)"))); + assertDepthError(c.execute(comp("(do :baz *depth*)"))); } diff --git a/convex-core/src/test/java/convex/core/lang/ParamTestEvals.java b/convex-core/src/test/java/convex/core/lang/ParamTestEvals.java index 68d9256c5..985a6db9c 100644 --- a/convex-core/src/test/java/convex/core/lang/ParamTestEvals.java +++ b/convex-core/src/test/java/convex/core/lang/ParamTestEvals.java @@ -47,7 +47,7 @@ public static Collection dataExamples() { Keyword.create("bar") }, { "*depth*", 0L }, // *depth* - { "(do *depth*)", 1L }, // do, *depth* + { "(do :foo *depth*)", 1L }, // do, *depth* { "(let [a *depth*] a)", 1L }, // let, *depth* { "(let [f (fn [] *depth*)] (f))", 2L }, // let, invoke, *depth* diff --git a/convex-core/src/test/java/convex/core/lang/ParamTestJuice.java b/convex-core/src/test/java/convex/core/lang/ParamTestJuice.java index b4187a484..8636acd6e 100644 --- a/convex-core/src/test/java/convex/core/lang/ParamTestJuice.java +++ b/convex-core/src/test/java/convex/core/lang/ParamTestJuice.java @@ -39,7 +39,7 @@ public static Collection dataExamples() { (Juice.EVAL + Juice.CORE + Juice.CONSTANT) + Juice.EXPAND_CONSTANT + Juice.COMPILE_CONSTANT + Juice.CONSTANT }, { "(do)", null, Juice.DO }, { "({} 0 1)", 1L, JUICE_EMPTY_MAP + Juice.CONSTANT * 2 }, - { "(do (do :foo))", Keyword.create("foo"), Juice.DO * 2 + Juice.CONSTANT }, + { "(do (do :foo))", Keyword.create("foo"), Juice.CONSTANT }, { "(let [])", null, Juice.LET }, { "(cond)", null, Juice.COND_OP }, { "(if 1 2 3)", 2L, Juice.COND_OP + 2 * Juice.CONSTANT }, { "(fn [x] x)", eval("(fn [x] x)").getResult(), JUICE_IDENTITY_FN },