Line 1... |
Line 1... |
__author__ = "Jon Dawson"
|
__author__ = "Jon Dawson"
|
__copyright__ = "Copyright (C) 2012, Jonathan P Dawson"
|
__copyright__ = "Copyright (C) 2012, Jonathan P Dawson"
|
__version__ = "0.1"
|
__version__ = "0.1"
|
|
|
|
import struct
|
|
|
class NotConstant(Exception):
|
class NotConstant(Exception):
|
pass
|
pass
|
|
|
def value(expression):
|
|
|
|
"""If an expression can be evaluated at compile time, return the value"""
|
|
|
|
if hasattr(expression, "value"):
|
|
return truncate(expression.value())
|
|
else:
|
|
raise NotConstant
|
|
|
|
def constant_fold(expression):
|
def constant_fold(expression):
|
|
|
"""Replace an expression with a constant if possible"""
|
"""Replace an expression with a constant if possible"""
|
|
|
try:
|
try:
|
return Constant(value(expression))
|
return Constant(expression.value(), expression.type_(), expression.size(), expression.signed())
|
except NotConstant:
|
except NotConstant:
|
return expression
|
return expression
|
|
|
def truncate(number):
|
|
|
|
"""Truncate arithmetic results to the target number of bits"""
|
|
|
|
#sign = number & 0x10000
|
|
#number = number & 0xffff
|
|
#if sign:
|
|
#number = ~0xffff | number
|
|
return int(number)
|
|
|
|
class Process:
|
class Process:
|
|
|
def generate(self):
|
def generate(self):
|
instructions = []
|
instructions = []
|
for function in self.functions:
|
for function in self.functions:
|
if hasattr(function, "declarations"):
|
if hasattr(function, "declarations"):
|
instructions.extend(function.generate())
|
instructions.extend(function.generate())
|
instructions.append({"op" :"jmp_and_link",
|
|
|
instructions.append(
|
|
{"op" :"jmp_and_link",
|
"dest" :self.main.return_address,
|
"dest" :self.main.return_address,
|
"label":"function_%s"%id(self.main)})
|
"label":"function_%s"%id(self.main)})
|
instructions.append({"op":"stop"})
|
|
|
instructions.append(
|
|
{"op":"stop"})
|
|
|
for function in self.functions:
|
for function in self.functions:
|
if not hasattr(function, "declarations"):
|
if not hasattr(function, "declarations"):
|
instructions.extend(function.generate())
|
instructions.extend(function.generate())
|
return instructions
|
return instructions
|
|
|
|
|
class Function:
|
class Function:
|
|
|
def generate(self):
|
def generate(self):
|
instructions = []
|
instructions = []
|
instructions.append({"op":"label", "label":"function_%s"%id(self)})
|
instructions.append({"op":"label", "label":"function_%s"%id(self)})
|
instructions.extend(self.statement.generate())
|
instructions.extend(self.statement.generate())
|
if not hasattr(self, "return_value"):
|
if not hasattr(self, "return_value"):
|
instructions.append({"op":"jmp_to_reg", "src":self.return_address})
|
instructions.append({"op":"jmp_to_reg", "src":self.return_address})
|
return instructions
|
return instructions
|
|
|
|
|
class Break:
|
class Break:
|
def generate(self): return [{"op":"goto", "label":"break_%s"%id(self.loop)}]
|
|
|
def generate(self): return [
|
|
{"op":"goto", "label":"break_%s"%id(self.loop)}]
|
|
|
|
|
class Continue:
|
class Continue:
|
def generate(self): return [{"op":"goto", "label":"continue_%s"%id(self.loop)}]
|
|
|
def generate(self): return [
|
|
{"op":"goto", "label":"continue_%s"%id(self.loop)}]
|
|
|
|
|
class Assert:
|
class Assert:
|
|
|
def generate(self):
|
def generate(self):
|
result = self.allocator.new(self.expression.size)
|
result = self.allocator.new(self.expression.size())
|
instructions = self.expression.generate(result)
|
instructions = self.expression.generate(result, self.allocator)
|
self.allocator.free(result)
|
self.allocator.free(result)
|
instructions.append({"op":"assert", "src":result, "line":self.line, "file":self.filename})
|
|
|
instructions.append(
|
|
{"op":"assert",
|
|
"src":result,
|
|
"line":self.line,
|
|
"file":self.filename})
|
|
|
return instructions
|
return instructions
|
|
|
|
|
class Return:
|
class Return:
|
|
|
def generate(self):
|
def generate(self):
|
if hasattr(self, "expression"):
|
if hasattr(self, "expression"):
|
instructions = self.expression.generate(self.function.return_value)
|
|
|
result = self.allocator.new(self.function.size)
|
|
instructions=self.function.return_value.copy(
|
|
self.expression,
|
|
result,
|
|
self.allocator)
|
|
self.allocator.free(result)
|
|
|
else:
|
else:
|
instructions = []
|
instructions = []
|
instructions.append({"op":"jmp_to_reg", "src":self.function.return_address})
|
|
|
instructions.append(
|
|
{"op":"jmp_to_reg",
|
|
"src":self.function.return_address})
|
|
|
return instructions
|
return instructions
|
|
|
|
|
class Report:
|
class Report:
|
|
|
def generate(self):
|
def generate(self):
|
result = self.allocator.new(self.expression.size)
|
result = self.allocator.new(self.expression.size())
|
instructions = self.expression.generate(result)
|
instructions = self.expression.generate(result, self.allocator)
|
self.allocator.free(result)
|
self.allocator.free(result)
|
instructions.append({"op":"report",
|
|
|
instructions.append(
|
|
{"op":"report",
|
"src":result,
|
"src":result,
|
"line":self.line,
|
"line":self.line,
|
"file":self.filename,
|
"file":self.filename,
|
"signed":self.expression.signed})
|
"type":self.expression.type_(),
|
|
"signed":self.expression.signed()})
|
|
|
return instructions
|
return instructions
|
|
|
|
|
class WaitClocks:
|
class WaitClocks:
|
|
|
def generate(self):
|
def generate(self):
|
result = self.allocator.new(self.expression.size)
|
result = self.allocator.new(self.expression.size())
|
instructions = self.expression.generate(result)
|
instructions = self.expression.generate(result, self.allocator)
|
self.allocator.free(result)
|
self.allocator.free(result)
|
instructions.append({"op":"wait_clocks", "src":result})
|
instructions.append({"op":"wait_clocks", "src":result})
|
return instructions
|
return instructions
|
|
|
|
|
class If:
|
class If:
|
|
|
def generate(self):
|
def generate(self):
|
|
|
try:
|
try:
|
if value(self.expression):
|
|
|
if self.expression.value():
|
return self.true_statement.generate()
|
return self.true_statement.generate()
|
else:
|
else:
|
if self.false_statement:
|
if self.false_statement:
|
return self.false_statement.generate()
|
return self.false_statement.generate()
|
else:
|
else:
|
return []
|
return []
|
|
|
except NotConstant:
|
except NotConstant:
|
result = self.allocator.new(self.expression.size)
|
|
|
result = self.allocator.new(self.expression.size())
|
instructions = []
|
instructions = []
|
instructions.extend(self.expression.generate(result))
|
instructions.extend(self.expression.generate(result, self.allocator))
|
instructions.append({"op" :"jmp_if_false",
|
|
|
instructions.append(
|
|
{"op" : "jmp_if_false",
|
"src" :result,
|
"src" :result,
|
"label":"else_%s"%id(self)})
|
"label":"else_%s"%id(self)})
|
|
|
self.allocator.free(result)
|
self.allocator.free(result)
|
instructions.extend(self.true_statement.generate())
|
instructions.extend(self.true_statement.generate())
|
instructions.append({"op":"goto", "label":"end_%s"%id(self)})
|
instructions.append({"op":"goto", "label":"end_%s"%id(self)})
|
instructions.append({"op":"label", "label":"else_%s"%id(self)})
|
instructions.append({"op":"label", "label":"else_%s"%id(self)})
|
if self.false_statement:
|
if self.false_statement:
|
instructions.extend(self.false_statement.generate())
|
instructions.extend(self.false_statement.generate())
|
instructions.append({"op":"label", "label":"end_%s"%id(self)})
|
instructions.append({"op":"label", "label":"end_%s"%id(self)})
|
return instructions
|
return instructions
|
|
|
|
|
class Switch:
|
class Switch:
|
|
|
def generate(self):
|
def generate(self):
|
result = self.allocator.new(self.expression.size)
|
result = self.allocator.new(self.expression.size())
|
test = self.allocator.new(self.expression.size)
|
test = self.allocator.new(self.expression.size())
|
instructions = self.expression.generate(result)
|
instructions = self.expression.generate(result, self.allocator)
|
for value, case in self.cases.iteritems():
|
for value, case in self.cases.iteritems():
|
instructions.append({"op":"==", "dest":test, "src":result, "right":value, "signed":True})
|
|
instructions.append({"op":"jmp_if_true", "src":test, "label":"case_%s"%id(case)})
|
instructions.append(
|
|
{"op":"==",
|
|
"dest":test,
|
|
"src":result,
|
|
"right":value,
|
|
"size": self.expression.size(),
|
|
"signed":True})
|
|
|
|
instructions.append(
|
|
{"op":"jmp_if_true",
|
|
"src":test,
|
|
"label":"case_%s"%id(case)})
|
|
|
if hasattr(self, "default"):
|
if hasattr(self, "default"):
|
instructions.append({"op":"goto", "label":"case_%s"%id(self.default)})
|
|
|
instructions.append(
|
|
{"op":"goto",
|
|
"label":"case_%s"%id(self.default)})
|
|
|
self.allocator.free(result)
|
self.allocator.free(result)
|
self.allocator.free(test)
|
self.allocator.free(test)
|
instructions.extend(self.statement.generate())
|
instructions.extend(self.statement.generate())
|
instructions.append({"op":"label", "label":"break_%s"%id(self)})
|
instructions.append({"op":"label", "label":"break_%s"%id(self)})
|
return instructions
|
return instructions
|
|
|
|
|
class Case:
|
class Case:
|
|
|
def generate(self):
|
def generate(self):
|
return [{"op":"label", "label":"case_%s"%id(self)}]
|
return [{"op":"label", "label":"case_%s"%id(self)}]
|
|
|
|
|
class Default:
|
class Default:
|
|
|
def generate(self):
|
def generate(self):
|
return [{"op":"label", "label":"case_%s"%id(self)}]
|
return [{"op":"label", "label":"case_%s"%id(self)}]
|
|
|
|
|
class Loop:
|
class Loop:
|
|
|
def generate(self):
|
def generate(self):
|
instructions = [{"op":"label", "label":"begin_%s"%id(self)}]
|
instructions = [{"op":"label", "label":"begin_%s"%id(self)}]
|
instructions.append({"op":"label", "label":"continue_%s"%id(self)})
|
instructions.append({"op":"label", "label":"continue_%s"%id(self)})
|
instructions.extend(self.statement.generate())
|
instructions.extend(self.statement.generate())
|
instructions.append({"op":"goto", "label":"begin_%s"%id(self)})
|
instructions.append({"op":"goto", "label":"begin_%s"%id(self)})
|
instructions.append({"op":"label", "label":"break_%s"%id(self)})
|
instructions.append({"op":"label", "label":"break_%s"%id(self)})
|
return instructions
|
return instructions
|
|
|
|
|
class For:
|
class For:
|
|
|
def generate(self):
|
def generate(self):
|
instructions = []
|
instructions = []
|
if hasattr(self, "statement1"):
|
if hasattr(self, "statement1"):
|
instructions.extend(self.statement1.generate())
|
instructions.extend(self.statement1.generate())
|
instructions.append({"op":"label", "label":"begin_%s"%id(self)})
|
instructions.append({"op":"label", "label":"begin_%s"%id(self)})
|
if hasattr(self, "expression"):
|
if hasattr(self, "expression"):
|
result = self.allocator.new(self.expression.size)
|
result = self.allocator.new(self.expression.size())
|
instructions.extend(self.expression.generate(result))
|
|
instructions.append({"op":"jmp_if_false", "src":result, "label":"end_%s"%id(self)})
|
instructions.extend(
|
|
self.expression.generate(result, self.allocator))
|
|
|
|
instructions.append(
|
|
{"op":"jmp_if_false",
|
|
"src":result,
|
|
"label":"end_%s"%id(self)})
|
|
|
self.allocator.free(result)
|
self.allocator.free(result)
|
instructions.extend(self.statement3.generate())
|
instructions.extend(self.statement3.generate())
|
instructions.append({"op":"label", "label":"continue_%s"%id(self)})
|
instructions.append({"op":"label", "label":"continue_%s"%id(self)})
|
if hasattr(self, "statement2"):
|
if hasattr(self, "statement2"):
|
instructions.extend(self.statement2.generate())
|
instructions.extend(self.statement2.generate())
|
instructions.append({"op":"goto", "label":"begin_%s"%id(self)})
|
instructions.append({"op":"goto", "label":"begin_%s"%id(self)})
|
instructions.append({"op":"label", "label":"end_%s"%id(self)})
|
instructions.append({"op":"label", "label":"end_%s"%id(self)})
|
instructions.append({"op":"label", "label":"break_%s"%id(self)})
|
instructions.append({"op":"label", "label":"break_%s"%id(self)})
|
return instructions
|
return instructions
|
|
|
|
|
class Block:
|
class Block:
|
|
|
def generate(self):
|
def generate(self):
|
instructions = []
|
instructions = []
|
for statement in self.statements:
|
for statement in self.statements:
|
instructions.extend(statement.generate())
|
instructions.extend(statement.generate())
|
return instructions
|
return instructions
|
|
|
|
|
class CompoundDeclaration:
|
class CompoundDeclaration:
|
|
|
def __init__(self, declarations):
|
def __init__(self, declarations):
|
self.declarations = declarations
|
self.declarations = declarations
|
|
|
def generate(self):
|
def generate(self):
|
instructions = []
|
instructions = []
|
for declaration in self.declarations:
|
for declaration in self.declarations:
|
instructions.extend(declaration.generate());
|
instructions.extend(declaration.generate());
|
return instructions
|
return instructions
|
|
|
|
|
class VariableDeclaration:
|
class VariableDeclaration:
|
def __init__(self, allocator, initializer, name, type_, size, signed):
|
|
|
def __init__(self, allocator, initializer, name, type_, size, signed, const):
|
self.initializer = initializer
|
self.initializer = initializer
|
self.allocator = allocator
|
self.allocator = allocator
|
self.type_ = type_
|
self._type = type_
|
self.size = size
|
self._size = size
|
self.signed = signed
|
self._signed = signed
|
|
self._const = const
|
self.name = name
|
self.name = name
|
|
|
def instance(self):
|
def instance(self):
|
register = self.allocator.new(self.size, "variable "+self.name)
|
register = self.allocator.new(self.size(), "variable "+self.name)
|
return VariableInstance(register, self.initializer, self.type_, self.size, self.signed)
|
|
|
return VariableInstance(
|
|
register,
|
|
self.initializer,
|
|
self.type_(),
|
|
self.size(),
|
|
self.signed(),
|
|
self.const(),
|
|
self.allocator)
|
|
|
|
def type_(self):
|
|
return self._type
|
|
|
|
def size(self):
|
|
return self._size
|
|
|
|
def signed(self):
|
|
return self._signed
|
|
|
|
def const(self):
|
|
return self._const
|
|
|
|
|
class VariableInstance:
|
class VariableInstance:
|
def __init__(self, register, initializer, type_, size, signed):
|
|
|
def __init__(self, register, initializer, type_, size, signed, const, allocator):
|
self.register = register
|
self.register = register
|
self.type_ = type_
|
self._type = type_
|
self.initializer = initializer
|
self.initializer = initializer
|
self.size = size
|
self._size = size
|
self.signed = signed
|
self._signed = signed
|
|
self._const = const
|
|
self.allocator = allocator
|
|
|
def generate(self):
|
def generate(self):
|
return self.initializer.generate(self.register)
|
return self.initializer.generate(self.register, self.allocator)
|
|
|
|
def reference(self):
|
|
return Variable(self)
|
|
|
|
def type_(self):
|
|
return self._type
|
|
|
|
def size(self):
|
|
return self._size
|
|
|
|
def signed(self):
|
|
return self._signed
|
|
|
|
def const(self):
|
|
return self._const
|
|
|
|
|
class ArrayDeclaration:
|
class ArrayDeclaration:
|
|
|
def __init__(self,
|
def __init__(self,
|
allocator,
|
allocator,
|
size,
|
size,
|
type_,
|
type_,
|
element_type,
|
element_type,
|
Line 228... |
Line 348... |
element_signed,
|
element_signed,
|
initializer = None,
|
initializer = None,
|
initialize_memory = False):
|
initialize_memory = False):
|
|
|
self.allocator = allocator
|
self.allocator = allocator
|
self.type_ = type_
|
self._type = type_
|
self.size = size
|
self._size = size
|
self.signed = False
|
self._signed = False
|
self.element_type = element_type
|
self.element_type = element_type
|
self.element_size = element_size
|
self.element_size = element_size
|
self.element_signed = element_signed
|
self.element_signed = element_signed
|
self.initializer = initializer
|
self.initializer = initializer
|
self.initialize_memory = initialize_memory
|
self.initialize_memory = initialize_memory
|
|
|
def instance(self):
|
def instance(self):
|
location = self.allocator.new_array(self.size, self.initializer, self.element_size)
|
|
|
location = self.allocator.new_array(
|
|
self.size(),
|
|
self.initializer,
|
|
self.element_size)
|
|
|
register = self.allocator.new(2, "array")
|
register = self.allocator.new(2, "array")
|
return ArrayInstance(location,
|
|
|
return ArrayInstance(
|
|
location,
|
register,
|
register,
|
self.size,
|
self.size(),
|
self.type_,
|
self.type_(),
|
self.initializer,
|
self.initializer,
|
self.initialize_memory,
|
self.initialize_memory,
|
self.element_type,
|
self.element_type,
|
self.element_size,
|
self.element_size,
|
self.element_signed)
|
self.element_signed)
|
|
|
|
def type_(self):
|
|
return self._type
|
|
|
|
def size(self):
|
|
return self._size
|
|
|
|
def signed(self):
|
|
return self._signed
|
|
|
class ArrayInstance:
|
class ArrayInstance:
|
|
|
def __init__(self,
|
def __init__(self,
|
location,
|
location,
|
register,
|
register,
|
size,
|
size,
|
type_,
|
type_,
|
Line 264... |
Line 401... |
element_size,
|
element_size,
|
element_signed):
|
element_signed):
|
|
|
self.register = register
|
self.register = register
|
self.location = location
|
self.location = location
|
self.type_ = type_
|
self._type = type_
|
self.size = size
|
self._size = size * element_size
|
self.signed = False
|
self._signed = False
|
self.element_type = element_type
|
self.element_type = element_type
|
self.element_size = element_size
|
self.element_size = element_size
|
self.element_signed = element_signed
|
self.element_signed = element_signed
|
self.initializer = initializer
|
self.initializer = initializer
|
self.initialize_memory = initialize_memory
|
self.initialize_memory = initialize_memory
|
Line 278... |
Line 415... |
def generate(self, result=None):
|
def generate(self, result=None):
|
instructions = []
|
instructions = []
|
#If initialize memory is true, the memory content will initialised (as at configuration time)
|
#If initialize memory is true, the memory content will initialised (as at configuration time)
|
#If initialize memory is false, then the memory will need to be filled by the program.
|
#If initialize memory is false, then the memory will need to be filled by the program.
|
if not self.initialize_memory and self.initializer is not None:
|
if not self.initialize_memory and self.initializer is not None:
|
location = 0
|
location=self.location
|
for value in self.initializer:
|
for value in self.initializer:
|
instructions.append({
|
|
"op":"memory_write_literal",
|
instructions.append(
|
|
{"op":"memory_write_literal",
|
"address":location,
|
"address":location,
|
"value":value,
|
"value":value,
|
"element_size":self.element_size
|
"element_size":self.element_size})
|
})
|
|
location += 1
|
location += 1
|
instructions.append({
|
|
"op":"literal",
|
instructions.append(
|
|
{"op":"literal",
|
"literal":self.location,
|
"literal":self.location,
|
"dest":self.register
|
"dest":self.register})
|
})
|
|
#this bit here is to make string literals work,
|
|
#in this case an array instance is created implicitly,
|
|
#but the value of the expression is the array register.
|
|
if result is not None and result != self.register:
|
|
instructions.append({
|
|
"op" :"move",
|
|
"dest":result,
|
|
"src" :self.register
|
|
})
|
|
return instructions
|
return instructions
|
|
|
|
|
|
def reference(self):
|
|
return Array(self)
|
|
|
|
def type_(self):
|
|
return self._type
|
|
|
|
def size(self):
|
|
return self._size
|
|
|
|
def signed(self):
|
|
return self._signed
|
|
|
|
|
class StructDeclaration:
|
class StructDeclaration:
|
|
|
def __init__(self, members):
|
def __init__(self, members):
|
self.members = members
|
self.members = members
|
|
self._type = "struct {%s}"%"; ".join(
|
|
[i.type_() for i in members.values()])
|
|
self._size = sum([i.size() for i in members.values()])
|
|
self._signed = False
|
|
|
def instance(self):
|
def instance(self):
|
instances = {}
|
instances = {}
|
for name, declaration in self.members.iteritems():
|
for name, declaration in self.members.iteritems():
|
instances[name] = declaration.instance()
|
instances[name] = declaration.instance()
|
return StructInstance(instances)
|
return StructInstance(instances)
|
|
|
|
def type_(self):
|
|
return self._type
|
|
|
|
def size(self):
|
|
return self._size
|
|
|
|
def signed(self):
|
|
return self._signed
|
|
|
|
|
class StructInstance:
|
class StructInstance:
|
|
|
def __init__(self, members):
|
def __init__(self, members):
|
self.members = members
|
self.members = members
|
self.type_ = "struct"
|
self._type = "struct {%s}"%"; ".join(
|
|
[i.type_() for i in members.values()])
|
|
self._size = sum([i.size() for i in members.values()])
|
|
self._signed = False
|
|
|
def generate(self):
|
def generate(self):
|
instructions = []
|
instructions = []
|
for member in self.members.values():
|
for member in self.members.values():
|
instructions.extend(member.generate())
|
instructions.extend(member.generate())
|
return instructions
|
return instructions
|
|
|
class Argument:
|
def reference(self):
|
def __init__(self,
|
return Struct(self)
|
name,
|
|
type_,
|
def type_(self):
|
size,
|
return self._type
|
signed,
|
|
parser,
|
def size(self):
|
element_type,
|
return self._size
|
element_size,
|
|
element_signed):
|
def signed(self):
|
self.type_=type_
|
return self._signed
|
self.size=size
|
|
self.signed=signed
|
|
self.element_type = element_type
|
|
self.element_size = element_size
|
|
self.element_signed = element_signed
|
|
parser.scope[name] = self
|
|
self.register = parser.allocator.new(size, "function argument "+name)
|
|
def generate(self): return []
|
|
|
|
class DiscardExpression:
|
class DiscardExpression:
|
|
|
def __init__(self, expression, allocator):
|
def __init__(self, expression, allocator):
|
self.expression = expression
|
self.expression = expression
|
self.allocator = allocator
|
self.allocator = allocator
|
|
|
def generate(self):
|
def generate(self):
|
result = self.allocator.new(self.expression.size)
|
result = self.allocator.new(self.expression.size())
|
instructions = self.expression.generate(result)
|
instructions = self.expression.generate(result, self.allocator)
|
self.allocator.free(result)
|
self.allocator.free(result)
|
return instructions
|
return instructions
|
|
|
#...then Expressions...
|
|
|
|
#Expressions generate methods accept a result argument.
|
class Expression:
|
#This indicates which register to put the result in.
|
|
|
def __init__(self, t, size, signed):
|
|
self.type_var=t
|
|
self.size_var=size
|
|
self.signed_var=signed
|
|
|
|
def type_(self):
|
|
return self.type_var
|
|
|
|
def size(self):
|
|
return self.size_var
|
|
|
|
def signed(self):
|
|
return self.signed_var
|
|
|
|
def value(self):
|
|
raise NotConstant
|
|
|
|
def const(self):
|
|
return True
|
|
|
|
def int_value(self):
|
|
if self.type_() == "float":
|
|
byte_value = struct.pack(">f", self.value())
|
|
value = ord(byte_value[0]) << 24
|
|
value |= ord(byte_value[1]) << 16
|
|
value |= ord(byte_value[2]) << 8
|
|
value |= ord(byte_value[3])
|
|
return value
|
|
else:
|
|
return self.value()
|
|
|
|
|
|
class Object(Expression):
|
|
|
|
def __init__(self, instance):
|
|
Expression.__init__(self, instance.type_(), instance.size(), instance.signed())
|
|
self.instance = instance
|
|
|
|
def value(self):
|
|
raise NotConstant
|
|
|
|
def const(self):
|
|
return False
|
|
|
#Expressions may also provide a value method which returns the value of an xpression
|
|
#if it can be calculated at compile time.
|
|
|
|
def AND(left, right):
|
def AND(left, right):
|
return ANDOR(left, right, "jmp_if_false")
|
return ANDOR(left, right, "jmp_if_false")
|
|
|
|
|
def OR(left, right):
|
def OR(left, right):
|
return ANDOR(left, right, "jmp_if_true")
|
return ANDOR(left, right, "jmp_if_true")
|
|
|
class ANDOR:
|
|
|
class ANDOR(Expression):
|
|
|
def __init__(self, left, right, op):
|
def __init__(self, left, right, op):
|
self.left = constant_fold(left)
|
self.left = constant_fold(left)
|
self.right = constant_fold(right)
|
self.right = constant_fold(right)
|
self.op = op
|
self.op = op
|
self.type_ = "int"
|
|
self.size = left.size
|
|
self.signed = left.signed
|
|
|
|
def generate(self, result):
|
Expression.__init__(
|
instructions = self.left.generate(result)
|
self,
|
|
"int",
|
|
max(left.size(), right.size()),
|
|
left.signed() and right.signed())
|
|
|
|
def generate(self, result, allocator):
|
|
instructions = self.left.generate(result, allocator)
|
instructions.append({"op":self.op, "src":result, "label":"end_%s"%id(self)})
|
instructions.append({"op":self.op, "src":result, "label":"end_%s"%id(self)})
|
instructions.extend(self.right.generate(result))
|
instructions.extend(self.right.generate(result, allocator))
|
instructions.append({"op":"label", "label":"end_%s"%id(self)})
|
instructions.append({"op":"label", "label":"end_%s"%id(self)})
|
return instructions
|
return instructions
|
|
|
def value(self):
|
def value(self):
|
if self.op == "jmp_if_false":
|
if self.op == "jmp_if_false":
|
return value(self.left) and value(self.right)
|
return self.left.value() and self.right.value()
|
else:
|
else:
|
return value(self.left) or value(self.right)
|
return self.left.value() or self.right.value()
|
|
|
|
|
|
def get_binary_type(left, right, operator):
|
|
"""
|
|
Given the type of the left and right hand operators, determine the type
|
|
of the resulting value.
|
|
"""
|
|
|
|
binary_types = {
|
|
"float,float,+" : ("float", 4, True),
|
|
"float,float,-" : ("float", 4, True),
|
|
"float,float,*" : ("float", 4, True),
|
|
"float,float,/" : ("float", 4, True),
|
|
"float,float,==" : ("int", 4, True),
|
|
"float,float,!=" : ("int", 4, True),
|
|
"float,float,<" : ("int", 4, True),
|
|
"float,float,>" : ("int", 4, True),
|
|
"float,float,<=" : ("int", 4, True),
|
|
"float,float,>=" : ("int", 4, True)}
|
|
|
|
signature = ",".join([left.type_(), right.type_(), operator])
|
|
if signature in binary_types:
|
|
type_, size, signed = binary_types[signature]
|
|
else:
|
|
type_ = left.type_()
|
|
size = max(left.size(), right.size())
|
|
signed = left.signed() and right.signed()
|
|
|
|
return type_, size, signed
|
|
|
|
class Binary(Expression):
|
|
|
class Binary:
|
def __init__(self, operator, left, right):
|
def __init__(self, operator, left, right, allocator):
|
|
self.left = constant_fold(left)
|
self.left = constant_fold(left)
|
self.right = constant_fold(right)
|
self.right = constant_fold(right)
|
self.operator = operator
|
self.operator = operator
|
self.allocator = allocator
|
type_, size, signed = get_binary_type(left, right, operator)
|
self.type_ = self.left.type_
|
|
self.size = max(left.size, right.size)
|
|
self.signed = left.signed and right.signed
|
|
|
|
def generate(self, result):
|
Expression.__init__(
|
new_register = self.allocator.new(self.size)
|
self,
|
|
type_,
|
|
size,
|
|
signed)
|
|
|
|
def generate(self, result, allocator):
|
|
new_register = allocator.new(self.size())
|
try:
|
try:
|
instructions = self.right.generate(new_register)
|
instructions = self.right.generate(new_register, allocator)
|
instructions.append({"op" :self.operator,
|
|
|
instructions.append(
|
|
{"op" :self.operator,
|
"dest":result,
|
"dest":result,
|
"left":value(self.left),
|
"left":self.left.int_value(),
|
"src":new_register,
|
"src":new_register,
|
"signed":self.signed})
|
"type":self.type_(),
|
|
"size":self.size(),
|
|
"signed":self.signed()})
|
|
|
except NotConstant:
|
except NotConstant:
|
try:
|
try:
|
instructions = self.left.generate(new_register)
|
instructions = self.left.generate(new_register, allocator)
|
instructions.append({"op" :self.operator,
|
|
|
instructions.append(
|
|
{"op" :self.operator,
|
"dest" :result,
|
"dest" :result,
|
"src" :new_register,
|
"src" :new_register,
|
"right":value(self.right),
|
"right":self.right.int_value(),
|
"signed" :self.signed})
|
"type":self.type_(),
|
|
"size":self.size(),
|
|
"signed" :self.signed()})
|
|
|
except NotConstant:
|
except NotConstant:
|
instructions = self.left.generate(new_register)
|
instructions = self.left.generate(new_register, allocator)
|
right = self.allocator.new(self.right.size)
|
right = allocator.new(self.size())
|
instructions.extend(self.right.generate(right))
|
instructions.extend(self.right.generate(right, allocator))
|
instructions.append({"op" :self.operator,
|
|
|
instructions.append(
|
|
{"op" :self.operator,
|
"dest":result,
|
"dest":result,
|
"src" :new_register,
|
"src" :new_register,
|
"srcb":right,
|
"srcb":right,
|
"signed":self.signed})
|
"type":self.type_(),
|
self.allocator.free(right)
|
"size":self.size(),
|
self.allocator.free(new_register)
|
"signed":self.signed()})
|
|
|
|
allocator.free(right)
|
|
allocator.free(new_register)
|
return instructions
|
return instructions
|
|
|
def value(self):
|
def value(self):
|
return eval("%s %s %s"%(value(self.left), self.operator, value(self.right)))
|
|
|
if self.type_() == "int":
|
|
|
|
return int(eval("%s %s %s"%(
|
|
self.left.value(),
|
|
self.operator,
|
|
self.right.value())))
|
|
|
|
else:
|
|
|
|
return float(eval("%s %s %s"%(
|
|
self.left.value(),
|
|
self.operator,
|
|
self.right.value())))
|
|
|
|
|
|
|
def SizeOf(expression):
|
def SizeOf(expression):
|
return Constant(expression.size)
|
return Constant(expression.size())
|
|
|
|
|
|
class IntToFloat(Expression):
|
|
|
|
def __init__(self, expression):
|
|
self.expression = constant_fold(expression)
|
|
|
|
Expression.__init__( self, "float", 4, True)
|
|
|
|
def generate(self, result, allocator):
|
|
new_register = allocator.new(self.size())
|
|
instructions = self.expression.generate(new_register, allocator)
|
|
|
|
instructions.extend([
|
|
{"op" : "int_to_float",
|
|
"dest" : result,
|
|
"src" : new_register}])
|
|
|
|
allocator.free(new_register)
|
|
return instructions
|
|
|
|
def value(self):
|
|
return float(self.expression.value())
|
|
|
|
|
|
class FloatToInt(Expression):
|
|
|
class Unary:
|
def __init__(self, expression):
|
def __init__(self, operator, expression, allocator):
|
self.expression = constant_fold(expression)
|
|
|
|
Expression.__init__( self, "int", 4, True)
|
|
|
|
def generate(self, result, allocator):
|
|
new_register = allocator.new(self.size())
|
|
instructions = self.expression.generate(new_register, allocator)
|
|
|
|
instructions.extend([
|
|
{"op" : "float_to_int",
|
|
"dest" : result,
|
|
"src" : new_register}])
|
|
|
|
allocator.free(new_register)
|
|
return instructions
|
|
|
|
def value(self):
|
|
return int(self.expression.value())
|
|
|
|
|
|
class Unary(Expression):
|
|
|
|
def __init__(self, operator, expression):
|
self.expression = constant_fold(expression)
|
self.expression = constant_fold(expression)
|
self.operator = operator
|
self.operator = operator
|
self.type_ = self.expression.type_
|
|
self.size = expression.size
|
|
self.signed = expression.signed
|
|
self.allocator = allocator
|
|
|
|
def generate(self, result):
|
Expression.__init__(
|
new_register = self.allocator.new(self.size)
|
self,
|
instructions = self.expression.generate(new_register)
|
expression.type_(),
|
instructions.extend([{"op":self.operator, "dest":result, "src":new_register}])
|
expression.size(),
|
self.allocator.free(new_register)
|
expression.signed())
|
|
|
|
def generate(self, result, allocator):
|
|
new_register = allocator.new(self.size())
|
|
instructions = self.expression.generate(new_register, allocator)
|
|
|
|
instructions.extend([
|
|
{"op":self.operator,
|
|
"dest":result,
|
|
"src":new_register}])
|
|
|
|
allocator.free(new_register)
|
return instructions
|
return instructions
|
|
|
def value(self):
|
def value(self):
|
return eval("%s%s"%(self.operator, value(self.expression)))
|
return eval("%s%s"%(self.operator, self.expression.value()))
|
|
|
|
|
|
class FunctionCall(Expression):
|
|
|
|
def __init__(self, function):
|
|
self.function = function
|
|
|
|
Expression.__init__(
|
|
self,
|
|
function.type_,
|
|
function.size,
|
|
function.signed)
|
|
|
class FunctionCall:
|
def generate(self, result, allocator):
|
def generate(self, result):
|
|
instructions = []
|
instructions = []
|
for expression, argument in zip(self.arguments, self.function.arguments):
|
|
instructions.extend(expression.generate(argument.register))
|
for expression, argument in zip(
|
instructions.append({"op" :"jmp_and_link",
|
self.arguments,
|
|
self.function.arguments):
|
|
|
|
temp_register = allocator.new(expression.size())
|
|
instructions.extend(
|
|
argument.copy(expression, temp_register, allocator))
|
|
allocator.free(temp_register)
|
|
|
|
instructions.append(
|
|
{"op" :"jmp_and_link",
|
"dest" :self.function.return_address,
|
"dest" :self.function.return_address,
|
"label":"function_%s"%id(self.function)})
|
"label":"function_%s"%id(self.function)})
|
|
|
if hasattr(self.function, "return_value"):
|
if hasattr(self.function, "return_value"):
|
instructions.append({"op" :"move",
|
|
"dest" :result,
|
instructions.extend(self.function.return_value.generate(
|
"src" :self.function.return_value})
|
result,
|
|
allocator))
|
|
|
return instructions
|
return instructions
|
|
|
class Output:
|
|
|
class Output(Expression):
|
|
|
def __init__(self, name, expression):
|
def __init__(self, name, expression):
|
self.name = name
|
self.name = name
|
self.expression = expression
|
self.expression = expression
|
self.type_ = "int"
|
Expression.__init__(self, "int", 2, True)
|
self.size = expression.size
|
|
|
def generate(self, result, allocator):
|
|
instructions = self.expression.generate(result, allocator)
|
|
|
|
instructions.append(
|
|
{"op" :"write",
|
|
"src" :result,
|
|
"output":self.name})
|
|
|
def generate(self, result):
|
|
instructions = self.expression.generate(result);
|
|
instructions.append({"op" :"write", "src" :result, "output":self.name})
|
|
return instructions
|
return instructions
|
|
|
class FileWrite:
|
|
|
class FileWrite(Expression):
|
|
|
def __init__(self, name, expression):
|
def __init__(self, name, expression):
|
self.name = name
|
self.name = name
|
self.expression = expression
|
self.expression = expression
|
self.type_ = "int"
|
Expression.__init__(
|
self.size = expression.size
|
self,
|
|
expression.type_(),
|
|
expression.size(),
|
|
expression.signed())
|
|
|
|
def generate(self, result, allocator):
|
|
instructions = self.expression.generate(result, allocator)
|
|
|
|
instructions.append(
|
|
{"op" :"file_write",
|
|
"src" :result,
|
|
"type":self.expression.type_(),
|
|
"file_name":self.name})
|
|
|
def generate(self, result):
|
|
instructions = self.expression.generate(result);
|
|
instructions.append({"op" :"file_write", "src" :result, "file_name":self.name})
|
|
return instructions
|
return instructions
|
|
|
class Input:
|
|
|
class Input(Expression):
|
|
|
def __init__(self, name):
|
def __init__(self, name):
|
self.name = name
|
self.name = name
|
self.type_ = "int"
|
Expression.__init__(self, "int", 2, True)
|
self.size = 2
|
|
self.signed = True
|
|
|
|
def generate(self, result):
|
def generate(self, result, allocator):
|
return [{"op" :"read", "dest" :result, "input":self.name}]
|
return [{"op" :"read", "dest" :result, "input":self.name}]
|
|
|
class FileRead:
|
|
|
class FileRead(Expression):
|
|
|
def __init__(self, name):
|
def __init__(self, name):
|
self.name = name
|
self.name = name
|
self.type_ = "int"
|
Expression.__init__(self, "int", 2, True)
|
self.size = 2
|
|
self.signed = True
|
|
|
|
def generate(self, result):
|
def generate(self, result, allocator):
|
return [{"op" :"file_read", "dest" :result, "file_name":self.name}]
|
return [{"op" :"file_read", "dest" :result, "file_name":self.name}]
|
|
|
class Ready:
|
|
|
class Ready(Expression):
|
|
|
def __init__(self, name):
|
def __init__(self, name):
|
self.name = name
|
self.name = name
|
self.type_ = "int"
|
Expression.__init__(self, "int", 2, True)
|
self.size = 2
|
|
self.signed = True
|
|
|
|
def generate(self, result):
|
def generate(self, result, allocator):
|
return [{"op" :"ready", "dest" :result, "input":self.name}]
|
return [{"op" :"ready", "dest" :result, "input":self.name}]
|
|
|
class Array:
|
|
def __init__(self, declaration, allocator):
|
|
self.declaration = declaration
|
|
self.allocator = allocator
|
|
self.storage = "register"
|
|
self.type_ = self.declaration.type_
|
|
self.size = int(self.declaration.size) * 2
|
|
self.signed = False
|
|
|
|
def generate(self, result):
|
class Struct(Object):
|
|
|
|
def __init__(self, instance):
|
|
Object.__init__(self, instance)
|
|
|
|
def generate(self, result, allocator):
|
instructions = []
|
instructions = []
|
if result != self.declaration.register:
|
if result != self.declaration.register:
|
instructions.append({"op" :"move",
|
|
|
instructions.append(
|
|
{"op" :"move",
|
"dest":result,
|
"dest":result,
|
"src" :self.declaration.register})
|
"src" :self.declaration.register})
|
|
|
return instructions
|
return instructions
|
|
|
class ArrayIndex:
|
def copy(self, expression, result, allocator):
|
def __init__(self, declaration, index_expression, allocator):
|
instructions = []
|
self.declaration = declaration
|
|
self.allocator = allocator
|
for lvalue, rvalue in zip(
|
|
self.instance.members.values(),
|
|
expression.instance.members.values()):
|
|
|
|
instructions.extend(
|
|
lvalue.reference().copy(rvalue.reference(), result, allocator))
|
|
|
|
return instructions
|
|
|
|
|
|
class Array(Object):
|
|
|
|
def __init__(self, instance):
|
|
Object.__init__(self, instance)
|
|
|
|
def generate(self, result, allocator):
|
|
instructions = []
|
|
if result != self.instance.register:
|
|
|
|
instructions.append(
|
|
{"op" : "move",
|
|
"dest" : result,
|
|
"src" : self.instance.register})
|
|
|
|
return instructions
|
|
|
|
def copy(self, expression, result, allocator):
|
|
instructions = expression.generate(result, allocator)
|
|
if result != self.instance.register:
|
|
|
|
instructions.append(
|
|
{"op" : "move",
|
|
"dest" : self.instance.register,
|
|
"src" : result})
|
|
|
|
return instructions
|
|
|
|
|
|
class ConstArray(Object):
|
|
|
|
def __init__(self, instance):
|
|
Object.__init__(self, instance)
|
|
|
|
def generate(self, result, allocator):
|
|
instructions = []
|
|
#If initialize memory is true, the memory content will initialised (as at configuration time)
|
|
#If initialize memory is false, then the memory will need to be filled by the program.
|
|
if not self.instance.initialize_memory and self.instance.initializer is not None:
|
|
location = self.instance.location
|
|
for value in self.instance.initializer:
|
|
|
|
instructions.append(
|
|
{"op":"memory_write_literal",
|
|
"address":location,
|
|
"value":value,
|
|
"element_size":self.instance.element_size})
|
|
|
|
location += 1
|
|
|
|
instructions.append(
|
|
{"op":"literal",
|
|
"literal":self.instance.location,
|
|
"dest":self.instance.register})
|
|
|
|
if result != self.instance.register:
|
|
|
|
instructions.append(
|
|
{"op" : "move",
|
|
"dest" : result,
|
|
"src" : self.instance.register})
|
|
|
|
return instructions
|
|
|
|
def copy(self, expression, result, allocator):
|
|
instructions = expression.generate(result, allocator)
|
|
if result != self.instance.register:
|
|
|
|
instructions.append(
|
|
{"op" : "move",
|
|
"dest" : self.instance.register,
|
|
"src" : result})
|
|
|
|
return instructions
|
|
|
|
|
|
class ArrayIndex(Object):
|
|
|
|
def __init__(self, instance, index_expression):
|
|
Object.__init__(self, instance)
|
|
assert self.type_var.endswith("[]")
|
|
self.type_var = self.type_var[:-2]
|
|
self.size_var = instance.element_size
|
self.index_expression = index_expression
|
self.index_expression = index_expression
|
self.storage = "memory"
|
|
self.type_ = self.declaration.element_type
|
def generate(self, result, allocator):
|
self.size = self.declaration.element_size
|
instructions = []
|
self.signed = self.declaration.element_signed
|
offset = allocator.new(2)
|
|
address = allocator.new(2)
|
def generate(self, result):
|
instructions.extend(self.index_expression.generate(offset, allocator))
|
instructions = []
|
|
offset = self.allocator.new(2)
|
instructions.append(
|
address = self.allocator.new(2)
|
{"op" :"+",
|
instructions.extend(self.index_expression.generate(offset))
|
|
instructions.append({"op" :"+",
|
|
"dest" :address,
|
"dest" :address,
|
"src" :offset,
|
"src" :offset,
|
"srcb" :self.declaration.register,
|
"srcb" :self.instance.register,
|
"signed":False})
|
"signed":False})
|
instructions.append({"op" :"memory_read_request",
|
|
|
instructions.append(
|
|
{"op" :"memory_read_request",
|
"src" :address,
|
"src" :address,
|
"sequence": id(self),
|
"sequence": id(self),
|
"element_size":self.size})
|
"element_size":self.size()})
|
instructions.append({"op" :"memory_read_wait",
|
|
|
instructions.append(
|
|
{"op" :"memory_read_wait",
|
"src" :address,
|
"src" :address,
|
"sequence": id(self),
|
"sequence": id(self),
|
"element_size":self.size})
|
"element_size":self.size()})
|
instructions.append({"op" :"memory_read",
|
|
|
instructions.append(
|
|
{"op" :"memory_read",
|
"src" :address,
|
"src" :address,
|
"dest" :result,
|
"dest" :result,
|
"sequence": id(self),
|
"sequence": id(self),
|
"element_size":self.size})
|
"element_size":self.size()})
|
self.allocator.free(address)
|
|
self.allocator.free(offset)
|
allocator.free(address)
|
|
allocator.free(offset)
|
return instructions
|
return instructions
|
|
|
class Variable:
|
def copy(self, expression, result, allocator):
|
def __init__(self, declaration, allocator):
|
index = allocator.new(2)
|
self.declaration = declaration
|
address = allocator.new(2)
|
self.allocator = allocator
|
instructions = expression.generate(result, allocator)
|
self.storage = "register"
|
instructions.extend(self.index_expression.generate(index, allocator))
|
self.type_ = self.declaration.type_
|
|
self.size = self.declaration.size
|
|
self.signed = self.declaration.signed
|
|
|
|
def generate(self, result):
|
instructions.append(
|
|
{"op" :"+",
|
|
"dest" :address,
|
|
"src" :index,
|
|
"srcb" :self.instance.register,
|
|
"signed" :expression.signed()})
|
|
|
|
instructions.append(
|
|
{"op" :"memory_write",
|
|
"src" :address,
|
|
"srcb" :result,
|
|
"element_size" :self.instance.element_size})
|
|
|
|
allocator.free(index)
|
|
allocator.free(address)
|
|
return instructions
|
|
|
|
|
|
class Variable(Object):
|
|
def __init__(self, instance):
|
|
Object.__init__(self, instance)
|
|
|
|
def generate(self, result, allocator):
|
instructions = []
|
instructions = []
|
if result != self.declaration.register:
|
if result != self.instance.register:
|
instructions.append({"op" :"move",
|
|
|
instructions.append(
|
|
{"op" :"move",
|
"dest":result,
|
"dest":result,
|
"src" :self.declaration.register})
|
"src" :self.instance.register})
|
|
|
|
return instructions
|
|
|
|
def copy(self, expression, result, allocator):
|
|
instructions = expression.generate(result, allocator)
|
|
if result != self.instance.register:
|
|
|
|
instructions.append(
|
|
{"op" : "move",
|
|
"dest" : self.instance.register,
|
|
"src" : result})
|
|
|
return instructions
|
return instructions
|
|
|
class PostIncrement:
|
def const(self):
|
|
return self.instance.const()
|
|
|
|
def value(self):
|
|
if self.const():
|
|
return self.instance.initializer.value()
|
|
else:
|
|
raise NotConstant
|
|
|
|
|
|
class PostIncrement(Expression):
|
|
|
def __init__(self, operator, lvalue, allocator):
|
def __init__(self, operator, lvalue, allocator):
|
self.operator = operator
|
self.operator = operator
|
self.lvalue = lvalue
|
self.lvalue = lvalue
|
self.allocator = allocator
|
allocator = allocator
|
self.type_ = self.lvalue.declaration.type_
|
Expression.__init__(self, lvalue.type_(), lvalue.size(), lvalue.signed())
|
self.size = self.lvalue.declaration.size
|
|
self.signed = self.lvalue.declaration.signed
|
|
|
|
def generate(self, result):
|
def generate(self, result, allocator):
|
|
|
instructions = []
|
instructions = []
|
|
|
instructions.append({"op" :"move",
|
instructions.append(
|
"src" :self.lvalue.declaration.register,
|
{"op" : "move",
|
|
"src" : self.lvalue.instance.register,
|
"dest" :result})
|
"dest" :result})
|
|
|
instructions.append({"op" :self.operator,
|
instructions.append(
|
"dest" :self.lvalue.declaration.register,
|
{"op" : self.operator,
|
|
"dest" : self.lvalue.instance.register,
|
"right" :1,
|
"right" :1,
|
"src" :self.lvalue.declaration.register,
|
"src" : self.lvalue.instance.register,
|
"signed":self.signed})
|
"size" : self.size(),
|
|
"signed": self.signed()})
|
|
|
return instructions
|
return instructions
|
|
|
class Assignment:
|
|
|
class Assignment(Expression):
|
|
|
def __init__(self, lvalue, expression, allocator):
|
def __init__(self, lvalue, expression, allocator):
|
|
Expression.__init__(self, lvalue.type_(), lvalue.size(), lvalue.signed())
|
self.lvalue = lvalue
|
self.lvalue = lvalue
|
self.expression = expression
|
self.expression = expression
|
self.allocator = allocator
|
self.allocator = allocator
|
self.type_ = self.lvalue.type_
|
|
self.size = self.lvalue.size
|
|
self.signed = self.lvalue.signed
|
|
|
|
def generate(self, result):
|
|
instructions = self.expression.generate(result)
|
|
if self.lvalue.storage == "register":
|
|
if result != self.lvalue.declaration.register:
|
|
instructions.append({"op" : "move",
|
|
"dest" : self.lvalue.declaration.register,
|
|
"src" : result})
|
|
|
|
elif self.lvalue.storage == "memory":
|
def generate(self, result, allocator):
|
index = self.allocator.new(2)
|
return self.lvalue.copy(self.expression, result, allocator)
|
address = self.allocator.new(2)
|
|
instructions.extend(self.lvalue.index_expression.generate(index))
|
|
instructions.append({"op" :"+",
|
|
"dest" :address,
|
|
"src" :index,
|
|
"srcb" :self.lvalue.declaration.register,
|
|
"signed" :self.signed})
|
|
instructions.append({"op" :"memory_write",
|
|
"src" :address,
|
|
"srcb" :result,
|
|
"element_size" :self.lvalue.declaration.element_size})
|
|
self.allocator.free(index)
|
|
self.allocator.free(address)
|
|
|
|
return instructions
|
|
|
|
class Constant:
|
class Constant(Expression):
|
def __init__(self, value, size=2, signed=True):
|
|
|
def __init__(self, value, type_="int", size=2, signed=True):
|
self._value = value
|
self._value = value
|
self.type_ = "int"
|
Expression.__init__(self, type_, size, signed)
|
self.size = size
|
|
self.signed = signed
|
|
|
|
def generate(self, result):
|
def generate(self, result, allocator):
|
instructions = [{"op":"literal", "dest":result, "literal":self._value}]
|
|
|
instructions = [{
|
|
"op":"literal",
|
|
"dest":result,
|
|
"size":self.size(),
|
|
"signed":self.size(),
|
|
"literal":self.int_value()}]
|
return instructions
|
return instructions
|
|
|
def value(self):
|
def value(self):
|
return self._value
|
return self._value
|
|
|
No newline at end of file
|
No newline at end of file
|
|
|
|
|
No newline at end of file
|
No newline at end of file
|