コード例 #1
0
ファイル: parser.py プロジェクト: joshikosuru/iPL
def p_arithmeticexpr_binop(p):
	"""
	arithmeticexpr  : arithmeticexpr PLUS arithmeticexpr
					| arithmeticexpr MINUS arithmeticexpr
					| arithmeticexpr POINTER arithmeticexpr
					| arithmeticexpr DIVIDE arithmeticexpr
	"""
	if(p[2] == "+"):
		if(not utils.arithmeticTypeCheck(p[1], p[3])):
			print("Error at +")
			sys.exit()
		p[0] = ASTNode('PLUS', p[1].dtype, p[1].pointerdepth, [p[1], p[3]])
	elif(p[2] == "-"):
		if(not utils.arithmeticTypeCheck(p[1], p[3])):
			print("Error at -")
			sys.exit()
		p[0] = ASTNode('MINUS', p[1].dtype, p[1].pointerdepth, [p[1], p[3]])
	elif(p[2] == "*"):
		if(not utils.arithmeticTypeCheck(p[1], p[3])):
			print("Error at *")
			sys.exit()
		p[0] = ASTNode('MUL', p[1].dtype, p[1].pointerdepth, [p[1], p[3]])
	else:
		if(not utils.arithmeticTypeCheck(p[1], p[3])):
			print("Error at /")
			sys.exit()
		p[0] = ASTNode('DIV', p[1].dtype, p[1].pointerdepth, [p[1], p[3]])
コード例 #2
0
ファイル: parser.py プロジェクト: joshikosuru/iPL
def p_returnstmtforfunc(p):
	"""
	returnstmtforfunc : returnstmt
	"""
	(funcRet, funcDerive, _) = funcSymDict[currentScope]
	temp = ASTNode('RETURN',funcRet ,funcDerive, [])
	if not utils.assignmentTypeCheck(temp, p[1], "return"):
		sys.exit()
	p[0] = ASTNode('RETURN', p[1].dtype, p[1].pointerdepth, [p[1]])
コード例 #3
0
ファイル: parser.py プロジェクト: joshikosuru/iPL
def p_assignment_leftvar(p):
	"""
	assignment : NAME ASSIGN arithmeticexpr
	"""
	global currentScope, varSymDict
	(dtype, pointerdepth) = utils.giveVarSymOutput(p[1], currentScope, varSymDict)
	nodeL = ASTNode('VAR', dtype, pointerdepth, [p[1]])
	if(not utils.assignmentTypeCheck(nodeL, p[3], "assignment")):
		print("Type mismatch at assignment")
		sys.exit()
	p[0] = ASTNode('ASGN', nodeL.dtype, nodeL.pointerdepth, [nodeL, p[3]])
コード例 #4
0
ファイル: parser.py プロジェクト: joshikosuru/iPL
def p_booleanexpr_term(p):
	"""
	booleanexpr : booleanexpr OR booleanexpr
				| booleanexpr AND booleanexpr
				| LPAREN booleanexpr RPAREN
				| NEGATION booleanexpr
	"""
	if(p[2] == '||'):
		p[0] = ASTNode('OR', None, None, [p[1], p[3]])
	elif(p[2] == '&&'):
		p[0] = ASTNode('AND', None, None, [p[1], p[3]])
	elif(p[1] == '!'):
		p[0] = ASTNode('NOT', None, None, [p[2]])
	else:
		p[0] = p[2]
コード例 #5
0
ファイル: codegeneration.py プロジェクト: khaller93/linkedPy
def generate_tree_based_intermediate_code(root: ASTNode,
                                          program_container: ProgramContainer):
    """
    Generates a tree-based intermediate code for the program represented by the given AST node.
    :param root: the root node of the abstract syntax tree that represents the AST node.
    :param program_container: the container of the program that shall be generated.
    """
    constant_pool = ConstantPool()
    program_trunk_byte = root.cache(constant_pool)
    # Concatenates the byte representation of the program.
    program_byte = bytearray(code_base_header)
    program_byte.extend(code_version)
    program_byte.extend(program_container.hash_digest)
    program_byte.extend(constant_pool.cache())
    program_byte.extend(code_program_chapter)
    program_byte.extend(program_trunk_byte)
    # Write out the bytecode.
    if program_container.program_name is None:
        raise ValueError(
            'The program container has too less information for caching the program.'
        )
    with open(
            join(program_container.program_dir,
                 program_container.program_name + '.lpyc'), 'wb') as out_fd:
        out_fd.write(program_byte)
コード例 #6
0
ファイル: parser.py プロジェクト: joshikosuru/iPL
def p_functioncall(p):
	"""
	functioncall : functioncallname LPAREN functioncalllist RPAREN
	"""
	global functionCallParamList, funcSymDict
	p[0] = ASTNode('CALL', funcSymDict[p[1]][0], funcSymDict[p[1]][1], [p[1], functionCallParamList])
	utils.checkTypeParams(functionCallParamList, funcSymDict[p[1]][2], p[1])
	functionCallParamList = []
コード例 #7
0
ファイル: parser.py プロジェクト: joshikosuru/iPL
def p_assignment_leftpointer(p):
	"""
	assignment : startwithstar ASSIGN arithmeticexpr
	"""
	if(not utils.assignmentTypeCheck(p[1], p[3], "assignment")):
		print("Type mismatch at assignment")
		sys.exit()
	p[0] = ASTNode('ASGN', p[1].dtype, p[1].pointerdepth, [p[1], p[3]])
コード例 #8
0
ファイル: parser.py プロジェクト: joshikosuru/iPL
def p_startwithstar_define(p):
	"""
	startwithstar : POINTER startwithany
	"""
	if(p[2].pointerdepth - 1 < 0):
		print("Pointer depth less than zero")
		sys.exit()
	p[0] = ASTNode('DEREF', p[2].dtype, p[2].pointerdepth - 1, [p[2]])
コード例 #9
0
ファイル: parser.py プロジェクト: joshikosuru/iPL
def p_arithmeticexpr_uminus(p):
	"""
	arithmeticexpr : MINUS arithmeticexpr %prec UMINUS
	"""
	if(p[2].pointerdepth == 0):
		if(p[2].data == 'VAR'):
			print("Direct base type access in UMINUS operation")
			sys.exit()
	p[0] = ASTNode('UMINUS', p[2].dtype, p[2].pointerdepth, [p[2]])
コード例 #10
0
ファイル: parser.py プロジェクト: joshikosuru/iPL
def p_startwithany_define(p):
	"""
	startwithany    : POINTER startwithany
					| AMPERSAND NAME
					| NAME
	"""
	global varSymDict, currentScope
	if(p[1] == "*"):
		if(p[2].pointerdepth - 1 < 0):
			print("Pointer depth less than zero")
			sys.exit()
		p[0] = ASTNode('DEREF', p[2].dtype, p[2].pointerdepth - 1, [p[2]])
	elif(p[1] == "&"):
		(dtype, pointerdepth) = utils.giveVarSymOutput(p[2], currentScope, varSymDict)
		p[0] = ASTNode('ADDR', dtype, pointerdepth + 1, [ASTNode('VAR', dtype, pointerdepth, [p[2]])])
	else:
		(dtype, pointerdepth) = utils.giveVarSymOutput(p[1], currentScope, varSymDict)
		p[0] = ASTNode('VAR', dtype, pointerdepth, [p[1]])
コード例 #11
0
def giveCFGFile(fnode, fileName):
    CFGfileName = fileName + ".cfg"
    CFGFile = open(CFGfileName, "w")

    blockCount = -1
    temp = 0
    for fitem in fnode:
        z = helperForCFG(fitem.name, fitem.paramList)
        CFGFile.write(z)
        x = ASTNode('IF', None, None, [True, fitem.ASTList])
        blocks1 = x.giveBlocks()
        blocks = blocks1[1]
        for i in range(1, len(blocks)):
            CFGFile.write("\n<bb " + str(i + blockCount) + ">\n")
            a = blocks[i]
            if a[-1] == 'IF':
                var, temp, lis = a[0].expand(temp, "")
                CFGFile.write(lis)
                CFGFile.write("if(" + var + ") goto <bb " +
                              str(blockCount + a[1] - 1) + ">\n")
                CFGFile.write("else goto <bb " + str(blockCount + a[2] - 1) +
                              ">\n")
            elif a[-1] == 'GOTO':
                for j in range(0, len(a) - 2):
                    var, temp, lis = a[j].expand(temp, "")
                    CFGFile.write(lis)
                CFGFile.write("goto <bb " +
                              str(blockCount + a[len(a) - 2] - 1) + ">\n")
            else:
                if (fitem.returnSTMT is not None):
                    if (len(fitem.returnSTMT) > 0):
                        var, temp, lis = fitem.returnSTMT[0].expand(temp, "")
                        CFGFile.write(lis)
                    else:
                        CFGFile.write("return\n\n")
                else:
                    CFGFile.write("return\n\n")
        blockCount += len(blocks) - 1
コード例 #12
0
ファイル: codegeneration.py プロジェクト: outofbits/linkedPy
def generate_tree_based_intermediate_code(root: ASTNode, program_container: ProgramContainer):
    """
    Generates a tree-based intermediate code for the program represented by the given AST node.
    :param root: the root node of the abstract syntax tree that represents the AST node.
    :param program_container: the container of the program that shall be generated.
    """
    constant_pool = ConstantPool()
    program_trunk_byte = root.cache(constant_pool)
    # Concatenates the byte representation of the program.
    program_byte = bytearray(code_base_header)
    program_byte.extend(code_version)
    program_byte.extend(program_container.hash_digest)
    program_byte.extend(constant_pool.cache())
    program_byte.extend(code_program_chapter)
    program_byte.extend(program_trunk_byte)
    # Write out the bytecode.
    if program_container.program_name is None:
        raise ValueError('The program container has too less information for caching the program.')
    with open(join(program_container.program_dir, program_container.program_name + '.lpyc'), 'wb') as out_fd:
        out_fd.write(program_byte)
コード例 #13
0
ファイル: parser.py プロジェクト: joshikosuru/iPL
def p_boolfromarith_def(p):
	"""
	boolfromarith   : arithmeticexpr LTE arithmeticexpr
					| arithmeticexpr GTE arithmeticexpr
					| arithmeticexpr LT arithmeticexpr
					| arithmeticexpr GT arithmeticexpr
					| arithmeticexpr COMPARENOTEQUAL arithmeticexpr
					| arithmeticexpr COMPAREEQUAL arithmeticexpr
	"""
	if not utils.assignmentTypeCheck(p[1], p[3], "comparison"):
		sys.exit()
	if(p[2] == '<='):
		p[0] = ASTNode('LE', None, None, [p[1], p[3]])
	elif(p[2] == '>='):
		p[0] = ASTNode('GE', None, None, [p[1], p[3]])
	elif(p[2] == '<'):
		p[0] = ASTNode('LT', None, None, [p[1], p[3]])
	elif(p[2] == '>'):
		p[0] = ASTNode('GT', None, None, [p[1], p[3]])
	elif(p[2] == '!='):
		p[0] = ASTNode('NE', None, None, [p[1], p[3]])
	else:
		p[0] = ASTNode('EQ', None, None, [p[1], p[3]])
コード例 #14
0
ファイル: parser.py プロジェクト: joshikosuru/iPL
def p_arithmeticexpr_terminal_floatnumber(p):
	"""
	arithmeticexpr : FLOATNUM
	"""
	p[0] = ASTNode('CONST', 'float', 0, [p[1]])
コード例 #15
0
ファイル: parser.py プロジェクト: joshikosuru/iPL
def p_arithmeticexpr_terminal_number(p):
	"""
	arithmeticexpr  : NUMBER
	"""
	p[0] = ASTNode('CONST', 'int', 0, [p[1]])
コード例 #16
0
def writeFS(f, varSymDict, blockCount):
    li = []
    for i in varSymDict.keys():
        if i[1] == f.name and varSymDict[i][2] == 0:
            li.append(i[0])
    li.sort()
    spaceForF = 0
    varAccessDict = {}
    for i in li:
        if (varSymDict[(i, f.name)][0] == 'int'
                or varSymDict[(i, f.name)][1] > 0):
            spaceForF += 4
        else:
            spaceForF += 8
        varAccessDict[i] = spaceForF
    free_reglist = list(range(18))
    stri = ""
    stri += ('\t.text\t# The .text assembler directive indicates\n')
    stri += ('\t.globl ' + str(f.name) + '\t# The following is the code\n')
    stri += (str(f.name) + ":\n")
    stri += (
        "# Prologue begins\n\tsw $ra, 0($sp)\t# Save the return address\n\tsw $fp, -4($sp)\t# Save the frame pointer\n\tsub $fp, $sp, 8\t# Update the frame pointer\n\tsub $sp, $sp, "
        + str(8 + spaceForF) +
        "\t# Make space for the locals\n# Prologue ends\n")

    spaceForFcpy = spaceForF + 8
    fparams = f.paramList
    for i in fparams:
        if (i[0] == 'int' or i[1] > 0):
            spaceForFcpy += 4
        else:
            spaceForFcpy += 8
        varAccessDict[i[2]] = spaceForFcpy
    newblockCount = blockCount
    x = ASTNode('IF', None, None, [True, f.ASTList])
    blocks1 = x.giveBlocks()
    blocks = blocks1[1]
    for i in range(1, len(blocks)):
        free_reglist = list(range(18))
        # 		this initialisation of free_reglist idk if its true
        stri += ("label" + str(i + blockCount) + ":\n")
        a = blocks[i]
        if a[-1] == 'IF':
            var, free_reglist, lis = a[0].expand_assembly(
                free_reglist, "", varAccessDict, False, i + blockCount)
            stri += lis
            stri += ("\tbne " + num_to_reg(var) + ", $0, label" +
                     str(blockCount + a[1] - 1) + "\n\tj label" +
                     str(blockCount + a[2] - 1) + "\n")
        elif a[-1] == 'GOTO':
            for j in range(0, len(a) - 2):
                var, free_reglist, lis = a[j].expand_assembly(
                    free_reglist, "", varAccessDict, False, i + blockCount)
                stri += lis

            stri += ("\tj label" + str(blockCount + a[len(a) - 2] - 1) + "\n")
        else:
            if (f.returnSTMT is not None):
                if (len(f.returnSTMT) > 0):
                    var, free_reglist, lis = f.returnSTMT[0].expand_assembly(
                        free_reglist, "", varAccessDict, False, i + blockCount)
                    stri += lis

            stri += ("\tj epilogue_" + (str(f.name)) + "\n")
    newblockCount += len(blocks) - 1

    stri += (
        "\n# Epilogue begins\nepilogue_" + str(f.name) + ":\n" +
        "\tadd $sp, $sp, " + str(8 + spaceForF) +
        "\n\tlw $fp, -4($sp)\n\tlw $ra, 0($sp)\n\tjr $ra\t# Jump back to the called procedure\n# Epilogue ends\n"
    )
    return stri, newblockCount
コード例 #17
0
ファイル: parser.py プロジェクト: joshikosuru/iPL
def p_whileblock(p):
	"""
	whileblock : WHILE LPAREN condition RPAREN conditionalbody
	"""
	p[0] = ASTNode('WHILE', None, None, [p[3], p[5]])
コード例 #18
0
ファイル: parser.py プロジェクト: joshikosuru/iPL
def p_ifblock_else(p):
	"""
	ifblock : IF LPAREN condition RPAREN conditionalbody ELSE elseconditionalbody
	"""
	p[0] = ASTNode('IFELSE', None, None, [p[3], p[5], p[7]])
コード例 #19
0
ファイル: parser.py プロジェクト: joshikosuru/iPL
def p_ifblock_if(p):
	"""
	ifblock : IF LPAREN condition RPAREN conditionalbody
	"""
	p[0] = ASTNode('IF', None, None, [p[3], p[5]])