[コンパイラ]加減算ができるコンパイラ

5+20-4のような式をアセンブラで書く

.intel_syntax noprefix
.global main

main:
	mov rax, 5
	add rax, 20
	sub rax, 4
	ret

$ cc -o tmp tmp.s
$ ./tmp
$ echo $?
21

これをCで書く

#include <stdio.h>
#include <stdlib.h> // strtol

int main(int argc, char **argv){
	if(argc != 2){
		fprintf(stderr, "引数の個数が正しくありません\n");
		return 1;
	}

	char *p = argv[1];

	printf(".intel_syntax noprefix\n");
	printf(".global main\n");
	printf("main:\n");
	printf("	mov rax, %ld\n", strtol(p, &p, 10)); // ldはlong d, strtolは文字列をlongに変換

	while(*p){
		if(*p == '+'){
			p++;
			printf("	add rax, %d\n", strtol(p, &p, 10));
			continue;
		}

		if(*p == '-'){
			p++;
			printf("	sub rax, %d\n", strtol(p, &p, 10));
			continue;
		}

		fprintf(stderr, "予期しない文字です: '%c'\n", *p);
		return 1;
	}

	printf("	ret\n");
	return 0;
}

strtolは数値を読み込んだ後、第2引数のポインタをアップデートして、読み込んだ最後の文字の次の文字を指すように値を更新

$ make
$ ./9cc ‘5+20-4’
.intel_syntax noprefix
.global main
main:
mov rax, 5
add rax, 20
sub rax, 4
ret