2 n@(nodes Node traits) setTo: val &environment: env
3 "A macro to expand the node and value into an appropriate assignment for the
4 location that the message appears to use."
5 "TODO: Use type inference on arguments to detect if there should be a concrete
6 slot attribute or other type of accessor to verify or distinguish."
9 load@(nodes LoadVariable traits) setTo: val &environment: env
10 "Expands a local variable reference into a store to it."
13 message@(nodes UnaryMessage traits) setTo: val &environment: env
14 "Makes a substitution of the unary message with a keyword message that is the
15 mutator form of that selector (appends a colon)."
17 env isNil \/ [(message arguments first = nodes ImplicitArgument) not]
18 ifTrue: [nodes KeywordMessage
19 sending: (message argument mutatorNameFor: message selector)
20 to: {message argument. val}]
22 [var: (env addVariableNamed: message selector).
26 literal@(nodes Literal traits) setTo: val &environment: env
29 (lhs is: Symbol) \/ [lhs is: String]
31 [literal value: lhs intern.
32 `(addSlot: literal `unquote valued: val `unquote)]
35 ifTrue: [`(at: literal `unquote put: val `unquote)]
37 [error: 'Assignment not implemented to this type of literal: ' ; lhs printString]]
40 _@(nodes Placeholder traits) setTo: val &environment: env
45 message@(nodes KeywordMessage traits) setTo: val &environment: env
46 "Expands a message by looking at its selector and picking the right setter."
48 (message selector isKeywordSelector ifTrue:
49 [message selector caseOf:
50 {#atSlotNamed: -> [#atSlotNamed:put:].
52 #byteAt: -> [#byteAt:put:].
53 #wordAt: -> [#wordAt:put:].
56 (selectorWithPut: message selector name ; 'put:')
57 isInterned ifTrue: [selectorWithPut intern]]])
58 ifNil: [error: 'The selector cannot be handled via setTo:.'. message]
60 [| :newSel | message sending: newSel to: (message arguments copyWith: val)]
63 paren@(nodes Parenthesis traits) setTo: val &environment: env
64 "Performs a multiple-assignment by transforming each statement."
67 result statements infect: [| :statement | statement setTo: val &environment: env].
71 array@(nodes Array traits) setTo: vals &environment: env
72 "Performs a multiple-assignment."
74 array statements size caseOf: {
76 1 -> [array statements last setTo: `(vals `unquote first) &environment: env]
82 [TODO: 'Can\'t handle this outside of a block context.']
84 [tmpVar: ((vals is: nodes LoadVariable)
85 ifTrue: [vals variable] ifFalse: [env addVariable]).
86 "result statements: array statements collectWithIndex:"
87 array statements doWithIndex:
88 [| :statement :index |
89 result statements at: index put:
91 (nodes KeywordMessage sending: #at: to:
92 {tmpVar load. nodes Literal for: index}) &environment: env)].
93 {tmpVar store: vals. result} as: nodes Parenthesis]]
96 load@(nodes LoadVariable traits) defaultsTo: default &environment: env
97 "A macro that expands to an expression that sets a variable in the scope to
98 the expression in the default."
99 [`(load `unquote ifNil: [(load store: default parenthesize) `unquote])].
101 node@(nodes Node traits) defaultsTo: default &environment: env
102 "Conditional assignment on the value being Nil or absent.
103 This generalizes on Load defaultsTo:."
104 [`(node `unquote ifNil: [(node setTo: default &environment: env) `unquote])].
106 node@(nodes Node traits) setToIfNotNil: value &environment: env
107 "Conditional assignment on the value being Nil or absent.
108 This generalizes on Load defaultsTo:."
110 `(value `unquote ifNotNil: [(node setTo: value &environment: env) `unquote])
113 "This is the tricky moment at which we activate the special macro.
114 Above here, it is unavailable, and after here, the definitions is not sound."
115 n@(nodes Node traits) := val &environment: env [n setTo: val &environment: env].
117 node@(nodes Node traits) ?= value &environment: env
119 node setToIfNotNil: value &environment: env
122 node@(nodes Node traits) += value &environment: env
124 node setTo: (nodes BinaryMessage sending: #+ to: {node. value}) &environment: env
127 node@(nodes Node traits) -= value &environment: env
129 node setTo: (nodes BinaryMessage sending: #- to: {node. value}) &environment: env
132 node@(nodes Node traits) *= value &environment: env
134 node setTo: (nodes BinaryMessage sending: #* to: {node. value}) &environment: env
137 node@(nodes Node traits) /= value &environment: env
139 node setTo: `(node `unquote / value `unquote) &environment: env