-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstack.c
79 lines (66 loc) · 2.7 KB
/
stack.c
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
/** @file Ficheiro que contém as funcionalidades relativas a stack */
#include <stdio.h>
#include <stdlib.h>
#include "stack.h"
int has_type(DATA elem, int mask) {
return (elem.type & mask) != 0;
}
STACK* create_stack () {
STACK *s = malloc(sizeof(STACK));
s->pos = -1; // -1 -> posição inicial: representa que a stack que está vazia
s->size = 128; // Definimos um tamanho inicial para a stack e aumentamos conforme seja preciso
s->stack = malloc(sizeof(DATA) * s->size);
return s;
}
void push(STACK *s, DATA elem) {
if (s->pos == s->size - 1) { // Se a stack estiver cheia, aumentamos ela
s->size *= 2; // assim enquanto houver espaço na nossa memória física, há espaço na stack
s->stack = realloc(s->stack, sizeof(DATA) * s->size);
}
s->stack[++s->pos] = elem;
}
DATA pop(STACK *s) {
if (s->pos != -1)
return s->stack[s->pos--];
return s->stack[s->pos];
}
DATA top (STACK *s) {
return s->stack[s->pos];
}
void push_unary_operation(STACK *s, double val) {
if (s->stack[s->pos + 1].type == DOUBLE) {push_DOUBLE(s, val); return;}
if (s->stack[s->pos + 1].type == INT) {push_INT(s, val); return;}
push_CHAR(s, val);
}
void push_binary_operation(STACK *s, long double val) {
if (s->stack[s->pos + 1].type == DOUBLE || s->stack[s->pos + 2].type == DOUBLE) {
push_DOUBLE(s, val); return;}
push_INT(s, val);
}
long double pop_operand(STACK *s) { // O double consegue armazenar os três tipos, sem trocar o valor do elemento
DATA elem = pop(s);
if (elem.type == INT) return elem.INT;
if (elem.type == DOUBLE) return elem.DOUBLE;
return elem.CHAR;
}
/**
* \brief macro para push's e pop's dos tipos de dados
* a macro define funções push e pop do tipo
* INT, DOUBLE, CHAR, STRING
*/
#define STACK_OPERATION(_type, _name) \
void push_##_name(STACK *s, _type val) { \
DATA elem; \
elem.type = _name; \
elem._name = val; \
push(s, elem); \
} \
_type pop_##_name(STACK *s) { \
DATA elem = pop(s); \
return elem._name; \
}
STACK_OPERATION(long, INT)
STACK_OPERATION(double, DOUBLE)
STACK_OPERATION(char, CHAR)
STACK_OPERATION(char *, STRING)
STACK_OPERATION(char *, BLOCK)