Skip to content

Commit

Permalink
Showing 6 changed files with 34 additions and 30 deletions.
16 changes: 8 additions & 8 deletions spec/compiler/parser/parser_spec.cr
Original file line number Diff line number Diff line change
@@ -830,11 +830,11 @@ describe "Parser" do

it_parses "foo $a", Call.new(nil, "foo", Global.new("$a"))

it_parses "$~", Call.new("$~".var, "not_nil!")
it_parses "$~.foo", Call.new(Call.new("$~".var, "not_nil!"), "foo")
it_parses "$1", Call.new(Call.new("$~".var, "not_nil!"), "[]", 1.int32)
it_parses "$1?", Call.new(Call.new("$~".var, "not_nil!"), "[]?", 1.int32)
it_parses "foo $1", Call.new(nil, "foo", Call.new(Call.new("$~".var, "not_nil!"), "[]", 1.int32))
it_parses "$~", Global.new("$~")
it_parses "$~.foo", Call.new(Global.new("$~"), "foo")
it_parses "$1", Call.new(Global.new("$~"), "[]", 1.int32)
it_parses "$1?", Call.new(Global.new("$~"), "[]?", 1.int32)
it_parses "foo $1", Call.new(nil, "foo", Call.new(Global.new("$~"), "[]", 1.int32))
it_parses "$~ = 1", Assign.new("$~".var, 1.int32)

it_parses "foo /a/", Call.new(nil, "foo", regex("a"))
@@ -843,9 +843,9 @@ describe "Parser" do
it_parses "foo(/ /, / /)", Call.new(nil, "foo", [regex(" "), regex(" ")] of ASTNode)
it_parses "foo a, / /", Call.new(nil, "foo", ["a".call, regex(" ")] of ASTNode)

it_parses "$?", Call.new("$?".var, "not_nil!")
it_parses "$?.foo", Call.new(Call.new("$?".var, "not_nil!"), "foo")
it_parses "foo $?", Call.new(nil, "foo", Call.new("$?".var, "not_nil!"))
it_parses "$?", Global.new("$?")
it_parses "$?.foo", Call.new(Global.new("$?"), "foo")
it_parses "foo $?", Call.new(nil, "foo", Global.new("$?"))
it_parses "$? = 1", Assign.new("$?".var, 1.int32)

it_parses "$0", Path.global("PROGRAM_NAME")
2 changes: 1 addition & 1 deletion src/compiler/crystal/semantic/ast.cr
Original file line number Diff line number Diff line change
@@ -1142,7 +1142,7 @@ module Crystal
ArrayLiteral HashLiteral RegexLiteral RangeLiteral
Case StringInterpolation
MacroExpression MacroIf MacroFor MultiAssign
SizeOf InstanceSizeOf) %}
SizeOf InstanceSizeOf Global) %}
class {{name.id}}
include ExpandableNode
end
4 changes: 4 additions & 0 deletions src/compiler/crystal/semantic/cleanup_transformer.cr
Original file line number Diff line number Diff line change
@@ -251,6 +251,10 @@ module Crystal
end

def transform(node : Global)
if expanded = node.expanded
return expanded
end

if const_node = @const_being_initialized
const_being_initialized = const_node.target_const.not_nil!

15 changes: 15 additions & 0 deletions src/compiler/crystal/semantic/main_visitor.cr
Original file line number Diff line number Diff line change
@@ -301,6 +301,21 @@ module Crystal
end

def visit(node : Global)
# Reading from a special global variable is actually
# reading from a local variable with that same not,
# invoking `not_nil!` on it (because these are usually
# accessed after invoking a method that brought them
# into the current scope, and it would be annoying
# to ask the user to always invoke `not_nil!` on it)
case node.name
when "$~", "$?"
expanded = Call.new(Var.new(node.name).at(node), "not_nil!").at(node)
expanded.accept self
node.bind_to expanded
node.expanded = expanded
return false
end

visit_global node
false
end
4 changes: 2 additions & 2 deletions src/compiler/crystal/syntax/parser.cr
Original file line number Diff line number Diff line change
@@ -957,7 +957,7 @@ module Crystal
@token.copy_from(@temp_token)
self.current_pos, @line_number, @column_number = old_pos, old_line, old_column

node_and_next_token Call.new(var, "not_nil!").at(location)
node_and_next_token Global.new(var.name).at(location)
end
when :GLOBAL_MATCH_DATA_INDEX
value = @token.value.to_s
@@ -971,7 +971,7 @@ module Crystal
method = "[]"
end
location = @token.location
node_and_next_token Call.new(Call.new(Var.new("$~").at(location), "not_nil!").at(location), method, NumberLiteral.new(value.to_i))
node_and_next_token Call.new(Global.new("$~").at(location), method, NumberLiteral.new(value.to_i))
end
when :__LINE__
node_and_next_token MagicConstant.expand_line_node(@token.location)
23 changes: 4 additions & 19 deletions src/compiler/crystal/tools/formatter.cr
Original file line number Diff line number Diff line change
@@ -1920,29 +1920,14 @@ module Crystal

obj = node.obj

# Special cases
if @token.type == :"$~" && node.name == "not_nil!" && obj.is_a?(Var) && obj.name == "$~"
write "$~"
next_token
return false
end

if @token.type == :"$?" && node.name == "not_nil!" && obj.is_a?(Var) && obj.name == "$?"
write "$?"
# Special case: $1, $2, ...
if @token.type == :GLOBAL_MATCH_DATA_INDEX && node.name == "[]" && obj.is_a?(Global)
write "$"
write @token.value
next_token
return false
end

if @token.type == :GLOBAL_MATCH_DATA_INDEX && node.name == "[]" && obj.is_a?(Call) && obj.name == "not_nil!"
obj2 = obj.obj
if obj2.is_a?(Var) && obj2.name == "$~"
write "$"
write @token.value
next_token
return false
end
end

write_token :"::" if node.global

if obj

0 comments on commit 4f755e7

Please sign in to comment.