From: Alex Smith Date: Mon, 7 Jul 2008 00:43:54 +0000 (-0400) Subject: Add ADGSVY to the IFFI fingerprint X-Git-Tag: 0.29~204 X-Git-Url: http://thyrsus.com/gitweb/?a=commitdiff_plain;h=f0a3ee9ddf109f21662977d587920a254af53d83;p=intercal.git Add ADGSVY to the IFFI fingerprint --- diff --git a/etc/IFFI.spec b/etc/IFFI.spec index d79fb60..f666425 100644 --- a/etc/IFFI.spec +++ b/etc/IFFI.spec @@ -5,11 +5,17 @@ %safe:false %begin-instrs #I name desc +A create CREATE a new INTERCAL instruction C comeFrom In markmode COME FROM the top of stack +D createData Push information about a CREATEd instruction argument F forget FORGET NEXT stack entries equal to top of stack +G varGet Get the value of an INTERCAL scalar variable L label Use top of stack as a line label for this point M marker Marks points where the code can be entered from outside N next Try to NEXT to the line labelled with the top of stack R resume RESUME to the top-of-stackth NEXT stack entry +S varSet Set the value of an INTERCAL scalar variable +V argSet Assign to a CREATEd instruction argument X nextFrom In markmode NEXT FROM the top of stack +Y yield Marks the end of initialisation %end diff --git a/etc/IFFI/IFFI.c b/etc/IFFI/IFFI.c index bfc3a1c..8c74ce9 100644 --- a/etc/IFFI/IFFI.c +++ b/etc/IFFI/IFFI.c @@ -93,6 +93,15 @@ void ick_iffi_InterpreterOneIteration(void) iffiIP->needMove = true; } +// A - CREATE a new INTERCAL instruction +static void FingerIFFIcreate(instructionPointer * ip) +{ + // arguments: line number on TOS, signature as 0gnirts beneath it + FUNGEDATATYPE l = StackPop(ip->stack); + char * restrict str = StackPopString(ip->stack); + ick_create(str, l); +} + // C - In markmode COME FROM the top of stack static void FingerIFFIcomeFrom(instructionPointer * ip) { @@ -107,6 +116,27 @@ static void FingerIFFIcomeFrom(instructionPointer * ip) } } +// D - Push information about a CREATED instruction argument +static void FingerIFFIcreateData(instructionPointer * ip) +{ + // Arguments: argument's index (0-based) on TOS + // Return: the following values (from bottom to top): + // The argument's data type, in bits + // Whether the argument is an array variable + // 0 if the argument is not a variable, or its number if it is + // The argument's value at the time the CREATED instruction was called + // The argument's value now (same as previous if -a was not used) + FUNGEDATATYPE i; + + i = StackPop(ip->stack); + + StackPush(ip->stack, ick_c_i_width(i)); + StackPush(ip->stack, ick_c_i_isarray(i)); + StackPush(ip->stack, ick_c_i_varnumber(i)); + StackPush(ip->stack, ick_c_i_value(i)); + StackPush(ip->stack, ick_c_i_getvalue(i)); +} + // F - FORGET NEXT stack entries equal to top of stack static void FingerIFFIforget(instructionPointer * ip) { @@ -124,6 +154,26 @@ static void FingerIFFIforget(instructionPointer * ip) ick_iffi_forgetcount = f; } +// G - Get the value of an INTERCAL scalar variable +static void FingerIFFIvarGet(instructionPointer * ip) +{ + // arguments: var number on TOS + // var numbers are positive for onespot, negative for twospot + // return: the value of the variable + + FUNGEDATATYPE v; + + v = StackPop(ip->stack); + + if (v == 0) { + ipReverse(ip); + } else if (v > 0) { + StackPush(ip->stack, ick_getonespot(v)); + } else { + StackPush(ip->stack, ick_gettwospot(-v)); + } +} + // L - Use top of stack as a line label for this point static void FingerIFFIlabel(instructionPointer * ip) { @@ -181,6 +231,40 @@ static void FingerIFFIresume(instructionPointer * ip) ick_iffi_breakloop = 1; } +// S - Set the value of an INTERCAL scalar variable +static void FingerIFFIvarSet(instructionPointer * ip) +{ + // arguments: var number on TOS, new value beneath it + // var numbers are positive for onespot, negative for twospot + // return: the value of the variable + + FUNGEDATATYPE v, d; + + v = StackPop(ip->stack); + d = StackPop(ip->stack); + + if (v == 0) { + ipReverse(ip); + } else if (v > 0) { + ick_setonespot(v, d); + } else { + ick_settwospot(-v, d); + } +} + +// V - Assign to a CREATEd instruction argument +static void FingerIFFIargSet(instructionPointer * ip) +{ + // arguments: 0-based argument index on TOS, new value beneath it + // note that this is a NOP unless -a was used when compiling + FUNGEDATATYPE i, d; + + i = StackPop(ip->stack); + d = StackPop(ip->stack); + + ick_c_i_setvalue(i, d); +} + // X - In markmode NEXT FROM the top of stack static void FingerIFFInextFrom(instructionPointer * ip) { @@ -195,17 +279,30 @@ static void FingerIFFInextFrom(instructionPointer * ip) } } -bool FingerIFFIload(instructionPointer * ip) +// Y - Marks the end of initialisation +static void FingerIFFIyield(instructionPointer * ip) { - static int firstload = 1; + static bool firstload = true; ick_iffi_breakloop = firstload; - firstload = 0; + if (! firstload) + ipReverse(ip); + firstload = false; +} + +bool FingerIFFIload(instructionPointer * ip) +{ + ManagerAddOpcode(IFFI, 'A', create) ManagerAddOpcode(IFFI, 'C', comeFrom) + ManagerAddOpcode(IFFI, 'D', createData) ManagerAddOpcode(IFFI, 'F', forget) + ManagerAddOpcode(IFFI, 'G', varGet) ManagerAddOpcode(IFFI, 'L', label) ManagerAddOpcode(IFFI, 'M', marker) ManagerAddOpcode(IFFI, 'N', next) ManagerAddOpcode(IFFI, 'R', resume) + ManagerAddOpcode(IFFI, 'S', varSet) + ManagerAddOpcode(IFFI, 'V', argSet) ManagerAddOpcode(IFFI, 'X', nextFrom) + ManagerAddOpcode(IFFI, 'Y', yield) return true; } diff --git a/etc/IFFI/IFFI.h b/etc/IFFI/IFFI.h index 36e2606..64f3460 100644 --- a/etc/IFFI/IFFI.h +++ b/etc/IFFI/IFFI.h @@ -35,10 +35,11 @@ struct ick_ipposdeltatype long long ix, iy, dx, dy; }; +// Externally-visible functions from IFFI.c bool FingerIFFIload(instructionPointer * ip); - void ick_InterpreterMainLoop(void); +// Communication variables with ecto_b98 extern unsigned short ick_iffi_forgetcount; extern int ick_iffi_nexting; extern int ick_iffi_comingfrom; @@ -49,7 +50,23 @@ extern uint32_t ick_iffi_linelabel; extern int ick_iffi_breakloop; extern int ick_iffi_inmarkmode; +// Communication variables with the compiled .cio file extern const char * ick_iffi_befungeString; + +// Communication variables with the runtime library extern int ick_printflow; +// Accessors and mutators for INTERCAL storage +extern void ick_create(char*, unsigned long); +extern uint16_t ick_getonespot(unsigned short); +extern void ick_setonespot(unsigned short, uint16_t); +extern uint32_t ick_gettwospot(unsigned short); +extern void ick_settwospot(unsigned short, uint32_t); +extern int ick_c_i_width(int); +extern int ick_c_i_isarray(int); +extern unsigned short ick_c_i_varnumber(int); +extern uint32_t ick_c_i_value(int); +extern uint32_t ick_c_i_getvalue(int); +extern void ick_c_i_setvalue(int, uint32_t); + #endif