Doc editing

This commit is contained in:
Maggie Mari 2012-08-20 17:52:00 -05:00
commit e7cbaea1e8

View file

@ -933,171 +933,183 @@ Abstract Syntax Tree (aka Parse Tree)
self.left = left self.left = left
self.right = right self.right = right
def CodeGen(self): left = self.left.CodeGen() def CodeGen(self):
right = self.right.CodeGen() left = self.left.CodeGen()
right = self.right.CodeGen()
if self.operator == '+': if self.operator == '+':
return g_llvm_builder.fadd(left, right, 'addtmp') return g_llvm_builder.fadd(left, right, 'addtmp')
elif self.operator == '-': elif self.operator == '-':
return g_llvm_builder.fsub(left, right, 'subtmp') return g_llvm_builder.fsub(left, right, 'subtmp')
elif self.operator == '*': elif self.operator == '*':
return g_llvm_builder.fmul(left, right, 'multmp') return g_llvm_builder.fmul(left, right, 'multmp')
elif self.operator == '<': elif self.operator == '<':
result = g_llvm_builder.fcmp(FCMP_ULT, left, right, 'cmptmp') result = g_llvm_builder.fcmp(FCMP_ULT, left, right, 'cmptmp')
# Convert bool 0 or 1 to double 0.0 or 1.0. # Convert bool 0 or 1 to double 0.0 or 1.0.
return g_llvm_builder.uitofp(result, Type.double(), 'booltmp') return g_llvm_builder.uitofp(result, Type.double(), 'booltmp')
else: else:
function = g_llvm_module.get_function_named('binary' + self.operator) function = g_llvm_module.get_function_named('binary' + self.operator)
return g_llvm_builder.call(function, [left, right], 'binop') return g_llvm_builder.call(function, [left, right], 'binop')
# Expression class for function calls. # Expression class for function calls.
class CallExpressionNode(ExpressionNode): class CallExpressionNode(ExpressionNode):
def __init__(self, callee, args): self.callee = callee self.args = def __init__(self, callee, args):
args self.callee = callee
self.args = args
def CodeGen(self): # Look up the name in the global module table. callee def CodeGen(self):
= g_llvm_module.get_function_named(self.callee) # Look up the name in the global module table.
callee = g_llvm_module.get_function_named(self.callee)
:: # Check for argument mismatch error.
if len(callee.args) != len(self.args):
raise RuntimeError('Incorrect number of arguments passed.')
# Check for argument mismatch error. arg_values = [i.CodeGen() for i in self.args]
if len(callee.args) != len(self.args):
raise RuntimeError('Incorrect number of arguments passed.')
arg_values = [i.CodeGen() for i in self.args] return g_llvm_builder.call(callee, arg_values, 'calltmp')
return g_llvm_builder.call(callee, arg_values, 'calltmp')
# Expression class for if/then/else. # Expression class for if/then/else.
class IfExpressionNode(ExpressionNode): class IfExpressionNode(ExpressionNode):
def __init__(self, condition, then_branch, else_branch): def __init__(self, condition, then_branch, else_branch):
self.condition = condition self.then_branch = then_branch self.condition = condition
self.else_branch = else_branch self.then_branch = then_branch
self.else_branch = else_branch
def CodeGen(self): condition = self.condition.CodeGen() def CodeGen(self): condition = self.condition.CodeGen()
:: # Convert condition to a bool by comparing equal to 0.0.
condition_bool = g_llvm_builder.fcmp(
FCMP_ONE, condition, Constant.real(Type.double(), 0), 'ifcond')
# Convert condition to a bool by comparing equal to 0.0. function = g_llvm_builder.basic_block.function
condition_bool = g_llvm_builder.fcmp(
FCMP_ONE, condition, Constant.real(Type.double(), 0), 'ifcond')
function = g_llvm_builder.basic_block.function # Create blocks for the then and else cases. Insert the 'then' block at the
# end of the function.
then_block = function.append_basic_block('then')
else_block = function.append_basic_block('else')
merge_block = function.append_basic_block('ifcond')
# Create blocks for the then and else cases. Insert the 'then' block at the g_llvm_builder.cbranch(condition_bool, then_block, else_block)
# end of the function.
then_block = function.append_basic_block('then')
else_block = function.append_basic_block('else')
merge_block = function.append_basic_block('ifcond')
g_llvm_builder.cbranch(condition_bool, then_block, else_block) # Emit then value.
g_llvm_builder.position_at_end(then_block)
then_value = self.then_branch.CodeGen()
g_llvm_builder.branch(merge_block)
# Emit then value. # Codegen of 'Then' can change the current block; update then_block for the
g_llvm_builder.position_at_end(then_block) # PHI node.
then_value = self.then_branch.CodeGen() then_block = g_llvm_builder.basic_block
g_llvm_builder.branch(merge_block)
# Codegen of 'Then' can change the current block; update then_block for the # Emit else block.
# PHI node. g_llvm_builder.position_at_end(else_block)
then_block = g_llvm_builder.basic_block else_value = self.else_branch.CodeGen()
g_llvm_builder.branch(merge_block)
# Emit else block. # Codegen of 'Else' can change the current block, update else_block for the
g_llvm_builder.position_at_end(else_block) # PHI node.
else_value = self.else_branch.CodeGen() else_block = g_llvm_builder.basic_block
g_llvm_builder.branch(merge_block)
# Codegen of 'Else' can change the current block, update else_block for the # Emit merge block.
# PHI node. g_llvm_builder.position_at_end(merge_block)
else_block = g_llvm_builder.basic_block phi = g_llvm_builder.phi(Type.double(), 'iftmp')
phi.add_incoming(then_value, then_block)
phi.add_incoming(else_value, else_block)
# Emit merge block. return phi
g_llvm_builder.position_at_end(merge_block)
phi = g_llvm_builder.phi(Type.double(), 'iftmp')
phi.add_incoming(then_value, then_block)
phi.add_incoming(else_value, else_block)
return phi
# Expression class for for/in. # Expression class for for/in.
class ForExpressionNode(ExpressionNode): class ForExpressionNode(ExpressionNode):
def __init__(self, loop_variable, start, end, step, body): def __init__(self, loop_variable, start, end, step, body):
self.loop_variable = loop_variable self.start = start self.end = end self.loop_variable = loop_variable
self.step = step self.body = body self.start = start
self.end = end
self.step = step
self.body = body
def CodeGen(self): # Output this as: # ... # start = startexpr # goto def CodeGen(self):
loop # loop: # variable = phi [start, loopheader], [nextvariable, # Output this as:
loopend] # ... # bodyexpr # ... # loopend: # step = stepexpr # # ...
nextvariable = variable + step # endcond = endexpr # br endcond, loop, # start = startexpr
endloop # outloop: # goto loop
# loop:
# variable = phi [start, loopheader], [nextvariable, loopend]
# ...
# bodyexpr
# ...
# loopend:
# step = stepexpr
# nextvariable = variable + step
# endcond = endexpr
# br endcond, loop, endloop
# outloop:
:: # Emit the start code first, without 'variable' in scope.
start_value = self.start.CodeGen()
# Emit the start code first, without 'variable' in scope. # Make the new basic block for the loop header, inserting after current
start_value = self.start.CodeGen() # block.
function = g_llvm_builder.basic_block.function
pre_header_block = g_llvm_builder.basic_block
loop_block = function.append_basic_block('loop')
# Make the new basic block for the loop header, inserting after current # Insert an explicit fallthrough from the current block to the loop_block.
# block. g_llvm_builder.branch(loop_block)
function = g_llvm_builder.basic_block.function
pre_header_block = g_llvm_builder.basic_block
loop_block = function.append_basic_block('loop')
# Insert an explicit fallthrough from the current block to the loop_block. # Start insertion in loop_block.
g_llvm_builder.branch(loop_block) g_llvm_builder.position_at_end(loop_block)
# Start insertion in loop_block. # Start the PHI node with an entry for start.
g_llvm_builder.position_at_end(loop_block) variable_phi = g_llvm_builder.phi(Type.double(), self.loop_variable)
variable_phi.add_incoming(start_value, pre_header_block)
# Start the PHI node with an entry for start. # Within the loop, the variable is defined equal to the PHI node. If it
variable_phi = g_llvm_builder.phi(Type.double(), self.loop_variable) # shadows an existing variable, we have to restore it, so save it now.
variable_phi.add_incoming(start_value, pre_header_block) old_value = g_named_values.get(self.loop_variable, None)
g_named_values[self.loop_variable] = variable_phi
# Within the loop, the variable is defined equal to the PHI node. If it # Emit the body of the loop. This, like any other expr, can change the
# shadows an existing variable, we have to restore it, so save it now. # current BB. Note that we ignore the value computed by the body.
old_value = g_named_values.get(self.loop_variable, None) self.body.CodeGen()
g_named_values[self.loop_variable] = variable_phi
# Emit the body of the loop. This, like any other expr, can change the # Emit the step value.
# current BB. Note that we ignore the value computed by the body. if self.step:
self.body.CodeGen() step_value = self.step.CodeGen()
else:
# If not specified, use 1.0.
step_value = Constant.real(Type.double(), 1)
# Emit the step value. next_value = g_llvm_builder.fadd(variable_phi, step_value, 'next')
if self.step:
step_value = self.step.CodeGen()
else:
# If not specified, use 1.0.
step_value = Constant.real(Type.double(), 1)
next_value = g_llvm_builder.fadd(variable_phi, step_value, 'next') # Compute the end condition and convert it to a bool by comparing to 0.0.
end_condition = self.end.CodeGen()
end_condition_bool = g_llvm_builder.fcmp(
FCMP_ONE, end_condition, Constant.real(Type.double(), 0), 'loopcond')
# Compute the end condition and convert it to a bool by comparing to 0.0. # Create the "after loop" block and insert it.
end_condition = self.end.CodeGen() loop_end_block = g_llvm_builder.basic_block
end_condition_bool = g_llvm_builder.fcmp( after_block = function.append_basic_block('afterloop')
FCMP_ONE, end_condition, Constant.real(Type.double(), 0), 'loopcond')
# Create the "after loop" block and insert it. # Insert the conditional branch into the end of loop_end_block.
loop_end_block = g_llvm_builder.basic_block g_llvm_builder.cbranch(end_condition_bool, loop_block, after_block)
after_block = function.append_basic_block('afterloop')
# Insert the conditional branch into the end of loop_end_block. # Any new code will be inserted in after_block.
g_llvm_builder.cbranch(end_condition_bool, loop_block, after_block) g_llvm_builder.position_at_end(after_block)
# Any new code will be inserted in after_block. # Add a new entry to the PHI node for the backedge.
g_llvm_builder.position_at_end(after_block) variable_phi.add_incoming(next_value, loop_end_block)
# Add a new entry to the PHI node for the backedge. # Restore the unshadowed variable.
variable_phi.add_incoming(next_value, loop_end_block) if old_value:
g_named_values[self.loop_variable] = old_value
else:
del g_named_values[self.loop_variable]
# Restore the unshadowed variable. # for expr always returns 0.0.
if old_value: return Constant.real(Type.double(), 0)
g_named_values[self.loop_variable] = old_value
else:
del g_named_values[self.loop_variable]
# for expr always returns 0.0.
return Constant.real(Type.double(), 0)
# Expression class for a unary operator. # Expression class for a unary operator.
class UnaryExpressionNode(ExpressionNode): class UnaryExpressionNode(ExpressionNode):