Skip to content

Commit

Permalink
try..catch..finally implemented
Browse files Browse the repository at this point in the history
  • Loading branch information
manuel-rubio committed Jun 23, 2017
1 parent a8f16b8 commit 7092ed3
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 1 deletion.
10 changes: 10 additions & 0 deletions src/ephp_class.erl
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
init_static_value/5,
set_static/4,

instance_of/2,

register_class/4,
set_alias/3,
instance/5,
Expand Down Expand Up @@ -116,6 +118,14 @@ instance(Ref, LocalCtx, GlobalCtx, RawClassName, Line) ->
{RawClassName}})
end.

instance_of(#reg_instance{class = #class{name = Name}}, Name) ->
true;
instance_of(#reg_instance{class = #class{extends = Extends,
implements = Impl}}, Name) ->
lists:member(Name, Extends) orelse lists:member(Name, Impl);
instance_of(_, _) ->
false.

initialize_class(#class{static_context=Ctx, attrs=Attrs}) ->
lists:foreach(fun
(#class_attr{type=static, name=Name, init_value=RawVal}) ->
Expand Down
55 changes: 54 additions & 1 deletion src/ephp_interpr.erl
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ run_depth(Context, #constant{type=define,name=Name,value=Expr,line=Line},
ephp_context:register_const(Context, Name, Value),
false;

run_depth(Context, #constant{line=Line}, false, Cover) ->
run_depth(Context, #constant{line = Line}, false, Cover) ->
ok = ephp_cover:store(Cover, constant, Context, Line),
false;

Expand All @@ -307,18 +307,71 @@ run_depth(Context, {silent, Statement}, false, Cover) ->
run_depth(_Context, die, false, _Cover) ->
throw(die);

run_depth(Context, #try_catch{code_block = Code, catches = Catches,
finally = Finally, line = Line}, false, Cover) ->
ok = ephp_cover:store(Cover, try_catch, Context, Line),
try
run(Context, #eval{statements = Code}, Cover)
catch
throw:Exception when ?IS_OBJECT(Exception) ->
Ret = lists:foldl(fun
(#catch_block{} = CatchBlock, throw) ->
run_catch(Context, CatchBlock, Exception, Finally, Cover);
(#catch_block{}, Ret) ->
Ret
end, throw, Catches),
case Ret of
throw ->
run_finally(Context, Finally, Cover),
throw(Exception);
_ ->
Ret
end
end,
run_finally(Context, Finally, Cover);

run_depth(_Context, Statement, false, _Cover) ->
ephp_error:error({error, eunknownst, undefined, ?E_CORE_ERROR, Statement}),
break;

run_depth(_Context, _Statement, Break, _Cover) ->
Break.

-spec exit_cond(flow_status()) -> flow_status().

exit_cond({return, Ret}) -> {return, Ret};
exit_cond({break, 0}) -> false;
exit_cond({break, N}) -> {break, N-1};
exit_cond(false) -> false.

-spec run_finally(context(), statements(), Cover :: boolean()) -> flow_status().

run_finally(_Context, [], _Cover) ->
false;
run_finally(Context, Finally, Cover) ->
run(Context, #eval{statements = Finally}, Cover).

-spec run_catch(context(), catch_block(), Exception :: binary(),
Finally :: statements(), Cover :: boolean()) -> throw |
flow_status().

run_catch(Context,
#catch_block{exception = #variable{data_type = Catch} = Var,
code_block = CatchCode},
Exception, Finally, Cover) ->
case ephp_class:instance_of(Exception, Catch) of
true ->
ephp_context:set(Context, Var, Exception),
try
run(Context, #eval{statements = CatchCode}, Cover)
catch throw:NewException when ?IS_OBJECT(NewException) ->
run_finally(Context, Finally, Cover),
throw(NewException)
end;
false ->
throw
end.

-spec run_loop(
PrePost :: (pre | post),
Context :: context(),
Expand Down
2 changes: 2 additions & 0 deletions test/code/test_try_catch.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
hey!
Exception: it's broken
10 changes: 10 additions & 0 deletions test/code/test_try_catch.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

try {
print "hey!\n";
throw new Exception("it's broken");
print "no way!\n";
} catch (Exception $e) {
print "Exception: " . $e->getMessage() . "\n";
}

10 changes: 10 additions & 0 deletions test/code/test_try_catch_finally.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
hey!
Exception: it's broken
and ends first one
hey again!
should this appears?

Fatal error: Uncaught exception 'Exception' with message 'Another exception in chain!' in {{CWD}}/test/code/test_try_catch_finally.php:18
Stack trace:
#0 {main}
thrown in {{CWD}}/test/code/test_try_catch_finally.php on line 18
21 changes: 21 additions & 0 deletions test/code/test_try_catch_finally.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

try {
print "hey!\n";
throw new Exception("it's broken");
print "no way!\n";
} catch (Exception $e) {
print "Exception: " . $e->getMessage() . "\n";
} finally {
print "and ends first one\n";
}

try {
print "hey again!\n";
throw new Exception("it's broken... again");
print "no way!\n";
} catch (Exception $e) {
throw new Exception("Another exception in chain!");
} finally {
print "should this appears?\n";
}
2 changes: 2 additions & 0 deletions test/code/test_try_finally.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
hello world!
ok
7 changes: 7 additions & 0 deletions test/code/test_try_finally.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

try {
print "hello world!\n";
} finally {
print "ok\n";
}

0 comments on commit 7092ed3

Please sign in to comment.