@@ -34,7 +34,9 @@ def tToken_finder(char):
3434 elif (char == "|" ):
3535 return "OR"
3636 elif (char == '"' ):
37- return "STRING"
37+ return "STRING"
38+ elif (char == "," ):
39+ return "COMMA"
3840 elif (char .isalpha () or char == "-" or char == "_" ):
3941 return "IDENT"
4042 elif (char .isdigit ()):
@@ -54,6 +56,8 @@ def IdentType(char):
5456 return "ELSE"
5557 elif (char == "while" ):
5658 return "WHILE"
59+ elif (char == "return" ):
60+ return "RETURN"
5761 elif (char == "bool" or char == "int" or char == "string" ):
5862 return "TYPE"
5963 elif (char == "true" or char == "false" ):
@@ -62,22 +66,30 @@ def IdentType(char):
6266class SymbolTable :
6367
6468 def __init__ (self ):
65- self .sym = {}
69+ self .sym = {} # (value,type)
70+ self .functions = {} # (name,value)
6671
6772 def setter (self , name , value , type ):
6873 if (value != None ):
6974 if (type == "bool" ):
7075 value = bool (value )
7176 elif (type == "int" ):
7277 value = int (value )
73- self .sym [name ] = (value ,type )
78+ if (type == "FUNCTION" ):
79+ self .functions [name ] = (value )
80+ else :
81+ self .sym [name ] = (value ,type )
7482
75- def getter (self , name ):
83+ def getter (self , name , type ):
7684 try :
77- return self .sym [name ]
85+ if type == "FUNC" :
86+ return self .functions [name ]
87+ else :
88+ return self .sym [name ]
7889 except :
7990 return "error"
80-
91+ def setFuncs (self ,dict ):
92+ self .functions = dict
8193
8294class Node ():
8395 def __init__ (self ,value = None , children = []):
@@ -95,6 +107,7 @@ class IntVal(Node):
95107 def Evaluate (self ,ST ):
96108 return (int (self .value ),"int" )
97109
110+
98111class BoolVal (Node ):
99112 def Evaluate (self ,ST ):
100113 if (self .value == "true" ):
@@ -132,15 +145,15 @@ class FirstAssign(Node):
132145 def Evaluate (self , ST ):
133146 type = self .children [0 ]
134147 name = self .children [1 ]
135- if (ST .getter (name ) != "error" ):
148+ if (ST .getter (name , " " ) != "error" ):
136149 raise Exception ("Variable " + name + " aready declared" )
137150 ST .setter (name , None ,type )
138151
139152class Assign (Node ):
140153 def Evaluate (self , ST ):
141154 name = self .children [0 ].value
142155 expression = self .children [1 ].Evaluate (ST )
143- type = ST .getter (name )[1 ]
156+ type = ST .getter (name , " " )[1 ]
144157 if (type == "error" ):
145158 raise Exception ("Symbol " + name + " not declared" )
146159 if (expression [1 ] != type ):
@@ -152,7 +165,7 @@ def Evaluate(self, ST):
152165
153166class Identifier (Node ):
154167 def Evaluate (self , ST ):
155- return ST .getter (self .value )
168+ return ST .getter (self .value , " " )
156169
157170class Println (Node ):
158171 def Evaluate (self , ST ):
@@ -211,6 +224,34 @@ def Evaluate(self, ST):
211224 if len (self .children ) > 2 :
212225 self .children [2 ].Evaluate (ST )
213226
227+ class FuncDeclare (Node ):
228+ def Evaluate (self , ST ):
229+ funcName = self .value
230+ funcList = self .children
231+ #ORDEM DA LISTA lista de argumentos (tipo,nome) / argumentos
232+ ST .setter (funcName , funcList ,"FUNCTION" )
233+
234+ class FuncCall (Node ):
235+ def Evaluate (self , ST ):
236+ funcName = self .value
237+ funcList = ST .getter (funcName ,"FUNC" )
238+ functionST = SymbolTable ()
239+ functionST .setFuncs (ST .functions )
240+ if (funcList == "error" ):
241+ raise Exception ("Func not Declared " + funcName )
242+ if (len (self .children ) != len (funcList [0 ])):
243+ raise Exception ("Not enough args in FuncCall " + funcName )
244+ for i in range (len (funcList [0 ])):
245+ print (self .children [0 ][i ])
246+ functionST .setter (funcList [0 ][i ][1 ],self .children [0 ][i ],funcList [0 ][i ][0 ])
247+ funcList [1 ].Evaluate (functionST )
248+
249+
250+ class ReturnVal (Node ):
251+ def Evaluate (self ,ST ):
252+ retValue = self .value .Evaluate (ST )
253+ return ST .getter (retValue , " " )
254+
214255
215256
216257class Comandos (Node ):
@@ -220,12 +261,6 @@ def Evaluate(self, ST):
220261
221262
222263
223-
224-
225-
226-
227-
228-
229264class Token :
230265 def __init__ (self , tToken = None , value = None ):
231266 self .type = tToken
@@ -426,10 +461,29 @@ def parseFactor():
426461 Parser .tokens .selectNext ()
427462 return node
428463 elif (Parser .tokens .actual .type == "IDENT" ):
429- node = Identifier ()
430- node .value = Parser .tokens .actual .value
431- Parser .tokens .selectNext ()
432- return node
464+ nodeValue = Parser .tokens .actual .value
465+ if Parser .tokens .actual .type != "OPN" :
466+ node = Identifier ()
467+ node .value = nodeValue
468+ Parser .tokens .selectNext ()
469+ return node
470+ else :
471+ assign = FuncCall (nodeValue ,[])
472+ Parser .tokens .selectNext ()
473+ if Parser .tokens .actual .type != "CLS" :
474+ assign .children .append (Parser .parseOrexPR )
475+ while (Parser .tokens .actual .type == "COMMA" ):
476+ Parser .tokens .selectNext ()
477+ assign .children .append (Parser .parseOrexPR )
478+ if Parser .tokens .actual .type != "CLS" :
479+ raise Exception (") NOT FUND in FCALL 2" )
480+ Parser .tokens .selectNext ()
481+ if Parser .tokens .actual .type != "ENDCOM" :
482+ raise Exception ("; NOT FOUND in FCALL 2" )
483+ return assign
484+
485+
486+
433487 elif (Parser .tokens .actual .type == "SUM" or Parser .tokens .actual .type == "MIN" or Parser .tokens .actual .type == "NEG" ):
434488 if (Parser .tokens .actual .type == "SUM" ):
435489 node = UnOp ("+" , [])
@@ -464,6 +518,55 @@ def parseFactor():
464518 else :
465519 raise Exception ("Factor error" )
466520
521+ @staticmethod
522+ def parseFuncDefBlock ():
523+ funcArr = []
524+ if Parser .tokens .actual .type == "TYPE" :
525+ while Parser .tokens .actual .type == "TYPE" :
526+ Parser .tokens .selectNext ()
527+ if Parser .tokens .actual .type == "IDENT" :
528+ func_name = Parser .tokens .actual .value
529+ decNode = FuncDeclare (func_name , [])
530+ decVars = []
531+ Parser .tokens .selectNext ()
532+ if Parser .tokens .actual .type == "OPN" :
533+ Parser .tokens .selectNext ()
534+ if (Parser .tokens .actual .type == "TYPE" ):
535+ argType = Parser .tokens .actual .value
536+ Parser .tokens .selectNext ()
537+ if (Parser .tokens .actual .type != "IDENT" ):
538+ raise Exception ("ERROR FUNC IDENT" )
539+ argName = Parser .tokens .actual .value
540+ decVars .append ((argType ,argName ))
541+ Parser .tokens .selectNext ()
542+ while (Parser .tokens .actual .type == "COMMA" ):
543+ Parser .tokens .selectNext ()
544+ if (Parser .tokens .actual .type != "TYPE" ):
545+ raise Exception ("ERROR FUNC TYPE" )
546+ argType = Parser .tokens .actual .value
547+ Parser .tokens .selectNext ()
548+ if (Parser .tokens .actual .type != "IDENT" ):
549+ raise Exception ("ERROR 1" )
550+ argName = Parser .tokens .actual .value
551+ decVars .append ((argType ,argName ))
552+ Parser .tokens .selectNext ()
553+ if Parser .tokens .actual .type != "CLS" :
554+ raise Exception ("ERROR 2" )
555+ decNode .children .append (decVars )
556+ Parser .tokens .selectNext ()
557+ decNode .children .append (Parser .parseCommand ())
558+ funcArr .append (decNode )
559+ else :
560+ raise Exception ("Did not find OPN in func" )
561+ else :
562+ raise Exception ("No name in function" )
563+ return funcArr
564+ else :
565+ print ("No function program" )
566+
567+
568+
569+
467570
468571 @staticmethod
469572 def parseBlock ():
@@ -484,21 +587,35 @@ def parseBlock():
484587 def parseCommand ():
485588 if Parser .tokens .actual .type == "IDENT" :
486589 var_name = Parser .tokens .actual .value
487- var_node = Identifier (var_name , [])
488-
489590 Parser .tokens .selectNext ()
490-
491591 if Parser .tokens .actual .type == "EQL" :
592+ var_node = Identifier (var_name , [])
492593 assign = Assign ("=" , [])
493594 assign .children .append (var_node )
494595 value = Parser .parseOrexPR ()
495596 assign .children .append (value )
496597 if Parser .tokens .actual .type != "ENDCOM" :
497598 raise Exception ("; NOT FOUND" )
498599 Parser .tokens .selectNext ()
600+
601+ elif Parser .tokens .actual .type == "OPN" :
602+ assign = FuncCall (var_name ,[])
603+ Parser .tokens .selectNext ()
604+ if Parser .tokens .actual .type != "CLS" :
605+ assign .children .append (Parser .parseOrexPR )
606+ Parser .tokens .selectNext ()
607+ while (Parser .tokens .actual .type == "COMMA" ):
608+ Parser .tokens .selectNext ()
609+ assign .children .append (Parser .parseOrexPR )
610+ Parser .tokens .selectNext ()
611+ if Parser .tokens .actual .type != "CLS" :
612+ raise Exception (") NOT FUND in FCALL" )
613+ Parser .tokens .selectNext ()
614+ if Parser .tokens .actual .type != "ENDCOM" :
615+ raise Exception ("; NOT FOUND in FCALL" )
616+ Parser .tokens .selectNext ()
499617 else :
500618 raise Exception ("COMMAND ERROR" )
501-
502619 return assign
503620
504621 elif Parser .tokens .actual .type == "TYPE" :
@@ -515,9 +632,6 @@ def parseCommand():
515632 raise Exception ("FIRST ASSIGN ERROR" )
516633 return firstAssign
517634
518-
519-
520-
521635 elif Parser .tokens .actual .type == "PRINT" :
522636 print_node = Println ("PRINT" , [])
523637 print_value = Parser .parseOrexPR ()
@@ -527,6 +641,15 @@ def parseCommand():
527641 Parser .tokens .selectNext ()
528642 return print_node
529643
644+ elif Parser .tokens .actual .type == "RETURN" :
645+ Parser .tokens .selectNext ()
646+ retNode = ReturnVal (Parser .parseOrexPR )
647+ Parser .tokens .selectNext ()
648+ if Parser .tokens .actual .type != "ENDCOM" :
649+ raise Exception ("; NOT FOUND" )
650+ Parser .tokens .selectNext ()
651+ return retNode
652+
530653 elif Parser .tokens .actual .type == "WHILE" :
531654 while_node = WhileOp ('while' , [])
532655 Parser .tokens .selectNext ()
@@ -571,10 +694,15 @@ def run(code):
571694 #executa o compilador
572695 Parser .tokens = Parser ().tokens (origin = code )
573696 Parser .tokens .selectNext ()
574- res = Parser ().parseBlock ()
697+ res = Parser ().parseFuncDefBlock ()
698+ ST = SymbolTable ()
699+ for funcs in res :
700+ funcs .Evaluate (ST )
701+ # print(ST.functions)
702+
575703 if (Parser .tokens .actual .type != "END" ):
576704 raise Exception ("ERROR" )
577- return res
705+ return ST
578706
579707
580708
@@ -586,9 +714,8 @@ def main():
586714 file += sys .argv [i ]
587715 f = open (file ,'r' )
588716 comando = f .read ()
589- resultado = Parser ().run (comando )
590- ST = SymbolTable ()
591- resultado .Evaluate (ST )
717+ ST = Parser ().run (comando )
718+ FuncCall ("main" ,[]).Evaluate (ST )
592719
593720if __name__ == "__main__" :
594721 main ()
0 commit comments