native/ - source code for Factor interpreter written in C.
library/platform/native - C interpreter-specific code
f - compiled C interpreter - needs image to run
-boot.image.le - image for x86
-boot.image.be - image for 32-bit SPARC and 32-bit PowerPC
+boot.image.le32 - image for x86
+boot.image.le64 - image for AMD64
+boot.image.be32 - image for 32-bit SPARC and 32-bit PowerPC
+boot.image.be64 - iamge for 64-bit SPARC and 64-bit PowerPC
Notes on the C interpreter
--------------------------
When you run the interpreter with a boot image, it loads a
bunch of files and saves a 'factor.image'. Run the
interpreter again with this image.
-
-At the moment it assumes a 32-bit architecture. Your C
-compiler's types must be as follows:
-
-short - signed 16 bits
-long - signed 32 bits
-long long - signed 64 bits
-double -IEEE double precision 64-bit float
-
-Moving to 64-bits would require a few changes in the image
-cross-compiler, namely in the way it packs strings.
-
-Not everything has been implemented yet. However, a lot
-already works. Compare the output of this in the C and
-Java interpreters to see how they differ:
-
-"vocabularies" get describe
-! Currently the plugin doesn't handle GENERIC: and M:, so we
-! disable the parser. too many errors :sidekick.parser=none:
+! A simple space shooter.
+!
+! To play the game:
+!
+! ./f factor.image -libraries:sdl=libSDL.so -libraries:sdl-gfx=libSDL_gfx.so
+!
+! "examples/oop.factor" run-file
+! "examples/factoroids.factor" run-file
+
IN: factoroids
USE: combinators
] with-screen ;
factoroids
+
+! Currently the plugin doesn't handle GENERIC: and M:, so we
+! disable the parser. too many errors :sidekick.parser=none:
: ffi-error ( obj -- )
"FFI: " write print ;
-: datastack-underflow-error ( obj -- )
- drop "Datastack underflow" print ;
-
-: datastack-overflow-error ( obj -- )
- drop "Datastack overflow" print ;
-
-: callstack-underflow-error ( obj -- )
- drop "Callstack underflow" print ;
-
-: callstack-overflow-error ( obj -- )
- drop "Callstack overflow" print ;
-
: port-closed-error ( obj -- )
"Port closed: " write . ;
c-string-error
ffi-disabled-error
ffi-error
- datastack-underflow-error
- datastack-overflow-error
- callstack-underflow-error
- callstack-overflow-error
port-closed-error
} vector-nth execute ;
exit(1);
}
-void throw_error(CELL error)
+void throw_error(CELL error, bool keep_stacks)
{
thrown_error = error;
+ thrown_keep_stacks = keep_stacks;
+ thrown_ds = ds;
+ thrown_cs = cs;
/* Return to run() method */
siglongjmp(toplevel,1);
void primitive_throw(void)
{
- throw_error(dpop());
+ throw_error(dpop(),true);
}
-void general_error(CELL error, CELL tagged)
+void early_error(CELL error)
{
- CELL c = cons(error,cons(tagged,F));
if(userenv[BREAK_ENV] == F)
{
/* Crash at startup */
- fprintf(stderr,"Error thrown before BREAK_ENV set\n");
- fprintf(stderr,"Error #%ld\n",to_fixnum(error));
- if(error == ERROR_TYPE)
- {
- CELL obj = untag_cons(untag_cons(tagged)->cdr)->car;
-
- fprintf(stderr,"Type #%ld\n",to_fixnum(
- untag_cons(tagged)->car));
- fprintf(stderr,"Object %ld\n",obj);
- fprintf(stderr,"Got type #%ld\n",type_of(obj));
- }
+ fprintf(stderr,"Error %ld thrown before BREAK_ENV set\n",to_fixnum(error));
fflush(stderr);
exit(1);
}
- throw_error(c);
+}
+
+void general_error(CELL error, CELL tagged)
+{
+ early_error(error);
+ throw_error(cons(error,cons(tagged,F)),true);
+}
+
+/* It is not safe to access 'ds' from a signal handler, so we just not
+touch it */
+void signal_error(int signal)
+{
+ early_error(ERROR_SIGNAL);
+ throw_error(cons(ERROR_SIGNAL,cons(tag_fixnum(signal),F)),false);
}
void type_error(CELL type, CELL tagged)
#define ERROR_C_STRING (12<<3)
#define ERROR_FFI_DISABLED (13<<3)
#define ERROR_FFI (14<<3)
-#define ERROR_DATASTACK_UNDERFLOW (15<<3)
-#define ERROR_DATASTACK_OVERFLOW (16<<3)
-#define ERROR_CALLSTACK_UNDERFLOW (17<<3)
-#define ERROR_CALLSTACK_OVERFLOW (18<<3)
-#define ERROR_CLOSED (19<<3)
+#define ERROR_CLOSED (15<<3)
/* When throw_error throws an error, it sets this global and
longjmps back to the top-level. */
CELL thrown_error;
+CELL thrown_keep_stacks;
+CELL thrown_ds;
+CELL thrown_cs;
void init_errors(void);
void fatal_error(char* msg, CELL tagged);
void critical_error(char* msg, CELL tagged);
-void throw_error(CELL object);
+void throw_error(CELL error, bool keep_stacks);
+void early_error(CELL error);
void general_error(CELL error, CELL tagged);
+void signal_error(int signal);
void type_error(CELL type, CELL tagged);
void primitive_throw(void);
void range_error(CELL tagged, FIXNUM index, CELL max);
sigsetjmp(toplevel, 1);
if(thrown_error != F)
{
- fix_stacks();
+ if(thrown_keep_stacks)
+ {
+ ds = thrown_ds;
+ cs = thrown_cs;
+ }
+ else
+ fix_stacks();
+
dpush(thrown_error);
/* Notify any 'catch' blocks */
call(userenv[BREAK_ENV]);
void signal_handler(int signal, siginfo_t* siginfo, void* uap)
{
- general_error(ERROR_SIGNAL,tag_fixnum(signal));
-}
-
-void memory_signal_handler(int signal, siginfo_t* siginfo, void* uap)
-{
- fprintf(stderr,"memory signal\n");
if(active.here > active.limit)
{
fprintf(stderr,"Out of memory\n");
exit(1);
}
else
- general_error(ERROR_SIGNAL,tag_fixnum(signal));
+ signal_error(signal);
}
/* Called from a signal handler. XXX - is this safe? */
{
struct sigaction custom_sigaction;
struct sigaction profiling_sigaction;
- struct sigaction memory_sigaction;
struct sigaction ign_sigaction;
custom_sigaction.sa_sigaction = signal_handler;
custom_sigaction.sa_flags = SA_SIGINFO;
profiling_sigaction.sa_sigaction = call_profiling_step;
profiling_sigaction.sa_flags = SA_SIGINFO;
- memory_sigaction.sa_sigaction = memory_signal_handler;
- memory_sigaction.sa_flags = SA_SIGINFO;
ign_sigaction.sa_handler = SIG_IGN;
sigaction(SIGABRT,&custom_sigaction,NULL);
sigaction(SIGFPE,&custom_sigaction,NULL);
- sigaction(SIGBUS,&memory_sigaction,NULL);
- sigaction(SIGSEGV,&memory_sigaction,NULL);
+ sigaction(SIGBUS,&custom_sigaction,NULL);
+ sigaction(SIGSEGV,&custom_sigaction,NULL);
sigaction(SIGPIPE,&ign_sigaction,NULL);
sigaction(SIGPROF,&profiling_sigaction,NULL);
}