86 lines
2.5 KiB
C
86 lines
2.5 KiB
C
#ifndef _IR_H
|
|
#define _IR_H
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
typedef uint32_t var;
|
|
typedef uint32_t label;
|
|
|
|
/// Call this at the beginning of execution.
|
|
/// It performs initialization and stuff.
|
|
void init_ir(var* argc, var* argv, var* env);
|
|
|
|
/// Enter a new block.
|
|
///
|
|
/// All labels defined in this block will have access to all variables
|
|
/// which are in scope as of calling `enter`. You will be able to jump
|
|
/// to any label which is defined in this block from here
|
|
/// to the symmetric `leave`.
|
|
///
|
|
/// This also generates a new label corresponding with the end of the block,
|
|
/// which will be automatically defined when you call `leave`.
|
|
void enter(void);
|
|
|
|
/// Leave a block.
|
|
///
|
|
/// This will restore the context to how it was when `enter` was called,
|
|
/// plus the return values declared by the call to `declare_continue`.
|
|
void leave(var* rets);
|
|
|
|
/// Declare a new label in the innermost block.
|
|
///
|
|
/// This label can only be called from the block or nested blocks.
|
|
/// This label must be called with the given number of arguments.
|
|
label declare(uint32_t argc);
|
|
|
|
//// Declare an exit label for the surrounding block.
|
|
///
|
|
/// Calling this label will exit the surrounding blocks.
|
|
/// The usual restrictions for labels apply.
|
|
label declare_exit(uint32_t retc);
|
|
|
|
// Define a label in the innermost block, automatically terminating
|
|
/// any previous labels.
|
|
///
|
|
/// All variables defined prior to the beginning of this block will be in scope.
|
|
/// The arguments associated with the label will be in scope.
|
|
/// Variables defined *after* the beginning of the block but *prior* to this label
|
|
/// will *not* be in scope.
|
|
///
|
|
/// From this label you can jump to any label in the enclosing block
|
|
/// or any parent block.
|
|
void define(label label, var* args);
|
|
|
|
/// Jump to label, unconditionally; never returns.
|
|
void jump(label label, var* args);
|
|
|
|
/// Jump to `index`th label in table; never returns.
|
|
///
|
|
/// All labels must be at the same depth and accept the same arguments.
|
|
/// `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);
|
|
|
|
/// Integer literal.
|
|
var lit(uint64_t lit);
|
|
|
|
/// String literal.
|
|
var lit_string(char* str);
|
|
|
|
/// Addition.
|
|
var add(var addend1, var addend2);
|
|
|
|
/// Subtraction.
|
|
var sub(var subtrahend, var minuend);
|
|
|
|
/// Perform a system call.
|
|
var syscall(size_t argc, var* args);
|
|
|
|
#endif
|