context_analysis.ml 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. open Printf
  2. open Ast
  3. open Util
  4. module StrMap = Map.Make (String)
  5. let analyse_context node =
  6. let scope = ref StrMap.empty in
  7. let add_to_scope name decl depth desc =
  8. if StrMap.mem name !scope then(
  9. eprintf "node: %s\n" (Stringify.node2str !decl);
  10. raise (LocError (sprintf "cannot redeclare %s \"%s\"" desc name, (locof !decl)))
  11. ) else
  12. scope := StrMap.add name (decl, depth) !scope
  13. in
  14. let rec analyse depth = function
  15. (* add node reference for this varname to vars map *)
  16. | VarDec (ctype, name, init, loc) as node ->
  17. let node = match init with
  18. | Some value ->
  19. let value = analyse depth value in
  20. VarDec (ctype, name, Some value, loc)
  21. | None -> node
  22. in
  23. add_to_scope name (ref node) depth "variable";
  24. node
  25. (* for a variable, look for its declaration in the current scope and
  26. * save a reference with the relative nesting depth *)
  27. | Var (name, loc) as node ->
  28. if StrMap.mem name !scope then
  29. let (decl, decl_depth) = StrMap.find name !scope in
  30. VarUse (node, decl, depth - decl_depth)
  31. else
  32. raise (LocError (sprintf "undefined variable \"%s\"" name, loc))
  33. (*
  34. (* increase nesting level when entering function *)
  35. | FunDef (export, ret_type, name, params, body, loc) as node ->
  36. let vars = StrMap.add name (ref node) vars in
  37. let inctrav vars = function
  38. | [] -> []
  39. | h :: t -> analyse vars h :: (inctrav vars
  40. in
  41. let body = inc_trav body
  42. let body = List.map (analyse vars) body in
  43. FunDef (export, ret_type, name, params, body, loc) as node ->
  44. *)
  45. | node -> transform_children (analyse depth) node
  46. in
  47. analyse 0 node
  48. let rec phase repr =
  49. let _ = prerr_endline "- Context analysis" in
  50. match repr with
  51. | Node (node, verbose) ->
  52. Node (analyse_context node, verbose)
  53. | _ -> raise (CompileError "invalid input for this phase")