Learning Rust by doing https://adventofcode.com/2019.
The project does not actually uses any new features in Rust nightly,
but it still requires nightly to build. I have some procedure macros
in advent/meta.rs
. Somehow it seems to conflict with my
makeIntEnum
macro. Either of them builds fine in Rust stable alone,
but they do not build at the same time… The problem is gone in
nightly.
Run cargo build
to build, and run cargo run DAY PART
to run.
The following example run day 5, part 2.
cargo run 5 2
In all cases, the input is taken from stdin, and output is printed to stdout, together with time duration of the run.
The Intcode puzzles are so fun, I decided to write a dedicated emulator and an assembler for it. To run the emulator, run
cargo run --bin emulator -- FILE
where FILE
is the file containing your Intcode source code. It takes
input from stdin (if there’s no input, you still need to press
ctrl+d
), and output to stdout.
To run the assembler, run
cargo run --bin assembler
The assembler read what I call “inssembly” code from stdin, and assemble it to Intcode, which is output to stdout. Here’s an example inssembly that does integer division:
; Integer division
input arg1
input arg2
addition:
add 1, result, result
mult result, arg2, test
eq test, arg1, equal_result
jmpt equal_result, :output
less arg1, test, less_result
jmpt less_result, :minus1 ; We overshot, need to minus 1.
jmpt 1, :addition
output:
output result
halt
minus1:
add -1, result, result
jmpt 1, :output
Besides the instruction provided by Intcode, inssembly also support functions. Here’s an example that demonstrate function calls
add 50, 50, add1_arg1
add 1, 2, add1_arg2
call :the_add
output add1_result
halt
the_add:
add add1_arg1, add1_arg2, add2_arg1
call :add2
add add2_result, 0, add1_result
rtn
add2:
add add2_arg1, 2, add2_result
rtn
Basically it defines a function the_add
, which adds its 2 arguments
and apply another function add2
on it. The function add2
just adds
2 to its only argument. Function calls are implemented by
pre-allocating a stack after the “text segment”. The size of the stack
is currently hard-coded to be 10. The “arguments” and “return values”
are all “static”.