diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2021-10-26 23:12:57 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2021-10-26 23:14:36 -0700 |
commit | c7dde8d8b4338d478fc61c4a8ea5e1c84bf5513e (patch) | |
tree | 62a083cd61861ea57568986682d75f941d4972a0 /tutorial | |
parent | 5713eb7302a11af489faeb3172cc376398db57e0 (diff) | |
download | mu-c7dde8d8b4338d478fc61c4a8ea5e1c84bf5513e.tar.gz |
task: primitive statements vs function calls
Diffstat (limited to 'tutorial')
-rw-r--r-- | tutorial/index.md | 66 | ||||
-rw-r--r-- | tutorial/task8a.mu | 10 | ||||
-rw-r--r-- | tutorial/task8b.mu | 8 | ||||
-rw-r--r-- | tutorial/task8c.mu | 7 |
4 files changed, 91 insertions, 0 deletions
diff --git a/tutorial/index.md b/tutorial/index.md index 1dbc0d4b..72917533 100644 --- a/tutorial/index.md +++ b/tutorial/index.md @@ -288,6 +288,72 @@ var x/edx: int <- copy 0 Run `translate` (or `translate_emulated`) as usual. Use your runbook from Task 6 to address the errors that arise. +## Task 8: primitive statements vs function calls + +Managing variables in memory vs register is one of two key skills to +programming in Mu. The second key skill is calling primitives (which are +provided by the x86 instruction set) vs functions (which are defined in terms +of primitives). + +To prepare for this task, reread the very first section of the Mu reference, +on [functions and function calls](https://github.com/akkartik/mu/blob/main/mu.md#functions). + +Now look at the following programs. In each case, write down whether you +expect translation to return any errors and why. + +``` +fn f a: int { +} + +fn main { + f 0 + var r/eax: int <- copy 3 + f r + var m: int + f m +} +``` + +(When you're ready, try the above program out as `./translate tutorial/task8a.mu`.) + +``` +fn f -> _/eax: int { + var result/ecx: int <- copy 0 + return result +} + +fn main { + var x/eax: int <- f +} +``` + +(When you're ready, try the above program out as `./translate tutorial/task8b.mu`.) + + +``` +fn f -> _/eax: int { + return 3 +} + +fn main { + var x/ecx: int <- f +} +``` + +(When you're ready, try the above program out as `./translate tutorial/task8c.mu`.) + +Functions have fewer restrictions than primitives on inouts, but more +restrictions on outputs. Inouts can be registers, or memory, or even literals. +This is why the first example above is legal. Outputs, however, _must_ +hard-code specific registers, and function calls must write their outputs to +matching registers. This is why the third example above is illegal. + +One subtlety here is that we only require agreement on output registers +between function call and function header. We don't actually have to `return` +the precise register a function header specifies. The return value can even be +a literal integer or in memory somewhere. The `return` is really just a `copy` +to the appropriate register(s). This is why the second example above is legal. + ## Task 9: operating with fractional numbers All our variables so far have had type `int` (integer), but there are limits diff --git a/tutorial/task8a.mu b/tutorial/task8a.mu new file mode 100644 index 00000000..bba989f7 --- /dev/null +++ b/tutorial/task8a.mu @@ -0,0 +1,10 @@ +fn f a: int { +} + +fn main { + f 0 + var r/eax: int <- copy 3 + f r + var m: int + f m +} diff --git a/tutorial/task8b.mu b/tutorial/task8b.mu new file mode 100644 index 00000000..888f01ec --- /dev/null +++ b/tutorial/task8b.mu @@ -0,0 +1,8 @@ +fn f -> _/eax: int { + var result/ecx: int <- copy 0 + return result +} + +fn main { + var x/eax: int <- f +} diff --git a/tutorial/task8c.mu b/tutorial/task8c.mu new file mode 100644 index 00000000..68d90c9a --- /dev/null +++ b/tutorial/task8c.mu @@ -0,0 +1,7 @@ +fn f -> _/eax: int { + return 3 +} + +fn main { + var x/ecx: int <- f +} |