Drkcore

10 12 2010 Python Tweet

石庭っていう画像埋め込みプログラムをつくろうとしたが途中で飽きた

プレゼンテーションZenに触発されてつくろうと思ったが途中で飽きた。あとは画像に埋め込むのと画像から抽出する部分を書けばいいんだけどね。まぁ気が向いたらまたやる。

ProductName プレゼンテーションzen
Garr Reynolds
ピアソン桐原 / 2415円 ( 2009-09-04 )


やりたかったのはうさぎの写真にfib(5)を実行するコードを埋め込むとか。

re.Scannerの使い方を覚えたのでよしとしよう。

import sys
import re
from re import Scanner
import Image

LOGLEVEL = 2

def log(level, *msg):
    if level <= LOGLEVEL:
        print "\t".join(map(str, msg))

class VM(object):
    """ Virtual Machine """
    def __init__(self,insns):
        self.insns = insns
        self.stack      = []
        self.heap       = {}
        self.labels     = self.find_labels(insns)

    def run(self):
        return_to = []
        pc = 0
        while pc < len(self.insns):
            if len(self.insns[pc]) == 1:
                insn = self.insns[pc][0]
            else:
                insn,arg = self.insns[pc]

            if insn == "push":
                self.push(arg)
            elif insn == "dup":
                self.push(self.stack[-1])
            elif insn == "copy":
                self.push(self.stack[(arg+1)])
            elif insn == "swap":
                x = self.pop()
                y = self.pop()
                self.push(x)
                self.push(y)
            elif insn == "discard":
                self.pop()
            elif insn == "slide":
                x = self.pop()
                for i in range(arg):
                    self.pop()
                self.push(x)
            elif insn == "add":
                self.push(self.pop() + self.pop())
            elif insn == "sub":
                y = self.pop()
                x = self.pop()
                self.push(x - y)                
            elif insn == "mul":
                self.push(self.pop() * self.pop())                
            elif insn == "div":
                y = self.pop()
                x = self.pop()
                self.push(x / y)
            elif insn == "mod":
                y = self.pop();
                x = self.pop()
                self.push(x % y)
            elif insn == "heap_write":
                value = self.pop()
                addr  = self.pop()
                self.heap[addr] = value
            elif insn == "heap_read":
                addr = self.pop()
                value = self.heap[addr]
                self.push(value)
            elif insn == "jump":
                pc = self.jump_to(arg)
            elif insn == "jump_zero":
                if self.pop() == 0:
                    pc = self.jump_to(arg)
            elif insn == "jump_negative":
                if self.pop() < 0:
                    pc = self.jump_to(arg)
            elif insn == "call":
                return_to.append(pc)
                pc = self.jump_to(arg)
            elif insn == "return":
                if len(return_to) < 1: IndexError('return_to has no item')
                pc = return_to.pop()
            elif insn == "exit":
                return
            elif insn == "char_out":
                sys.stdout.write(chr(self.pop()))
            elif insn == "num_out":
                print self.pop()
            elif insn == "char_in":
                addr = self.pop()
                self.heap[addr] = ord(sys.stdin.read(1))
            elif insn == "num_in":
                addr = self.pop()
                self.heap[addr] = int(sys.stdin.read())
            pc += 1
        print "プログラムの最後がexitではない"

    def push(self, item):
        if type(item).__name__ != 'int': raise TypeError('Not a Integer')
        self.stack.append(item)
        log(2, "stack op: ",self.stack)
    def pop(self):
        if len(self.stack) < 1: raise IndexError('stack has no item')
        return self.stack.pop()

    def jump_to(self, name):
        pc = self.labels[name]
        return pc

    def find_labels(self, insns):
        labels = {}
        for i,tp in enumerate(insns):
            if tp[0] == 'label':
                labels[tp[1]] = i
        return labels

### Scanner

rnum = "([01]+)2"
rlabel = rnum

scanner = Scanner([
    (r"00%s" % rnum,    lambda s,token: ("push", to_num(re.sub(r'^00','',token)))),
    (r"020",            lambda s,token: ("dup",)),
    (r"010%s" % rnum,   lambda s,token: ("copy", to_num(re.sub(r'^010','',token)))),
    (r"021",            lambda s,token: ("swap",)),
    (r"022",            lambda s,token: ("discard",)),
    (r"012%s" % rnum,   lambda s,token: ("slide", to_num(re.sub(r'^012','',token)))),
    (r"1000",           lambda s,token: ("add",)),
    (r"1001",           lambda s,token: ("sub",)),
    (r"1002",           lambda s,token: ("mul",)),
    (r"1010",           lambda s,token: ("div",)),
    (r"1011",           lambda s,token: ("mod",)),
    (r"110",            lambda s,token: ("heap_write",)),
    (r"111",            lambda s,token: ("heap_read",)),
    (r"200%s" % rlabel, lambda s,token: ("label", to_label(re.sub(r'^200','',token)))),
    (r"201%s" % rlabel, lambda s,token: ("call",  to_label(re.sub(r'^201','',token)))),
    (r"202%s" % rlabel, lambda s,token: ("jump",  to_label(re.sub(r'^202','',token)))),
    (r"210%s" % rlabel, lambda s,token: ("jump_zero", to_label(re.sub(r'^210','',token)))),
    (r"211%s" % rlabel, lambda s,token: ("jump_negative", to_label(re.sub(r'^211','',token)))),
    (r"212",            lambda s,token: ("return",)),
    (r"222",            lambda s,token: ("exit",)),
    (r"1200",           lambda s,token: ("char_out",)),
    (r"1201",           lambda s,token: ("num_out",)),
    (r"1210",           lambda s,token: ("char_in",)),
    (r"1211",           lambda s,token: ("num_in",))
    ])

def to_num(str):
    n = int(str[1:-1],2)
    if str[0] == '0': return n
    elif str[0] == '1': return -n
    else: raise TypeError('Not a Integer')

def to_label(str): return str[:-1]

### Parser

def parse_image(file):
    "pixelのrgpの合計のmod3をつなげた文字列を返す"
    modstr = ""
    im = Image.open(file)
    height,width = im.size
    for h in range(height):
        for w in range(width):
            r,g,b = im.getpixel((h,w))
            modstr += str((r+g+b)%3)
    return modstr

def extract_code(str):
    """10個以上の210の並びと10個以上の210の並びに挟まれた領域がコード領域"""
    return re.search(r'(210){10,}([012]+?)(210){10,}').group(2)

if __name__ == '__main__':

#     print "Hello World\n================="
#     t = [('push',10),('push',100),('push',108),('push',114),('push',111),('push',87),('push',32),
#          ('push',111),('push',108),('push',108),('push',101),('push',72),('char_out',),('char_out',),
#          ('char_out',),('char_out',),('char_out',),('char_out',),('char_out',),('char_out',),
#          ('char_out',),('char_out',),('char_out',),('char_out',),('exit',),]
#     vm = VM(t)
#     vm.run()

     print "token check\n================"
     tokens, remainder = scanner.scan("0001000012000110010020001101100200011100102000110111120001010111200010000020001101111200011011002000110110020001100101200010010002120012001200120012001200120012001200120012001200222")

     print tokens

     print "token -> vm\n================"
     vm2 = VM(tokens)

ProductName Rubyで作る奇妙なプログラミング言語 ~Esoteric Language~
原 悠
毎日コミュニケーションズ / ?円 ( 2008-12-20 )


About

  • もう5年目(wishlistありマス♡)
  • 最近はPythonとDeepLearning
  • 日本酒自粛中
  • ドラムンベースからミニマルまで
  • ポケモンGOゆるめ

Tag

Python Deep Learning javascript chemoinformatics Emacs sake and more...

Ad

© kzfm 2003-2021