Update calling convention
Previously, the stack would look like this when calling a function: TOP | arg2 | | arg1 | | function | BOTTOM This order is now reversed, with the function coming first and then the args: TOP | function | | arg2 | | arg1 | BOTTOM This is a little more friendly to the stack-based machine. It is slightly less intuitive as far as order of operations goes, but having a function's arguments depend on the state of the function itself is a little suspect and easy to work around if you truly need that. Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
@@ -142,10 +142,10 @@ impl Compiler {
|
||||
fn emit_expr(&mut self, expr: &SpExpr) -> Thunk {
|
||||
match expr.inner() {
|
||||
Expr::Call(expr, args) => {
|
||||
let mut thunk = VecDeque::with_capacity(args.len() + 1);
|
||||
thunk.push_back(self.emit_expr(expr));
|
||||
thunk.extend(args.iter().map(|arg| self.emit_expr(arg)));
|
||||
let mut thunk = Thunk::List(thunk);
|
||||
let mut thunk_items = VecDeque::with_capacity(args.len() + 1);
|
||||
thunk_items.extend(args.iter().map(|arg| self.emit_expr(arg)));
|
||||
thunk_items.push_back(self.emit_expr(expr));
|
||||
let mut thunk = Thunk::List(thunk_items);
|
||||
thunk.push_back(Inst::Call(args.len()));
|
||||
thunk
|
||||
}
|
||||
|
||||
@@ -25,8 +25,8 @@ pub enum Inst {
|
||||
/// Pops the top item off of the stack, discarding it.
|
||||
Pop,
|
||||
|
||||
/// Pops the top N function arguments off the stack, and attempt to call the
|
||||
/// next stack item.
|
||||
/// Pops the top item off of the stack to call, and then pops off the
|
||||
/// following N arguments.
|
||||
Call(usize),
|
||||
|
||||
/// Exits the current function stack frame and returns control to the
|
||||
|
||||
@@ -195,6 +195,7 @@ impl Vm {
|
||||
Inst::Call(argc) => {
|
||||
let argc = *argc;
|
||||
let stack = self.stack_mut();
|
||||
let fun = stack.pop().expect("No function pointer in Inst::Call");
|
||||
let split_at = stack.len() - argc;
|
||||
let args = stack.split_off(split_at);
|
||||
|
||||
@@ -204,7 +205,6 @@ impl Vm {
|
||||
"Not enough arguments popped in Inst::Call"
|
||||
);
|
||||
|
||||
let fun = stack.pop().expect("No function pointer in Inst::Call");
|
||||
next_frame = self.make_frame(fun, args);
|
||||
}
|
||||
Inst::Return => {
|
||||
|
||||
Reference in New Issue
Block a user