1 node@(nodes Node traits) expand &environment: env
3 [node macroExpand &environment: env].
5 node@(nodes Node traits) macroExpand &environment: _
6 "The default do-nothing action of macro expansion."
11 ann@(nodes Annotation traits) macroExpand &environment: env
12 "Return the annotation node, but replace the expression that the node
13 annotates with its expansion."
15 ann value == (expansion := ann value macroExpand &environment: env)
16 ifFalse: [ann value := expansion].
20 macro@(nodes Macro traits) macroExpand &optionals: opts &environment: env
21 "Simply apply the macro-method to its arguments. The generated nodes
22 inherit the macro node's debugging information."
24 macro selector = #macroExpand ifTrue:
25 [error: 'Cannot macroExpand `macroExpand. Use `(expr) macroExpand instead'.
31 opts keywords with: opts arguments do:
32 [| :key :arg | result nextPutAll: {key intern. arg}]] writingAs: #{}].
34 (macro selector sendTo: macro arguments
35 &optionals: (opts ; {#&environment:. env}))
36 macroExpand &environment: env.
37 macro lineNumber ifNotNilDo:
40 [| :child | child lineNumber `defaultsTo: lineNumber]].
44 message@(nodes Message traits) macroExpand &optionals: opts &environment: env
45 "Replace each argument to the message with its macro-expanded value.
46 When appropriate substitute a LoadVariable or StoreVariable for the message."
48 "Ensure macro expansions properly refer to Variables."
50 [message == (expansion := env linkVariablesIn: message)
51 ifFalse: [^ (expansion macroExpand &optionals: opts &environment: env)]].
55 argument == (expansion := argument macroExpand &environment: env)
56 ifFalse: [message arguments at: index put: expansion]].
60 [opts message == message
61 ifFalse: [opts message := message].
65 argument == (expansion := argument macroExpand &environment: env)
67 [opts arguments at: index put: expansion]].
71 opts@(nodes OptionalKeywords traits) macroExpand &environment: env
72 "Replace each argument to the optional keywords with its macro-expanded value."
74 opts message macroExpand &optionals: opts &environment: env
77 rest@(nodes RestArguments traits) macroExpand &environment: env
78 "Replace each rest argument with its macro-expanded value."
80 (rest for: (rest message macroExpand &environment: env)) `>>
81 [arguments := rest arguments collect:
82 [| :arg | arg macroExpand &environment: env]. ]
85 group@(nodes CompoundStatement traits) macroExpand &environment: env
86 "Replace the group's contents with their macro-expansions. This covers:
87 Arrays, Blocks, and Parentheses."
91 [| :statement :index expansion |
92 statement == (expansion := statement macroExpand &environment: env)
94 [group statements at: index put: expansion]].
98 block@(nodes Block traits) macroExpand &environment: env
99 "Set up the environment optional parameter to use the block as its value,
100 and resend it on to handle the main structure."
102 env ifNotNil: [env linkVariablesIn: block].
107 method@(nodes MethodDefinition traits) macroExpand &environment: env
108 "MethodDefinition nodes must handle the additional complication of roles."
115 role == (expansion := role macroExpand &environment: env)
116 ifFalse: [method roles at: index put: expansion]]].
120 load@(nodes LoadVariable traits) macroExpand &environment: env
124 ifNotNil: [env linkVariablesIn: load]
127 store@(nodes StoreVariable traits) macroExpand &environment: env
128 "Expand the value to be stored."
131 [store == (expansion := env linkVariablesIn: store)
132 ifFalse: [^ (expansion macroExpand &environment: env)]].
133 store value == (expansion := store value macroExpand &environment: env)
134 ifFalse: [store value := expansion].
138 ret@(nodes Return traits) macroExpand &environment: env
139 "Expand the value to be returned."
141 ret value == (expansion := ret value macroExpand &environment: env)
142 ifFalse: [ret value := expansion].
146 _@(nodes Block traits) linkVariablesIn: node
151 b@(nodes Block traits) linkVariablesIn: load@(nodes LoadVariable traits)
153 (b includesScope: load variable scope)
157 [(b findVariable: load variable name)
159 [nodes UnaryMessage sending: load variable name to: {nodes ImplicitArgument}]
162 load variable := var.
166 b@(nodes Block traits) linkVariablesIn: store@(nodes StoreVariable traits)
168 (b includesScope: store variable scope)
172 [(b findVariable: store variable name)
174 [nodes KeywordMessage
175 sending: store variable name name ; ':'
176 to: {nodes ImplicitArgument. store value}]
179 store variable := var.
183 b@(nodes Block traits) linkVariablesIn: msg@(nodes UnaryMessage traits)
185 (msg arguments first isSameAs: nodes ImplicitArgument)
186 ifTrue: [(b findVariable: msg selector)
188 ifNotNilDo: #load `er]
192 b@(nodes Block traits) linkVariablesIn: msg@(nodes KeywordMessage traits)
194 (msg arguments first isSameAs: nodes ImplicitArgument)
195 /\ [msg arguments size = 2]
196 ifTrue: [(b findVariable: msg selector name allButLast intern)
198 ifNotNilDo: [| :var | var store: msg arguments second]]
202 parent@(nodes Block traits) linkVariablesIn: child@(nodes Block traits)
204 child parentScope == parent \/ [child == parent]
205 ifFalse: [child parentScope := parent].
209 b@(nodes Block traits) linkVariables
210 "Fixes up a Block syntax tree so that all message sends within which should
211 actually be loads and stores are turned into those corresponding expression
212 types. This works by recursing down the tree with linkVariablesIn:."
214 b transformBy: [| :node | b linkVariablesIn: node]