/
githubmirror
/
julia
Обзор
Документация
Войти
/
githubmirror
/
julia
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
JuliaLowering/src/kinds.jl
225 строк
10 KB
Em Chu
[JuliaLowering] Make `SyntaxTree` a standard tree (#62474)
29 июл 2026, 15:34
Не верифицирован
29 июл 2026, 15:34
92cca2d
Код
Авторство
О чём код?
# The following kinds are used in intermediate forms by lowering but are not # part of the surface syntax function _register_kinds() JuliaSyntax.register_kinds!(JuliaLowering, 1, [ # "Syntax extensions" - expression kinds emitted by macros or macro # expansion, and known to lowering. These are part of the AST API but # without having surface syntax. "BEGIN_EXTENSION_KINDS" # atomic fields or accesses (see `@atomic`) "atomic" # Flag for @generated parts of a function "generated" # Temporary rooting of identifiers (GC.@preserve) "gc_preserve" "gc_preserve_begin" "gc_preserve_end" # A (quoted) `Symbol` "Symbol" "inbounds" "inbounds_pop" # expr: (inbounds pop) with identifier "pop" "boundscheck" "inline" "noinline" "loopinfo" "purity" "aliasscope" "popaliasscope" # Call into foreign code "foreigncall" # Look up a symbol in foreign code "foreignglobal" # ccall convention "cconv" # Special form for constructing a function callable from C "cfunction" # Special form emitted by `Base.Experimental.@opaque` "opaque_closure" # Test whether a variable is defined "isdefined" # [K"throw_undef_if_not" var cond] # This form is used internally in Core.Compiler but might be # emitted by packages such as Diffractor. In principle it needs to # be passed through lowering in a similar way to `isdefined` "throw_undef_if_not" # named labels for `@label` and `@goto` "symboliclabel" # Goto named label "symbolicgoto" # Goto named label (old syntax version, no try/finally check) "oldsymbolicgoto" # Labeled block for `@label name expr` (block break) "symbolicblock" # Internal initializer for struct types, for inner constructors/functions "new" "splatnew" # Used for converting `esc()`'d expressions arising from old macro # invocations during macro expansion (gone after macro expansion) "escape" # Used for converting the old-style macro hygienic-scope form (gone # after macro expansion). "hygienic-scope" # Only produced by flisp macro expansion (which Core.@doc (cursed) # invokes manually) "copyast" # An expression which will eventually be evaluated "statically" in # the context of a CodeInfo and thus allows access only to globals # and static parameters. Used for ccall, cfunction, cglobal # TODO: Use this for GeneratedFunctionStub also? "static_eval" "islocal" "isglobal" "locals" "thisfunction" "overlay" "syntaxquote" "syntaxunquote" "END_EXTENSION_KINDS" # The following kinds are internal to lowering "BEGIN_LOWERING_KINDS" # Semantic assertions used by lowering. The content of an assertion # is not considered to be quoted, so use K"Symbol" etc inside where necessary. "assert" # Unique identifying integer for bindings (of variables, constants, etc) "BindingId" # Various heads harvested from flisp lowering. # (TODO: May or may not need all these - assess later) # Like block, but introduces a lexical scope; used during scope resolution. "scope_block" # Equivalent to Expr(:softscope). If found in the top-level thunk, # all enclosed neutral scopes become soft scopes. :hardscope exists # too, but is always produced inside scope-blocks, so we represent # it with an attribute on our scope-blocks. "softscope" # [K"always_defined" x] is an assertion that variable `x` is assigned before use # ('local-def in flisp implementation is K"local" plus K"always_defined" "always_defined" # `(relayered_global old::Identifier)` is used to tell scope # resolution that any declaration conflicting with `(global old)` # should fail, even though `old` was never actually declared "relayered_global" "_while" "_do_while" # (_typevar name lb ub). flisp usually uses 3-long lists for these, # usually called `sparams` "_typevar" "_typevars" # used for supplying already-allocated `TypeVar`s to `where` # (_generated_body (quote gen) nongen) to allow arglist-related desugaring # to occur before the methods are created "_generated_body" "with_static_parameters" # converted from nothing::K"Value" into desugaring. flisp: (null) "nothing" "top" "core" "lambda" # "A source location literal" - a node which exists only to record # a sourceref "SourceLocation" # [K"function_decl" name] # Declare a zero-method generic function with global `name` or # creates a closure object and assigns it to the local `name`. "function_decl" # [K"function_type" name] # Evaluates to the type of the function or closure with given `name` "function_type" # [K"method_defs" name [K"block" typevars...] [K"block" body...]] # The code in `body` defines methods for generic function `name`. # If non-toplevel, all contained methods share a closure type. # `typevars` are assigned-once top-level locals only referenced # inside `K"method"`, but outside of `K"lambda"`, since any # reference inside a lambda should resolve to the lambda's sparam # shadowing it. "method_defs" # [K"typevar" name rhs] appears only in method_defs and gets special # scope resolution: a sequence of K"sparam"s are similar to nested # let-blocks, but without introducing a local scope. "typevar" "_opaque_closure" # The enclosed statements must be executed at top level "toplevel_butfirst" # like v = val, except that if `v` turns out global (either # implicitly or by explicit `global`), it gains an implicit `const` "assign_or_constdecl_if_global" "global_if_global" "moved_local" "label" "trycatchelse" "tryfinally" # The contained block of code causes no side effects and can be # removed by a later lowering pass if its value isn't used. # (That is, it's removable in the same sense as # `@assume_effects :removable`.) "removable" # Variable type declaration; `x::T = rhs` will be temporarily # desugared to include `(decl x T)` "decl" # [K"captured_local" index] # A local variable captured into a global method. Contains the # `index` of the associated `Box` in the rewrite list. "captured_local" # Causes the linearization pass to conditionally emit a world age increment "latestworld_if_toplevel" # This has two forms: # [K"constdecl" var val] => declare and assign constant # [K"constdecl" var] => declare undefined constant # var is GlobalRef Value or Identifier "constdecl" # Returned from statements that should error if the result is used. "unused_only" # Pre-lowered SSA value reference from Expr(:ssavalue, N). # Translated to a BindingId during desugaring. "ssavalue" # Wraps the first argument of a foreigncall / foreignglobal when it # should not be lowered (and should mostly be treated as :inert), but # requires scope resolution and special conversion to Expr. "foreignsymbol" "thunk" # Options specific to K"lambda" "generated_lambda" "toplevel_lambda" # Options specific to K"scope_block" "hard_scope" "neutral_scope" "LambdaBindings" "Slots" "END_LOWERING_KINDS" # The following kinds are emitted by lowering and used in Julia's untyped IR "BEGIN_IR_KINDS" # Identifier for a value which is only assigned once "SSAValue" # Local variable in a `CodeInfo` code object (including lambda arguments) "slot" # Static parameter to a `CodeInfo` code object ("type parameters" to methods) "static_parameter" # References/declares a global variable within a module "globalref" # Unconditional goto "goto" # Conditional goto "gotoifnot" # Exception handling "enter" "leave" "pop_exception" # Lowering targets for method definitions arising from `function` etc "method" # (re-)initialize a slot to undef # See Core.NewvarNode "newvar" # Result of lowering a `K"lambda"` after bindings have been # converted to slot/globalref/SSAValue. "code_info" # Internal initializer for opaque closures "new_opaque_closure" # Wrapper for the lambda of around opaque closure methods "opaque_closure_method" # World age increment (TODO: use top level assertion and only one latestworld kind) "latestworld" "END_IR_KINDS" ]) end