-don't crash on bad prim #\r
-fixnum/string pseudo-type for error reporting\r
-to_c_string allots too much\r
+- alist -vs- assoc terminology\r
+- some way to run httpd from command line\r
+- 'default responder' for when we go to root\r
+- file responder:\r
+ - directory listings\r
+ - index.html\r
+ - if a directory is requested and URL does not end with /, redirect\r
+- doc strings with native factor\r
\r
+ bignums:\r
\r
-- cached 0/-1/1 should be cross compiled in image\r
-- bignum cross compiling\r
- move some s48_ functions into bignum.c\r
- remove unused functions\r
\r
- fedit broken with listener\r
- maple-like: press enter at old commands to evaluate there\r
- input style after clicking link\r
-- plugin not unloaded\r
- listener backspace overzealous\r
- completion in the listener\r
- special completion for USE:/IN:\r
\r
+ misc:\r
\r
-- alist -vs- assoc terminology\r
- 'cascading' styles\r
- jedit ==> jedit-word, jedit takes a file name\r
-- some way to run httpd from command line\r
- rethink strhead/strtail&co\r
- namespace clone drops static var bindings\r
- ditch expand\r
+ httpd:\r
\r
- quit responder breaks with multithreading\r
-- 'default responder' for when we go to root\r
-- file responder:\r
- - port to native\r
- - if a directory is requested and URL does not end with /, redirect\r
- wiki responder:\r
- port to native\r
- text styles\r
( Bignums )
: 'bignum ( bignum -- tagged )
- 'fixnum ;
-! #! Very bad!
-! object-tag here-as >r
-! bignum-type >header emit
-! 1 emit ( capacity )
-! 0 emit ( sign XXXX )
-! ( bignum -- ) emit r> ;
+ object-tag here-as >r
+ bignum-type >header emit
+ dup 0 = 1 2 ? emit ( capacity )
+ dup 0 < [
+ 1 emit neg emit
+ ] [
+ 0 emit emit
+ ] ifte r> ;
( Special objects )
: f, object-tag here-as "f" set f-type >header emit 0 'fixnum emit ;
: t, object-tag here-as "t" set t-type >header emit 0 'fixnum emit ;
+: 0, 0 'bignum drop ;
+: 1, 1 'bignum drop ;
+: -1, -1 'bignum drop ;
+
( Beginning of the image )
-! The image proper begins with the header, then F, T
+! The image proper begins with the header, then F, T,
+! and the bignums 0, 1, and -1.
-: begin ( -- ) header f, t, ;
+: begin ( -- ) header f, t, 0, 1, -1, ;
( Words )
: negative-array-size-error ( obj -- )
"Cannot allocate array with negative size " write . ;
+: bad-primitive-error ( obj -- )
+ "Bad primitive number: " write . ;
+
: kernel-error. ( obj n -- str )
{
expired-port-error
signal-error
profiling-disabled-error
negative-array-size-error
+ bad-primitive-error
} vector-nth execute ;
: kernel-error? ( obj -- ? )
[ 101 | "fixnum/bignum/ratio" ]
[ 102 | "fixnum/bignum/ratio/float" ]
[ 103 | "fixnum/bignum/ratio/float/complex" ]
+ [ 104 | "fixnum/string" ]
] assoc ;
: java? f ;
USE: stack
: (gcd) ( x y -- z )
- USE: prettyprint .s
dup 0 = [ drop ] [ tuck mod (gcd) ] ifte ;
: gcd ( x y -- z )
IN: scratchpad
+USE: combinators
USE: parser
USE: test
USE: unparser
#include "factor.h"
-void init_bignum(void)
-{
- bignum_zero = bignum_allocate(0,0);
-
- bignum_pos_one = bignum_allocate(1,0);
- (BIGNUM_REF (bignum_pos_one, 0)) = 1;
-
- bignum_neg_one = bignum_allocate(1,1);
- (BIGNUM_REF (bignum_neg_one, 0)) = 1;
-}
-
void primitive_bignump(void)
{
drepl(tag_boolean(typep(BIGNUM_TYPE,dpeek())));
void copy_bignum_constants(void)
{
- bignum_zero = copy_array(bignum_zero);
- bignum_pos_one = copy_array(bignum_pos_one);
- bignum_neg_one = copy_array(bignum_neg_one);
+ copy_object(&bignum_zero);
+ copy_object(&bignum_pos_one);
+ copy_object(&bignum_neg_one);
}
return (ARRAY*)UNTAG(tagged);
}
-ARRAY* bignum_zero;
-ARRAY* bignum_pos_one;
-ARRAY* bignum_neg_one;
+CELL bignum_zero;
+CELL bignum_pos_one;
+CELL bignum_neg_one;
-void init_bignum(void);
void primitive_bignump(void);
ARRAY* to_bignum(CELL tagged);
void primitive_to_bignum(void);
#define ERROR_SIGNAL (10<<3)
#define ERROR_PROFILING_DISABLED (11<<3)
#define ERROR_NEGATIVE_ARRAY_SIZE (12<<3)
+#define ERROR_BAD_PRIMITIVE (13<<3)
void fatal_error(char* msg, CELL tagged);
void critical_error(char* msg, CELL tagged);
load_image(argv[1]);
init_stacks();
init_io();
- init_bignum();
init_signals();
args = F;
gc_debug("collect_roots",scan);
/* these two must be the first in the heap */
copy_object(&F);
- gc_debug("f",F);
copy_object(&T);
- gc_debug("t",T);
- copy_object(&callframe);
+ /* the bignum 0 1 -1 constants must be the next three */
copy_bignum_constants();
+ copy_object(&callframe);
for(ptr = ds_bot; ptr < ds; ptr += CELLS)
copy_object((void*)ptr);
CELL primitive_to_xt(CELL primitive)
{
if(primitive < 0 || primitive >= PRIMITIVE_COUNT)
- critical_error("Bad primitive number",primitive);
+ general_error(ERROR_BAD_PRIMITIVE,tag_fixnum(primitive));
return (CELL)primitives[primitive];
}
}
}
+void init_object(CELL* handle, CELL type)
+{
+ if(untag_header(get(relocating)) != type)
+ fatal_error("init_object() failed",get(relocating));
+ *handle = tag_object((CELL*)relocating);
+ relocate_next();
+}
+
void relocate(CELL r)
{
relocation_base = r;
relocating = active->base;
/* The first two objects in the image must always be F, T */
- if(untag_header(get(relocating)) != F_TYPE)
- fatal_error("Not F",get(relocating));
- F = tag_object((CELL*)relocating);
- relocate_next();
-
- if(untag_header(get(relocating)) != T_TYPE)
- fatal_error("Not T",get(relocating));
- T = tag_object((CELL*)relocating);
- relocate_next();
+ init_object(&F,F_TYPE);
+ init_object(&T,T_TYPE);
+ /* The next three must be bignum 0, 1, -1 */
+ init_object(&bignum_zero,BIGNUM_TYPE);
+ init_object(&bignum_pos_one,BIGNUM_TYPE);
+ init_object(&bignum_neg_one,BIGNUM_TYPE);
+
for(;;)
{
if(relocating >= active->here)
/* These definitions are here to facilitate caching of the constants
0, 1, and -1. */
-#define BIGNUM_ZERO() bignum_zero
+#define BIGNUM_ZERO() (ARRAY*)UNTAG(bignum_zero)
#define BIGNUM_ONE(neg_p) \
- (neg_p ? bignum_neg_one : bignum_pos_one)
+ (ARRAY*)UNTAG(neg_p ? bignum_neg_one : bignum_pos_one)
#define BIGNUM_ONE_P(bignum,negative_p) ((bignum) == BIGNUM_ONE(negative_p))
sbuf_append_string(sbuf,untag_string(object));
break;
default:
- type_error(STRING_TYPE,object);
+ type_error(TEXT_TYPE,object);
break;
}
}
/* untagged */
char* to_c_string(STRING* s)
{
- STRING* _c_str = allot_string(s->capacity + 1 /* null byte */);
+ STRING* _c_str = allot_string(s->capacity / CHARS + 1);
CELL i;
char* c_str = (char*)(_c_str + 1);
#define RATIONAL_TYPE 101 /* INTEGER or RATIO */
#define REAL_TYPE 102 /* RATIONAL or FLOAT */
#define NUMBER_TYPE 103 /* COMPLEX or REAL */
+#define TEXT_TYPE 104 /* FIXNUM or STRING */
CELL type_of(CELL tagged);
bool typep(CELL type, CELL tagged);
if(port->type != PORT_WRITE)
general_error(ERROR_INCOMPATIBLE_PORT,tag_object(port));
- switch(port->type)
+ buf_capacity = port->buffer->capacity * CHARS;
+ /* Is the string longer than the buffer? */
+ if(port->buf_fill == 0 && len > buf_capacity)
{
- case PORT_READ:
- return false;
- case PORT_WRITE:
- buf_capacity = port->buffer->capacity * CHARS;
- /* Is the string longer than the buffer? */
- if(port->buf_fill == 0 && len > buf_capacity)
- {
- /* Increase the buffer to fit the string */
- port->buffer = allot_string(len / CHARS + 1);
- return true;
- }
- else
- return (port->buf_fill + len <= buf_capacity);
- default:
- critical_error("Bad port->type",port->type);
- return false;
+ /* Increase the buffer to fit the string */
+ port->buffer = allot_string(len / CHARS + 1);
+ return true;
}
+ else
+ return (port->buf_fill + len <= buf_capacity);
}
void primitive_can_write(void)
write_string_8(port,str);
break;
default:
- type_error(STRING_TYPE,text);
+ type_error(TEXT_TYPE,text);
break;
}
}