diff --git a/calculadora/calc b/calculadora/calc
new file mode 100755
index 0000000000000000000000000000000000000000..8d7a4dac79d6762c834c6c3a97b70f9067d60434
Binary files /dev/null and b/calculadora/calc differ
diff --git a/calculadora/calculadora.c b/calculadora/calculadora.c
new file mode 100644
index 0000000000000000000000000000000000000000..02b4363baec33b9fb524e0df8ca2f67c73698906
--- /dev/null
+++ b/calculadora/calculadora.c
@@ -0,0 +1,243 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include "libpilha.h"
+
+typedef double t_operador;
+
+#define TAM_ENTRADA 256
+#define TAM_PILHA 1024
+
+
+/* Constantes com valores para identificar os operadores. O valor 
+   antes do ponto flutuante difine a precedencia entre os operadores, 
+   valores maiores tem maior precedencia. */
+#define SOM 10.1
+#define SUB 10.2
+#define MUL 20.1
+#define DIV 20.2
+
+
+/* Identificador de '(' para ser empilhado na pilha de operadores */
+#define PAR 99.0
+
+
+/* Converte os caracteres que representam os operadores na entrada
+   para valores constantes que identificam os operadores. 
+   Retorna 1 se o caracter c representa um operador valido e 0 caso
+   contrario. */
+int converte_operador(t_operador *op, char c) {
+    switch(c) {
+		case '+': *op = SOM; break;
+		case '-': *op = SUB; break;
+		case '*': *op = MUL; break;
+		case '/': *op = DIV; break;
+		default : return 0;
+	}
+    return 1;
+}
+
+
+/* Retorna 1 se o operador op1 tem precedencia sobre o operador op2.
+   Retorna 0 caso contrario. */
+int precede(t_operador op1, t_operador op2) {
+    if((op1 - op2) >= 1.0)
+        return 1;
+    return 0;
+}
+
+
+/* Desempilha os dois valores no topo da pilha de valores, aplica o
+   operador sobre esses valores e empilha o resultado na pilha de 
+   valores. */
+int opera(t_operador op, t_pilha *valores) {
+    double val_esq, val_dir;
+
+    if(!desempilha(&val_dir, valores))
+        return 0;
+    if(!desempilha(&val_esq, valores))
+        return 0;
+    if(op == SOM)
+        return empilha(val_esq + val_dir, valores);
+    if(op == SUB)
+        return empilha(val_esq - val_dir, valores);
+    if(op == MUL)
+        return empilha(val_esq * val_dir, valores);
+    if(op == DIV && val_dir != 0.0)
+        return empilha(val_esq / val_dir, valores);
+    return 0;
+}
+
+
+/* Imprime na saida de erro (stderr) a mensagem de erro e a linha e 
+   a coluna da entrada onde o erro foi detectado. */
+void erro_aborta(char *msg, int col) {
+    fprintf(stderr, "ERRO: %s (coluna %d)\n", msg, col);
+    exit(1);
+}
+
+
+/* Le da entrada padrao, usando fgets, um vetor de caracteres ate o \n.
+   Se o tamanho da entrada for maior que o vetor de leitura, aumenta
+   o tamanho do vetor e continua a leitura ate encontrar o \n.
+   Retorna um ponteiro para o vetor lido ou NULL caso ocorra algum erro
+   ne leitura ou ne alocação de memoria. */
+/*
+char* le_entrada() {
+    char *ent, *ret_realloc, *ret_fgets;
+    int tam, pos;
+
+    ent = NULL;
+    tam = 0;
+    pos = 0;
+    
+    do {
+        tam += TAM_ENTRADA;
+        ret_realloc = (char*) realloc(ent, sizeof(char) * tam);
+        if(!ret_realloc) {
+            free(ent);
+            return NULL;
+        }
+        ent = ret_realloc;
+        ent[tam - 1] = ' ';
+        ret_fgets = fgets(ent + pos, tam - pos, stdin);
+        pos = tam - 1;    
+    } while(ret_fgets && ent[tam - 1] == '\0' && ent[tam - 2] != '\n');
+    
+    if(!ret_fgets && tam == TAM_ENTRADA) {
+        free(ent);
+        return NULL;
+    }
+    
+    return ent;
+}
+*/
+
+
+/* Le da entrada padrao, usando fgets, um vetor de caracteres ate o \n.
+   Retorna um ponteiro para o vetor lido ou NULL caso ocorra algum erro
+   ne leitura ou na alocação de memoria. Se o tamanho da entrada for 
+   maior que o vetor de leitura, retorna NULL. */
+char* le_entrada() {
+    char *ent, *ret_fgets;
+    int tam;
+    
+    tam = TAM_ENTRADA;
+    ent = (char*) malloc(sizeof(char) * tam);
+    if(!ent)
+        return NULL;
+    ent[tam - 1] = ' ';
+    ret_fgets = fgets(ent, tam, stdin);
+    if(!ret_fgets || (ent[tam - 1] == '\0' && ent[tam - 2] != '\n')) {
+        free(ent);
+        return NULL;
+    }
+    return ent;
+}
+
+
+int main() {
+    t_pilha *pilha_valores, *pilha_operadores;
+    t_operador operador, op_topo;
+    double operando, resultado;
+    char *entrada, *c, *prox;
+
+    pilha_valores = cria_pilha(TAM_PILHA);
+    if(!pilha_valores)
+        erro_aborta("erro ao criar pilha de valores", 0);
+
+    pilha_operadores = cria_pilha(TAM_PILHA);
+    if(!pilha_operadores)
+        erro_aborta("erro ao criar pilha de operadores", 0);
+
+    entrada = le_entrada();
+    if(!entrada)
+        erro_aborta("erro de leitura", 0);
+
+    c = entrada;
+    while(*c != '\n') {
+        /* Percorre o ponteiro c pela entrada ate o final de linha. */
+
+        /* Caso 1: separadores */
+        if(*c == ' ' || *c == '\t')
+            /* Se for sepador, passa para o proximo caracter. */
+            c++;
+
+        /* Caso 2: operando */
+        else if(isdigit(*c)) {
+            /* Se for [1..9] le um valor e empilha na pilha de valores. */
+            operando = strtod(c, &prox);
+            if(c == prox)
+                erro_aborta("operando incorreto", c - entrada + 1);
+            if(!empilha(operando, pilha_valores))
+                erro_aborta("pilha de valores cheia", c - entrada + 1);
+            c = prox;
+        }
+
+        /* Caso 3: abre parenteses */
+        else if(*c == '(') {
+            /* Se for abre parenteses, empilha PAR na pilha de operadores. */
+            if(!empilha(PAR, pilha_operadores))
+                erro_aborta("pilha de operadores cheia", c - entrada + 1);
+            c++;
+        }
+
+        /* Caso 4: fecha parenteses */
+        else if(*c == ')') {
+            /* Se for fecha parenteses, processa a pilha de operadores até 
+               encontar um PAR. */ 
+            while(topo(&op_topo, pilha_operadores) && op_topo != PAR) {
+                desempilha(&op_topo, pilha_operadores);
+                if(!opera(op_topo, pilha_valores))
+                    erro_aborta("formato incorreto", c - entrada + 1);
+            }
+            if(pilha_vazia(pilha_operadores) ||
+               (desempilha(&op_topo, pilha_operadores) && op_topo != PAR))
+                erro_aborta("formato incorreto", c - entrada + 1);
+            c++;
+        }
+
+        /* Caso 5: operador */
+        else if(converte_operador(&operador, *c)) {
+            /* Se for um operador valido, verifica a precedencia em relacao
+               ao topo da pilha de operadores. */
+            while(topo(&op_topo, pilha_operadores) &&
+                  op_topo != PAR &&
+                  precede(op_topo, operador)) {
+                /* Enquando o topo da pilha tiver precedencia, desempilha e
+                   processa o operador do topo da pilha. */
+                desempilha(&op_topo, pilha_operadores);
+                if(!opera(op_topo, pilha_valores))
+                    erro_aborta("formato incorreto", c - entrada + 1);
+            }
+            if(!empilha(operador, pilha_operadores))
+                /* Empilha o novo operador na pilha de operadores. */
+                erro_aborta("pilha de operadores cheia", c - entrada + 1);
+            c++;
+        }
+
+        /* Caso 6: caracter invalido na entrada */
+        else
+            erro_aborta("caracter desconhecido", c - entrada + 1);
+    }
+
+    /* Nesse ponto o processamento da entrada terminou e pode ser o caso da 
+       pilha de operadores nao estar vazia. */
+    while(desempilha(&op_topo, pilha_operadores)) {
+        /* Processa os operadores que restaram na pilha. */
+        if(!opera(op_topo, pilha_valores))
+            erro_aborta("formato incorreto", c - entrada + 1);
+    }
+
+    /* Após o processamento, o resultado final da expressao esta no topo da 
+       pilha de valores. */
+    if(!desempilha(&resultado, pilha_valores))
+        erro_aborta("formato incorreto", c - entrada + 1);
+    printf("%.16g\n", resultado);
+
+    destroi_pilha(pilha_valores);
+    destroi_pilha(pilha_operadores);
+    free(entrada);
+
+    return 0;
+}
diff --git a/calculadora/libpilha.c b/calculadora/libpilha.c
new file mode 100644
index 0000000000000000000000000000000000000000..9a4384276a3728ac24e2c819daf60be2b33b76b9
--- /dev/null
+++ b/calculadora/libpilha.c
@@ -0,0 +1,49 @@
+#include <stdlib.h>
+#include "libpilha.h"
+
+t_pilha* cria_pilha(int n) {
+	t_pilha *p;
+	if ( !(p = malloc(sizeof(t_pilha) * n)) )
+		return NULL;
+
+	p->tam = n;
+	p->topo = -1;
+	
+	if ( !(p->v = malloc(sizeof(double) * n)) )
+		return NULL;
+	return p;
+}
+
+t_pilha* destroi_pilha(t_pilha *p) {
+	free(p->v);
+	free(p);
+	return NULL;
+}
+
+int pilha_vazia(t_pilha *p) {
+	return p->topo == -1;
+}
+
+int empilha(double x, t_pilha *p) {
+	if (p->topo == p->tam)
+		return 0;
+	p->topo++;
+	p->v[p->topo] = x;
+
+	return 1;
+}
+
+int desempilha(double *t, t_pilha *p) {
+	if (pilha_vazia(p))
+		return 0;
+	*t = p->v[p->topo];
+	p->topo--;
+	return 1;
+}
+
+int topo(double *t, t_pilha *p) {
+	if (pilha_vazia(p))
+		return 0;
+	*t = p->v[p->topo];
+	return 1;
+}
diff --git a/calculadora/libpilha.h b/calculadora/libpilha.h
new file mode 100644
index 0000000000000000000000000000000000000000..3eddf49979b0408d6af3501820e64e36c97d6a9b
--- /dev/null
+++ b/calculadora/libpilha.h
@@ -0,0 +1,31 @@
+struct s_pilha {
+    int tam;
+    int topo;
+    double *v;
+};
+typedef struct s_pilha t_pilha;
+
+
+/* Cria uma pilha com espaço para n elementos do tipo double. 
+   Retorna um ponteiro para a pilha ou NULL em caso de erro na 
+   alocacao de memoria. */
+t_pilha* cria_pilha(int n);
+
+/* Desaloca a memoria usada pela pilha e retorna NULL */
+t_pilha* destroi_pilha(t_pilha *p);
+
+/* Retorna 1 se a pilha p esta vazia e 0 caso contrario. */
+int pilha_vazia(t_pilha *p);
+
+/* Empilha o double x na pilha p. Retorna 1 se a operacao foi 
+   realizada com sucesso e 0 caso contrario. */
+int empilha(double x, t_pilha *p);
+
+/* Retorna em t o elemento do topo da pilha e o desempilha. A funcao 
+   retorna 1 se a operacao foi bem sucedida e 0 caso contrario. */
+int desempilha(double *t, t_pilha *p);
+
+/* Retorna em t o elemento do topo da pilha, sem desempilhar. 
+   A funcao retorna 1 se a operacao foi bem sucedida e 0 caso 
+   contrario.   */
+int topo(double *t, t_pilha *p);
diff --git a/calculadora/makefile b/calculadora/makefile
new file mode 100644
index 0000000000000000000000000000000000000000..0031aa354f97e35fbdaa2a9de557021582482f5f
--- /dev/null
+++ b/calculadora/makefile
@@ -0,0 +1,14 @@
+CC = gcc
+CFLAGS = -Wall -g -std=c90
+
+calc: calculadora.o libpilha.o
+	$(CC) calculadora.o libpilha.o -o calc
+
+calculadora.o : libpilha.h calculadora.c	
+	$(CC) $(CFLAGS) -c calculadora.c
+
+libpilha.o : libpilha.h libpilha.c
+	$(CC) $(CFLAGS) -c libpilha.c
+
+clean :
+	rm -f *.o