roc/test/snapshots/can_basic_scoping.md
2025-11-25 10:05:41 -05:00

3.3 KiB

META

description=Basic variable scoping behavior
type=snippet

SOURCE

# Top-level variables
x = 5
y = 10

# Function that shadows outer variable
outerFunc = |_| {
    x = 20  # Should shadow top-level x
    innerResult = {
        # Block scope
        z = x + y  # x should resolve to 20, y to 10
        z + 1
    }
    innerResult
}

EXPECTED

DUPLICATE DEFINITION - can_basic_scoping.md:7:5:7:6

PROBLEMS

DUPLICATE DEFINITION The name x is being redeclared in this scope.

The redeclaration is here: can_basic_scoping.md:7:5:7:6:

    x = 20  # Should shadow top-level x
^

But x was already defined here: can_basic_scoping.md:2:1:2:2:

x = 5

^

TOKENS

LowerIdent,OpAssign,Int,
LowerIdent,OpAssign,Int,
LowerIdent,OpAssign,OpBar,Underscore,OpBar,OpenCurly,
LowerIdent,OpAssign,Int,
LowerIdent,OpAssign,OpenCurly,
LowerIdent,OpAssign,LowerIdent,OpPlus,LowerIdent,
LowerIdent,OpPlus,Int,
CloseCurly,
LowerIdent,
CloseCurly,
EndOfFile,

PARSE

(file
	(type-module)
	(statements
		(s-decl
			(p-ident (raw "x"))
			(e-int (raw "5")))
		(s-decl
			(p-ident (raw "y"))
			(e-int (raw "10")))
		(s-decl
			(p-ident (raw "outerFunc"))
			(e-lambda
				(args
					(p-underscore))
				(e-block
					(statements
						(s-decl
							(p-ident (raw "x"))
							(e-int (raw "20")))
						(s-decl
							(p-ident (raw "innerResult"))
							(e-block
								(statements
									(s-decl
										(p-ident (raw "z"))
										(e-binop (op "+")
											(e-ident (raw "x"))
											(e-ident (raw "y"))))
									(e-binop (op "+")
										(e-ident (raw "z"))
										(e-int (raw "1"))))))
						(e-ident (raw "innerResult"))))))))

FORMATTED

# Top-level variables
x = 5
y = 10

# Function that shadows outer variable
outerFunc = |_| {
	x = 20 # Should shadow top-level x
	innerResult = {
		# Block scope
		z = x + y # x should resolve to 20, y to 10
		z + 1
	}
	innerResult
}

CANONICALIZE

(can-ir
	(d-let
		(p-assign (ident "x"))
		(e-num (value "5")))
	(d-let
		(p-assign (ident "y"))
		(e-num (value "10")))
	(d-let
		(p-assign (ident "outerFunc"))
		(e-closure
			(captures
				(capture (ident "y")))
			(e-lambda
				(args
					(p-underscore))
				(e-block
					(s-let
						(p-assign (ident "x"))
						(e-num (value "20")))
					(s-let
						(p-assign (ident "innerResult"))
						(e-block
							(s-let
								(p-assign (ident "z"))
								(e-binop (op "add")
									(e-lookup-local
										(p-assign (ident "x")))
									(e-lookup-local
										(p-assign (ident "y")))))
							(e-binop (op "add")
								(e-lookup-local
									(p-assign (ident "z")))
								(e-num (value "1")))))
					(e-lookup-local
						(p-assign (ident "innerResult"))))))))

TYPES

(inferred-types
	(defs
		(patt (type "a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
		(patt (type "a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
		(patt (type "_arg -> a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]")))
	(expressions
		(expr (type "a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
		(expr (type "a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))
		(expr (type "_arg -> a where [a.from_numeral : Numeral -> Try(a, [InvalidNumeral(Str)])]"))))