Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- """
- L-Systems interpreter based on Andrew Brown's excellent tutorial:
- PyPy tutorial by Andrew Brown
- example5.py - BF interpreter in RPython, translatable by PyPy, with JIT, and
- with a get_printable_location function and pure function wrapper
- for the dictionary lookup.
- """
- WIDTH = 800
- HEIGHT = 600
- import os
- import sys
- import math
- from pypy.rlib.jit import JitDriver, elidable, promote
- class Rule(object):
- """
- a rule maps a variable to a tokens string
- """
- _immutable_=True
- variable = ""
- tokens = ""
- def __init__(self, variable, tokens):
- self.variable = variable
- self.tokens = tokens
- def __str__(self):
- return "%s : %s" % (self.variable, self.tokens)
- class ScriptContext(object):
- """
- contains all context belonging to a script
- """
- _immutable_fields_ = [
- "cairo_context", "cairo_surface",
- "iterations", "start", "rules", "state"
- ]
- cairo_context = 0L #SIZE_T
- cairo_surface = 0L
- iterations = 0
- start = ""
- rules = None
- state = None
- @elidable
- def get_rule(self, symbol):
- return self.rules[symbol]
- @elidable
- def is_in_rules(self, symbol):
- return symbol in self.rules
- class DrawingState(object):
- """
- object to store drawing state information like
- current pen position, color, direction, etc.
- """
- pos_x = 0.0
- pos_y = 0.0
- step = 2.0
- angle = 0.0
- ############ Sorry for the mess, here are some cairo-functions:
- from pypy.rpython.lltypesystem import rffi, lltype
- from pypy.translator.tool.cbuild import ExternalCompilationInfo
- eci1 = ExternalCompilationInfo.from_compiler_flags("-pthread -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/include/cairo -I/usr/include/pixman-1")
- eci2 = ExternalCompilationInfo.from_linker_flags("-lcairo")
- eci3 = ExternalCompilationInfo(includes=["cairo.h"])
- info = eci1.merge(eci2)
- info = eci3.merge(info)
- cairo_image_surface_create = rffi.llexternal(
- "cairo_image_surface_create",
- [rffi.INT, rffi.INT, rffi.INT], rffi.SIZE_T,
- compilation_info=info)
- cairo_create = rffi.llexternal(
- "cairo_create", [rffi.SIZE_T], rffi.SIZE_T,
- compilation_info=info)
- cairo_set_source_rgb = rffi.llexternal(
- "cairo_set_source_rgb",
- [rffi.SIZE_T, rffi.DOUBLE, rffi.DOUBLE, rffi.DOUBLE], lltype.Void,
- compilation_info=info)
- cairo_paint = rffi.llexternal("cairo_paint", [rffi.SIZE_T], lltype.Void,
- compilation_info=info)
- cairo_move_to = rffi.llexternal(
- "cairo_move_to",
- [rffi.SIZE_T, rffi.DOUBLE, rffi.DOUBLE], lltype.Void,
- compilation_info=info)
- cairo_line_to = rffi.llexternal(
- "cairo_line_to",
- [rffi.SIZE_T, rffi.DOUBLE, rffi.DOUBLE], lltype.Void,
- compilation_info=info)
- cairo_stroke = rffi.llexternal("cairo_stroke", [rffi.SIZE_T], lltype.Void,
- compilation_info=info)
- cairo_surface_write_to_png = rffi.llexternal(
- "cairo_surface_write_to_png",
- [rffi.SIZE_T, rffi.CCHARP], rffi.INT,
- compilation_info=info)
- cairo_surface_destroy = rffi.llexternal(
- "cairo_surface_destroy",
- [rffi.SIZE_T], lltype.Void,
- compilation_info=info)
- cairo_destroy = rffi.llexternal("cairo_destroy",
- [rffi.SIZE_T], lltype.Void,
- compilation_info=info)
- def get_location(depth, rule):
- return "%s - %s" % (depth, rule.__str__())
- jitdriver = JitDriver(
- greens=['depth', 'rule'],
- reds=['context'],
- get_printable_location = get_location)
- def recurse_eval(rule, context, depth):
- jitdriver.jit_merge_point(
- depth = depth, rule = rule, context = context
- )
- state = context.state
- state = promote(state)
- context = promote(context)
- for symbol in rule.tokens:
- if context.is_in_rules(symbol) and depth < context.iterations:
- next_rule = context.get_rule(symbol)
- recurse_eval(next_rule, context, depth + 1)
- elif symbol == "+":
- state.angle += math.pi / 2.0
- elif symbol == "-":
- state.angle -= math.pi / 2.0
- elif symbol == "F":
- state.pos_x = state.pos_x + math.cos(state.angle) * state.step
- state.pos_y = state.pos_y + math.sin(state.angle) * state.step
- cairo_line_to(context.cairo_context,
- state.pos_x, state.pos_y)
- def mainloop(scriptctx):
- scriptctx.cairo_surface = cairo_image_surface_create(0, WIDTH, HEIGHT)
- scriptctx.cairo_context = cairo_create(scriptctx.cairo_surface)
- cairo_set_source_rgb(scriptctx.cairo_context, 0.0, 0.0, 0.0)
- cairo_paint(scriptctx.cairo_context)
- cairo_move_to(scriptctx.cairo_context, WIDTH / 2, HEIGHT / 2)
- scriptctx.state = DrawingState()
- scriptctx.state.pos_x, scriptctx.state.pos_y = WIDTH / 2, HEIGHT / 2
- curr_rule = scriptctx.get_rule(scriptctx.start)
- recurse_eval(curr_rule, scriptctx, 0)
- cairo_set_source_rgb(scriptctx.cairo_context, 1.0, 1.0, 1.0)
- cairo_stroke(scriptctx.cairo_context)
- cairo_surface_write_to_png(scriptctx.cairo_surface, "out.png")
- cairo_surface_destroy(scriptctx.cairo_surface)
- cairo_destroy(scriptctx.cairo_context)
- def parse(program):
- iterations = 0
- start = ""
- rules = {}
- for line in program.split("\n"):
- l = line.split(":")
- if len(l) == 2:
- lhs, rhs = l[0].strip(" "), l[1].strip(" ")
- if lhs == "iterations":
- iterations = int(rhs)
- elif lhs == "start":
- start = rhs
- elif lhs != "":
- r = Rule(lhs, rhs)
- rules[lhs] = r
- return iterations, start, rules
- def run(fp):
- program_contents = ""
- while True:
- read = os.read(fp, 4096)
- if len(read) == 0:
- break
- program_contents += read
- os.close(fp)
- iterations, start, rules = parse(program_contents)
- script_context = ScriptContext()
- script_context.iterations = iterations
- script_context.start = start
- script_context.rules = rules
- mainloop(script_context)
- def entry_point(argv):
- try:
- filename = argv[1]
- except IndexError:
- print "You must supply a filename"
- return 1
- run(os.open(filename, os.O_RDONLY, 0777))
- return 0
- def target(*args):
- return entry_point, None
- def jitpolicy(driver):
- from pypy.jit.codewriter.policy import JitPolicy
- return JitPolicy()
- if __name__ == "__main__":
- entry_point(sys.argv)
Add Comment
Please, Sign In to add comment