|
@@ -4,17 +4,23 @@ open Util
|
|
|
|
|
|
|
|
module StrMap = Map.Make (String)
|
|
module StrMap = Map.Make (String)
|
|
|
|
|
|
|
|
-let analyse_context node =
|
|
|
|
|
|
|
+let analyse_context args node =
|
|
|
let scope = ref StrMap.empty in
|
|
let scope = ref StrMap.empty in
|
|
|
let add_to_scope name decl depth desc =
|
|
let add_to_scope name decl depth desc =
|
|
|
- if StrMap.mem name !scope then(
|
|
|
|
|
- raise (NodeError (!decl, sprintf "cannot redeclare %s \"%s\"" desc name))
|
|
|
|
|
|
|
+ if StrMap.mem name !scope then (
|
|
|
|
|
+ let msg = sprintf "Error: cannot redeclare %s \"%s\"" desc name in
|
|
|
|
|
+ prerr_loc_msg (locof !decl) msg args.verbose;
|
|
|
|
|
+
|
|
|
|
|
+ let (orig, _) = StrMap.find name !scope in
|
|
|
|
|
+ prerr_loc_msg (locof !orig) "Previously declared here:" args.verbose;
|
|
|
|
|
+
|
|
|
|
|
+ raise EmptyError
|
|
|
) else
|
|
) else
|
|
|
scope := StrMap.add name (decl, depth) !scope
|
|
scope := StrMap.add name (decl, depth) !scope
|
|
|
in
|
|
in
|
|
|
- let rec analyse depth = function
|
|
|
|
|
|
|
+ let rec analyse depth node = match node with
|
|
|
(* Add node reference for this varname to vars map *)
|
|
(* Add node reference for this varname to vars map *)
|
|
|
- | VarDec (ctype, name, init, loc) as node ->
|
|
|
|
|
|
|
+ | VarDec (ctype, name, init, loc) ->
|
|
|
let node = match init with
|
|
let node = match init with
|
|
|
| Some value ->
|
|
| Some value ->
|
|
|
let value = analyse depth value in
|
|
let value = analyse depth value in
|
|
@@ -26,25 +32,29 @@ let analyse_context node =
|
|
|
|
|
|
|
|
(* For a variable, look for its declaration in the current scope and
|
|
(* For a variable, look for its declaration in the current scope and
|
|
|
* save a reference with the relative nesting depth *)
|
|
* save a reference with the relative nesting depth *)
|
|
|
- | Var (name, _) as node ->
|
|
|
|
|
|
|
+ | Var (name, _) ->
|
|
|
if StrMap.mem name !scope then
|
|
if StrMap.mem name !scope then
|
|
|
let (decl, decl_depth) = StrMap.find name !scope in
|
|
let (decl, decl_depth) = StrMap.find name !scope in
|
|
|
VarUse (node, decl, depth - decl_depth)
|
|
VarUse (node, decl, depth - decl_depth)
|
|
|
else
|
|
else
|
|
|
raise (NodeError (node, (sprintf "undefined variable \"%s\"" name)))
|
|
raise (NodeError (node, (sprintf "undefined variable \"%s\"" name)))
|
|
|
|
|
|
|
|
- (*
|
|
|
|
|
(* Increase nesting level when entering function *)
|
|
(* Increase nesting level when entering function *)
|
|
|
- | FunDef (export, ret_type, name, params, body, loc) as node ->
|
|
|
|
|
- let vars = StrMap.add name (ref node) vars in
|
|
|
|
|
- let inctrav vars = function
|
|
|
|
|
- | [] -> []
|
|
|
|
|
- | h :: t -> analyse vars h :: (inctrav vars
|
|
|
|
|
- in
|
|
|
|
|
- let body = inc_trav body
|
|
|
|
|
- let body = List.map (analyse vars) body in
|
|
|
|
|
- FunDef (export, ret_type, name, params, body, loc) as node ->
|
|
|
|
|
- *)
|
|
|
|
|
|
|
+ | FunDef (export, ret_type, name, params, body, loc) ->
|
|
|
|
|
+ add_to_scope name (ref node) depth "function";
|
|
|
|
|
+ let params = List.map (analyse (depth + 1)) params in
|
|
|
|
|
+ let body = analyse (depth + 1) body in
|
|
|
|
|
+ FunDef (export, ret_type, name, params, body, loc)
|
|
|
|
|
+
|
|
|
|
|
+ | Param (ArrayDec (_, dims) as atype, name, _) as node ->
|
|
|
|
|
+ let add dim = add_to_scope dim (ref (Type atype)) depth "variable" in
|
|
|
|
|
+ List.iter add dims;
|
|
|
|
|
+ add_to_scope name (ref node) depth "variable";
|
|
|
|
|
+ node
|
|
|
|
|
+
|
|
|
|
|
+ | Param (_, name, _) ->
|
|
|
|
|
+ add_to_scope name (ref node) depth "variable";
|
|
|
|
|
+ node
|
|
|
|
|
|
|
|
| node -> transform_children (analyse depth) node
|
|
| node -> transform_children (analyse depth) node
|
|
|
in
|
|
in
|
|
@@ -54,5 +64,5 @@ let rec phase input =
|
|
|
prerr_endline "- Context analysis";
|
|
prerr_endline "- Context analysis";
|
|
|
match input with
|
|
match input with
|
|
|
| Ast (node, args) ->
|
|
| Ast (node, args) ->
|
|
|
- Ast (analyse_context node, args)
|
|
|
|
|
|
|
+ Ast (analyse_context args node, args)
|
|
|
| _ -> raise (InvalidInput "context analysis")
|
|
| _ -> raise (InvalidInput "context analysis")
|