Update etc
This commit is contained in:
parent
159151f847
commit
b777ac42a7
@ -20,4 +20,8 @@
|
|||||||
|
|
||||||
|
|
||||||
class HyError(Exception):
|
class HyError(Exception):
|
||||||
|
"""
|
||||||
|
Generic Hy error. All interal Exceptions will be subclassed from this
|
||||||
|
Exception.
|
||||||
|
"""
|
||||||
pass
|
pass
|
||||||
|
@ -23,6 +23,9 @@ from hy.lex.states import Idle, LexException
|
|||||||
|
|
||||||
|
|
||||||
def tokenize(buf):
|
def tokenize(buf):
|
||||||
|
"""
|
||||||
|
Tokenize a Lisp file or string buffer into internal Hy objects.
|
||||||
|
"""
|
||||||
machine = Machine(Idle, 1, 0)
|
machine = Machine(Idle, 1, 0)
|
||||||
machine.process(buf)
|
machine.process(buf)
|
||||||
if type(machine.state) != Idle:
|
if type(machine.state) != Idle:
|
||||||
|
@ -22,6 +22,11 @@ from hy.lex.states import Idle, LexException
|
|||||||
|
|
||||||
|
|
||||||
class Machine(object):
|
class Machine(object):
|
||||||
|
"""
|
||||||
|
Hy State Machine. This controls all the state hopping we need to do
|
||||||
|
to properly parse Hy source.
|
||||||
|
"""
|
||||||
|
|
||||||
__slots__ = ("submachine", "nodes", "state", "line", "column",
|
__slots__ = ("submachine", "nodes", "state", "line", "column",
|
||||||
"start_line", "start_column")
|
"start_line", "start_column")
|
||||||
|
|
||||||
@ -33,8 +38,12 @@ class Machine(object):
|
|||||||
self.state = None
|
self.state = None
|
||||||
self.set_state(state)
|
self.set_state(state)
|
||||||
|
|
||||||
|
|
||||||
def set_state(self, state):
|
def set_state(self, state):
|
||||||
|
"""
|
||||||
|
Set the new internal machine state. This helps keep line annotations
|
||||||
|
correct, and make sure that we properly call enter and exit.
|
||||||
|
"""
|
||||||
|
|
||||||
if self.state:
|
if self.state:
|
||||||
self.state._exit()
|
self.state._exit()
|
||||||
|
|
||||||
@ -47,9 +56,15 @@ class Machine(object):
|
|||||||
self.start_column = self.column
|
self.start_column = self.column
|
||||||
|
|
||||||
def sub(self, state):
|
def sub(self, state):
|
||||||
|
"""
|
||||||
|
Set up a submachine for this machine.
|
||||||
|
"""
|
||||||
self.submachine = Machine(state, self.line, self.column)
|
self.submachine = Machine(state, self.line, self.column)
|
||||||
|
|
||||||
def accept_result(self, state):
|
def accept_result(self, state):
|
||||||
|
"""
|
||||||
|
Accept and annotate the result.
|
||||||
|
"""
|
||||||
if state and state.result:
|
if state and state.result:
|
||||||
result = state.result
|
result = state.result
|
||||||
|
|
||||||
@ -59,6 +74,9 @@ class Machine(object):
|
|||||||
self.nodes.append(result)
|
self.nodes.append(result)
|
||||||
|
|
||||||
def process(self, buf):
|
def process(self, buf):
|
||||||
|
"""
|
||||||
|
process an iterable of chars into Hy internal models of the Source.
|
||||||
|
"""
|
||||||
for char in buf:
|
for char in buf:
|
||||||
|
|
||||||
self.column += 1
|
self.column += 1
|
||||||
|
@ -30,10 +30,19 @@ WHITESPACE = [" ", "\t", "\n", "\r"]
|
|||||||
|
|
||||||
|
|
||||||
class LexException(HyError):
|
class LexException(HyError):
|
||||||
|
"""
|
||||||
|
Error during the Lexing of a Hython expression.
|
||||||
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def _resolve_atom(obj):
|
def _resolve_atom(obj):
|
||||||
|
"""
|
||||||
|
Resolve a bare atom into one of the following (in order):
|
||||||
|
|
||||||
|
- Integer
|
||||||
|
- Symbol
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
return HyInteger(obj)
|
return HyInteger(obj)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
@ -43,30 +52,53 @@ def _resolve_atom(obj):
|
|||||||
|
|
||||||
|
|
||||||
class State(object):
|
class State(object):
|
||||||
|
"""
|
||||||
|
Generic State model.
|
||||||
|
"""
|
||||||
|
|
||||||
__slots__ = ("nodes", "machine")
|
__slots__ = ("nodes", "machine")
|
||||||
|
|
||||||
def __init__(self, machine):
|
def __init__(self, machine):
|
||||||
self.machine = machine
|
self.machine = machine
|
||||||
|
|
||||||
def _enter(self):
|
def _enter(self):
|
||||||
|
""" Internal shim for running global ``enter`` code """
|
||||||
self.result = None
|
self.result = None
|
||||||
self.nodes = []
|
self.nodes = []
|
||||||
self.enter()
|
self.enter()
|
||||||
|
|
||||||
def _exit(self):
|
def _exit(self):
|
||||||
|
""" Internal shim for running global ``exit`` code """
|
||||||
self.exit()
|
self.exit()
|
||||||
|
|
||||||
def enter(self):
|
def enter(self):
|
||||||
|
"""
|
||||||
|
Overridable ``enter`` routines. Subclasses may implement this.
|
||||||
|
"""
|
||||||
pass # ABC
|
pass # ABC
|
||||||
|
|
||||||
def exit(self):
|
def exit(self):
|
||||||
|
"""
|
||||||
|
Overridable ``exit`` routines. Subclasses may implement this.
|
||||||
|
"""
|
||||||
pass # ABC
|
pass # ABC
|
||||||
|
|
||||||
def process(self, char):
|
def process(self, char):
|
||||||
|
"""
|
||||||
|
Overridable ``process`` routines. Subclasses must implement this to be
|
||||||
|
useful.
|
||||||
|
"""
|
||||||
pass # ABC
|
pass # ABC
|
||||||
|
|
||||||
|
|
||||||
class Expression(State):
|
class Expression(State):
|
||||||
|
"""
|
||||||
|
Expression state. This will handle stuff like:
|
||||||
|
|
||||||
|
(...... (....))
|
||||||
|
^^^^^^ -- expression
|
||||||
|
^^^^^^^^^^^^^^^ -- expression
|
||||||
|
"""
|
||||||
|
|
||||||
def enter(self):
|
def enter(self):
|
||||||
self.buf = ""
|
self.buf = ""
|
||||||
@ -81,6 +113,13 @@ class Expression(State):
|
|||||||
self.result = HyExpression(self.nodes)
|
self.result = HyExpression(self.nodes)
|
||||||
|
|
||||||
def process(self, char):
|
def process(self, char):
|
||||||
|
"""
|
||||||
|
State transitions:
|
||||||
|
|
||||||
|
- ( - sub Expression
|
||||||
|
- " - sub String
|
||||||
|
- (whitespace) - Idle
|
||||||
|
"""
|
||||||
if char == "(":
|
if char == "(":
|
||||||
self.machine.sub(Expression)
|
self.machine.sub(Expression)
|
||||||
return
|
return
|
||||||
@ -100,10 +139,22 @@ class Expression(State):
|
|||||||
|
|
||||||
|
|
||||||
class String(State):
|
class String(State):
|
||||||
|
"""
|
||||||
|
String state. This will handle stuff like:
|
||||||
|
|
||||||
|
(println "foobar")
|
||||||
|
^^^^^^^^ -- String
|
||||||
|
"""
|
||||||
|
|
||||||
def exit(self):
|
def exit(self):
|
||||||
self.result = HyString("".join(self.nodes))
|
self.result = HyString("".join(self.nodes))
|
||||||
|
|
||||||
def process(self, char):
|
def process(self, char):
|
||||||
|
"""
|
||||||
|
State transitions:
|
||||||
|
|
||||||
|
- " - Idle
|
||||||
|
"""
|
||||||
if char == "\"":
|
if char == "\"":
|
||||||
return Idle
|
return Idle
|
||||||
|
|
||||||
@ -111,7 +162,19 @@ class String(State):
|
|||||||
|
|
||||||
|
|
||||||
class Idle(State):
|
class Idle(State):
|
||||||
|
"""
|
||||||
|
Idle state. This is the first (and last) thing that we should
|
||||||
|
be in.
|
||||||
|
"""
|
||||||
|
|
||||||
def process(self, char):
|
def process(self, char):
|
||||||
|
"""
|
||||||
|
State transitions:
|
||||||
|
|
||||||
|
- ( - Expression
|
||||||
|
- (default) - Error
|
||||||
|
"""
|
||||||
|
|
||||||
if char == "(":
|
if char == "(":
|
||||||
return Expression
|
return Expression
|
||||||
|
|
||||||
|
@ -20,4 +20,8 @@
|
|||||||
|
|
||||||
|
|
||||||
class HyObject(object):
|
class HyObject(object):
|
||||||
|
"""
|
||||||
|
Generic Hy Object model. This is helpful to inject things into all the
|
||||||
|
Hy lexing Objects at once.
|
||||||
|
"""
|
||||||
pass
|
pass
|
||||||
|
@ -22,4 +22,7 @@ from hy.models import HyObject
|
|||||||
|
|
||||||
|
|
||||||
class HyExpression(HyObject, list):
|
class HyExpression(HyObject, list):
|
||||||
|
"""
|
||||||
|
Hy S-Expression. Basically just a list.
|
||||||
|
"""
|
||||||
pass
|
pass
|
||||||
|
@ -22,6 +22,11 @@ from hy.models import HyObject
|
|||||||
|
|
||||||
|
|
||||||
class HyInteger(HyObject, int):
|
class HyInteger(HyObject, int):
|
||||||
|
"""
|
||||||
|
Internal represntation of a Hy Integer. May raise a ValueError as if
|
||||||
|
int(foo) was caled, given HyInteger(foo).
|
||||||
|
"""
|
||||||
|
|
||||||
def __new__(cls, number, *args, **kwargs):
|
def __new__(cls, number, *args, **kwargs):
|
||||||
number = int(number)
|
number = int(number)
|
||||||
return super(HyInteger, cls).__new__(cls, number)
|
return super(HyInteger, cls).__new__(cls, number)
|
||||||
|
@ -29,6 +29,12 @@ else:
|
|||||||
|
|
||||||
|
|
||||||
class HyString(HyObject, _str_type):
|
class HyString(HyObject, _str_type):
|
||||||
|
"""
|
||||||
|
Generic Hy String object. Helpful to store string literals from Hy
|
||||||
|
scripts. It's either a ``str`` or a ``unicode``, depending on the
|
||||||
|
Python version.
|
||||||
|
"""
|
||||||
|
|
||||||
def __new__(cls, value):
|
def __new__(cls, value):
|
||||||
obj = _str_type.__new__(cls, value)
|
obj = _str_type.__new__(cls, value)
|
||||||
return obj
|
return obj
|
||||||
|
@ -22,9 +22,9 @@ from hy.models.string import HyString
|
|||||||
|
|
||||||
|
|
||||||
class HySymbol(HyString):
|
class HySymbol(HyString):
|
||||||
|
"""
|
||||||
|
Hy Symbol. Basically a String.
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, string):
|
def __init__(self, string):
|
||||||
self += string
|
self += string
|
||||||
|
|
||||||
def eval(self, lns, *args, **kwargs):
|
|
||||||
obj = self.lookup(lns, self)
|
|
||||||
return obj
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user