mirror of
https://github.com/anoma/juvix.git
synced 2024-12-14 08:27:03 +03:00
76548e464a
* 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.
179 lines
2.9 KiB
Plaintext
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;
|
|
}
|