Skip to content

Commit

Permalink
Compiler optimisation for short do forms
Browse files Browse the repository at this point in the history
  • Loading branch information
mikera committed Feb 22, 2024
1 parent ddf2c92 commit b02da84
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 15 deletions.
21 changes: 14 additions & 7 deletions convex-core/src/main/java/convex/core/lang/Compiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -494,12 +494,7 @@ private static Context compileList(AList<ACell> 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<AOp<ACell>>) 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);

Expand Down Expand Up @@ -787,7 +782,19 @@ private static Context compileDef(AList<ACell> list, Context context) {
return context.withResult(Juice.COMPILE_NODE, op);
}


private static Context compileDo(AList<ACell> 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<AOp<ACell>> 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);
}


/**
Expand Down
4 changes: 2 additions & 2 deletions convex-core/src/test/java/convex/core/lang/CompilerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
10 changes: 6 additions & 4 deletions convex-core/src/test/java/convex/core/lang/ContextTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -113,16 +113,18 @@ 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
assertEquals(2L,evalL("(do (defn f [] *depth*) (f))")); // do + invoke

// 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
Expand All @@ -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*)")));
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public static Collection<Object[]> 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*

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public static Collection<Object[]> 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 },
Expand Down

0 comments on commit b02da84

Please sign in to comment.