Execute HQ9+: Difference between revisions

Rename Perl 6 -> Raku, alphabetize, minor clean-up
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.)
(Rename Perl 6 -> Raku, alphabetize, minor clean-up)
Line 185:
270 NEXT B
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}}==
Line 351 ⟶ 215:
Return output
}</lang>
 
 
=={{header|BASIC256}}==
Line 402 ⟶ 265:
end
</lang>
 
 
=={{header|BBC BASIC}}==
Line 485 ⟶ 347:
}
};</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++}}==
Line 523 ⟶ 411:
}
};</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}}==
Line 1,022 ⟶ 884:
Go to the store, buy some more.
</pre>
 
 
=={{header|FreeBASIC}}==
Line 1,077 ⟶ 938:
End
</lang>
 
 
=={{header|Go}}==
Line 1,152 ⟶ 1,012:
return out;
}</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}}==
Line 1,208 ⟶ 1,042:
return
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}}==
 
Line 1,677 ⟶ 1,538:
return 'Take one down and pass it around' if $n > 0;
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>
 
Line 1,988 ⟶ 1,782:
;;; you can jolly well read (and sing along to) the output of '9'
)</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}}==
Line 2,086 ⟶ 1,948:
 
See [[RCHQ9+/Ruby]].
 
 
=={{header|Rust}}==
Line 2,260 ⟶ 2,121:
 
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}}==
10,327

edits