step by step explanation of grace
This commit is contained in:
164
README.md
164
README.md
@@ -1 +1,163 @@
|
||||
# DR_QUINE
|
||||
# DR QUINE
|
||||
|
||||
#### constructing a quine with macro :
|
||||
---
|
||||
|
||||
**a quine could be this structure basically :**
|
||||
```
|
||||
int main()
|
||||
{
|
||||
char *quine = THE_WHOLE_PROGRAM;
|
||||
printf(quine);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**in one line :**
|
||||
```
|
||||
int main(){ char *quine = THIS_LINE_&_THE_LINES_AROUND; printf(quine); return 0; }
|
||||
```
|
||||
|
||||
**whole code idea :**
|
||||
```
|
||||
#include <stdio.h>
|
||||
#define MAIN() int main() { char *quine = "BEFORE" "THIS_MACRO_ITSELF" "AFTER"; printf(quine); return 0; }
|
||||
|
||||
MAIN()
|
||||
```
|
||||
|
||||
|
||||
#### let's try it
|
||||
---
|
||||
|
||||
```
|
||||
#include <stdio.h>
|
||||
#define MAIN(s) int main() { char *quine = "#include <stdio.h>\n#define MAIN(s) "s"\n\nMAIN(str(MAIN(s)))\n"; printf(quine); return 0; }
|
||||
|
||||
MAIN(s)
|
||||
```
|
||||
|
||||
**expansions :**
|
||||
-> `int main() { char *quine = "#include <stdio.h>\n#define MAIN(s) "s "\n\nMAIN(MAIN(s))\n"; printf(quine); return 0; }`
|
||||
|
||||
**exploded view :**
|
||||
```
|
||||
int main()
|
||||
{
|
||||
char *quine = "#include <stdio.h>\n#define MAIN(s) "s "\n\nMAIN(MAIN(s))";
|
||||
printf(quine);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**problem :** the `char *quine` string should contain a copy of the whole code in place of "s"
|
||||
|
||||
|
||||
#### second try
|
||||
---
|
||||
|
||||
```
|
||||
#include <stdio.h>
|
||||
#define MAIN(s) int main() { char *quine = "#include <stdio.h>\n#define MAIN(s) "s"\n\nMAIN(MAIN(s))\n"; printf(quine); return 0; }
|
||||
|
||||
MAIN(MAIN(s))
|
||||
```
|
||||
|
||||
**expansions :**
|
||||
-> `int main() { char *quine = "#include <stdio.h>\n#define MAIN(s) "int main() { char *quine = "#include <stdio.h>\n#define MAIN(s) "s "\n\nMAIN(MAIN(s))"; printf(quine); return 0; }"\n\nMAIN(MAIN(s))\n"; printf(quine); return 0; }`
|
||||
|
||||
**exploded view :**
|
||||
```
|
||||
int main()
|
||||
{
|
||||
char *quine = "#include <stdio.h>\n#define MAIN(s) "int main() { char *quine = "#include <stdio.h>\n#define MAIN(s) "s "\n\nMAIN(MAIN(s))"; printf(quine); return 0; }"\n\nMAIN(MAIN(s))\n";
|
||||
printf(quine);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**problem :** almost there, but the content of the string quine should be a litteral string instead of code
|
||||
|
||||
|
||||
|
||||
#### lets stringify the content of the string quine
|
||||
---
|
||||
|
||||
**the previous can be written with an extra step :**
|
||||
```
|
||||
#define str(s) s
|
||||
#define MAIN(s) content s content
|
||||
MAIN(str(MAIN(s)))
|
||||
|
||||
/* EQUIVALENT */
|
||||
|
||||
#define MAIN(s) content s content
|
||||
MAIN((MAIN(s)))
|
||||
```
|
||||
|
||||
**we can use this extra step to stringify the content :**
|
||||
```
|
||||
#include <stdio.h>
|
||||
#define str(s) #s
|
||||
#define MAIN(s) int main() { char *quine = "#include <stdio.h>\n#define str(s) #s\n#define MAIN(s) "s"\n\nMAIN(str(MAIN(s)))\n"; printf(quine); return 0; }
|
||||
|
||||
MAIN(str(MAIN(s)))
|
||||
```
|
||||
|
||||
**expansions :**
|
||||
-> `int main() { char *quine = "#include <stdio.h>\n#define MAIN(s) ""MAIN(s)""\n\nMAIN(str(MAIN(s)))\n"; printf(quine); return 0; }`
|
||||
|
||||
|
||||
**exploded view :**
|
||||
```
|
||||
int main()
|
||||
{
|
||||
char *quine = "#include <stdio.h>\n#define MAIN(s) ""MAIN(s)""\n\nMAIN(str(MAIN(s)))";
|
||||
printf(quine);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**problem :** oops, it stringified the paramter name, not it's expanded version, see https://gcc.gnu.org/onlinedocs/cpp/Stringizing.html
|
||||
|
||||
|
||||
#### working stringification
|
||||
---
|
||||
|
||||
```
|
||||
#include <stdio.h>
|
||||
#define xstr(s) #s
|
||||
#define str(s) xstr(s)
|
||||
#define MAIN(s) int main() { char *quine = "#include <stdio.h>\n#define xstr(s) #s\n#define str(s) xstr(s)\n#define MAIN(s) "s"\n\nMAIN(str(MAIN(s)))\n"; printf(quine); return 0; }
|
||||
|
||||
MAIN(str(MAIN(s)))
|
||||
```
|
||||
|
||||
**expansions :**
|
||||
-> `int main() { char *quine = "#include <stdio.h>\n#define xstr(s) #s\n#define str(s) xstr(s)\n#define MAIN(s) ""int main() { char *quine = \"#include <stdio.h>\\n#define xstr(s) #s\\n#define str(s) xstr(s)\\n#define MAIN(s) \"s\"\\n\\nMAIN(str(MAIN(s)))\\n\"; printf(quine); return 0; }""\n\nMAIN(str(MAIN(s)))\n"; printf(quine); return 0; }`
|
||||
|
||||
**exploded view :**
|
||||
```
|
||||
int main()
|
||||
{
|
||||
char *quine =
|
||||
"#include <stdio.h>\n#define xstr(s) #s\n#define str(s) xstr(s)\n#define MAIN(s) "
|
||||
"int main() { char *quine = \"#include <stdio.h>\\n#define xstr(s) #s\\n#define str(s) xstr(s)\\n#define MAIN(s) \"s\"\\n\\nMAIN(str(MAIN(s)))\\n\"; printf(quine); return 0; }"
|
||||
"\n\nMAIN(str(MAIN(s)))\n";
|
||||
printf(quine);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**output :**
|
||||
```
|
||||
#include <stdio.h>
|
||||
#define xstr(s) #s
|
||||
#define str(s) xstr(s)
|
||||
#define MAIN(s) int main() { char *quine = "#include <stdio.h>\n#define xstr(s) #s\n#define str(s) xstr(s)\n#define MAIN(s) "s"\n\nMAIN(str(MAIN(s)))\n"; printf(quine); return 0; }
|
||||
|
||||
MAIN(str(MAIN(s)))
|
||||
```
|
||||
|
||||
**victory ;)**
|
||||
|
||||
|
||||
Reference in New Issue
Block a user