Old, incomplete, broken stuff from a month ago.

James T. Martin 6 months ago
parent d9edbab10c
commit 894c10903c
Signed by: james
GPG Key ID: D6FB2F9892F9B225

@ -103,16 +103,17 @@ var push_var(reg reg) {
void load_args(struct label* label, var* args) {
struct stack_frame* dest_frame = &stack_frames[label->frame];
struct stack_frame* dest_frame = &stack_frames[label->frame - 1];
uint32_t depth_diff = stack_depth - dest_frame->depth;
if (depth_diff > 0) {
// FIXME: should be immX!!!
x86_inst_add_r64_imm8(SP, depth_diff);
x86_inst_add_r64_imm8(SP, depth_diff * 8);
for (uint32_t arg = 0; arg < label->argc; arg++) {
load_var(AX, args[arg]);
stack_depth = dest_frame->depth + label->argc;
void jump(label l, var* args) {
@ -126,20 +127,15 @@ void jump_table(size_t branches, label* labels, var index, var* args) {
assert(0); // UNIMPLEMENTED
void jump_if(label l, var cond, var* args) {
struct label* label = &labels[l];
printf("JUMP_IF %i (%i)\n", l, label->argc);
void jump_if(label t, label e, var cond, var* args) {
struct label* then = &labels[t];
struct label* else_ = &labels[e];
printf("JUMP_IF %i ELSE %i (%i)\n", t, e, then->argc);
assert(then->argc == else_->argc && then->frame == else_->frame);
load_var(BX, cond);
load_args(label, args);
inst_jump_if_not_zero(label->symbol, BX);
void jump_unless(label l, var cond, var* args) {
struct label* label = &labels[l];
printf("JUMP_UNLESS %i (%i)\n", l, label->argc);
load_var(BX, cond);
load_args(label, args);
inst_jump_if_zero(label->symbol, BX);
load_args(then, args);
inst_jump_if_not_zero(then->symbol, BX);
var lit(uint64_t lit) {

@ -7,6 +7,40 @@
typedef uint32_t var;
typedef uint32_t label;
struct jump_target {
label label;
var* args;
/// Declare a new label in the current scope with the provided number
/// of arguments.
/// Local variables (not part of a stack frame generated by `define` or `enter`)
/// will not be in scope of the definition of the label.
label declare(uint32_t argc);
/// Define a label and create a new scope for local variables.
/// The new scope will have access to all of the variables
/// of the parent scope of the label and the label's arguments,
/// but not any local variables from previous definitions.
void define(label label, var* args);
/// Create a new scope which encompasses all local variables defined up to this point.
/// This allows nested definitions to have access to local variables.
void enter(void);
/// Jump to label, unconditionally. Ends the continuation.
void jump(struct jump_target dest);
/// Jump to `then` if `cond` is not zero; jump to `else` otherwise.
/// Ends the continuation.
void jump_if(struct jump_target then, struct jump_target else_, var cond);
/// Jump to the `index`th destination. Ends the continuation.
void jump_table(uint32_t destc, struct jump_target* destinations, var index);
/// Call this at the beginning of execution.
/// It performs initialization and stuff.
void init_ir(var* argc, var* argv, var* env);
@ -61,11 +95,8 @@ void jump(label label, var* args);
/// `index` must not be out of bounds.
void jump_table(size_t branches, label* labels, var index, var* args);
/// Jump to label if `cond` is not zero.
void jump_if(label label, var cond, var* args);
/// Jump to label if `cond` is zero.
void jump_unless(label label, var cond, var* args);
/// Jump to `then` if cond is not zero, `else` if cond is zero.
void jump_if(label then, label else_, var cond, var* args);
/// Integer literal.
var lit(uint64_t lit);

@ -473,8 +473,7 @@ void exit_expr(void) {
case IF_CRUMB: {
struct if_crumb* ifc = &ctx->data.if_;
assert(ifc->state == IF_COND);
jump_unless(ifc->else_, ret, NULL);
//jump(ifc->then_, NULL);
jump_if(ifc->then, ifc->else_, ret, NULL);
ifc->state = IF_THEN;