CL-style (but more limited) restarts, better undefined word handling in the parser

slava 2006-05-24 08:29:25 +00:00
parent 3856c26f69
commit c90c1d66da
15 changed files with 265 additions and 207 deletions

View File

@ -57,7 +57,6 @@
- focus is not top-level window aware - focus is not top-level window aware
- display lists - display lists
- saving the image should save window configuration - saving the image should save window configuration
- fix up the min thumb size hack
- variable width word wrap - variable width word wrap
- new gesture style - new gesture style

View File

@ -11,9 +11,8 @@ vectors words ;
: parse-resource* ( path -- ) : parse-resource* ( path -- )
[ parse-resource ] catch [ [ parse-resource ] catch [
dup error. { { "Parse file again" t } } condition drop
"Try again? [yn]" print flush readln "yY" subseq? parse-resource*
[ drop parse-resource* ] [ rethrow ] if
] when* ; ] when* ;
: if-arch ( arch seq -- ) : if-arch ( arch seq -- )
@ -80,7 +79,7 @@ vectors words ;
"/library/io/files.factor" "/library/io/files.factor"
"/library/io/binary.factor" "/library/io/binary.factor"
"/library/syntax/parser.factor" "/library/syntax/early-parser.factor"
"/library/generic/generic.factor" "/library/generic/generic.factor"
"/library/generic/standard-combination.factor" "/library/generic/standard-combination.factor"
@ -92,6 +91,7 @@ vectors words ;
"/library/syntax/prettyprint.factor" "/library/syntax/prettyprint.factor"
"/library/syntax/see.factor" "/library/syntax/see.factor"
"/library/syntax/parser.factor"
"/library/tools/interpreter.factor" "/library/tools/interpreter.factor"
@ -104,9 +104,9 @@ vectors words ;
"/library/tools/describe.factor" "/library/tools/describe.factor"
"/library/tools/debugger.factor" "/library/tools/debugger.factor"
"/library/syntax/parse-stream.factor"
"/library/syntax/parse-stream.factor"
"/library/tools/memory.factor" "/library/tools/memory.factor"
"/library/tools/listener.factor" "/library/tools/listener.factor"
"/library/tools/walker.factor" "/library/tools/walker.factor"
@ -260,6 +260,7 @@ vectors words ;
"/library/math/ratio.facts" "/library/math/ratio.facts"
"/library/math/trig-hyp.facts" "/library/math/trig-hyp.facts"
"/library/math/vectors.facts" "/library/math/vectors.facts"
"/library/syntax/early-parser.facts"
"/library/syntax/parse-stream.facts" "/library/syntax/parse-stream.facts"
"/library/syntax/parser.facts" "/library/syntax/parser.facts"
"/library/syntax/parse-syntax.facts" "/library/syntax/parse-syntax.facts"

View File

@ -1,7 +1,7 @@
! Copyright (C) 2004, 2005 Slava Pestov. ! Copyright (C) 2004, 2005 Slava Pestov.
! See http://factor.sf.net/license.txt for BSD license. ! See http://factor.sf.net/license.txt for BSD license.
IN: kernel-internals IN: kernel-internals
USING: sequences ; USING: generic sequences ;
: >c ( continuation -- ) catchstack* push ; : >c ( continuation -- ) catchstack* push ;
: c> ( -- continuation ) catchstack* pop ; : c> ( -- continuation ) catchstack* pop ;
@ -24,4 +24,25 @@ USING: kernel ;
[ >c drop call c> drop ] [ >c drop call c> drop ]
[ drop (continue-with) rot drop swap call ] ifcc ; inline [ drop (continue-with) rot drop swap call ] ifcc ; inline
TUPLE: condition restarts cc ;
C: condition ( error restarts cc -- condition )
[ set-condition-cc ] keep
[ set-condition-restarts ] keep
[ set-delegate ] keep ;
: condition ( error restarts -- value )
[ <condition> throw ] callcc1 2nip ;
GENERIC: compute-restarts
M: object compute-restarts drop { } ;
M: tuple compute-restarts delegate compute-restarts ;
M: condition compute-restarts
[ delegate compute-restarts ] keep
[ condition-cc ] keep
condition-restarts [ swap add ] map-with append ;
GENERIC: error. ( error -- ) GENERIC: error. ( error -- )

View File

@ -1,34 +1,34 @@
! Copyright (C) 2004, 2005 Slava Pestov. ! Copyright (C) 2004, 2006 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
IN: math IN: math
USING: errors generic kernel math-internals namespaces sequences USING: errors generic kernel math-internals namespaces sequences
strings ; strings ;
: not-a-number "Not a number" throw ;
DEFER: base> DEFER: base>
: string>ratio ( "a/b" radix -- a/b ) : string>ratio ( "a/b" radix -- a/b )
>r "/" split1 r> tuck base> >r base> r> / ; >r "/" split1 r> tuck base> >r base> r>
2dup and [ / ] [ 2drop f ] if ;
GENERIC: digit> ( ch -- n ) GENERIC: digit> ( ch -- n )
M: digit digit> CHAR: 0 - ; M: digit digit> CHAR: 0 - ;
M: letter digit> CHAR: a - 10 + ; M: letter digit> CHAR: a - 10 + ;
M: LETTER digit> CHAR: A - 10 + ; M: LETTER digit> CHAR: A - 10 + ;
M: object digit> not-a-number ; M: object digit> drop f ;
: digit+ ( num digit base -- num ) : digit+ ( num digit base -- num )
2dup < [ rot * + ] [ not-a-number ] if ; pick pick and
[ 2dup < [ rot * + ] [ 3drop f ] if ] [ 3drop f ] if ;
: (string>integer) ( base str -- num ) : (string>integer) ( radix str -- num )
dup empty? [ dup empty? [
not-a-number 2drop f
] [ ] [
0 [ digit> pick digit+ ] reduce nip 0 [ digit> pick digit+ ] reduce nip
] if ; ] if ;
: string>integer ( string -- n ) : string>integer ( string radix -- n )
swap "-" ?head >r (string>integer) r> [ neg ] when ; swap "-" ?head >r (string>integer) dup r> and [ neg ] when ;
: base> ( string radix -- n ) : base> ( string radix -- n )
{ {

View File

@ -0,0 +1,48 @@
! Copyright (C) 2005, 2006 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
IN: parser
USING: arrays errors generic hashtables kernel math namespaces
sequences strings vectors words ;
SYMBOL: use
SYMBOL: in
SYMBOL: file
SYMBOL: line-number
SYMBOL: line-text
SYMBOL: column
: check-vocab ( name -- vocab )
dup vocab
[ ] [ " is not a vocabulary name" append throw ] ?if ;
: use+ ( string -- ) check-vocab use get push ;
: add-use ( seq -- ) [ use+ ] each ;
: set-use ( seq -- ) [ check-vocab ] map >vector use set ;
: set-in ( name -- ) dup ensure-vocab dup in set use+ ;
: parsing? ( word -- ? )
dup word? [ "parsing" word-prop ] [ drop f ] if ;
: save-location ( word -- )
dup set-word
dup line-number get "line" set-word-prop
file get "file" set-word-prop ;
: create-in in get create dup save-location ;
: create-constructor ( class -- word )
word-name in get constructor-word dup save-location ;
TUPLE: parse-error file line col text ;
C: parse-error ( error -- error )
file get over set-parse-error-file
line-number get over set-parse-error-line
column get over set-parse-error-col
line-text get over set-parse-error-text
[ set-delegate ] keep ;

View File

@ -0,0 +1,75 @@
USING: help kernel parser sequences ;
IN: help : $parsing-note
drop "This word should only be called from parsing words." $notes ;
HELP: use f
{ $description "A variable holding the current vocabulary search path as a sequence of hashtables." }
{ $see-also in use+ set-use POSTPONE: USING: POSTPONE: USE: } ;
HELP: in f
{ $description "A variable holding the current vocabulary for new definitions." }
{ $see-also use set-in POSTPONE: IN: } ;
HELP: check-vocab "( name -- vocab )"
{ $values { "name" "a string" } { "vocab" "a hashtable" } }
{ $description "Outputs a named vocabulary." }
{ $errors "Throws an error if the vocabulary does not exist." } ;
HELP: use+ "( vocab -- )"
{ $values { "vocab" "a string" } }
{ $description "Adds a new vocabulary at the front of the search path. Subsequent word lookups by the parser will search this vocabulary first." }
$parsing-note
{ $errors "Throws an error if the vocabulary does not exist." }
{ $see-also in use add-use set-use POSTPONE: USE: } ;
HELP: set-use "( seq -- )"
{ $values { "seq" "a sequence of strings" } }
{ $description "Sets the vocabulary search path. Later vocabularies take precedence." }
{ $errors "Throws an error if one of the vocabularies does not exist." }
$parsing-note
{ $see-also in use use+ add-use file-vocabs } ;
HELP: add-use "( seq -- )"
{ $values { "seq" "a sequence of strings" } }
{ $description "Adds multiple vocabularies to the search path, with later vocabularies taking precedence." }
{ $errors "Throws an error if one of the vocabularies does not exist." }
$parsing-note
{ $see-also in use use+ set-use POSTPONE: USING: } ;
HELP: set-in "( name -- )"
{ $values { "name" "a string" } }
{ $description "Sets the current vocabulary where new words will be defined, creating the vocabulary first if it does not exist." }
$parsing-note
{ $see-also in use POSTPONE: IN: } ;
HELP: parsing? "( obj -- ? )"
{ $values { "obj" "an object" } { "?" "a boolean" } }
{ $description "Tests if an object is a parsing word." }
{ $notes "Outputs " { $link f } " if the object is not a word." } ;
HELP: file f
{ $description "Variable stores the file name being parsed. This is the input parameter to " { $link parse-stream } "." } ;
HELP: line-number f
{ $description "Variable holds the line number being parsed." } ;
HELP: line-text f
{ $description "Variable holds the text of the line being parsed." } ;
HELP: column f
{ $description "Variable holds the column number being parsed." } ;
HELP: save-location "( word -- )"
{ $values { "word" "a word" } }
{ $description "Sets the " { $snippet "\"file\"" } " and " { $snippet "\"line\"" } " word properties to the current parser location." }
$parsing-note ;
HELP: create-in "( string -- word )"
{ $values { "string" "a word name" } { "word" "a new word" } }
{ $description "Creates a word in the current vocabulary. Until re-defined, the word throws an error when invoked." }
$parsing-note ;
HELP: create-constructor "( word -- constructor )"
{ $values { "class" "a word" } { "constructor" "a new word" } }
{ $description "Creates a new word in the current vocabulary, named by surrounding " { $snippet "word" } " with angle brackets." } ;

View File

@ -7,7 +7,8 @@ words ;
: file-vocabs ( -- ) : file-vocabs ( -- )
"scratchpad" set-in { "syntax" "scratchpad" } set-use ; "scratchpad" set-in { "syntax" "scratchpad" } set-use ;
: with-parser ( quot -- ) [ <parse-error> rethrow ] recover ; : with-parser ( quot -- )
[ [ <parse-error> rethrow ] recover ] with-scope ;
: parse-lines ( lines -- quot ) : parse-lines ( lines -- quot )
[ [

View File

@ -1,41 +1,8 @@
! Copyright (C) 2005, 2006 Slava Pestov. ! Copyright (C) 2005, 2006 Slava Pestov.
! See http://factor.sf.net/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
IN: parser IN: parser
USING: errors generic hashtables kernel math namespaces USING: arrays errors generic hashtables kernel math namespaces
sequences strings vectors words ; prettyprint sequences strings vectors words ;
SYMBOL: use
SYMBOL: in
: check-vocab ( name -- vocab )
dup vocab
[ ] [ " is not a vocabulary name" append throw ] ?if ;
: use+ ( string -- ) check-vocab use get push ;
: add-use ( seq -- ) [ use+ ] each ;
: set-use ( seq -- ) [ check-vocab ] map >vector use set ;
: set-in ( name -- ) dup ensure-vocab dup in set use+ ;
: parsing? ( word -- ? )
dup word? [ "parsing" word-prop ] [ drop f ] if ;
SYMBOL: file
SYMBOL: line-number
SYMBOL: line-text
SYMBOL: column
TUPLE: parse-error file line col text ;
C: parse-error ( error -- error )
file get over set-parse-error-file
line-number get over set-parse-error-line
column get over set-parse-error-col
line-text get over set-parse-error-text
[ set-delegate ] keep ;
: skip ( i seq quot -- n | quot: elt -- ? ) : skip ( i seq quot -- n | quot: elt -- ? )
over >r find* drop dup -1 = over >r find* drop dup -1 =
@ -55,24 +22,29 @@ C: parse-error ( error -- error )
column [ line-text get (scan) dup ] change column [ line-text get (scan) dup ] change
2dup = [ 2drop f ] [ line-text get subseq ] if ; 2dup = [ 2drop f ] [ line-text get subseq ] if ;
: save-location ( word -- )
dup set-word
dup line-number get "line" set-word-prop
file get "file" set-word-prop ;
: create-in in get create dup save-location ;
: create-constructor ( class -- word )
word-name in get constructor-word dup save-location ;
: CREATE ( -- word ) scan create-in ; : CREATE ( -- word ) scan create-in ;
SYMBOL: string-mode SYMBOL: string-mode
: do-what-i-mean ( string -- restarts )
all-words [ word-name = ] subset-with natural-sort [
[ "Use the word " swap synopsis append ] keep 2array
] map ;
: word-not-found ( str -- word )
"No word named "
over
" found in current vocabulary search path" append3
swap do-what-i-mean condition ;
: scan-word ( -- obj ) : scan-word ( -- obj )
scan dup [ scan dup [
dup ";" = not string-mode get and [ dup ";" = not string-mode get and [
dup use get hash-stack [ ] [ string>number ] ?if dup use get hash-stack [ ] [
dup string>number [ ] [
word-not-found dup word-vocabulary use+
] ?if
] ?if
] unless ] unless
] when ; ] when ;
@ -118,11 +90,11 @@ SYMBOL: string-mode
global [ global [
{ {
"scratchpad" "syntax" "alien" "arrays" "compiler" "scratchpad" "syntax" "arrays" "compiler"
"errors" "generic" "hashtables" "help" "inference" "errors" "generic" "hashtables" "help" "inference"
"inspector" "io" "jedit" "kernel" "listener" "math" "inspector" "io" "jedit" "kernel" "listener" "math"
"memory" "namespaces" "optimizer" "parser" "prettyprint" "memory" "namespaces" "parser" "prettyprint"
"queues" "sequences" "shells" "strings" "styles" "test" "sequences" "shells" "strings" "styles" "test"
"threads" "vectors" "walker" "words" "threads" "vectors" "walker" "words"
} set-use } set-use
"scratchpad" set-in "scratchpad" set-in

View File

@ -1,65 +1,5 @@
USING: help kernel parser sequences ; USING: help kernel parser sequences ;
IN: help : $parsing-note
drop "This word should only be called from parsing words." $notes ;
HELP: use f
{ $description "A variable holding the current vocabulary search path as a sequence of hashtables." }
{ $see-also in use+ set-use POSTPONE: USING: POSTPONE: USE: } ;
HELP: in f
{ $description "A variable holding the current vocabulary for new definitions." }
{ $see-also use set-in POSTPONE: IN: } ;
HELP: check-vocab "( name -- vocab )"
{ $values { "name" "a string" } { "vocab" "a hashtable" } }
{ $description "Outputs a named vocabulary." }
{ $errors "Throws an error if the vocabulary does not exist." } ;
HELP: use+ "( vocab -- )"
{ $values { "vocab" "a string" } }
{ $description "Adds a new vocabulary at the front of the search path. Subsequent word lookups by the parser will search this vocabulary first." }
$parsing-note
{ $errors "Throws an error if the vocabulary does not exist." }
{ $see-also in use add-use set-use POSTPONE: USE: } ;
HELP: set-use "( seq -- )"
{ $values { "seq" "a sequence of strings" } }
{ $description "Sets the vocabulary search path. Later vocabularies take precedence." }
{ $errors "Throws an error if one of the vocabularies does not exist." }
$parsing-note
{ $see-also in use use+ add-use file-vocabs } ;
HELP: add-use "( seq -- )"
{ $values { "seq" "a sequence of strings" } }
{ $description "Adds multiple vocabularies to the search path, with later vocabularies taking precedence." }
{ $errors "Throws an error if one of the vocabularies does not exist." }
$parsing-note
{ $see-also in use use+ set-use POSTPONE: USING: } ;
HELP: set-in "( name -- )"
{ $values { "name" "a string" } }
{ $description "Sets the current vocabulary where new words will be defined, creating the vocabulary first if it does not exist." }
$parsing-note
{ $see-also in use POSTPONE: IN: } ;
HELP: parsing? "( obj -- ? )"
{ $values { "obj" "an object" } { "?" "a boolean" } }
{ $description "Tests if an object is a parsing word." }
{ $notes "Outputs " { $link f } " if the object is not a word." } ;
HELP: file f
{ $description "Variable stores the file name being parsed. This is the input parameter to " { $link parse-stream } "." } ;
HELP: line-number f
{ $description "Variable holds the line number being parsed." } ;
HELP: line-text f
{ $description "Variable holds the text of the line being parsed." } ;
HELP: column f
{ $description "Variable holds the column number being parsed." } ;
HELP: skip "( i seq quot -- n )" HELP: skip "( i seq quot -- n )"
{ $values { "n" "a starting index" } { "seq" "a sequence" } { "quot" "a quotation with stack effect " { $snippet "( elt -- ? )" } } } { $values { "n" "a starting index" } { "seq" "a sequence" } { "quot" "a quotation with stack effect " { $snippet "( elt -- ? )" } } }
{ $description "Variant of " { $link find* } " that outputs the length of the sequence instead of -1 if no elements satisfy the predicate." } ; { $description "Variant of " { $link find* } " that outputs the length of the sequence instead of -1 if no elements satisfy the predicate." } ;
@ -82,20 +22,6 @@ HELP: scan "( -- token )"
{ $description "Reads the next token from the line currently being parsed. This is the key word that the Factor parser is built on." } { $description "Reads the next token from the line currently being parsed. This is the key word that the Factor parser is built on." }
$parsing-note ; $parsing-note ;
HELP: save-location "( word -- )"
{ $values { "word" "a word" } }
{ $description "Sets the " { $snippet "\"file\"" } " and " { $snippet "\"line\"" } " word properties to the current parser location." }
$parsing-note ;
HELP: create-in "( string -- word )"
{ $values { "string" "a word name" } { "word" "a new word" } }
{ $description "Creates a word in the current vocabulary. Until re-defined, the word throws an error when invoked." }
$parsing-note ;
HELP: create-constructor "( word -- constructor )"
{ $values { "class" "a word" } { "constructor" "a new word" } }
{ $description "Creates a new word in the current vocabulary, named by surrounding " { $snippet "word" } " with angle brackets." } ;
HELP: CREATE "( -- word )" HELP: CREATE "( -- word )"
{ $values { "word" "a word" } } { $values { "word" "a word" } }
{ $description "Reads the next token from the line currently being parsed, and creates a word with that name in the current vocabulary." } { $description "Reads the next token from the line currently being parsed, and creates a word with that name in the current vocabulary." }

View File

@ -1,116 +1,112 @@
IN: temporary IN: temporary
USING: errors kernel math parser sequences test ; USING: errors kernel math parser sequences test ;
: parse-number ( str -- num )
#! Convert a string to a number; return f on error.
[ string>number ] catch [ drop f ] when ;
[ f ] [ f ]
[ f parse-number ] [ f string>number ]
unit-test unit-test
[ f ] [ f ]
[ "12345abcdef" parse-number ] [ "12345abcdef" string>number ]
unit-test unit-test
[ t ] [ t ]
[ "-12" parse-number 0 < ] [ "-12" string>number 0 < ]
unit-test unit-test
[ f ] [ f ]
[ "--12" parse-number ] [ "--12" string>number ]
unit-test unit-test
[ f ] [ f ]
[ "-" parse-number ] [ "-" string>number ]
unit-test unit-test
[ f ] [ f ]
[ "e" parse-number ] [ "e" string>number ]
unit-test unit-test
[ "100.0" ] [ "100.0" ]
[ "1.0e2" parse-number number>string ] [ "1.0e2" string>number number>string ]
unit-test unit-test
[ "-100.0" ] [ "-100.0" ]
[ "-1.0e2" parse-number number>string ] [ "-1.0e2" string>number number>string ]
unit-test unit-test
[ "0.01" ] [ "0.01" ]
[ "1.0e-2" parse-number number>string ] [ "1.0e-2" string>number number>string ]
unit-test unit-test
[ "-0.01" ] [ "-0.01" ]
[ "-1.0e-2" parse-number number>string ] [ "-1.0e-2" string>number number>string ]
unit-test unit-test
[ f ] [ f ]
[ "-1e-2e4" parse-number ] [ "-1e-2e4" string>number ]
unit-test unit-test
[ "3.14" ] [ "3.14" ]
[ "3.14" parse-number number>string ] [ "3.14" string>number number>string ]
unit-test unit-test
[ f ] [ f ]
[ "." parse-number ] [ "." string>number ]
unit-test unit-test
[ f ] [ f ]
[ ".e" parse-number ] [ ".e" string>number ]
unit-test unit-test
[ "101.0" ] [ "101.0" ]
[ "1.01e2" parse-number number>string ] [ "1.01e2" string>number number>string ]
unit-test unit-test
[ "-101.0" ] [ "-101.0" ]
[ "-1.01e2" parse-number number>string ] [ "-1.01e2" string>number number>string ]
unit-test unit-test
[ "1.01" ] [ "1.01" ]
[ "101.0e-2" parse-number number>string ] [ "101.0e-2" string>number number>string ]
unit-test unit-test
[ "-1.01" ] [ "-1.01" ]
[ "-101.0e-2" parse-number number>string ] [ "-101.0e-2" string>number number>string ]
unit-test unit-test
[ 5 ] [ 5 ]
[ "10/2" parse-number ] [ "10/2" string>number ]
unit-test unit-test
[ -5 ] [ -5 ]
[ "-10/2" parse-number ] [ "-10/2" string>number ]
unit-test unit-test
[ -5 ] [ -5 ]
[ "10/-2" parse-number ] [ "10/-2" string>number ]
unit-test unit-test
[ 5 ] [ 5 ]
[ "-10/-2" parse-number ] [ "-10/-2" string>number ]
unit-test unit-test
[ 5.0 ] [ 5.0 ]
[ "10.0/2" parse-number ] [ "10.0/2" string>number ]
unit-test unit-test
[ f ] [ f ]
[ "1e1/2" parse-number ] [ "1e1/2" string>number ]
unit-test unit-test
[ f ] [ f ]
[ "e/2" parse-number ] [ "e/2" string>number ]
unit-test unit-test
[ "33/100" ] [ "33/100" ]
[ "66/200" parse-number number>string ] [ "66/200" string>number number>string ]
unit-test unit-test
[ "12" bin> ] unit-test-fails [ f ] [ "12" bin> ] unit-test
[ "fdsf" bin> ] unit-test-fails [ f ] [ "fdsf" bin> ] unit-test
[ 3 ] [ "11" bin> ] unit-test [ 3 ] [ "11" bin> ] unit-test
[ t ] [ [ t ] [

View File

@ -7,6 +7,7 @@ sequences-internals strings vectors words ;
SYMBOL: error SYMBOL: error
SYMBOL: error-continuation SYMBOL: error-continuation
SYMBOL: restarts
: expired-error. ( obj -- ) : expired-error. ( obj -- )
"Object did not survive image save/load: " write third . ; "Object did not survive image save/load: " write third . ;
@ -23,9 +24,6 @@ SYMBOL: error-continuation
"Object type: " write dup fourth class . "Object type: " write dup fourth class .
"Expected type: " write third type>class . ; "Expected type: " write third type>class . ;
: float-format-error. ( list -- )
"Invalid floating point literal format: " write third . ;
: signal-error. ( obj -- ) : signal-error. ( obj -- )
"Operating system signal " write third . ; "Operating system signal " write third . ;
@ -67,7 +65,6 @@ M: kernel-error error. ( error -- )
[ io-error. ] [ io-error. ]
[ undefined-word-error. ] [ undefined-word-error. ]
[ type-check-error. ] [ type-check-error. ]
[ float-format-error. ]
[ signal-error. ] [ signal-error. ]
[ negative-array-size-error. ] [ negative-array-size-error. ]
[ c-string-error. ] [ c-string-error. ]
@ -114,6 +111,8 @@ M: parse-error error. ( error -- )
M: bounds-error summary drop "Sequence index out of bounds" ; M: bounds-error summary drop "Sequence index out of bounds" ;
M: condition error. delegate error. ;
M: tuple error. ( error -- ) describe ; M: tuple error. ( error -- ) describe ;
M: object error. ( error -- ) . ; M: object error. ( error -- ) . ;
@ -127,7 +126,20 @@ M: object error. ( error -- ) . ;
: :get ( var -- value ) : :get ( var -- value )
error-continuation get continuation-name hash-stack ; error-continuation get continuation-name hash-stack ;
: :res ( n -- ) restarts get nth first3 continue-with ;
: restarts. ( -- )
restarts get dup empty? [
drop
] [
"The following restarts are available:" print
dup length [
number>string write " :res " write first print
] 2each
] if ;
: debug-help ( -- ) : debug-help ( -- )
restarts.
":s :r :c show stacks at time of error" print ":s :r :c show stacks at time of error" print
":get ( var -- value ) accesses variables at time of error" print ":get ( var -- value ) accesses variables at time of error" print
":error starts the inspector with the error" print ":error starts the inspector with the error" print
@ -144,7 +156,9 @@ M: object error. ( error -- ) . ;
: try ( quot -- ) [ print-error terpri debug-help ] recover ; : try ( quot -- ) [ print-error terpri debug-help ] recover ;
: save-error ( error continuation -- ) : save-error ( error continuation -- )
error-continuation set-global error set-global ; error-continuation set-global
dup error set-global
compute-restarts restarts set-global ;
: error-handler ( error -- ) : error-handler ( error -- )
dup continuation save-error rethrow ; dup continuation save-error rethrow ;

View File

@ -15,7 +15,7 @@ SYMBOL: error-hook
[ drop terpri debug-help ] error-hook set-global [ drop terpri debug-help ] error-hook set-global
: bye ( -- ) quit-flag on ; : bye ( -- ) quit-flag on ;
help
: (read-multiline) ( quot depth -- quot ? ) : (read-multiline) ( quot depth -- quot ? )
>r readln dup [ >r readln dup [
(parse) depth r> dup >r <= [ (parse) depth r> dup >r <= [
@ -28,7 +28,9 @@ SYMBOL: error-hook
] if ; ] if ;
: read-multiline ( -- quot ? ) : read-multiline ( -- quot ? )
[ f depth (read-multiline) >r >quotation r> ] with-parser ; [
f depth (read-multiline) >r >quotation r> in get
] with-parser in set ;
: listen-try : listen-try
[ [

View File

@ -48,10 +48,10 @@ void primitive_die(void)
factorbug(); factorbug();
} }
void general_error(CELL error, CELL arg1, CELL arg2, bool keep_stacks) void general_error(F_ERRORTYPE error, CELL arg1, CELL arg2, bool keep_stacks)
{ {
CELL thrown = make_array_4(userenv[ERROR_ENV],error,arg1,arg2); throw_error(make_array_4(userenv[ERROR_ENV],
throw_error(thrown,keep_stacks); tag_fixnum(error),arg1,arg2),keep_stacks);
} }
/* It is not safe to access 'ds' from a signal handler, so we just not /* It is not safe to access 'ds' from a signal handler, so we just not

View File

@ -1,22 +1,24 @@
#define ERROR_EXPIRED (0<<3) typedef enum
#define ERROR_IO (1<<3) {
#define ERROR_UNDEFINED_WORD (2<<3) ERROR_EXPIRED
#define ERROR_TYPE (3<<3) ERROR_IO
#define ERROR_FLOAT_FORMAT (4<<3) ERROR_UNDEFINED_WORD
#define ERROR_SIGNAL (5<<3) ERROR_TYPE
#define ERROR_NEGATIVE_ARRAY_SIZE (6<<3) ERROR_SIGNAL
#define ERROR_C_STRING (7<<3) ERROR_NEGATIVE_ARRAY_SIZE
#define ERROR_FFI (8<<3) ERROR_C_STRING
#define ERROR_HEAP_SCAN (9<<3) ERROR_FFI
#define ERROR_UNDEFINED_SYMBOL (10<<3) ERROR_HEAP_SCAN
#define ERROR_USER_INTERRUPT (11<<3) ERROR_UNDEFINED_SYMBOL
#define ERROR_DS_UNDERFLOW (12<<3) ERROR_USER_INTERRUPT
#define ERROR_DS_OVERFLOW (13<<3) ERROR_DS_UNDERFLOW
#define ERROR_RS_UNDERFLOW (14<<3) ERROR_DS_OVERFLOW
#define ERROR_RS_OVERFLOW (15<<3) ERROR_RS_UNDERFLOW
#define ERROR_CS_UNDERFLOW (16<<3) ERROR_RS_OVERFLOW
#define ERROR_CS_OVERFLOW (17<<3) ERROR_CS_UNDERFLOW
#define ERROR_OBJECTIVE_C (18<<3) ERROR_CS_OVERFLOW
ERROR_OBJECTIVE_C
} F_ERRORTYPE;
/* Are we throwing an error? */ /* Are we throwing an error? */
bool throwing; bool throwing;
@ -32,7 +34,7 @@ void fatal_error(char* msg, CELL tagged);
void critical_error(char* msg, CELL tagged); void critical_error(char* msg, CELL tagged);
void throw_error(CELL error, bool keep_stacks); void throw_error(CELL error, bool keep_stacks);
void early_error(CELL error); void early_error(CELL error);
void general_error(CELL error, CELL arg1, CELL arg2, bool keep_stacks); void general_error(F_ERRORTYPE error, CELL arg1, CELL arg2, bool keep_stacks);
void signal_error(int signal); void signal_error(int signal);
void type_error(CELL type, CELL tagged); void type_error(CELL type, CELL tagged);
void primitive_throw(void); void primitive_throw(void);

View File

@ -44,8 +44,9 @@ void primitive_str_to_float(void)
end = c_str; end = c_str;
f = strtod(c_str,&end); f = strtod(c_str,&end);
if(end != c_str + string_capacity(str)) if(end != c_str + string_capacity(str))
general_error(ERROR_FLOAT_FORMAT,tag_object(str),F,true); drepl(F);
drepl(tag_float(f)); else
drepl(tag_float(f));
} }
void primitive_float_to_str(void) void primitive_float_to_str(void)