Execute HQ9+: Difference between revisions
Content added Content deleted
Childishbeat (talk | contribs) m (→{{header|NS-HUBASIC}}: A bug resulting in the user getting an ?NF ERROR if an invalid command is in the HQ9+ code has been fixed.) |
Thundergnat (talk | contribs) (Rename Perl 6 -> Raku, alphabetize, minor clean-up) |
||
Line 185: | Line 185: | ||
270 NEXT B |
270 NEXT B |
||
280 NEXT I</lang> |
280 NEXT I</lang> |
||
=={{header|x86 Assembly}}== |
|||
<lang X86 Assembly> |
|||
;ds:si: pointer to asciiz string containing HQ9++ source code |
|||
ExecuteHQ9: |
|||
push ax |
|||
push dx |
|||
push si |
|||
push di |
|||
push es |
|||
push bx |
|||
mov bx, si |
|||
.interpret: |
|||
lodsb |
|||
cmp al, 'H' |
|||
je .doHelloWorld |
|||
cmp al, 'Q' |
|||
je .doPrintCode |
|||
cmp al, '9' |
|||
je .doDrinkBeer |
|||
cmp al, '+' |
|||
je .doCounter |
|||
pop bx |
|||
pop es |
|||
pop di |
|||
pop si |
|||
pop dx |
|||
pop ax |
|||
ret |
|||
.doHelloWorld: |
|||
push ds |
|||
mov ax, cs |
|||
mov ds, ax |
|||
push si |
|||
mov si, .dataHelloWorld |
|||
call .printString |
|||
pop si |
|||
pop ds |
|||
jmp .interpret |
|||
.doPrintCode: |
|||
push si |
|||
mov si, bx |
|||
call .printString |
|||
pop si |
|||
jmp .interpret |
|||
.doDrinkBeer: |
|||
push ds |
|||
push si |
|||
push ax |
|||
mov ax, cs |
|||
mov ds, ax |
|||
mov ax, 99 |
|||
.beer_loop: |
|||
call .printHexNumber |
|||
mov si, .dataBeerSong1 |
|||
call .printString |
|||
call .printHexNumber |
|||
mov si, .dataBeerSong2 |
|||
call .printString |
|||
dec ax |
|||
call .printHexNumber |
|||
mov si, .dataBeerSong3 |
|||
call .printString |
|||
test ax, ax |
|||
jnz .beer_loop |
|||
pop ax |
|||
pop si |
|||
pop ds |
|||
jmp .interpret |
|||
.doCounter: |
|||
push ax |
|||
inc ax |
|||
pop ax |
|||
jmp .interpret |
|||
.printString: |
|||
push ax |
|||
push si |
|||
.looping: |
|||
lodsb |
|||
test al, al |
|||
jz .done |
|||
mov ah, 0Eh |
|||
int 10h |
|||
jmp .looping |
|||
.done: |
|||
pop si |
|||
pop ax |
|||
ret |
|||
.printHexNumber: |
|||
pusha |
|||
push ds |
|||
mov ax, cs |
|||
mov ds, ax |
|||
push word 0 |
|||
mov bx, ax |
|||
xor dx, dx |
|||
mov cx, 4r |
|||
.convert_loop: |
|||
mov ax, bx |
|||
and ax, 0Fh |
|||
cmp ax, 9 |
|||
ja .greater_than_9 |
|||
add ax, '0' |
|||
jmp .converted |
|||
.greater_than_9: |
|||
add ax, 'A'-0Ah |
|||
.converted: |
|||
push ax |
|||
shr bx, 4 |
|||
dec cx |
|||
jnz .convert_loop |
|||
.popoff: |
|||
pop ax |
|||
cmp ax, 0 |
|||
je .done |
|||
mov ah, 0Eh |
|||
int 10h |
|||
jmp .popoff |
|||
.done: |
|||
pop ds |
|||
popa |
|||
ret |
|||
.dataHelloWorld: db "Hello World!", 0 |
|||
.dataBeerSong1: db " bottles of beer on the wall ", 0 |
|||
.dataBeerSong2: db " bottles of beer", 13, 10, "Take one down, pass it around " |
|||
.dataBeerSong3: db 0, " bottles of beer on the wall", 0 |
|||
</lang> |
|||
=={{header|AutoHotkey}}== |
=={{header|AutoHotkey}}== |
||
Line 351: | Line 215: | ||
Return output |
Return output |
||
}</lang> |
}</lang> |
||
=={{header|BASIC256}}== |
=={{header|BASIC256}}== |
||
Line 402: | Line 265: | ||
end |
end |
||
</lang> |
</lang> |
||
=={{header|BBC BASIC}}== |
=={{header|BBC BASIC}}== |
||
Line 485: | Line 347: | ||
} |
} |
||
};</lang> |
};</lang> |
||
=={{header|C sharp}}== |
|||
<lang csharp> |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
class Program |
|||
{ |
|||
static void RunCode(string code) |
|||
{ |
|||
int accumulator = 0; |
|||
var opcodes = new Dictionary<char, Action> |
|||
{ |
|||
{'H', () => Console.WriteLine("Hello, World!"))}, |
|||
{'Q', () => Console.WriteLine(code) }, |
|||
{'9', () => Console.WriteLine(Enumerable.Range(1,100).Reverse().Select(n => string.Format("{0} bottles of beer on the wall\n{0} bottles of beer\nTake one down, pass it around\n{1} bottles of beer on the wall\n", n, n-1)).Aggregate((a,b) => a + "\n" + b))}, |
|||
{'+', () => accumulator++ } |
|||
} |
|||
foreach(var c in code) |
|||
opcodes[c](); |
|||
} |
|||
} |
|||
</lang> |
|||
=={{header|C++}}== |
=={{header|C++}}== |
||
Line 523: | Line 411: | ||
} |
} |
||
};</lang> |
};</lang> |
||
=={{header|C sharp}}== |
|||
<lang csharp> |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
class Program |
|||
{ |
|||
static void RunCode(string code) |
|||
{ |
|||
int accumulator = 0; |
|||
var opcodes = new Dictionary<char, Action> |
|||
{ |
|||
{'H', () => Console.WriteLine("Hello, World!"))}, |
|||
{'Q', () => Console.WriteLine(code) }, |
|||
{'9', () => Console.WriteLine(Enumerable.Range(1,100).Reverse().Select(n => string.Format("{0} bottles of beer on the wall\n{0} bottles of beer\nTake one down, pass it around\n{1} bottles of beer on the wall\n", n, n-1)).Aggregate((a,b) => a + "\n" + b))}, |
|||
{'+', () => accumulator++ } |
|||
} |
|||
foreach(var c in code) |
|||
opcodes[c](); |
|||
} |
|||
} |
|||
</lang> |
|||
=={{header|Ceylon}}== |
=={{header|Ceylon}}== |
||
Line 1,022: | Line 884: | ||
Go to the store, buy some more. |
Go to the store, buy some more. |
||
</pre> |
</pre> |
||
=={{header|FreeBASIC}}== |
=={{header|FreeBASIC}}== |
||
Line 1,077: | Line 938: | ||
End |
End |
||
</lang> |
</lang> |
||
=={{header|Go}}== |
=={{header|Go}}== |
||
Line 1,152: | Line 1,012: | ||
return out; |
return out; |
||
}</lang> |
}</lang> |
||
=={{header|Inform 7}}== |
|||
<lang inform7>HQ9+ is a room. |
|||
After reading a command: |
|||
interpret the player's command; |
|||
reject the player's command. |
|||
To interpret (code - indexed text): |
|||
let accumulator be 0; |
|||
repeat with N running from 1 to the number of characters in code: |
|||
let C be character number N in code in upper case; |
|||
if C is "H": |
|||
say "Hello, world!"; |
|||
otherwise if C is "Q": |
|||
say "[code][line break]"; |
|||
otherwise if C is "9": |
|||
repeat with iteration running from 1 to 99: |
|||
let M be 100 - iteration; |
|||
say "[M] bottle[s] of beer on the wall[line break]"; |
|||
say "[M] bottle[s] of beer[line break]"; |
|||
say "Take one down, pass it around[line break]"; |
|||
say "[M - 1] bottle[s] of beer on the wall[paragraph break]"; |
|||
otherwise if C is "+": |
|||
increase accumulator by 1.</lang> |
|||
=={{header|Icon}} and {{header|Unicon}}== |
=={{header|Icon}} and {{header|Unicon}}== |
||
Line 1,208: | Line 1,042: | ||
return |
return |
||
end</lang> |
end</lang> |
||
=={{header|Inform 7}}== |
|||
<lang inform7>HQ9+ is a room. |
|||
After reading a command: |
|||
interpret the player's command; |
|||
reject the player's command. |
|||
To interpret (code - indexed text): |
|||
let accumulator be 0; |
|||
repeat with N running from 1 to the number of characters in code: |
|||
let C be character number N in code in upper case; |
|||
if C is "H": |
|||
say "Hello, world!"; |
|||
otherwise if C is "Q": |
|||
say "[code][line break]"; |
|||
otherwise if C is "9": |
|||
repeat with iteration running from 1 to 99: |
|||
let M be 100 - iteration; |
|||
say "[M] bottle[s] of beer on the wall[line break]"; |
|||
say "[M] bottle[s] of beer[line break]"; |
|||
say "Take one down, pass it around[line break]"; |
|||
say "[M - 1] bottle[s] of beer on the wall[paragraph break]"; |
|||
otherwise if C is "+": |
|||
increase accumulator by 1.</lang> |
|||
=={{header|J}}== |
=={{header|J}}== |
||
Line 1,677: | Line 1,538: | ||
return 'Take one down and pass it around' if $n > 0; |
return 'Take one down and pass it around' if $n > 0; |
||
return 'Go to the store and buy some more'; |
return 'Go to the store and buy some more'; |
||
}</lang> |
|||
=={{header|Perl 6}}== |
|||
{{works with|rakudo|2015-09-10}} |
|||
The spec is kind of vague about how to do error handling... and whether white space is significant... and how the accumulator should be accessed... and pretty much everything else too. |
|||
<lang perl6>class HQ9Interpreter { |
|||
has @!code; |
|||
has $!accumulator; |
|||
has $!pointer; |
|||
method run ($code) { |
|||
@!code = $code.comb; |
|||
$!accumulator = 0; |
|||
$!pointer = 0; |
|||
while $!pointer < @!code { |
|||
given @!code[$!pointer].lc { |
|||
when 'h' { say 'Hello world!' } |
|||
when 'q' { say @!code } |
|||
when '9' { bob(99) } |
|||
when '+' { $!accumulator++ } |
|||
default { note "Syntax error: Unknown command \"{@!code[$!pointer]}\"" } |
|||
} |
|||
$!pointer++; |
|||
} |
|||
} |
|||
sub bob ($beer is copy) { |
|||
sub what { "{$beer??$beer!!'No more'} bottle{$beer-1??'s'!!''} of beer" }; |
|||
sub where { 'on the wall' }; |
|||
sub drink { $beer--; "Take one down, pass it around," } |
|||
while $beer { |
|||
.say for "&what() &where(),", "&what()!", |
|||
"&drink()", "&what() &where()!", '' |
|||
} |
|||
} |
|||
} |
|||
# Feed it a command string: |
|||
my $hq9 = HQ9Interpreter.new; |
|||
$hq9.run("hHq+++Qq"); |
|||
say ''; |
|||
$hq9.run("Jhq.k+hQ");</lang> |
|||
Output: |
|||
<pre> |
|||
Hello world! |
|||
Hello world! |
|||
hHq+++Qq |
|||
hHq+++Qq |
|||
hHq+++Qq |
|||
Syntax error: Unknown command "J" |
|||
Hello world! |
|||
Jhq.k+hQ |
|||
Syntax error: Unknown command "." |
|||
Syntax error: Unknown command "k" |
|||
Hello world! |
|||
Jhq.k+hQ |
|||
</pre> |
|||
Or start a REPL (Read Execute Print Loop) and interact at the command line: |
|||
<lang perl6>my $hq9 = HQ9Interpreter.new; |
|||
while 1 { |
|||
my $in = prompt('HQ9+>').chomp; |
|||
last unless $in.chars; |
|||
$hq9.run($in) |
|||
}</lang> |
}</lang> |
||
Line 1,988: | Line 1,782: | ||
;;; you can jolly well read (and sing along to) the output of '9' |
;;; you can jolly well read (and sing along to) the output of '9' |
||
)</lang> |
)</lang> |
||
=={{header|Raku}}== |
|||
(formerly Perl 6) |
|||
{{works with|rakudo|2015-09-10}} |
|||
The spec is kind of vague about how to do error handling... and whether white space is significant... and how the accumulator should be accessed... and pretty much everything else too. |
|||
<lang perl6>class HQ9Interpreter { |
|||
has @!code; |
|||
has $!accumulator; |
|||
has $!pointer; |
|||
method run ($code) { |
|||
@!code = $code.comb; |
|||
$!accumulator = 0; |
|||
$!pointer = 0; |
|||
while $!pointer < @!code { |
|||
given @!code[$!pointer].lc { |
|||
when 'h' { say 'Hello world!' } |
|||
when 'q' { say @!code } |
|||
when '9' { bob(99) } |
|||
when '+' { $!accumulator++ } |
|||
default { note "Syntax error: Unknown command \"{@!code[$!pointer]}\"" } |
|||
} |
|||
$!pointer++; |
|||
} |
|||
} |
|||
sub bob ($beer is copy) { |
|||
sub what { "{$beer??$beer!!'No more'} bottle{$beer-1??'s'!!''} of beer" }; |
|||
sub where { 'on the wall' }; |
|||
sub drink { $beer--; "Take one down, pass it around," } |
|||
while $beer { |
|||
.say for "&what() &where(),", "&what()!", |
|||
"&drink()", "&what() &where()!", '' |
|||
} |
|||
} |
|||
} |
|||
# Feed it a command string: |
|||
my $hq9 = HQ9Interpreter.new; |
|||
$hq9.run("hHq+++Qq"); |
|||
say ''; |
|||
$hq9.run("Jhq.k+hQ");</lang> |
|||
Output: |
|||
<pre> |
|||
Hello world! |
|||
Hello world! |
|||
hHq+++Qq |
|||
hHq+++Qq |
|||
hHq+++Qq |
|||
Syntax error: Unknown command "J" |
|||
Hello world! |
|||
Jhq.k+hQ |
|||
Syntax error: Unknown command "." |
|||
Syntax error: Unknown command "k" |
|||
Hello world! |
|||
Jhq.k+hQ |
|||
</pre> |
|||
Or start a REPL (Read Execute Print Loop) and interact at the command line: |
|||
<lang perl6>my $hq9 = HQ9Interpreter.new; |
|||
while 1 { |
|||
my $in = prompt('HQ9+>').chomp; |
|||
last unless $in.chars; |
|||
$hq9.run($in) |
|||
}</lang> |
|||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
Line 2,086: | Line 1,948: | ||
See [[RCHQ9+/Ruby]]. |
See [[RCHQ9+/Ruby]]. |
||
=={{header|Rust}}== |
=={{header|Rust}}== |
||
Line 2,260: | Line 2,121: | ||
See [[RCHQ9+/Ursala]]. |
See [[RCHQ9+/Ursala]]. |
||
=={{header|x86 Assembly}}== |
|||
<lang X86 Assembly> |
|||
;ds:si: pointer to asciiz string containing HQ9++ source code |
|||
ExecuteHQ9: |
|||
push ax |
|||
push dx |
|||
push si |
|||
push di |
|||
push es |
|||
push bx |
|||
mov bx, si |
|||
.interpret: |
|||
lodsb |
|||
cmp al, 'H' |
|||
je .doHelloWorld |
|||
cmp al, 'Q' |
|||
je .doPrintCode |
|||
cmp al, '9' |
|||
je .doDrinkBeer |
|||
cmp al, '+' |
|||
je .doCounter |
|||
pop bx |
|||
pop es |
|||
pop di |
|||
pop si |
|||
pop dx |
|||
pop ax |
|||
ret |
|||
.doHelloWorld: |
|||
push ds |
|||
mov ax, cs |
|||
mov ds, ax |
|||
push si |
|||
mov si, .dataHelloWorld |
|||
call .printString |
|||
pop si |
|||
pop ds |
|||
jmp .interpret |
|||
.doPrintCode: |
|||
push si |
|||
mov si, bx |
|||
call .printString |
|||
pop si |
|||
jmp .interpret |
|||
.doDrinkBeer: |
|||
push ds |
|||
push si |
|||
push ax |
|||
mov ax, cs |
|||
mov ds, ax |
|||
mov ax, 99 |
|||
.beer_loop: |
|||
call .printHexNumber |
|||
mov si, .dataBeerSong1 |
|||
call .printString |
|||
call .printHexNumber |
|||
mov si, .dataBeerSong2 |
|||
call .printString |
|||
dec ax |
|||
call .printHexNumber |
|||
mov si, .dataBeerSong3 |
|||
call .printString |
|||
test ax, ax |
|||
jnz .beer_loop |
|||
pop ax |
|||
pop si |
|||
pop ds |
|||
jmp .interpret |
|||
.doCounter: |
|||
push ax |
|||
inc ax |
|||
pop ax |
|||
jmp .interpret |
|||
.printString: |
|||
push ax |
|||
push si |
|||
.looping: |
|||
lodsb |
|||
test al, al |
|||
jz .done |
|||
mov ah, 0Eh |
|||
int 10h |
|||
jmp .looping |
|||
.done: |
|||
pop si |
|||
pop ax |
|||
ret |
|||
.printHexNumber: |
|||
pusha |
|||
push ds |
|||
mov ax, cs |
|||
mov ds, ax |
|||
push word 0 |
|||
mov bx, ax |
|||
xor dx, dx |
|||
mov cx, 4r |
|||
.convert_loop: |
|||
mov ax, bx |
|||
and ax, 0Fh |
|||
cmp ax, 9 |
|||
ja .greater_than_9 |
|||
add ax, '0' |
|||
jmp .converted |
|||
.greater_than_9: |
|||
add ax, 'A'-0Ah |
|||
.converted: |
|||
push ax |
|||
shr bx, 4 |
|||
dec cx |
|||
jnz .convert_loop |
|||
.popoff: |
|||
pop ax |
|||
cmp ax, 0 |
|||
je .done |
|||
mov ah, 0Eh |
|||
int 10h |
|||
jmp .popoff |
|||
.done: |
|||
pop ds |
|||
popa |
|||
ret |
|||
.dataHelloWorld: db "Hello World!", 0 |
|||
.dataBeerSong1: db " bottles of beer on the wall ", 0 |
|||
.dataBeerSong2: db " bottles of beer", 13, 10, "Take one down, pass it around " |
|||
.dataBeerSong3: db 0, " bottles of beer on the wall", 0 |
|||
</lang> |
|||
=={{header|XSLT}}== |
=={{header|XSLT}}== |