Fixed the absence of environment-passing for assignment special macros.
[cslatevm.git] / src / lib / assignment.slate
blobded21d087522bf7ad2d31f9b0c9c60863d078035
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."
7 [overrideThis].
9 load@(nodes LoadVariable traits) setTo: val &environment: env
10 "Expands a local variable reference into a store to it."
11 [load store: val].
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)."
16 [| var |
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}]
21     ifFalse:
22       [var: (env addVariableNamed: message selector).
23        var store: val]
26 literal@(nodes Literal traits) setTo: val &environment: env
27 [| lhs |
28   lhs: literal value.
29   (lhs is: Symbol) \/ [lhs is: String]
30     ifTrue:
31       [literal value: lhs intern.
32        `(addSlot: literal `unquote valued: val `unquote)]
33     ifFalse:
34       [(lhs is: Integer)
35          ifTrue: [`(at: literal `unquote put: val `unquote)]
36          ifFalse:
37            [error: 'Assignment not implemented to this type of literal: ' ; lhs printString]]
40 _@(nodes Placeholder traits) setTo: val &environment: env
42   val
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:].
51        #at: -> [#at:put:].
52        #byteAt: -> [#byteAt:put:].
53        #wordAt: -> [#wordAt:put:].
54      } otherwise:
55        [| selectorWithPut |
56         (selectorWithPut: message selector name ; 'put:')
57           isInterned ifTrue: [selectorWithPut intern]]])
58     ifNil: [error: 'The selector cannot be handled via setTo:.'. message]
59     ifNotNilDo:
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."
65 [| result |
66   result: paren copy.
67   result statements infect: [| :statement | statement setTo: val &environment: env].
68   result
71 array@(nodes Array traits) setTo: vals &environment: env
72 "Performs a multiple-assignment."
74   array statements size caseOf: {
75     0 -> [vals].
76     1 -> [array statements last setTo: `(vals `unquote first) &environment: env]
77   } otherwise:
78     [| result tmpVar |
79      result: array copy.
80      env
81        ifNil:
82          [TODO: 'Can\'t handle this outside of a block context.']
83        ifNotNil:
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:
90                (statement setTo:
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