@@ -294,6 +294,19 @@ fn (mut t Transformer) transform_expr(expr ast.Expr) ast.Expr {
294294 pos: expr.pos
295295 })
296296 }
297+ ast.KeywordOperator {
298+ if expr.op == .key_typeof && expr.exprs.len > 0 {
299+ type_name := t.resolve_typeof_expr (expr.exprs[0 ])
300+ if type_name != '' {
301+ return ast.StringLiteral{
302+ kind: .v
303+ value: quote_v_string_literal (type_name)
304+ pos: expr.pos
305+ }
306+ }
307+ }
308+ expr
309+ }
297310 else {
298311 expr
299312 }
@@ -577,6 +590,19 @@ fn (mut t Transformer) transform_slice_index_expr(lhs ast.Expr, orig_lhs ast.Exp
577590
578591// transform_selector_expr transforms a selector expression, applying smart cast if applicable
579592fn (mut t Transformer) transform_selector_expr (expr ast.SelectorExpr) ast.Expr {
593+ // typeof(x).name -> string literal with V type name
594+ if expr.lhs is ast.KeywordOperator && expr.lhs.op == .key_typeof && expr.rhs.name == 'name' {
595+ if expr.lhs.exprs.len > 0 {
596+ type_name := t.resolve_typeof_expr (expr.lhs.exprs[0 ])
597+ if type_name != '' {
598+ return ast.StringLiteral{
599+ kind: .v
600+ value: quote_v_string_literal (type_name)
601+ pos: expr.pos
602+ }
603+ }
604+ }
605+ }
580606 // Check for smart cast field access: check ALL contexts in the stack
581607 if t.has_active_smartcast () {
582608 full_str := t.expr_to_string (expr)
@@ -595,6 +621,7 @@ fn (mut t Transformer) transform_selector_expr(expr ast.SelectorExpr) ast.Expr {
595621 }
596622 }
597623 // Handle module-qualified enum value access: module.EnumType.value -> module__EnumType__value
624+ // Also handle nested module references: rand.seed.time_seed_array -> seed__time_seed_array
598625 if expr.lhs is ast.SelectorExpr {
599626 lhs_sel := expr.lhs as ast.SelectorExpr
600627 if lhs_sel.lhs is ast.Ident {
@@ -609,6 +636,28 @@ fn (mut t Transformer) transform_selector_expr(expr ast.SelectorExpr) ast.Expr {
609636 }
610637 }
611638 }
639+ // Nested module reference: rand.seed.time_seed_array -> seed__time_seed_array
640+ // Only resolve when both the outer ident is a module AND the inner name
641+ // is also a sub-module (not a variable like os.args.len).
642+ if t.is_module_ident (module_name) {
643+ sub_mod := lhs_sel.rhs.name
644+ fn_name := expr.rhs.name
645+ // Check if sub_mod is actually a module scope
646+ if t.get_module_scope (sub_mod) != none {
647+ return ast.Ident{
648+ name: '${sub_mod }__${fn_name }'
649+ pos: expr.pos
650+ }
651+ }
652+ // Try full qualified name (module__sub_mod as scope key)
653+ full_mod := '${module_name }__${sub_mod }'
654+ if t.get_module_scope (full_mod) != none {
655+ return ast.Ident{
656+ name: '${full_mod }__${fn_name }'
657+ pos: expr.pos
658+ }
659+ }
660+ }
612661 }
613662 }
614663 // Default transformation
@@ -2382,6 +2431,45 @@ fn (mut t Transformer) transform_infix_expr(expr ast.InfixExpr) ast.Expr {
23822431 // arr1 == arr2 -> array__eq(arr1, arr2)
23832432 return eq_call
23842433 }
2434+ // Check for map comparisons: map1 == map2 or map1 != map2
2435+ // Exclude pointer-to-map types (those should be pointer comparisons)
2436+ if expr.op in [.eq, .ne] {
2437+ mut is_lhs_ptr_map := false
2438+ if lhs_type := t.get_expr_type (expr.lhs) {
2439+ if lhs_type is types.Pointer {
2440+ is_lhs_ptr_map = true
2441+ }
2442+ }
2443+ mut is_rhs_ptr_map := false
2444+ if rhs_type := t.get_expr_type (expr.rhs) {
2445+ if rhs_type is types.Pointer {
2446+ is_rhs_ptr_map = true
2447+ }
2448+ }
2449+ if ! is_lhs_ptr_map && ! is_rhs_ptr_map {
2450+ lhs_map_type := t.get_map_type_for_expr (expr.lhs)
2451+ rhs_map_type := t.get_map_type_for_expr (expr.rhs)
2452+ if lhs_map_type != none || rhs_map_type != none {
2453+ map_type_name := lhs_map_type or { rhs_map_type or { 'map' } }
2454+ eq_fn := '${map_type_name }_map_eq'
2455+ map_eq_call := ast.CallExpr{
2456+ lhs: ast.Ident{
2457+ name: eq_fn
2458+ }
2459+ args: [t.transform_expr (expr.lhs), t.transform_expr (expr.rhs)]
2460+ pos: expr.pos
2461+ }
2462+ if expr.op == .ne {
2463+ return ast.PrefixExpr{
2464+ op: .not
2465+ expr: map_eq_call
2466+ pos: expr.pos
2467+ }
2468+ }
2469+ return map_eq_call
2470+ }
2471+ }
2472+ }
23852473 }
23862474 // Check for struct operator overloading (e.g., time.Time - time.Time)
23872475 // This transforms t1 - t2 into time__Time__minus(t1, t2) for structs with operator overloading
0 commit comments