Merge branch 'smarter_error_list' of git://factorcode.org/git/factor into smarter_error_list

db4
Slava Pestov 2009-04-14 15:09:07 -05:00
commit d582c260ac
10 changed files with 70 additions and 65 deletions

View File

@ -309,15 +309,14 @@ M: source-file-error error.
[
[
[ file>> [ % ": " % ] when* ]
[ line#>> [ # ": " % ] when* ]
[ summary % ] tri
[ line#>> [ # ": " % ] when* ] bi
] "" make
] [
[
presented set
bold font-style set
] H{ } make-assoc
] bi format nl
] bi format
] [ error>> error. ] bi ;
M: bad-effect summary

View File

@ -82,7 +82,7 @@ M: object error-line
error get (:edit) ;
: edit-error ( error -- )
[ file>> ] [ line#>> ] bi edit-location ;
[ file>> ] [ line#>> ] bi 2dup and [ edit-location ] [ 2drop ] if ;
: edit-each ( seq -- )
[

View File

@ -76,9 +76,11 @@ $nl
{ $code "." }
"What we just did is called " { $emphasis "interactive testing" } ". A more advanced technique which comes into play with larger programs is " { $link "tools.test" } "."
$nl
"Open the file named " { $snippet "palindrome-tests.factor" } "; it is located in the same directory as " { $snippet "palindrome.factor" } ", and it was created by the scaffold tool."
"Create a test harness file using the scaffold tool:"
{ $code "\"palindrome\" scaffold-tests" }
"Now, open the file named " { $snippet "palindrome-tests.factor" } "; it is located in the same directory as " { $snippet "palindrome.factor" } ", and it was created by the scaffold tool."
$nl
"We will add some unit tests, which are similar to the interactive tests we did above. Unit tests are defined with the " { $link unit-test } " word, which takes a sequence of expected outputs, and a piece of code. It runs the code, and asserts that it outputs the expected values."
"We will add some unit tests, which are similar to the interactive tests we did above. Unit tests are defined with the " { $link POSTPONE: unit-test } " word, which takes a sequence of expected outputs, and a piece of code. It runs the code, and asserts that it outputs the expected values."
$nl
"Add the following three lines to " { $snippet "palindrome-tests.factor" } ":"
{ $code

View File

@ -1,4 +1,4 @@
USING: help.markup help.syntax kernel io system prettyprint ;
USING: help.markup help.syntax kernel io system prettyprint continuations ;
IN: listener
ARTICLE: "listener-watch" "Watching variables in the listener"
@ -41,32 +41,18 @@ $nl
{ $example "{ 1 2 3 } [\n .\n] each" "1\n2\n3" }
"The listener knows when to expect more input by looking at the height of the stack. Parsing words such as " { $link POSTPONE: { } " leave elements on the parser stack, and corresponding words such as " { $link POSTPONE: } } " pop them."
{ $subsection "listener-watch" }
"You can start a nested listener or exit a listener using the following words:"
"To start a nested listener:"
{ $subsection listener }
{ $subsection bye }
"Finally, the multi-line expression reading word can be used independently of the rest of the listener:"
"To exit the listener, invoke the " { $link return } " word."
$nl
"Multi-line quotations can be read independently of the rest of the listener:"
{ $subsection read-quot } ;
ABOUT: "listener"
<PRIVATE
HELP: quit-flag
{ $var-description "Variable set to true by " { $link bye } " word; it forces the next iteration of the " { $link listener } " loop to end." } ;
PRIVATE>
HELP: read-quot
{ $values { "quot/f" "a parsed quotation, or " { $link f } " indicating end of file" } }
{ $description "Reads a Factor expression which possibly spans more than one line from " { $link input-stream } ". Additional lines of input are read while the parser stack height is greater than one. Since structural parsing words push partial quotations on the stack, this will keep on reading input until all delimited parsing words are terminated." } ;
HELP: listen
{ $description "Prompts for an expression on " { $link input-stream } " and evaluates it. On end of file, " { $link quit-flag } " is set to terminate the listener loop." }
{ $errors "If the expression input by the user throws an error, the error is printed to " { $link output-stream } " and the word returns normally." } ;
HELP: listener
{ $description "Prompts for expressions on " { $link input-stream } " and evaluates them until end of file is reached." } ;
HELP: bye
{ $description "Exits the current listener." }
{ $notes "This word is for interactive use only. To exit the Factor runtime, use " { $link exit } "." } ;

View File

@ -4,7 +4,7 @@ USING: arrays hashtables io kernel math math.parser memory
namespaces parser lexer sequences strings io.styles
vectors words generic system combinators continuations debugger
definitions compiler.units accessors colors prettyprint fry
sets vocabs.parser source-files.errors ;
sets vocabs.parser source-files.errors locals ;
IN: listener
GENERIC: stream-read-quot ( stream -- quot/f )
@ -32,14 +32,6 @@ M: object stream-read-quot
: read-quot ( -- quot/f ) input-stream get stream-read-quot ;
<PRIVATE
SYMBOL: quit-flag
PRIVATE>
: bye ( -- ) quit-flag on ;
SYMBOL: visible-vars
: show-var ( var -- ) visible-vars [ swap suffix ] change ;
@ -98,28 +90,43 @@ SYMBOL: error-summary-hook
] dip
] when stack. ;
: stacks. ( -- )
: datastack. ( datastack -- )
display-stacks? get [
datastack [ nl "--- Data stack:" title. trimmed-stack. ] unless-empty
] when ;
[ nl "--- Data stack:" title. trimmed-stack. ] unless-empty
] [ drop ] if ;
: prompt. ( -- )
"( " in get auto-use? get [ " - auto" append ] when " )" 3append
in get auto-use? get [ " - auto" append ] when "( " " )" surround
H{ { background T{ rgba f 1 0.7 0.7 1 } } } format bl flush ;
[ error-summary ] error-summary-hook set-global
: listen ( -- )
error-summary-hook get call( -- ) visible-vars. stacks. prompt.
[ read-quot [ [ call-error-hook ] recover ] [ bye ] if* ]
[ dup lexer-error? [ call-error-hook ] [ rethrow ] if ] recover ;
: call-error-summary-hook ( -- )
error-summary-hook get call( -- ) ;
: until-quit ( -- )
quit-flag get [ quit-flag off ] [ listen until-quit ] if ;
:: (listener) ( datastack -- )
call-error-summary-hook
visible-vars.
datastack datastack.
prompt.
[
read-quot [
'[ datastack _ with-datastack ]
[ call-error-hook datastack ]
recover
(listener)
] when*
] [
dup lexer-error?
[ call-error-hook datastack (listener) ]
[ rethrow ]
if
] recover ;
PRIVATE>
: listener ( -- )
[ until-quit ] with-interactive-vocabs ;
[ [ { } (listener) ] with-interactive-vocabs ] with-return ;
MAIN: listener

View File

@ -42,6 +42,7 @@ $nl
ABOUT: "tools.test"
HELP: unit-test
{ $syntax "[ output ] [ input ] unit-test" }
{ $values { "output" "a sequence of expected stack elements" } { "input" "a quotation run with an empty stack" } }
{ $description "Runs a quotation with an empty stack, comparing the resulting stack with " { $snippet "output" } ". Elements are compared using " { $link = } ". Throws an error if the expected stack does not match the resulting stack." } ;

View File

@ -92,7 +92,7 @@ M: object add-breakpoint ;
: (step-into-call-next-method) ( method -- )
next-method-quot (step-into-quot) ;
{
<< {
(step-into-quot)
(step-into-dip)
(step-into-2dip)
@ -102,7 +102,7 @@ M: object add-breakpoint ;
(step-into-execute)
(step-into-continuation)
(step-into-call-next-method)
} [ t "no-compile" set-word-prop ] each
} [ t "no-compile" set-word-prop ] each >>
! Messages sent to walker thread
SYMBOL: step

View File

@ -37,14 +37,17 @@ error-toggle source-file-table error-table error-display ;
SINGLETON: source-file-renderer
M: source-file-renderer row-columns
drop first2
[ [ source-file-icon ] [ ] [ length number>string ] tri* ] output>array ;
drop first2 [
[ source-file-icon ]
[ "<Listener input>" or ]
[ length number>string ] tri*
] output>array ;
M: source-file-renderer prototype-row
drop source-file-icon "" "" 3array ;
M: source-file-renderer row-value
drop dup [ first <pathname> ] when ;
drop dup [ first [ <pathname> ] [ f ] if* ] when ;
M: source-file-renderer column-titles
drop { "" "File" "Errors" } ;
@ -76,7 +79,7 @@ M: error-renderer row-columns
drop [
{
[ error-type error-icon ]
[ line#>> number>string ]
[ line#>> [ number>string ] [ "" ] if* ]
[ asset>> unparse-short ]
[ error>> summary ]
} cleave
@ -94,11 +97,15 @@ M: error-renderer column-titles
M: error-renderer column-alignment drop { 0 1 0 0 } ;
: sort-errors ( seq -- seq' )
[ [ [ file>> ] [ line#>> ] bi 2array ] compare ] sort ;
[ [ [ asset>> ] [ line#>> ] bi 2array ] keep ] { } map>assoc
sort-keys values ;
: file-matches? ( error pathname/f -- ? )
[ file>> ] [ dup [ string>> ] when ] bi* = ;
: <error-table-model> ( error-list -- model )
[ model>> ] [ source-file>> ] bi
[ [ file>> ] [ string>> ] bi* = ] <search>
[ file-matches? ] <search>
[ sort-errors ] <arrow> ;
:: <error-table> ( error-list -- table )

View File

@ -82,6 +82,8 @@ M: engine-word stack-effect
effect boa
] [ 2drop f ] if ;
M: engine-word where "tuple-dispatch-generic" word-prop where ;
M: engine-word crossref? "forgotten" word-prop not ;
M: engine-word irrelevant? drop t ;

View File

@ -20,18 +20,9 @@ GENERIC: error-type ( error -- type )
new
swap
[ >>asset ]
[
where [ first2 ] [ "<unknown file>" 0 ] if*
[ >>file ] [ >>line# ] bi*
] bi
[ where [ first2 [ >>file ] [ >>line# ] bi* ] when* ] bi
swap >>error ; inline
: delete-file-errors ( seq file type -- )
[
[ swap file>> = ] [ swap error-type = ]
bi-curry* bi and not
] 2curry filter-here ;
SYMBOL: error-types
error-types [ V{ } clone ] initialize
@ -42,8 +33,11 @@ error-types [ V{ } clone ] initialize
: error-icon-path ( type -- icon )
error-types get at icon>> ;
: error-counts ( -- alist )
error-types get [ nip dup quot>> call( -- seq ) length ] assoc-map ;
: error-summary ( -- )
error-types get [ nip dup quot>> call( -- seq ) length ] assoc-map
error-counts
[ nip 0 > ] assoc-filter
[
over
@ -68,3 +62,10 @@ SYMBOL: error-observers
: remove-error-observer ( observer -- ) error-observers get delq ;
: notify-error-observers ( -- ) error-observers get [ errors-changed ] each ;
: delete-file-errors ( seq file type -- )
[
[ swap file>> = ] [ swap error-type = ]
bi-curry* bi and not
] 2curry filter-here
notify-error-observers ;