5 ms·
A tiny self-remaking C program
- LorenDB 2y agoIn D, this is a fully-supported used case. The DMD compiler provides an executable called rdmd that can be used as the shebang executable at the top of any D file, and the shebang itself is also codified as valid D syntax.
- rwmj 2y agoThis is completely off topic for the actual article, but I had a bit of fun a while back working out how to make self-executing C and OCaml scripts/programs. It's an interesting exercise working out what is both a comment in the target language but is also an executable shell script. For C it's reasonably straightforward but for OCaml it's quite subtle: https://libguestfs.org/nbdkit-cc-plugin.3.html#C-plugin-as-a-self-contained-script https://libguestfs.org/nbdkit-cc-plugin.3.html#C-plugin-as-a... https://libguestfs.org/nbdkit-cc-plugin.3.html#Using-this-plugin-with-OCaml https://libguestfs.org/nbdkit-cc-plugin.3.html#Using-this-pl...
- d99kris 2y agoI do something similar (but less portable and more verbose) in C++ sometimes when I want to prototype something. My boilerplate is something like this: #if 0 TMP=$(mktemp -d); c++ -std=c++11 -o ${TMP}/a.out ${0} && ${TMP}/a.out ${@:1}; RV=${?}; rm -rf ${TMP}; exit ${RV}; #endif #include <iostream> int main() { std::cout << "Hello, world!\n"; } (the trailing semi-colons in the script part is to make my editor indent the C++ code properly)
- stefanos82 2y agoHA! I was about to share my way, but you seem to have done more or less what I have in C instead! I was having fun with old Golang C code before they started bootstrapping in Go and have found they were using interpunct to separate function names, so I decided to play around with shellscript-like C code to goof around: #if 0 set -e; [ "$0" -nt "$0.bin" ] && gcc -O2 -Wall -Wextra -Wpedantic -std=c11 "$0" -o "$0.bin" -s exec "$0.bin" "$@" #endif #include <stdio.h> void runtime·sysAlloc(void); int main(void) { unsigned age = 44; printf("I am %u years old.\n", age); runtime·sysAlloc(); return 0; } void runtime·sysAlloc(void) { printf("Hello from C code, %d!\n", 90); }
- hawski 2y agoThat's exactly how I keep my quick test C or C++ programs. I like how one can keep all the compilation options in the same file this way.
- seeknotfind 2y agoI love the opening #if 0. So many tricks from multilingual quines, maybe they can actually be useful :)
- ktm5j 2y agoI absolutely love this, super clever!
- hippich 2y agoSomewhat adjacent- I recently discovered https://github.com/rofl0r/rcb2 https://github.com/rofl0r/rcb2 - it can take it quite far without using make file. And similarly to OP - it allows to keep relevant build info right in the source code. (Rcb2 is great at prototype stage, but obviously at some point makefiles are worth spending time on)
- slippy 2y agoDidn't this exist conceptually anyway as the C shell (csh) where the scripting language was "closer to" C? https://en.wikipedia.org/wiki/C_shell https://en.wikipedia.org/wiki/C_shell It seems like you are on your way to making the C++ shell.
- 082349872349872 2y agoAlthough the substantial functionality overlap between shells and programming languages has caused many to attempt to combine them, someone a while back (Yossi Kreinin?) had a reason that's probably not what we want: a shell should be optimised for quickly doing specific things, and programming languages should be optimised for concisely doing general things. In particular, this suggests that bare words in shells should default to being literals, and variable substitution will take extra characters, while bare words in programming languages should default to being variables, and literal values will take extra characters.
- trollied 2y agoYou might all enjoy The International Obfuscated C Code Contest https://www.ioccc.org/ https://www.ioccc.org/ https://www.ioccc.org/years.html https://www.ioccc.org/years.html
- hoseja 2y agoIs the linked example a quine or something else? It's a quine, right?
- mananaysiempre 2y agoTFA? No, it’s a C / Bourne shell polyglot where the shell part compiles and runs the C part. I’ve also used this technique when I needed to post self-contained examples (e.g. to mailing lists), but I don’t know if people actually appreciated it.
- lifthrasiir 2y agoIOCCC is almost irrelevant here, but one particular winning entry is relevant: 2000/tomx [1]. Nowadays IOCCC is hosted in GitHub Pages and it is hard to look at the verbatim source, so the following is the entire source code: #include <stdio.h> #define true true /*:all CC=cc PROG=tomx false : make -f $0 $1 exit 0 all: $(PROG) %:%.c $(CC) $< -o $@ clean: rm $(PROG) .PHONY: /* true clean */ int main() {return!printf("Hello, world\n");} (All indentations here are actually tabs.) [1] https://www.ioccc.org/2000/tomx.c https://www.ioccc.org/2000/tomx.c
- rramadass 2y agoThis compiles as both "./tomx.c" and "make -f tomx.c" to produce the executable "tomx"; but am not fully clear how?
- lifthrasiir 2y agoAs a shell script, anything starting with `#`, `true<WS>` and `false<WS>` are meant to be ignored and variable declarations are compatible with Make. The next lines to be executed are therefore `make -f $0 $1` and `exit 0`, as you would expect. Shell scripts are parsed linewise so subsequent lines are ignored. As a Makefile, again `#` lines are ignored and variable declarations are compatible but lines starting with `true<WS>` and `false<WS>` have to be a valid construct, so they are made into rules. Make doesn't rely much on the rule's recipe (you can do way more weird things by setting `SHELL` to non-shells by the way!), so indented lines are essentially ignored unless the rule is triggered. Next lines are usual stuffs for Makefile. As `true` (and anything follows, see the next paragraph) would be the first and thus default rule target, it has to trigger `all` manually and ensure that `all` is always executed in this way by setting the final `.PHONY` rule. As a C source code, `#` lines are now preprocessor directives and used to hide the first `true` token from the compiler. As an identifier followed by a colon wouldn't be a valid C code at the top level, `true` should be followed by a comment which extends to the second-to-last line. (There is no technical reason for `*/` to be a requisite here I believe.) The final line is an usual indented C code, which is a part of `.PHONY` which recipe is ignored. Since Make will interpret `/*` as path patterns, they have to be also handled by `.PHONY`.
- actionfromafar 2y ago"TCC can also be used to make C scripts, i.e. pieces of C source that you run as a Perl or Python script. Compilation is so fast that your script will be as fast as if it was an executable." https://bellard.org/tcc/tcc-doc.html https://bellard.org/tcc/tcc-doc.html
- fuhsnn 2y agohttps://github.com/vnmakarov/mir https://github.com/vnmakarov/mir is also great for this, the c2m binary is an optimizing C11 JIT runner, even accept "*.c" as input.
- necovek 2y agoThe way I see it, this is something a true built-from-source system could do with their packaging system to enable no-effort code changes for any system utility and true trust in you running what you have source for (other than backdoored hardware). Debian is pretty far off from this vision (if we also want performant execution), but I wonder how do the Gentoo, ArchLinux and Nix fare in this regard? Is this something that could be viably built with their current packaging formats?
- antoinealb 2y agoIn arch at least it is reasonnably easy to download the source for a package, modify it locally, build it and install it. Not sure if that's what you are asking for?
- Brian_K_White 2y agoI think no matter how easy a seperate source package is, it's still a seperate thing, and not the same (not as good) as the source being a built in part of the package. freebsd/gentoo ports comes close where if you pretend that pkg doesn't exist, or at least imagine a world where it's only used for the absolute minimum necessary bootstrap, then ports is probably the closest. The source is still actually a seperate thing even then so I think even ports with no pkg usage is still not really there. Imagine the package itself being the source, the one and only form of the package is the source. If it builds an executable, that executable is actually just an automatically generated throw-away artifact that you don't care about and don't save or distribute. Maybe most normal users don't even know where the compiled bin really lives, buried in some /var tree or something, or maybe even in a kind of kernel level db. All the user ever overtly interacts with is actually the self-building source package. When you want to copy it or delete it etc, that's the only thing you touch and everything else is just automatically managed cache. Then it's not merely easy to get the source and modify it, it's simply THE package in the first place. If you can even run a thing, then you automatically and indellibly also have the full source to that thing. That would be pretty huge I think. It would probably result in slow installs and updates like gentoo or freebsd ports, but only if we only imagine switching to this today as the only variable changed, out of context, without also imagining the last 40 years of tooling and os development optimizing pain points to make whatever we do most go faster, if we had decided to package apps this way all along.
- codethief 2y ago> the right conceptual basis for build systems: ”build is the first stage of execution” I have long been thinking the same. And also: "Running tests is the first stage of deploying in production" etc. In other words: There is often a whole dependency graph between various stages (install toolchain, install 3rd-party dependencies, do code generation, compile, link/bundle, test, run, …) and each of those stages should ideally be a pure function mapping inputs to outputs. In my experience, we often don't do a good job making this graph explicit, nor do we usually implement build steps as pure functions or think of build systems as another piece of software which needs to be subject to the same quality criteria that we apply to any other line of code we write. As a result, developer experience ends up suffering. Large JavaScript projects are particularly bad in this regard. Dependencies, auto-generated code and build output live right alongside source code, essentially making them global state from the point of view of the build system. The package.json contains dozens of "run" commands which more often than not are an arcane mix of bash scripts invoking JS code. Even worse, those commands typically need to be run in juuust the right order because they all operate on the same global state. There is no notion of one command depending on another. No effort put into isolating build tasks from each other and making them pure. No caching of intermediate results. Pipelines take ages even though they wouldn't have to. Developers get confused because a coworker introduced a new npm command yesterday which now needs be to run before anything else. Ugghhh.
- haberman 2y ago"Build is the first stage of execution" resonates with me too. It follows that build systems should be written in terms of real, encapsulated APIs that separate interface from implementation. Make-like build systems are like programming in assembly language: there is no structure that isolates one build step from another. Make offers no way of creating a "local variable" -- an intermediate file that is hidden from any other build step. The filesystem is like memory: as long as you can figure out the filename (address) somehow, you can read and write whatever you want. Even if you can declare that one build step depends on another, there's usually nothing that prevents a step from reading (or even writing!) files from other build steps that it did not declare a dependency on. What you want is a build system that lets you define real APIs, with truly private state. For example, cc_library() in Bazel (cxx_library() in Buck2) lets you define a C++ library in terms of the srcs/hdrs/etc, but you don't know how it will be implemented. Other rules and targets can consume the outputs of cc_library(), but only the files that are publicly exposed in the returned providers. This model brings true encapsulation to build systems, which makes it much more feasible to change implementation details without breaking users.
- seanw265 2y agoBased on the title, I was expecting this to be about quines [1]. If you aren't familiar, quines are programs which produce their own source as their only output. They're quite interesting and worth a dive if you haven't explored them before. My personal favorites are the radiation-hardened variety, which still produce the original pre-modified source even when any single character is removed before the program is run. [1]: https://en.wikipedia.org/wiki/Quine_(computing) https://en.wikipedia.org/wiki/Quine_(computing)
- f1shy 2y agoYou can chain 128 quines: https://github.com/mame/quine-relay https://github.com/mame/quine-relay
- cmdlineluser 2y agoTheir "keep ruby weird" quine is my favourite: https://www.youtube.com/watch?v=IgF75PjxHHA https://www.youtube.com/watch?v=IgF75PjxHHA %q!.!;eval$s=%q{eval(%w{$s=("%q!.!;eval$s=%q{#$s}"+'.gsub(/#{27.chr<<92<<91}[0-9]+m/,"")').lines;C=->x,y{Complex(x,y)};P=->r,a{Complex.polar(r,a*Math::PI)};S=->((a,b),(c ,d)){[a-c,b-d]};D=->((a,b),(c,d)){(a*c.conj).real+b*d};R=->((a,b),(c,d)){e,f=a.rect;g,h=c.rect;[C[f*d-b*h,b*g-e*d],e*h-f*g]};a=[];b=[];6.times{|i|a<<[P[1,i/3.0],1];b<<[P [2,(i+0.5)/3.0],0]};F=[a];6.times{|j|F<<[a[i=j-1],b[i],a[j]]<<[a[j],b[i],b[j]]<<[b[i],[0,-2],b[j]]};J=->k,v{k=[k/500.0,0].min+2.5;(v/(k+0.5)+C[k,k/2])*48};r=0;T=->p{x,y= p.rect;z =O[y/2];x>=0&&y>=0&&z&&z[x]&&z[x]|=(y%2>1?2:1)|r};L=->p,q{s=(p+q)/2;(p-q).abs<1?(T[s];q):L[L[p,s],q]};N=->((a,b)){s=(a.abs2+b*b)**0.5;[a/s,b/s]};E=->p,r,a{10 0.times {| i|m=-P[r,1.5+i*a*0.02];c,d=(p+m).rect;(c.abs-d>2||d<-1)&&(T[J[0,p+m]];T[J[0,C[-c,d ]]])}};A=27.chr;$><<"%q#{33. chr+A}[H#{A}[2J";g="NZDD CLYJXMX ;Y K(OQ'PP YZA5YTZ7M(VOBBSYVXQQ[SUZV(U:G[NVZ[ZS&V[(YUU(ZTT[[X'X&Y%Y'ZZWW['Z&$$[%('' '(&[$(%($( CRGZHZI)DIOZ;IVPZ(SP)[X* DRZCGJJT<< +XI,%%:S=[E==RE&LEXX-'. RMY:(>>U(HU /U[/[R KOO0Y$1F?LZ%&M@(2NGU341RU?+6S2(NVYVAFVR(8FFRYRN4W'NHI@>(EUM6H@ZISSMS-XL .LLVL?RR8O[O K9B,$%Y[3Y0X";41.upto(91 ){|c|g=g[2.. -1].gsub(c.chr){g[0,2] }};G=g.spli t(?(); Z=[C[7,10],C[13,76]];U=(0..48).map{[0]*169};O=[];srand(0);q=20;m=40;x=0; Threa d.new {open("/dev/dsp","w"){ |f|50 0.dow nto(0){|k|e=[];300.tim es{|i|e<<(( x=(x+ k**1.9/9e4+0.001)%8)>4?138:118)};f<<e.pack("C*")}}};I=(0..48).map{[0]*169 };9.t imes{ |y|76.times{|x|"1ea8yyjb v4x7d zlzqj sxd8dz4uqjfpb66bq7tu6l wql6vdbds6f 6h60 xz2iglxie44ax1nygtie5t8xpgk2oq00uzj0ucoq2gqc70y9fplfzez0d682syamnhicpwflot4 o9s".to_i( 36)[x+y*76]>0&&I[24+y][4 +x]=1}};-5 00.upto(518){|k|k==1&&s leep(1);k= =q& &(n=rand(11);q+=m;m-=2 ;spawn("espeak","-s",(60+m*2).to_s,"-ven+#{n<7?"m #{n+ 1}":"f#{n-6}"}",["keep",k< 320| |k>360?"ruby":"Austin"," weird"]*32 .c hr));a=[-k,0].max**1.9/ 1e4;v ,z=d=N[[P[1,a/3],Math.sin(Math::PI*a)]];u=N[z==0 ? [0,-1]:z>0?[v,z-1/z]:[-v,1/z-z]] ; n=R[d,u];O.replace(U.map{ |l|l+ [ ]});F.m ap{ |f|a, b,c=f;D [R[S[b,a],S[c,a]],d]>0&&f.size.times{|i|a,b=f[ i], f[i-1];L[J[k,C[D[n,a],D[u,a]]],J[k,C[D [n, b],D[u,b]]]]}};k>0&&(b=M ath. sin( [k,210] .m i n* Math : :PI /15)/36;a=P[1,b*2];y=(30-[k,30].min)/10.0-2.8; E[C[ -1.2,y]*a.conj,(2-k/10%2)*0.06,-1];E[C [-1. 2,y]*a.conj,0.45,-1];E[C [-1. 2,y +1.1]*a, 2. 7 5, b-0. 3]; E[C[-0.6,y+0.5]*a,1.85,b-0.25]);k>=90&&k<210&&2 .tim es{|i|G[(k-90)*2+i].scan(/./){|c|Z[i]+ =[C[ 1,0],C[0,2],C[-1,0],C[0, -2]][c . ord%4]} ;i = k/ 10% 7*8+92 ;U[Z[0]. imag/2][Z[0].real,2]=U[Z[1].imag/2][Z [1]. real,2]=[i,i];r=8;L[J[k,C[-1.2,-2.8] *a.c onj],Z[0]];L[J[k,C[1.2,- 2.8]*a], Z[ 1]];r=0} ; j= 0;k==400&&15.times{|y|65.times{|x|"7gtz whx13 bfmrr9tsr8y0d007qlmygnh47axi9g9v609t cxjuv la0k6y1r96drdisqmfpao411 n6e661l3 zykt bqk p4i33eecq7i2u tfm 2n0bhrviijbr51nwcuhm5ufx3t79a9whf01e3a8kzzepid45ro83 n9r07k xxeht1pycrqo72".to_i(36)[x+y*65]>0 &&U[21 +y][14+x]=88}};s=O.map{| l|i=0;j+ =1;l.m ap{|n|(i+=1)>2& &i<8 3&&k>260&&k<420&&((k-j/6)%80>60||k>320&&k<400&&I[j- 1][i]>0 )&&n=88;a=("%c^_@****"%32)[n%8]; n>7?"%c [%dm%s%c[0m"%[27,30+n/8, a,27]:a} *""};$><<A+"[H"+(0..47).ma p{|i |k+i>517?$s[i].chomp.gsub(32.chr){27.chr+"[44m"+$&+ 27.chr+" [0m"}:s[i]}*10.chr;sleep(0.0 2)};puts }*'');%q{%q.;eval$s=%qev al(%w$s= ("%q.;eval$s=%q$s"+'.gsub(/ 27. chr<<92<<91[0-9]+m/,"")').lines;C=->x,yComplex(x,y) ;P=->r,a Complex.polar(r,a*Math::PI );S=->(( a,b),(c,d))[a-c,b-d];D=- >((a,b), (c,d) )(a*c.conj). re al+b*d;R=->((a,b),(c ,d))e,f=a. rect;g,h=c.rect;[ C[f*d-b*h ,b*g-e*d],e*h-f*g];a=[ ];b=[];6. times|i|a<<[P[1,i/3.0],1] ;b<<[P[2,(i+0.5 )/3.0], 0];F= [a ];6 .t imes|j| F<<[a[i= j-1],b[i],a[j]]<<[ a[j],b [i],b[ j]]<<[b[i],[0,-2],b[j]];J =->k,vk=[k/500. 0,0].min+ 2.5 ;(v/(k+0. 5) +C[k, k/2] )*48;r =0;T=->px,y=p.rect;z =O[ y /2];x>=0&& y>=0 &&z&&z[x]& & z[x ]|=(y%2>1?2:1)|r;L=->p,qs= (p+q)/2;(p-q).a bs<1?(T[s] ;q ):L[L[p,s ], q];N=- >((a ,b)) s=(a.abs2+b*b)**0.5;[a /s, b/s];E=- >p,r,a10 0.times| i|m =-P[r,1.5+i*a*0.02];c,d=(p+ m).rect;(c.abs- d>2||d<-1) && (T[J[0,p+ m] ];T[J[ 0,C[- c, d]]]);A=27.chr;$><<"%q 33.ch r+A[HA [2J";g="NZDD CLYJXM X;YK( OQ'PPYZA5YTZ7M(VOBBSYVXQQ[ SUZV(U:G[NVZ[ZS &V[(YUU(ZT T[ [X'X&Y%Y' ZZ WW[ 'Z&$$[%( '''(&[$(%($(CRGZHZI)D IOZ;IVP Z(SP )[X*DRZCGJJT<<+X I,%% :S=[E== RE&LEXX-'.RMY:(>>U(HU/U[ /[RKOO0Y$1F?LZ% &M@(2NGU3 41R U?+6S2(NV YV AFVR(8FFR YRN4W'NHI@>(EUM6H@Z ISSMS-XL. LLV L?RR8O[OK9B,$%Y[3Y0X ";4 1.upto(91 )|c|g=g[2..-1].gsub(c .chr)g[0,2];G=g .split (?();Z=[C [7 ,10],C [13,76]] ;U=(0..48).map[0] *169;O=[];s r and(0);q=20;m=40;x=0;Thr e ad.newopen( "/dev/dsp","w")|f|5 00.downto(0)|k| e=[];3 00.time s|i|e<<( (x =(x+k** 1.9/9e 4+0.001)%8)>4?13 8:118);f<<e.pa ck("C*");I=(0..48).map[0]*16 9;9.times|y|76 .times|x|"1ea8yyj bv4x7dzlzqjsxd8 dz4uqjf pb66bq 7tu6lwql 6v dbds6f6 h60xz 2iglxie44ax1nygti e5t8xpgk2oq00uzj0 ucoq2gqc70y9fpl fzez0d68 2syam nhicpwfl ot 4o9s".t o_i( 36)[x+y*76]>0&&I[24+ y][4+x]=1;-50 0.upto(518)|k|k==1&&sleep(1) ;k==q&&(n=ran d(11);q+=m;m-=2;spa wn("espeak","-s ",(60+m*2 ).to _s,"-ve n+n <7?"mn +1": "fn-6"",["keep",k<320|| k>360?"ruby" :"Austin","weird"]*32.chr) );a=[-k,0].m ax**1.9/1e4;v,z=d=N[[ P[1,a/3],Math. sin(Math::P I*a) ]];u= N[z= =0? [0,- 1]:z>0?[v,z-1/z]:[-v,1/z-z ]];n=R[d,u] ;O.replace(U.map|l|l+[]) ;F.map|f|a, b,c=f;D[R[S[b,a],S[c,a] ],d]>0&&f.size .times|i|a, b=f[i] ,f[i-1] ;L[J[k, C[D[n,a],D[u,a]]],J[k,C[D[n, b],D[u,b]] ]];k>0&&(b=Math.sin([k ,210].min* Math::PI/15)/36;a=P[1,b*2 ];y=(30-[k,30] .min)/10.0-2.8;E[C[-1.2,y]*a.conj,(2-k/10%2)*0.06,-1];E[C[-1.2,y]*a.conj,0.45,-1] ;E[C[-1.2 ,y+1.1]*a,2.75,b-0.3 ];E[C[-0. 6,y+0.5]*a,1.85,b-0.25]);k> =90&&k<210&&2.times|i|G[(k-90)*2+i].scan(/. /)|c|Z[i]+=[C[1, 0],C[0,2],C[-1,0],C[0,-2]][c.ord%4]; i=k/10%7 *8+92;U[Z[0].imag/ 2][Z[0]. real,2]=U[Z[1].imag/2][Z[1].r eal,2]=[i,i];r=8;L[J[k,C[-1.2,-2.8]*a.conj],Z[0]];L[J[k,C[1.2,- 2.8]*a],Z[1]];r=0;j=0;k==400&&15.time s|y|65. times|x|"7gtzwhx 13bfmrr 9tsr8y0d007qlmygnh47axi9g9v609t cxjuvla0k6y1r 96drdisqmf pao4 11n6 e661 l 3zyktb qkp4i33eecq7i2utfm2n0bhrviijbr51nwcuhm 5ufx3t 79a9whf01e3a8k zzepid 45ro83n9r07kxxeht1pycrqo72".to_i( 36)[x+y*65]>0 &&U[ 21+y] [1 4+x]=8 8;s= O.ma p|l|i= 0;j+= 1;l.map|n|(i+=1)>2&&i<83&&k>260&&k<420& &((k- j/6)%80>60|| k>320 &&k<400&&I[j-1][i]>0)&&n=88;a=("%c^ _@****"%32)[n %8]; n>7?" %c [%dm% s%c[ 0m"%[27, 30+n/8,a,27]:a*"";$><<A+"[H"+(0..47).map |i|k +i>517?$s[ i].c homp.gsub(32.chr)27.chr+"[44m"+$&+27. chr+"[0m":s[i] *10 .chr; sl eep(0.02 ); puts *'');% q%q.;e val$ s=%qeval(%w$s=("%q.;eval$s=%q$s"+'. gsu b(/27.ch r<< 92<<91[0-9]+m/,"")').lines;C=->x,yCompl ex(x,y);P=->r,aC om plex .pola r(r ,a*Ma th::PI); S=- >((a,b),(c,d))[a-c,b-d];D=->((a,b),(c ,d ))(a*c .c onj).real+b*d;R=->((a,b),(c,d))e,f=a.rect ;g,h=c.rect;[C[f*d-b*h,b*g-e*d],e*h-f*g];a=[] ;b= [];6.t imes|i |a<<[P[1,i/3.0],1];b<<[P[2,(i+0.5)/3.0],0];F=[ a ];6. t imes|j|F<<[a[i=j-1],b[i],a[j]]<<[a[j],b[i], b[j]]<<[b[i],[0,-2],b[j]];J=->k,vk=[k/500.0,0].min+2.5;(v/( k+0.5)+C[k,k/2])*48;r=0;T=->px,y=p.rect;z=O[y/2]; x> =0&&y>=0&&z&&z[x]&&z[x]|=(y%2>1?2:1)|r;L=->p, qs=(p+q)/2;(p-q).abs<1?(T[s];q):L[L[p,s],q];N=->((a,b))s=(a.abs2+b*b)**0.5;[a/s,b/s];E=->p,r,a100.times|i|m=-P[r,1.5+i *a*0.02];c,d=(p+m).rect;(c.abs-d>2||d<-1)&&(T[J [0,p+m]];T[J[0,C[-c,d]]]);A=27.chr;$><<"%q33.chr+A[HA[2J";g="NZDDCLYJXMX;YK(OQ'PPYZA5YTZ7M(VOBBSYVXQQ[SUZV(U:G[NVZ[ZS&V[(YUU(ZTT[[X'X&Y%Y'ZZWW['Z&$$[%('''(&[$(%($(CRGZHZ I)DIOZ;IVPZ(SP)[X*DRZCGJJT<<+XI,%%:S=[E==RE&LEXX-'.RMY:(>>U(HU/U[/[RKOO0Y$1F?LZ%&M@(2NGU341RU?+6S2(NVYVAFVR(8FFRYRN4W'NHI@>(EUM6H@Z}}.gsub(/#{27.chr<<92<<91}[0-9]+m/,"")
- o11c 2y agoSometimes it's useful to do something like: /*usr/bin/env echo 'Hello World!' #*/ Even if, for some reason, there are multiple `usr` folders, the use of `env` means it will eventually call the executable. As for getting rid of the shebang - swapping the ! with a / means that the line and character counts don't change so you get meaningful error messages.
- dorianmariefr 2y agowhat kind of sorcery is this :D
- rramadass 2y agoAh; the /* at the beginning is expanded by the shell to a proper path while the trailing #*/ becomes a shell comment.
- dorianmariefr 2y ago"$0".bin: -c: line 0: unexpected EOF while looking for matching `'' "$0".bin: -c: line 1: syntax error: unexpected end of file
- lboc 2y agoSeems to be replicating mainframe JCL and in-stream data sets. Processing instructions and input are combined in a single file. Used all the time for compiling, running utilities etc. I'm guessing that this (IBM) example is setting the delimeter to '@@' to avoid problems with the comment - JCL also understands the '/*' sequence. I've not seen it used with other languages (Cobol etc.) //jobname JOB acctno,name... //COMPILE EXEC PGM=CCNDRVR, // PARM='/SEARCH(''CEE.SCEEH.+'') NOOPT SO OBJ' //STEPLIB DD DSNAME=CEE.SCEERUN,DISP=SHR // DD DSNAME=CEE.SCEERUN2,DISP=SHR // DD DSNAME=CBC.SCCNCMP,DISP=SHR //SYSLIN DD DSNAME=MYID.MYPROG.OBJ(MEMBER),DISP=SHR //SYSPRINT DD SYSOUT=* //SYSIN DD DATA,DLM=@@ #include <stdio.h> ⋮ int main(void) { /* comment */ ⋮ } @@ //SYSUT1 DD DSN=... ⋮ //* https://en.wikipedia.org/wiki/Job_Control_Language#In-stream_input https://en.wikipedia.org/wiki/Job_Control_Language#In-stream...*
- z4ziggy 2y ago//bin/env gcc $0 -g -o ${0%.} && ./${0%.} ; exit thats the one i've been using. feel free to adopt and change.