Golf me an HQ9+ Compiler

8

1

Your task is "simple" should you choose to accept it.

Write an HQ9+ compiler in a language of your choice.

HQ9+ has four commands (as you may be able to tell) H prints "Hello, World!" Q prints out the source code (this can either be the compiled source or HQ9+ source for the purpose of this challenge),9 prints out the lyrics to 99 bottles of beer on the wall, and + is essentially a noop.

Your submission should be written in some language X, and should take input of HQ9+ source and output a program in X.

Wait, I know what you're thinking. This is not a duplicate of Creating a HQ9+ interpreter as it should not run HQ9+ code, but rather compile it. It should output a fully functional program.


Rules
  1. Language X should satisfy the traditional definition of a language
  2. Standard loopholes disallowed
  3. This is code golf (shortest program in bytes wins)
  4. Your solution must be testable
  5. X cannot be HQ9+ or an extension of HQ9+


Clarifications

There has been some confusion as to what the q command should do. I had originally thought that it would output the compiled code (i.e code in langauge X), but my reference implementation outputs the hq9+ code. I would like to see either one depending on your golfing preferences.

Rohan Jhunjhunwala

Posted 2016-07-01T00:06:39.937

Reputation: 2 569

Question was closed 2016-07-02T13:39:16.807

What would HH produce? – Leaky Nun – 2016-07-01T00:07:28.933

Hello, World!Hello, World!@LeakyNun – Rohan Jhunjhunwala – 2016-07-01T00:10:28.127

@LeakyNun Presumably Hello, World!\nHello, World!\n – Mego – 2016-07-01T00:10:39.310

can the output language be HQ9+? – Maltysen – 2016-07-01T00:12:03.487

No, adding that to the specs – Rohan Jhunjhunwala – 2016-07-01T00:15:28.653

4This would be a perhaps better challenge for languages X and Y to be the same. – Conor O'Brien – 2016-07-01T00:22:33.443

Perhaps but its too late now – Rohan Jhunjhunwala – 2016-07-01T00:23:24.877

It's not too late. There's only one valid answer currently (mine), and it wouldn't be invalidated by that rule change. Additionally, banning extensions of HQ9+ (like those found in the "See Also" section of this page) is probably a good idea.

– Mego – 2016-07-01T00:26:35.367

Ok altering the challenge – Rohan Jhunjhunwala – 2016-07-01T00:35:25.840

Dr Green Eggs. It is not I talked about how it is not an interpeter it is different because it is a compiler. – Rohan Jhunjhunwala – 2016-07-01T00:48:14.793

@RohanJhunjhunwala Yes I know, but I think the difference is pretty small. I could write print "print" at the beginning of the python answer and copy the rest. Although FWIW, it'll take 3 other users to agree with me, so the question might stay open anyway. – James – 2016-07-01T01:00:16.877

IT is fairly similar of a challenge I guess, but I would say that it does open itself to some interesting variations, and it does actually fit HQ9+'s spec of ingnore extraneous characters. – Rohan Jhunjhunwala – 2016-07-01T01:03:33.493

4Should Q output the source of the input program, or the compiled program? – Conor O'Brien – 2016-07-01T01:05:54.240

@CᴏɴᴏʀO'Bʀɪᴇɴ I would think the compiled program - otherwise it wouldn't really be a quine. – Mego – 2016-07-01T02:58:30.413

@Mego I don't know... a C quine doesn't output its compiled binary either. – Martin Ender – 2016-07-01T05:51:05.770

6The post would benefit from the inclusion of HQ9+ specs. – Fatalize – 2016-07-01T06:16:43.880

@MartinEnder A C Quine outputs its own source code. C doesn't have to be compiled (though the interpreters admittedly don't work well). – Mego – 2016-07-01T06:33:04.510

@Mego But a C quine still outputs its C source code even if it is compiled. HQ9+ doesn't need to be compiled either. I really don't see why you want to treat one differently from the other. – Martin Ender – 2016-07-01T06:58:50.037

@MartinEnder Fair enough. I guess clarification from the OP would be helpful. I interpreted it as "write a program that outputs an equivalent program to the HQ9+ input program in your language", meaning a quine should output the compiled program and not the input program. – Mego – 2016-07-01T07:14:49.743

My reference implementation has q print out the hq9+ source as opposed to the compiled source, but it would be interesting to make it be the compiled source – Rohan Jhunjhunwala – 2016-07-01T13:16:52.083

The accepted answer is the one that wins the challenge. Though you are not obligated to accept an answer, if you do, the consensus on meta is that you should accept the answer with the best score - for code golf, that's the shortest answer in bytes. – Mego – 2016-07-01T21:14:54.583

@Mego ok I guess I can accept the smallest program. – Rohan Jhunjhunwala – 2016-07-01T21:23:20.577

2This should stay closed. If you can interpret HQ9, then all you have to do is stringify the commands used in your code and output them at the correct moments. – Rɪᴋᴇʀ – 2017-04-11T03:27:12.987

Answers

11

Actually, 17 bytes

"HQ9"∩εj'N'9(t'.j

Try it online!

This program compiles HQ9+ to Actually.

Actually is (almost) a superset of HQ9+ - the only difference is that the 9 command in HQ9+ is N in Actually. Because + is a NOP in HQ9+ (the accumulator is never actually used or displayed, and thus many implementations treat it as a NOP), it is stripped out.

Explanation:

"HQ9"∩εj'N'9(t'.j
"HQ9"∩εj           strip all characters not in "HQ9", preserving order
        'N'9(t     replace all occurrences of "9" with "N"
              '.j  insert a "." between every pair of characters

-1 byte from Christian Irwin

Mego

Posted 2016-07-01T00:06:39.937

Reputation: 32 998

You... you are good. – Conor O'Brien – 2016-07-01T00:21:29.817

Impressed! Only 533 more bytes of golf needed on my java solution! – Rohan Jhunjhunwala – 2016-07-01T00:49:37.723

Superset for the win! I've been watching your language for some time, quite interesting xD – busukxuan – 2016-07-01T04:54:59.693

Isn't Actually a variant of HQ9+, since it contains commands that do all of HQ9+'s specification? – Addison Crump – 2016-07-01T22:36:33.087

@VTCAKAVSMoACE Actually contains the HW, Quine, and NNBB commands, but does not have an "increment accumulator" command. Additionally, since the NNBB command is N instead of 9, it's not quite an extension/variant/superset. The need to explicitly print with . between every command further differentiates Actually from HQ9+ (since H and N don't do the HW and NNBB commands if the stack is not empty). – Mego – 2016-07-01T22:38:37.603

@Mego ¯\(ツ)/¯ It just feels weird for this to be feasible in 17 bytes. – Addison Crump – 2016-07-01T22:40:08.587

4

Java only 551 bytes

Joined in on the fun! This is a java compiler which compilers HQ9+ to java.Java is not verbose at all. Some code shamelssly stolen borrowed from "99 Bottles of Beer".


public class a{public static void main(String[]a){System.out.printf("public class a{public static void main(String[]z){String p=\"%s\";for(char a:p.toCharArray()){if(a=='H')p(\"Hello, World\\n\");if(a=='Q')p(p);if(a=='9'){String b=\" of beer\",c=\" on the wall\",n=\".\\n\",s;for(int i=100;i-->1;){s=\" bottle\"+(i>1?\"s\":\"\");p(i+s+b+c+\", \"+i+s+b+n+(i<2?\"Go to the store and buy some more, 99\":\"Take one down and pass it around, \"+(i-1))+\" bottle\"+(i!=2?\"s\":\"\")+b+c+n);}}}}public static void p(String s){System.out.print(s);}}",a[0]);}}

Rohan Jhunjhunwala

Posted 2016-07-01T00:06:39.937

Reputation: 2 569

3

Mathematica, 453 bytes

"("<>#~StringReplace~{"H"->"Print[\"Hello, world!\"]; ","Q"->"Print[ToString[#0, InputForm]]; ","9"->"a = StringJoin[ToString[#1], {\" bottle\", If[#1 < 2, \"\", \"s\"], \" of beer\"}] & ; b = StringJoin[a[#1], \" on the wall\"] & ; Do[Print[b[i], \", \", a[i], c = \".\n\", If[i < 2, StringJoin[\"Go to the store and buy some more, \", b[99], \".\"], StringJoin[\"Take one down and pass it around, \", b[i - 1], c]]], {i, 99, 1, -1}]; ",_->""}<>") & "&

"99 Bottles" code adapted from @alephalpha's program. Outputs a function that, when run, will print the output. (Could probably still find a less verbose quine method.)

LegionMammal978

Posted 2016-07-01T00:06:39.937

Reputation: 15 731

Looks like you missed the rule change - solutions must compile HQ9+ to the same language as the compiler. – Mego – 2016-07-01T00:51:30.737

@Mego Fixed that – LegionMammal978 – 2016-07-01T01:15:22.003

2

Haskell, 383 bytes

    s#'Q'="putStrLn\""++s++"\"\n"
    s#'H'="putStr\"Hello, World\\n\"\n"
    s#'9'="f\n"
    s#_=""
    c s="o=\" of beer on the wall\"\na 1=\"1 bottle\" \na n=shows n\" bottles\"\nb 1=\"Go to the store and buy some more, \"++a 99\nb n=\"Take one down and pass it around, \"++a(n-1)\nf=putStr$[99,98..1]>>= \\n->[a n,o,\", \",a n,\" of beer.\\n\",b n,o,\".\\n\\n\"]>>=id\nmain=do\n"++(concat.map(s#)$s)

Thanks to nimi for the beer.

Sample outout

o=" of beer on the wall"
a 1="1 bottle" 
a n=shows n" bottles"
b 1="Go to the store and buy some more, "++a 99
b n="Take one down and pass it around, "++a(n-1)
f=putStr$[99,98..1]>>= \n->[a n,o,", ",a n," of beer.\n",b n,o,".\n\n"]>>=id
main=do
putStr"Hello, World\n"
putStrLn"HQ9+"
f

ankh-morpork

Posted 2016-07-01T00:06:39.937

Reputation: 1 350

1

Dyalog APL, 244

H P
h←'''hello, world'''
q←M,(P/⍨1+P=M),M←''''
n←'∊{z←8↑k←'' of beer on the wall''⋄r←{r←'' bottles''↑⍨8-⍵=1⋄⍵=0:''No'',r⋄r,⍨⍕⍵}⋄m,k,g,(m←r⍵),z,g,''Take one down and pass it around'',z,g,(r⍵-1),k,g,g←3⌷⎕tc}¨⌽⍳99'
⎕FX'F',h h q q n''['HhQq9'⍳P]

This is a tfn H, which takes a HQ9+ program as its input and defines in the workspace a tfn F, which runs that program.

Example:

      H 'QhqH' ⍝ compile 'QhqH'
      F ⍝ run compiled function F
QhqH
hello, world
QhqH
hello, world
      ⎕CR 'F' ⍝ source code for function F
 F             
 'QhqH'        
 'hello, world'
 'QhqH'        
 'hello, world'

marinus

Posted 2016-07-01T00:06:39.937

Reputation: 30 224