Shop OBEX P1 Docs P2 Docs Learn Events
[puzzle] Quine in Spin - Page 2 — Parallax Forums

[puzzle] Quine in Spin

2»

Comments

  • Andrey DemenevAndrey Demenev Posts: 377
    edited 2011-03-19 06:18
    Here's another one

    Produces more readable PASM code
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-03-19 08:11
    Could you please post the source code instead of the binary? Some of us don't have a Prop (or a serial-enabled version of SpinSim) within arm's reach to run the binary. I'm too lazy to get up from my chair to get my prop board that's sitting on a shelf 6 feet away. :)

    Thanks,
    Dave
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2011-03-19 08:31
    Would not it be most challenging to use a decompiler (for high level languages) or disassembler (for assembly) that is sufficient to produce the original source of the author and include enough formatting information, symbol names and locations, and comments as data that is used in the decompilation of the app? Would not this meet the challenge of reproducing the authors original source? For (based on the understanding of a Quine as a challenge) what chalenge is there in simply outputting the source from data and then reproducing the data behind that?

    I can not give my example at this time, as my only 2 Propellers are in continuous use for another test at this time. Thus I am unable to reliably test my code (I have not verified the accuracy of my PASM simulator, nor have I tested out a simulator by any one else, to know the differences from the real Propeller).
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-03-19 08:49
    ...what chalenge is there in simply outputting the source from data and then reproducing the data behind that?
    The challenge, as I see it, is to devise the shortest program that can do that. But, according to this page on quines, they call what you describe a "cheat". I do notice from their examples, however, that facilities like print or printf are treated as an atomic element of many languages, which makes the job much easier.

    -Phil
  • Heater.Heater. Posts: 21,230
    edited 2011-03-19 09:28
    A program may well be able to decompile itself. Perhaps not quite into the source as originally written. Generally there is no way it recreate the formatting or comments. That information is lost during compilation.
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2011-03-19 09:59
    Heater:
    As I stated above the decompiler should be written to use identifiers, comments, and formatting information from the data section of the program, and it would be a purpose specific decompiler, not general purpose.

    Phil:
    Beings that the authors original source would be reproduced, and all information used to due so is contained in the program; How is this a cheat?
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2011-03-19 10:06
    Phil:
    Further the page to witch you link gives examples of interpreted languages, in witch the source and the program are one and the same, using a command of the language with the same meaning as LIST in BASIC. While they say these are not cheats they say that doing so in BASIC is a cheat. So where is the standard? Would a basic program that peeks in memory from where it is being executed and then outputs this be a cheat? After all this is what the BASIC LIST command does (at least with most basic interpreters.
  • Heater.Heater. Posts: 21,230
    edited 2011-03-19 10:27
    David Saunders,
    OK I'll buy that decompiler idea.
    Looking at some of those examples some of them seem to be feindishly short. Perhaps there is room for improvement in Spin.
  • potatoheadpotatohead Posts: 10,261
    edited 2011-03-19 10:35
    This was shown as a cheat:

    10 LIST : REM MER : TSIL 01

    This was not:
    10 READ A$:PRINT 10 A$:PRINT 20 "DATA" A$ 20 DATA READ A$:PRINT 10 A$:PRINT 20 "DATA" A$ 
    
    Neither was this:

    10 DATA "B$='DATA '+CHR$(34)
    20 DATA "FOR J=10 TO 180 STEP 10
    30 DATA "READ A$
    40 DATA PRINT J;B$;A$
    50 DATA "IF J<>90 THEN 170
    60 DATA "RESTORE
    70 DATA "B$=' ' 80 DATA "NEXT J
    90 DATA "END
    100 B$='DATA '+CHR$(34)
    110 FOR J=10 TO 180 STEP 10
    120 READ A$
    130 PRINT J;B$;A$
    140 IF J<>90 THEN 170
    150 RESTORE
    160 B$=' '
    170 NEXT J
    180 END

    This one is interesting to me.

    a$[1]="a$[":a$[2]="]=":a$[3]="q$=chr$(34):for i=1 to 3:?a$[1]str$(i)a $[2]q$ a$q$ chr$(58);:next i:?a$[3]":q$=chr$(34):for i=1 to 3:?a$[ 1]str$(i)a$[2]q$ a$q$ chr$(58);:next i:?a$[3]


    IMHO, including things like "list" uses a reference outside the program to complete the task. I think that's the standard; namely, limiting references to those entities in the program to the highest degree possible. A secondary standard would be the number of references used, where less is more. Finally, "clever", or "off label" uses of the language elements is "interesting", for bonus points.

    Looking the examples over, I see two basic themes. One is where the program contains the data needed to output the program, and that data really is data.

    The other is where the program really is the data, both executed and used as data, where the nature of the program is sufficient to output the program, without using something like "list".
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2011-03-19 10:42
    Patatohead:
    IMHO, including things like "list" uses a reference outside the program to complete the task. I think that's the standard; namely, limiting references to those entities in the program to the highest degree possible. A secondary standard would be the number of references used, where less is more. Finally, "clever", or "off label" uses of the language elements is "interesting", for bonus points.
    So this means that the last example on the page: http://www.nyx.net/~gthompso/self_asm.txt is invalid? It just lists it self from the running copy.
  • potatoheadpotatohead Posts: 10,261
    edited 2011-03-19 10:58
    I don't think it's invalid. Seems to work just the same way the one in BASIC above does, where the program listing is in DATA statements. It's just not a very interesting one, because there is data, and there is the program. The program acts on the data to output itself.

    The more interesting ones are where the data and the program are one and the same, with no discrete block of data that's easy to process.

    And that's subjective, IMHO.

    So is something like "list". Technically, "list" is part of the language, so I would call it valid, but not interesting. A BASIC program that uses peek and poke to read itself, parse, and output itself is far more interesting, because it is far more challenging. Frankly, the number of self-references is another point of interest. The "list" one does not require many, because "list" does most of the work. The program that interprets itself requires far more self-references. That's "interesting", IMHO.

    BTW: A tangent that's probably gonna make a mess is the Propeller COG vs many other CPU's. I find Propeller PASM interesting because every long in the memory space is either program or data. The distinction is up to the programmer. A storage location is just a storage location, and each one is atomic, containing a value that is either instruction or data.

    On many other CPUs, the distinction between program and data is not as pure. A storage location may contain part of a instruction, for example.

    The interesting quines to me, and make no mistake I'm new to these just reading with interest, are those that are "pure" like that, where the data and the program are combined to appear as just a program, not a program that acts on a well defined unit of data.
  • potatoheadpotatohead Posts: 10,261
    edited 2011-03-19 11:07
    Look at this one!
    Author: Bertram Felgenhauer
    Notes: 80x86 TASM. Basically, the program reads it's own code/data segment and converts it
    to decimal numbers, seperated by "\nDB ".
    
    MODEL TINY
    .CODE
    .STARTUP
    DB 177
    DB 076
    DB 186
    DB 044
    DB 001
    DB 172
    DB 180
    DB 036
    DB 179
    DB 004
    DB 191
    DB 080
    DB 001
    DB 079
    DB 136
    DB 037
    DB 212
    DB 010
    DB 004
    DB 048
    DB 134
    DB 196
    DB 075
    DB 117
    DB 244
    DB 180
    DB 009
    DB 205
    DB 033
    DB 178
    DB 071
    DB 226
    DB 228
    DB 178
    DB 038
    DB 205
    DB 033
    DB 195
    DB 013
    DB 010
    DB 069
    DB 078
    DB 068
    DB 036
    DB 077
    DB 079
    DB 068
    DB 069
    DB 076
    DB 032
    DB 084
    DB 073
    DB 078
    DB 089
    DB 013
    DB 010
    DB 046
    DB 067
    DB 079
    DB 068
    DB 069
    DB 013
    DB 010
    DB 046
    DB 083
    DB 084
    DB 065
    DB 082
    DB 084
    DB 085
    DB 080
    DB 013
    DB 010
    DB 068
    DB 066
    DB 032
    END
    
    Beautiful! (if it does, in fact output that exact text)

    It is beautiful because it references itself in every way, except for the output function. The only way to get a more self-referencing thing would be to code it for a specific machine, where the output can be displayed, or something with only the code input.

    That's not portable, and because of that, not a significant consideration. STDOUT, printf, etc... are simply necessary things, but for a seriously pure and academic example, IMHO.

    LIST is not a necessary thing, and perhaps that's where the line is on "cheats", and I think I'm just going to factor all that out, and say that if it outputs itself, it's a quine, with there being only interesting quines, and not so interesting ones, with interesting being keyed to the references that exist outside the input, and whether or not the program parses itself, rather than just outputting a formatted copy of itself.

    Both of those increase difficulty, which makes them interesting.
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2011-03-19 11:20
    Ok I see the point of the beauty, I agree that more complex and shorter solutions are much much more interesting.

    My quine for the prop (witch I shall post once I have a free Propeller on witch to test it) uses a very similar method to the x86 asm one mentioned above. Of course it uses LONG instead of DB and has to reproduce the SPIN loader code (as it is meant to run by it self on a propeller). As such I am trying to assure my self that this is a valid quine, especially as other self referrals are often considered invalid, even when they do not rely on an external file in any way shape or form.

    I should note that I wrote it before seeing the above code, it is just the most sensible method for doing such a thing in a pure way.
  • potatoheadpotatohead Posts: 10,261
    edited 2011-03-19 11:23
    Yeah, I think it's valid. And the SPIN portion increases the overall difficulty. The pure assembly example above is not as difficult as one on the Prop will be, because the listing is less uniform, which presents a challenge in terms of overall size.

    The nature of the machine has to be considered.

    Edit: I just noticed you did cite the LAST example. I had looked at some of the earlier ones. Sorry, if that came across goofy.
  • Andrey DemenevAndrey Demenev Posts: 377
    edited 2011-03-19 23:41
    Here is my self-disassembling version. I wonder if someone can come up with something smaller, but more clever than just a bunch of LONG's :)
    CON _CLKMODE=XTAL1+PLL16X,_XINFREQ=5000000
    PUB m
    coginit(0, @b,@b)
    DAT
    b
                      MOV     DIRA,                  pinmask                 wr
                      MOV     OUTA,                  pinmask                 wr
                      MOV     pc,                    #b                      wr
                      MOV     opcode_addr,           PAR                     wr
                      SHL     conditions_addr,       #$002                   wr
                      ADD     conditions_addr,       PAR                     wr
                      SHL     operations_addr,       #$002                   wr
                      ADD     operations_addr,       PAR                     wr
                      SHL     flags_str_addr,        #$002                   wr
                      ADD     flags_str_addr,        PAR                     wr
                      SHL     long_str_addr,         #$002                   wr
                      ADD     long_str_addr,         PAR                     wr
                      SHL     byte_str_addr,         #$002                   wr
                      ADD     byte_str_addr,         PAR                     wr
                      SHL     registers_addr,        #$002                   wr
                      ADD     registers_addr,        PAR                     wr
                      MOV     str_address,           #prologue               wr
                      SHL     str_address,           #$002                   wr
                      ADD     str_address,           PAR                     wr
                      JMPRET  idx_str_ret,           #str                    wr
    mainl
                      RDLONG  code_end,              opcode_addr             
                      ADD     opcode_addr,           #$004                   wr
                      MOV     src,                   code_end                wr
                      AND     src,                   #$1FF                   wr
                      SHR     code_end,              #$009                   wr
                      MOV     dst,                   code_end                wr
                      AND     dst,                   #$1FF                   wr
                      SHR     code_end,              #$009                   wr
                      MOV     cond,                  code_end                wr
                      AND     cond,                  #$00F                   wr
                      SHR     code_end,              #$004                   wr
                      MOV     imm,                   code_end                wr
                      AND     imm,                   #$001                   wr
                      SHR     code_end,              #$001                   wr
                      MOV     flags,                 code_end                wr
                      AND     flags,                 #$007                   wr
                      SHR     code_end,              #$003                   wr
                      MOV     tmp,                   pc                      wr
                      JMPRET  find_label_ret,        #find_label             wr
                      AND     str_address,           str_address             nr, wz
        if_z          JMPRET  b,                     #no_label               nr
                      JMPRET  idx_str_ret,           #str                    wr
                      MOV     char,                  #$00A                   wr
                      JMPRET  tx_ret,                #tx                     wr
    no_label
                      MOV     tmp,                   #$004                   wr
                      JMPRET  align_ret,             #align                  wr
                      MOV     tmp,                   cond                    wr
                      MOV     str_address,           conditions_addr         wr
                      JMPRET  idx_str_ret,           #idx_str                wr
                      MOV     tmp,                   #$012                   wr
                      JMPRET  align_ret,             #align                  wr
                      SUB     cond,                  #b                      nr, wz
        if_z          MOV     tmp,                   #b                      wr
        if_z          MOV     flags,                 #$008                   wr
        if_z          JMPRET  b,                     #non_mem                nr
                      MOV     tmp,                   code_end                wr
                      ADD     tmp,                   #$001                   wr
                      SUB     tmp,                   #$004                   nr, wz, wc
        if_nc         ADD     tmp,                   #$003                   wr
        if_nc         JMPRET  b,                     #non_mem                nr
                      AND     flags,                 #$001                   nr, wc
        if_c          ADD     tmp,                   #$003                   wr
                      SHR     flags,                 #$001                   wr
                      ADD     flags,                 #$008                   wr
    non_mem
                      MOV     str_address,           operations_addr         wr
                      JMPRET  idx_str_ret,           #idx_str                wr
                      SUB     cond,                  #b                      nr, wz
        if_z          JMPRET  b,                     #no_oprnds              nr
                      MOV     tmp,                   #$01A                   wr
                      JMPRET  align_ret,             #align                  wr
                      MOV     tmp,                   dst                     wr
                      JMPRET  label_or_binary_ret,   #label_or_binary        wr
                      MOV     char,                  #no_label               wr
                      JMPRET  tx_ret,                #tx                     wr
                      MOV     char,                  #$020                   wr
                      JMPRET  tx_ret,                #tx                     wr
                      MOV     tmp,                   #$031                   wr
                      JMPRET  align_ret,             #align                  wr
                      AND     imm,                   #$001                   nr, wz
        if_nz         MOV     char,                  #$023                   wr
        if_nz         JMPRET  tx_ret,                #tx                     wr
                      MOV     tmp,                   src                     wr
                      JMPRET  label_or_binary_ret,   #label_or_binary_dst    wr
    no_oprnds
                      MOV     tmp,                   #$048                   wr
                      JMPRET  align_ret,             #align                  wr
                      MOV     char,                  #$020                   wr
                      JMPRET  tx_ret,                #tx                     wr
                      MOV     str_address,           flags_str_addr          wr
                      MOV     tmp,                   flags                   wr
                      JMPRET  idx_str_ret,           #idx_str                wr
                      MOV     char,                  #$00A                   wr
                      JMPRET  tx_ret,                #tx                     wr
                      ADD     pc,                    #$001                   wr
                      DJNZ    code_size,             #mainl                  wr
                      MOV     char,                  #$00A                   wr
                      JMPRET  tx_ret,                #tx                     wr
                      MOV     char,                  #$00A                   wr
                      JMPRET  tx_ret,                #tx                     wr
    vars_loop
                      MOV     tmp,                   pc                      wr
                      JMPRET  find_label_ret,        #find_label             wr
                      SUB     str_address,           #b                      nr, wz
        if_z          JMPRET  b,                     #no_var_label           nr
                      JMPRET  idx_str_ret,           #str                    wr
                      MOV     char,                  #$00A                   wr
                      JMPRET  tx_ret,                #tx                     wr
    no_var_label
                      MOV     str_address,           long_str_addr           wr
                      JMPRET  idx_str_ret,           #str                    wr
                      RDLONG  tmp,                   opcode_addr             
                      ADD     opcode_addr,           #$004                   wr
                      MOV     tmp_ctr,               #$008                   wr
                      ROR     tmp,                   #$01C                   wr
                      JMPRET  binary2_ret,           #binary2                wr
                      MOV     char,                  #$00A                   wr
                      JMPRET  tx_ret,                #tx                     wr
                      ADD     pc,                    #$001                   wr
                      DJNZ    vars_size,             #vars_loop              wr
                      MOV     tmp,                   pc                      wr
                      JMPRET  find_label_ret,        #find_label             wr
                      SUB     str_address,           #b                      nr, wz
        if_z          JMPRET  b,                     #print_data             nr
                      JMPRET  idx_str_ret,           #str                    wr
                      MOV     char,                  #$00A                   wr
                      JMPRET  tx_ret,                #tx                     wr
    print_data
                      SHL     data_size,             #$002                   wr
                      MOV     code_end,              #b                      wr
    data_loop
                      SUB     code_end,              #b                      nr, wz
        if_nz         JMPRET  b,                     #comma                  nr
                      MOV     str_address,           byte_str_addr           wr
                      JMPRET  idx_str_ret,           #str                    wr
                      JMPRET  b,                     #bits                   nr
    comma
                      MOV     char,                  #no_label               wr
                      JMPRET  tx_ret,                #tx                     wr
    bits
                      MOV     tmp_ctr,               #$008                   wr
                      RDBYTE  tmp,                   opcode_addr             
                      ADD     opcode_addr,           #$001                   wr
                      SUB     tmp,                   #$020                   nr, wz, wc
        if_c          JMPRET  b,                     #bin                    nr
                      SUB     tmp,                   #$07F                   nr, wz, wc
        if_nc_and_nz  JMPRET  b,                     #bin                    nr
                      MOV     char,                  #$022                   wr
                      JMPRET  tx_ret,                #tx                     wr
                      MOV     char,                  tmp                     wr
                      JMPRET  tx_ret,                #tx                     wr
                      MOV     char,                  #$022                   wr
                      JMPRET  tx_ret,                #tx                     wr
                      JMPRET  b,                     #nxt                    nr
    bin
                      JMPRET  binary2_ret,           #binary                 wr
    nxt
                      SUB     code_end,              #$00F                   nr, wz
        if_z          MOV     char,                  #$00A                   wr
        if_z          JMPRET  tx_ret,                #tx                     wr
                      ADD     code_end,              #$001                   wr
                      AND     code_end,              #$00F                   wr
                      DJNZ    data_size,             #data_loop              wr
                      HUBOP   code_size,             #$001                   wr
                      HUBOP   code_size,             #$003                   nr
    str
                      MOV     tmp,                   #b                      wr
    idx_str
                      TJZ     tmp,                   #done                   nr
    seek_loop
                      RDBYTE  char,                  str_address             wz
                      ADD     str_address,           #$001                   wr
        if_nz         JMPRET  b,                     #seek_loop              nr
                      DJNZ    tmp,                   #seek_loop              wr
    done
                      RDBYTE  char,                  str_address             wz
        if_z          JMPRET  b,                     #idx_str_ret            nr
                      ADD     str_address,           #$001                   wr
                      JMPRET  tx_ret,                #tx                     wr
                      JMPRET  b,                     #done                   nr
    idx_str_ret
                      JMPRET  b,                     #b                      nr
    label_or_binary_dst
                      AND     imm,                   imm                     nr, wz
        if_nz         JMPRET  b,                     #noreg                  nr
    label_or_binary
                      SUB     tmp,                   #$1F0                   nr, wz, wc
        if_c          JMPRET  b,                     #noreg                  nr
                      SUB     tmp,                   #$1FF                   nr, wz, wc
                      MOV     str_address,           registers_addr          wr
                      SUB     tmp,                   #$1F0                   wr
                      JMPRET  idx_str_ret,           #idx_str                wr
                      JMPRET  b,                     #label_or_binary_ret    nr
        if_nc_and_nz  JMPRET  b,                     #noreg                  nr
    noreg
                      JMPRET  find_label_ret,        #find_label             wr
                      SUB     str_address,           #b                      nr, wz
        if_z          JMPRET  b,                     #out_binary             nr
                      JMPRET  idx_str_ret,           #str                    wr
                      JMPRET  b,                     #label_or_binary_ret    nr
    out_binary
                      JMPRET  binary2_ret,           #binary                 wr
    label_or_binary_ret
                      JMPRET  b,                     #b                      nr
    binary
                      MOV     tmp_ctr,               #$003                   wr
                      ROR     tmp,                   #$008                   wr
    binary2
                      MOV     char,                  #$024                   wr
                      JMPRET  tx_ret,                #tx                     wr
    bin_loop
                      MOV     char,                  tmp                     wr
                      ROL     tmp,                   #$004                   wr
                      AND     char,                  #$00F                   wr
                      SUB     char,                  #$009                   nr, wz, wc
        if_nc_and_nz  ADD     char,                  #$037                   wr
        if_c_or_z     ADD     char,                  #$030                   wr
                      JMPRET  tx_ret,                #tx                     wr
                      DJNZ    tmp_ctr,               #bin_loop               wr
    binary2_ret
                      JMPRET  b,                     #b                      nr
    align
                      SUB     tmp,                   position                nr, wz, wc
        if_c_or_z     JMPRET  b,                     #align_ret              nr
                      MOV     char,                  #$020                   wr
                      JMPRET  tx_ret,                #tx                     wr
                      JMPRET  b,                     #align                  nr
    align_ret
                      JMPRET  b,                     #b                      nr
    tx
                      SUB     char,                  #$00A                   nr, wz
        if_z          MOV     position,              #b                      wr
        if_nz         ADD     position,              #$001                   wr
                      OR      char,                  #vars_size              wr
                      SHL     char,                  #$002                   wr
                      OR      char,                  #$001                   wr
                      MOV     bitcount,              #$00B                   wr
                      MOV     timer,                 CNT                     wr
                      ADD     timer,                 bittime                 wr
    tx_loop
                      SHR     char,                  #$001                   wr, wc
                      MUXC    OUTA,                  pinmask                 wr
                      WAITCNT timer,                 bittime                 wr
                      DJNZ    bitcount,              #tx_loop                wr
    tx_ret
                      JMPRET  b,                     #b                      nr
    find_label
                      MOV     str_address,           #vars_end               wr
                      SHL     str_address,           #$002                   wr
                      ADD     str_address,           PAR                     wr
    check_label
                      RDWORD  char,                  str_address             
                      ADD     str_address,           #$002                   wr
                      ROR     char,                  #$00F                   wr
                      AND     char,                  #$001                   nr, wc
        if_c          MOV     str_address,           #b                      wr
        if_c          JMPRET  b,                     #find_label_ret         nr
                      ROL     char,                  #$00F                   wr
                      SUB     char,                  tmp                     nr, wz
        if_z          JMPRET  b,                     #find_label_ret         nr
    skip_label
                      RDBYTE  char,                  str_address             wz
                      ADD     str_address,           #$001                   wr
        if_nz         JMPRET  b,                     #skip_label             nr
                      AND     str_address,           #$001                   nr, wc
        if_c          ADD     str_address,           #$001                   wr
                      JMPRET  b,                     #check_label            nr
    find_label_ret
                      JMPRET  b,                     #b                      nr
    
    
    code_end
    long $00000000
    src
    long $00000000
    dst
    long $00000000
    flags
    long $00000000
    pc
    long $00000000
    cond
    long $00000000
    imm
    long $00000000
    tmp
    long $00000000
    tmp_ctr
    long $00000000
    char
    long $00000000
    str_address
    long $00000000
    bitcount
    long $00000000
    bittime
    long $000002B6
    timer
    long $00000000
    pinmask
    long $40000000
    conditions_addr
    long $000001F5
    operations_addr
    long $00000217
    registers_addr
    long $000001E1
    code_size
    long $000000EC
    data_size
    long $0000016D
    vars_size
    long $0000002C
    flags_str_addr
    long $0000026F
    long_str_addr
    long $00000281
    byte_str_addr
    long $00000283
    opcode_addr
    long $00000000
    position
    long $00000000
    prologue
    long $204E4F43
    long $4B4C435F
    long $45444F4D
    long $4154583D
    long $502B314C
    long $36314C4C
    long $585F2C58
    long $52464E49
    long $353D5145
    long $30303030
    long $500A3030
    long $6D204255
    long $676F630A
    long $74696E69
    long $202C3028
    long $402C6240
    long $440A2962
    long $000A5441
    vars_end
    byte $000,$000,"b",$000,$014,$000,"m","a","i","n","l",$000,",",$000,"n","o"
    byte "_","l","a","b","e","l",$000,$000,"@",$000,"n","o","n","_","m","e"
    byte "m",$000,"@",$000,"n","o","p","_",$000,$000,"S",$000,"n","o","_","o"
    byte "p","r","n","d","s",$000,"b",$000,"v","a","r","s","_","l","o","o"
    byte "p",$000,"i",$000,"n","o","_","v","a","r","_","l","a","b","e","l"
    byte $000,$000,"{",$000,"p","r","i","n","t","_","d","a","t","a",$000,$000
    byte "}",$000,"d","a","t","a","_","l","o","o","p",$000,$082,$000,"c","o"
    byte "m","m","a",$000,$084,$000,"b","i","t","s",$000,$000,$092,$000,"b","i"
    byte "n",$000,$093,$000,"n","x","t",$000,$09B,$000,"s","t","r",$000,$09C,$000
    byte "i","d","x","_","s","t","r",$000,$09D,$000,"s","e","e","k","_","l"
    byte "o","o","p",$000,$0A1,$000,"d","o","n","e",$000,$000,$0A6,$000,"i","d"
    byte "x","_","s","t","r","_","r","e","t",$000,$0A6,$000,"s","t","r","_"
    byte "r","e","t",$000,$0A7,$000,"l","a","b","e","l","_","o","r","_","b"
    byte "i","n","a","r","y","_","d","s","t",$000,$0A9,$000,"l","a","b","e"
    byte "l","_","o","r","_","b","i","n","a","r","y",$000,$0B1,$000,"n","o"
    byte "r","e","g",$000,$0B6,$000,"o","u","t","_","b","i","n","a","r","y"
    byte $000,$000,$0B7,$000,"l","a","b","e","l","_","o","r","_","b","i","n"
    byte "a","r","y","_","r","e","t",$000,$0B7,$000,"l","a","b","e","l","_"
    byte "o","r","_","b","i","n","a","r","y","_","d","s","t","_","r","e"
    byte "t",$000,$0B8,$000,"b","i","n","a","r","y",$000,$000,$0BA,$000,"b","i"
    byte "n","a","r","y","2",$000,$0BC,$000,"b","i","n","_","l","o","o","p"
    byte $000,$000,$0C4,$000,"b","i","n","a","r","y","2","_","r","e","t",$000
    byte $0C4,$000,"b","i","n","a","r","y","_","r","e","t",$000,$000,$0C5,$000
    byte "a","l","i","g","n",$000,$0CA,$000,"a","l","i","g","n","_","r","e"
    byte "t",$000,$0CB,$000,"t","x",$000,$000,$0D4,$000,"t","x","_","l","o","o"
    byte "p",$000,$0D8,$000,"t","x","_","r","e","t",$000,$000,$0D9,$000,"f","i"
    byte "n","d","_","l","a","b","e","l",$000,$000,$0DC,$000,"c","h","e","c"
    byte "k","_","l","a","b","e","l",$000,$0E5,$000,"s","k","i","p","_","l"
    byte "a","b","e","l",$000,$000,$0EB,$000,"f","i","n","d","_","l","a","b"
    byte "e","l","_","r","e","t",$000,$000,$0EC,$000,"c","o","d","e","_","e"
    byte "n","d",$000,$000,$0EC,$000,"o","p","c","o","d","e",$000,$000,$0ED,$000
    byte "s","r","c",$000,$0EE,$000,"d","s","t",$000,$0EF,$000,"f","l","a","g"
    byte "s",$000,$0F0,$000,"p","c",$000,$000,$0F1,$000,"c","o","n","d",$000,$000
    byte $0F2,$000,"i","m","m",$000,$0F3,$000,"t","m","p",$000,$0F4,$000,"t","m"
    byte "p","_","c","t","r",$000,$0F5,$000,"c","h","a","r",$000,$000,$0F6,$000
    byte "s","t","r","_","a","d","d","r","e","s","s",$000,$0F7,$000,"b","i"
    byte "t","c","o","u","n","t",$000,$000,$0F8,$000,"b","i","t","t","i","m"
    byte "e",$000,$0F9,$000,"t","i","m","e","r",$000,$0FA,$000,"p","i","n","m"
    byte "a","s","k",$000,$0FB,$000,"c","o","n","d","i","t","i","o","n","s"
    byte "_","a","d","d","r",$000,$0FC,$000,"o","p","e","r","a","t","i","o"
    byte "n","s","_","a","d","d","r",$000,$0FD,$000,"r","e","g","i","s","t"
    byte "e","r","s","_","a","d","d","r",$000,$000,$0FE,$000,"c","o","d","e"
    byte "_","s","i","z","e",$000,$0FF,$000,"d","a","t","a","_","s","i","z"
    byte "e",$000,$000,$001,"v","a","r","s","_","s","i","z","e",$000,$001,$001
    byte "f","l","a","g","s","_","s","t","r","_","a","d","d","r",$000,$000
    byte $002,$001,"l","o","n","g","_","s","t","r","_","a","d","d","r",$000
    byte $003,$001,"b","y","t","e","_","s","t","r","_","a","d","d","r",$000
    byte $004,$001,"o","p","c","o","d","e","_","a","d","d","r",$000,$005,$001
    byte "p","o","s","i","t","i","o","n",$000,$000,$006,$001,"p","r","o","l"
    byte "o","g","u","e",$000,$000,$018,$001,"v","a","r","s","_","e","n","d"
    byte $000,$000,$0FF,$0FF,"P","A","R",$000,"C","N","T",$000,"I","N","A",$000
    byte "I","N","B",$000,"O","U","T","A",$000,"O","U","T","B",$000,"D","I"
    byte "R","A",$000,"D","I","R","B",$000,"C","T","R","A",$000,"C","T","R"
    byte "B",$000,"F","R","Q","A",$000,"F","R","Q","B",$000,"P","H","S","A"
    byte $000,"P","H","S","B",$000,"V","C","F","G",$000,"V","S","C","L",$000
    byte $000,$000,$000,$000,$000,"i","f","_","n","c","_","a","n","d","_","n"
    byte "z",$000,"i","f","_","n","c","_","a","n","d","_","z",$000,"i","f"
    byte "_","n","c",$000,"i","f","_","c","_","a","n","d","_","n","z",$000
    byte "i","f","_","n","z",$000,"i","f","_","c","_","n","e","_","z",$000
    byte "i","f","_","n","c","_","o","r","_","n","z",$000,"i","f","_","c"
    byte "_","a","n","d","_","z",$000,"i","f","_","c","_","e","q","_","z"
    byte $000,"i","f","_","z",$000,"i","f","_","n","c","_","o","r","_","z"
    byte $000,"i","f","_","c",$000,"i","f","_","c","_","o","r","_","n","z"
    byte $000,"i","f","_","c","_","o","r","_","z",$000,$000,"N","O","P",$000
    byte "W","R","B","Y","T","E",$000,"W","R","W","O","R","D",$000,"W","R"
    byte "L","O","N","G",$000,"R","D","B","Y","T","E",$000,"R","D","W","O"
    byte "R","D",$000,"R","D","L","O","N","G",$000,"H","U","B","O","P",$000
    byte "?",$000,"?",$000,"?",$000,"?",$000,"R","O","R",$000,"R","O","L",$000
    byte "S","H","R",$000,"S","H","L",$000,"R","C","R",$000,"R","C","L",$000
    byte "S","A","R",$000,"R","E","V",$000,"M","I","N","S",$000,"M","A","X"
    byte "S",$000,"M","I","N",$000,"M","A","X",$000,"M","O","V","S",$000,"M"
    byte "O","V","D",$000,"M","O","V","I",$000,"J","M","P","R","E","T",$000
    byte "A","N","D",$000,"A","N","D","N",$000,"O","R",$000,"X","O","R",$000
    byte "M","U","X","C",$000,"M","U","X","N","C",$000,"M","U","X","Z",$000
    byte "M","U","X","N","Z",$000,"A","D","D",$000,"S","U","B",$000,"A","D"
    byte "D","A","B","S",$000,"S","U","B","A","B","S",$000,"S","U","M","C"
    byte $000,"S","U","M","N","C",$000,"S","U","M","Z",$000,"S","U","M","N"
    byte "Z",$000,"M","O","V",$000,"N","E","G",$000,"A","B","S",$000,"A","B"
    byte "S","N","E","G",$000,"N","E","G","C",$000,"N","E","G","N","C",$000
    byte "N","E","G","Z",$000,"N","E","G","N","Z",$000,"C","M","P","S",$000
    byte "C","M","P","S","X",$000,"A","D","D","X",$000,"S","U","B","X",$000
    byte "A","D","D","S",$000,"S","U","B","S",$000,"A","D","D","S","X",$000
    byte "S","U","B","S","X",$000,"C","M","P","S","U","B",$000,"D","J","N"
    byte "Z",$000,"T","J","N","Z",$000,"T","J","Z",$000,"W","A","I","T","P"
    byte "E","Q",$000,"W","A","I","T","P","N","E",$000,"W","A","I","T","C"
    byte "N","T",$000,"W","A","I","T","V","I","D",$000,$000,"n","r",$000,"w"
    byte "r",$000,"n","r",","," ","w","c",$000,"w","r",","," ","w","c",$000
    byte "n","r",","," ","w","z",$000,"w","r",","," ","w","z",$000,"n","r"
    byte ","," ","w","z",","," ","w","c",$000,"w","r",","," ","w","z",","
    byte " ","w","c",$000,$000,"w","c",$000,"w","z",$000,"w","z",","," ","w"
    byte "c",$000,$000,$000,"l","o","n","g"," ",$000,$000,$000,"b","y","t","e"
    byte " ",$000,$000,$000
    
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-03-20 12:15
    Here's my contribution to the quine challenge:
    CON
    
       _clkmode = xtal1 + pll16x
       _xinfreq = 5_000_000
    
    VAR
    
      byte s[4000]
      word p, r
    
    PRI dmp | i, c
    
      r~~
      repeat i from 0 to p - 1
        case c := s[i]
          1: str(string(32,32,98,117,102,40,115,116,114,105,110,103,40,34))
          2: str(string(34,41,41,13))
          other: tx(c)
      str(string(32,32,100,109,112,13))
    
    PRI buf(i)
    
      s[p++] := 1
      bytemove(@s[p], i, strsize(i))
      p += strsize(i)
      s[p++] := 2
      str(i)
    
    PRI str(i) | c
    
      repeat while c := byte[i++]
        if (r == 0 and c == 92)
          c := 13
        tx(c)
    
    PRI tx(i) | t
    
      t := cnt
      i := (i | $300) << 1
      repeat 11
        waitcnt(t += 8333)
        outa[30] := i & 1
        i >>= 1
    
    PUB go
    
      waitcnt(cnt + clkfreq + outa[30]~~ + dira[30]~~)
      buf(string("CON\\   _clkmode = xtal1 + pll16x\   _xinfreq = 5_000_000\\VAR\\  byte s[4000]\ "))
      buf(string(" word p, r\\PRI dmp | i, c\\  r~~\  repeat i from 0 to p - 1\    case c := s[i]\"))
      buf(string("      1: str(string(32,32,98,117,102,40,115,116,114,105,110,103,40,34))\      2:"))
      buf(string(" str(string(34,41,41,13))\      other: tx(c)\  str(string(32,32,100,109,112,13))"))
      buf(string("\\PRI buf(i)\\  s[p++] := 1\  bytemove(@s[p], i, strsize(i))\  p += strsize(i)\ "))
      buf(string(" s[p++] := 2\  str(i)\\PRI str(i) | c\\  repeat while c := byte[i++]\    if (r ="))
      buf(string("= 0 and c == 92)\      c := 13\    tx(c)\\PRI tx(i) | t\\  t := cnt\  i := (i | "))
      buf(string("$300) << 1\  repeat 11\    waitcnt(t += 8333)\    outa[30] := i & 1\    i >>= 1\"))
      buf(string("\PUB go\\  waitcnt(cnt + clkfreq + outa[30]~~ + dira[30]~~)\"))
      dmp
    

    -Phil
  • potatoheadpotatohead Posts: 10,261
    edited 2011-03-20 16:31
    @Andrey awesome entry.

    Yours is "beautiful" and "interesting" in exactly the opposite way of the one I cited above. Very well done. Impressive.
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-03-22 10:38
    Here's a Spin quine that generates it's source by looking at it's bytecodes. The first file is the actual quine and the second file is the one that generated it. They are functionally equivalent, but the quine doesn't contain comments or meaningful variable names.

    Dave
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2011-03-22 11:34
    Dave Hein:
    So I would say that this means that the generated file is a valid quine and the original source is not???
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-03-22 12:39
    Yes, genquine.spin is not a quine, but it's output is a valid quine. quine.spin will produce an identical copy of itself.

    It took quite a few lines of code to generate Spin source from bytecodes. I had to limit the number of operators I used, and I use "repeat while" to do all my loops and if statements.
Sign In or Register to comment.