Last active
May 19, 2019 00:24
-
-
Save SeijiEmery/8088773068ef73462de2b104f9ba1fe8 to your computer and use it in GitHub Desktop.
Compile-time Arith
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
g++ -std=c++11 Arith.cpp -S && cat Arith.S | |
g++ -std=c++11 Arith.cpp && ./a.out |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Const<12> => 12 | |
Add<Const<2>, Const<3>> => 5 | |
Add<Const<3>, Const<2>> => 5 | |
Mul<Add<Const<2>, Const<3>>, Const<11>> => 55 | |
Mul<Const<11>, Add<Const<2>, Const<3>>> => 55 | |
Add<Const<12>, Mul<Add<Const<2>, Const<3>>, Const<11>>> => 67 | |
Add<Mul<Add<Const<2>, Const<3>>, Const<11>>, Const<12>> => 67 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <cstdio> | |
enum { TYPE_CONST = 0, TYPE_ADD, TYPE_MUL }; | |
template <int x> | |
struct Const { | |
enum { | |
type = TYPE_CONST, | |
result = x | |
}; | |
static std::ostream& repr (std::ostream& os) { | |
return os << "Const<" << x << ">"; | |
} | |
static void printf () { | |
::printf("Const<%d>", x); | |
} | |
}; | |
template <typename L, typename R> | |
struct Add { | |
typedef L Left; | |
typedef R Right; | |
enum { | |
type = TYPE_ADD, | |
result = Left::result + Right::result | |
}; | |
static std::ostream& repr (std::ostream& os) { | |
return os << "Add<", | |
Left::repr(os) << ", ", | |
Right::repr(os) << ">"; | |
} | |
static void printf () { | |
::printf("Add<"); Left::printf(); ::printf(", "); Right::printf(); ::printf(">"); | |
} | |
}; | |
template <typename L, typename R> | |
struct Mul { | |
typedef L Left; | |
typedef R Right; | |
enum { | |
type = TYPE_MUL, | |
result = Left::result * Right::result | |
}; | |
static std::ostream& repr (std::ostream& os) { | |
return os << "Mul<", | |
Left::repr(os) << ", ", | |
Right::repr(os) << ">"; | |
} | |
static void printf () { | |
::printf("Mul<"); Left::printf(); ::printf(", "); Right::printf(); ::printf(">"); | |
} | |
}; | |
#define eval(Expr) (Expr::result) | |
#define repr(Expr) (Expr::repr(std::cout)) | |
#define print(Expr) (Expr::printf()) | |
// #define printEval(Expr) (repr(Expr) << " => " << eval(Expr) << '\n') | |
// #define printEval(Expr) (std::cout << " => " << eval(Expr) << '\n') | |
#define printEval(Expr) (print(Expr), printf(" => %d\n", eval(Expr))) | |
// #define printEval(Expr) | |
// #define printEval(Expr) (printf(" => %d\n", eval(Expr))) | |
#define assertEvaluatesTo(Expr, result) \ | |
static_assert(eval(Expr) == result, #Expr " !=> " #result) | |
int main () { | |
using A = Const<12>; | |
assertEvaluatesTo(A, 12); | |
printEval(A); | |
using B = Add<Const<2>, Const<3>>; | |
using B_ = Add<Const<3>, Const<2>>; | |
assertEvaluatesTo(B, 5); | |
assertEvaluatesTo(B_, 5); | |
printEval(B); | |
printEval(B_); | |
using C = Mul<B, Const<11>>; | |
using C_ = Mul<Const<11>, B>; | |
assertEvaluatesTo(C, 55); | |
assertEvaluatesTo(C_, 55); | |
printEval(C); | |
printEval(C_); | |
using D = Add<A, C>; | |
using D_ = Add<C, A>; | |
assertEvaluatesTo(D, 67); | |
assertEvaluatesTo(D_, 67); | |
// assertEvaluatesTo(D_, 62); | |
printEval(D); | |
printEval(D_); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.section __TEXT,__text,regular,pure_instructions | |
.build_version macos, 10, 14 | |
.globl _main ## -- Begin function main | |
.p2align 4, 0x90 | |
_main: ## @main | |
.cfi_startproc | |
## %bb.0: | |
pushq %rbp | |
.cfi_def_cfa_offset 16 | |
.cfi_offset %rbp, -16 | |
movq %rsp, %rbp | |
.cfi_def_cfa_register %rbp | |
xorl %eax, %eax | |
popq %rbp | |
retq | |
.cfi_endproc | |
## -- End function | |
.subsections_via_symbols |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.section __TEXT,__text,regular,pure_instructions | |
.build_version macos, 10, 14 | |
.globl _main ## -- Begin function main | |
.p2align 4, 0x90 | |
_main: ## @main | |
.cfi_startproc | |
## %bb.0: | |
pushq %rbp | |
.cfi_def_cfa_offset 16 | |
.cfi_offset %rbp, -16 | |
movq %rsp, %rbp | |
.cfi_def_cfa_register %rbp | |
subq $32, %rsp | |
callq __ZN5ConstILi12EE6printfEv | |
leaq L_.str(%rip), %rdi | |
movl $12, %esi | |
movb $0, %al | |
callq _printf | |
movl %eax, -4(%rbp) ## 4-byte Spill | |
callq __ZN3AddI5ConstILi2EES0_ILi3EEE6printfEv | |
leaq L_.str(%rip), %rdi | |
movl $5, %esi | |
movb $0, %al | |
callq _printf | |
movl %eax, -8(%rbp) ## 4-byte Spill | |
callq __ZN3AddI5ConstILi3EES0_ILi2EEE6printfEv | |
leaq L_.str(%rip), %rdi | |
movl $5, %esi | |
movb $0, %al | |
callq _printf | |
movl %eax, -12(%rbp) ## 4-byte Spill | |
callq __ZN3MulI3AddI5ConstILi2EES1_ILi3EEES1_ILi11EEE6printfEv | |
leaq L_.str(%rip), %rdi | |
movl $55, %esi | |
movb $0, %al | |
callq _printf | |
movl %eax, -16(%rbp) ## 4-byte Spill | |
callq __ZN3MulI5ConstILi11EE3AddIS0_ILi2EES0_ILi3EEEE6printfEv | |
leaq L_.str(%rip), %rdi | |
movl $55, %esi | |
movb $0, %al | |
callq _printf | |
movl %eax, -20(%rbp) ## 4-byte Spill | |
callq __ZN3AddI5ConstILi12EE3MulIS_IS0_ILi2EES0_ILi3EEES0_ILi11EEEE6printfEv | |
leaq L_.str(%rip), %rdi | |
movl $67, %esi | |
movb $0, %al | |
callq _printf | |
movl %eax, -24(%rbp) ## 4-byte Spill | |
callq __ZN3AddI3MulIS_I5ConstILi2EES1_ILi3EEES1_ILi11EEES1_ILi12EEE6printfEv | |
leaq L_.str(%rip), %rdi | |
movl $67, %esi | |
movb $0, %al | |
callq _printf | |
xorl %esi, %esi | |
movl %eax, -28(%rbp) ## 4-byte Spill | |
movl %esi, %eax | |
addq $32, %rsp | |
popq %rbp | |
retq | |
.cfi_endproc | |
## -- End function | |
.globl __ZN5ConstILi12EE6printfEv ## -- Begin function _ZN5ConstILi12EE6printfEv | |
.weak_definition __ZN5ConstILi12EE6printfEv | |
.p2align 4, 0x90 | |
__ZN5ConstILi12EE6printfEv: ## @_ZN5ConstILi12EE6printfEv | |
.cfi_startproc | |
## %bb.0: | |
pushq %rbp | |
.cfi_def_cfa_offset 16 | |
.cfi_offset %rbp, -16 | |
movq %rsp, %rbp | |
.cfi_def_cfa_register %rbp | |
subq $16, %rsp | |
leaq L_.str.1(%rip), %rdi | |
movl $12, %esi | |
movb $0, %al | |
callq _printf | |
movl %eax, -4(%rbp) ## 4-byte Spill | |
addq $16, %rsp | |
popq %rbp | |
retq | |
.cfi_endproc | |
## -- End function | |
.globl __ZN3AddI5ConstILi2EES0_ILi3EEE6printfEv ## -- Begin function _ZN3AddI5ConstILi2EES0_ILi3EEE6printfEv | |
.weak_definition __ZN3AddI5ConstILi2EES0_ILi3EEE6printfEv | |
.p2align 4, 0x90 | |
__ZN3AddI5ConstILi2EES0_ILi3EEE6printfEv: ## @_ZN3AddI5ConstILi2EES0_ILi3EEE6printfEv | |
.cfi_startproc | |
## %bb.0: | |
pushq %rbp | |
.cfi_def_cfa_offset 16 | |
.cfi_offset %rbp, -16 | |
movq %rsp, %rbp | |
.cfi_def_cfa_register %rbp | |
subq $16, %rsp | |
leaq L_.str.2(%rip), %rdi | |
movb $0, %al | |
callq _printf | |
movl %eax, -4(%rbp) ## 4-byte Spill | |
callq __ZN5ConstILi2EE6printfEv | |
leaq L_.str.3(%rip), %rdi | |
movb $0, %al | |
callq _printf | |
movl %eax, -8(%rbp) ## 4-byte Spill | |
callq __ZN5ConstILi3EE6printfEv | |
leaq L_.str.4(%rip), %rdi | |
movb $0, %al | |
callq _printf | |
movl %eax, -12(%rbp) ## 4-byte Spill | |
addq $16, %rsp | |
popq %rbp | |
retq | |
.cfi_endproc | |
## -- End function | |
.globl __ZN3AddI5ConstILi3EES0_ILi2EEE6printfEv ## -- Begin function _ZN3AddI5ConstILi3EES0_ILi2EEE6printfEv | |
.weak_definition __ZN3AddI5ConstILi3EES0_ILi2EEE6printfEv | |
.p2align 4, 0x90 | |
__ZN3AddI5ConstILi3EES0_ILi2EEE6printfEv: ## @_ZN3AddI5ConstILi3EES0_ILi2EEE6printfEv | |
.cfi_startproc | |
## %bb.0: | |
pushq %rbp | |
.cfi_def_cfa_offset 16 | |
.cfi_offset %rbp, -16 | |
movq %rsp, %rbp | |
.cfi_def_cfa_register %rbp | |
subq $16, %rsp | |
leaq L_.str.2(%rip), %rdi | |
movb $0, %al | |
callq _printf | |
movl %eax, -4(%rbp) ## 4-byte Spill | |
callq __ZN5ConstILi3EE6printfEv | |
leaq L_.str.3(%rip), %rdi | |
movb $0, %al | |
callq _printf | |
movl %eax, -8(%rbp) ## 4-byte Spill | |
callq __ZN5ConstILi2EE6printfEv | |
leaq L_.str.4(%rip), %rdi | |
movb $0, %al | |
callq _printf | |
movl %eax, -12(%rbp) ## 4-byte Spill | |
addq $16, %rsp | |
popq %rbp | |
retq | |
.cfi_endproc | |
## -- End function | |
.globl __ZN3MulI3AddI5ConstILi2EES1_ILi3EEES1_ILi11EEE6printfEv ## -- Begin function _ZN3MulI3AddI5ConstILi2EES1_ILi3EEES1_ILi11EEE6printfEv | |
.weak_definition __ZN3MulI3AddI5ConstILi2EES1_ILi3EEES1_ILi11EEE6printfEv | |
.p2align 4, 0x90 | |
__ZN3MulI3AddI5ConstILi2EES1_ILi3EEES1_ILi11EEE6printfEv: ## @_ZN3MulI3AddI5ConstILi2EES1_ILi3EEES1_ILi11EEE6printfEv | |
.cfi_startproc | |
## %bb.0: | |
pushq %rbp | |
.cfi_def_cfa_offset 16 | |
.cfi_offset %rbp, -16 | |
movq %rsp, %rbp | |
.cfi_def_cfa_register %rbp | |
subq $16, %rsp | |
leaq L_.str.5(%rip), %rdi | |
movb $0, %al | |
callq _printf | |
movl %eax, -4(%rbp) ## 4-byte Spill | |
callq __ZN3AddI5ConstILi2EES0_ILi3EEE6printfEv | |
leaq L_.str.3(%rip), %rdi | |
movb $0, %al | |
callq _printf | |
movl %eax, -8(%rbp) ## 4-byte Spill | |
callq __ZN5ConstILi11EE6printfEv | |
leaq L_.str.4(%rip), %rdi | |
movb $0, %al | |
callq _printf | |
movl %eax, -12(%rbp) ## 4-byte Spill | |
addq $16, %rsp | |
popq %rbp | |
retq | |
.cfi_endproc | |
## -- End function | |
.globl __ZN3MulI5ConstILi11EE3AddIS0_ILi2EES0_ILi3EEEE6printfEv ## -- Begin function _ZN3MulI5ConstILi11EE3AddIS0_ILi2EES0_ILi3EEEE6printfEv | |
.weak_definition __ZN3MulI5ConstILi11EE3AddIS0_ILi2EES0_ILi3EEEE6printfEv | |
.p2align 4, 0x90 | |
__ZN3MulI5ConstILi11EE3AddIS0_ILi2EES0_ILi3EEEE6printfEv: ## @_ZN3MulI5ConstILi11EE3AddIS0_ILi2EES0_ILi3EEEE6printfEv | |
.cfi_startproc | |
## %bb.0: | |
pushq %rbp | |
.cfi_def_cfa_offset 16 | |
.cfi_offset %rbp, -16 | |
movq %rsp, %rbp | |
.cfi_def_cfa_register %rbp | |
subq $16, %rsp | |
leaq L_.str.5(%rip), %rdi | |
movb $0, %al | |
callq _printf | |
movl %eax, -4(%rbp) ## 4-byte Spill | |
callq __ZN5ConstILi11EE6printfEv | |
leaq L_.str.3(%rip), %rdi | |
movb $0, %al | |
callq _printf | |
movl %eax, -8(%rbp) ## 4-byte Spill | |
callq __ZN3AddI5ConstILi2EES0_ILi3EEE6printfEv | |
leaq L_.str.4(%rip), %rdi | |
movb $0, %al | |
callq _printf | |
movl %eax, -12(%rbp) ## 4-byte Spill | |
addq $16, %rsp | |
popq %rbp | |
retq | |
.cfi_endproc | |
## -- End function | |
.globl __ZN3AddI5ConstILi12EE3MulIS_IS0_ILi2EES0_ILi3EEES0_ILi11EEEE6printfEv ## -- Begin function _ZN3AddI5ConstILi12EE3MulIS_IS0_ILi2EES0_ILi3EEES0_ILi11EEEE6printfEv | |
.weak_definition __ZN3AddI5ConstILi12EE3MulIS_IS0_ILi2EES0_ILi3EEES0_ILi11EEEE6printfEv | |
.p2align 4, 0x90 | |
__ZN3AddI5ConstILi12EE3MulIS_IS0_ILi2EES0_ILi3EEES0_ILi11EEEE6printfEv: ## @_ZN3AddI5ConstILi12EE3MulIS_IS0_ILi2EES0_ILi3EEES0_ILi11EEEE6printfEv | |
.cfi_startproc | |
## %bb.0: | |
pushq %rbp | |
.cfi_def_cfa_offset 16 | |
.cfi_offset %rbp, -16 | |
movq %rsp, %rbp | |
.cfi_def_cfa_register %rbp | |
subq $16, %rsp | |
leaq L_.str.2(%rip), %rdi | |
movb $0, %al | |
callq _printf | |
movl %eax, -4(%rbp) ## 4-byte Spill | |
callq __ZN5ConstILi12EE6printfEv | |
leaq L_.str.3(%rip), %rdi | |
movb $0, %al | |
callq _printf | |
movl %eax, -8(%rbp) ## 4-byte Spill | |
callq __ZN3MulI3AddI5ConstILi2EES1_ILi3EEES1_ILi11EEE6printfEv | |
leaq L_.str.4(%rip), %rdi | |
movb $0, %al | |
callq _printf | |
movl %eax, -12(%rbp) ## 4-byte Spill | |
addq $16, %rsp | |
popq %rbp | |
retq | |
.cfi_endproc | |
## -- End function | |
.globl __ZN3AddI3MulIS_I5ConstILi2EES1_ILi3EEES1_ILi11EEES1_ILi12EEE6printfEv ## -- Begin function _ZN3AddI3MulIS_I5ConstILi2EES1_ILi3EEES1_ILi11EEES1_ILi12EEE6printfEv | |
.weak_definition __ZN3AddI3MulIS_I5ConstILi2EES1_ILi3EEES1_ILi11EEES1_ILi12EEE6printfEv | |
.p2align 4, 0x90 | |
__ZN3AddI3MulIS_I5ConstILi2EES1_ILi3EEES1_ILi11EEES1_ILi12EEE6printfEv: ## @_ZN3AddI3MulIS_I5ConstILi2EES1_ILi3EEES1_ILi11EEES1_ILi12EEE6printfEv | |
.cfi_startproc | |
## %bb.0: | |
pushq %rbp | |
.cfi_def_cfa_offset 16 | |
.cfi_offset %rbp, -16 | |
movq %rsp, %rbp | |
.cfi_def_cfa_register %rbp | |
subq $16, %rsp | |
leaq L_.str.2(%rip), %rdi | |
movb $0, %al | |
callq _printf | |
movl %eax, -4(%rbp) ## 4-byte Spill | |
callq __ZN3MulI3AddI5ConstILi2EES1_ILi3EEES1_ILi11EEE6printfEv | |
leaq L_.str.3(%rip), %rdi | |
movb $0, %al | |
callq _printf | |
movl %eax, -8(%rbp) ## 4-byte Spill | |
callq __ZN5ConstILi12EE6printfEv | |
leaq L_.str.4(%rip), %rdi | |
movb $0, %al | |
callq _printf | |
movl %eax, -12(%rbp) ## 4-byte Spill | |
addq $16, %rsp | |
popq %rbp | |
retq | |
.cfi_endproc | |
## -- End function | |
.globl __ZN5ConstILi2EE6printfEv ## -- Begin function _ZN5ConstILi2EE6printfEv | |
.weak_definition __ZN5ConstILi2EE6printfEv | |
.p2align 4, 0x90 | |
__ZN5ConstILi2EE6printfEv: ## @_ZN5ConstILi2EE6printfEv | |
.cfi_startproc | |
## %bb.0: | |
pushq %rbp | |
.cfi_def_cfa_offset 16 | |
.cfi_offset %rbp, -16 | |
movq %rsp, %rbp | |
.cfi_def_cfa_register %rbp | |
subq $16, %rsp | |
leaq L_.str.1(%rip), %rdi | |
movl $2, %esi | |
movb $0, %al | |
callq _printf | |
movl %eax, -4(%rbp) ## 4-byte Spill | |
addq $16, %rsp | |
popq %rbp | |
retq | |
.cfi_endproc | |
## -- End function | |
.globl __ZN5ConstILi3EE6printfEv ## -- Begin function _ZN5ConstILi3EE6printfEv | |
.weak_definition __ZN5ConstILi3EE6printfEv | |
.p2align 4, 0x90 | |
__ZN5ConstILi3EE6printfEv: ## @_ZN5ConstILi3EE6printfEv | |
.cfi_startproc | |
## %bb.0: | |
pushq %rbp | |
.cfi_def_cfa_offset 16 | |
.cfi_offset %rbp, -16 | |
movq %rsp, %rbp | |
.cfi_def_cfa_register %rbp | |
subq $16, %rsp | |
leaq L_.str.1(%rip), %rdi | |
movl $3, %esi | |
movb $0, %al | |
callq _printf | |
movl %eax, -4(%rbp) ## 4-byte Spill | |
addq $16, %rsp | |
popq %rbp | |
retq | |
.cfi_endproc | |
## -- End function | |
.globl __ZN5ConstILi11EE6printfEv ## -- Begin function _ZN5ConstILi11EE6printfEv | |
.weak_definition __ZN5ConstILi11EE6printfEv | |
.p2align 4, 0x90 | |
__ZN5ConstILi11EE6printfEv: ## @_ZN5ConstILi11EE6printfEv | |
.cfi_startproc | |
## %bb.0: | |
pushq %rbp | |
.cfi_def_cfa_offset 16 | |
.cfi_offset %rbp, -16 | |
movq %rsp, %rbp | |
.cfi_def_cfa_register %rbp | |
subq $16, %rsp | |
leaq L_.str.1(%rip), %rdi | |
movl $11, %esi | |
movb $0, %al | |
callq _printf | |
movl %eax, -4(%rbp) ## 4-byte Spill | |
addq $16, %rsp | |
popq %rbp | |
retq | |
.cfi_endproc | |
## -- End function | |
.section __TEXT,__cstring,cstring_literals | |
L_.str: ## @.str | |
.asciz " => %d\n" | |
L_.str.1: ## @.str.1 | |
.asciz "Const<%d>" | |
L_.str.2: ## @.str.2 | |
.asciz "Add<" | |
L_.str.3: ## @.str.3 | |
.asciz ", " | |
L_.str.4: ## @.str.4 | |
.asciz ">" | |
L_.str.5: ## @.str.5 | |
.asciz "Mul<" | |
.subsections_via_symbols |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
full implementation: https://github.com/SeijiEmery/arith/tree/master/cpp