1 # Test var / setvar / etc.
2
3 # TODO: GetVar needs a mode where Obj[str] gets translated to value.Str?
4 # Then all code will work.
5 #
6 # word_eval:
7 #
8 # val = self.mem.GetVar(var_name) ->
9 # val = GetWordVar(self.mem, var_name)
10 #
11 # Conversely, in oil_lang/expr_eval.py:
12 # LookupVar gives you a plain Python object. I don't think there's any
13 # downside here.
14 #
15 # repr exposes the differences.
16 #
17 # Notes:
18 #
19 # - osh/cmd_exec.py handles OilAssign, which gets wrapped in value.Obj()
20 # - osh/word_eval.py _ValueToPartValue handles 3 value types. Used in:
21 # - _EvalBracedVarSub
22 # - SimpleVarSub in _EvalWordPart
23 # - osh/expr_eval.py: _LookupVar wrapper should disallow using Oil values
24 # - this is legacy stuff. Both (( )) and [[ ]]
25 # - LhsIndexedName should not reference Oil vars either
26
27
28 #### integers expression and augmented assignment
29 var x = 1 + 2 * 3
30 echo x=$x
31
32 setvar x += 4
33 echo x=$x
34 ## STDOUT:
35 x=7
36 x=11
37 ## END
38
39 #### setvar when variable isn't declared results in fatal error
40 var x = 1
41 f() {
42 # setting global is OK
43 setvar x = 2
44 echo x=$x
45
46 setvar y = 3 # NOT DECLARED
47 echo y=$y
48 }
49 f
50 ## status: 1
51 ## STDOUT:
52 x=2
53 ## END
54
55 #### var/setvar x, y = 1, 2
56
57 # Python doesn't allow you to have annotation on each variable!
58 # https://www.python.org/dev/peps/pep-0526/#where-annotations-aren-t-allowed
59 var x Int, y Int = 3, 4
60 echo x=$x y=$y
61
62 setvar x, y = 1, 9
63 echo x=$x y=$y
64
65 setvar y, x = x, y
66 echo x=$x y=$y
67
68 ## STDOUT:
69 x=3 y=4
70 x=1 y=9
71 x=9 y=1
72 ## END
73
74 #### setvar d->key = 42 (setitem)
75 shopt -s oil:all
76
77 var d = {}
78 setvar d['f2'] = 42
79 setvar d->f3 = 43
80
81 # Use the opposite thing to retrieve
82 var f3 = d['f3']
83 var f2 = d->f2
84 echo f3=$f3
85 echo f2=$f2
86 ## STDOUT:
87 f3=43
88 f2=42
89 ## END
90
91 #### setvar mylist[1] = 42 (setitem)
92 shopt -s oil:all
93 var mylist = [1,2,3]
94 setvar mylist[1] = 42
95
96 echo -sep ' ' @mylist
97 ## STDOUT:
98 1 42 3
99 ## END
100
101 #### setvar obj.attr = 42 (setattr)
102 shopt -s oil:all
103
104 # TODO: dicts and list can't have arbitrary attributes set. But right now
105 # regex objects can. Should we change that?
106
107 var myobj = /d+/
108
109 setvar myobj.x = 42
110 var val = myobj.x
111 echo val=$val
112 ## STDOUT:
113 val=42
114 ## END
115
116 #### setvar f()[2] = 42 (setitem)
117 shopt -s oil:all
118
119 var mylist = [1,2,3]
120 func f() {
121 return mylist
122 }
123 setvar f()[2] = 42
124 echo @mylist
125 ## STDOUT:
126 1
127 2
128 42
129 ## END
130
131 #### duplicate var def results in fatal error
132 var x = "global"
133 f() {
134 var x = "local"
135 echo x=$x
136 }
137 f
138 var x = "redeclaration is an error"
139 ## status: 1
140 ## STDOUT:
141 x=local
142 ## END
143
144 #### setvar dynamic scope (TODO: change this?)
145 modify_with_shell_assignment() {
146 f=shell
147 }
148
149 modify_with_setvar() {
150 setvar f = "setvar"
151 }
152
153 f() {
154 var f = 1
155 echo f=$f
156 modify_with_shell_assignment
157 echo f=$f
158 modify_with_setvar
159 echo f=$f
160 }
161 f
162 ## STDOUT:
163 f=1
164 f=shell
165 f=setvar
166 ## END
167