]> thyrsus.com Git - intercal.git/commitdiff
Add ADGSVY to the IFFI fingerprint
authorAlex Smith <ais523@bham.ac.uk>
Mon, 7 Jul 2008 00:43:54 +0000 (20:43 -0400)
committerEric S. Raymond <esr@thyrsus.com>
Thu, 26 Aug 2010 00:35:10 +0000 (20:35 -0400)
etc/IFFI.spec
etc/IFFI/IFFI.c
etc/IFFI/IFFI.h

index d79fb606c0911c59f3e07cb5e811e43029186eaf..f66642559334a17cb0a8e31c0684b1315c4a8f8f 100644 (file)
@@ -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
index bfc3a1cf8e0684d0173b820f12657aa8c00d35ba..8c74ce942e9b0ef52bd757eecb0b3fdcb3a760c2 100644 (file)
@@ -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;
 }
index 36e26063bc18ace915c93df36634fce57ffe2671..64f3460b25bfc3f348a2b10a4eb2836531d736a3 100644 (file)
@@ -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