#include "../../settings.h"
#include "../../interpreter.h"
+#ifdef HAVE_clock_gettime
+# include <time.h>
+#else
+# include <sys/time.h>
+#endif
+
static instructionPointer *iffiIP = NULL;
static bool firstload = true;
// Communication functions with the ecto_b98 expansion library
-void ick_SaveIPPosDelta(struct ick_ipposdeltatype* ippd)
+void ick_save_ip_pos_delta(struct ick_ipposdeltatype* ippd)
{
ippd->ix = iffiIP->position.x;
ippd->iy = iffiIP->position.y;
ippd->dy = iffiIP->delta.y;
}
-void ick_RestoreIPPosDelta(struct ick_ipposdeltatype* ippd)
+void ick_restore_ip_pos_delta(const struct ick_ipposdeltatype* ippd)
{
iffiIP->position.x = ippd->ix;
iffiIP->position.y = ippd->iy;
iffiIP->delta.y = ippd->dy;
}
-void ick_InterpreterRun(void)
+void ick_interpreter_run(void)
{
- if (!FungeSpaceCreate()) {
+ if (!fungespace_create()) {
perror("Couldn't create funge space!?");
exit(EXIT_FAILURE);
}
- FungeSpaceLoadString(ick_iffi_befungeString);
- iffiIP = ipCreate();
+ fungespace_load_string((const unsigned char*)ick_iffi_befungeString);
+ iffiIP = ip_create();
if (iffiIP == NULL) {
perror("Couldn't create instruction pointer!?");
exit(EXIT_FAILURE);
}
{
+#ifdef HAVE_clock_gettime
+ struct timespec tv;
+ if (clock_gettime(CLOCK_REALTIME, &tv)) {
+ perror("Couldn't get time of day?!");
+ exit(EXIT_FAILURE);
+ }
+ // Set up randomness
+ srandom(tv.tv_nsec);
+#else
struct timeval tv;
if (gettimeofday(&tv, NULL)) {
perror("Couldn't get time of day?!");
exit(EXIT_FAILURE);
}
- /* Set up randomness */
+ // Set up randomness
srandom(tv.tv_usec);
+#endif
}
- if(ick_printflow) SettingTraceLevel=9;
- ick_InterpreterMainLoop();
+ if(ick_printflow) setting_trace_level=9;
+ ick_interpreter_main_loop();
}
-void ick_iffi_InterpreterOneIteration(void)
+void ick_iffi_interpreter_one_iteration(void)
{
fungeCell opcode;
- opcode = FungeSpaceGet(&iffiIP->position);
+ opcode = fungespace_get(&iffiIP->position);
- if (SettingTraceLevel > 8) {
+ if (setting_trace_level > 8) {
fprintf(stderr, "x=%" FUNGECELLPRI " y=%" FUNGECELLPRI
": %c (%" FUNGECELLPRI ")\n",
iffiIP->position.x, iffiIP->position.y, (char)opcode, opcode);
- PrintStackTop(iffiIP->stack);
- } else if (SettingTraceLevel > 3) {
+ stack_print_top(iffiIP->stack);
+ } else if (setting_trace_level > 3) {
fprintf(stderr, "x=%" FUNGECELLPRI " y=%" FUNGECELLPRI
": %c (%" FUNGECELLPRI ")\n",
iffiIP->position.x, iffiIP->position.y, (char)opcode, opcode);
- } else if (SettingTraceLevel > 2)
+ } else if (setting_trace_level > 2)
fprintf(stderr, "%c", (char)opcode);
- ExecuteInstruction(opcode, iffiIP);
+ execute_instruction(opcode, iffiIP);
if (iffiIP->needMove)
- ipForward(iffiIP, 1);
+ ip_forward(iffiIP, 1);
else
iffiIP->needMove = true;
}
// A - CREATE a new INTERCAL instruction
-static void FingerIFFIcreate(instructionPointer * ip)
+static void finger_IFFI_create(instructionPointer * ip)
{
// arguments: line number on TOS, signature as 0gnirts beneath it
- fungeCell l = StackPop(ip->stack);
- char * restrict str = StackPopString(ip->stack);
- ick_create(str, l);
+ fungeCell l = stack_pop(ip->stack);
+ unsigned char * restrict str = stack_pop_string(ip->stack);
+ ick_create((char*)str, l);
}
// C - In markmode COME FROM the top of stack
-static void FingerIFFIcomeFrom(instructionPointer * ip)
+static void finger_IFFI_come_from(instructionPointer * ip)
{
fungeCell l;
- l = StackPop(ip->stack);
+ l = stack_pop(ip->stack);
if (ick_iffi_inmarkmode) {
ick_iffi_breakloop = 1;
}
// D - Push information about a CREATED instruction argument
-static void FingerIFFIcreateData(instructionPointer * ip)
+static void finger_IFFI_create_data(instructionPointer * ip)
{
// Arguments: argument's index (0-based) on TOS
// Return: the following values (from bottom to top):
fungeCell i;
if (firstload) {
- ipReverse(ip);
+ ip_reverse(ip);
return;
}
- i = StackPop(ip->stack);
+ i = stack_pop(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));
+ stack_push(ip->stack, ick_c_i_width(i));
+ stack_push(ip->stack, ick_c_i_isarray(i));
+ stack_push(ip->stack, ick_c_i_varnumber(i));
+ stack_push(ip->stack, ick_c_i_value(i));
+ stack_push(ip->stack, ick_c_i_getvalue(i));
}
// F - FORGET NEXT stack entries equal to top of stack
-static void FingerIFFIforget(instructionPointer * ip)
+static void finger_IFFI_forget(instructionPointer * ip)
{
fungeCell f;
if (firstload) {
- ipReverse(ip);
+ ip_reverse(ip);
return;
}
if (ick_iffi_inmarkmode) { /* this is an error in the user's code */
- ipReverse(ip);
+ ip_reverse(ip);
return;
}
- f = StackPop(ip->stack);
+ f = stack_pop(ip->stack);
if (f > 81 || f < 0) f = 81;
}
// G - Get the value of an INTERCAL scalar variable
-static void FingerIFFIvarGet(instructionPointer * ip)
+static void finger_IFFI_var_get(instructionPointer * ip)
{
// arguments: var number on TOS
// var numbers are positive for onespot, negative for twospot
fungeCell v;
if (firstload) {
- ipReverse(ip);
+ ip_reverse(ip);
return;
}
- v = StackPop(ip->stack);
+ v = stack_pop(ip->stack);
if (v == 0) {
- ipReverse(ip);
+ ip_reverse(ip);
} else if (v > 0) {
- StackPush(ip->stack, ick_getonespot(v));
+ stack_push(ip->stack, ick_getonespot(v));
} else {
- StackPush(ip->stack, ick_gettwospot(-v));
+ stack_push(ip->stack, ick_gettwospot(-v));
}
}
// L - Use top of stack as a line label for this point
-static void FingerIFFIlabel(instructionPointer * ip)
+static void finger_IFFI_label(instructionPointer * ip)
{
fungeCell l;
if (firstload) {
- ipReverse(ip);
+ ip_reverse(ip);
return;
}
- l = StackPop(ip->stack);
+ l = stack_pop(ip->stack);
ick_iffi_breakloop = 1;
ick_iffi_linelabel = l;
}
// M - Marks points where the code can be entered from outside
-static void FingerIFFImarker(instructionPointer * ip)
+static void finger_IFFI_marker(instructionPointer * ip)
{
(void) ip;
ick_iffi_breakloop = ick_iffi_inmarkmode;
}
// N - Try to NEXT to the line labelled with the top of stack
-static void FingerIFFInext(instructionPointer * ip)
+static void finger_IFFI_next(instructionPointer * ip)
{
fungeCell l;
if (firstload) {
- ipReverse(ip);
+ ip_reverse(ip);
return;
}
if (ick_iffi_inmarkmode) { /* this is an error in the user's code */
- ipReverse(ip);
+ ip_reverse(ip);
return;
}
- l = StackPop(ip->stack);
+ l = stack_pop(ip->stack);
ick_iffi_breakloop = 1;
ick_iffi_linelabel = l;
}
// R - RESUME to the top-of-stackth NEXT stack entry
-static void FingerIFFIresume(instructionPointer * ip)
+static void finger_IFFI_resume(instructionPointer * ip)
{
fungeCell f;
if (firstload) {
- ipReverse(ip);
+ ip_reverse(ip);
return;
}
if (ick_iffi_inmarkmode) { /* this is an error in the user's code */
- ipReverse(ip);
+ ip_reverse(ip);
return;
}
- f = StackPop(ip->stack);
+ f = stack_pop(ip->stack);
if (f > 81 || f < 0) f = 81;
}
// S - Set the value of an INTERCAL scalar variable
-static void FingerIFFIvarSet(instructionPointer * ip)
+static void finger_IFFI_var_set(instructionPointer * ip)
{
// arguments: var number on TOS, new value beneath it
// var numbers are positive for onespot, negative for twospot
fungeCell v, d;
if (firstload) {
- ipReverse(ip);
+ ip_reverse(ip);
return;
}
- v = StackPop(ip->stack);
- d = StackPop(ip->stack);
+ v = stack_pop(ip->stack);
+ d = stack_pop(ip->stack);
if (v == 0) {
- ipReverse(ip);
+ ip_reverse(ip);
} else if (v > 0) {
ick_setonespot(v, d);
} else {
}
// V - Assign to a CREATEd instruction argument
-static void FingerIFFIargSet(instructionPointer * ip)
+static void finger_IFFI_arg_set(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
fungeCell i, d;
if (firstload) {
- ipReverse(ip);
+ ip_reverse(ip);
return;
}
- i = StackPop(ip->stack);
- d = StackPop(ip->stack);
+ i = stack_pop(ip->stack);
+ d = stack_pop(ip->stack);
ick_c_i_setvalue(i, d);
}
// X - In markmode NEXT FROM the top of stack
-static void FingerIFFInextFrom(instructionPointer * ip)
+static void finger_IFFI_next_from(instructionPointer * ip)
{
fungeCell l;
- l = StackPop(ip->stack);
+ l = stack_pop(ip->stack);
if (ick_iffi_inmarkmode) {
ick_iffi_breakloop = 1;
}
// Y - Marks the end of initialisation
-static void FingerIFFIyield(instructionPointer * ip)
+static void finger_IFFI_yield(instructionPointer * ip)
{
ick_iffi_breakloop = firstload;
if (! firstload)
- ipReverse(ip);
+ ip_reverse(ip);
firstload = false;
}
-bool FingerIFFIload(instructionPointer * ip)
+bool finger_IFFI_load(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)
+ manager_add_opcode(IFFI, 'A', create)
+ manager_add_opcode(IFFI, 'C', come_from)
+ manager_add_opcode(IFFI, 'D', create_data)
+ manager_add_opcode(IFFI, 'F', forget)
+ manager_add_opcode(IFFI, 'G', var_get)
+ manager_add_opcode(IFFI, 'L', label)
+ manager_add_opcode(IFFI, 'M', marker)
+ manager_add_opcode(IFFI, 'N', next)
+ manager_add_opcode(IFFI, 'R', resume)
+ manager_add_opcode(IFFI, 'S', var_set)
+ manager_add_opcode(IFFI, 'V', arg_set)
+ manager_add_opcode(IFFI, 'X', next_from)
+ manager_add_opcode(IFFI, 'Y', yield)
return true;
}
# programs. The cfunge distribution itself is not modified; all changes
# are made on a copy.
-test x$1 != x || (
- echo Please give the path to the root of a cfunge source
- echo distribution as an argument to this script.
+die() { echo "Error: $1"; exit 1; }
+
+if [ -z "$1" ] || [ -z "$2" ]; then
+ echo "Usage: $0 ick-source-path cfunge-path"
+ exit 1
+fi
+
+# test x$1 != x || (
+# echo Please give the path to the root of a cfunge source
+# echo distribution as an argument to this script.
+# exit 1
+# ) || exit 1
+
+ICKSRC_PATH="$1"
+CFUNGE_PATH="$2"
+BUILD_PATH="$(pwd)"
+
+ICKSRC_PATH=`(cd $ICKSRC_PATH; pwd)` || (
+ echo Please give the path to the root of C-INTERCAL source
+ echo distribution as the first argument to this script\; the directory
+ echo or file you gave does not exist.
exit 1
) || exit 1
-CFUNGEPATH=`(cd $1; pwd)` || (
+CFUNGE_PATH=`(cd $CFUNGE_PATH; pwd)` || (
echo Please give the path to the root of a cfunge source
- echo distribution as an argument to this script\; the directory
+ echo distribution as the second argument to this script\; the directory
echo or file you gave does not exist.
exit 1
) || exit 1
-test -f $CFUNGEPATH/src/interpreter.c || (
+test -f "$CFUNGE_PATH/src/interpreter.c" || (
echo Please give the path to the root of a cfunge source
- echo distribution as an argument to this script.
- echo You gave $CFUNGEPATH, but it does not appear to be a cfunge
+ echo distribution as the second argument to this script.
+ echo You gave $CFUNGE_PATH, but it does not appear to be a cfunge
echo source distribution.
exit 1
) || exit 1
-test -f IFFI.spec || (
- echo Please run this script in the /etc directory of your
- echo C-INTERCAL distribution.
+test -f "$ICKSRC_PATH/etc/IFFI.spec" || (
+ echo Please give the path to the root of the C-INTERCAL source
+ echo distribution as the first argument of this script.
+ echo You gave $ICKSRC_PATH, but it does not appear to be a C-INTERCAL
+ echo source distribution.
exit 1
) || exit 1
echo Compiling cfunge into a library suitable for use with C-INTERCAL:
-cd temp
+rm -rf temp || die "Failed to remove any old temp directory"
+mkdir -p temp || die "Failed to create temp directory"
+cd temp || die "Failed to change directory to temp directory"
-CFLAGS="--std=c99 -DUSE32 -DDISABLE_GC -DFUNGE_EXTERNAL_LIBRARY -D_POSIX_C_SOURCE=200112L -D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED -DFUNGE_OLD_HANDPRINT=0x43464649 '-DFUNGE_NEW_HANDPRINT=\"http://example.com/\"'"
+CFLAGS="-std=c99 -DUSE32 -DDISABLE_GC -DFUNGE_EXTERNAL_LIBRARY -D_POSIX_C_SOURCE=200112L -D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED -DFUNGE_OLD_HANDPRINT=0x43464649 '-DFUNGE_NEW_HANDPRINT=\"http://example.com/\"'"
+# Allow optional -O2 or such:
+if [ "$CFUNGE_CFLAGS" ]; then
+ CFLAGS="$CFLAGS $CFUNGE_CFLAGS"
+fi
+# Please enable this when making changes. Requested by the cfunge author.
+#CFLAGS="$CFLAGS -Wall -Wextra -pedantic -Wpointer-arith -Wimplicit -Wnested-externs -Wcast-align -Wcast-qual -Wbad-function-cast -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wparentheses -Wshadow -Wundef -Wpacked -Wredundant-decls -Wfloat-equal -Wstrict-aliasing=2 -Wformat=2 -Wdisabled-optimization -Wmissing-noreturn -Wmissing-format-attribute -Wdeclaration-after-statement -Wunused-function -Wunused-label -Wunused-value -Wunused-variable -Wwrite-strings"
echo " " Duplicating cfunge source tree so that it can be modified...
-cp -r $CFUNGEPATH/src $CFUNGEPATH/lib .
+cp -r $CFUNGE_PATH/src $CFUNGE_PATH/lib .
# Comment these lines back in if patching is needed
# echo " " Patching cfunge source tree for use with C-INTERCAL...
# patch -p0 < ../cfunge.patch
echo " " Adding the IFFI fingerprint...
-cp -r ../IFFI ../IFFI.spec src/fingerprints
+cp -r "$ICKSRC_PATH/etc/IFFI" "$ICKSRC_PATH/etc/IFFI.spec" src/fingerprints
echo " " Regenerating fingerprint lists...
-$CFUNGEPATH/tools/gen_fprint_list.sh > /dev/null
+$CFUNGE_PATH/tools/gen_fprint_list.sh > /dev/null || die "Failed to regen list."
# Trust the filenames that are in the cfunge directory tree; if the user's
# trying to trick themselves into running this on something that looks like
find . -name '*.c' -printf "gcc $CFLAGS -c %p -o %f.o\n" | sh
echo " " Creating library...
-ar cr ../../prebuilt/libick_ecto_b98.a *.o
-ranlib ../../prebuilt/libick_ecto_b98.a
+ar cr ../libick_ecto_b98.a *.o
+ranlib ../libick_ecto_b98.a
echo " " Cleaning up...
rm -rf *
long long ix, iy, dx, dy;
};
-void ick_InterpreterMainLoop(void);
-void ick_InterpreterRun(void);
-void ick_iffi_InterpreterOneIteration(void);
-void ick_iffi_HandleControl(void);
-void ick_SaveIPPosDelta(struct ick_ipposdeltatype*);
-void ick_RestoreIPPosDelta(struct ick_ipposdeltatype*);
+/* This is called from IFFI. Remember to keep matching
+ extern over there in sync. */
+void ick_interpreter_main_loop(void);
+
+/* This is just a forward decl. */
+void ick_iffi_handle_control(void);
+
+/* These are implemented in IFFI. */
+extern void ick_interpreter_run(void);
+extern void ick_iffi_interpreter_one_iteration(void);
+extern void ick_save_ip_pos_delta(struct ick_ipposdeltatype*);
+extern void ick_restore_ip_pos_delta(const struct ick_ipposdeltatype*);
unsigned short ick_iffi_forgetcount=0;
int ick_iffi_nexting=0;
extern long long ick_iffi_markerposns[][2];
extern int ick_iffi_markercount;
-ICK_EC_FUNC_START(ick_InterpreterMainLoop)
+ICK_EC_FUNC_START(ick_interpreter_main_loop)
{
- ick_startup( {ick_InterpreterRun();} ); /* could be put anywhere, is put here
+ ick_startup( {ick_interpreter_run();} ); /* could be put anywhere, is put here
for convenience */
/* we enter here when running at startup code and continue until IFFI is loaded */
if(ick_global_linelabel == 0x70001ff2)
{
auto struct ick_ipposdeltatype ippd;
- ick_SaveIPPosDelta(&ippd);
+ ick_save_ip_pos_delta(&ippd);
ick_iffi_sucking = 0;
ick_checksuckpoint(ick_iffi_linelabel); /* may not return */
- ick_RestoreIPPosDelta(&ippd);
+ ick_restore_ip_pos_delta(&ippd);
}
}
ick_iffi_breakloop=0;
while(!ick_iffi_breakloop)
{
- ick_iffi_InterpreterOneIteration();
+ ick_iffi_interpreter_one_iteration();
if (ick_iffi_forgetcount && !ick_iffi_breakloop)
{
ick_forget(ick_iffi_forgetcount);
onto the C stack. This is done in a struct ick_ipposdatatype, using the
functions available for such save/restore. */
auto struct ick_ipposdeltatype ippd;
- ick_SaveIPPosDelta(&ippd);
+ ick_save_ip_pos_delta(&ippd);
ick_iffi_nexting = 0;
ick_next(ick_iffi_linelabel); /* may not return */
- ick_RestoreIPPosDelta(&ippd);
+ ick_restore_ip_pos_delta(&ippd);
goto ick_iffi_iml_rerun; /* continue the main loop if we got here */
}
if(ick_iffi_sucking && ! ick_iffi_inmarkmode)
{
/* Handle a line-label encountered in normal execution. */
auto struct ick_ipposdeltatype ippd;
- ick_SaveIPPosDelta(&ippd);
+ ick_save_ip_pos_delta(&ippd);
ick_iffi_sucking = 0;
ick_checksuckpoint(ick_iffi_linelabel); /* may not return */
- ick_RestoreIPPosDelta(&ippd);
+ ick_restore_ip_pos_delta(&ippd);
goto ick_iffi_iml_rerun; /* continue the main loop if we got here */
}
}
ICK_EC_FUNC_END
-ICK_EC_FUNC_START(ick_iffi_HandleControl)
+ICK_EC_FUNC_START(ick_iffi_handle_control)
{
static int recursing=0;
int markerno, dirno, nextcheck;
recursing=1;
- ick_SaveIPPosDelta(&ippd);
+ ick_save_ip_pos_delta(&ippd);
markerno=ick_iffi_markercount;
while(markerno--)
tippd.ix, tippd.iy, dirno["^>v<"]);
tippd.ix += tippd.dx;
tippd.iy += tippd.dy;
- ick_RestoreIPPosDelta(&tippd);
+ ick_restore_ip_pos_delta(&tippd);
ick_iffi_inmarkmode = 1;
ick_local_checkmode = ick_global_checkmode;
ick_global_checkmode = 0;
- ick_InterpreterMainLoop();
+ ick_interpreter_main_loop();
ick_global_checkmode = ick_local_checkmode;
ick_iffi_inmarkmode = 0;
if((ick_iffi_nextingfrom||ick_iffi_comingfrom) &&
ick_global_goto=0x70001FF1; /* we found a suckpoint */
if(ick_iffi_nextingfrom) ick_global_checkmode = 3; /* do a next from */
/* if it's a come-from, the checkmode is already correct */
- ick_SaveIPPosDelta(&ippd);
+ ick_save_ip_pos_delta(&ippd);
}
if(ick_iffi_sucking && ick_iffi_linelabel == ick_global_linelabel &&
nextcheck)
if(ick_printflow)
fprintf(stderr,"Line label found!\n");
/* Another part of the code is NEXTing to this line label. */
- ick_SaveIPPosDelta(&ippd);
+ ick_save_ip_pos_delta(&ippd);
nextcheck = 2; /* when this loop ends, goto the main loop */
}
ick_iffi_nextingfrom = 0;
/* Set the IP to what we want it to be on resume, or otherwise return it to
its original value. (Returning it to its original value is unneccesary
but harmless.) */
- ick_RestoreIPPosDelta(&ippd);
+ ick_restore_ip_pos_delta(&ippd);
recursing=0;
ick_iffi_linelabel = ick_global_linelabel;
if(nextcheck == 2)