Finished editing PythonLangImpl5.rst

This commit is contained in:
Maggie Mari 2012-08-19 13:17:33 -05:00
commit cb7b778bfd

View file

@ -1257,7 +1257,8 @@ Parser
def __init__(self, tokens, binop_precedence): def __init__(self, tokens, binop_precedence):
self.tokens = tokens self.tokens = tokens
self.binop_precedence = binop_precedence self.Next() self.binop_precedence = binop_precedence
self.Next()
# Provide a simple token buffer. Parser.current is the current token the # Provide a simple token buffer. Parser.current is the current token the
# parser is looking at. Parser.Next() reads another token from the lexer and # parser is looking at. Parser.Next() reads another token from the lexer and
@ -1375,20 +1376,26 @@ Parser
return ForExpressionNode(loop_variable, start, end, step, body) return ForExpressionNode(loop_variable, start, end, step, body)
# primary ::= identifierexpr | numberexpr | parenexpr | ifexpr | # primary ::= identifierexpr | numberexpr | parenexpr | ifexpr | forexpr
forexpr def ParsePrimary(self): if isinstance(self.current, def ParsePrimary(self):
IdentifierToken): return self.ParseIdentifierExpr() elif if isinstance(self.current, IdentifierToken):
isinstance(self.current, NumberToken): return self.ParseNumberExpr() return self.ParseIdentifierExpr()
elif isinstance(self.current, IfToken): return self.ParseIfExpr() elif elif isinstance(self.current, NumberToken):
isinstance(self.current, ForToken): return self.ParseForExpr() elif return self.ParseNumberExpr()
self.current == CharacterToken('('): return self.ParseParenExpr() else: elif isinstance(self.current, IfToken):
return self.ParseIfExpr()
elif isinstance(self.current, ForToken):
return self.ParseForExpr()
elif self.current == CharacterToken('('):
return self.ParseParenExpr()
else:
raise RuntimeError('Unknown token when expecting an expression.') raise RuntimeError('Unknown token when expecting an expression.')
# binoprhs ::= (operator primary)* def ParseBinOpRHS(self, left, # binoprhs ::= (operator primary)*
left_precedence): # If this is a binary operator, find its precedence. def ParseBinOpRHS(self, left, left_precedence):
while True: precedence = self.GetCurrentTokenPrecedence() # If this is a binary operator, find its precedence.
while True:
:: precedence = self.GetCurrentTokenPrecedence()
# If this is a binary operator that binds at least as tightly as the # If this is a binary operator that binds at least as tightly as the
# current one, consume it; otherwise we are done. # current one, consume it; otherwise we are done.
@ -1410,14 +1417,15 @@ Parser
# Merge left/right. # Merge left/right.
left = BinaryOperatorExpressionNode(binary_operator, left, right) left = BinaryOperatorExpressionNode(binary_operator, left, right)
# expression ::= primary binoprhs def ParseExpression(self): left = # expression ::= primary binoprhs
self.ParsePrimary() return self.ParseBinOpRHS(left, 0) def ParseExpression(self):
left = self.ParsePrimary()
return self.ParseBinOpRHS(left, 0)
# prototype ::= id '(' id* ')' def ParsePrototype(self): if not # prototype ::= id '(' id* ')'
isinstance(self.current, IdentifierToken): raise RuntimeError('Expected def ParsePrototype(self):
function name in prototype.') if not isinstance(self.current, IdentifierToken):
raise RuntimeError('Expected function name in prototype.')
::
function_name = self.current.name function_name = self.current.name
self.Next() # eat function name. self.Next() # eat function name.
@ -1439,54 +1447,88 @@ Parser
return PrototypeNode(function_name, arg_names) return PrototypeNode(function_name, arg_names)
# definition ::= 'def' prototype expression def ParseDefinition(self): # definition ::= 'def' prototype expression
self.Next() # eat def. proto = self.ParsePrototype() body = def ParseDefinition(self):
self.ParseExpression() return FunctionNode(proto, body) self.Next() # eat def.
proto = self.ParsePrototype()
body = self.ParseExpression()
return FunctionNode(proto, body)
# toplevelexpr ::= expression def ParseTopLevelExpr(self): proto = # toplevelexpr ::= expression
PrototypeNode('', []) return FunctionNode(proto, self.ParseExpression()) def ParseTopLevelExpr(self):
proto = PrototypeNode('', [])
return FunctionNode(proto, self.ParseExpression())
# external ::= 'extern' prototype def ParseExtern(self): self.Next() # # external ::= 'extern' prototype
eat extern. return self.ParsePrototype() def ParseExtern(self):
self.Next() # eat extern.
return self.ParsePrototype()
# Top-Level parsing def HandleDefinition(self): # Top-Level parsing
def HandleDefinition(self):
self.Handle(self.ParseDefinition, 'Read a function definition:') self.Handle(self.ParseDefinition, 'Read a function definition:')
def HandleExtern(self): self.Handle(self.ParseExtern, 'Read an extern:') def HandleExtern(self):
self.Handle(self.ParseExtern, 'Read an extern:')
def HandleTopLevelExpression(self): try: function = def HandleTopLevelExpression(self):
self.ParseTopLevelExpr().CodeGen() result = try:
g_llvm_executor.run_function(function, []) print 'Evaluated to:', function = self.ParseTopLevelExpr().CodeGen()
result.as_real(Type.double()) except Exception, e: print 'Error:', e result = g_llvm_executor.run_function(function, [])
try: self.Next() # Skip for error recovery. except: pass print 'Evaluated to:', result.as_real(Type.double())
except Exception, e:
print 'Error:', e
try:
self.Next() # Skip for error recovery.
except:
pass
def Handle(self, function, message): try: print message, def Handle(self, function, message):
function().CodeGen() except Exception, e: print 'Error:', e try: try:
self.Next() # Skip for error recovery. except: pass print message, function().CodeGen()
except Exception, e:
print 'Error:', e
try:
self.Next() # Skip for error recovery.
except:
pass
Main driver code. Main driver code.
----------------- -----------------
def main(): # Set up the optimizer pipeline. Start with registering info .. code-block:: python
about how the # target lays out data structures.
g_llvm_pass_manager.add(g_llvm_executor.target_data) # Do simple def main():
"peephole" optimizations and bit-twiddling optzns. # Set up the optimizer pipeline. Start with registering info about how the
g_llvm_pass_manager.add(PASS_INSTRUCTION_COMBINING) # Reassociate # target lays out data structures.
expressions. g_llvm_pass_manager.add(PASS_REASSOCIATE) # Eliminate g_llvm_pass_manager.add(g_llvm_executor.target_data)
Common SubExpressions. g_llvm_pass_manager.add(PASS_GVN) # Simplify # Do simple "peephole" optimizations and bit-twiddling optzns.
the control flow graph (deleting unreachable blocks, etc). g_llvm_pass_manager.add(PASS_INSTRUCTION_COMBINING)
# Reassociate expressions.
g_llvm_pass_manager.add(PASS_REASSOCIATE)
# Eliminate Common SubExpressions.
g_llvm_pass_manager.add(PASS_GVN)
# Simplify the control flow graph (deleting unreachable blocks, etc).
g_llvm_pass_manager.add(PASS_CFG_SIMPLIFICATION) g_llvm_pass_manager.add(PASS_CFG_SIMPLIFICATION)
g_llvm_pass_manager.initialize() g_llvm_pass_manager.initialize()
# Install standard binary operators. # 1 is lowest possible precedence. # Install standard binary operators.
40 is the highest. operator_precedence = { '<': 10, '+': 20, '-': 20, # 1 is lowest possible precedence. 40 is the highest.
'*': 40 } operator_precedence = {
'<': 10,
'+': 20,
'-': 20,
'*': 40
}
# Run the main "interpreter loop". while True: print 'ready>', try: raw # Run the main "interpreter loop".
= raw_input() except KeyboardInterrupt: break while True:
print 'ready>',
:: try:
raw = raw_input()
except KeyboardInterrupt:
break
parser = Parser(Tokenize(raw), operator_precedence) parser = Parser(Tokenize(raw), operator_precedence)
while True: while True:
@ -1502,4 +1544,5 @@ Parser
# Print out all of the generated code. print '', g_llvm_module # Print out all of the generated code. print '', g_llvm_module
if **name** == '__main__': main() if __name__ == '__main__':
main()