PyPy și RPython

Presenter Notes

PyPy

  • Reimplementare a limbajului Python
  • Diferența dintre specificație și implementare
  • Python: un limbaj
  • CPython, Jython, IronPython, PyPy, Pyston: implementări ale unui limbaj
  • Python vs CPython
  • Url: http://pypy.org/

Presenter Notes

PyPy

  • Foarte rapid (http://speed.pypy.org/)
  • Just in Time compiler
  • Compatibil cu Python 2.7 și 3.2
  • Încă are GIL, dar se lucrează la pypy STM
  • Nu se pot folosi extension modules scrise în api-ul CPython.

Presenter Notes

RPython

  • limbaj subset al limbajului Python, ce este potrivit pentru analiza statică
  • toolchain pentru generarea de interpretoare
  • aspecte ale interpretorului generat pot fi configurate cu toolchainul
  • poți alege ce tip de garbage collection să folosească
  • poți alege să ai un JIT sau nu
  • PyPy este doar unul din rezultatele acestui framework
  • Topaz, interpretor Ruby scris în RPython
  • HippyVM, interpretor PHP scris în RPython
  • "HippyVM on average is 7.3x faster than stock PHP and 2x faster than Facebook's HHVM."

Presenter Notes

RPython - limbajul

  • este un fel de Python ce limitează dinamismul pe care poți să-l folosești
  • variabilele globale sunt considerate constante
  • nu poți avea mai multe tipuri de date pentru o variabilă în toate situațiile
  • nu poți folosi metode de reflecție (__dict__)
  • nu poți să ai closures
  • poți folosi doar o parte din metodele speciale
  • poți folosi doar o parte din bibliotecile standard
  • nu poți folosi raw_input, open etc. (folosești direct os.read / os.write pe un file descriptor)
  • Definiția limbajului nu este specificată complet: "RPython is whatever our toolchain can accept"

Presenter Notes

RPython - toolchainul

  • componente separate ce pot lucra cu abstractizări
  • nu lucrează cu cod sursă sau arbori de sintaxă, lucrează doar cu code objects (bytecode)
  • are un concept de Space
  • Flow space pentru partea ce ține de sintaxă (control flow)
  • Object space pentru partea ce ține de operațiile efectuate pe obiecte (semantica)

Presenter Notes

RPython flow

https://rpython.readthedocs.org/en/latest/_images/graphviz-867b9238454890f2cf191d89a7389a534ef37fd9.png

Presenter Notes

RPython translator

  • fiecare program trebuie să aibă un punct de intrare de care RPython să știe (target)
import sys

def entry_point(argv):
    print("works!")
    return 0

def target(*args):
    return entry_point, None

if __name__ == "__main__":
    entry_point(sys.argv)
$ hg clone https://bitbucket.org/pypy/pypy
$ ... # build pypy
$ python pyp\rpython\translator\goal\translate.py sample.py
$ ./sample-c

Presenter Notes

Interpretor

  • un compilator specializat, "codul mașină" fiind procesat de VM-ul interpretorului
  • Lexer - transformă codul sursă în tokeni
  • Parser - transformă tokenii într-o reprezentare intermediară
  • Arbori abstracți de sintaxă sau bytecode
  • Interpretarea arborilor sau interpretarea bytecode-ului
  • Rularea codului de către VM-ul interpretorului (eval loop)

Presenter Notes

Lexer

from rply import LexerGenerator

lg = LexerGenerator()
# Regulă și expresia regulată care prinde regula respectivă
lg.add("NUMBER", "\d+")
lg.add("ADD", "\+")

# Ignoră alte caractere
lg.ignore(r"\s+")

# construiește lexerul
lexer = lg.build()

for token in lexer.lex("2+2"):
    print(token)
$ python lexer.py

Token('NUMBER', '2')
Token('ADD', '+')
Token('NUMBER', '2')

Presenter Notes

Parser

  • folosim tot RPLY
from rply import ParserGenerator

pg = ParserGenerator(
    [
          # Tokeni suportați
      "ADD", "NUMBER",
    ])

# Regula de producție, în stânga e regula, în dreapta sunt
# simboluri sau nume de alte reguli
@pg.production("main : expr")
def main(p):
    return p[0]

 ...

Presenter Notes

Parser (2)

...

# NUMBER - nume de symbol
# expr - nume de regulă
@pg.production("expr : NUMBER")
def expr(p):
    return int(p[0].value)

 @pg.production("expr : expr ADD expr")
 def addition(p):
     return p[0] + p[2]


 parser = pg.build()
 import sys
 print(parser.parse(lexer.lex(sys.argv[1])))
$ python parser.py 2+2+4
8

Presenter Notes

Arbori abstracți de sintaxă

  • reprezentarea intermediară generată de către parser
  • în RPython, regulile de producție ale unui parser nu pot genera structuri și obiecte Python
  • se așteaptă ca rezultatul să fie un Box, peste care pot fi efectuate operațiile
from rply.token import BaseBox

class Number(BaseBox):
    def __init__(self, value):
        self.value = value
    def eval(self):
        return int(self.value)

Presenter Notes

Presenter Notes