We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
LIST-COMP breaks with certain variable names
Try compiling:

```
(list-comp (, i j) (i [-1 0 1] j [-1 0 1]))
```

With hy and you'll get some strange errors. If you replace "i" and "j" with "x" and "y" respectively, the same piece of code works as expected.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `hy/lex/states.py`
Content:
```
1 # Copyright (c) 2013 Paul Tagliamonte <paultag@debian.org>
2 #
3 # Permission is hereby granted, free of charge, to any person obtaining a
4 # copy of this software and associated documentation files (the "Software"),
5 # to deal in the Software without restriction, including without limitation
6 # the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 # and/or sell copies of the Software, and to permit persons to whom the
8 # Software is furnished to do so, subject to the following conditions:
9 #
10 # The above copyright notice and this permission notice shall be included in
11 # all copies or substantial portions of the Software.
12 #
13 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
16 # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19 # DEALINGS IN THE SOFTWARE.
20 
21 from hy.models.expression import HyExpression
22 from hy.models.integer import HyInteger
23 from hy.models.lambdalist import HyLambdaListKeyword
24 from hy.models.float import HyFloat
25 from hy.models.complex import HyComplex
26 from hy.models.symbol import HySymbol
27 from hy.models.string import HyString
28 from hy.models.keyword import HyKeyword
29 from hy.models.dict import HyDict
30 from hy.models.list import HyList
31 
32 from hy.errors import HyError
33 
34 from abc import ABCMeta, abstractmethod
35 
36 
37 WHITESPACE = [" ", "\t", "\n", "\r"]
38 
39 
40 class LexException(HyError):
41     """
42     Error during the Lexing of a Hython expression.
43     """
44     pass
45 
46 
47 def _resolve_atom(obj):
48     """
49     Resolve a bare atom into one of the following (in order):
50 
51         - Integer
52         - LambdaListKeyword
53         - Float
54         - Complex
55         - Symbol
56     """
57     try:
58         return HyInteger(obj)
59     except ValueError:
60         pass
61 
62     if obj.startswith("&"):
63         return HyLambdaListKeyword(obj)
64 
65     try:
66         return HyFloat(obj)
67     except ValueError:
68         pass
69 
70     try:
71         return HyComplex(obj)
72     except ValueError:
73         pass
74 
75     table = {
76         "true": "True",
77         "false": "False",
78         "null": "None",
79     }
80 
81     if obj in table:
82         return HySymbol(table[obj])
83 
84     if obj.startswith(":"):
85         return HyKeyword(obj)
86 
87     if obj.startswith("*") and obj.endswith("*") and obj not in ("*", "**"):
88         obj = obj[1:-1].upper()
89 
90     if "-" in obj and obj != "-":
91         obj = obj.replace("-", "_")
92 
93     return HySymbol(obj)
94 
95 
96 class State(object):
97     """
98     Generic State model.
99     """
100 
101     __slots__ = ("nodes", "machine")
102     __metaclass__ = ABCMeta
103 
104     def __init__(self, machine):
105         self.machine = machine
106 
107     def _enter(self):
108         """ Internal shim for running global ``enter`` code """
109         self.result = None
110         self.nodes = []
111         self.enter()
112 
113     def _exit(self):
114         """ Internal shim for running global ``exit`` code """
115         self.exit()
116 
117     def enter(self):
118         """
119         Overridable ``enter`` routines. Subclasses may implement this.
120         """
121         pass
122 
123     def exit(self):
124         """
125         Overridable ``exit`` routines. Subclasses may implement this.
126         """
127         pass
128 
129     @abstractmethod
130     def process(self, char):
131         """
132         Overridable ``process`` routines. Subclasses must implement this to be
133         useful.
134         """
135         pass  # ABC
136 
137 
138 class ListeyThing(State):
139 
140     def enter(self):
141         self.buf = ""
142 
143     def commit(self):
144         if self.buf != "":
145             ret = _resolve_atom(self.buf)
146             ret.start_line = self._start_line
147             ret.start_column = self._start_column
148             ret.end_line = self.machine.line
149             ret.end_column = (self.machine.column - 1)
150 
151             self.nodes.append(ret)
152         self.buf = ""
153 
154     def exit(self):
155         self.commit()
156         self.result = self.result_type(self.nodes)
157 
158     def process(self, char):
159         if char == "(":
160             self.commit()
161             self.machine.sub(Expression)
162             return
163 
164         if char == "{":
165             self.commit()
166             self.machine.sub(Dict)
167             return
168 
169         if char == "[":
170             self.commit()
171             self.machine.sub(List)
172             return
173 
174         if char == "\"":
175             self.commit()
176             self.machine.sub(String)
177             return
178 
179         if char == ";":
180             self.commit()
181             self.machine.sub(Comment)
182             return
183 
184         if char == self.end_char:
185             return Idle
186 
187         if char in ")]}":
188             raise LexException("Unexpected closing character: `%s'" % (char))
189 
190         if char in WHITESPACE:
191             self.commit()
192             return
193 
194         if self.buf == "":
195             self._start_line = self.machine.line
196             self._start_column = self.machine.column
197 
198         self.buf += char
199 
200 
201 class List(ListeyThing):
202     """
203     This state parses a Hy list (like a Clojure vector) for use in native
204     Python interop.
205 
206     [foo 1 2 3 4] is a good example.
207     """
208 
209     result_type = HyList
210     end_char = "]"
211 
212 
213 class Expression(ListeyThing):
214     """
215     This state parses a Hy expression (statement, to be evaluated at runtime)
216     for running things & stuff.
217     """
218 
219     result_type = HyExpression
220     end_char = ")"
221 
222 
223 class Dict(ListeyThing):
224     """
225     This state parses a Hy dict for things.
226     """
227 
228     def exit(self):
229         self.commit()
230         it = iter(self.nodes)
231         result = dict(zip(it, it))
232         self.result = HyDict(result)
233 
234     end_char = "}"
235 
236 
237 class String(State):
238     """
239     String state. This will handle stuff like:
240 
241         (println "foobar")
242                  ^^^^^^^^  -- String
243     """
244 
245     def enter(self):
246         self.escaped = False
247 
248     def exit(self):
249         self.result = HyString("".join(self.nodes))
250 
251     def process(self, char):
252         """
253         State transitions:
254 
255             - " - Idle
256         """
257         if self.escaped:
258             self.escaped = False
259             if char == "n":
260                 self.nodes.append("\n")
261                 return
262             if char == "\\":
263                 self.nodes.append("\\")
264                 return
265             if char == "\"":
266                 self.nodes.append("\"")
267                 return
268 
269             raise LexException("Unknown modifier: `%s'" % (char))
270 
271         if char == "\"":
272             return Idle
273 
274         if char == "\\":
275             self.escaped = True
276             return
277 
278         self.nodes.append(char)
279 
280 
281 class Atom(State):
282     """
283     This state parses integer constants, boolean constants, and symbols
284     """
285 
286     def __init__(self, machine):
287         State.__init__(self, machine)
288         self.initial_buf = ''
289 
290     def enter(self):
291         self.buf = self.initial_buf
292 
293     def exit(self):
294         self.result = _resolve_atom(self.buf)
295 
296     def process(self, char):
297         """
298         State transitions:
299 
300             - WHITESPACE - Idle
301             - ; - Comment
302         """
303 
304         if char in WHITESPACE:
305             return Idle
306 
307         if char == ";":
308             return Comment
309 
310         self.buf += char
311 
312 
313 def AtomStartingWith(initial_char):
314     def AtomFactory(machine):
315         state = Atom(machine)
316         state.initial_buf = initial_char
317         return state
318     return AtomFactory
319 
320 
321 class Idle(State):
322     """
323     Idle state. This is the first (and last) thing that we should
324     be in.
325     """
326 
327     def process(self, char):
328         """
329         State transitions:
330 
331             - ( - Expression
332             - [ - List
333             - { - Dict
334             - \" - String
335             - ; - Comment
336             - # - Hash
337             - (default) - Atom
338         """
339 
340         if char == "(":
341             return Expression
342 
343         if char == "[":
344             return List
345 
346         if char == "{":
347             return Dict
348 
349         if char == "\"":
350             return String
351 
352         if char == ";":
353             return Comment
354 
355         if char == "#":
356             return Hash
357 
358         if char in WHITESPACE:
359             return
360 
361         return AtomStartingWith(char)
362 
363 
364 class Comment(State):
365     """
366     Comment state.
367     """
368 
369     def process(self, char):
370         """
371         State transitions:
372 
373             - \n - Idle
374             - (default) - disregard.
375         """
376 
377         if char == "\n":
378             return Idle
379 
380 
381 class Hash(State):
382     """
383     Hash state
384     """
385 
386     def process(self, char):
387         """
388         State transitions:
389 
390             - ! - Comment
391         """
392 
393         if char == "!":
394             return Comment
395 
396         raise LexException("Unknown char (Hash state): `%s'" % (char))
397
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/hy/lex/states.py b/hy/lex/states.py
--- a/hy/lex/states.py
+++ b/hy/lex/states.py
@@ -67,10 +67,11 @@
     except ValueError:
         pass
 
-    try:
-        return HyComplex(obj)
-    except ValueError:
-        pass
+    if obj != "j":
+        try:
+            return HyComplex(obj)
+        except ValueError:
+            pass
 
     table = {
         "true": "True",

{"golden_diff": "diff --git a/hy/lex/states.py b/hy/lex/states.py\n--- a/hy/lex/states.py\n+++ b/hy/lex/states.py\n@@ -67,10 +67,11 @@\n     except ValueError:\n         pass\n \n-    try:\n-        return HyComplex(obj)\n-    except ValueError:\n-        pass\n+    if obj != \"j\":\n+        try:\n+            return HyComplex(obj)\n+        except ValueError:\n+            pass\n \n     table = {\n         \"true\": \"True\",\n", "issue": "LIST-COMP breaks with certain variable names\nTry compiling:\n\n```\n(list-comp (, i j) (i [-1 0 1] j [-1 0 1]))\n```\n\nWith hy and you'll get some strange errors. If you replace \"i\" and \"j\" with \"x\" and \"y\" respectively, the same piece of code works as expected.\n\n", "before_files": [{"content": "# Copyright (c) 2013 Paul Tagliamonte <paultag@debian.org>\n#\n# Permission is hereby granted, free of charge, to any person obtaining a\n# copy of this software and associated documentation files (the \"Software\"),\n# to deal in the Software without restriction, including without limitation\n# the rights to use, copy, modify, merge, publish, distribute, sublicense,\n# and/or sell copies of the Software, and to permit persons to whom the\n# Software is furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in\n# all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\n# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n# DEALINGS IN THE SOFTWARE.\n\nfrom hy.models.expression import HyExpression\nfrom hy.models.integer import HyInteger\nfrom hy.models.lambdalist import HyLambdaListKeyword\nfrom hy.models.float import HyFloat\nfrom hy.models.complex import HyComplex\nfrom hy.models.symbol import HySymbol\nfrom hy.models.string import HyString\nfrom hy.models.keyword import HyKeyword\nfrom hy.models.dict import HyDict\nfrom hy.models.list import HyList\n\nfrom hy.errors import HyError\n\nfrom abc import ABCMeta, abstractmethod\n\n\nWHITESPACE = [\" \", \"\\t\", \"\\n\", \"\\r\"]\n\n\nclass LexException(HyError):\n    \"\"\"\n    Error during the Lexing of a Hython expression.\n    \"\"\"\n    pass\n\n\ndef _resolve_atom(obj):\n    \"\"\"\n    Resolve a bare atom into one of the following (in order):\n\n        - Integer\n        - LambdaListKeyword\n        - Float\n        - Complex\n        - Symbol\n    \"\"\"\n    try:\n        return HyInteger(obj)\n    except ValueError:\n        pass\n\n    if obj.startswith(\"&\"):\n        return HyLambdaListKeyword(obj)\n\n    try:\n        return HyFloat(obj)\n    except ValueError:\n        pass\n\n    try:\n        return HyComplex(obj)\n    except ValueError:\n        pass\n\n    table = {\n        \"true\": \"True\",\n        \"false\": \"False\",\n        \"null\": \"None\",\n    }\n\n    if obj in table:\n        return HySymbol(table[obj])\n\n    if obj.startswith(\":\"):\n        return HyKeyword(obj)\n\n    if obj.startswith(\"*\") and obj.endswith(\"*\") and obj not in (\"*\", \"**\"):\n        obj = obj[1:-1].upper()\n\n    if \"-\" in obj and obj != \"-\":\n        obj = obj.replace(\"-\", \"_\")\n\n    return HySymbol(obj)\n\n\nclass State(object):\n    \"\"\"\n    Generic State model.\n    \"\"\"\n\n    __slots__ = (\"nodes\", \"machine\")\n    __metaclass__ = ABCMeta\n\n    def __init__(self, machine):\n        self.machine = machine\n\n    def _enter(self):\n        \"\"\" Internal shim for running global ``enter`` code \"\"\"\n        self.result = None\n        self.nodes = []\n        self.enter()\n\n    def _exit(self):\n        \"\"\" Internal shim for running global ``exit`` code \"\"\"\n        self.exit()\n\n    def enter(self):\n        \"\"\"\n        Overridable ``enter`` routines. Subclasses may implement this.\n        \"\"\"\n        pass\n\n    def exit(self):\n        \"\"\"\n        Overridable ``exit`` routines. Subclasses may implement this.\n        \"\"\"\n        pass\n\n    @abstractmethod\n    def process(self, char):\n        \"\"\"\n        Overridable ``process`` routines. Subclasses must implement this to be\n        useful.\n        \"\"\"\n        pass  # ABC\n\n\nclass ListeyThing(State):\n\n    def enter(self):\n        self.buf = \"\"\n\n    def commit(self):\n        if self.buf != \"\":\n            ret = _resolve_atom(self.buf)\n            ret.start_line = self._start_line\n            ret.start_column = self._start_column\n            ret.end_line = self.machine.line\n            ret.end_column = (self.machine.column - 1)\n\n            self.nodes.append(ret)\n        self.buf = \"\"\n\n    def exit(self):\n        self.commit()\n        self.result = self.result_type(self.nodes)\n\n    def process(self, char):\n        if char == \"(\":\n            self.commit()\n            self.machine.sub(Expression)\n            return\n\n        if char == \"{\":\n            self.commit()\n            self.machine.sub(Dict)\n            return\n\n        if char == \"[\":\n            self.commit()\n            self.machine.sub(List)\n            return\n\n        if char == \"\\\"\":\n            self.commit()\n            self.machine.sub(String)\n            return\n\n        if char == \";\":\n            self.commit()\n            self.machine.sub(Comment)\n            return\n\n        if char == self.end_char:\n            return Idle\n\n        if char in \")]}\":\n            raise LexException(\"Unexpected closing character: `%s'\" % (char))\n\n        if char in WHITESPACE:\n            self.commit()\n            return\n\n        if self.buf == \"\":\n            self._start_line = self.machine.line\n            self._start_column = self.machine.column\n\n        self.buf += char\n\n\nclass List(ListeyThing):\n    \"\"\"\n    This state parses a Hy list (like a Clojure vector) for use in native\n    Python interop.\n\n    [foo 1 2 3 4] is a good example.\n    \"\"\"\n\n    result_type = HyList\n    end_char = \"]\"\n\n\nclass Expression(ListeyThing):\n    \"\"\"\n    This state parses a Hy expression (statement, to be evaluated at runtime)\n    for running things & stuff.\n    \"\"\"\n\n    result_type = HyExpression\n    end_char = \")\"\n\n\nclass Dict(ListeyThing):\n    \"\"\"\n    This state parses a Hy dict for things.\n    \"\"\"\n\n    def exit(self):\n        self.commit()\n        it = iter(self.nodes)\n        result = dict(zip(it, it))\n        self.result = HyDict(result)\n\n    end_char = \"}\"\n\n\nclass String(State):\n    \"\"\"\n    String state. This will handle stuff like:\n\n        (println \"foobar\")\n                 ^^^^^^^^  -- String\n    \"\"\"\n\n    def enter(self):\n        self.escaped = False\n\n    def exit(self):\n        self.result = HyString(\"\".join(self.nodes))\n\n    def process(self, char):\n        \"\"\"\n        State transitions:\n\n            - \" - Idle\n        \"\"\"\n        if self.escaped:\n            self.escaped = False\n            if char == \"n\":\n                self.nodes.append(\"\\n\")\n                return\n            if char == \"\\\\\":\n                self.nodes.append(\"\\\\\")\n                return\n            if char == \"\\\"\":\n                self.nodes.append(\"\\\"\")\n                return\n\n            raise LexException(\"Unknown modifier: `%s'\" % (char))\n\n        if char == \"\\\"\":\n            return Idle\n\n        if char == \"\\\\\":\n            self.escaped = True\n            return\n\n        self.nodes.append(char)\n\n\nclass Atom(State):\n    \"\"\"\n    This state parses integer constants, boolean constants, and symbols\n    \"\"\"\n\n    def __init__(self, machine):\n        State.__init__(self, machine)\n        self.initial_buf = ''\n\n    def enter(self):\n        self.buf = self.initial_buf\n\n    def exit(self):\n        self.result = _resolve_atom(self.buf)\n\n    def process(self, char):\n        \"\"\"\n        State transitions:\n\n            - WHITESPACE - Idle\n            - ; - Comment\n        \"\"\"\n\n        if char in WHITESPACE:\n            return Idle\n\n        if char == \";\":\n            return Comment\n\n        self.buf += char\n\n\ndef AtomStartingWith(initial_char):\n    def AtomFactory(machine):\n        state = Atom(machine)\n        state.initial_buf = initial_char\n        return state\n    return AtomFactory\n\n\nclass Idle(State):\n    \"\"\"\n    Idle state. This is the first (and last) thing that we should\n    be in.\n    \"\"\"\n\n    def process(self, char):\n        \"\"\"\n        State transitions:\n\n            - ( - Expression\n            - [ - List\n            - { - Dict\n            - \\\" - String\n            - ; - Comment\n            - # - Hash\n            - (default) - Atom\n        \"\"\"\n\n        if char == \"(\":\n            return Expression\n\n        if char == \"[\":\n            return List\n\n        if char == \"{\":\n            return Dict\n\n        if char == \"\\\"\":\n            return String\n\n        if char == \";\":\n            return Comment\n\n        if char == \"#\":\n            return Hash\n\n        if char in WHITESPACE:\n            return\n\n        return AtomStartingWith(char)\n\n\nclass Comment(State):\n    \"\"\"\n    Comment state.\n    \"\"\"\n\n    def process(self, char):\n        \"\"\"\n        State transitions:\n\n            - \\n - Idle\n            - (default) - disregard.\n        \"\"\"\n\n        if char == \"\\n\":\n            return Idle\n\n\nclass Hash(State):\n    \"\"\"\n    Hash state\n    \"\"\"\n\n    def process(self, char):\n        \"\"\"\n        State transitions:\n\n            - ! - Comment\n        \"\"\"\n\n        if char == \"!\":\n            return Comment\n\n        raise LexException(\"Unknown char (Hash state): `%s'\" % (char))\n", "path": "hy/lex/states.py"}], "after_files": [{"content": "# Copyright (c) 2013 Paul Tagliamonte <paultag@debian.org>\n#\n# Permission is hereby granted, free of charge, to any person obtaining a\n# copy of this software and associated documentation files (the \"Software\"),\n# to deal in the Software without restriction, including without limitation\n# the rights to use, copy, modify, merge, publish, distribute, sublicense,\n# and/or sell copies of the Software, and to permit persons to whom the\n# Software is furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in\n# all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\n# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n# DEALINGS IN THE SOFTWARE.\n\nfrom hy.models.expression import HyExpression\nfrom hy.models.integer import HyInteger\nfrom hy.models.lambdalist import HyLambdaListKeyword\nfrom hy.models.float import HyFloat\nfrom hy.models.complex import HyComplex\nfrom hy.models.symbol import HySymbol\nfrom hy.models.string import HyString\nfrom hy.models.keyword import HyKeyword\nfrom hy.models.dict import HyDict\nfrom hy.models.list import HyList\n\nfrom hy.errors import HyError\n\nfrom abc import ABCMeta, abstractmethod\n\n\nWHITESPACE = [\" \", \"\\t\", \"\\n\", \"\\r\"]\n\n\nclass LexException(HyError):\n    \"\"\"\n    Error during the Lexing of a Hython expression.\n    \"\"\"\n    pass\n\n\ndef _resolve_atom(obj):\n    \"\"\"\n    Resolve a bare atom into one of the following (in order):\n\n        - Integer\n        - LambdaListKeyword\n        - Float\n        - Complex\n        - Symbol\n    \"\"\"\n    try:\n        return HyInteger(obj)\n    except ValueError:\n        pass\n\n    if obj.startswith(\"&\"):\n        return HyLambdaListKeyword(obj)\n\n    try:\n        return HyFloat(obj)\n    except ValueError:\n        pass\n\n    if obj != \"j\":\n        try:\n            return HyComplex(obj)\n        except ValueError:\n            pass\n\n    table = {\n        \"true\": \"True\",\n        \"false\": \"False\",\n        \"null\": \"None\",\n    }\n\n    if obj in table:\n        return HySymbol(table[obj])\n\n    if obj.startswith(\":\"):\n        return HyKeyword(obj)\n\n    if obj.startswith(\"*\") and obj.endswith(\"*\") and obj not in (\"*\", \"**\"):\n        obj = obj[1:-1].upper()\n\n    if \"-\" in obj and obj != \"-\":\n        obj = obj.replace(\"-\", \"_\")\n\n    return HySymbol(obj)\n\n\nclass State(object):\n    \"\"\"\n    Generic State model.\n    \"\"\"\n\n    __slots__ = (\"nodes\", \"machine\")\n    __metaclass__ = ABCMeta\n\n    def __init__(self, machine):\n        self.machine = machine\n\n    def _enter(self):\n        \"\"\" Internal shim for running global ``enter`` code \"\"\"\n        self.result = None\n        self.nodes = []\n        self.enter()\n\n    def _exit(self):\n        \"\"\" Internal shim for running global ``exit`` code \"\"\"\n        self.exit()\n\n    def enter(self):\n        \"\"\"\n        Overridable ``enter`` routines. Subclasses may implement this.\n        \"\"\"\n        pass\n\n    def exit(self):\n        \"\"\"\n        Overridable ``exit`` routines. Subclasses may implement this.\n        \"\"\"\n        pass\n\n    @abstractmethod\n    def process(self, char):\n        \"\"\"\n        Overridable ``process`` routines. Subclasses must implement this to be\n        useful.\n        \"\"\"\n        pass  # ABC\n\n\nclass ListeyThing(State):\n\n    def enter(self):\n        self.buf = \"\"\n\n    def commit(self):\n        if self.buf != \"\":\n            ret = _resolve_atom(self.buf)\n            ret.start_line = self._start_line\n            ret.start_column = self._start_column\n            ret.end_line = self.machine.line\n            ret.end_column = (self.machine.column - 1)\n\n            self.nodes.append(ret)\n        self.buf = \"\"\n\n    def exit(self):\n        self.commit()\n        self.result = self.result_type(self.nodes)\n\n    def process(self, char):\n        if char == \"(\":\n            self.commit()\n            self.machine.sub(Expression)\n            return\n\n        if char == \"{\":\n            self.commit()\n            self.machine.sub(Dict)\n            return\n\n        if char == \"[\":\n            self.commit()\n            self.machine.sub(List)\n            return\n\n        if char == \"\\\"\":\n            self.commit()\n            self.machine.sub(String)\n            return\n\n        if char == \";\":\n            self.commit()\n            self.machine.sub(Comment)\n            return\n\n        if char == self.end_char:\n            return Idle\n\n        if char in \")]}\":\n            raise LexException(\"Unexpected closing character: `%s'\" % (char))\n\n        if char in WHITESPACE:\n            self.commit()\n            return\n\n        if self.buf == \"\":\n            self._start_line = self.machine.line\n            self._start_column = self.machine.column\n\n        self.buf += char\n\n\nclass List(ListeyThing):\n    \"\"\"\n    This state parses a Hy list (like a Clojure vector) for use in native\n    Python interop.\n\n    [foo 1 2 3 4] is a good example.\n    \"\"\"\n\n    result_type = HyList\n    end_char = \"]\"\n\n\nclass Expression(ListeyThing):\n    \"\"\"\n    This state parses a Hy expression (statement, to be evaluated at runtime)\n    for running things & stuff.\n    \"\"\"\n\n    result_type = HyExpression\n    end_char = \")\"\n\n\nclass Dict(ListeyThing):\n    \"\"\"\n    This state parses a Hy dict for things.\n    \"\"\"\n\n    def exit(self):\n        self.commit()\n        it = iter(self.nodes)\n        result = dict(zip(it, it))\n        self.result = HyDict(result)\n\n    end_char = \"}\"\n\n\nclass String(State):\n    \"\"\"\n    String state. This will handle stuff like:\n\n        (println \"foobar\")\n                 ^^^^^^^^  -- String\n    \"\"\"\n\n    def enter(self):\n        self.escaped = False\n\n    def exit(self):\n        self.result = HyString(\"\".join(self.nodes))\n\n    def process(self, char):\n        \"\"\"\n        State transitions:\n\n            - \" - Idle\n        \"\"\"\n        if self.escaped:\n            self.escaped = False\n            if char == \"n\":\n                self.nodes.append(\"\\n\")\n                return\n            if char == \"\\\\\":\n                self.nodes.append(\"\\\\\")\n                return\n            if char == \"\\\"\":\n                self.nodes.append(\"\\\"\")\n                return\n\n            raise LexException(\"Unknown modifier: `%s'\" % (char))\n\n        if char == \"\\\"\":\n            return Idle\n\n        if char == \"\\\\\":\n            self.escaped = True\n            return\n\n        self.nodes.append(char)\n\n\nclass Atom(State):\n    \"\"\"\n    This state parses integer constants, boolean constants, and symbols\n    \"\"\"\n\n    def __init__(self, machine):\n        State.__init__(self, machine)\n        self.initial_buf = ''\n\n    def enter(self):\n        self.buf = self.initial_buf\n\n    def exit(self):\n        self.result = _resolve_atom(self.buf)\n\n    def process(self, char):\n        \"\"\"\n        State transitions:\n\n            - WHITESPACE - Idle\n            - ; - Comment\n        \"\"\"\n\n        if char in WHITESPACE:\n            return Idle\n\n        if char == \";\":\n            return Comment\n\n        self.buf += char\n\n\ndef AtomStartingWith(initial_char):\n    def AtomFactory(machine):\n        state = Atom(machine)\n        state.initial_buf = initial_char\n        return state\n    return AtomFactory\n\n\nclass Idle(State):\n    \"\"\"\n    Idle state. This is the first (and last) thing that we should\n    be in.\n    \"\"\"\n\n    def process(self, char):\n        \"\"\"\n        State transitions:\n\n            - ( - Expression\n            - [ - List\n            - { - Dict\n            - \\\" - String\n            - ; - Comment\n            - # - Hash\n            - (default) - Atom\n        \"\"\"\n\n        if char == \"(\":\n            return Expression\n\n        if char == \"[\":\n            return List\n\n        if char == \"{\":\n            return Dict\n\n        if char == \"\\\"\":\n            return String\n\n        if char == \";\":\n            return Comment\n\n        if char == \"#\":\n            return Hash\n\n        if char in WHITESPACE:\n            return\n\n        return AtomStartingWith(char)\n\n\nclass Comment(State):\n    \"\"\"\n    Comment state.\n    \"\"\"\n\n    def process(self, char):\n        \"\"\"\n        State transitions:\n\n            - \\n - Idle\n            - (default) - disregard.\n        \"\"\"\n\n        if char == \"\\n\":\n            return Idle\n\n\nclass Hash(State):\n    \"\"\"\n    Hash state\n    \"\"\"\n\n    def process(self, char):\n        \"\"\"\n        State transitions:\n\n            - ! - Comment\n        \"\"\"\n\n        if char == \"!\":\n            return Comment\n\n        raise LexException(\"Unknown char (Hash state): `%s'\" % (char))\n", "path": "hy/lex/states.py"}]}