Fixed some of the code spacing for docs
This commit is contained in:
parent
538fd76b1f
commit
c25b4853fc
1 changed files with 80 additions and 82 deletions
|
|
@ -35,18 +35,23 @@ First we define code generation methods in each AST node class:
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
# Expression class for numeric literals like
|
# Expression class for numeric literals like
|
||||||
"1.0". class NumberExpressionNode(ExpressionNode):
|
"1.0".
|
||||||
|
class NumberExpressionNode(ExpressionNode):
|
||||||
|
|
||||||
def __init__(self, value): self.value = value
|
def __init__(self, value):
|
||||||
|
self.value = value
|
||||||
|
|
||||||
def CodeGen(self): ...
|
def CodeGen(self):
|
||||||
|
...
|
||||||
|
|
||||||
# Expression class for referencing a variable, like "a".
|
# Expression class for referencing a variable, like "a".
|
||||||
class VariableExpressionNode(ExpressionNode):
|
class VariableExpressionNode(ExpressionNode):
|
||||||
|
|
||||||
def __init__(self, name): self.name = name
|
def __init__(self, name):
|
||||||
|
self.name = name
|
||||||
|
|
||||||
def CodeGen(self): ...
|
def CodeGen(self):
|
||||||
|
...
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
@ -117,8 +122,8 @@ First we'll do numeric literals:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
def CodeGen(self): return
|
def CodeGen(self):
|
||||||
Constant.real(Type.double(), self.value)
|
return Constant.real(Type.double(), self.value)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -133,9 +138,11 @@ one directly.
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
def CodeGen(self): if self.name in
|
def CodeGen(self):
|
||||||
g_named_values: return g_named_values[self.name] else: raise
|
if self.name in g_named_values:
|
||||||
RuntimeError('Unknown variable name: ' + self.name)
|
return g_named_values[self.name]
|
||||||
|
else:
|
||||||
|
raise RuntimeError('Unknown variable name: ' + self.name)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -152,23 +159,22 @@ and for `local variables <PythonLangImpl7.html#localvars>`_.
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
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 == '+':
|
||||||
|
return g_llvm_builder.fadd(left, right, 'addtmp')
|
||||||
if self.operator == '+':
|
elif self.operator == '-':
|
||||||
return g_llvm_builder.fadd(left, right, 'addtmp')
|
return g_llvm_builder.fsub(left, right, 'subtmp')
|
||||||
elif self.operator == '-':
|
elif self.operator == '*':
|
||||||
return g_llvm_builder.fsub(left, right, 'subtmp')
|
return g_llvm_builder.fmul(left, right, 'multmp')
|
||||||
elif self.operator == '*':
|
elif self.operator == '<':
|
||||||
return g_llvm_builder.fmul(left, right, 'multmp')
|
result = g_llvm_builder.fcmp(FCMP_ULT, left, right, 'cmptmp')
|
||||||
elif self.operator == '<':
|
# Convert bool 0 or 1 to double 0.0 or 1.0.
|
||||||
result = g_llvm_builder.fcmp(FCMP_ULT, left, right, 'cmptmp')
|
return g_llvm_builder.uitofp(result, Type.double(), 'booltmp')
|
||||||
# Convert bool 0 or 1 to double 0.0 or 1.0.
|
else:
|
||||||
return g_llvm_builder.uitofp(result, Type.double(), 'booltmp')
|
raise RuntimeError('Unknown binary operator.')
|
||||||
else:
|
|
||||||
raise RuntimeError('Unknown binary operator.')
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -213,19 +219,17 @@ the input value.
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
def CodeGen(self): # Look up the name in the
|
def CodeGen(self):
|
||||||
global module table. callee =
|
# Look up the name in the global module table.
|
||||||
g_llvm_module.get_function_named(self.callee)
|
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')
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -267,13 +271,12 @@ with:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
def CodeGen(self): # Make the function type, eg.
|
def CodeGen(self):
|
||||||
double(double,double). funct_type = Type.function( Type.double(),
|
# Make the function type, eg.
|
||||||
[Type.double()] \* len(self.args), False)
|
double(double,double). funct_type = Type.function(
|
||||||
|
Type.double(), [Type.double()] \* len(self.args), False)
|
||||||
|
|
||||||
::
|
function = Function.new(g_llvm_module, funct_type, self.name)
|
||||||
|
|
||||||
function = Function.new(g_llvm_module, funct_type, self.name)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -303,10 +306,10 @@ the function call code above.
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
# If the name conflicted, there was already
|
# If the name conflicted, there was already
|
||||||
something with the same name. # If it has a body, don't allow
|
something with the same name. # If it has a body, don't allow redefinition or reextern.
|
||||||
redefinition or reextern. if function.name != self.name:
|
if function.name != self.name:
|
||||||
function.delete() function =
|
function.delete()
|
||||||
g_llvm_module.get_function_named(self.name)
|
function = g_llvm_module.get_function_named(self.name)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -333,16 +336,14 @@ name.
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
# If the function already has a body, reject
|
# If the function already has a body, reject this.
|
||||||
this. if not function.is_declaration: raise RuntimeError('Redefinition
|
if not function.is_declaration:
|
||||||
of function.')
|
raise RuntimeError('Redefinition of function.')
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
# If F took a different number of args, reject.
|
# If F took a different number of args, reject.
|
||||||
if len(callee.args) != len(self.args):
|
if len(callee.args) != len(self.args):
|
||||||
raise RuntimeError('Redeclaration of a function with different number '
|
raise RuntimeError('Redeclaration of a function with different number '
|
||||||
'of args.')
|
'of args.')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -358,12 +359,11 @@ match up. If not, we emit an error.
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
# Set names for all arguments and add them to the
|
# Set names for all arguments and add them to the variables symbol table.
|
||||||
variables symbol table. for arg, arg_name in zip(function.args,
|
for arg, arg_name in zip(function.args, self.args):
|
||||||
self.args): arg.name = arg_name # Add arguments to variable symbol
|
arg.name = arg_name
|
||||||
table. g_named_values[arg_name] = arg
|
# Add arguments to variable symbol
|
||||||
|
table. g_named_values[arg_name] = arg
|
||||||
::
|
|
||||||
|
|
||||||
return function
|
return function
|
||||||
|
|
||||||
|
|
@ -383,13 +383,12 @@ caller.
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
def CodeGen(self): # Clear scope.
|
def CodeGen(self):
|
||||||
g_named_values.clear()
|
# Clear scope.
|
||||||
|
g_named_values.clear()
|
||||||
|
|
||||||
::
|
# Create a function object.
|
||||||
|
function = self.prototype.CodeGen()
|
||||||
# Create a function object.
|
|
||||||
function = self.prototype.CodeGen()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -404,10 +403,9 @@ LLVM Function object that is ready to go for us.
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
# Create a new basic block to start insertion
|
# Create a new basic block to start insertion into.
|
||||||
into. block = function.append_basic_block('entry') global
|
block = function.append_basic_block('entry')
|
||||||
g_llvm_builder g_llvm_builder = Builder.new(block) {% endhighlight
|
global g_llvm_builder g_llvm_builder = Builder.new(block) {% endhighlight %}
|
||||||
%}
|
|
||||||
|
|
||||||
Now we get to the point where ``g_llvm_builder`` is set up. The first
|
Now we get to the point where ``g_llvm_builder`` is set up. The first
|
||||||
line creates a new `basic
|
line creates a new `basic
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue