Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add quine for QB64 #29

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions QB64/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
## Files
To compile the source, you need the QB64 Phoenix Edition, which can be found [here](https://github.com/QB64-Phoenix-Edition/QB64pe).

There are 6 files in this directory
* quine2.bas - The complete quine, which reproduces itself.
* quine2raw.bas - This is the original program without itself attached as data statements.
* dataconvert.bas - The program that reads another program and trranslates it to decimal data.
* Common_Dialog_Prefix.bi - Support values for dataconvert to use the Windows File Open dialog window.
* Common_Dialog_Suffix.bi - Support SUBroutines for dataconvert to use the Windows File Open dialog window.
* README.md - You're reading it now.

## How to use
* Start QB64 Phoenix Edition. The IDE will appear.
* Open **quine2.bas**.
* Run the program. It will generate an on-screen listing of itself which looks exactly like the copy you have in the ide.

## How this is created
To recreate the quine,
* Start QB64 Phoenix Edition. The IDE will appear.
* Open **dataconvert.bas** using QB64 Phoenix Edition IDE.
* Run the **dataconvert** program.*
* For input to the Windows Open Dialog Box, give it the name of the original file, **quine2raw.bas**.
* In the console output window, a series of **data** statements will be generated. Copy them by using the mouse to select all the text, then press enter to copy. (Note: right-clicking on the hightlighted area with the mouse will not work.)
* Now, open **quine2raw.bas** in the IDE, at the end, paste the data statements. Add **,0** to the end of the last line to indicate end of file.
* Save As a different name, e.g. **quine2new.bas**.
* Run this program, and it produces a copy of itself. This is the same behavior as **quine2.bas**.
41 changes: 41 additions & 0 deletions QB64/dataconvert.bas
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
$Console:Only
'$Include:'Common_Dialog_Prefix.bi'
ReDim As _Unsigned _Byte Prg(1), L
Dim As Long I, J, K, Size


' Invoke Open Read File dialog
Filter$ = "Basic Programs (*.bas,bi.bm)|*.bas,*.bi,*.bm|All files (*.*)|*.*"
Flags& = OFN_FILEMUSTEXIST + OFN_NOCHANGEDIR + OFN_READONLY ' add flag constants here
F$ = GetOpenFileName$("Select name of Basic/QB64/qb64pe source code file", ".\", Filter$, 1, Flags&, Hwnd&)

If F$ = "" Then
Print "Operation cancelled."
End
End If

Open F$ For Binary Access Read As #1
I = LOF(1)
ReDim Prg(1 To I)
Get #1, , Prg()
Close #1

For J = 1 To I
If L = 0 Then Print "Data ";
Print LTrim$(Str$(Prg(J)));
If J < I Then
L = L + 1
If L = 20 Then
Print
L = 0
Else
Print ",";
End If
Else
Print
End If
Next

End

'$Include:'Common_Dialog_Suffix.bi'
61 changes: 61 additions & 0 deletions QB64/quine2.bas
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
$Console:Only
Option _Explicit
Dim As _Unsigned _Byte Prg(1 To 100000), L
Dim As Long I, J, K

Do
I = I + 1
Read Prg(I)
If Prg(I) = 0 Then Exit Do
Loop


For J = 1 To I
Print Chr$(Prg(J));
Next

For J = 1 To I
If L = 0 Then Print "Data ";
Print LTrim$(Str$(Prg(J)));
If J < I Then
L = L + 1
If L = 20 Then
Print
L = 0
Else
Print ",";
End If
Else
Print
End If
Next

End

Data 36,67,111,110,115,111,108,101,58,79,110,108,121,13,10,79,112,116,105,111
Data 110,32,95,69,120,112,108,105,99,105,116,13,10,68,105,109,32,65,115,32
Data 95,85,110,115,105,103,110,101,100,32,95,66,121,116,101,32,80,114,103,40
Data 49,32,84,111,32,49,48,48,48,48,48,41,44,32,76,13,10,68,105,109
Data 32,65,115,32,76,111,110,103,32,73,44,32,74,44,32,75,13,10,13,10
Data 68,111,13,10,32,32,32,32,73,32,61,32,73,32,43,32,49,13,10,32
Data 32,32,32,82,101,97,100,32,80,114,103,40,73,41,13,10,32,32,32,32
Data 73,102,32,80,114,103,40,73,41,32,61,32,48,32,84,104,101,110,32,69
Data 120,105,116,32,68,111,13,10,76,111,111,112,13,10,13,10,13,10,70,111
Data 114,32,74,32,61,32,49,32,84,111,32,73,13,10,32,32,32,32,80,114
Data 105,110,116,32,67,104,114,36,40,80,114,103,40,74,41,41,59,13,10,78
Data 101,120,116,13,10,13,10,70,111,114,32,74,32,61,32,49,32,84,111,32
Data 73,13,10,32,32,32,32,73,102,32,76,32,61,32,48,32,84,104,101,110
Data 32,80,114,105,110,116,32,34,68,97,116,97,32,34,59,13,10,32,32,32
Data 32,80,114,105,110,116,32,76,84,114,105,109,36,40,83,116,114,36,40,80
Data 114,103,40,74,41,41,41,59,13,10,32,32,32,32,73,102,32,74,32,60
Data 32,73,32,84,104,101,110,13,10,32,32,32,32,32,32,32,32,76,32,61
Data 32,76,32,43,32,49,13,10,32,32,32,32,32,32,32,32,73,102,32,76
Data 32,61,32,50,48,32,84,104,101,110,13,10,32,32,32,32,32,32,32,32
Data 32,32,32,32,80,114,105,110,116,13,10,32,32,32,32,32,32,32,32,32
Data 32,32,32,76,32,61,32,48,13,10,32,32,32,32,32,32,32,32,69,108
Data 115,101,13,10,32,32,32,32,32,32,32,32,32,32,32,32,80,114,105,110
Data 116,32,34,44,34,59,13,10,32,32,32,32,32,32,32,32,69,110,100,32
Data 73,102,13,10,32,32,32,32,69,108,115,101,13,10,32,32,32,32,32,32
Data 32,32,80,114,105,110,116,13,10,32,32,32,32,69,110,100,32,73,102,13
Data 10,78,101,120,116,13,10,13,10,69,110,100,13,10,13,10,0

34 changes: 34 additions & 0 deletions QB64/quine2raw.bas
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
$Console:Only
Option _Explicit
Dim As _Unsigned _Byte Prg(1 To 100000), L
Dim As Long I, J, K

Do
I = I + 1
Read Prg(I)
If Prg(I) = 0 Then Exit Do
Loop


For J = 1 To I
Print Chr$(Prg(J));
Next

For J = 1 To I
If L = 0 Then Print "Data ";
Print LTrim$(Str$(Prg(J)));
If J < I Then
L = L + 1
If L = 20 Then
Print
L = 0
Else
Print ",";
End If
Else
Print
End If
Next

End