Talk:ABCDXYZ
Link to implementation?
--YamTokTpaFa (talk) 03:35, 1 September 2019 (UTC)
I may as well just copy and paste it here. The following program is public domain by ais523, originally written in 2006.
/* ABCDXYZ to BackFlip compiler. By Alex Smith. */ /* The ABCDXYZ language was inspired when working on BackFlip; it is * designed to be compilable into BackFlip and therefore has the same * restrictions (no I/O, reversible, limited memory). These restrictions * are enforced by banning recursion; a version in which recursion is legal * would be more general. The operations used are those used by the first * (hopefully) practical BackFlip data-storage function discovered. * * An ABCDXYZ program consists of a set of objects, each of which has * a value (which can only be A, B, C, or D) and a function. Objects can * affect each other using three commands (X, Y, and Z). All objects start * initialized to A. * * If an object's value is | X does | Y does | Z does * A | Value := B | Value := B | Value := A * B | Value := C, | Value := C | Value := D * | run function | | * C | Value := D | Value := D, | Value := B * | | run function | * D | Value := A | Value := A | Value := C * * The syntax of a program is * * <object>: * <command><object> <command><object> <command><object>, etc. * * <object> is a number, <command> is X, Y, or Z. Newline and space are * interchangeable as separators, and any number of them can be used. * * This version also accepts ", followed by a character, as a command. * Using this will quote the character into the BackFlip output; the * program will exit if it continues straight, or continue with the next * command if it rebounds. This can be used to access BackFlip extensions. * * Object 0's function is run when the program starts; there is no way to * modify object 0's value (it cannot be used as the operand of a command). * Objects must be given in numerical order, and consecutive numbers must * be used. This implementation does not enforce this, but will give * incorrect answers if it isn't true, or possibly dump core. * * This implementation insists that the input file is seekable (so, don't * use /dev/stdin or /dev/tty, but most files should be fine). * * This implementation limits object numbers to half the range of an int, * without checking, and doesn't do error checking on the input program. * (It is likely to dump core or produce incorrect results if the input * program is incorrect). * * This implementation assumes that char is smaller than int, which is true * on most systems. * * The compiled output appears on stdout. */ #include <stdio.h> #include <stdlib.h> #include <limits.h> #if UCHAR_MAX > INT_MAX #error int must be strictly larger than char for this program to work. #endif int numobjects = 0; int objrefhi(int ref, int obj) { if(ref<-numobjects) return 0; if(ref>numobjects) ref-=numobjects; if(ref<0) ref*=-1; return ref<obj; } int main(int argc, char** argv) { int totalcmdcount = 0; FILE* in; int c,i,j,k,l; if(argc != 2) { fprintf(stderr,"Usage: abcdxyz [input file]\n"); fprintf(stderr,"Output goes to stdout, which should be redirected if\n"); fprintf(stderr,"you want to save the output.\n"); return (argc!=1)*EXIT_FAILURE; } in = fopen(argv[1],"r"); if(!in) { perror(argv[1]); return EXIT_FAILURE; } while((c=getc(in))!=EOF) numobjects+=c==':'; rewind(in); { int* objectcmdcount=malloc(sizeof(int)*numobjects); int** objectcmds=malloc(sizeof(int*)*numobjects); int* wasblank=malloc(sizeof(int)*numobjects); i=numobjects; while(i--) objectcmdcount[i]=0; /* i is -1 */ while((c=getc(in))!=EOF) { if(c==':') i++; if(c=='X'||c=='Y'||c=='Z'||c=='"'/*||c=='\''*/) { objectcmdcount[i]++; totalcmdcount++; wasblank[i]=0; } } i=numobjects; while(i--) { if(!objectcmdcount[i]) { objectcmdcount[i]++; wasblank[i]=1; totalcmdcount++; } objectcmds[i]=malloc(sizeof(int)*objectcmdcount[i]); if(!objectcmds[i]) { while(++i<numobjects) free(objectcmds[i]); fprintf(stderr,"Out of memory."); fclose(in); return EXIT_FAILURE; } } rewind(in); /* i is again -1 */ while((c=getc(in))!=EOF) { if(c==':') {i++; j=0;} if(c=='X'||c=='Y'||c=='Z') fscanf(in,"%d",&objectcmds[i][j]); if(/*c=='\''||*/c=='"') objectcmds[i][j]=-getc(in); if(c=='X') objectcmds[i][j++]*=-1; if(c=='Y') objectcmds[i][j++]+=numobjects; if(c=='Z') j++; if(c=='"') objectcmds[i][j++]-=numobjects; /*if(c=='\'') objectcmds[i][j++]-=numobjects+1+(int)UCHAR_MAX;*/ } fclose(in); /* Now the program has been read in; time to do the translation. * This is pretty mechanical. */ i=totalcmdcount+5; /* Maximum line width */ i-=printf("V-- BackFlip source for the ABCDXYZ program %s --",argv[1]); while(i-->0) putchar('-'); /* First line must be the longest */ printf("\n\n "); j=totalcmdcount; while(j--) putchar('V'); printf("\n> "); k=0; i=-1; while(++i < numobjects) { if(i) { /* Data storage block */ printf(" VV"); /* Write < for every X command pointing to this object */ j=-1; while(++j < numobjects) { l=-1; while(++l < objectcmdcount[j]) putchar(objectcmds[j][l]==-i?'<':' '); } putchar('\n'); printf(" V / "); /* Write < for every Z command pointing to this object */ j=-1; while(++j < numobjects) { l=-1; while(++l < objectcmdcount[j]) putchar(objectcmds[j][l]==i?'<':' '); } putchar('\n'); printf(" V "); /* Write < for every Y command pointing to this object */ j=-1; while(++j < numobjects) { l=-1; while(++l < objectcmdcount[j]) putchar(objectcmds[j][l]==i+numobjects?'<':' '); } putchar('\n'); printf(" V \n"); printf(" >/<\n"); printf(" ^\\^\n"); printf(" > V\n"); printf(" >/< \n"); printf(" ^\\^ \n"); printf(" VV <\n"); printf(">/< \n"); printf(">\\^ \n"); printf(" > "); } /* The function */ j=k; while(j--) putchar(' '); if(!wasblank[i]) { j=-1; while(++j<objectcmdcount[i]-1) putchar(objrefhi(objectcmds[i][j],i)?'/':'\\'); putchar(objrefhi(objectcmds[i][objectcmdcount[i]-1],i)?'^':'V'); } else putchar('<'); putchar('\n'); k+=objectcmdcount[i]; } printf(" "); k=totalcmdcount; j=-1; while(++j < numobjects) { l=-1; while(++l < objectcmdcount[j]) putchar(objectcmds[j][l]<-numobjects&& objectcmds[j][l]>-numobjects-(int)UCHAR_MAX? -objectcmds[j][l]-numobjects:'^'); } putchar('\n'); i=numobjects; while(i--) free(objectcmds[i]); free(objectcmds); free(objectcmdcount); free(wasblank); } return 0; }
It appears to be a compiler into BackFlip. I'm not sure how portable it is, but I found it alongside a DOS .exe file with the same name so it probably originally targeted DJGPP. --ais523 21:26, 10 April 2020 (UTC)
Java Compiler to Java
This is by no means efficient (it's very very inefficient), but I have created a compiler from ABCDXYZ into Java, written in Java. Input is given by specifying the number of objects, followed by the event of each object in order, each on its own line. No keys or blank lines necessary or allowed. It uses an enum as the ABCD type, specifies each event as its own static method, and represents the instructions as switch statements with the ABCD values as cases.
BoundedBeans (talk) 18:35, 12 July 2022 (UTC)
Real interpreter
I've created a real interpreter in Python. --None1 (talk) 03:45, 15 June 2024 (UTC)