Print itself: Difference between revisions

From Rosetta Code
Content added Content deleted
m (added output and fixed formatting)
m (→‎{{header|Z80 Assembly}}: displayed bytecode alongside assembly)
Line 176: Line 176:
=={{header|Z80 Assembly}}==
=={{header|Z80 Assembly}}==
This program prints its bytecode as text to the Amstrad CPC terminal. The program is run by typing <code>call &1000</code> to the screen.
This program prints its bytecode as text to the Amstrad CPC terminal. The program is run by typing <code>call &1000</code> to the screen.
<pre>WinAPE Z80 Assembler V1.0.13
<lang z80>org &1001


ld hl,&1001 ;&1000 won't work since that contains &00.
000001 0000 (1001) org &1001
000003 1001 21 01 10 ld hl,&1001
ld e,&ff ;&00 is the terminator so we can't use zero as an immediate directly
000004 1004 1E FF ld e,&ff ;0 is the terminator so we can't use zero as an immediate directly
inc e ;Must abuse 8-bit underflow to get it.
000005 1006 1C inc e ;we have to abuse 8-bit underflow to get it.
loop:
000006 1007 loop
ld a,(hl)
000007 1007 7E ld a,(hl)
cp e
000008 1008 BB cp e
jp z,ProgramEnd
000009 1009 CA 2B 10 jp z,ProgramEnd

call UnpackNibbles
000011 100C CD 36 10 call UnpackNibbles
000012 100F 78 ld a,b
ld a,b
000013 1010 FE 0A cp &0A
cp &0A
jr c,noCorrectHex_B
000014 1012 38 02 jr c,noCorrectHex_B
000015 1014 C6 07 add &07
add &07
noCorrectHex_B:
000016 1016 noCorrectHex_B
000017 1016 C6 30 add &30
add &30
call &bb5a
000018 1018 CD 5A BB call &bb5a
000020 101B 79 ld a,c

000021 101C FE 0A cp &0A
ld a,c
000022 101E 38 02 jr c,noCorrectHex_C
cp &0A
000023 1020 C6 07 add &07
jr c,noCorrectHex_C
000024 1022 noCorrectHex_C
add &07
000025 1022 C6 30 add &30
noCorrectHex_C:
000026 1024 CD 5A BB call &bb5a
add &30
000027 1027 23 inc hl
call &bb5a
000028 1028 C3 07 10 jp loop
inc hl
000029 102B ProgramEnd
jp loop
000030 102B 3E 30 ld a,&30
ProgramEnd:
000031 102D CD 5A BB call &bb5a
ld a,&30
000032 1030 3E 30 ld a,&30
call &bb5a
000033 1032 CD 5A BB call &bb5a
ld a,&30
000034 1035 C9 ret ;return to basic
call &bb5a
000037 1036 UnpackNibbles
ret ;return to basic
000038 1036 ;splits a into its component nibbles, storing high nibble in B and low in C.

000039 1036 F5 push af

000040 1037 E6 0F and &0f
UnpackNibbles:
000041 1039 4F ld c,a
;splits a into its component nibbles, storing high nibble in B and low in C.
000042 103A F1 pop af
push af
000043 103B E6 F0 and &f0
and &0f
000044 103D 0F rrca
ld c,a
000045 103E 0F rrca
pop af
000046 103F 0F rrca
and &f0
000047 1040 0F rrca
rrca
000048 1041 47 ld b,a
rrca
000049 1042 C9 ret
rrca
000051 1043 00 db 0 ;this must be the only instance of 00 in the bytecode for this to work.
rrca
</pre>
ld b,a
ret

db 0 ;null terminator. No instructions or operands above compile to &00. </lang>
{{out}}
{{out}}
[https://ibb.co/KbzjpNQ Output on WinAPE]
[https://ibb.co/KbzjpNQ Output on WinAPE]

Revision as of 00:47, 28 September 2021

Print itself is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Create a program, which prints its source code to the stdout!

Related tasks


11l

<lang 11l>

start:

-V sourceFileName = fs:path:split_ext(:argv[0])[0]‘.11l’ print(File(sourceFileName).read()) </lang>

Batch File

<lang dos> @echo off for /f "tokens=*" %%s in (%~n0%~x0) do (echo %%s) </lang>

FreeBASIC

This works for Linux. <lang freebasic>shell( "cat quine.bas" )</lang>

Furor

<lang Furor> 1 argv getfile dup sprint free end </lang>

Go

<lang go>package main

import (

   "fmt"
   "io/ioutil"
   "log"
   "os"
   "path"

)

func main() {

   self := path.Base(os.Args[0]) + ".go"
   bytes, err := ioutil.ReadFile(self)
   if err != nil {
       log.Fatal(err)
   }
   fmt.Print(string(bytes))

}</lang>

Output:

Just the invoking line as remainder is, of course, as above.

$ go run self_print.go

Julia

The running program's filename is referenced as the builtin PROGRAM_FILE variable in Julia. <lang julia>""" Read the program file and print it. """ printitself() = print(read(PROGRAM_FILE, String))

printitself() </lang>

Nanoquery

<lang Nanoquery>println new(Nanoquery.IO.File).open(args[1]).readAll()</lang>

Nim

We suppose that the source file is in the same directory as the executable file. <lang Nim>import os

let execFile = getAppFilename() let sourceFile = execFile.addFileExt("nim") stdout.write sourceFile.readFile()</lang>

Perl

<lang Perl># 20201011 added Perl programming solution

use strict; use warnings;

open my $in, '<', $0 or die; print while <$in>; close($in)

  1. @ARGV=$0; print <> # slurp without an explicit open()</lang>

Phix

Interpreted only: <lang Phix>puts(1,get_text(command_line()[2]))</lang>

Output:
puts(1,get_text(command_line()[2]))

Interpreted or compiled - latter only works while executable and source are still in the same directory, and not renamed. <lang Phix>puts(1,get_text(substitute(command_line()[2],".exe",".exw")))</lang>

Output:
>p test ;; or p -c test
puts(1,get_text(substitute(command_line()[2],".exe",".exw")))

Alternative - see the docs (ie phix.chm) for an explanation of the ("") and [1][2]: <lang Phix>?get_text(include_path("")&include_files()[1][2])</lang>

Output:
"?get_text(include_path("")&include_files()[1][2])"

PowerShell

<lang PowerShell> Write-Host $MyInvocation.MyCommand </lang>

Python

Works with: python3

<lang python>import sys with open(sys.argv[0],'r') as input:

   for row in input:
       print(row, end=)</lang>

Raku

Works with: Rakudo version 2020.05

Not really sure what the point of this task is.

Is it supposed to be a quine? <lang perl6>my &f = {say $^s, $^s.raku;}; f "my \&f = \{say \$^s, \$^s.raku;}; f " </lang>

Or just a program that when executed echoes its source to STDOUT? (Here's probably the simplest valid program that when executed, echoes its source to STDOUT. It is exceptionally short: zero bytes; and when executed echoes zero bytes to STDOUT.)

<lang perl6></lang>

Or are we supposed to demonstrate how to locate the currently executing source code file and incidentally, print it.

<lang perl6>print $*PROGRAM.slurp</lang>

Whatever. Any of these satisfy the rather vague specifications.

REXX

<lang rexx>/*REXX program prints its own multi─line source to the standard output (stdout). */

   do j=1  for sourceline()
   call lineout , sourceline(j)
   end   /*j*/                                  /*stick a fork in it,  we're all done. */</lang>

Ring

<lang ring> fileName = filename() fp = fopen(fileName,"r") ? read(filename()) fclose(fp) </lang>

Output:
fileName = filename()
fp = fopen(fileName,"r")
? read(filename())
fclose(fp)

Wren

<lang ecmascript>import "os" for Process import "io" for File

var args = Process.allArguments System.write(File.read(args[1]))</lang>

Output:

Just the invoking line as remainder is, of course, as above.

$ wren self_print.wren

Z80 Assembly

This program prints its bytecode as text to the Amstrad CPC terminal. The program is run by typing call &1000 to the screen.

WinAPE Z80 Assembler V1.0.13

000001  0000  (1001)        org &1001
000003  1001  21 01 10      ld hl,&1001
000004  1004  1E FF         ld e,&ff    ;0 is the terminator so we can't use zero as an immediate directly
000005  1006  1C            inc e       ;we have to abuse 8-bit underflow to get it.
000006  1007                loop
000007  1007  7E            ld a,(hl)
000008  1008  BB            cp e
000009  1009  CA 2B 10      jp z,ProgramEnd
000011  100C  CD 36 10      call UnpackNibbles
000012  100F  78            ld a,b
000013  1010  FE 0A         cp &0A
000014  1012  38 02         jr c,noCorrectHex_B
000015  1014  C6 07         add &07
000016  1016                noCorrectHex_B
000017  1016  C6 30         add &30
000018  1018  CD 5A BB      call &bb5a
000020  101B  79            ld a,c
000021  101C  FE 0A         cp &0A
000022  101E  38 02         jr c,noCorrectHex_C
000023  1020  C6 07         add &07
000024  1022                noCorrectHex_C
000025  1022  C6 30         add &30
000026  1024  CD 5A BB      call &bb5a
000027  1027  23            inc hl
000028  1028  C3 07 10      jp loop
000029  102B                ProgramEnd
000030  102B  3E 30         ld a,&30
000031  102D  CD 5A BB      call &bb5a
000032  1030  3E 30         ld a,&30
000033  1032  CD 5A BB      call &bb5a
000034  1035  C9            ret		;return to basic
000037  1036                UnpackNibbles
000038  1036                ;splits a into its component nibbles, storing high nibble in B and low in C.
000039  1036  F5            push af
000040  1037  E6 0F         and &0f
000041  1039  4F            ld c,a
000042  103A  F1            pop af
000043  103B  E6 F0         and &f0
000044  103D  0F            rrca
000045  103E  0F            rrca
000046  103F  0F            rrca
000047  1040  0F            rrca
000048  1041  47            ld b,a
000049  1042  C9            ret
000051  1043  00            db 0         ;this must be the only instance of 00 in the bytecode for this to work.
Output:

Output on WinAPE