X-Git-Url: https://git.xandkar.net/?a=blobdiff_plain;f=compiler%2Fsrc%2Flib%2Ftiger%2Ftiger_semant.ml;h=5d5d71b2c026f567669ef47c409a86453614cbab;hb=4c550cd5b9653add413e21d06c73efe3aa657e06;hp=3265c81cbd887777550c6d23ad105e4b22d74215;hpb=161a300dddce2df54b21863ae94e2dda281906fd;p=tiger.ml.git diff --git a/compiler/src/lib/tiger/tiger_semant.ml b/compiler/src/lib/tiger/tiger_semant.ml index 3265c81..5d5d71b 100644 --- a/compiler/src/lib/tiger/tiger_semant.ml +++ b/compiler/src/lib/tiger/tiger_semant.ml @@ -56,6 +56,8 @@ end = struct let check_int expty ~pos : unit = check_same {exp=(); ty=Type.Int} expty ~pos + (* TODO: actual_ty *) + let rec transExp ~env exp = let rec trexp exp = (match exp with @@ -65,12 +67,37 @@ end = struct return_int | A.StringExp {string=_; _} -> return_string - | A.CallExp {func=_; args=_; pos=_} -> - unimplemented () + | A.CallExp {func; args; pos} -> + (match env_get_val ~sym:func ~env ~pos with + | Value.Fun {formals; result} -> + List.iter2 formals args ~f:(fun ty_expected exp_given -> + check_same {exp=(); ty = ty_expected} (trexp exp_given) ~pos; + ); + return result + | Value.Var _ -> + E.raise (E.Id_not_a_function {id=func; pos}) + ) | A.OpExp {oper; left; right; pos} -> trop oper ~left ~right ~pos - | A.RecordExp {fields=_; typ=_; pos=_} -> - unimplemented () + | A.RecordExp {fields=field_exps; typ; pos} -> + let ty = env_get_typ ~sym:typ ~env ~pos in + Type.if_record + ty + ~f:(fun field_tys -> + List.iter field_exps ~f:(fun (field, exp, pos) -> + (match List.assoc_opt field field_tys with + | Some field_ty -> + check_same {exp=(); ty=field_ty} (trexp exp) ~pos + | None -> + E.raise + (E.No_such_field_in_record {field; record=ty; pos}) + ) + ) + ) + ~otherwise:(fun () -> + E.raise (E.Wrong_type_used_as_record {ty_id=typ; ty; pos}) + ); + return ty | A.SeqExp exps -> (* Ignoring value because we only care if a type-checking exception * is raised in one of trexp calls: *) @@ -108,8 +135,18 @@ end = struct return_unit | A.LetExp {decs=_; body=_; _} -> unimplemented () - | A.ArrayExp {typ=_; size=_; init=_; _} -> - unimplemented () + | A.ArrayExp {typ; size; init; pos} -> + check_int (trexp size) ~pos; + let ty = env_get_typ ~sym:typ ~env ~pos in + Type.if_array + ty + ~f:(fun ty_elements -> + check_same {exp=(); ty=ty_elements} (trexp init) ~pos + ) + ~otherwise:(fun () -> + E.raise (E.Wrong_type_used_as_array {ty_id=typ; ty; pos}) + ); + return ty | A.VarExp var -> trvar var )