about summary refs log tree commit diff stats
path: root/mu_summary
diff options
context:
space:
mode:
Diffstat (limited to 'mu_summary')
-rw-r--r--mu_summary192
1 files changed, 192 insertions, 0 deletions
diff --git a/mu_summary b/mu_summary
new file mode 100644
index 00000000..676b1151
--- /dev/null
+++ b/mu_summary
@@ -0,0 +1,192 @@
+Mu programs are lists of functions. Each function has the following form:
+
+  fn _name_ _inouts_with_types_ -> _outputs_with_types_ {
+    _instructions_
+  }
+
+Instructions may be primitives or function calls. Either way, all instructions
+have one of the following forms:
+
+  # defining variables
+  var _name_: _type_
+  var _name_/_register_: _type_
+
+  # doing things with variables
+  _operation_ _inouts_
+  _outputs_ <- _operation_ _inouts_
+
+Instructions and functions may have inouts and outputs. Both inouts and
+outputs are variables.
+
+As seen above, variables can be defined to live in a register, like this:
+
+  n/eax
+
+Variables not assigned a register live in the stack.
+
+Function inouts must always be on the stack, and outputs must always be in
+registers. A function call must always write to the exact registers its
+definition requires. For example:
+
+  fn foo -> x/eax: int {
+    ...
+  }
+  fn main {
+    a/eax <- foo  # ok
+    a/ebx <- foo  # wrong
+  }
+
+Primitive inouts may be on the stack or in registers, but outputs must always
+be in registers.
+
+Functions can contain nested blocks inside { and }. Variables defined in a
+block don't exist outside it.
+
+## Primitive instructions
+
+Primitive instructions currently supported in Mu:
+
+  var/eax <- increment
+  var/ecx <- increment
+  var/edx <- increment
+  var/ebx <- increment
+  var/esi <- increment
+  var/edi <- increment
+  increment var
+
+  var/eax <- decrement
+  var/ecx <- decrement
+  var/edx <- decrement
+  var/ebx <- decrement
+  var/esi <- decrement
+  var/edi <- decrement
+  decrement var
+
+  var1/reg1 <- add var2/reg2
+  var/reg <- add var2
+  add-to var1, var2/reg
+  var/eax <- add n
+  var/reg <- add n
+  add-to var, n
+
+  var1/reg1 <- sub var2/reg2
+  var/reg <- sub var2
+  sub-from var1, var2/reg
+  var/eax <- sub n
+  var/reg <- sub n
+  sub-from var, n
+
+  var1/reg1 <- and var2/reg2
+  var/reg <- and var2
+  and-with var1, var2/reg
+  var/eax <- and n
+  var/reg <- and n
+  and-with var, n
+
+  var1/reg1 <- or var2/reg2
+  var/reg <- or var2
+  or-with var1, var2/reg
+  var/eax <- or n
+  var/reg <- or n
+  or-with var, n
+
+  var1/reg1 <- xor var2/reg2
+  var/reg <- xor var2
+  xor-with var1, var2/reg
+  var/eax <- xor n
+  var/reg <- xor n
+  xor-with var, n
+
+  var/eax <- copy n
+  var/ecx <- copy n
+  var/edx <- copy n
+  var/ebx <- copy n
+  var/esi <- copy n
+  var/edi <- copy n
+  var1/reg1 <- copy var2/reg2
+  copy-to var1, var2/reg
+  var/reg <- copy var2
+  var/reg <- copy n
+  copy-to var, n
+
+  compare var1, var2/reg
+  compare var1/reg, var2
+  compare var/eax, n
+  compare var, n
+
+  var/reg <- multiply var2
+
+## Primitive jump instructions
+
+There are two kinds of jumps, both with many variations: `break` and `loop`.
+`break` instructions jump to the end of the containing block. `loop` instructions
+jump to the beginning of the containing block.
+
+Jumps can take an optional label starting with '$':
+
+  loop $foo
+
+This instruction jumps to the beginning of the block called $foo. It must lie
+somewhere inside such a box. Jumps are only legal to containing blocks.
+
+There are two unconditional jumps:
+
+  loop
+  loop label
+  # unconditional break instructions don't seem useful
+
+The remaining jump instructions are all conditional. Conditional jumps rely on
+the result of the most recently executed `compare` instruction. (To keep
+programs easy to read, keep compare instructions close to the jump that uses
+them.)
+
+  break-if-=
+  break-if-= label
+  break-if-!=
+  break-if-!= label
+
+Inequalities are similar, but have unsigned and signed variants. We assume
+unsigned variants are only ever used to compare addresses.
+
+  break-if-<
+  break-if-< label
+  break-if->
+  break-if-> label
+  break-if-<=
+  break-if-<= label
+  break-if->=
+  break-if->= label
+
+  break-if-addr<
+  break-if-addr< label
+  break-if-addr>
+  break-if-addr> label
+  break-if-addr<=
+  break-if-addr<= label
+  break-if-addr>=
+  break-if-addr>= label
+
+Similarly, conditional loops:
+
+  loop-if-=
+  loop-if-= label
+  loop-if-!=
+  loop-if-!= label
+
+  loop-if-<
+  loop-if-< label
+  loop-if->
+  loop-if-> label
+  loop-if-<=
+  loop-if-<= label
+  loop-if->=
+  loop-if->= label
+
+  loop-if-addr<
+  loop-if-addr< label
+  loop-if-addr>
+  loop-if-addr> label
+  loop-if-addr<=
+  loop-if-addr<= label
+  loop-if-addr>=
+  loop-if-addr>= label