\ c-to-factor c-to-factor-word set
\ lazy-jit-compile lazy-jit-compile-word set
\ unwind-native-frames unwind-native-frames-word set
- [ undefined ] undefined-quot set ;
+ undefined-def undefined-quot set ;
: emit-special-objects ( -- )
special-objects get keys [ emit-special-object ] each ;
def>> . ;
M: undefined summary
- drop "Calling a deferred word before it has been defined" ;
+ word>> undefined?
+ "Cannot call a deferred word before it has been defined"
+ "Cannot call a word before it has been compiled"
+ ? ;
M: no-compilation-unit error.
"Attempting to define " write
-! Copyright (C) 2003, 2009 Slava Pestov.
+! Copyright (C) 2003, 2010 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: arrays accessors assocs colors combinators grouping io
io.streams.string io.styles kernel make math math.parser namespaces
parser prettyprint.backend prettyprint.config prettyprint.custom
prettyprint.sections quotations sequences sorting strings vocabs
-vocabs.prettyprint words sets ;
+vocabs.prettyprint words sets generic ;
IN: prettyprint
: with-use ( obj quot -- )
] [ ] make ;
: remove-breakpoints ( quot pos -- quot' )
- over quotation? [
- 1 + short cut [ (remove-breakpoints) ] bi@
- [ -> ] glue
- ] [
- drop
- ] if ;
-
-PRIVATE>
+ 1 + short cut [ (remove-breakpoints) ] bi@ [ -> ] glue ;
-: callstack. ( callstack -- )
- callstack>array 2 <groups> [
+: callframe. ( triple -- )
+ first3
+ [
+ {
+ { [ dup method-body? ] [ "Method: " write . ] }
+ { [ dup word? ] [ "Word: " write . ] }
+ [ drop ]
+ } cond
+ ] 2dip
+ over quotation? [
+ "Quotation: " write
remove-breakpoints
[
3 nesting-limit set
100 length-limit set
.
] with-scope
- ] assoc-each ;
+ ] [ 2drop ] if ;
+
+PRIVATE>
+
+: callstack. ( callstack -- )
+ callstack>array 3 <groups> [ nl ] [ callframe. ] interleave ;
: .c ( -- ) callstack callstack. ;
"DEFER:" [
scan current-vocab create
- [ fake-definition ] [ set-word ] [ [ undefined ] define ] tri
+ [ fake-definition ] [ set-word ] [ undefined-def define ] tri
] define-core-syntax
"ALIAS:" [
FORGET: another-forgotten
: another-forgotten ( -- ) ;
+! Make sure that undefined words throw proper errors
+DEFER: deferred
+[ deferred ] [ T{ undefined f deferred } = ] must-fail-with
-DEFER: x
-[ x ] [ undefined? ] must-fail-with
+[ "IN: words.tests DEFER: not-compiled << not-compiled >>" eval( -- ) ]
+[ error>> [ undefined? ] [ word>> name>> "not-compiled" = ] bi and ] must-fail-with
+
+[ ] [ "IN: words.tests FORGET: not-compiled" eval( -- ) ] unit-test
[ ] [ [ "no-loc" "words.tests" create drop ] with-compilation-unit ] unit-test
[ f ] [ "no-loc" "words.tests" lookup where ] unit-test
: reset-props ( word seq -- ) [ remove-word-prop ] with each ;
-ERROR: undefined ;
+<PRIVATE
-PREDICATE: deferred < word ( obj -- ? ) def>> [ undefined ] = ;
+: caller ( callstack -- word ) callstack>array <reversed> third ;
+
+PRIVATE>
+
+TUPLE: undefined word ;
+: undefined ( -- * ) callstack caller \ undefined boa throw ;
+
+: undefined-def ( -- quot )
+ #! 'f' inhibits tail call optimization in non-optimizing
+ #! compiler, ensuring that we can pull out the caller word
+ #! above.
+ [ undefined f ] ;
+
+PREDICATE: deferred < word ( obj -- ? ) def>> undefined-def = ;
M: deferred definer drop \ DEFER: f ;
M: deferred definition drop f ;
void operator()(stack_frame *frame)
{
- data_root<object> executing(parent->frame_executing_quot(frame),parent);
+ data_root<object> executing_quot(parent->frame_executing_quot(frame),parent);
+ data_root<object> executing(parent->frame_executing(frame),parent);
data_root<object> scan(parent->frame_scan(frame),parent);
frames.add(executing.value());
+ frames.add(executing_quot.value());
frames.add(scan.value());
}
};