|
@@ -9,7 +9,7 @@ let type2str = function Funcname _ -> "function" | Varname _ -> "variable"
|
|
|
let mapfind name tbl =
|
|
let mapfind name tbl =
|
|
|
if Hashtbl.mem tbl name then Some (Hashtbl.find tbl name) else None
|
|
if Hashtbl.mem tbl name then Some (Hashtbl.find tbl name) else None
|
|
|
|
|
|
|
|
-let check_in_scope name errnode scope =
|
|
|
|
|
|
|
+let check_in_scope name errnode scope err =
|
|
|
let (vars, funs) = scope in
|
|
let (vars, funs) = scope in
|
|
|
let (name, tbl, other_map, desired_type) = match name with
|
|
let (name, tbl, other_map, desired_type) = match name with
|
|
|
| Varname name -> (name, vars, funs, "variable")
|
|
| Varname name -> (name, vars, funs, "variable")
|
|
@@ -23,7 +23,8 @@ let check_in_scope name errnode scope =
|
|
|
| Some _ -> sprintf "\"%s\" is not a %s" name desired_type
|
|
| Some _ -> sprintf "\"%s\" is not a %s" name desired_type
|
|
|
| None -> sprintf "undefined %s \"%s\"" desired_type name
|
|
| None -> sprintf "undefined %s \"%s\"" desired_type name
|
|
|
in
|
|
in
|
|
|
- raise (NodeError (errnode, msg))
|
|
|
|
|
|
|
+ err := !err @ [NodeMsg (errnode, msg)];
|
|
|
|
|
+ (DummyNode, -1)
|
|
|
|
|
|
|
|
let add_to_scope name dec depth (vars, funs) =
|
|
let add_to_scope name dec depth (vars, funs) =
|
|
|
let (name, tbl, name_type) = match name with
|
|
let (name, tbl, name_type) = match name with
|
|
@@ -43,13 +44,13 @@ let add_to_scope name dec depth (vars, funs) =
|
|
|
let msg = sprintf "Error: cannot redeclare %s \"%s\"" name_type name in
|
|
let msg = sprintf "Error: cannot redeclare %s \"%s\"" name_type name in
|
|
|
prerr_loc_msg (locof dec) msg;
|
|
prerr_loc_msg (locof dec) msg;
|
|
|
prerr_loc_msg (locof orig) "Previously declared here:";
|
|
prerr_loc_msg (locof orig) "Previously declared here:";
|
|
|
- raise EmptyError
|
|
|
|
|
|
|
+ raise (FatalError NoMsg)
|
|
|
| Some _ ->
|
|
| Some _ ->
|
|
|
Hashtbl.replace tbl name (dec, depth, name_type)
|
|
Hashtbl.replace tbl name (dec, depth, name_type)
|
|
|
| None ->
|
|
| None ->
|
|
|
Hashtbl.add tbl name (dec, depth, name_type)
|
|
Hashtbl.add tbl name (dec, depth, name_type)
|
|
|
|
|
|
|
|
-let rec analyse scope depth node =
|
|
|
|
|
|
|
+let rec analyse scope depth node err =
|
|
|
let rec collect node = match node with
|
|
let rec collect node = match node with
|
|
|
(* For extern array declarations, add the dimension names as well *)
|
|
(* For extern array declarations, add the dimension names as well *)
|
|
|
| GlobalDec (ArrayDims (ctype, dims), name, ann) ->
|
|
| GlobalDec (ArrayDims (ctype, dims), name, ann) ->
|
|
@@ -86,21 +87,21 @@ let rec analyse scope depth node =
|
|
|
(* For a variable or function call, look for its declaration in the
|
|
(* For a variable or function call, look for its declaration in the
|
|
|
* current scope and save a its type/depth information *)
|
|
* current scope and save a its type/depth information *)
|
|
|
| Var (name, dims, ann) ->
|
|
| Var (name, dims, ann) ->
|
|
|
- let (dec, dec_depth) = check_in_scope (Varname name) node scope in
|
|
|
|
|
|
|
+ let (dec, dec_depth) = check_in_scope (Varname name) node scope err in
|
|
|
VarUse (dec, optmap collect dims, Depth depth :: ann)
|
|
VarUse (dec, optmap collect dims, Depth depth :: ann)
|
|
|
|
|
|
|
|
| FunCall (name, args, ann) ->
|
|
| FunCall (name, args, ann) ->
|
|
|
- let (dec, dec_depth) = check_in_scope (Funcname name) node scope in
|
|
|
|
|
|
|
+ let (dec, dec_depth) = check_in_scope (Funcname name) node scope err in
|
|
|
FunUse (dec, List.map collect args, Depth depth :: ann)
|
|
FunUse (dec, List.map collect args, Depth depth :: ann)
|
|
|
|
|
|
|
|
(* Assign statements are replaced with VarLet nodes, which stores the
|
|
(* Assign statements are replaced with VarLet nodes, which stores the
|
|
|
* declaration of the assigned variable *)
|
|
* declaration of the assigned variable *)
|
|
|
| Assign (name, dims, value, ann) ->
|
|
| Assign (name, dims, value, ann) ->
|
|
|
- let (dec, dec_depth) = check_in_scope (Varname name) node scope in
|
|
|
|
|
|
|
+ let (dec, dec_depth) = check_in_scope (Varname name) node scope err in
|
|
|
VarLet (dec, optmap collect dims, collect value, Depth depth :: ann)
|
|
VarLet (dec, optmap collect dims, collect value, Depth depth :: ann)
|
|
|
|
|
|
|
|
| Allocate (dec, dims, ann) ->
|
|
| Allocate (dec, dims, ann) ->
|
|
|
- let (dec, dec_depth) = check_in_scope (Varname (nameof dec)) node scope in
|
|
|
|
|
|
|
+ let (dec, dec_depth) = check_in_scope (Varname (nameof dec)) node scope err in
|
|
|
Allocate (dec, List.map collect dims, Depth depth :: ann)
|
|
Allocate (dec, List.map collect dims, Depth depth :: ann)
|
|
|
|
|
|
|
|
| _ -> traverse_unit collect node
|
|
| _ -> traverse_unit collect node
|
|
@@ -113,7 +114,7 @@ let rec analyse scope depth node =
|
|
|
let (vars, funs) = scope in
|
|
let (vars, funs) = scope in
|
|
|
let local_scope = (Hashtbl.copy vars, Hashtbl.copy funs) in
|
|
let local_scope = (Hashtbl.copy vars, Hashtbl.copy funs) in
|
|
|
let params = List.map (traverse local_scope (depth + 1)) params in
|
|
let params = List.map (traverse local_scope (depth + 1)) params in
|
|
|
- let body = analyse local_scope (depth + 1) body in
|
|
|
|
|
|
|
+ let body = analyse local_scope (depth + 1) body err in
|
|
|
FunDef (export, ret_type, name, params, body, ann)
|
|
FunDef (export, ret_type, name, params, body, ann)
|
|
|
|
|
|
|
|
| Param (ArrayDims (ctype, dims), name, ann) ->
|
|
| Param (ArrayDims (ctype, dims), name, ann) ->
|
|
@@ -159,8 +160,10 @@ let rec analyse scope depth node =
|
|
|
|
|
|
|
|
let analyse_context program =
|
|
let analyse_context program =
|
|
|
let scope = (Hashtbl.create 20, Hashtbl.create 20) in
|
|
let scope = (Hashtbl.create 20, Hashtbl.create 20) in
|
|
|
- analyse scope 0 program
|
|
|
|
|
|
|
+ let err = ref [] in
|
|
|
|
|
+ let node = analyse scope 0 program err in
|
|
|
|
|
+ quit_on_error node !err
|
|
|
|
|
|
|
|
let phase = function
|
|
let phase = function
|
|
|
| Ast node -> Ast (analyse_context node)
|
|
| Ast node -> Ast (analyse_context node)
|
|
|
- | _ -> raise (InvalidInput "context analysis")
|
|
|
|
|
|
|
+ | _ -> raise InvalidInput
|