1
1
mirror of https://github.com/anoma/juvix.git synced 2024-12-14 08:27:03 +03:00
juvix/tests/Asm/positive/test031.jva
Łukasz Czajka 76548e464a
Structured temporary stack manipulation in JuvixAsm (#2554)
* Replaces the `pusht` and `popt` instructions with block-based `save`
and `tsave`. This encodes the structure of temporary stack manipulation
syntactically, making it impossible to manipulate it in unexpected ways.
Also simplifies compilation to Nock.
* Adds optional names for temporaries and function arguments.
2023-12-15 12:55:53 +00:00

179 lines
2.9 KiB
Plaintext

-- temporary stack with branching
type tree {
leaf : tree;
node : tree -> tree -> tree;
}
function gen(integer) : tree {
push 0;
push arg[0];
le;
br {
true: {
alloc leaf;
ret;
}
false: {
push 1;
push arg[0];
sub;
call gen;
push 2;
push arg[0];
sub;
call gen;
alloc node;
ret;
}
};
}
function g(tree) : tree;
function f(tree) : integer {
push arg[0];
case tree {
leaf: {
pop;
push 1;
ret;
}
node: {
tsave {
push tmp[0].node[0];
call g;
tsave {
push tmp[0].node[1];
call g;
tsave {
push tmp[1];
case tree {
leaf: {
pop;
push 3;
push 0;
sub;
}
node: {
save {
push 32768;
push tmp[3].node[1];
call f;
push tmp[3].node[0];
call f;
add;
mod;
};
}
};
tsave {
push tmp[2];
case tree {
node: {
save {
push 32768;
push tmp[4].node[1];
call f;
push tmp[4].node[0];
call f;
add;
mod;
};
}
default: {
pop;
push 2;
}
};
tsave {
push 32768;
push tmp[3];
push tmp[4];
mul;
mod;
ret;
};
};
};
};
};
}
};
}
function isNode(tree) : bool {
push arg[0];
case tree {
node: { pop; push true; ret; }
default: { pop; push false; ret; }
};
}
function isLeaf(tree) : bool {
push arg[0];
case tree {
leaf: { pop; push true; ret; }
default: { pop; push false; ret; }
};
}
function g(tree) : tree {
push arg[0];
call isLeaf;
br {
true: {
push arg[0];
ret;
}
false: {
push arg[0];
case tree {
node: {
tsave {
push tmp[0].node[0];
call isNode;
br {
true: {
push tmp[0].node[1];
ret;
}
false: {
push tmp[0].node[1];
push tmp[0].node[0];
alloc node;
ret;
}
};
};
}
};
}
};
}
function main() {
push 10;
call gen;
call f;
trace;
pop;
push 15;
call gen;
call f;
trace;
pop;
push 16;
call gen;
call f;
trace;
pop;
push 17;
call gen;
call f;
trace;
pop;
push void;
ret;
}