ããã«ã¡ã¯ãèªåã®ããã°ãæ¸ãã®ã¯ãã®ãããä¹ ãã¶ãã®id:rskyã§ããä½å¹´ç¥ç便ç§ã ã£ããã ã£ã¦æãã§ããã
表é¡ã®ã¨ããããããCã³ã³ãã¤ã©ãä½ã£ã¦ããããã¨æãã¾ããååã®DQNEOãããï¼8cc.goï¼ã¨ããã³ã³ãã¤ã©ãä½ããã¦ãã¦ãããã«è§¦çºããã¦ãRustã§ãã£ã¦ã¿ãããã¨ãããã¨ã§ãï¼ä½ã¬ã¤ã¤ãç¥ããã人ã®ããã®Cã³ã³ãã¤ã©ä½æå ¥éï¼ãCã§ãªãRustã§ãã£ã¦ããã¾ãã Rustèªä½ãåãã¦ãªã®ã§ããããå«ãã¦ã©ããªãã®ã«ãªã£ã¦ããã®ããèªåã§ã楽ãã¿ã§ãã
ãªããä»å¾ãã®ã·ãªã¼ãºã§ã¯ï¼ä½ã¬ã¤ã¤ãç¥ããã人ã®ããã®Cã³ã³ãã¤ã©ä½æå ¥éï¼ãäºéé¤æ¬å¼§ã¤ãã®ãå ¥éãã¨è¡¨è¨ãã¾ãã
éçºç°å¢
èªåã®éçºãã·ã³ã¯Macã§ãããmacOSã¯ã¿ã¼ã²ããã¨ããLinuxã§åããã®ãä½ã£ã¦ããã¾ãããå ¥éãã«ã
macOSã¯Linuxã¨ã¢ã»ã³ããªã®ã½ã¼ã¹ã¬ãã«ã§ããªãäºææ§ãããã¾ãããå®å ¨äºæã§ã¯ããã¾ããããã®æ¬ã®å 容ã«å¾ã£ã¦macOS対å¿ã®Cã³ã³ãã¤ã©ãä½æããã®ã¯ä¸å¯è½ã§ã¯ãªããã®ã®ãå®éã«è©¦ãã¦ã¿ãã¨ãç´°ããªç¹ã§ãããããªéäºææ§ã«æ©ã¾ããããã¨ã«ãªãã§ããããCã³ã³ãã¤ã©ä½æã®ãã¯ããã¯ã¨ãmacOSã¨Linuxã®å·®ç°ãåæã«å¦ã¶ã¨ããã®ã¯ããã¾ããå§ãã§ãããã¨ã§ã¯ããã¾ãããä½ãããã¾ãåããªãå ´åãã©ã¡ãã®ç解ãééã£ã¦ããã®ãããããããªããªã£ã¦ãã¾ãããã§ãããããã£ã¦ç¾æç¹ã§ã¯ãæ¬æ¸ã§ã¯macOSã¯å¯¾è±¡å¤ã¨ãã¾ããmacOSã§ã¯Dockerãªã©ã使ã£ã¦Linuxç°å¢ãç¨æããããã«ãã¦ãã ããã
ã¨ããããã«ãã³ã³ãã¤ã©ä½æã®æ¬è³ªã«æ³¨åããããã§ãã äºæã§ãããµãã§Windowsã使ã£ã¦ãããWSL2ã¨Windows Terminalã®åºæ¥å¦ä½ã§ã¯ããããã¡ã¤ã³éçºç°å¢ãWindowsã«ãã¦ãããããªã¨æã£ã¦ãã¾ãã
ã³ã©ã : macOSã§ã®å·®ç°
Linuxã¨ã·ã³ãã«ãã¤æ大ã®éãã¨ããã°ãmacOSã§ã¯å
¬éã·ã³ãã«ã«ã¢ã³ãã¼ã¹ã³ã¢ã®prefixãå¿
è¦ãªãã¨ã§ãããããmain
é¢æ°ã¯ã¢ã»ã³ããªã§ã¯_main
ã¨ããååã§å®£è¨ããªãã¨ããã¾ããã
macOSç°å¢ã«ããã¦ã·ã³ãã«ã«ã¢ã³ãã¼ã¹ã³ã¢ã®prefixããã件ã ãã¡ãã£ã¨æ³¨æã§ãããããã¯ãã§ããããã¯ã³ã³ãã¤ã©ã§ãããªã«ããã®ãããã®ããª? pic.twitter.com/ZbiDkWg8mK
— Ryusuke SEKIYAMA (@rsky) 2019å¹´5æ10æ¥
ã¾ããããã¯æãã¦ããã ãããã¨ã§ãããã¬ã¸ã¹ã¿ã«ãéãããããããã§ãããã®ãããã®ç¥èã¯ä»ã®èªåã«å ¨ãæ¬ ãã¦ãããã¨ããããç´ ç´ã«Linuxã®ã¿ãã¿ã¼ã²ããã«ãããã¨ã«ãã¾ãããå°æ¥çã«ã¯ã¯ãã¹ã³ã³ãã¤ã«ã«ããã£ã¬ã³ã¸ãã¦ã¿ããã§ããã
ã¬ã¸ã¹ã¿ãè¥å¹²ç°ãªãã®ã鬼éãã¤ã³ã https://t.co/DpIS64UIYU
— Kawakamiã®ãã£ãã (@kawakami_o3) 2019å¹´5æ10æ¥
Repository
æ¢ã«ä½ææ¸ã¿ã®9cc.rustãcloneãã¦ä½æ¥ãã¾ãã
$ git clone [email protected]:rsky/9cc.rust.git $ cd 9cc.rust
Dockerfile
Ubuntu 18.04 LTSãã¼ã¹ã®ã¤ã¡ã¼ã¸ãä½ãã¾ãã
FROM ubuntu:18.04 # Install build tools RUN apt-get update && apt-get install -y gcc make git curl binutils libc6-dev # Install Rust RUN curl https://sh.rustup.rs -o rustup-init.sh && chmod +x rustup-init.sh && ./rustup-init.sh -y WORKDIR /9cc.rust COPY . /9cc.rust
Getting Started
ãã®ã·ãªã¼ãºã§ä½ãã³ã³ãã¤ã©ã®ãã¤ããªå㯠r9cc
ã¨ãã¾ããããã§ã¯ãã£ããããã¸ã§ã¯ããä½æãã¾ããããä»ã¾ãã«èªã¿å§ããã°ããã®ï¼ããã°ã©ãã³ã°Rustï¼ã«å¾ã£ã¦ããã±ã¼ã¸ãä½æãã¾ãã
$ cargo new --bin r9cc Created binary (application) `r9cc` project
$ tree r9cc r9cc âââ Cargo.toml âââ src âââ main.rs 1 directory, 2 files
ãããæ¢ã«9cc.rustããã¸ã§ã¯ãå ã§ä½æ¥ãã¦ããã®ã§ããã§ã¯ã¡ãã£ã¨é½åãæªããã¨ãããã¨ã§ãªãã¼ã ãã¾ããã
$ mv -v r9cc/* . r9cc/Cargo.toml -> ./Cargo.toml r9cc/src -> ./src $ rmdir r9cc
Hello, Rust!
ã¾ãã¯å¼æ°ãåãããåºå®ã®ã¢ã»ã³ããªã³ã¼ããåãã ãã®ããã°ã©ã ãæ¸ãã¦ã¿ã¾ããåèªèº«åã®Rustã³ã¼ãã§ãã
src/main.rs
fn main() { println!(".intel_syntax noprefix"); println!(".global main"); println!("main:"); println!(" mov rax, 1"); println!(" ret"); }
ããããã«ããã¾ããâ»ããããå ã¯ã³ã³ããä¸ã§ã®ä½æ¥ã§ãããããã辺ã®èª¬æã¯ãã£ããçãã¦ãã¾ãã
$ cargo run Compiling r9cc v0.1.0 (/9cc.rust) Finished dev [unoptimized + debuginfo] target(s) in 5.60s Running `target/debug/r9cc` .intel_syntax noprefix .global main main: mov rax, 1 ret
target/debug/r9cc
ã«ãã¤ããªãä½ããããããªã®ã§ããããå®è¡ãçæç©ãã¢ã»ã³ãã«ãã¦å®è¡ãã¾ãã
$ ./target/debug/r9cc > tmp.s $ cat tmp.s .intel_syntax noprefix .global main main: mov rax, 1 ret $ gcc -o tmp tmp.s $ ./tmp $ echo $? 1
OKã§ãããå¼ãç¶ãå¼æ°ã¨ãã¦åã£ãæ°å¤ãè¿ãããã«ãã¾ãã
Take Arguments
ã³ãã³ãã©ã¤ã³å¼æ°ã®å¦çã¯ï¼ããã°ã©ãã³ã°Rustï¼ã®ç¬¬2ç« åºç¤ã«æ¸ããã¦ããããã®ã¾ã¾ä½¿ãã¾ããã
use std::io::Write; use std::str::FromStr; fn main() { let mut numbers = Vec::new(); for arg in std::env::args().skip(1) { numbers.push(u8::from_str(&arg).expect("error parsing argument")) } if numbers.len() != 1 { writeln!(std::io::stderr(), "Invalid number of arguments.").unwrap(); std::process::exit(1); } println!(".intel_syntax noprefix"); println!(".global main"); println!("main:"); println!(" mov rax, {}", numbers[0]); println!(" ret"); }
ãã«ããã¦å®è¡ãã¦ã¿ã¾ããå¼æ°ã®ãã¼ã¹ã¨ã©ã¼ãå¦çã§ãã¦ãã¦ãããããã§ããã
$ cargo run Compiling r9cc v0.1.0 (/9cc.rust) Finished dev [unoptimized + debuginfo] target(s) in 0.41s Running `target/debug/r9cc` Invalid number of arguments. $ ./target/debug/r9cc Invalid number of arguments. $ ./target/debug/r9cc 42 .intel_syntax noprefix .global main main: mov rax, 42 ret $ ./target/debug/r9cc 65535 thread 'main' panicked at 'error parsing argument: ParseIntError { kind: Overflow }', src/libcore/result.rs:997:5 note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace. $ ./target/debug/r9cc foo thread 'main' panicked at 'error parsing argument: ParseIntError { kind: InvalidDigit }', src/libcore/result.rs:997:5 note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
ã¨ããããã§ãå¼æ°ãæå®ãã¦åºåããã³ã¼ããã¢ã»ã³ãã«ãå®è¡ãã¾ãã
$ ./target/debug/r9cc 42 > tmp.s $ cat tmp.s .intel_syntax noprefix .global main main: mov rax, 42 ret $ gcc -o tmp tmp.s $ ./tmp $ echo $? 42
OKã§ãããããã§ãããããå ¥éãã®ã¹ããã1ã®éä¸ããã³ã³ãã¤ã©æ¬ä½ã®ä½æãã¾ã§å®äºãã¾ããã 次åã¯ãã¦ããããã¹ãã®ä½æãã§ãã