Skip to content

Commit

Permalink
Questão 3 - Pronta
Browse files Browse the repository at this point in the history
  • Loading branch information
LSinzker committed May 9, 2017
1 parent 34e3990 commit 3ad7361
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 97 deletions.
97 changes: 0 additions & 97 deletions LFLE01E2.0.hs

This file was deleted.

67 changes: 67 additions & 0 deletions LFLE02E.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
module LFLE02E where

-- A linguagem LFLE02 suporta tanto
-- expressoes identificadas (LET) quanto
-- identificadores e expressoes + funcoes.
-- As funcoes aceitam apenas um argumento
-- sem informacoes de tipo.
--
-- As substituicoes sao realizadas de maneira
-- postergadas! Essa eh a principal diferenca
-- desta versao para a disponibilizada na
-- linguagem LFLE01
--

type Id = String
type Nome = String
type Arg = String

type Ambiente = [DecFuncao]

type Referencias = [(Id, Int)]

data DecFuncao = DecFuncao Nome Arg Expressao

data Expressao = Valor Int
| Soma Expressao Expressao
| Subtracao Expressao Expressao
| Multiplicacao Expressao Expressao
| Divisao Expressao Expressao
| Let Id Expressao Expressao
| Ref Id
| Aplicacao Nome Expressao
deriving(Show, Eq)

-- O interpretador da linguagem LLE eh
-- basicamente um avaliador de expressoes, mas
-- com suporte a substituicao.

avaliar :: Expressao -> Ambiente -> Referencias -> Int
avaliar (Valor n) _ _ = n
avaliar (Soma e d) amb ref = avaliar e amb ref + avaliar d amb ref
avaliar (Subtracao e d) amb ref = avaliar e amb ref - avaliar d amb ref
avaliar (Multiplicacao e d) amb ref = avaliar e amb ref * avaliar d amb ref
avaliar (Divisao e d) amb ref = avaliar e amb ref `div` avaliar d amb ref
avaliar (Aplicacao nome exp) amb ref = avaliar corpo amb ref'
where
(DecFuncao n arg corpo) = pesquisarFuncao nome amb
valor = avaliar exp amb ref
ref' = (arg, valor):ref
avaliar (Let subId expNomeada corpoExp) amb ref = avaliar corpoExp amb ref'
where
valor = avaliar expNomeada amb ref
ref' = ref ++ [(subId, valor)]

avaliar (Ref var) amb ref = pesquisarValor var ref

pesquisarFuncao :: Nome -> Ambiente -> DecFuncao
pesquisarFuncao nome [] = error ("Funcao " ++ nome ++ " nao declarada")
pesquisarFuncao nome (dec@(DecFuncao n a e):xs)
| nome == n = dec
| otherwise = pesquisarFuncao nome xs

pesquisarValor :: Nome -> Referencias -> Int
pesquisarValor n [] = error ("identificador " ++ n ++ " nao declarado")
pesquisarValor nome ((n, v):rs)
| nome == n = v
| otherwise = pesquisarValor nome rs
64 changes: 64 additions & 0 deletions LFLE2ETestes.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
module LFLETestes where

import LFLE02E

import Test.HUnit

inc :: DecFuncao
inc = DecFuncao "inc" "x" (Soma (Ref "x") (Valor 1))

sqr :: DecFuncao
sqr = DecFuncao "sqr" "x" (Multiplicacao (Ref "x") (Ref "x"))

f :: DecFuncao
f = DecFuncao "f" "p" (Ref "n")

app1 :: Expressao
app1 = Aplicacao "inc" (Valor 5)

app2 :: Expressao
app2 = Aplicacao "sqr" (Valor 5)

let1 :: Expressao
let1 = Let "x" (Valor 5) (Soma (Ref "x") (Ref "x"))

let2 :: Expressao
let2 = Let "x" (Valor 10) (Aplicacao "sqr" (Ref "x"))

let3 :: Expressao
let3 = Let "n" (Valor 5) (Aplicacao "f" (Valor 10))

let4 :: Expressao
let4 = Let "x" (Valor 10) (Soma (Ref "x") (Let "x" (Valor 5) (Soma (Ref "x") (Valor 8))))

let5 :: Expressao
let5 = Let "x" (Valor 10)
(Soma (Let "x" (Valor 5) (Soma (Ref "x") (Valor 8))) (Ref "x"))


amb = [inc, sqr, f]

testeInc = TestCase (assertEqual "avaliar inc 5" 6 (avaliar app1 amb []))

testeSqr = TestCase (assertEqual "avaliar sqr 5" 25 (avaliar app2 amb []))

testeLet1 = TestCase (assertEqual "avaliar let x = 5 in x + x" 10 (avaliar let1 [] []))

testeLet2 = TestCase (assertEqual "avaliar let x = 10 in sqr x)" 100 (avaliar let2 amb []))

testeLet3 = TestCase (assertEqual "avaliar let n = 5 in f 10)" 5 (avaliar let3 amb []))

testeLet4 = TestCase (assertEqual "avaliar let x = 10 in x + (let x = 5 in x + 8)" 28
(avaliar let4 [] []))

testeLet5 = TestCase (assertEqual "avaliar let x = 10 in (let x = 5 in x + 8) + x" 28
(avaliar let5 [] []))

todosOsTestes = TestList [ testeInc
, testeSqr
, testeLet1
, testeLet2
, testeLet3
]

executarTestes = runTestTT todosOsTestes

0 comments on commit 3ad7361

Please sign in to comment.