implementation module StdException /* StdException -- version 1.2 Written by Arjen van Weelden (with the help of John van Groningen), University of Nijmegen Send comments and bug reports to arjenw@cs.kun.nl. */ import StdDynamic :: Catch a = Catch /*h ::*/ .(Dynamic -> a) /*Psp ::*/ !Int /*BCsp ::*/ !Int raise :: e -> .a | TC e raise exception = raiseDynamic (dynamic exception :: e^) raiseDynamic :: Dynamic -> .a raiseDynamic dyn = raise_ (Catch omega 0 0) (raiseDynamic dyn) dyn where omega :: .a omega => omega (catchIO) infixl 0 :: !u:(*env -> (.a, *env)) v:(e -> u:(*env -> (.a, *env))) -> u:(*env -> (.a, *env)) | TC e & ExceptionEnv env, [u <= v] (catchIO) f h = f catchAllIO match h (catchAll) infixl 0 :: u:a v:(Dynamic -> u:a) -> w:(*env -> (u:a, *env)) | ExceptionEnv env, [w <= u, w <= v] (catchAll) x h = f x h where f :: .a .(Dynamic -> .a) !*env -> (!.a, !*env) f x h env = (x unsafeCatchAll h, env) (catch) infixl 0 :: u:a v:(e -> u:a) -> w:(*env -> (u:a, *env)) | TC e & ExceptionEnv env, [w <= u, w <= v] (catch) x h = x catchAll match h /*f x h where f :: .a .(e -> .a) !*env -> (!.a, !*env) | TC e f x h env = (x unsafeCatch h, env)*/ getExceptionIO :: !.(*env -> (.a, *env)) !*env -> (MaybeException .a, !*env) | ExceptionEnv env getExceptionIO f env = (g f catchAllIO h) env where g :: !.(*env -> (.b, *env)) *env -> (MaybeException .b, !*env) g f env # (x, env) = f env = (NoException x, env) h :: !Dynamic !*env -> (!MaybeException .b, !*env) h x env = (Exception x, env) getException :: .a !*env -> (!MaybeException .a, !*env) | ExceptionEnv env getException e env = (NoException e unsafeCatchAll Exception, env) (unsafeCatchAll) infixl 0 :: .a .(Dynamic -> .a) -> .a (unsafeCatchAll) e h = catch_ (Catch h) e (unsafeCatch) infixl 0 :: .a .(e -> .a) -> .a | TC e (unsafeCatch) e h = e unsafeCatchAll match h unsafeGetException :: .a -> MaybeException .a unsafeGetException e = (NoException e) unsafeCatchAll Exception evalToNF :: !.a -> .a evalToNF x = code { push_a 0 .d 1 0 jsr _eval_to_nf .o 0 0 } instance ExceptionEnv World where (catchAllIO) f h = g f h where g :: !.(*World -> (.a, *World)) .(Dynamic -> .(*World -> (.a, *World))) !*World -> (.a, !*World) g f h world # (w1, w2) = copy world = f` f w1 unsafeCatchAll h` h w2 where f` :: !.(*World -> (.a, *World)) !*World -> (.a, !*World) f` f world = f world h` :: !.(Dynamic -> .(*World -> (.a, *World))) !*World Dynamic -> (.a, !*World) h` h world x = h x world copy :: !.a -> (!.a, !.a) copy x = code inline { push_a 0 } match :: .(e -> .a) !Dynamic -> .a | TC e match f (exception :: e^) = f exception match _ dyn = raiseDynamic dyn catch_ :: !.(Int -> .(Int -> .Catch .a)) .a -> .a catch_ f e = code { |A| !f | e pushL profile_stack_pointer |B| profile_stack_pointer push_b_a 0 |A| profile_stack_pointer | !f | e pop_b 1 |B| pushD_a 0 |B| Psp pop_a 1 |A| !f | e pushI 0 |B| 4 | Psp addI |B| Psp + 4 buildI_b 0 |A| !p=(Int (Psp + 4)) | !f | e pop_b 1 |B| push_a 1 |A| !f | !p | !f | e update_a 1 2 |A| !f | !p | !p | e updatepop_a 0 1 |A| !f | !p | e .d 2 0 jsr e_system_sAP |A| !(f p) | e .o 1 0 pushI -4 |B| -4 :arjen_1 instruction 1 |addl %esp, %eax instruction 224 |B| BCsp :arjen_2 buildI_b 0 |A| !bc=(Int BCsp) | !(f p) | e pop_b 1 |B| push_a 1 |A| !(f p) | !bc | !(f p) | e update_a 1 2 |A| !(f p) | !bc | !bc | e updatepop_a 0 1 |A| !(f p) | !bc | e .d 2 0 jsr e_system_sAP |A| !c=(f p bc)=(Catch h !p !bc) | e .o 1 0 push_a 1 |A| e | !c | e update_a 1 2 |A| e | !c | !c updatepop_a 0 1 |A| e | !c jsr_eval 0 |A| !e | ? .keep 1 0 updatepop_a 0 1 |A| !e } raise_ :: !(Catch .a) b Dynamic -> .c raise_ c t x = code { |A| !c=(Catch ? ? ?) | t | x | ? pushL stack_p |B| stack_p push_b_a 0 |A| stack_p | !c | t | x | ? pop_b 1 |B| pushD_a 0 |B| Astart pop_a 1 |A| !c | t | x | ? pushD_a 0 |B| c-desc | Astart pop_a 1 |A| t | x | ? create |A| _ | t | x | ? push_node _cycle_in_spine 0 |A| BH | t | x | ? pushD_a 0 |B| BH-desc | c-desc | Astart pop_a 1 |A| t | x | ? :arjen_3 push_b 1 |B| c-desc | BH-desc | c-desc | Astart pushD_a 2 |B| ?-desc | c-desc | BH-desc | c-desc | Astart eqI |B| (?-desc == c-desc) | BH-desc | c-desc | Astart jmp_true arjen_7 |B| BH-desc | c-desc | Astart push_b 0 |B| BH-desc | BH-desc | c-desc | Astart pushD_a 2 |B| ?-desc | BH-desc | BH-desc | c-desc | Astart eqI |B| (?-desc == BH-desc) | BH-desc | c-desc | Astart jmp_false arjen_4 |B| BH-desc | c-desc | Astart fill_a 0 2 |A| t | x | t' :arjen_4 update_a 1 2 |A| t | x | x updatepop_a 0 1 |A| t | x | ? pushI -4 |B| -4 | BH-desc | c-desc | Astart :arjen_5 instruction 1 |addl %esi, %ebx instruction 243 |B| Asp | BH-desc | c-desc | Astart :arjen_6 push_b 3 |B| Astart | Asp | BH-desc | c-desc | Astart ltI |B| (Astart < Asp) | BH-desc | c-desc | Astart jmp_true arjen_3 |B| BH-desc | c-desc | Astart pop_b 3 |B| pop_a 1 |A| x repl_r_args 2 0 |A| value | type updatepop_a 0 1 |A| value buildAC "Run time error, exception raised: " |A| text | x .d 1 0 jsr print_string_ |A| x .o 0 0 .d 1 0 jsr _print_graph |A| .o 0 0 halt :arjen_7 pop_b 3 |B| push_a 2 |A| !c=(Catch h !p !bc) | t | x | !c update_a 1 3 |A| !c | t | x | t updatepop_a 0 1 |A| !c | x | t repl_r_args 1 2 |A| h | x | t |B| p | bc :arjen_8 instruction 137 |movl %eax, %esp instruction 196 |BCsp:=bc :arjen_9 updatepop_b 0 1 |B| p pushL profile_stack_pointer |B| profile_stack_pointer | p :arjen_10 instruction 137 |movl %eax, (%ebx) instruction 3 |Psp:=p :arjen_11 pop_b 2 |B| jsr_eval 0 |A| !h | x | t .d 2 0 jsr e_system_sAP |A| !(h x) | t .o 1 0 }