From 275d165a839d1ca9ed883f29b6c749764a7ce35e Mon Sep 17 00:00:00 2001 From: lucafs Date: Fri, 4 Jun 2021 08:38:42 -0300 Subject: [PATCH 1/7] almost done --- main.py | 189 ++++++++++++++++++++++++++++++++++++++++++++++---------- teste.c | 25 ++++---- 2 files changed, 169 insertions(+), 45 deletions(-) diff --git a/main.py b/main.py index 6d69859..6ff675d 100644 --- a/main.py +++ b/main.py @@ -34,7 +34,9 @@ def tToken_finder(char): elif(char == "|"): return "OR" elif(char == '"'): - return "STRING" + return "STRING" + elif(char == ","): + return "COMMA" elif(char.isalpha() or char == "-" or char == "_"): return "IDENT" elif(char.isdigit()): @@ -54,6 +56,8 @@ def IdentType(char): return "ELSE" elif(char == "while"): return "WHILE" + elif(char == "return"): + return "RETURN" elif(char == "bool" or char == "int" or char == "string"): return "TYPE" elif(char == "true" or char == "false"): @@ -62,7 +66,8 @@ def IdentType(char): class SymbolTable: def __init__(self): - self.sym = {} + self.sym = {} # (value,type) + self.functions = {} # (name,value) def setter(self, name, value, type): if(value != None): @@ -70,14 +75,21 @@ def setter(self, name, value, type): value = bool(value) elif(type == "int"): value = int(value) - self.sym[name] = (value,type) + if(type == "FUNCTION"): + self.functions[name] = (value) + else: + self.sym[name] = (value,type) - def getter(self, name): + def getter(self, name, type): try: - return self.sym[name] + if type == "FUNC": + return self.functions[name] + else: + return self.sym[name] except: return "error" - + def setFuncs(self,dict): + self.functions = dict class Node(): def __init__(self,value = None , children = []): @@ -95,6 +107,7 @@ class IntVal(Node): def Evaluate(self,ST): return (int(self.value),"int") + class BoolVal(Node): def Evaluate(self,ST): if(self.value == "true"): @@ -132,7 +145,7 @@ class FirstAssign(Node): def Evaluate(self, ST): type = self.children[0] name = self.children[1] - if(ST.getter(name) != "error"): + if(ST.getter(name," ") != "error"): raise Exception ("Variable " + name + " aready declared") ST.setter(name, None ,type) @@ -140,7 +153,7 @@ class Assign(Node): def Evaluate(self, ST): name = self.children[0].value expression = self.children[1].Evaluate(ST) - type = ST.getter(name)[1] + type = ST.getter(name, " ")[1] if(type == "error"): raise Exception ("Symbol "+name+ " not declared") if(expression[1] != type): @@ -152,7 +165,7 @@ def Evaluate(self, ST): class Identifier(Node): def Evaluate(self, ST): - return ST.getter(self.value) + return ST.getter(self.value, " ") class Println(Node): def Evaluate(self, ST): @@ -211,6 +224,34 @@ def Evaluate(self, ST): if len(self.children) > 2: self.children[2].Evaluate(ST) +class FuncDeclare(Node): + def Evaluate(self, ST): + funcName = self.value + funcList = self.children + #ORDEM DA LISTA lista de argumentos (tipo,nome) / argumentos + ST.setter(funcName, funcList ,"FUNCTION") + +class FuncCall(Node): + def Evaluate(self, ST): + funcName = self.value + funcList = ST.getter(funcName,"FUNC") + functionST = SymbolTable() + functionST.setFuncs(ST.functions) + if(funcList == "error"): + raise Exception ("Func not Declared " + funcName) + if(len(self.children) != len(funcList[0])): + raise Exception ("Not enough args in FuncCall " + funcName) + for i in range(len(funcList[0])): + print(self.children[0][i]) + functionST.setter(funcList[0][i][1],self.children[0][i],funcList[0][i][0]) + funcList[1].Evaluate(functionST) + + +class ReturnVal(Node): + def Evaluate(self,ST): + retValue = self.value.Evaluate(ST) + return ST.getter(retValue, " ") + class Comandos(Node): @@ -220,12 +261,6 @@ def Evaluate(self, ST): - - - - - - class Token: def __init__(self, tToken = None, value = None): self.type = tToken @@ -426,10 +461,29 @@ def parseFactor(): Parser.tokens.selectNext() return node elif(Parser.tokens.actual.type== "IDENT"): - node = Identifier() - node.value= Parser.tokens.actual.value - Parser.tokens.selectNext() - return node + nodeValue = Parser.tokens.actual.value + if Parser.tokens.actual.type != "OPN": + node = Identifier() + node.value= nodeValue + Parser.tokens.selectNext() + return node + else: + assign = FuncCall(nodeValue,[]) + Parser.tokens.selectNext() + if Parser.tokens.actual.type != "CLS": + assign.children.append(Parser.parseOrexPR) + while(Parser.tokens.actual.type == "COMMA"): + Parser.tokens.selectNext() + assign.children.append(Parser.parseOrexPR) + if Parser.tokens.actual.type != "CLS": + raise Exception (") NOT FUND in FCALL 2") + Parser.tokens.selectNext() + if Parser.tokens.actual.type != "ENDCOM": + raise Exception("; NOT FOUND in FCALL 2") + return assign + + + elif(Parser.tokens.actual.type == "SUM" or Parser.tokens.actual.type == "MIN" or Parser.tokens.actual.type == "NEG"): if(Parser.tokens.actual.type == "SUM"): node = UnOp("+", []) @@ -464,6 +518,55 @@ def parseFactor(): else: raise Exception ("Factor error") + @staticmethod + def parseFuncDefBlock(): + funcArr = [] + if Parser.tokens.actual.type == "TYPE": + while Parser.tokens.actual.type == "TYPE": + Parser.tokens.selectNext() + if Parser.tokens.actual.type == "IDENT": + func_name = Parser.tokens.actual.value + decNode = FuncDeclare(func_name, []) + decVars = [] + Parser.tokens.selectNext() + if Parser.tokens.actual.type == "OPN": + Parser.tokens.selectNext() + if(Parser.tokens.actual.type == "TYPE"): + argType = Parser.tokens.actual.value + Parser.tokens.selectNext() + if(Parser.tokens.actual.type !="IDENT"): + raise Exception ("ERROR FUNC IDENT") + argName = Parser.tokens.actual.value + decVars.append((argType,argName)) + Parser.tokens.selectNext() + while(Parser.tokens.actual.type == "COMMA"): + Parser.tokens.selectNext() + if(Parser.tokens.actual.type !="TYPE"): + raise Exception ("ERROR FUNC TYPE") + argType = Parser.tokens.actual.value + Parser.tokens.selectNext() + if(Parser.tokens.actual.type !="IDENT"): + raise Exception ("ERROR 1") + argName = Parser.tokens.actual.value + decVars.append((argType,argName)) + Parser.tokens.selectNext() + if Parser.tokens.actual.type != "CLS": + raise Exception ("ERROR 2") + decNode.children.append(decVars) + Parser.tokens.selectNext() + decNode.children.append(Parser.parseCommand()) + funcArr.append(decNode) + else: + raise Exception ("Did not find OPN in func") + else: + raise Exception ("No name in function") + return funcArr + else: + print("No function program") + + + + @staticmethod def parseBlock(): @@ -484,11 +587,9 @@ def parseBlock(): def parseCommand(): if Parser.tokens.actual.type == "IDENT": var_name = Parser.tokens.actual.value - var_node = Identifier(var_name, []) - Parser.tokens.selectNext() - if Parser.tokens.actual.type == "EQL": + var_node = Identifier(var_name, []) assign = Assign("=", []) assign.children.append(var_node) value = Parser.parseOrexPR() @@ -496,9 +597,25 @@ def parseCommand(): if Parser.tokens.actual.type != "ENDCOM": raise Exception("; NOT FOUND") Parser.tokens.selectNext() + + elif Parser.tokens.actual.type == "OPN": + assign = FuncCall(var_name,[]) + Parser.tokens.selectNext() + if Parser.tokens.actual.type != "CLS": + assign.children.append(Parser.parseOrexPR) + Parser.tokens.selectNext() + while(Parser.tokens.actual.type == "COMMA"): + Parser.tokens.selectNext() + assign.children.append(Parser.parseOrexPR) + Parser.tokens.selectNext() + if Parser.tokens.actual.type != "CLS": + raise Exception (") NOT FUND in FCALL") + Parser.tokens.selectNext() + if Parser.tokens.actual.type != "ENDCOM": + raise Exception("; NOT FOUND in FCALL") + Parser.tokens.selectNext() else: raise Exception("COMMAND ERROR") - return assign elif Parser.tokens.actual.type == "TYPE": @@ -515,9 +632,6 @@ def parseCommand(): raise Exception("FIRST ASSIGN ERROR") return firstAssign - - - elif Parser.tokens.actual.type == "PRINT": print_node = Println("PRINT", []) print_value = Parser.parseOrexPR() @@ -527,6 +641,15 @@ def parseCommand(): Parser.tokens.selectNext() return print_node + elif Parser.tokens.actual.type == "RETURN": + Parser.tokens.selectNext() + retNode = ReturnVal(Parser.parseOrexPR) + Parser.tokens.selectNext() + if Parser.tokens.actual.type != "ENDCOM": + raise Exception("; NOT FOUND") + Parser.tokens.selectNext() + return retNode + elif Parser.tokens.actual.type == "WHILE": while_node = WhileOp('while', []) Parser.tokens.selectNext() @@ -571,10 +694,15 @@ def run(code): #executa o compilador Parser.tokens = Parser().tokens(origin = code) Parser.tokens.selectNext() - res = Parser().parseBlock() + res = Parser().parseFuncDefBlock() + ST = SymbolTable() + for funcs in res: + funcs.Evaluate(ST) + # print(ST.functions) + if(Parser.tokens.actual.type != "END"): raise Exception ("ERROR") - return res + return ST @@ -586,9 +714,8 @@ def main(): file += sys.argv[i] f = open(file,'r') comando = f.read() - resultado = Parser().run(comando) - ST = SymbolTable() - resultado.Evaluate(ST) + ST = Parser().run(comando) + FuncCall("main",[]).Evaluate(ST) if __name__ == "__main__": main() \ No newline at end of file diff --git a/teste.c b/teste.c index f1dd9ba..62ebd17 100644 --- a/teste.c +++ b/teste.c @@ -1,15 +1,12 @@ -{ - bool a; - int b; - int c; - - b = 32; - c = 32; - a = true; - if ((b && c) == a) { - println(1); - }else{ - println(2); - } -} \ No newline at end of file +int soma(int numero, int outro){ + int somaFinal; + somaFinal = numero + outro; + println(somaFinal); + return somaFinal; +} +int main(){ + int somatotal; + soma(3,4); + println(somatotal); +} From defdf4059d3f8f215115d6a737a0c41c939dd565 Mon Sep 17 00:00:00 2001 From: lucafs Date: Fri, 4 Jun 2021 14:40:17 -0300 Subject: [PATCH 2/7] done --- main.py | 153 +++++++++++++++++++++++++++++++++++++++++++++----------- teste.c | 23 +++++---- 2 files changed, 136 insertions(+), 40 deletions(-) diff --git a/main.py b/main.py index 6ff675d..3c80661 100644 --- a/main.py +++ b/main.py @@ -80,6 +80,12 @@ def setter(self, name, value, type): else: self.sym[name] = (value,type) + def firsSet(self,name,value,type): + if name in self.sym: + pass + else: + self.sym[name] = (value,type) + def getter(self, name, type): try: if type == "FUNC": @@ -147,13 +153,13 @@ def Evaluate(self, ST): name = self.children[1] if(ST.getter(name," ") != "error"): raise Exception ("Variable " + name + " aready declared") - ST.setter(name, None ,type) + ST.firsSet(name, None ,type) class Assign(Node): def Evaluate(self, ST): name = self.children[0].value - expression = self.children[1].Evaluate(ST) type = ST.getter(name, " ")[1] + expression = self.children[1].Evaluate(ST) if(type == "error"): raise Exception ("Symbol "+name+ " not declared") if(expression[1] != type): @@ -242,15 +248,23 @@ def Evaluate(self, ST): if(len(self.children) != len(funcList[0])): raise Exception ("Not enough args in FuncCall " + funcName) for i in range(len(funcList[0])): - print(self.children[0][i]) - functionST.setter(funcList[0][i][1],self.children[0][i],funcList[0][i][0]) + if(len(self.children[i].Evaluate(ST))>1): + functionST.setter(funcList[0][i][1],self.children[i].Evaluate(ST)[0],funcList[0][i][0]) + else: + functionST.setter(funcList[0][i][1],self.children[i].Evaluate(ST)[0],funcList[0][i][0]) + funcList[1].Evaluate(functionST) + returnVal = functionST.getter("RETURN__VALUE","") + if(returnVal != "error"): + return returnVal + class ReturnVal(Node): def Evaluate(self,ST): retValue = self.value.Evaluate(ST) - return ST.getter(retValue, " ") + ST.firsSet("RETURN__VALUE", retValue[0],retValue[1]) + return self.value.Evaluate(ST) @@ -351,6 +365,89 @@ def selectNext(self): self.actual.value += self.origin[self.position] return self.actual + + + def seeNext(self): + actualVal = self.actual + actualPos = self.position + #se for o ultimo acaba + if (self.position >= len(self.origin)): + self.actual = Token(tToken= "END") + return self.actual.type + if(self.position < len(self.origin)): + #passa enquanto for espaço + while(self.origin[self.position] == " " or self.origin[self.position] == "\t"): + self.position += 1 + #se for o ultimo acaba + if (self.position >= len(self.origin)): + self.actual = Token(tToken= "END") + retVal = self.actual + self.actual = actualVal + self.position = actualPos + return retVal.type + #Aqui achou o proximo token valido. + + self.actual = Token(tToken= tToken_finder(self.origin[self.position]),value = self.origin[self.position]) + self.position += 1 + if((self.position < len(self.origin)) and self.actual.type == "NUM"): + while(tToken_finder(self.origin[self.position]) == "NUM"): + self.actual.value += self.origin[self.position] + self.position += 1 + if(self.position == len(self.origin)): + break + + + if((self.position < len(self.origin)) and self.actual.type == "STRING"): + while(tToken_finder(self.origin[self.position]) != "STRING"): + if(self.position == len(self.origin) or tToken_finder(self.origin[self.position]) == "ENDCOM"): + raise Exception ("ASPAS DE STRING NÃO FECHADAS") + self.actual.value += self.origin[self.position] + self.position += 1 + self.actual.value += self.origin[self.position] + self.position += 1 + + if((self.position < len(self.origin)) and self.actual.type == "IDENT"): + while(tToken_finder(self.origin[self.position]) == "IDENT" or tToken_finder(self.origin[self.position]) == "NUM"): + self.actual.value += self.origin[self.position] + self.position += 1 + if(self.actual.value == "else"): + break + if(self.position == len(self.origin)): + break + identT = IdentType(self.actual.value) + if(identT != None): + self.actual.type = identT + + + if((self.position < len(self.origin)) and self.actual.type == "ENDCOM"): + while(tToken_finder(self.origin[self.position]) == "ENDCOM"): + self.actual.value += self.origin[self.position] + self.position += 1 + if(self.position == len(self.origin)): + break + if((self.position < len(self.origin)) and self.actual.type == "EQL"): + if(tToken_finder(self.origin[self.position]) == "EQL"): + self.actual.value += self.origin[self.position] + self.actual.type = "DUALEQL" + self.position +=1 + + if(self.actual.type == "OR"): + if(tToken_finder(self.origin[self.position]) != "OR"): + raise Exception("OR INCOMPLETE") + self.position +=1 + self.actual.value += self.origin[self.position] + + if(self.actual.type == "AND"): + if(tToken_finder(self.origin[self.position]) != "AND"): + raise Exception("AND INCOMPLETE") + self.position +=1 + self.actual.value += self.origin[self.position] + retVal = self.actual + self.actual = actualVal + self.position = actualPos + return retVal.type + + @@ -462,28 +559,25 @@ def parseFactor(): return node elif(Parser.tokens.actual.type== "IDENT"): nodeValue = Parser.tokens.actual.value + Parser.tokens.selectNext() if Parser.tokens.actual.type != "OPN": + node = Identifier() node.value= nodeValue - Parser.tokens.selectNext() return node else: assign = FuncCall(nodeValue,[]) - Parser.tokens.selectNext() - if Parser.tokens.actual.type != "CLS": - assign.children.append(Parser.parseOrexPR) + if Parser.tokens.seeNext() != "CLS": + assign.children.append(Parser.parseOrexPR()) while(Parser.tokens.actual.type == "COMMA"): - Parser.tokens.selectNext() - assign.children.append(Parser.parseOrexPR) - if Parser.tokens.actual.type != "CLS": - raise Exception (") NOT FUND in FCALL 2") + assign.children.append(Parser.parseOrexPR()) + if Parser.tokens.actual.type != "CLS": + raise Exception (") NOT FUND in FCALL 2") + else: + Parser.tokens.selectNext() Parser.tokens.selectNext() - if Parser.tokens.actual.type != "ENDCOM": - raise Exception("; NOT FOUND in FCALL 2") return assign - - - + elif(Parser.tokens.actual.type == "SUM" or Parser.tokens.actual.type == "MIN" or Parser.tokens.actual.type == "NEG"): if(Parser.tokens.actual.type == "SUM"): node = UnOp("+", []) @@ -515,6 +609,8 @@ def parseFactor(): else: raise Exception("Read error") return node + elif(Parser.tokens.actual.type == "CLS"): + pass else: raise Exception ("Factor error") @@ -587,6 +683,7 @@ def parseBlock(): def parseCommand(): if Parser.tokens.actual.type == "IDENT": var_name = Parser.tokens.actual.value + Parser.tokens.selectNext() if Parser.tokens.actual.type == "EQL": var_node = Identifier(var_name, []) @@ -600,16 +697,14 @@ def parseCommand(): elif Parser.tokens.actual.type == "OPN": assign = FuncCall(var_name,[]) - Parser.tokens.selectNext() - if Parser.tokens.actual.type != "CLS": - assign.children.append(Parser.parseOrexPR) - Parser.tokens.selectNext() + if Parser.tokens.seeNext() != "CLS": + assign.children.append(Parser.parseOrexPR()) while(Parser.tokens.actual.type == "COMMA"): - Parser.tokens.selectNext() - assign.children.append(Parser.parseOrexPR) - Parser.tokens.selectNext() - if Parser.tokens.actual.type != "CLS": - raise Exception (") NOT FUND in FCALL") + assign.children.append(Parser.parseOrexPR()) + if Parser.tokens.actual.type != "CLS": + raise Exception (") NOT FUND in FCALL") + else: + Parser.tokens.selectNext() Parser.tokens.selectNext() if Parser.tokens.actual.type != "ENDCOM": raise Exception("; NOT FOUND in FCALL") @@ -642,9 +737,7 @@ def parseCommand(): return print_node elif Parser.tokens.actual.type == "RETURN": - Parser.tokens.selectNext() - retNode = ReturnVal(Parser.parseOrexPR) - Parser.tokens.selectNext() + retNode = ReturnVal(Parser.parseOrexPR()) if Parser.tokens.actual.type != "ENDCOM": raise Exception("; NOT FOUND") Parser.tokens.selectNext() diff --git a/teste.c b/teste.c index 62ebd17..b424bad 100644 --- a/teste.c +++ b/teste.c @@ -1,12 +1,15 @@ -int soma(int numero, int outro){ - int somaFinal; - somaFinal = numero + outro; - println(somaFinal); - return somaFinal; -} -int main(){ - int somatotal; - soma(3,4); - println(somatotal); +int soma(int x, int y) +{ + int res; + res = x + y; + return res; } + +int main() +{ + int x; + soma(3,5);/*Ok fazer isso*/ + x = soma(3,5); + println(x); +} \ No newline at end of file From 447e5af1a31ae5bf369537756004b7754676e3ab Mon Sep 17 00:00:00 2001 From: lucafs Date: Fri, 4 Jun 2021 17:24:39 -0300 Subject: [PATCH 3/7] fix return --- main.py | 18 +++++--- program.asm | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++ teste.asm | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++ teste.c | 26 ++++++------ 4 files changed, 265 insertions(+), 17 deletions(-) create mode 100644 program.asm create mode 100644 teste.asm diff --git a/main.py b/main.py index 3c80661..0dd23b2 100644 --- a/main.py +++ b/main.py @@ -243,6 +243,7 @@ def Evaluate(self, ST): funcList = ST.getter(funcName,"FUNC") functionST = SymbolTable() functionST.setFuncs(ST.functions) + if(funcList == "error"): raise Exception ("Func not Declared " + funcName) if(len(self.children) != len(funcList[0])): @@ -270,8 +271,15 @@ def Evaluate(self,ST): class Comandos(Node): def Evaluate(self, ST): + ReturnHappend = True for x in self.children: - x.Evaluate(ST) + if(ReturnHappend): + x.Evaluate(ST) + if(isinstance(x,ReturnVal)): + ReturnHappend = False + elif(not ReturnHappend and isinstance(x,NoOp)): + ReturnHappend = True + @@ -658,7 +666,7 @@ def parseFuncDefBlock(): raise Exception ("No name in function") return funcArr else: - print("No function program") + return funcArr @@ -672,6 +680,7 @@ def parseBlock(): while(Parser.tokens.actual.type != "CLS_COM"): commands.children.append(Parser.parseCommand()) if(Parser.tokens.actual.type == "CLS_COM"): + commands.children.append(NoOp()) Parser.tokens.selectNext() else: raise Exception("} not found") @@ -789,10 +798,9 @@ def run(code): Parser.tokens.selectNext() res = Parser().parseFuncDefBlock() ST = SymbolTable() + ReturnHappend = False for funcs in res: - funcs.Evaluate(ST) - # print(ST.functions) - + funcs.Evaluate(ST) if(Parser.tokens.actual.type != "END"): raise Exception ("ERROR") return ST diff --git a/program.asm b/program.asm new file mode 100644 index 0000000..5d13420 --- /dev/null +++ b/program.asm @@ -0,0 +1,119 @@ + +; constantes +SYS_EXIT equ 1 +SYS_READ equ 3 +SYS_WRITE equ 4 +STDIN equ 0 +STDOUT equ 1 +True equ 1 +False equ 0 + +segment .data + +segment .bss ; variaveis + res RESB 1 + +section .text + global _start + +print: ; subrotina print + + PUSH EBP ; guarda o base pointer + MOV EBP, ESP ; estabelece um novo base pointer + + MOV EAX, [EBP+8] ; 1 argumento antes do RET e EBP + XOR ESI, ESI + +print_dec: ; empilha todos os digitos + MOV EDX, 0 + MOV EBX, 0x000A + DIV EBX + ADD EDX, '0' + PUSH EDX + INC ESI ; contador de digitos + CMP EAX, 0 + JZ print_next ; quando acabar pula + JMP print_dec + +print_next: + CMP ESI, 0 + JZ print_exit ; quando acabar de imprimir + DEC ESI + + MOV EAX, SYS_WRITE + MOV EBX, STDOUT + + POP ECX + MOV [res], ECX + MOV ECX, res + + MOV EDX, 1 + INT 0x80 + JMP print_next + +print_exit: + POP EBP + RET + +; subrotinas if/while +binop_je: + JE binop_true + JMP binop_false + +binop_jg: + JG binop_true + JMP binop_false + +binop_jl: + JL binop_true + JMP binop_false + +binop_false: + MOV EBX, False + JMP binop_exit +binop_true: + MOV EBX, True +binop_exit: + RET + +_start: + + PUSH EBP ; guarda o base pointer + MOV EBP, ESP ; estabelece um novo base pointer + + ; codigo gerado pelo compilador + PUSH DWORD 0 ; + MOV [EBP-1], EBX + PUSH DWORD 0 ; + MOV [EBP-2], EBX + PUSH DWORD 0 ; + MOV [EBP-3], EBX + MOV EBX, 32 ; + MOV [EBP-2], EBX; + MOV EBX, 32 ; + MOV [EBP-3], EBX; + MOV EBX, True ; + MOV [EBP-1], EBX; + CMP EBX, False ; + JE ELSE_4 ; + JMP EXIT_4 ; + ELSE_4 ; + EXIT_4 ; + POP EAX + CMP EAX, EBX + CALL binop_je + POP EAX + AND EAX, EBX + CALL binop_jl + MOV EBX, [EBP-2] ; + MOV EBX, [EBP-3] ; + MOV EBX, [EBP-1] ; + MOV EBX, 1 ; + PUSH EBX ; + CALL print ; + POP EBX ; + + ; interrupcao de saida + POP EBP + MOV EAX, 1 + INT 0x80 \ No newline at end of file diff --git a/teste.asm b/teste.asm new file mode 100644 index 0000000..5d13420 --- /dev/null +++ b/teste.asm @@ -0,0 +1,119 @@ + +; constantes +SYS_EXIT equ 1 +SYS_READ equ 3 +SYS_WRITE equ 4 +STDIN equ 0 +STDOUT equ 1 +True equ 1 +False equ 0 + +segment .data + +segment .bss ; variaveis + res RESB 1 + +section .text + global _start + +print: ; subrotina print + + PUSH EBP ; guarda o base pointer + MOV EBP, ESP ; estabelece um novo base pointer + + MOV EAX, [EBP+8] ; 1 argumento antes do RET e EBP + XOR ESI, ESI + +print_dec: ; empilha todos os digitos + MOV EDX, 0 + MOV EBX, 0x000A + DIV EBX + ADD EDX, '0' + PUSH EDX + INC ESI ; contador de digitos + CMP EAX, 0 + JZ print_next ; quando acabar pula + JMP print_dec + +print_next: + CMP ESI, 0 + JZ print_exit ; quando acabar de imprimir + DEC ESI + + MOV EAX, SYS_WRITE + MOV EBX, STDOUT + + POP ECX + MOV [res], ECX + MOV ECX, res + + MOV EDX, 1 + INT 0x80 + JMP print_next + +print_exit: + POP EBP + RET + +; subrotinas if/while +binop_je: + JE binop_true + JMP binop_false + +binop_jg: + JG binop_true + JMP binop_false + +binop_jl: + JL binop_true + JMP binop_false + +binop_false: + MOV EBX, False + JMP binop_exit +binop_true: + MOV EBX, True +binop_exit: + RET + +_start: + + PUSH EBP ; guarda o base pointer + MOV EBP, ESP ; estabelece um novo base pointer + + ; codigo gerado pelo compilador + PUSH DWORD 0 ; + MOV [EBP-1], EBX + PUSH DWORD 0 ; + MOV [EBP-2], EBX + PUSH DWORD 0 ; + MOV [EBP-3], EBX + MOV EBX, 32 ; + MOV [EBP-2], EBX; + MOV EBX, 32 ; + MOV [EBP-3], EBX; + MOV EBX, True ; + MOV [EBP-1], EBX; + CMP EBX, False ; + JE ELSE_4 ; + JMP EXIT_4 ; + ELSE_4 ; + EXIT_4 ; + POP EAX + CMP EAX, EBX + CALL binop_je + POP EAX + AND EAX, EBX + CALL binop_jl + MOV EBX, [EBP-2] ; + MOV EBX, [EBP-3] ; + MOV EBX, [EBP-1] ; + MOV EBX, 1 ; + PUSH EBX ; + CALL print ; + POP EBX ; + + ; interrupcao de saida + POP EBP + MOV EAX, 1 + INT 0x80 \ No newline at end of file diff --git a/teste.c b/teste.c index b424bad..861aa06 100644 --- a/teste.c +++ b/teste.c @@ -1,15 +1,17 @@ +/*Ok: para eval quando encontra return*/ -int soma(int x, int y) -{ - int res; - res = x + y; - return res; +int qualquer(){ + int x; + x = 10; + + println(x); + return x; + + println(x*2); } -int main() -{ - int x; - soma(3,5);/*Ok fazer isso*/ - x = soma(3,5); - println(x); -} \ No newline at end of file + +int main(){ + int y; + y = qualquer(); +} From 91d3cfc890a3d0d91b08ae66a187760b98e1c151 Mon Sep 17 00:00:00 2001 From: lucafs Date: Fri, 4 Jun 2021 17:31:05 -0300 Subject: [PATCH 4/7] delete extra files --- program.asm | 119 ---------------------------------------------------- teste.asm | 119 ---------------------------------------------------- teste.c | 3 +- 3 files changed, 2 insertions(+), 239 deletions(-) delete mode 100644 program.asm delete mode 100644 teste.asm diff --git a/program.asm b/program.asm deleted file mode 100644 index 5d13420..0000000 --- a/program.asm +++ /dev/null @@ -1,119 +0,0 @@ - -; constantes -SYS_EXIT equ 1 -SYS_READ equ 3 -SYS_WRITE equ 4 -STDIN equ 0 -STDOUT equ 1 -True equ 1 -False equ 0 - -segment .data - -segment .bss ; variaveis - res RESB 1 - -section .text - global _start - -print: ; subrotina print - - PUSH EBP ; guarda o base pointer - MOV EBP, ESP ; estabelece um novo base pointer - - MOV EAX, [EBP+8] ; 1 argumento antes do RET e EBP - XOR ESI, ESI - -print_dec: ; empilha todos os digitos - MOV EDX, 0 - MOV EBX, 0x000A - DIV EBX - ADD EDX, '0' - PUSH EDX - INC ESI ; contador de digitos - CMP EAX, 0 - JZ print_next ; quando acabar pula - JMP print_dec - -print_next: - CMP ESI, 0 - JZ print_exit ; quando acabar de imprimir - DEC ESI - - MOV EAX, SYS_WRITE - MOV EBX, STDOUT - - POP ECX - MOV [res], ECX - MOV ECX, res - - MOV EDX, 1 - INT 0x80 - JMP print_next - -print_exit: - POP EBP - RET - -; subrotinas if/while -binop_je: - JE binop_true - JMP binop_false - -binop_jg: - JG binop_true - JMP binop_false - -binop_jl: - JL binop_true - JMP binop_false - -binop_false: - MOV EBX, False - JMP binop_exit -binop_true: - MOV EBX, True -binop_exit: - RET - -_start: - - PUSH EBP ; guarda o base pointer - MOV EBP, ESP ; estabelece um novo base pointer - - ; codigo gerado pelo compilador - PUSH DWORD 0 ; - MOV [EBP-1], EBX - PUSH DWORD 0 ; - MOV [EBP-2], EBX - PUSH DWORD 0 ; - MOV [EBP-3], EBX - MOV EBX, 32 ; - MOV [EBP-2], EBX; - MOV EBX, 32 ; - MOV [EBP-3], EBX; - MOV EBX, True ; - MOV [EBP-1], EBX; - CMP EBX, False ; - JE ELSE_4 ; - JMP EXIT_4 ; - ELSE_4 ; - EXIT_4 ; - POP EAX - CMP EAX, EBX - CALL binop_je - POP EAX - AND EAX, EBX - CALL binop_jl - MOV EBX, [EBP-2] ; - MOV EBX, [EBP-3] ; - MOV EBX, [EBP-1] ; - MOV EBX, 1 ; - PUSH EBX ; - CALL print ; - POP EBX ; - - ; interrupcao de saida - POP EBP - MOV EAX, 1 - INT 0x80 \ No newline at end of file diff --git a/teste.asm b/teste.asm deleted file mode 100644 index 5d13420..0000000 --- a/teste.asm +++ /dev/null @@ -1,119 +0,0 @@ - -; constantes -SYS_EXIT equ 1 -SYS_READ equ 3 -SYS_WRITE equ 4 -STDIN equ 0 -STDOUT equ 1 -True equ 1 -False equ 0 - -segment .data - -segment .bss ; variaveis - res RESB 1 - -section .text - global _start - -print: ; subrotina print - - PUSH EBP ; guarda o base pointer - MOV EBP, ESP ; estabelece um novo base pointer - - MOV EAX, [EBP+8] ; 1 argumento antes do RET e EBP - XOR ESI, ESI - -print_dec: ; empilha todos os digitos - MOV EDX, 0 - MOV EBX, 0x000A - DIV EBX - ADD EDX, '0' - PUSH EDX - INC ESI ; contador de digitos - CMP EAX, 0 - JZ print_next ; quando acabar pula - JMP print_dec - -print_next: - CMP ESI, 0 - JZ print_exit ; quando acabar de imprimir - DEC ESI - - MOV EAX, SYS_WRITE - MOV EBX, STDOUT - - POP ECX - MOV [res], ECX - MOV ECX, res - - MOV EDX, 1 - INT 0x80 - JMP print_next - -print_exit: - POP EBP - RET - -; subrotinas if/while -binop_je: - JE binop_true - JMP binop_false - -binop_jg: - JG binop_true - JMP binop_false - -binop_jl: - JL binop_true - JMP binop_false - -binop_false: - MOV EBX, False - JMP binop_exit -binop_true: - MOV EBX, True -binop_exit: - RET - -_start: - - PUSH EBP ; guarda o base pointer - MOV EBP, ESP ; estabelece um novo base pointer - - ; codigo gerado pelo compilador - PUSH DWORD 0 ; - MOV [EBP-1], EBX - PUSH DWORD 0 ; - MOV [EBP-2], EBX - PUSH DWORD 0 ; - MOV [EBP-3], EBX - MOV EBX, 32 ; - MOV [EBP-2], EBX; - MOV EBX, 32 ; - MOV [EBP-3], EBX; - MOV EBX, True ; - MOV [EBP-1], EBX; - CMP EBX, False ; - JE ELSE_4 ; - JMP EXIT_4 ; - ELSE_4 ; - EXIT_4 ; - POP EAX - CMP EAX, EBX - CALL binop_je - POP EAX - AND EAX, EBX - CALL binop_jl - MOV EBX, [EBP-2] ; - MOV EBX, [EBP-3] ; - MOV EBX, [EBP-1] ; - MOV EBX, 1 ; - PUSH EBX ; - CALL print ; - POP EBX ; - - ; interrupcao de saida - POP EBP - MOV EAX, 1 - INT 0x80 \ No newline at end of file diff --git a/teste.c b/teste.c index 861aa06..30772fc 100644 --- a/teste.c +++ b/teste.c @@ -13,5 +13,6 @@ int qualquer(){ int main(){ int y; - y = qualquer(); + y=0; + y = qualquer(y); } From 74cf5cd930285b04c5007843b4f935572c3c65e4 Mon Sep 17 00:00:00 2001 From: lucafs Date: Fri, 4 Jun 2021 18:17:50 -0300 Subject: [PATCH 5/7] Final v.2.4.0 --- main.py | 7 ++++++- teste.c | 27 ++++++++++++++------------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/main.py b/main.py index 0dd23b2..6d1bc70 100644 --- a/main.py +++ b/main.py @@ -76,6 +76,8 @@ def setter(self, name, value, type): elif(type == "int"): value = int(value) if(type == "FUNCTION"): + if(name in self.functions): + raise Exception("Can't use the same function name = " + name) self.functions[name] = (value) else: self.sym[name] = (value,type) @@ -243,12 +245,15 @@ def Evaluate(self, ST): funcList = ST.getter(funcName,"FUNC") functionST = SymbolTable() functionST.setFuncs(ST.functions) - if(funcList == "error"): raise Exception ("Func not Declared " + funcName) if(len(self.children) != len(funcList[0])): raise Exception ("Not enough args in FuncCall " + funcName) for i in range(len(funcList[0])): + if(self.children[i].Evaluate(ST) == "error"): + raise Exception("Variable not declared") + # print(self.children[i].Evaluate(ST)) + if(len(self.children[i].Evaluate(ST))>1): functionST.setter(funcList[0][i][1],self.children[i].Evaluate(ST)[0],funcList[0][i][0]) else: diff --git a/teste.c b/teste.c index 30772fc..d0a7dda 100644 --- a/teste.c +++ b/teste.c @@ -1,18 +1,19 @@ -/*Ok: para eval quando encontra return*/ +/*Ok*/ -int qualquer(){ +int soma(int x, int y) +{ + int res; + res = x + y; + return res; +} + +int main() +{ + bool res; int x; - x = 10; + x = 3; - println(x); - return x; + res = soma(x,2) == 8; - println(x*2); -} - - -int main(){ - int y; - y=0; - y = qualquer(y); + println(res); } From ed23ca51773ab6b7c5afc24b76288aeb8945c546 Mon Sep 17 00:00:00 2001 From: lucafs Date: Fri, 4 Jun 2021 18:31:18 -0300 Subject: [PATCH 6/7] Fixed Issues --- main.py | 6 +++++- teste.c | 13 +++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/main.py b/main.py index 6d1bc70..eef9f01 100644 --- a/main.py +++ b/main.py @@ -192,7 +192,9 @@ def Evaluate(self, ST): class LogOp(Node): def Evaluate(self, ST): variableType1 = self.children[0].Evaluate(ST)[1] - variableType2 = self.children[1].Evaluate(ST)[1] + variableType2 = "" + if self.value != "!": + variableType2 = self.children[1].Evaluate(ST)[1] if((variableType1 == "string" and variableType2 != "string") or (variableType1 != "string" and variableType2 == "string")): raise Exception ("Not valid boolean operation") if self.value == "<": @@ -269,6 +271,8 @@ def Evaluate(self, ST): class ReturnVal(Node): def Evaluate(self,ST): retValue = self.value.Evaluate(ST) + if(retValue[1] == "string"): + raise Exception ("Invalid return type") ST.firsSet("RETURN__VALUE", retValue[0],retValue[1]) return self.value.Evaluate(ST) diff --git a/teste.c b/teste.c index d0a7dda..bda5a59 100644 --- a/teste.c +++ b/teste.c @@ -1,19 +1,16 @@ -/*Ok*/ +/*Error: tipo de retorno*/ int soma(int x, int y) { int res; res = x + y; - return res; + return "somei"; } int main() { - bool res; - int x; - x = 3; + string x; + x = soma(3,2); + println(x); - res = soma(x,2) == 8; - - println(res); } From 01134839559f129bb97d1361badf1223fbb1a39d Mon Sep 17 00:00:00 2001 From: lucafs Date: Fri, 10 Sep 2021 23:25:46 -0300 Subject: [PATCH 7/7] att Readme --- README.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 406435e..beba72d 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,19 @@ ![git status](http://3.129.230.99/svg/lucafs/Compilador-L-gica/) -# Compilador-Lógica +# Compilador Lógica + + ### Este projeto se resume em um compilador feito em python com o objetivo de compilar códigos de C básicos. Este compilador suporta as seguintes funcionalidades. + + - Println + - Readln + - Declarações de funções + - Declarações de variáveis + - While + - Chamada de função + - Operações lógicas + - If / Else + + +# Estrutura do código: ![DS1](https://i.imgur.com/XC7Qrwm.png) ![DS2](https://i.imgur.com/G29Aidx.png)