From b777ac42a7e8f2f2638712d035add134d0bae873 Mon Sep 17 00:00:00 2001 From: "Paul R. Tagliamonte" Date: Sat, 2 Mar 2013 20:38:18 -0500 Subject: [PATCH] Update etc --- hy/errors.py | 4 +++ hy/lex/__init__.py | 3 ++ hy/lex/machine.py | 20 ++++++++++++- hy/lex/states.py | 63 +++++++++++++++++++++++++++++++++++++++++ hy/models/__init__.py | 4 +++ hy/models/expression.py | 3 ++ hy/models/integer.py | 5 ++++ hy/models/string.py | 6 ++++ hy/models/symbol.py | 8 +++--- 9 files changed, 111 insertions(+), 5 deletions(-) diff --git a/hy/errors.py b/hy/errors.py index a36f557..a362197 100644 --- a/hy/errors.py +++ b/hy/errors.py @@ -20,4 +20,8 @@ class HyError(Exception): + """ + Generic Hy error. All interal Exceptions will be subclassed from this + Exception. + """ pass diff --git a/hy/lex/__init__.py b/hy/lex/__init__.py index bba059f..ed2564e 100644 --- a/hy/lex/__init__.py +++ b/hy/lex/__init__.py @@ -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: diff --git a/hy/lex/machine.py b/hy/lex/machine.py index cc651bb..3b81989 100644 --- a/hy/lex/machine.py +++ b/hy/lex/machine.py @@ -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 diff --git a/hy/lex/states.py b/hy/lex/states.py index 8f478d6..9d67bdd 100644 --- a/hy/lex/states.py +++ b/hy/lex/states.py @@ -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 diff --git a/hy/models/__init__.py b/hy/models/__init__.py index a344cbf..e462db4 100644 --- a/hy/models/__init__.py +++ b/hy/models/__init__.py @@ -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 diff --git a/hy/models/expression.py b/hy/models/expression.py index b99f43d..74c6164 100644 --- a/hy/models/expression.py +++ b/hy/models/expression.py @@ -22,4 +22,7 @@ from hy.models import HyObject class HyExpression(HyObject, list): + """ + Hy S-Expression. Basically just a list. + """ pass diff --git a/hy/models/integer.py b/hy/models/integer.py index c5d2b95..38c29a3 100644 --- a/hy/models/integer.py +++ b/hy/models/integer.py @@ -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) diff --git a/hy/models/string.py b/hy/models/string.py index 7e6e0c0..d2a542a 100644 --- a/hy/models/string.py +++ b/hy/models/string.py @@ -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 diff --git a/hy/models/symbol.py b/hy/models/symbol.py index 7116744..86cd4cb 100644 --- a/hy/models/symbol.py +++ b/hy/models/symbol.py @@ -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