Upgrade to Pro — share decks privately, control downloads, hide ads and more …

我々はどうやって言語を作り 彼らはどうやって言語を紡いでいったか 第一章

mackee
April 12, 2014
70

我々はどうやって言語を作り 彼らはどうやって言語を紡いでいったか 第一章

mackee

April 12, 2014
Tweet

More Decks by mackee

Transcript

  1. hippyvm ΊͬͪΌ͸΍͍PHP HippyVM on average is 7.3x faster than stock

    PHP and 2x faster than Facebook's HHVM. Please check our benchmarks. ཁ໿͢ΔͱΊͬͪΌ͸΍͍
  2. main.py͔ΒΑΊ͹Α͍ def main(filename, rest_of_args, cgi, gcdump, debugger_pipes=(-1, -1)): try: f

    = open(filename) data = f.read() f.close() except: print "Error opening %s" % filename return 2 # space = getspace() interp = Interpreter(space) IJQQZNBJOQZ
  3. main.py͔ΒΑΊ͹Α͍ try: ini_data = open('hippy.ini').read() except (OSError, IOError): ini_data =

    None if ini_data is not None: try: load_ini(interp, ini_data) except: os.write(2, "error reading `hippy.ini`") interp.setup(cgi, argv=[filename] + rest_of_args) absname = os.path.abspath(filename) bc = interp.compile_bytecode(absname, data) IJQQZNBJOQZ
  4. interp͕͍Ζ͍Ζ΍͍ͬͯΔ def setup(self, cgi=False, argv=None): if self._setup: return space =

    self.space get, post = None, None if cgi: from hippy.cgisupport import setup_cgi self.web_config = setup_cgi(self, argv) self.cgi = True self.error_level = space.int_w(self.config.get_ini_w( 'error_reporting')) self._setup = True self.setup_globals(space, argv) IJQQZJOUFSQSFUFSQZ
  5. interp͕͍Ζ͍Ζ΍͍ͬͯΔ def compile_bytecode(self, filename, source): try: return compile_php(filename, source, self.space,

    self) except (ParseError, LexerError) as exc: msg = "%s in %s on line %s" % (exc.message, filename, exc.source_pos) self.log_error(constants.E_PARSE, msg) return None except CompilerError as exc: msg = "%s in %s on line %s" % (exc.msg, exc.filename, exc.lineno) self.log_error(constants.E_ERROR, msg) return None IJQQZJOUFSQSFUFSQZ
  6. compile_php ! def compile_php(filename, source, space, interp=None): phplexerwrapper = PHPLexerWrapper(source,

    filename, interp) if DEBUG: lst = [] while True: tok = phplexerwrapper.next() if tok is None: break else: lst.append(tok) print [x.__dict__ for x in lst] phplexerwrapper = iter(lst + [None]) parser = SourceParser(space, None, filename=filename) tokens = parser.parser.parse(phplexerwrapper, state=parser) bc = compile_ast(filename, source, tokens, space) return bc IJQQZQIQDPNQJMFSQZ
  7. parse͚ͩΕͲlexer΋΍ͬͯΔ class LexerWrapper(BaseLexer): def __init__(self, lexer): self.lexer = lexer !

    def next(self): while True: tok = self.lexer.token() if tok is None or tok.name not in ('H_NEW_LINE', 'H_WHITESPACE', 'T_COMMENT', 'H_TABULATURE'): return tok IJQQZTPVSDFQBSTFSQZ
  8. τʔΧφΠζʙ def token(self): # தུ if self.pos >= self.heredoc_finish and

    self.heredoc_finish != -1: start = self.pos end = self.pos + self.heredoc_lgt assert start >= 0 assert end >= 0 tok = Token('T_END_HEREDOC', self.buf[start:end], self.lineno) self.pos = self.heredoc_finish + self.heredoc_lgt self.heredoc_finish = -1 self.heredoc_lgt = 0 self.context_stack.pop() return tok IJQQZMFYFSQZ
  9. τʔΧφΠζʙ for token_regex, token_type in rules: pos = self.pos assert

    pos >= 0 m = self.match(token_regex, tmp_buf, pos) if m: start, end = self._getstartend(m) value = self.buf[start:end] if token_type == 'H_NEW_LINE': self.lineno += 1 elif token_type == 'T_COMMENT': self.lineno += value.count('\n') elif token_type == 'T_CONSTANT_ENCAPSED_STRING': self.lineno += value.count("\n") # tokens changing the context tok = Token(token_type, value, self.lineno) tok = self.maybe_change_context(ctx, tok, token_type, end) self.last_token = token_type IJQQZMFYFSQZ
  10. RULES += [ ("b?\<\<\<.*?\n", 'T_START_HEREDOC'), ("\x00", 'T_END_HEREDOC'), # generated artificially

    ("\x00", 'T_ENCAPSED_AND_WHITESPACE'), # generated artificially ("\x00", 'T_IGNORE_THIS_TOKEN'), # generated artificially ! (r'b?"([^"\\]|\\.)*"|' + r"b?'([^'\\]|\\.)*'", 'T_CONSTANT_ENCAPSED_STRING'), ! ("[a-zA-Z_][a-zA-Z_0-9]*", 'T_STRING'), ! ("\?\>", 'B_END_OF_CODE_BLOCK'), ("\x00", 'B_LITERAL_BLOCK'), ! ("\+\=", 'T_PLUS_EQUAL'), ("\-\=", 'T_MINUS_EQUAL'), ("\*\=", 'T_MUL_EQUAL'), ("\/\=", 'T_DIV_EQUAL'), ("\.\=", 'T_CONCAT_EQUAL'), ("\%\=", 'T_MOD_EQUAL'), ("\&\=", 'T_AND_EQUAL'), ("\|\=", 'T_OR_EQUAL'),