Cả câu trả lời của Charlie và câu trả lời trước đó của tôi đều hoạt động theo nguyên tắc cho phép bộ xử lý trước viết rất nhiều mã, nhưng họ chủ yếu thực hiện chính bộ xử lý trước, lexer (ý tưởng tốt là bước này thường chậm) và trình phân tích cú pháp. Mine cũng cố gắng thực hiện các bước tối ưu hóa và tạo mã, nhưng rõ ràng nó không đạt được nhiều ở đó.
Suy nghĩ về cách một trình biên dịch c điển hình hoạt động, tôi nhận ra rằng chúng ta sẽ không cung cấp mã biểu tượng liên quan đến bảng biểu tượng. Mục này là một nỗ lực để khắc phục điều đó. Nó được cho là gợi nhớ đến việc định hướng đối tượng cơ bản trong triển khai c, nhưng không làm gì thú vị: sử dụng kỹ thuật mở rộng tiền xử lý để khai báo và tầm thường (và không chính xác) khởi tạo một loạt các đối tượng. Các đối tượng sử dụng các loại phức tạp, trên nhiều cấp độ phạm vi, tạo bóng cho nhau ở các mức loại bỏ khác nhau. Nó nên cung cấp cho bảng biểu tượng một công việc thực sự ra.
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
// Exercise the symbol table mechanism of the compiler in an effort to
// take a unreasonable about of time compiling
#define PTR(T) T*
#define CONST(T) T const
#define FUNC(NAME,RTYPE,ARG) RTYPE NAME(ARG)
#define FPTR(NAME,RTYPE,ARG) FUNC((*NAME),RTYPE,ARG)
// Forward decalration of repeated OO method pointers
typedef void* (*cctor_ptr)(void*this, void*that, ...);
typedef void* (*dtor_ptr)(void*this);
// Assumes three var-args: sizeof(payload type), cctor, dtor
void* default_ctor(void*this, ...){
// Pull in variadac bits
va_list list;
va_start(list,this);
int size=va_arg(list,int);
cctor_ptr cctor=va_arg(list,cctor_ptr);
dtor_ptr dtor=va_arg(list,dtor_ptr);
va_end(list);
// process
if (!this) this = malloc(size);
if (this) {
memset(this,size,0);
/* various dodges to install the cctor and dtor in the write places */
}
return this;
}
// Copies the payload from that to this;
void* default_cctor(void*restrict this, void* restrict that, ...){
// Pull in variadac bits
va_list list;
va_start(list,that);
int size=va_arg(list,int);
cctor_ptr cctor=va_arg(list,cctor_ptr);
dtor_ptr dtor=va_arg(list,dtor_ptr);
va_end(list);
// process
if (!this) this = malloc(size);
if (this) {
memcpy(this,that,size);
/* various dodges to install the cctor and dtor in the write places */
}
return this;
}
// Assumes that his was allocated with malloc, does not use varargs
void* default_dtor(void*this, ...){
free(this);
return NULL;
};
#define DECLARE_STRUCT(N) struct S##N##_s
#define TYPEDEF_ACCESSOR(N,T) typedef FPTR(f##N##_ptr,CONST(PTR(T)),PTR(CONST(struct S##N##_s)))
#define TYPEDEF_STRUCT(N,T) typedef struct S##N##_s {PTR(T)p; cctor_ptr cctor; dtor_ptr dtor; f##N##_ptr f##N;} S##N
#define OO_STRUCT(N,T) DECLARE_STRUCT(N); TYPEDEF_ACCESSOR(N,T); TYPEDEF_STRUCT(N,T)
OO_STRUCT(1,char);
OO_STRUCT(2,int);
OO_STRUCT(3,double*);
OO_STRUCT(4,S3);
OO_STRUCT(5,S4);
OO_STRUCT(6,S5);
OO_STRUCT(7,S6);
OO_STRUCT(8,S7);
#define SUBSCOPE(A) { \
S1*A##1=default_ctor(NULL,sizeof(char),default_cctor,default_dtor); \
S2 A##2; default_ctor(&A##2,sizeof(int),default_cctor,default_dtor); \
S2*A##3=default_ctor(NULL,sizeof(double*),default_cctor,default_dtor); \
S8 A##5; default_ctor(&A##5,sizeof(S4),default_cctor,default_dtor); \
S6 A##6; default_ctor(&A##6,sizeof(S5),default_cctor,default_dtor); \
S8*A##8=default_ctor(NULL,sizeof(S7),default_cctor,default_dtor); \
}
#define SUBSCOPE2(A,B) { \
S2*B##5=default_ctor(NULL,sizeof(S4),default_cctor,default_dtor); \
S4 A##7; default_ctor(&A##7,sizeof(S6),default_cctor,default_dtor); \
SUBSCOPE(A) SUBSCOPE(B); \
}
#define SUBSCOPE6(A,B,C) { \
S2*A##3=default_ctor(NULL,sizeof(double*),default_cctor,default_dtor); \
S2 B##2; default_ctor(&B##2,sizeof(int),default_cctor,default_dtor); \
S4*C##4=NULL; \
SUBSCOPE2(A,C) SUBSCOPE2(B,C) SUBSCOPE2(A,B); \
}
#define SUBSCOPE24(A,B,C,D) { \
S1*D##1=default_ctor(NULL,sizeof(char),default_cctor,default_dtor); \
S2 C##2; default_ctor(&C##2,sizeof(int),default_cctor,default_dtor); \
S2*B##3=default_ctor(NULL,sizeof(double*),default_cctor,default_dtor); \
S4 A##4; default_ctor(&A##4,sizeof(S3),default_cctor,default_dtor); \
SUBSCOPE6(A,B,C) SUBSCOPE6(A,B,D) SUBSCOPE6(A,C,D) SUBSCOPE6(B,C,D); \
}
#define SUBSCOPE120(A,B,C,D,E) { \
S5*A##5=default_ctor(NULL,sizeof(S4),default_cctor,default_dtor); \
S6*A##6=default_ctor(NULL,sizeof(S5),default_cctor,default_dtor); \
S8 A##8; default_ctor(&A##8,sizeof(S7),default_cctor,default_dtor); \
SUBSCOPE24(A,B,C,D) SUBSCOPE24(A,B,C,E) SUBSCOPE24(A,B,D,E); \
SUBSCOPE24(A,C,D,E) SUBSCOPE24(B,C,D,E); \
}
#define SUBSCOPE720(A,B,C,D,E,F) { \
S5 A##5; default_ctor(&A##5,sizeof(S4),default_cctor,default_dtor); \
S6 A##6; default_ctor(&A##6,sizeof(S5),default_cctor,default_dtor); \
S8*A##8=default_ctor(NULL,sizeof(S7),default_cctor,default_dtor); \
SUBSCOPE120(A,B,C,D,E) SUBSCOPE120(A,B,C,D,F) SUBSCOPE120(A,B,C,E,F); \
SUBSCOPE120(A,B,D,E,F) SUBSCOPE120(A,C,D,E,F) SUBSCOPE120(B,C,D,E,F); \
}
int main(){
S4 s4;
SUBSCOPE720(A,B,C,D,E,F)
}
Thời gian biên dịch trên máy của tôi vượt quá 4 giây -O3
và hơn 1 giây không được tối ưu hóa.
Rõ ràng bước tiếp theo sẽ là hoàn thành việc triển khai OO cho các lớp BCD và thực hiện lại các phép tính pi bằng cách sử dụng nó để tôi có được cả hai hiệu ứng chạy mạnh.