Пример #1
0
	def _addHelperFunctionsPostTranslation(self):
		# if this module contains a main function emit code which will call it

		flist = self._findSymbol(name=u'main', type_=ESFunction, mayFail=True)

		if flist:
			assert(len(flist) == 1)
			esMain = flist[0]

			s = []
			s.append('The main function defined in this module has an unsupported signature.')
			s.append('supported signatures:')
			s.append('\tdef main() as int32')
			s.append('\tdef main() as void')

			int32 = self._findSymbol(name=u'int32', type_=ESType)
			void = self._findSymbol(name=u'void', type_=ESType)
			validA = ESType.createFunction([int32], [])
			validB = ESType.createFunction([void], [])

			ok = False
			for x in [validA, validB]:
				if x.isEquivalentTo(esMain.esType, False):
					ok = True

			if not ok:
				self._raiseException(RecoverableCompileError, postText=s)


			# has arguments?
			if len(esMain.esType.getFunctionParameterTypes()) == 0:
				functionType= Type.function(Type.int(32), [])
				function = self._module.add_function(functionType, 'main')

				entryBB = function.append_basic_block('entry')
				BB = function.append_basic_block('bb')

				b = Builder.new(entryBB)
				if self._debugMode:
					dbgSubProg = self._debugInfoBuilder.addFunctionInfoStart(module=self._module, builder=b, lineNumber=0, name='main', displayName='main')
				b.branch(BB)


				b = Builder.new(BB)
				r = b.call(esMain.llvmRef, [])

				retTypes = esMain.esType.getFunctionReturnTypes()
				assert(len(retTypes) == 1)

				if retTypes[0].toLLVMType() != Type.void():
					b.ret(r)
				else:
					b.ret(Constant.int(Type.int(32), 0))

				if self._debugMode:
					self._debugInfoBuilder.addFunctionInfoEnd(module=self._module, builder=b, subprogram=dbgSubProg)
			else:
				# TODO implement version with parameters
				self._raiseException(RecoverableCompileError, postText=s)
Пример #2
0
	def _onFuncPrototype(self, ast, modifierKeys, modifierValues, name, returnTypeName, parameterNames, parameterTypeNames, block):
		# create type of function
		self._dispatch(returnTypeName)
		returnTypes = [returnTypeName.esType]

		paramNames = []
		paramTypes = []
		for i in range(len(parameterTypeNames)):
			paramNames.append(parameterNames[i].text)

			self._dispatch(parameterTypeNames[i])
			paramTypes.append(parameterTypeNames[i].esType)

		functionType = ESType.createFunction(returnTypes, paramTypes)


		# parse modifiers
		linkage = None
		mangling = None
		for i in range(len(modifierKeys)):
			k = modifierKeys[i].text
			v = modifierValues[i].text

			if k == u'linkage':
				linkage = v
			elif k == u'mangling':
				mangling = v
			else:
				self._raiseException(RecoverableCompileError, tree=modifierKeys[i], inlineText='unknown function modifier')


		esFunction = ESFunction(name.text, self._moduleNode.packageName, self._moduleNode.moduleName, functionType, paramNames, mangling=mangling, linkage=linkage)
		ast.esFunction = esFunction
		ast.esType = functionType


		if name.text in ['ctor', 'dtor']:
			# function is a constructor / destructor
			# TODO allow only global functions to be module constructors / destructors

			moduleXTor = True
			if moduleXTor:
				# module XTors must have the signature 'def Xtor() as void'
				expectedType = ESType.createFunction([self._findSymbol(name=u'void', type_=ESType)], [])
				if not functionType.isEquivalentTo(expectedType, True): # structurally / name based should not matter for module Xtors
					self._raiseException(RecoverableCompileError, tree=name, inlineText='a module ctor / dtor must have the type \'def Xtor() as void\'')

				if name.text == 'ctor':
					self._moduleCTors.append(esFunction)
				else:
					self._moduleDTors.append(esFunction)


		# TODO check for duplicate entries
		self._addSymbol(fromTree=name, symbol=esFunction)
Пример #3
0
	def _addHelperFunctionsPreTranslation(self):
		# int puts(char *);
		returnTypes = [self._findSymbol(name=u'int32', type_=ESType)]
		paramTypes = [self._findSymbol(name=u'int8', type_=ESType).derivePointer()]
		esType = ESType.createFunction(returnTypes, paramTypes)
		esFunc = ESFunction(u'puts', '', '', esType, [u's'], mangling='C', linkage='extern')
		self._addSymbol(name=u'puts', symbol=esFunc)
		type = esType.toLLVMType()
		func = self._module.add_function(type, 'puts')


		# void abort();
		returnTypes = [self._findSymbol(name=u'void', type_=ESType)]
		paramTypes = []
		esType = ESType.createFunction(returnTypes, paramTypes)
		esFunc = ESFunction(u'abort', '', '', esType, [], mangling='C', linkage='extern')
		type = esType.toLLVMType()
		func = self._module.add_function(type, 'abort')
Пример #4
0
	def _onFunctionTypeName(self, ast):
		# FIXME move ast unpacking to AstWalker!

		types = []
		for x in ast.children:
			self._dispatch(x)
			types.append(x.esType)

		esType = ESType.createFunction([types[-1]], types[:-1])
		esType = esType.derivePointer()

		ast.esType = esType
Пример #5
0
	def _onDefStruct(self, ast, name, members):
		# since structs can refer to them selves using pointers we have to add this type right now
		structType = ESType.createStruct(name.text, [], [])
		self._addSymbol(fromTree=name, symbol=structType)

		esTypes = []
		names = []
		for x in members:
			# DO NOT dispatch x itself! that would add entries to a symbol table that does not exist
			# process name manually and dispatch type name
			self._dispatch(x.children[1])
			esTypes.append(x.children[1].esType)

			if x.children[0].text in names:
				self._raiseException(RecoverableCompileError, tree=x.children[0], inlineText='name already used')
			names.append(x.children[0].text)

		# add members
		# FIXME derive type name from package and module!
		t = ESType.createStruct(name.text, esTypes, names)
		structType.payload = t.payload
		structType.parents = t.parents

		ast.esType = structType
Пример #6
0
	def _onTypeName(self, ast):
		def insideStructDef(self):
			sdn = None
			for n in reversed(self._nodes):
				if n.type == TreeType.STRUCT:
					sdn = n
					break
			return sdn


		n = len(ast.children)
		if n == 1:
			ast.esType = self._findSymbol(fromTree=ast.children[0], type_=ESType)

			if ast.esType.isStruct() and not ast.esType.parents:
				assert(insideStructDef(self))
				self._raiseException(RecoverableCompileError, fromTree=ast, inlineText='structs can not contain themself. Use a pointer')
		else:
			# later we could implement here const / invariant etc.
			# but now just look up name
			baseType = self._findSymbol(fromTree=ast.children[0], type_=ESType)

			if baseType.isStruct() and not baseType.parents:
				assert(insideStructDef(self))
				baseType = ESType.createSelfPointer()

			# no nesting allowed for now!
			if ast.children[1].type not in [TreeType.STAR, TreeType.DOUBLESTAR]:
				self._raiseException(RecoverableCompileError, tree=ast.children[1], inlineText='type constructors are not supported')

			for x in ast.children[1:]:
				baseType = baseType.derivePointer()
				if x.type == TreeType.DOUBLESTAR:
					baseType = baseType.derivePointer()

			ast.esType = baseType
Пример #7
0
	def _onNoneConstant(self, ast):
		ast.esType = ESType.createNone()