Franck Pommereau

initial import

*~
,*
+*
*.aux
*.log
*.fdb_latexmk
*.fls
*.nav
*.vrb
*.out
*.snm
*.synctex.gz
*.toc
__pycache__
class ExecEnv (dict) :
def __init__ (self, *l, **k) :
super().__init__(*l, **k)
def __setitem__ (self, key, val) :
old = self.get(key, None)
try :
old.set(val)
except AttributeError :
super().__setitem__(key, val)
def __getitem__ (self, key) :
old = self.get(key, None)
try :
return old.get()
except AttributeError :
return super().__getitem__(key)
def exec (self, code) :
exec(code, self)
def eval (self, code) :
return eval(code, self)
class CAni (object) :
_env = ExecEnv()
@property
def IP (self) :
return self._env.get("IP", 1)
@IP.setter
def IP (self, val) :
self._env["IP"] = val
@property
def RET (self) :
return self._env.get("RET", None)
@RET.setter
def RET (self, val) :
self._env["RET"] = val
def exec (self, code) :
self._env.exec(code)
def eval (self, code) :
RET = self.RET = self._env.eval(code)
return RET
This diff is collapsed. Click to expand it.
from inspect import Signature, Parameter
from . import CAni
from .highlight import pygmentize
class _CODE (CAni) :
_fields = []
_options = []
def __init__ (self, *l, **k) :
params = []
for i, name in enumerate(self._fields) :
if name[0] == "*" :
self._fields = self._fields[:]
self._fields[i] = name[1:]
params.append(Parameter(name[1:], Parameter.VAR_POSITIONAL))
else :
params.append(Parameter(name, Parameter.POSITIONAL_OR_KEYWORD))
for name in self._options :
params.append(Parameter(name, Parameter.POSITIONAL_OR_KEYWORD, default=None))
params.append(Parameter("src", Parameter.KEYWORD_ONLY, default=None))
sig = Signature(params)
args = sig.bind(*l, **k)
args.apply_defaults()
for key, val in args.arguments.items() :
setattr(self, key, val)
self._at = set()
def __str__ (self) :
content = []
for key, val in self.items() :
if isinstance(val, _CODE) :
content.append((key, str(val)))
else :
content.append((key, repr(val)))
return "%s(%s)" % (self.__class__.__name__,
", ".join("%s=%r" % item for item in content))
def items (self) :
for field in self._fields :
yield field, getattr(self, field)
for field in self._options :
member = getattr(self, field, None)
if member is not None :
yield field, member
def source (self) :
sub = {}
for key, val in self.items() :
if isinstance(val, _CODE) :
sub[key] = val.source()
else :
sub[key] = val
return self.src.format(**sub)
def tex (self) :
sub = self.src.format(**{key : "$" for key, val in self.items()}).split("$")
parts = [pygmentize(sub[0])]
for (key, val), txt in zip(self.items(), sub[1:]) :
if isinstance(val, _CODE) :
parts.append(val.tex())
else :
parts.append(pygmentize(str(val)))
parts.append(pygmentize(txt))
tex = "".join(parts)
if self._at :
return r"\onlyhl{%s}{" % ",".join(str(i) for i in self._at) + tex + "}"
else :
return tex
class BLOCK (_CODE) :
_fields = ["*body"]
def __call__ (self) :
self._at.add(self.IP)
for code in self.body :
code()
def source (self) :
return "".join(b.source() for b in self.body)
def tex (self) :
return "".join(b.tex() for b in self.body)
class STMT (_CODE) :
_fields = ["*steps"]
def __call__ (self) :
for s in self.steps :
self._at.add(self.IP)
self.exec(s)
self.IP += 1
class EXPR (_CODE) :
_fields = ["expr"]
def __init__ (self, *l, **k) :
super().__init__(*l, **k)
if self.src is None :
self.src = self.expr
def __call__ (self) :
self._at.add(self.IP)
self.eval(self.expr)
self.IP += 1
class PY (_CODE) :
_fields = ["py"]
def __call__ (self) :
self.exec(self.py)
def tex (self) :
return ""
def source (self) :
return ""
class ENV (_CODE) :
_fields = ["name", "value"]
def __call__ (self) :
self._env[self.name] = self.value
def tex (self) :
return ""
def source (self) :
return ""
class WS (_CODE) :
_fields = []
def __init__ (self, src) :
super().__init__(src=src)
def __call__ (self) :
pass
def tex (self) :
return self.src
class XDECL (_CODE) :
_fields = ["*names"]
def __call__ (self) :
for name in self.names :
self._env[name] = None
self._at.add(self.IP)
self.IP += 1
class DECL (_CODE) :
_fields = ["name"]
_options = ["init"]
def __call__ (self) :
if self.init is not None :
self.init()
self._env[self.name] = self.RET
else :
self._env[self.name] = None
self._at.add(self.IP)
self.IP += 1
def tex (self) :
src = super().tex()
if self.animate is None :
return src
else :
return src + " " + "".join(self._tex())
def _tex (self) :
tail = r"\PY{{c+c1}}{{/* {value} */}}"
for value, start, stop in self._cell.hist :
if value is not None :
yield (r"\onlyshow{{{start}-{stop}}}{{{value}}}"
r"").format(start=start or 1,
stop=stop or "",
value=tail.format(value=value))
class BreakLoop (Exception) :
def __init__ (self) :
super().__init__()
class BREAK (_CODE) :
def __call__ (self) :
self._at.add(self.IP)
self.IP += 1
raise BreakLoop()
class FunctionReturn (Exception) :
def __init__ (self, RET) :
super().__init__()
self.RET = RET
class RETURN (_CODE) :
_fields = ["value"]
def __call__ (self) :
self.value()
self._at.add(self.IP)
self.IP += 1
raise FunctionReturn(self.RET)
class IF (_CODE) :
_fields = ["cond", "then"]
_options = ["otherwise"]
def __call__ (self) :
self.cond()
if self.RET :
self.then()
elif self.otherwise is not None :
self.otherwise()
class WHILE (_CODE) :
_fields = ["cond", "body"]
def __call__ (self) :
try :
while True :
self.cond()
if not self.RET :
break
self.body()
except BreakLoop :
return
class DO (_CODE) :
_fields = ["body", "cond"]
def __call__ (self) :
try :
while True :
self.body()
self.cond()
if not self.RET :
break
except BreakLoop :
pass
class FOR (_CODE) :
_fields = ["init", "cond", "step", "body"]
def __call__ (self) :
self.init()
try :
while True :
self.cond()
if not self.RET :
break
self.body()
self.step()
except BreakLoop :
pass
class FUNC (_CODE) :
_fields = ["body"]
def __call__ (self) :
try :
self.body()
except FunctionReturn as exc :
self._env["RET"] = exc.RET
from pygments import highlight as _pygmentize
import pygments.lexers, pygments.formatters
##
## code pretty-printing
##
_lexer = pygments.lexers.get_lexer_by_name("C")
_formatter = pygments.formatters.get_formatter_by_name("latex")
def pygmentize (src) :
return "\n".join("\n".join(_pygmentize(line, _lexer, _formatter).splitlines()[1:-1])
for line in src.split("\n"))