Update etc

This commit is contained in:
Paul R. Tagliamonte 2013-03-02 20:38:18 -05:00
parent 159151f847
commit b777ac42a7
9 changed files with 111 additions and 5 deletions

View File

@ -20,4 +20,8 @@
class HyError(Exception):
"""
Generic Hy error. All interal Exceptions will be subclassed from this
Exception.
"""
pass

View File

@ -23,6 +23,9 @@ from hy.lex.states import Idle, LexException
def tokenize(buf):
"""
Tokenize a Lisp file or string buffer into internal Hy objects.
"""
machine = Machine(Idle, 1, 0)
machine.process(buf)
if type(machine.state) != Idle:

View File

@ -22,6 +22,11 @@ from hy.lex.states import Idle, LexException
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",
"start_line", "start_column")
@ -33,8 +38,12 @@ class Machine(object):
self.state = None
self.set_state(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:
self.state._exit()
@ -47,9 +56,15 @@ class Machine(object):
self.start_column = self.column
def sub(self, state):
"""
Set up a submachine for this machine.
"""
self.submachine = Machine(state, self.line, self.column)
def accept_result(self, state):
"""
Accept and annotate the result.
"""
if state and state.result:
result = state.result
@ -59,6 +74,9 @@ class Machine(object):
self.nodes.append(result)
def process(self, buf):
"""
process an iterable of chars into Hy internal models of the Source.
"""
for char in buf:
self.column += 1

View File

@ -30,10 +30,19 @@ WHITESPACE = [" ", "\t", "\n", "\r"]
class LexException(HyError):
"""
Error during the Lexing of a Hython expression.
"""
pass
def _resolve_atom(obj):
"""
Resolve a bare atom into one of the following (in order):
- Integer
- Symbol
"""
try:
return HyInteger(obj)
except ValueError:
@ -43,30 +52,53 @@ def _resolve_atom(obj):
class State(object):
"""
Generic State model.
"""
__slots__ = ("nodes", "machine")
def __init__(self, machine):
self.machine = machine
def _enter(self):
""" Internal shim for running global ``enter`` code """
self.result = None
self.nodes = []
self.enter()
def _exit(self):
""" Internal shim for running global ``exit`` code """
self.exit()
def enter(self):
"""
Overridable ``enter`` routines. Subclasses may implement this.
"""
pass # ABC
def exit(self):
"""
Overridable ``exit`` routines. Subclasses may implement this.
"""
pass # ABC
def process(self, char):
"""
Overridable ``process`` routines. Subclasses must implement this to be
useful.
"""
pass # ABC
class Expression(State):
"""
Expression state. This will handle stuff like:
(...... (....))
^^^^^^ -- expression
^^^^^^^^^^^^^^^ -- expression
"""
def enter(self):
self.buf = ""
@ -81,6 +113,13 @@ class Expression(State):
self.result = HyExpression(self.nodes)
def process(self, char):
"""
State transitions:
- ( - sub Expression
- " - sub String
- (whitespace) - Idle
"""
if char == "(":
self.machine.sub(Expression)
return
@ -100,10 +139,22 @@ class Expression(State):
class String(State):
"""
String state. This will handle stuff like:
(println "foobar")
^^^^^^^^ -- String
"""
def exit(self):
self.result = HyString("".join(self.nodes))
def process(self, char):
"""
State transitions:
- " - Idle
"""
if char == "\"":
return Idle
@ -111,7 +162,19 @@ class String(State):
class Idle(State):
"""
Idle state. This is the first (and last) thing that we should
be in.
"""
def process(self, char):
"""
State transitions:
- ( - Expression
- (default) - Error
"""
if char == "(":
return Expression

View File

@ -20,4 +20,8 @@
class HyObject(object):
"""
Generic Hy Object model. This is helpful to inject things into all the
Hy lexing Objects at once.
"""
pass

View File

@ -22,4 +22,7 @@ from hy.models import HyObject
class HyExpression(HyObject, list):
"""
Hy S-Expression. Basically just a list.
"""
pass

View File

@ -22,6 +22,11 @@ from hy.models import HyObject
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):
number = int(number)
return super(HyInteger, cls).__new__(cls, number)

View File

@ -29,6 +29,12 @@ else:
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):
obj = _str_type.__new__(cls, value)
return obj

View File

@ -22,9 +22,9 @@ from hy.models.string import HyString
class HySymbol(HyString):
"""
Hy Symbol. Basically a String.
"""
def __init__(self, string):
self += string
def eval(self, lns, *args, **kwargs):
obj = self.lookup(lns, self)
return obj