@@ -373,7 +373,8 @@ and exp ?(in_constant_context = false) (env : env) (e : Syntax.exp) : env * exp
373373 env , { e = EString value; t; loc }
374374 | { e = SEGroup e; _ } -> exp ~in_constant_context env e
375375 | { e = SEId name; loc } when not (String .equal (String .capitalize_ascii name ) name ) -> (
376- match Env .lookupExpressionSymbol env name loc in_constant_context with
376+ let name_path : path = { id = name; n = None ; loc } in
377+ match Env .lookupExpressionSymbol env name_path in_constant_context with
377378 | ExprVariable var ->
378379 let t = var .t in
379380 let e =
@@ -503,41 +504,61 @@ and exp ?(in_constant_context = false) (env : env) (e : Syntax.exp) : env * exp
503504 let t = applyFunction e.loc args_t ret [ e ] in
504505 env, { e = EUnOp (op, e); t; loc }
505506 | { e = SEMember (e1 , m ); loc } -> (
506- (* First, try to interpret this as an enum reference if e1 is an SEId *)
507+ (* First, try to interpret this as an enum reference if e1 is an SEId or SEEnum *)
507508 match e1 with
508- | { e = SEId module_name ; _ } -> (
509- (* Try to lookup as enum: module_name.m *)
510- let enum_path = Syntax. { id = m; n = Some module_name; loc } in
511- try
512- let type_path, tloc, index = Env. lookEnum env enum_path loc in
513- let t = C. path_t tloc type_path in
514- env, { e = EInt index; t; loc }
515- with
516- | _ -> (
517- (* If enum lookup fails, fall back to normal member access *)
518- let env, e1 = exp ~in_constant_context env e1 in
519- match (unlink e1.t).tx with
520- | TEId path -> (
521- match Env. lookType env path loc with
522- | { path; descr = Record members ; _ } -> (
523- match Map. find m members with
524- | None -> Error. raiseError (" The field '" ^ m ^ " ' is not part of the type '" ^ pathString path ^ " '" ) loc
525- | Some { t; _ } ->
526- let t = refreshConstness t in
527- (* if the type is a builtin (a value) do not unify the constness *)
528- let () =
529- if (not in_constant_context) && not (Env. isBuiltinType t) then
530- unifyConstness t e1.t
531- in
532- env, { e = EMember (e1, m); t; loc })
533- | _ ->
534- let t = Pla. print (Typed. print_type_ e1.t) in
535- let e = Pla. print (Typed. print_exp e1) in
536- Error. raiseError (" The expression '" ^ e ^ " ' of type '" ^ t ^ " ' does not have a member '" ^ m ^ " '." ) loc)
537- | _ ->
538- let t = Pla. print (Typed. print_type_ e1.t) in
539- let e = Pla. print (Typed. print_exp e1) in
540- Error. raiseError (" The expression '" ^ e ^ " ' of type '" ^ t ^ " ' does not have a member '" ^ m ^ " '." ) loc))
509+ | { e = SEId module_name ; _ } when String. equal (String. capitalize_ascii module_name) module_name -> (
510+ (* First check if this is a module name - try module-qualified access *)
511+ let const_path = Syntax. { id = m; n = Some module_name; loc } in
512+ let results = Env. lookupPath env const_path in
513+ match results with
514+ | _ :: _ -> (
515+ (* Found something in module - check what it is *)
516+ match Env. findVar results with
517+ | Some var when var.kind = Const ->
518+ let t = var.t in
519+ env, { e = EConst const_path; t; loc }
520+ | Some var ->
521+ Error. raiseError
522+ (" Found '"
523+ ^ module_name
524+ ^ " ."
525+ ^ m
526+ ^ " ' but it's not a constant (it's a "
527+ ^ (match var.kind with
528+ | Val -> " variable"
529+ | Mem _ -> " memory"
530+ | Inst -> " instance"
531+ | Const -> " constant" )
532+ ^ " )" )
533+ loc
534+ | None -> (
535+ (* Check for function or enum *)
536+ match Env. findFunction results with
537+ | Some _ ->
538+ Error. raiseError
539+ (" '"
540+ ^ module_name
541+ ^ " ."
542+ ^ m
543+ ^ " ' is a function, not a constant. Use function call syntax: "
544+ ^ module_name
545+ ^ " ."
546+ ^ m
547+ ^ " (args)" )
548+ loc
549+ | None -> (
550+ match Env. findEnum results with
551+ | Some (type_path , tloc , index ) ->
552+ let t = C. path_t tloc type_path in
553+ env, { e = EInt index; t; loc }
554+ | None ->
555+ Error. raiseError (" Found '" ^ module_name ^ " ." ^ m ^ " ' but it's not a constant, function, or enum" ) loc)
556+ ))
557+ | [] ->
558+ (* Module not found - check if it's an actual module name or just not found *)
559+ Error. raiseError
560+ (" Module '" ^ module_name ^ " ' not found. Check that the module is included or spelled correctly" )
561+ loc)
541562 | _ -> (
542563 (* For non-SEId expressions, use normal member access *)
543564 let env, e1 = exp ~in_constant_context env e1 in
@@ -563,13 +584,10 @@ and exp ?(in_constant_context = false) (env : env) (e : Syntax.exp) : env * exp
563584 let t = Pla. print (Typed. print_type_ e1.t) in
564585 let e = Pla. print (Typed. print_exp e1) in
565586 Error. raiseError (" The expression '" ^ e ^ " ' of type '" ^ t ^ " ' does not have a member '" ^ m ^ " '." ) loc))
566- | { e = SEEnum path ; loc } ->
567- let type_path, tloc, index = Env. lookEnum env path loc in
568- let t = C. path_t tloc type_path in
569- env, { e = EInt index; t; loc }
570587 | { e = SEId id ; loc } -> (
571588 (* This case handles uppercase identifiers (enum constructors) *)
572- match Env. lookupExpressionSymbol env id loc in_constant_context with
589+ let id_path : path = { id; n = None ; loc } in
590+ match Env. lookupExpressionSymbol env id_path in_constant_context with
573591 | ExprEnum (type_path , tloc , index ) ->
574592 let t = C. path_t tloc type_path in
575593 env, { e = EInt index; t; loc }
@@ -755,7 +773,7 @@ let makeIterWhile (env : env) name id_loc value body loc =
755773 { s = SStmtBlock [ decl; while_s ]; loc }
756774
757775
758- let makeIfOfMatch e cases =
776+ let makeIfOfMatch env e cases =
759777 let rec makeComparison (e : Syntax.exp ) (p : Syntax.pattern ) =
760778 let makeEq e1 e2 = Syntax. { e = SEOp (" ==" , e1, e2); loc = e1.loc } in
761779 let makeAnd e1 e2 = Syntax. { e = SEOp (" &&" , e1, e2); loc = e1.loc } in
@@ -789,7 +807,17 @@ let makeIfOfMatch e cases =
789807 | _ , { p = SPReal f ; loc } -> makeEq e Syntax. { e = SEReal f; loc }
790808 | _ , { p = SPFixed f ; loc } -> makeEq e Syntax. { e = SEFixed f; loc }
791809 | _ , { p = SPString s ; loc } -> makeEq e Syntax. { e = SEString s; loc }
792- | _ , { p = SPEnum p ; loc } -> makeEq e Syntax. { e = SEEnum p; loc }
810+ | _ , { p = SPId id ; loc } -> (
811+ (* Handle enum constructor and constant patterns *)
812+ let id_path : path = { id; n = None ; loc } in
813+ match Env. lookupExpressionSymbol env id_path false with
814+ | ExprEnum (_ , _ , _ ) ->
815+ (* Enum constructor: compare with the enum value itself *)
816+ makeEq e Syntax. { e = SEId id; loc }
817+ | ExprVariable var when var.kind = Const ->
818+ (* Constant: create a constant reference for comparison *)
819+ makeEq e Syntax. { e = SEId id; loc }
820+ | _ -> Error. raiseError (" Pattern '" ^ id ^ " ' is not a valid enum constructor or constant" ) loc)
793821 in
794822 let if_stmt =
795823 CCList. fold_right
@@ -855,7 +883,7 @@ let rec stmt (env : env) (return : type_) (s : Syntax.stmt) : env * stmt list =
855883 let while_s = makeIterWhile env name id_loc value body loc in
856884 stmt env return while_s
857885 | { s = SStmtMatch { e; cases } ; _ } ->
858- let if_stmt = makeIfOfMatch e cases in
886+ let if_stmt = makeIfOfMatch env e cases in
859887 stmt env return if_stmt
860888
861889
0 commit comments