-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMain.hs
More file actions
143 lines (130 loc) · 4.27 KB
/
Main.hs
File metadata and controls
143 lines (130 loc) · 4.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
{-
- Projeto do interpretador para a linguagem C++
-}
{-
-
-}
module Main where
import IO
import Variavel
import Mensagens
import Funcao
import Expressao
import Lexico
import Char
import System.IO.Unsafe -- unsafePerformIO
-- Lê um arquivo de código-fonte C++ e executa sua função 'main'.
main :: String -> IO ()
main nomeDoArquivo =
putStr (programa (unsafePerformIO (leitura nomeDoArquivo)) [] [])
-- Lê uma string com lexemas e executa suas instruções.
programa :: String -> [Variavel] -> [Funcao] -> String
programa fonte variaveis funcoes =
let tmp = fonte in
let (lexema, fonte) = getProxLexema tmp in
if elem lexema tipos then
let tipo = lexema in
let tmp = fonte in
let (lexema, fonte) = getProxLexema tmp in
if isIdValido lexema [] funcoes tipos then
let id = lexema in
let tmp = fonte in
let (lexema, fonte) = getProxLexema tmp in
if lexema == "(" then
let idFuncao = id ; tmp = fonte in
let (argumentosFunc, fonte) = argumentosFuncao tmp idFuncao variaveis funcoes in
let tmp = fonte in
let (lexema, fonte) = getProxLexema tmp in
if lexema == "{" then
let tmp = fonte in
let (instrucoes, fonte) = instrucoesFuncao tmp [] 0 in
let funcao = ( idFuncao, (stringToTipo tipo), argumentosFunc, instrucoes ) in
programa fonte variaveis (funcoes ++ [funcao])
else
exibeMsgErro (lexemaInesperadoEsperado lexema "{")
else
exibeMsgErro (lexemaInesperadoEsperado lexema "(")
else
exibeMsgErro (idInvalido lexema)
else if lexema == "" then
let (status, main) =
findFuncaoByNome funcoes "main" in
if status == True then
if equalsTipo (getRetornoFuncao main) Void then
let saida = executaFuncao main [] funcoes in
saida
else
exibeMsgErro (mainRetornaVoid)
else
exibeMsgErro (mainNaoEncontrada)
else
exibeMsgErro (tipoInvalido lexema)
-- Lê os argumentos da declaração da função até encontrar um ')'.
-- Exemplo: argumentosFuncao "int x, int b)" "" [] []
argumentosFuncao :: String -> String -> [Variavel] -> [Funcao] -> ([Variavel], String)
argumentosFuncao fonte escopo variaveisGlobais funcoes =
let tmp = fonte in
let (lexema, fonte) = getProxLexema tmp in
if lexema == ")" then
([], fonte)
else if elem lexema tiposVar then
let tipoArg = lexema ; tmp = fonte in
let (lexema, fonte) = getProxLexema tmp in
if isIdValido lexema variaveisGlobais funcoes tipos then
let idArg = lexema ; valorArg = stringToValor tipoArg in
let argumento = (idArg, valorArg, escopo) in
argumentosFuncaoRecur [argumento] fonte escopo variaveisGlobais funcoes
else
exibeMsgErro (idInvalido lexema)
else
exibeMsgErro (lexemaInesperado lexema)
-- Auxiliar recursiva para a função 'argumentosFuncao'.
argumentosFuncaoRecur :: [Variavel] -> String -> String -> [Variavel] ->
[Funcao] ->([Variavel], String)
argumentosFuncaoRecur argumentos fonte escopo variaveisGlobais funcoes =
let tmp = fonte in
let (lexema, fonte) = getProxLexema tmp in
if lexema == ")" then
(argumentos, fonte)
else if lexema == "," then
let tmp = fonte in
let (lexema, fonte) = getProxLexema tmp in
if elem lexema tiposVar then
let tipo = lexema ; tmp = fonte in
let (lexema, fonte) = getProxLexema tmp in
if isIdValido lexema argumentos [] tipos then
let id = lexema ; valor = stringToValor tipo in
let argumento = (id, valor, escopo) in
argumentosFuncaoRecur
(argumentos ++ [argumento])
(fonte)
(escopo)
(variaveisGlobais)
(funcoes)
else
exibeMsgErro (idInvalido lexema)
else
exibeMsgErro (tipoInvalido lexema)
else
exibeMsgErro (lexemaInesperado lexema)
{-
- Lê instrucoes da função e retorna a lista dos seus lexemas adicionando no final um "\0",
- que indica o final da lista.
- Casos de teste:
- instrucoesFuncao "int a; {}} ..." [] 0
-}
instrucoesFuncao :: String -> [String] -> Int -> ([String], String)
instrucoesFuncao fonte lexemas n =
let tmp = fonte in
let (lexema, fonte) = getProxLexema tmp in
if lexema == "" then
exibeMsgErro (funcaoNaoTerminada)
else if lexema == "}" then
if n == 0 then
(lexemas ++["\0"], fonte)
else
instrucoesFuncao fonte ( lexemas ++ [lexema] ) (n - 1)
else if lexema == "{" then
instrucoesFuncao fonte ( lexemas ++ [lexema] ) (n + 1)
else
instrucoesFuncao fonte ( lexemas ++ [lexema] ) n