Skip to content

Commit

Permalink
check_expr_static_call
Browse files Browse the repository at this point in the history
  • Loading branch information
mathis committed Dec 31, 2021
1 parent 059d6db commit 2560caa
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 90 deletions.
4 changes: 2 additions & 2 deletions doc/contextual_checks.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@

* (Called method exists
* Called method params are compatible with declaration
* (**Missing**) Called static method exists in static class
* (**Missing**) Called static method params are compatible with declaration
* Called static method exists in static class
* Called static method params are compatible with declaration
* (**Missing**) Call to New exists
* (**Missing**) Params in New call are compatible with ctor
* (**Missing**) Numeric operators are used on Integer types
Expand Down
16 changes: 16 additions & 0 deletions lib/astmanip.ml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,22 @@ let rec find_method_opt decls name decl =
in find_method_opt decls name superDecl
)

(** Get a static method declaration in a class with a given name. *)

let get_static_method_opt name decl =
List.find_opt (fun (meth: methodDecl) -> meth.name = name) decl.body.staticMethods

(** Get a static method declaration in a class with a given name.
@raise Not_found if the class has no such static method. *)

let get_static_method name decl =
get_static_method_opt name decl
|> Optmanip.get_or_else (fun () ->
(* Printf.eprintf "[ERR] get_static_method_opt '%s' failed\n" name; *)
raise Not_found
)


(** Get the type of an attribute in a class declaration. *)

let rec get_inst_attr_opt attrName decl =
Expand Down
31 changes: 26 additions & 5 deletions lib/contextual.ml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ let check_inheritance decls =
)
in decls_with_super |> List.iter (fun (name, super) ->
match find_class_opt decls super with
| None -> err (Printf.sprintf "class '%s' extends non-existing class '%s'" name super)
| None -> err (Printf.sprintf "class '%s' extends unknown class '%s'" name super)
| _ -> ()
)

Expand Down Expand Up @@ -322,6 +322,9 @@ and check_expr_static_attr decls (t, name) =
in if Option.is_none attr
then err (Printf.sprintf "no static attribute named '%s' in class '%s'" name t)

(** Checks a function call expression.
@raise Contextual_error if a check fails. *)

and check_expr_call decls env (e, methName, args) =
check_expr decls env e;
let t = get_expr_type decls env e
Expand All @@ -335,7 +338,7 @@ and check_expr_call decls env (e, methName, args) =
| "String", _, _::_ -> err (Printf.sprintf "'%S::%s' expects no arguments" t methName)

| "String", _, _
| "Integer", _, _ -> err (Printf.sprintf "call to non-existing method '%s::%s'" t methName)
| "Integer", _, _ -> err (Printf.sprintf "call to unknown method '%s::%s'" t methName)

| _ ->
let decl = find_class decls t
Expand All @@ -346,7 +349,24 @@ and check_expr_call decls env (e, methName, args) =
)
in match meth with
| Some(meth) -> check_call_args decls args meth
| None -> err (Printf.sprintf "call to non-existing method '%s::%s'" t methName)
| None -> err (Printf.sprintf "call to unknown method '%s::%s'" t methName)

(** Checks a function call expression.
@raise Contextual_error if a check fails. *)

and check_expr_static_call decls env (className, methName, args) =
let decl = find_class_opt decls className
in match decl with
| None -> err (Printf.sprintf "call to static method '%s' of unknown class '%s'" methName className)
| Some(decl) ->
let meth = get_static_method_opt methName decl
in let args = args |> List.map (fun e ->
check_expr decls env e;
get_expr_type decls env e
)
in match meth with
| Some(meth) -> check_call_args decls args meth
| None -> err (Printf.sprintf "call to unknown static method '%s::%s'" className methName)

(** Checks an expression.
@raise Contextual_error if a check fails. *)
Expand All @@ -357,10 +377,11 @@ and check_expr decls env expr =
| Attr(e, name) -> check_expr_attr decls env (e, name)
| StaticAttr(className, name) -> check_expr_static_attr decls (className, name)
| UMinus e -> check_expr decls env e
| Call(e, methName, args) -> check_expr_call decls env (e, methName, args)
| List le | New(_, le) -> List.iter (check_expr decls env) le
| Call(e, methName, args) -> check_expr_call decls env (e, methName, args)
| StaticCall(className, methName, args) -> check_expr_static_call decls env (className, methName, args)
| BinOp(e1, _, e2) | StrCat(e1, e2) -> check_expr decls env e1; check_expr decls env e2
| Cste _ | StaticCall _ | String _ -> ()
| Cste _ | String _ -> ()

(* -------------------------------------------------------------------------- *)

Expand Down
83 changes: 0 additions & 83 deletions progs/ex1_ast.txt
Original file line number Diff line number Diff line change
@@ -1,86 +1,3 @@
(Ast.Attr ((Ast.Id "this"), "clone"))
(Ast.Attr ((Ast.Id "this"), "clone"))
(Ast.String "Inside Point::print")
(Ast.Attr ((Ast.Id "this"), "name"))
(Ast.Attr ((Ast.Id "this"), "x"))
(Ast.Attr ((Ast.Id "this"), "y"))
(Ast.StrCat (
(Ast.StrCat (
(Ast.StrCat (
(Ast.StrCat ((Ast.String "= ("),
(Ast.Call ((Ast.Attr ((Ast.Id "this"), "x")), "toString", [])))),
(Ast.String ", "))),
(Ast.Call ((Ast.Attr ((Ast.Id "this"), "y")), "toString", [])))),
(Ast.String ")")))
(Ast.Id "this")
(Ast.String "Inside Couleur::estGris")
(Ast.String "Inside Couleur::couleur")
(Ast.String "Inside PointColore::print")
(Ast.Id "super")
(Ast.Id "this")
(Ast.Call ((Ast.Id "this"), "couleur", []))
(Ast.Call ((Ast.Call ((Ast.Id "this"), "couleur", [])), "name",
[(Ast.Cste 1)]))
(Ast.Attr ((Ast.Id "this"), "coul"))
(Ast.Attr ((Ast.Id "this"), "coul"))
(Ast.Id "p")
(Ast.Call ((Ast.Id "p"), "couleur", []))
(Ast.Call ((Ast.Call ((Ast.Id "p"), "couleur", [])), "name", [(Ast.Cste 1)]))
(Ast.Id "p")
(Ast.Id "p2")
(Ast.String "Appel 1: ")
(Ast.Id "p2")
(Ast.String "Appel 2: ")
(Ast.Id "p3")
(Ast.String "Appel 3: ")
(Ast.Id "p3")
(Ast.String "Resultats de test: ")
(Ast.Id "c")
(Ast.String " ")
(Ast.Id "c2")
(Ast.String " ")
(Ast.Id "c3")
(Ast.String "")
(Ast.String "Debut du programme")
(Ast.Id "p1")
(Ast.Id "p2")
(Ast.Id "p2")
(Ast.Id "p1")
(Ast.Id "p1")
(Ast.Id "p2")
(Ast.Id "o")
(Ast.Id "o")
(Ast.Id "o")
(Ast.Id "p2")
(Ast.Id "p1")
(Ast.Id "p1")
(Ast.Id "p2")
(Ast.String "On va essayer le clonage:")
(Ast.Id "p1")
(Ast.Id "clone1")
(Ast.String "p1 isCloned: ")
(Ast.Id "p1")
(Ast.String "OK")
(Ast.String "KO")
(Ast.Id "clone1")
(Ast.Id "clone2")
(Ast.Call ((Ast.Id "clone2"), "move",
[(Ast.Cste 54); (Ast.Cste 36); (Ast.Cste 0)]))
(Ast.String "Impression de tous les clones de p1:")
(Ast.Id "p1")
(Ast.String "Fin de l'impression de tous les clones")
(Ast.String "Valeur du compteur de nombre de points: ")
(Ast.StaticCall ("Point", "howMany", []))
(Ast.Call ((Ast.StaticCall ("Point", "howMany", [])), "toString", []))
(Ast.Id "p1")
(Ast.Call ((Ast.Id "p1"), "clone", []))
(Ast.Id "p1")
(Ast.Id "o")
(Ast.Call ((Ast.Id "o"), "clone", []))
(Ast.String "test(Point, PointColore, PointNoir)")
(Ast.String "test(PointNoir, PointNoir, PointNoir)")
(Ast.String "test(PointNoir, PointNoir, PointNoir)")
(Ast.String "\nDone")
{ Ast.decls =
[{ Ast.name = "Point";
ctorParams =
Expand Down

0 comments on commit 2560caa

Please sign in to comment.