刚开始没必要看书
也没必要听那些所谓的老手的建议
什么学习路线的,那些都是扯淡的
没什么卵用的
为什么呢?
因为想要提高你的水平,最重要的就是动手,实战
你照着那些路线慢慢的学下去,学不了几天,你的耐心就都被磨没了
耐心都磨没了,还学个屁
所以我的建议是,基本语法熟悉之后,直接去实战
过程中遇到不懂的地方再去找答案,这样你容易有成就感,也学的快
需要的话,我这里有很多实战的项目资料,有需要的可以找我来拿
参考下图找我
let rec print_abbrev fs = function
| Return {recursive= false; stk= s} ->
print_abbrev fs s ;
Format.pp_print_char fs 'R'
| Return {recursive= true; stk= s} ->
print_abbrev fs s ;
Format.pp_print_string fs "R↑"
| Throw (_, s) ->
print_abbrev fs s ;
Format.pp_print_char fs 'T'
| Empty -> ()
let invariant s =
let@ () = Invariant.invariant [%here] s [%sexp_of: t] in
match s with
| Return _ | Throw (_, Return _) | Empty -> ()
| Throw _ -> fail "malformed stack: %a" print_abbrev s ()
let empty = Empty |> check invariant
let push_return Llair.{callee= {formals; locals}; return; recursive}
from_call stk =
Return {recursive; dst= return; formals; locals; from_call; stk}
|> check invariant
let push_throw jmp stk =
(match jmp with None -> stk | Some jmp -> Throw (jmp, stk))
|> check invariant
let push_call (Llair.{return; throw} as call) ~bound from_call stk =
[%Trace.call fun {pf} -> pf "%a" print_abbrev stk]
;
let rec count_f_in_stack acc f = function
| Return {stk= next_frame; dst= dest_block} ->
count_f_in_stack
(if Llair.Jump.equal dest_block f then acc + 1 else acc)
f next_frame
| _ -> acc
in
let n = count_f_in_stack 0 return stk in
( if n > bound then None
else Some (push_throw throw (push_return call from_call stk)) )
|>
[%Trace.retn fun {pf} _ ->
pf "%d of %a on stack" n Llair.Jump.pp return]
let rec pop_return = function
| Throw (_, stk) -> pop_return stk
| Return {from_call; dst; stk} -> Some (from_call, dst, stk)
| Empty -> None
let pop_throw stk ~init ~unwind =
let rec pop_throw_ state = function
| Return {formals; locals; from_call; stk} ->
pop_throw_ (unwind formals locals from_call state) stk
| Throw (dst, Return {from_call; stk}) ->
Some (from_call, dst, stk, state)
| Empty -> None
| Throw _ as stk -> violates invariant stk
in
pop_throw_ init stk
end