├── testes_ptg ├── saida.h ├── quadruplas.h ├── testeerror.ptg ├── teste1.ptg ├── teste2.ptg ├── teste3.ptg ├── teste4.ptg ├── teste6.ptg ├── teste1.asm.c ├── teste5.ptg ├── teste7.ptg ├── teste10.ptg ├── teste9.ptg ├── teste1.c ├── teste2.c ├── teste8.ptg ├── testeerror.c ├── teste3.c ├── teste4.c ├── teste5.c ├── testese.ptg ├── teste6.c ├── teste10.c ├── teste7.asm.c ├── teste7.c ├── testese.asm.c ├── teste9.c ├── teste8.c ├── teste-tudo.ptg └── teste-tudo.asm.c ├── AUTHORS ├── compila.sh ├── saida.h ├── ptg-quad.sh ├── .github ├── PULL_REQUEST_TEMPLATE.md ├── ISSUE_TEMPLATE.md ├── BECOSYSTEMS_CODE_OF_CONDUCT.md └── CONTRIBUTING.md ├── flexyagcc.sh ├── portugol.h ├── y.tab.h ├── README.md ├── ptg.xml ├── portugol.l ├── quadruplas-v2a.h ├── portugol.y ├── LICENSE ├── quadruplas.h └── portugol.c /testes_ptg/saida.h: -------------------------------------------------------------------------------- 1 | ../saida.h -------------------------------------------------------------------------------- /testes_ptg/quadruplas.h: -------------------------------------------------------------------------------- 1 | ../quadruplas.h -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | == Author == 2 | 3 | Prof. Dr. Ruben Carlo Benante, @drbeco 4 | Email: rcb@beco.cc 5 | Site: www.beco.cc 6 | 7 | -------------------------------------------------------------------------------- /testes_ptg/testeerror.ptg: -------------------------------------------------------------------------------- 1 | //comentario 2 | inicio; 3 | imprima A; 4 | imprima B; //erro b minusculo corrigido 5 | imprima C; 6 | imprima d; //erro d minusculo 7 | imprima E; 8 | fim; 9 | 10 | -------------------------------------------------------------------------------- /testes_ptg/teste1.ptg: -------------------------------------------------------------------------------- 1 | // Compilador PORTUGOL v.1.0 2 | // Autor: Ruben Carlo Benante 3 | // Email: benante@gmail.com 4 | // Data: 23/04/2009 5 | // 6 | // Menor programa 7 | 8 | inicio; 9 | ; 10 | fim; -------------------------------------------------------------------------------- /testes_ptg/teste2.ptg: -------------------------------------------------------------------------------- 1 | // Compilador PORTUGOL v.1.0 2 | // Autor: Ruben Carlo Benante 3 | // Email: benante@gmail.com 4 | // Data: 23/04/2009 5 | // 6 | // imprima constante 7 | 8 | inicio; 9 | imprima 5.0; 10 | fim; -------------------------------------------------------------------------------- /testes_ptg/teste3.ptg: -------------------------------------------------------------------------------- 1 | // Compilador PORTUGOL v.1.0 2 | // Autor: Ruben Carlo Benante 3 | // Email: benante@gmail.com 4 | // Data: 23/04/2009 5 | // 6 | // uso de variaveis 7 | 8 | inicio; 9 | A=1.0; 10 | imprima A; 11 | fim; -------------------------------------------------------------------------------- /testes_ptg/teste4.ptg: -------------------------------------------------------------------------------- 1 | // Compilador PORTUGOL v.1.0 2 | // Autor: Ruben Carlo Benante 3 | // Email: benante@gmail.com 4 | // Data: 23/04/2009 5 | // 6 | // comando se-entao 7 | 8 | inicio; 9 | A=1.0; 10 | se(A==0) entao imprima 57.8; 11 | imprima A; 12 | fim; -------------------------------------------------------------------------------- /testes_ptg/teste6.ptg: -------------------------------------------------------------------------------- 1 | // Compilador PORTUGOL v.1.0 2 | // Autor: Ruben Carlo Benante 3 | // Email: benante@gmail.com 4 | // Data: 23/04/2009 5 | // 6 | // expressoes 7 | 8 | inicio; 9 | A=1.0; 10 | B=-1.3; 11 | C=1.0/(A*(B+3.0)-10.0); 12 | imprima A+B-2*C; 13 | fim; -------------------------------------------------------------------------------- /testes_ptg/teste1.asm.c: -------------------------------------------------------------------------------- 1 | // Gerado pelo compilador PORTUGOL versao 1q 2 | // Autor: Ruben Carlo Benante 3 | // Email: benante@gmail.com 4 | // Data: 23/04/2009 5 | 6 | #include "quadruplas.h" 7 | 8 | int main(void) 9 | { 10 | nop(NULL,NULL,NULL); 11 | } 12 | -------------------------------------------------------------------------------- /testes_ptg/teste5.ptg: -------------------------------------------------------------------------------- 1 | // Compilador PORTUGOL v.1.0 2 | // Autor: Ruben Carlo Benante 3 | // Email: benante@gmail.com 4 | // Data: 23/04/2009 5 | // 6 | // comando se-entao-senao 7 | 8 | inicio; 9 | A=1.0; 10 | se(A<2.0) entao 11 | imprima 57.8; 12 | senao 13 | imprima 0.0; 14 | fim; -------------------------------------------------------------------------------- /testes_ptg/teste7.ptg: -------------------------------------------------------------------------------- 1 | // Compilador PORTUGOL v.1.0 2 | // Autor: Ruben Carlo Benante 3 | // Email: benante@gmail.com 4 | // Data: 23/04/2009 5 | // 6 | // bloco de comandos 7 | 8 | inicio; 9 | A=1.0; 10 | B=2.0; 11 | C=3.0; 12 | se(A!=1.0) entao 13 | inicio; 14 | imprima A; 15 | imprima B; 16 | fim; 17 | imprima C; 18 | fim; -------------------------------------------------------------------------------- /testes_ptg/teste10.ptg: -------------------------------------------------------------------------------- 1 | // Compilador PORTUGOL v.1.0 2 | // Autor: Ruben Carlo Benante 3 | // Email: benante@gmail.com 4 | // Data: 23/04/2009 5 | // 6 | // ambiguidade do se-entao-senao 7 | 8 | inicio; 9 | A=1.0; //atribuir 1.0 para A 10 | B=2.0; //atribuir 2.0 para B 11 | se(A==1.0) entao se(B==2.0) entao imprima B; senao imprima X; 12 | fim; -------------------------------------------------------------------------------- /compila.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Compila o Portugol1, com lex e yacc 3 | #/* 4 | # Compilador PORTUGOL v.1.0 5 | # Autor: Ruben Carlo Benante 6 | # Email: benante@gmail.com 7 | # Data: 23/04/2009 8 | #*/ 9 | 10 | flex $1.l 11 | yacc -d $1.y 12 | gcc -o $1.bin y.tab.c lex.yy.c $1.c 13 | #./$1.bin teste1.ptg > teste1.c 14 | #gcc -o teste1.bin teste1.c 15 | #./teste1.bin 16 | -------------------------------------------------------------------------------- /testes_ptg/teste9.ptg: -------------------------------------------------------------------------------- 1 | // Compilador PORTUGOL v.1.0 2 | // Autor: Ruben Carlo Benante 3 | // Email: benante@gmail.com 4 | // Data: 23/04/2009 5 | // 6 | // operadores logicos 7 | 8 | inicio; 9 | A=1.0; 10 | B=2.0; 11 | C=3.0; 12 | se(A==1.0 ou B!=2.0 e C==3.0) entao 13 | imprima 111.1; 14 | senao 15 | inicio; 16 | imprima C; 17 | se(nao (A==2 e B==3.0)) entao 18 | imprima 222.2; 19 | fim; 20 | fim; -------------------------------------------------------------------------------- /testes_ptg/teste1.c: -------------------------------------------------------------------------------- 1 | // Gerado pelo compilador PORTUGOL versao 1.0 2 | // Autor: Ruben Carlo Benante 3 | // Email: benante@gmail.com 4 | // Data: 23/04/2009 5 | 6 | #include 7 | #include 8 | 9 | float var[26] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; 10 | 11 | int main(void) 12 | { 13 | ; 14 | } 15 | -------------------------------------------------------------------------------- /testes_ptg/teste2.c: -------------------------------------------------------------------------------- 1 | // Gerado pelo compilador PORTUGOL versao 1.0 2 | // Autor: Ruben Carlo Benante 3 | // Email: benante@gmail.com 4 | // Data: 23/04/2009 5 | 6 | #include 7 | #include 8 | 9 | float var[26] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; 10 | 11 | int main(void) 12 | { 13 | printf("5.00\n"); 14 | } 15 | -------------------------------------------------------------------------------- /testes_ptg/teste8.ptg: -------------------------------------------------------------------------------- 1 | // Compilador PORTUGOL v.1.0 2 | // Autor: Ruben Carlo Benante 3 | // Email: benante@gmail.com 4 | // Data: 23/04/2009 5 | // 6 | // bloco de comandos 7 | 8 | inicio; 9 | A=1.0; 10 | B=2.0; 11 | C=3.0; 12 | se(A!=1.0) entao 13 | inicio; 14 | imprima A; 15 | imprima B; 16 | fim; 17 | senao 18 | inicio; 19 | A=A+1.0; 20 | imprima 113.0; 21 | imprima A; 22 | fim; 23 | imprima C; 24 | fim; -------------------------------------------------------------------------------- /testes_ptg/testeerror.c: -------------------------------------------------------------------------------- 1 | // Gerado pelo compilador PORTUGOL versao 1.1 2 | // Autor: Ruben Carlo Benante 3 | // Email: benante@gmail.com 4 | // Data: 23/04/2009 5 | 6 | #include 7 | #include 8 | 9 | float var[26] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; 10 | 11 | int main(void) 12 | // Falha! Programa em Portugol nao compilado. 13 | 14 | -------------------------------------------------------------------------------- /testes_ptg/teste3.c: -------------------------------------------------------------------------------- 1 | // Gerado pelo compilador PORTUGOL versao 1.0 2 | // Autor: Ruben Carlo Benante 3 | // Email: benante@gmail.com 4 | // Data: 23/04/2009 5 | 6 | #include 7 | #include 8 | 9 | float var[26] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; 10 | 11 | int main(void) 12 | { 13 | var[0] = 1.00; 14 | printf("%.2f\n", var[0]); 15 | } 16 | -------------------------------------------------------------------------------- /saida.h: -------------------------------------------------------------------------------- 1 | // Gerado pelo compilador Portugol versao 2q 2 | // Autor: Ruben Carlo Benante 3 | // Email: benante@gmail.com 4 | // Data: 23/05/2009 5 | 6 | #define MAX_TS 12 /* tabela de variaveis */ 7 | #define MAX_TC 26 /* tabela de constantes */ 8 | #define MAX_TP 32 /* tabela de temporarios */ 9 | 10 | #define MAX_TF 5 /* tabela de funcoes */ 11 | 12 | superTipo ts[MAX_TS]; 13 | superTipo tc[MAX_TC]; 14 | superTipo tp[MAX_TP]; 15 | superFunc tf[MAX_TF]; 16 | 17 | -------------------------------------------------------------------------------- /testes_ptg/teste4.c: -------------------------------------------------------------------------------- 1 | // Gerado pelo compilador PORTUGOL versao 1.0 2 | // Autor: Ruben Carlo Benante 3 | // Email: benante@gmail.com 4 | // Data: 23/04/2009 5 | 6 | #include 7 | #include 8 | 9 | float var[26] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; 10 | 11 | int main(void) 12 | { 13 | var[0] = 1.00; 14 | if(var[0] == 0.00) 15 | printf("57.80\n"); 16 | printf("%.2f\n", var[0]); 17 | } 18 | -------------------------------------------------------------------------------- /testes_ptg/teste5.c: -------------------------------------------------------------------------------- 1 | // Gerado pelo compilador PORTUGOL versao 1.0 2 | // Autor: Ruben Carlo Benante 3 | // Email: benante@gmail.com 4 | // Data: 23/04/2009 5 | 6 | #include 7 | #include 8 | 9 | float var[26] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; 10 | 11 | int main(void) 12 | { 13 | var[0] = 1.00; 14 | if(var[0] < 2.00) 15 | printf("57.80\n"); 16 | else 17 | printf("0.00\n"); 18 | } 19 | -------------------------------------------------------------------------------- /testes_ptg/testese.ptg: -------------------------------------------------------------------------------- 1 | // Compilador PORTUGOL v.2q 2 | // Autor: Ruben Carlo Benante 3 | // Email: benante@gmail.com 4 | // Data: 23/04/2009 5 | // 6 | // se-entao-senao 7 | 8 | #debug _TABELA 9 | 10 | inicio; //inicio 11 | int A; 12 | real O; 13 | texto S; 14 | int B; 15 | real P; 16 | 17 | A=1+1; //atribuicao inteira 18 | B=1; //repetindo a constante 19 | O=2.2; //atribuicao flutuante 20 | S="oi"; //atribuicao string 21 | ; 22 | B=A; 23 | P=O; 24 | ; 25 | imprima A; //inteiro 1 26 | se (A==1) entao 27 | imprima 2.2; 28 | senao 29 | imprima 1; 30 | ; 31 | fim; 32 | -------------------------------------------------------------------------------- /testes_ptg/teste6.c: -------------------------------------------------------------------------------- 1 | // Gerado pelo compilador PORTUGOL versao 1.0 2 | // Autor: Ruben Carlo Benante 3 | // Email: benante@gmail.com 4 | // Data: 23/04/2009 5 | 6 | #include 7 | #include 8 | 9 | float var[26] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; 10 | 11 | int main(void) 12 | { 13 | var[0] = 1.00; 14 | var[1] = -1.30; 15 | var[2] = 1.00 / ( var[0] * ( var[1] + 3.00 ) - 10.00 ); 16 | printf("%.2f\n", ( var[0] + var[1] - 2.00 * var[2] )); 17 | } 18 | -------------------------------------------------------------------------------- /testes_ptg/teste10.c: -------------------------------------------------------------------------------- 1 | // Gerado pelo compilador PORTUGOL versao 1.0 2 | // Autor: Ruben Carlo Benante 3 | // Email: benante@gmail.com 4 | // Data: 23/04/2009 5 | 6 | #include 7 | #include 8 | 9 | float var[26] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; 10 | 11 | int main(void) 12 | { 13 | var[0] = 1.00; 14 | var[1] = 2.00; 15 | if(var[0] == 1.00) 16 | if(var[1] == 2.00) 17 | printf("%.2f\n", var[1]); 18 | else 19 | printf("%.2f\n", var[23]); 20 | } 21 | -------------------------------------------------------------------------------- /testes_ptg/teste7.asm.c: -------------------------------------------------------------------------------- 1 | // Gerado pelo compilador PORTUGOL versao 1q 2 | // Autor: Ruben Carlo Benante 3 | // Email: benante@gmail.com 4 | // Data: 23/04/2009 5 | 6 | #include "quadruplas.h" 7 | 8 | int main(void) 9 | { 10 | mov(1.00,NULL,&ts[0]); 11 | mov(2.00,NULL,&ts[1]); 12 | mov(3.00,NULL,&ts[2]); 13 | comp_ne(ts[0],1.00,&temp[0]); 14 | jump_f(temp[0],NULL,l1); 15 | param(ts[0],NULL,NULL); 16 | call("imprima",1,NULL); 17 | param(ts[1],NULL,NULL); 18 | call("imprima",1,NULL); 19 | jump(NULL,NULL,l2); 20 | l1: 21 | l2: 22 | param(ts[2],NULL,NULL); 23 | call("imprima",1,NULL); 24 | } 25 | -------------------------------------------------------------------------------- /testes_ptg/teste7.c: -------------------------------------------------------------------------------- 1 | // Gerado pelo compilador PORTUGOL versao 1.1 2 | // Autor: Ruben Carlo Benante 3 | // Email: benante@gmail.com 4 | // Data: 23/04/2009 5 | 6 | #include 7 | #include 8 | 9 | float var[26] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; 10 | 11 | int main(void) 12 | { 13 | var[0] = 1.00; 14 | var[1] = 2.00; 15 | var[2] = 3.00; 16 | if(var[0] != 1.00) 17 | { 18 | printf("%.2f\n", var[0]); 19 | printf("%.2f\n", var[1]); 20 | } 21 | printf("%.2f\n", var[2]); 22 | } 23 | -------------------------------------------------------------------------------- /ptg-quad.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Compila com Portugol v2q e gera .asm.c e .asm.bin 3 | #/* 4 | # Autor: Ruben Carlo Benante 5 | # Email: benante@gmail.com 6 | # Data: 23/04/2009 7 | #*/ 8 | # 9 | # Exemplo: 10 | # ./ptg-v1q.sh teste1 11 | # 12 | # entrada: 13 | # teste1.ptg 14 | # arquivo em linguagem portugol 15 | # 16 | # saida: 17 | # teste1.asm.c 18 | # arquivo em quadruplas 19 | # 20 | # teste1.asm.bin 21 | # arquivo executavel 22 | 23 | echo portugol $1.ptg $1.asm.c 24 | ./portugol-v2q.bin $1.ptg $1.asm.c 25 | echo gcc $1.asm.c -o $1.asm.bin 26 | gcc $1.asm.c -o $1.asm.bin 27 | echo ./$1.asm.bin 28 | ./$1.asm.bin 29 | 30 | -------------------------------------------------------------------------------- /testes_ptg/testese.asm.c: -------------------------------------------------------------------------------- 1 | // Gerado pelo compilador PORTUGOL versao 1q 2 | // Autor: Ruben Carlo Benante 3 | // Email: benante@gmail.com 4 | // Data: 23/04/2009 5 | 6 | #include "quadruplas.h" 7 | 8 | int main(void) 9 | { 10 | mov(1.00,NULL,&ts[0]); 11 | comp_eq(ts[0],1.00,&temp[0]); 12 | jump_f(temp[0],NULL,l1); 13 | param(111.00,NULL,NULL); 14 | call("imprima",1,NULL); 15 | jump(NULL,NULL,l2); 16 | l1: 17 | param(222.00,NULL,NULL); 18 | call("imprima",1,NULL); 19 | l2: 20 | param(333.00,NULL,NULL); 21 | call("imprima",1,NULL); 22 | param(444.00,NULL,NULL); 23 | call("imprima",1,NULL); 24 | param(ts[0],NULL,NULL); 25 | call("imprima",1,NULL); 26 | } 27 | -------------------------------------------------------------------------------- /testes_ptg/teste9.c: -------------------------------------------------------------------------------- 1 | // Gerado pelo compilador PORTUGOL versao 1.0 2 | // Autor: Ruben Carlo Benante 3 | // Email: benante@gmail.com 4 | // Data: 23/04/2009 5 | 6 | #include 7 | #include 8 | 9 | float var[26] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; 10 | 11 | int main(void) 12 | { 13 | var[0] = 1.00; 14 | var[1] = 2.00; 15 | var[2] = 3.00; 16 | if(var[0] == 1.00 || var[1] != 2.00 && var[2] == 3.00) 17 | printf("111.10\n"); 18 | else 19 | { 20 | printf("%.2f\n", var[2]); 21 | if(!( var[0] == 2.00 && var[1] == 3.00 )) 22 | printf("222.20\n"); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /testes_ptg/teste8.c: -------------------------------------------------------------------------------- 1 | // Gerado pelo compilador PORTUGOL versao 1.0 2 | // Autor: Ruben Carlo Benante 3 | // Email: benante@gmail.com 4 | // Data: 23/04/2009 5 | 6 | #include 7 | #include 8 | 9 | float var[26] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; 10 | 11 | int main(void) 12 | { 13 | var[0] = 1.00; 14 | var[1] = 2.00; 15 | var[2] = 3.00; 16 | if(var[0] != 1.00) 17 | { 18 | printf("%.2f\n", var[0]); 19 | printf("%.2f\n", var[1]); 20 | } 21 | else 22 | { 23 | var[0] = var[0] + 1.00; 24 | printf("113.00\n"); 25 | printf("%.2f\n", var[0]); 26 | } 27 | printf("%.2f\n", var[2]); 28 | } 29 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # Pull Request 2 | 3 | # Formato do título: 4 | 5 | Use o formato: 6 | 7 | grp X: descrição 8 | 9 | Onde: 10 | 11 | * X é o número do seu grupo, e 12 | * descrição é uma breve explicação do conteúdo do _pull request_ 13 | 14 | # Conteúdo do commit: 15 | 16 | Lembre-se de seguir estas recomendações: 17 | 18 | * Discuta nos _issues_ antes de fazer um _pull request_ 19 | - Explique a *API* 20 | - Descreva a funcionalidade que você espera codificar 21 | * Faça _pull requests_ pequenos 22 | - Faça em doses homeopáticas 23 | - Resolva um problema de cada vez 24 | - Não misture ideias diferentes 25 | - Não altere o que não precisa (mesmo que seja algo que está errado! Use outro commit e outro _pull request_ para corrigir o erro) 26 | 27 | Boas contribuições! 28 | 29 | -------------------------------------------------------------------------------- /flexyagcc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Compila arq com lex e yacc (portugol v2q) 3 | #/* 4 | # Autor: Ruben Carlo Benante 5 | # Email: benante@gmail.com 6 | # Data: 23/04/2009 7 | # Modificado em: 24/05/2009 8 | #*/ 9 | # 10 | # Exemplo: 11 | # ./flexyacc portugol teste 12 | # 13 | # inicia os seguintes processos: 14 | # flex portugol.l 15 | # yacc -d portugol.y 16 | # gcc y.tab.c lex.yy.c portugol.c -o portugol.bin 17 | # 18 | # entrada: 19 | # portugol.l (arquivo em linguagem lex, analisador lexico) 20 | # portugol.y (arquivo em linguagem yacc, analisador sintatico) 21 | # portugol.c (arquivo em linguagem c, gerador de codigo) 22 | # 23 | # saida: 24 | # lex.yy.c (saida do lex, em linguagem c) 25 | # y.tab.c (saida do yacc, em linguagem c) 26 | # y.tab.h (saida do yacc, definicoes da linguagem portugol) 27 | # portugol.bin (saida do gcc, arquivo executavel, finalmente o compilador portugol) 28 | # 29 | # Para compilar um fonte.ptg veja abaixo. 30 | 31 | echo --- flex -------------------- flex $1.l 32 | flex $1.l 33 | echo --- bison ------------------- bison -dy $1.y 34 | #yacc -d $1.y 35 | bison -dy $1.y 36 | echo --- gcc --------------------- gcc y.tab.c lex.yy.c $1.c -o $1.bin -lm -ly 37 | gcc y.tab.c lex.yy.c $1.c -o $1.bin -lm -ly 38 | 39 | #Descomente as ultimas linhas para compilar usando o portugol (ou compilar e executar): 40 | # 41 | #./portugol.bin teste1.ptg teste1.c 42 | # 43 | #entrada: 44 | # teste1.ptg (arquivo em linguagem portugol) 45 | # 46 | #saida: 47 | # teste1.asm.c (arquivo em linguagem c -- ou .asm.c para quadruplas) 48 | # teste1.bin (arquivo executavel) 49 | # 50 | 51 | echo --- portugol ---------------- ./$1.bin $2.ptg $2.asm.c 52 | ./$1.bin $2.ptg $2.asm.c 53 | echo --- gcc --------------------- gcc $2.asm.c -o $2.bin -lm 54 | gcc $2.asm.c -o $2.bin -lm 55 | echo --- Running! ---------------- ./$2.asm.bin 56 | ./$2.bin 57 | -------------------------------------------------------------------------------- /testes_ptg/teste-tudo.ptg: -------------------------------------------------------------------------------- 1 | // Compilador PORTUGOL v.1.0 2 | // Autor: Ruben Carlo Benante 3 | // Email: benante@gmail.com 4 | // Data: 24/05/2009 5 | // 6 | // toda a linguagem 7 | 8 | //#debug _ARVORE 9 | #debug _TABELA 10 | 11 | //comentario 12 | inicio; //inicio 13 | texto S; 14 | texto T; 15 | int variavel_3E; 16 | int A; //declaracao de inteiro 17 | int C; 18 | int B; 19 | //int D; 20 | real D; 21 | real M; 22 | real N; 23 | real P; 24 | real O; 25 | 26 | S=""; 27 | M=-C+0.0; 28 | 29 | A= 1; 30 | D=0.0; 31 | 32 | A=10/100; //0.1 arredonda ou trunca? 33 | B=99/100; //0.99 arredonda ou trunca? 34 | M= 1.0/2; 35 | imprima A; 36 | imprima B; 37 | imprima M; 38 | 39 | S="oi"; //atribuicao string 40 | A=1; //atribuicao inteira 41 | O=2.2; //atribuicao flutuante 42 | ; 43 | T=S; 44 | B=A; 45 | P=O; 46 | ; 47 | imprima S; //"oi" 48 | imprima A; //inteiro 1 49 | imprima O; //flutuante 2.2 50 | ; 51 | imprima 1.1; 52 | imprima 1; 53 | imprima "alo #conStr"; 54 | ; 55 | //erro: B=2.0; //atribuicao flutuante em IVAR 56 | //erro: N=1; //atribuicao inteira em FVAR 57 | D=1.1; //repetindo a constante 58 | ; 59 | D=1.0 + 1 * (2 / -3 + 4.0) - A * B + C; //expressao com inteiros, flutuantes e variaveis 60 | se(A==1 ou (B!=2.0 e C>=3.0)) entao //relacionais e e ou, logicos ==, !=, >= 61 | se (D<=0) entao //ambiguidade se-entao-entao-senao, logico <= 62 | inicio; 63 | imprima 111.1; //imprima 64 | saia(1+1); 65 | fim; 66 | senao 67 | inicio; //bloco de comandos 68 | imprima C; 69 | se(nao (A>2 e B<3.0)) entao //relacional nao, logicos > e < 70 | imprima 222.2; 71 | fim; //fim do bloco de comandos 72 | ; //faz nada (nop) 73 | imprima A; 74 | leia M; 75 | se(M==0) entao 76 | aborte; 77 | ; 78 | leia N; 79 | //leia A; // Linha:76. Erro semantico: Chamada da funcao leia com argumento de tipo incorreto. leia . 80 | enquanto (M<5) //enquanto 81 | inicio; 82 | imprima M; 83 | M=M+1; 84 | fim; 85 | ; 86 | ; 87 | ; 88 | ; 89 | M=raiz(9.0); 90 | N=exp(1.0); 91 | imprima "raiz(9)="; 92 | imprima M; 93 | imprima "exp(1) (ou e^1)="; 94 | imprima N; 95 | 96 | variavel_3E = 3 % 2; 97 | imprima "variavel_3E"; //erro: _variavel. Iniciar com sublinhado esta reservado. 98 | imprima variavel_3E; 99 | ; 100 | int i; 101 | para(i=2; i. */ 19 | 20 | /* As a special exception, you may create a larger work that contains 21 | part or all of the Bison parser skeleton and distribute that work 22 | under terms of your choice, so long as that work isn't itself a 23 | parser generator using the skeleton or a modified version thereof 24 | as a parser skeleton. Alternatively, if you modify or redistribute 25 | the parser skeleton itself, you may (at your option) remove this 26 | special exception, which will cause the skeleton and the resulting 27 | Bison output files to be licensed under the GNU General Public 28 | License without this special exception. 29 | 30 | This special exception was added by the Free Software Foundation in 31 | version 2.2 of Bison. */ 32 | 33 | #ifndef YY_YY_Y_TAB_H_INCLUDED 34 | # define YY_YY_Y_TAB_H_INCLUDED 35 | /* Debug traces. */ 36 | #ifndef YYDEBUG 37 | # define YYDEBUG 0 38 | #endif 39 | #if YYDEBUG 40 | extern int yydebug; 41 | #endif 42 | 43 | /* Token type. */ 44 | #ifndef YYTOKENTYPE 45 | # define YYTOKENTYPE 46 | enum yytokentype 47 | { 48 | SE = 258, 49 | ENTAO = 259, 50 | SENAO = 260, 51 | INICIO = 261, 52 | FIM = 262, 53 | IMPRIMA = 263, 54 | LEIA = 264, 55 | ENQUANTO = 265, 56 | ABORTE = 266, 57 | SAIA = 267, 58 | PARA = 268, 59 | INT = 269, 60 | REAL = 270, 61 | TEXTO = 271, 62 | DEFINE = 272, 63 | IMPORTE = 273, 64 | FUNC = 274, 65 | DEBUG = 275, 66 | ARVORE = 276, 67 | TABELA = 277, 68 | IDENT = 278, 69 | INTCON = 279, 70 | REALCON = 280, 71 | TEXTOCON = 281, 72 | OU = 282, 73 | E = 283, 74 | NAO = 284, 75 | GE = 285, 76 | LE = 286, 77 | EQ = 287, 78 | NE = 288, 79 | GT = 289, 80 | LT = 290, 81 | UMENOS = 291 82 | }; 83 | #endif 84 | /* Tokens. */ 85 | #define SE 258 86 | #define ENTAO 259 87 | #define SENAO 260 88 | #define INICIO 261 89 | #define FIM 262 90 | #define IMPRIMA 263 91 | #define LEIA 264 92 | #define ENQUANTO 265 93 | #define ABORTE 266 94 | #define SAIA 267 95 | #define PARA 268 96 | #define INT 269 97 | #define REAL 270 98 | #define TEXTO 271 99 | #define DEFINE 272 100 | #define IMPORTE 273 101 | #define FUNC 274 102 | #define DEBUG 275 103 | #define ARVORE 276 104 | #define TABELA 277 105 | #define IDENT 278 106 | #define INTCON 279 107 | #define REALCON 280 108 | #define TEXTOCON 281 109 | #define OU 282 110 | #define E 283 111 | #define NAO 284 112 | #define GE 285 113 | #define LE 286 114 | #define EQ 287 115 | #define NE 288 116 | #define GT 289 117 | #define LT 290 118 | #define UMENOS 291 119 | 120 | /* Value type. */ 121 | #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED 122 | typedef union YYSTYPE YYSTYPE; 123 | union YYSTYPE 124 | { 125 | #line 28 "portugol.y" /* yacc.c:1909 */ 126 | 127 | tabelaSimb *pSimb; /* yylval.pSimb ponteiro para o IDENT na TS */ 128 | nodo *pNodo; /* tipo do comando e expr */ 129 | 130 | #line 131 "y.tab.h" /* yacc.c:1909 */ 131 | }; 132 | # define YYSTYPE_IS_TRIVIAL 1 133 | # define YYSTYPE_IS_DECLARED 1 134 | #endif 135 | 136 | 137 | extern YYSTYPE yylval; 138 | 139 | int yyparse (void); 140 | 141 | #endif /* !YY_YY_Y_TAB_H_INCLUDED */ 142 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Ao incluir um **bug report** tenha o cuidado de cumprir este _check-list_: 2 | 3 | * Coloque (pelo menos) um _label_. 4 | * Associe um _milestone_. 5 | * Se houver divisão de tarefas, associe a pessoa responsável pelo _bug_. 6 | * Confira se o _bug_ já não foi relatado, evite _bugs_ duplicados. 7 | * Se houver _bugs_ parecidos ou relacionados, inclua um link para eles. 8 | * Confira se está usando a última versão do programa no _develop_. 9 | * Descreva apenas um único _bug_ por _issue_. 10 | * Relate fatos úteis: mensagens de erros, comportamento errático, arquivos ou recursos problemáticos. 11 | * Não relate opiniões, críticas, reclamações ou questões pessoais. 12 | * Se é um _bug_ de segurança, faça o relato em privado. Não coloque a galinha na boca da raposa. 13 | * Seja preciso: vá direto ao ponto, sem rodeios. 14 | * Seja claro: evite pronomes indefinidos (isso, aquilo). Escreva explicitamente o que é, onde é (linha), nome da variável ou função, etc. 15 | * Todo _bug_ merece relatório: não existe _bug_ simples demais para valer um relatório. 16 | * Configure a saída de erro para inglês. Se preciso relatar uma mensagem de erro maior, use o comando _sprunge_. 17 | 18 | Ao criar o **bug report**, siga este guia: 19 | 20 | 0- Assunto (título) 21 | * Objetivo: tornar o bug "buscável" (_searchable_) e inequivocadamente identificável. 22 | * Tamanho: máximo de 100 caracteres. Recomendado até 60. 23 | * Ruim: Travou o arrastar 24 | * Bom: Arrastar textos de uma página trava o editor 25 | 26 | 1- Descrição 27 | * Objetivo: explicar o bug para o programador. 28 | * Inclui: 29 | - Resumo do comportamento (interpretação das falhas) 30 | - Justificativa do motivo que é um bug 31 | - Quaisquer especificações relevantes 32 | - Interpretação da especificação 33 | - Informação em outros programas ou implementações similares 34 | 35 | 2- Passos para a reprodução 36 | * Objetivo: Ensinar ao desenvolvedor (programador) como recriar o bug no sistema dele 37 | * Caso simples: 38 | - Dê explicações junto com cada comando real ou operação realizada. 39 | * Caso complexo: 40 | - Explique cada comando digitado, na ordem. 41 | - Cada clique ativando determinada função do programa 42 | - Caso tenha alterado as configurações padrão do sistema, indique o que há de diferente. 43 | - Faça upload de um caso de teste 44 | 45 | 3- Resultados obtidos 46 | * A mensagem de erro 47 | * A descrição de um comportamento errático 48 | - Descreva o que obteve de resposta 49 | - Cite (literalmente) a(s) mensagem(ns) de erro retornada(s) (use o _sprunge_) 50 | 51 | 4- Resultados esperados 52 | * Como seria o correto em caso de sucesso 53 | * Objetivo: mostrar ao desenvolvedor o que está errado 54 | - Descreva o que você entende que deveria ser a resposta correta 55 | - Escreva de modo preciso como seria a mensagem de saída em caso de sucesso 56 | 57 | 5- Caso de teste mínimo 58 | * Objetivo: isolar o problema e permitir a sua imediata reprodução 59 | - Remova toda informação desnecessária ao teste para a reprodução do _bug_ 60 | - Variações: tente variações do "_test case_" mínimo para descobrir outras situações que também podem disparar o _bug_ 61 | - Anexe arquivos que julgar necessários (fotos, arquivos de entrada, arquivos de saída) 62 | - Não use "fotos" de texto, pois não permitem facilmente reproduzir o erro e reutilizar (copiar) a informação digitada 63 | 64 | 6- Versões e plataforma 65 | * Tenha a certeza de estar tratando da última versão. Senão este _bug_ pode já estar resolvido na versão mais recente. Inclua: 66 | - Versão do programa 67 | - Sistema Operacional 68 | - Arquitetura do computador ou dispositivo (hardware, celular, tablet, &c) 69 | - Acesso (remoto ou local) 70 | 71 | 7- Informações adicionais 72 | * Seu login ou username 73 | * Nomes completos dos arquivos relevantes 74 | * Pasta/diretório onde estão localizado os arquivos relevantes 75 | * URLs, referências, links para mensagens do _sprunge_ ou outros artigos 76 | * Dados do crash (core dumped, texto, input, &c) 77 | * Arquivos de log (/var/log/ ou outros) (quando longos, devem ser preferencialmente anexados) 78 | * Use _labels_ para descrever a gravidade do _bug_. A classificação mais usada é: 79 | - Urgente: afeta a todos (usuários e público em geral). 80 | - Grave: afeta todos usuários 81 | - Média: afeta um determinado grupo de pessoas (ou meu próprio grupo) 82 | - Leve: afeta apenas a mim ou a uma outra pessoa 83 | - Pedido: não afeta ninguém, este é apenas o pedido para se criar uma nova característica do software. 84 | 85 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Portugol - Uma linguagem algorítmica em Português 2 | 3 | ### Introdução 4 | 5 | Linguagem desenvolvida com inspiração em C, em português, para facilitar o ensino de algoritmos a alunos iniciando em programação. 6 | 7 | O projeto iniciou em 23/Abril/2009, e inaugura sua participação no github no aniversário de 8 anos. 8 | 9 | Uma das características marcantes do compilador Portugol é a geração de um bytecode semelhante à linguagem Assembly, chamada de quádruplas. É uma ótima opção para ensinar o básico de Assembly, como se converte código, como ficam os laços e atribuições. 10 | 11 | A linguagem é compilada em três passos: 12 | 13 | 1. Análise léxica e sintática. 14 | 2. Análise sintática, de escopo e de indentação 15 | 3. Análise semântica e geração de código. 16 | 17 | ### Comandos 18 | 19 | Os comandos válidos na linguagem Portugol são: 20 | 21 | * se ... entao ... senao : condição típica para decisões 22 | * inicio ... fim : marca um bloco de comandos subordinados 23 | * imprima : imprime uma mensagem ou variável na saída padrão 24 | * leia : lê um valor da entrada padrão 25 | * enquanto : comando para laço condicional 26 | * para : comando para laço com inicialização, condição e incremento 27 | * aborte : termina abruptamente o programa 28 | * retorne : retorna de uma função para a função chamadora 29 | * saia : termina o programa com um código de sucesso/erro 30 | 31 | ### Tipos de dados 32 | 33 | * inteiro : valores inteiros com sinal (int) 34 | * real : valores reais com sinal (float) 35 | * texto : cadeia de caracteres (string, char \*) 36 | * nada : ponteiro para variável sem tipo (void \*) 37 | * ponteiro : ponteiro para inteiro, real ou texto. 38 | 39 | ### Expressões e operadores (relacionais e lógicos) 40 | 41 | * atribuição: c = 0; 42 | * incremento: c++; ++c; (pós e préfixado) 43 | * decremento: c--; --c; (pós e préfixado) 44 | * apontador: \*p = 0; (dereferenciador de ponteiros) 45 | * endereço: p = & c; (endereço de uma variável) 46 | * Aritméticas: - (unário), +, -, \*, /, e % (módulo, ou resto da divisão) 47 | * Relacionais: >=, <=, ==, !=, > e < 48 | * Lógicas: e, ou e nao (sem acentos) 49 | 50 | ### Opções mais avançadas 51 | 52 | * tipo funcao(arg1, arg2, arg3) : pode-se declarar funções com até 3 argumentos (\*) 53 | * externa : define uma função externa 54 | * define : define uma macro 55 | * \#debug : se ativado, o compilador imprimirá a árvore sintática durante a compilação 56 | * \_ARVORE: ativado, liga impressão da árvore sintática 57 | * \_TABELA: ativado, liga a impressão da tabela de símbolos 58 | 59 | Nota: (\*) limite de 3 argumentos nas funções imposto no momento, mas suficiente para o estudo dos algoritmos básicos. 60 | 61 | ### Constantes e miscelâneas 62 | 63 | * Números podem ser escritos em notação científica 64 | * Comentários são feitos com o símbolo // e são apenas de linha 65 | * Strings são entre "aspas" (duplas) 66 | * Formato para imprimir e ler: %d, %f ou %s (inteiros, reais e _strings_) com uso de modificadores 67 | 68 | * inc, dec, incpos, incpre decpos, decpre 69 | * pont upont uend pattrib 70 | * ponti pontr ponts 71 | * indent intcon realcon textocon principal 72 | 73 | ### Prioridade dos operadores 74 | 75 | Os operadores são processados na seguinte ordem (do menos prioritário para o de maior prioridade): 76 | 77 | * incremento pós-fixado 78 | * ou 79 | * e 80 | * nao 81 | * operadores relacionais 82 | * atribuição 83 | * adição e subtração 84 | * multiplicação, divisão e módulo 85 | * incremento pré-fixado 86 | * dereferenciamento de ponteiros 87 | * endereço de variáveis 88 | 89 | ### Exemplos 90 | 91 | Abaixo um exemplo de código em sua correta indentação: 92 | 93 | * Extensão utilizada pelo Portugol: **ptg** 94 | * Arquivo: **teste.ptg** 95 | 96 | ``` 97 | inteiro principal(nada) 98 | inicio; 99 | 100 | real o; 101 | inteiro u; 102 | 103 | imprima("digite um numero %f\n", o); 104 | leia("%f", o); 105 | se(o<0.0) entao 106 | inicio; 107 | imprima("%s\n","erro: numero negativo!"); 108 | saia(1); 109 | fim; 110 | senao 111 | se(o==0.0) entao 112 | inicio; 113 | imprima("%f\n", 1.0); // Comentario de linha 114 | saia(0); 115 | fim; 116 | 117 | para(u=1; u<5; u=u+1) 118 | inicio; 119 | imprima("%d\n", u); 120 | fim; 121 | retorne 1; 122 | fim; 123 | ``` 124 | 125 | ### Syntax highlighting 126 | 127 | Se você usa o editor _Kate_ (do _KDE_) ou compatíveis com o _XML_ de _syntax highlighting_, basta usar o seguinte comando para ver o código colorido: 128 | 129 | ``` 130 | $ cp ptg.xml /home/user/.kde/share/apps/katepart/syntax/ 131 | ``` 132 | 133 | ### Autor e Copyright 134 | 135 | * Autor: Prof. Dr. Ruben Carlo Benante 136 | * Email: rcb@upe.br 137 | * Data: 2009-04-23 até data corrente (autom. atualizado) 138 | * Licensa: GNU/GPL v2.0 139 | 140 | -------------------------------------------------------------------------------- /ptg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 28 | 29 | 30 | inicio 31 | fim 32 | se 33 | entao 34 | senao 35 | enquanto 36 | aborte 37 | para 38 | importe 39 | define 40 | 41 | 42 | int 43 | real 44 | texto 45 | 46 | 47 | e 48 | ou 49 | nao 50 | 51 | 52 | imprima 53 | leia 54 | saia 55 | raiz 56 | exp 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 | -------------------------------------------------------------------------------- /portugol.l: -------------------------------------------------------------------------------- 1 | %{ 2 | /* 3 | Compilador PORTUGOL v.2q 4 | Autor: Ruben Carlo Benante 5 | Email: benante@gmail.com 6 | Data criação: 23/04/2009 7 | Data modificação: 24/05/2009 8 | */ 9 | 10 | #include 11 | #include 12 | #include "portugol.h" 13 | #include "y.tab.h" 14 | 15 | FILE *fhead=NULL; 16 | %} 17 | 18 | %% 19 | 20 | /* comandos reservados */ 21 | inicio { return INICIO; } /* { */ 22 | fim { return FIM; } /* } */ 23 | se { return SE; } /* if */ 24 | entao { return ENTAO; } /* then_separator */ 25 | senao { return SENAO; } /* else */ 26 | enquanto { return ENQUANTO; } /* while */ 27 | aborte { return ABORTE; } /* exit(1) */ 28 | para { return PARA; } /* for */ 29 | int { return INT; } /* int */ 30 | real { return REAL; } /* float */ 31 | texto { return TEXTO; } /* char* */ 32 | importe { return IMPORTE; } /* import double sqrt ( double ) */ 33 | define { return DEFINE; } /* define int funcId ( int argId ) */ 34 | "#debug" { return DEBUG; } /* pre-processor directive */ 35 | _ARVORE { return ARVORE; } /* turn on print-syntatic-tree option */ 36 | _TABELA { return TABELA; } /* turn on print-symbol-table option */ 37 | 38 | /* funcoes reservadas */ 39 | imprima { return IMPRIMA; } /* printf(format,x); format=={"%d", "%.2f", "%s"} */ 40 | leia { return LEIA; } /* scanf("%f",&x); */ 41 | saia { return SAIA; } /* exit(x) */ 42 | 43 | /* Pontuacao */ 44 | ">=" { return GE; } 45 | "<=" { return LE; } 46 | "==" { return EQ; } 47 | "!=" { return NE; } 48 | ">" { return GT; } 49 | "<" { return LT; } 50 | "e" { return E; } 51 | "ou" { return OU; } 52 | "nao" { return NAO; } 53 | 54 | [-+*/=();%] { return yytext[0]; } 55 | 56 | /* Identificadores */ 57 | [a-zA-Z][a-zA-Z0-9_]* { tabelaSimb *ps = achaId(yytext); 58 | yylval.pSimb = ps; 59 | return IDENT; 60 | } 61 | 62 | /* Constantes */ 63 | [0-9]+"."[0-9]+([eE][+-]?[0-9]+)? { tabelaSimb *ps = achaFloat(atof(yytext)); 64 | yylval.pSimb = ps; 65 | return REALCON; 66 | } 67 | 68 | [0-9]+ { tabelaSimb *ps = achaInt(atoi(yytext)); 69 | yylval.pSimb = ps; 70 | return INTCON; 71 | } 72 | 73 | "\""[^"\n]*"\"" { tabelaSimb *ps = achaStr(yytext); 74 | yylval.pSimb = ps; 75 | return TEXTOCON; 76 | } 77 | 78 | /* espacos e comentarios */ 79 | \n { lineno++; } 80 | [ \t\r]+ ; /* do nothing */ 81 | "//".* ; /* one-line comments */ 82 | 83 | /* Outras coisas */ 84 | . { yyerror("caracter invalido"); } 85 | 86 | %% 87 | 88 | int yywrap(void) 89 | { 90 | return 1; 91 | } 92 | 93 | void yyerror(char *s) 94 | { 95 | fprintf(stderr, "// Linha:%d. Erro: %s Token: '%s'.\n", lineno, s, yytext); 96 | } 97 | 98 | int main(int ac, char **av) 99 | { 100 | int i; 101 | 102 | yyin=stdin; 103 | yyout=stdout; 104 | fhead=stdout; 105 | if(ac>2) //tem arquivo de saida 106 | { 107 | if((yyout = fopen(av[2],"w"))==NULL) 108 | { 109 | fprintf(stderr, "Nao consigo abrir arquivo %s para gravacao.\n", av[2]); 110 | exit(1); 111 | } 112 | if((fhead = fopen("saida.h","w"))==NULL) 113 | { 114 | fprintf(stderr, "Nao consigo abrir arquivo saida.h para gravacao.\n"); 115 | exit(1); 116 | } 117 | } 118 | 119 | if(ac>1) 120 | { 121 | if((yyin = fopen(av[1],"r"))==NULL) 122 | { 123 | fprintf(stderr, "Nao consigo abrir arquivo %s para leitura.\n", av[1]); 124 | exit(1); 125 | } 126 | } 127 | else 128 | fprintf(yyout, "Compilador PORTUGOL versao 2q, por Ruben Carlo Benante (24/05/09).\n"); 129 | 130 | addFuncVoid("imprima", (void *)printf, "printf"); 131 | addFuncVoid("leia", (void *)scanf, "scanf"); 132 | addFuncVoid("saia", (void *)exit, "exit"); 133 | addFuncDouble("raiz", sqrt, "sqrt"); 134 | addFuncDouble("exp", exp, "exp"); 135 | addConStr("?"); 136 | if(yyparse()) //falhou 137 | { 138 | fprintf(stderr, "// Falha! Programa em Portugol nao compilado.\n\n"); 139 | if(yyout!=stdout) 140 | fprintf(yyout, "// Falha! Programa em Portugol nao compilado.\n\n"); 141 | return 1; 142 | } 143 | 144 | return 0; 145 | } 146 | 147 | void addConStr(char *s) 148 | { 149 | tabelaSimb *ps = achaStr(s); 150 | } 151 | 152 | void addFuncDouble(char *id, double (*func)(), char *idF) 153 | { 154 | tabelaSimb *ps = achaId(id); //ps->idNome = strdup(nome); 155 | ps->dfunc = func; 156 | ps->tipoD = tipoIdFuncDouble; 157 | ps->idx = geraTF(); 158 | ps->idFunc = strdup(idF); 159 | } 160 | 161 | void addFuncVoid(char *id, void (*func)(), char *idF) 162 | { 163 | tabelaSimb *ps = achaId(id); //idName 164 | ps->vfunc = func; 165 | ps->tipoD = tipoIdFuncVoid; 166 | ps->idx = geraTF(); 167 | ps->idFunc = strdup(idF); 168 | } 169 | -------------------------------------------------------------------------------- /.github/BECOSYSTEMS_CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Código de Conduta BecoSystems 2 | 3 | ## Código de Conduta do Software Livre e Aberto BecoSystems 4 | 5 | 6 | Para que se possa promover uma comunidade inclusiva, gentil, livre de assédios e cooperativa, BecoSystems (\*) utiliza este código de conduta para projetos de software livre e aberto. 7 | 8 | ## Resumo 9 | 10 | Assédio em código e discussão ou violação de limites físicos é completamente inaceitável em qualquer repositório do BecoSystems, em relatórios de _bugs_/erros (_issue trackers_), salas de bate-papo (_chatrooms_), listas de discussão (_mailing lists_), reuniões ou quaisquer outros eventos. Os violadores deste código serão advertidos pelo adminstrador do time. A repetição de violações resultará em bloqueio ou banimento do time, o que tem consequências diretas sobre o desempenho acadêmico do responsável e do seu grupo. 11 | 12 | ## Em detalhes 13 | 14 | Assédio inclui comentários verbais ofensivos relacionados a identidade de gênero, expressão de gênero, orientação sexual, disabilidade, aparência física, tamanho do corpo, raça, religião, imagens sexuais, intimidação deliberada, perseguição, ruído e disrupção constante, e atenção sexual inapropriada. 15 | 16 | Dos indivíduos que forem instados a pararem com qualquer comportamento de assédio, espera-se que assim o façam imediatamente. 17 | 18 | Os mantenedores também estão sujeitos à política de anti-assédio. 19 | 20 | Se qualquer pessoa se enveredar em comportamento de assédio, incluindo mantenedores, tomaremos medidas apropriadas, desde um aviso ao ofensor, apagamento de comentários, remoção do mesmo do projeto e do sistema de comunicação, até escalar ao suporte do Github e coordenação da universidade. 21 | 22 | Se você está sendo assediado(a), ou notar que alguém está sendo assediado, ou tem alguma outra preocupação, por favor contacte um membro do time ou envie um email para o seu professor imediatamente. 23 | 24 | Nós esperamos que todos sigam estas regras em quaisquer projetos no Github do BecoSystem, nos relatórios de bugs, salas de bate-papo, listas de discussões e outros meios de comunicação. 25 | 26 | Finalmente, não esqueça de que cometer erros é humano! Todos nós cometemos. Vamos trabalhar em conjunto para ajudarmos uns aos outros, resolver nossas diferenças e aprender com os erros que nós vamos inevitavelmente cometer de tempos em tempos. 27 | 28 | ## Obrigado 29 | 30 | Obrigado ao _ThoughtBot Code of Conduct_, _CocoaPods Code of Conduct_, _Blunder Code of Conduct_, _JSConf Code of Conduct_ e _Contributor Covenant_ pela inspiração e ideias. 31 | 32 | ## Licença 33 | 34 | Dentro da extensão possível da lei, BecoSystem não proclama nenhum copyright ou direitos relacionados ou próximos ao Código de Conduta BecoSystems. 35 | Este trabalho foi publicado no Brasil. 36 | 37 | * [Texto licenciado sob Domínio Público Universal CC0 1.0](http://creativecommons.org/publicdomain/zero/1.0/) 38 | * [Referência em que este código foi baseado](https://thoughtbot.com/open-source-code-of-conduct) 39 | 40 | ![Public Domain](https://i.creativecommons.org/p/zero/1.0/88x31.png) 41 | 42 | --- 43 | 44 | # BecoSystems Code of Conduct 45 | 46 | ## Free Open Source Code of Conduct 47 | 48 | In order to foster an inclusive, kind, harassment-free, and cooperative community, BecoSystems (\*) enforces this code of conduct on our free, open source projects. 49 | 50 | ## Summary 51 | 52 | Harassment in code and discussion or violation of physical boundaries is completely unacceptable anywhere in BecoSystems' project codebases, issue trackers, chatrooms, mailing lists, meetups, and other events. Violators will be warned by the core team. Repeat violations will result in being blocked or banned from the team, which have direct impact on the academic grades of the responsible and his/her team. 53 | 54 | ## In detail 55 | 56 | Harassment includes offensive verbal comments related to gender identity, gender expression, sexual orientation, disability, physical appearance, body size, race, religion, sexual images, deliberate intimidation, stalking, sustained disruption, and unwelcome sexual attention. 57 | 58 | Individuals asked to stop any harassing behavior are expected to comply immediately. 59 | 60 | Maintainers are also subject to the anti-harassment policy. 61 | 62 | If anyone engages in harassing behavior, including maintainers, we may take appropriate action, up to and including warning the offender, deletion of comments, removal from the project's codebase and communication systems, and escalation to GitHub support and the university's coordination. 63 | 64 | If you are being harassed, notice that someone else is being harassed, or have any other concerns, please contact a member of the core team or email your professor immediately. 65 | 66 | We expect everyone to follow these rules anywhere in BecoSystems' project codebases, issue trackers, chatrooms, and mailing lists. 67 | 68 | Finally, don't forget that it is human to make mistakes! We all do. Let's work together to help each other, resolve issues, and learn from the mistakes that we will all inevitably make from time to time. 69 | 70 | ## Thanks 71 | 72 | Thanks to the ThoughBot Code of Conduct, CocoaPods Code of Conduct, Bundler Code of Conduct, JSConf Code of Conduct, and Contributor Covenant for inspiration and ideas. 73 | 74 | ## License 75 | 76 | To the extent possible under law, the BecoSystems team has waived all copyright and related or neighboring rights to BecoSystems Code of Conduct. This work is published from Brazil. 77 | 78 | * [Text Published as Public Domain License CC0 1.0 Universal](http://creativecommons.org/publicdomain/zero/1.0/) 79 | * [Original text reference](https://thoughtbot.com/open-source-code-of-conduct) 80 | 81 | ![Public Domain](https://i.creativecommons.org/p/zero/1.0/88x31.png) 82 | 83 | -------------------------------------------------------------------------------- /quadruplas-v2a.h: -------------------------------------------------------------------------------- 1 | // Compilador PORTUGOL versao 2q 2 | // Autor: Ruben Carlo Benante 3 | // Email: benante@gmail.com 4 | // Data criação: 23/04/2009 5 | // Data modificação: 25/05/2009 6 | 7 | #include 8 | #include 9 | #include 10 | #include "portugol-v2q.h" 11 | 12 | #define STACK_SIZE 100 13 | #define FUNC_NAME_SIZE 32 14 | #define MAX_PARAM 4 15 | 16 | struct tabela_call //tabela de nomes e enderecos de funcoes para chamar com call 17 | { 18 | char nome[FUNC_NAME_SIZE]; //nome da funcao 19 | void (*func)(); //ponteiro para a funcao 20 | } tabcall[] = { 21 | {"imprima", (void *)printf}, //imprima A; -> printf("%.2f",ts[0]); 22 | {"leia", (void *)scanf}, //leia A; -> scanf("%f",&ts[0]); 23 | {"saia", (void *)exit} //saia(A); -> exit(ts[0]); 24 | }; 25 | 26 | enum {imprima, leia, saia}; //enumeracao de funcoes disponiveis 27 | 28 | float stack[STACK_SIZE]; //pilha 29 | int stack_idx=0; //indice da pilha 30 | 31 | #define jump_f(Q1,NUL1,LABEL) if(!Q1) goto LABEL /* jump to LABEL if Q1==false */ 32 | #define jump(NUL1,NUL2,LABEL) goto LABEL /* jump to LABEL */ 33 | void nop(float *nul1, float *nul2, float *nul3); // do nothing 34 | void halt(float *nul1, float *nul2, float *nul3); // abort with exit(1) 35 | 36 | void mov(float q1, float *nul1, float *qres); // *qres=q1; 37 | 38 | void uminus(float q1, float *nul1, float *qres); // *qres = -q1 39 | void add(float q1, float q2, float *qres); // *qres = q1 + q2 40 | void sub(float q1, float q2, float *qres); // *qres = q1 - q2 41 | void mult(float q1, float q2, float *qres); // *qres = q1 * q2 42 | void divi(float q1, float q2, float *qres); // *qres = q1 / q2 43 | void comp_eq(float q1, float q2, float *qres); // *qres = (q1 == q2) 44 | void comp_ne(float q1, float q2, float *qres); // *qres = (q1 != q2) 45 | void comp_gt(float q1, float q2, float *qres); // *qres = (q1 > q2) 46 | void comp_lt(float q1, float q2, float *qres); // *qres = (q1 < q2) 47 | void comp_ge(float q1, float q2, float *qres); // *qres = (q1 >= q2) 48 | void comp_le(float q1, float q2, float *qres); // *qres = (q1 <= q2) 49 | void rela_an(float q1, float q2, float *qres); // *qres = (q1 && q2) 50 | void rela_or(float q1, float q2, float *qres); // *qres = (q1 || q2) 51 | void rela_no(float q1, float *nul1, float *qres); // *qres = (!q1) 52 | 53 | void param(float q1, float *nul1, float *nul2); // push q1 to stak as function parameter 54 | void call(char *q1, int i, float *qres); // *qres = fname(a[1], ..., a[i]); where q1:fname, q2:# of param 55 | 56 | void push(float f); // poe na pilha de execucao 57 | float pop(void); // tira da pilha de execucao 58 | 59 | /* ------------------------------------------------------------------------------------------------- */ 60 | 61 | void push(float f) 62 | { 63 | stack[stack_idx]=f; 64 | stack_idx++; 65 | if(stack_idx>=STACK_SIZE) 66 | { fprintf(stderr,"Erro: pilha cheia."); 67 | exit(1); 68 | } 69 | } 70 | 71 | float pop(void) 72 | { 73 | if(stack_idx<=0) 74 | { fprintf(stderr,"Erro: pilha vazia."); 75 | exit(1); 76 | } 77 | return(stack[--stack_idx]); 78 | } 79 | 80 | /* misc operations */ 81 | //--------------------------- 82 | //nop : //do nothing 83 | void nop(float *nul1, float *nul2, float *nul3) { ; } 84 | // abort with exit(1) 85 | void halt(float *nul1, float *nul2, float *nul3) { exit(1); } 86 | /* memory operations */ 87 | //--------------------------- 88 | void mov(float q1, float *nul1, float *qres) { *qres=q1; } 89 | /*mathematical operations */ 90 | //--------------------------- 91 | // uminus (3.00,NULL,&temp[1]); //temp[1]=-3.0; 92 | void uminus(float q1, float *nul1, float *qres) { *qres=-q1; } 93 | // add(temp[2],4.00,&temp[3]); //temp[3]=temp[2]+4.0; 94 | void add(float q1, float q2, float *qres) { *qres=q1+q2; } 95 | // sub(temp[5],temp[6],&temp[7]); //temp[7]=temp[5]-temp[6]; 96 | void sub(float q1, float q2, float *qres) { *qres=q1-q2; } 97 | // mult(1.00,temp[3],&temp[4]); //temp[4]=1.0*temp[3]; 98 | void mult(float q1, float q2, float *qres) { *qres=q1*q2; } 99 | // divi(2.00,temp[1],&temp[2]); //temp[2]=2.0/temp[1]; 100 | void divi(float q1, float q2, float *qres) { *qres=q1/q2; } 101 | // mod(10.00,7.00,&temp[2]); //temp[2]=10.0/7.00; 102 | void mod(float q1, float q2, float *qres) { *qres=(float)((int)q1%(int)q2); } 103 | /* logical operations */ 104 | //--------------------------- 105 | // comp_eq(ts[1],2.00,&temp[0]); //temp[0]=(ts[1]==2.0); 106 | void comp_eq(float q1, float q2, float *qres) { *qres=(q1==q2); } 107 | // comp_ne(ts[1],2.00,&temp[10]); //temp[10]=(ts[1]!=2.0); 108 | void comp_ne(float q1, float q2, float *qres) { *qres=(q1!=q2); } 109 | // comp_gt(ts[0],2.00,&temp[15]); //temp[15]=(ts[0]>2.0); 110 | void comp_gt(float q1, float q2, float *qres) { *qres=(q1>q2); } 111 | // comp_lt(ts[1],3.00,&temp[16]); //temp[16]=(ts[1]<3.0); 112 | void comp_lt(float q1, float q2, float *qres) { *qres=(q1=3.0); 114 | void comp_ge(float q1, float q2, float *qres) { *qres=(q1>=q2); } 115 | // comp_le(ts[3],0.00,&temp[14]); //temp[14]=(ts[3]<=0.0); 116 | void comp_le(float q1, float q2, float *qres) { *qres=(q1<=q2); } 117 | /* relational operations */ 118 | //--------------------------- 119 | // rela_an(temp[10],temp[11],&temp[12]); //temp[12]=(temp[10]&&temp[11]); 120 | void rela_an(float q1, float q2, float *qres) { *qres=(q1&&q2); } 121 | // rela_or(temp[9],temp[12],&temp[13]); //temp[13]=(temp[9]||temp[12]); 122 | void rela_or(float q1, float q2, float *qres) { *qres=(q1||q2); } 123 | // rela_no(temp[17],NULL,&temp[18]); //temp[18]=!(temp[17]); 124 | void rela_no(float q1, float *nul1, float *qres) { *qres=(!q1); } 125 | /*stack and function operations */ 126 | //--------------------------- 127 | // param(temp[1],NULL,NULL); // put temp[1] into parameter stack 128 | void param(float q1, float *nul1, float *nul2) { push(q1); } 129 | // call ("print",1,&ts[0]); //call a function "print" with 1 arg from stack, and return a value to ts[0]. 130 | void call(char *q1, int i, float *qres) 131 | { 132 | int j=0; 133 | float a[MAX_PARAM];//maximo funcao com 4 argumentos f(a0, a1, a2, a3); 134 | 135 | if(i>MAX_PARAM) 136 | fprintf(stderr, "error: cant call function with more than %d (MAX_PARAM) parameters.", MAX_PARAM); 137 | 138 | for(j=0; j 7 | #include "quadruplas.h" 8 | #include "saida.h" 9 | 10 | void filltf(void) 11 | { 12 | tf[0].tipoRet=tipoRetFuncVoid; 13 | tf[0].vfunc=(void *)printf; 14 | tf[0].idNome=malloc(strlen("imprima")+1); 15 | strcpy(tf[0].idNome,"imprima"); 16 | 17 | tf[1].tipoRet=tipoRetFuncVoid; 18 | tf[1].vfunc=(void *)scanf; 19 | tf[1].idNome=malloc(strlen("leia")+1); 20 | strcpy(tf[1].idNome,"leia"); 21 | 22 | tf[2].tipoRet=tipoRetFuncVoid; 23 | tf[2].vfunc=(void *)exit; 24 | tf[2].idNome=malloc(strlen("saia")+1); 25 | strcpy(tf[2].idNome,"saia"); 26 | 27 | tf[3].tipoRet=tipoRetFuncDouble; 28 | tf[3].dfunc=sqrt; 29 | tf[3].idNome=malloc(strlen("raiz")+1); 30 | strcpy(tf[3].idNome,"raiz"); 31 | 32 | tf[4].tipoRet=tipoRetFuncDouble; 33 | tf[4].dfunc=exp; 34 | tf[4].idNome=malloc(strlen("exp")+1); 35 | strcpy(tf[4].idNome,"exp"); 36 | 37 | } 38 | 39 | int main(void) 40 | { 41 | filltf(); 42 | 43 | loads("\0", NULL, &ts[0]); /* str S; */ 44 | loads("\0", NULL, &ts[1]); /* str T; */ 45 | loadi(0, NULL, &ts[2]); /* int variavel_3E; */ 46 | loadi(0, NULL, &ts[3]); /* int A; */ 47 | loadi(0, NULL, &ts[4]); /* int C; */ 48 | loadi(0, NULL, &ts[5]); /* int B; */ 49 | loadf(0.00, NULL, &ts[6]); /* real D; */ 50 | loadf(0.00, NULL, &ts[7]); /* real M; */ 51 | loadf(0.00, NULL, &ts[8]); /* real N; */ 52 | loadf(0.00, NULL, &ts[9]); /* real P; */ 53 | loadf(0.00, NULL, &ts[10]); /* real O; */ 54 | loads("",NULL,&tc[1]); 55 | mov(tc[1],NULL,&ts[0]); /* S = tc[1] */ 56 | uminus(ts[4],NULL,&tp[0]); 57 | loadf(0.00,NULL,&tc[2]); 58 | add(tp[0],tc[2],&tp[1]); 59 | mov(tp[1],NULL,&ts[7]); /* M = tp[1] */ 60 | loadi(1,NULL,&tc[3]); 61 | mov(tc[3],NULL,&ts[3]); /* A = tc[3] */ 62 | mov(tc[2],NULL,&ts[6]); /* D = tc[2] */ 63 | loadi(10,NULL,&tc[4]); 64 | loadi(100,NULL,&tc[5]); 65 | divi(tc[4],tc[5],&tp[2]); 66 | mov(tp[2],NULL,&ts[3]); /* A = tp[2] */ 67 | loadi(99,NULL,&tc[6]); 68 | divi(tc[6],tc[5],&tp[3]); 69 | mov(tp[3],NULL,&ts[5]); /* B = tp[3] */ 70 | loadf(1.00,NULL,&tc[7]); 71 | loadi(2,NULL,&tc[8]); 72 | divi(tc[7],tc[8],&tp[4]); 73 | mov(tp[4],NULL,&ts[7]); /* M = tp[4] */ 74 | param(ts[3],NULL,NULL); 75 | call("imprima",1,NULL); 76 | param(ts[5],NULL,NULL); 77 | call("imprima",1,NULL); 78 | param(ts[7],NULL,NULL); 79 | call("imprima",1,NULL); 80 | loads("oi",NULL,&tc[9]); 81 | mov(tc[9],NULL,&ts[0]); /* S = tc[9] */ 82 | mov(tc[3],NULL,&ts[3]); /* A = tc[3] */ 83 | loadf(2.20,NULL,&tc[10]); 84 | mov(tc[10],NULL,&ts[10]); /* O = tc[10] */ 85 | nop(NULL,NULL,NULL); /* no operation */ 86 | mov(ts[0],NULL,&ts[1]); /* T = ts[0] */ 87 | mov(ts[3],NULL,&ts[5]); /* B = ts[3] */ 88 | mov(ts[10],NULL,&ts[9]); /* P = ts[10] */ 89 | nop(NULL,NULL,NULL); /* no operation */ 90 | param(ts[0],NULL,NULL); 91 | call("imprima",1,NULL); 92 | param(ts[3],NULL,NULL); 93 | call("imprima",1,NULL); 94 | param(ts[10],NULL,NULL); 95 | call("imprima",1,NULL); 96 | nop(NULL,NULL,NULL); /* no operation */ 97 | loadf(1.10,NULL,&tc[11]); 98 | param(tc[11],NULL,NULL); 99 | call("imprima",1,NULL); 100 | param(tc[3],NULL,NULL); 101 | call("imprima",1,NULL); 102 | loads("alo #conStr",NULL,&tc[12]); 103 | param(tc[12],NULL,NULL); 104 | call("imprima",1,NULL); 105 | nop(NULL,NULL,NULL); /* no operation */ 106 | mov(tc[11],NULL,&ts[6]); /* D = tc[11] */ 107 | nop(NULL,NULL,NULL); /* no operation */ 108 | loadi(3,NULL,&tc[13]); 109 | uminus(tc[13],NULL,&tp[5]); 110 | divi(tc[8],tp[5],&tp[6]); 111 | loadf(4.00,NULL,&tc[14]); 112 | add(tp[6],tc[14],&tp[7]); 113 | mult(tc[3],tp[7],&tp[8]); 114 | add(tc[7],tp[8],&tp[9]); 115 | mult(ts[3],ts[5],&tp[10]); 116 | sub(tp[9],tp[10],&tp[11]); 117 | add(tp[11],ts[4],&tp[12]); 118 | mov(tp[12],NULL,&ts[6]); /* D = tp[12] */ 119 | comp_eq(ts[3],tc[3],&tp[13]); 120 | loadf(2.00,NULL,&tc[15]); 121 | comp_ne(ts[5],tc[15],&tp[14]); 122 | loadf(3.00,NULL,&tc[16]); 123 | comp_ge(ts[4],tc[16],&tp[15]); 124 | rela_an(tp[14],tp[15],&tp[16]); 125 | rela_or(tp[13],tp[16],&tp[17]); 126 | jump_f(tp[17],NULL,l1); /* if(F) goto l1 */ 127 | loadi(0,NULL,&tc[17]); 128 | comp_le(ts[6],tc[17],&tp[18]); 129 | jump_f(tp[18],NULL,l2); /* if(F) goto l2 */ 130 | loadf(111.10,NULL,&tc[18]); 131 | param(tc[18],NULL,NULL); 132 | call("imprima",1,NULL); 133 | add(tc[3],tc[3],&tp[19]); 134 | param(tp[19],NULL,NULL); 135 | call("saia",1,NULL); 136 | jump(NULL,NULL,l3); 137 | l2: /* else */ 138 | param(ts[4],NULL,NULL); 139 | call("imprima",1,NULL); 140 | comp_gt(ts[3],tc[8],&tp[20]); 141 | comp_lt(ts[5],tc[16],&tp[21]); 142 | rela_an(tp[20],tp[21],&tp[22]); 143 | rela_no(tp[22],NULL,&tp[23]); 144 | jump_f(tp[23],NULL,l4); /* if(F) goto l4 */ 145 | loadf(222.20,NULL,&tc[19]); 146 | param(tc[19],NULL,NULL); 147 | call("imprima",1,NULL); 148 | l4: /* endif */ 149 | l3: /* endif */ 150 | l1: /* endif */ 151 | nop(NULL,NULL,NULL); /* no operation */ 152 | param(ts[3],NULL,NULL); 153 | call("imprima",1,NULL); 154 | loads("?",NULL,&tc[0]); 155 | param(tc[0],NULL,NULL); 156 | call("imprima",1,NULL); 157 | call("leia",0,&ts[7]); 158 | comp_eq(ts[7],tc[17],&tp[24]); 159 | jump_f(tp[24],NULL,l5); /* if(F) goto l5 */ 160 | halt(NULL,NULL,NULL); 161 | l5: /* endif */ 162 | nop(NULL,NULL,NULL); /* no operation */ 163 | param(tc[0],NULL,NULL); 164 | call("imprima",1,NULL); 165 | call("leia",0,&ts[8]); 166 | l6: /* while */ 167 | loadi(5,NULL,&tc[20]); 168 | comp_lt(ts[7],tc[20],&tp[25]); 169 | jump_f(tp[25],NULL,l7); 170 | param(ts[7],NULL,NULL); 171 | call("imprima",1,NULL); 172 | add(ts[7],tc[3],&tp[26]); 173 | mov(tp[26],NULL,&ts[7]); /* M = tp[26] */ 174 | jump(NULL,NULL,l6); 175 | l7: /* end_while */ 176 | nop(NULL,NULL,NULL); /* no operation */ 177 | nop(NULL,NULL,NULL); /* no operation */ 178 | nop(NULL,NULL,NULL); /* no operation */ 179 | nop(NULL,NULL,NULL); /* no operation */ 180 | loadf(9.00,NULL,&tc[21]); 181 | param(tc[21], NULL, NULL); 182 | call("raiz", 1, &tp[27]); 183 | mov(tp[27],NULL,&ts[7]); /* M = tp[27] */ 184 | param(tc[7], NULL, NULL); 185 | call("exp", 1, &tp[28]); 186 | mov(tp[28],NULL,&ts[8]); /* N = tp[28] */ 187 | loads("raiz(9)=",NULL,&tc[22]); 188 | param(tc[22],NULL,NULL); 189 | call("imprima",1,NULL); 190 | param(ts[7],NULL,NULL); 191 | call("imprima",1,NULL); 192 | loads("exp(1) (ou e^1)=",NULL,&tc[23]); 193 | param(tc[23],NULL,NULL); 194 | call("imprima",1,NULL); 195 | param(ts[8],NULL,NULL); 196 | call("imprima",1,NULL); 197 | mod(tc[13],tc[8],&tp[29]); 198 | mov(tp[29],NULL,&ts[2]); /* variavel_3E = tp[29] */ 199 | loads("variavel_3E",NULL,&tc[24]); 200 | param(tc[24],NULL,NULL); 201 | call("imprima",1,NULL); 202 | param(ts[2],NULL,NULL); 203 | call("imprima",1,NULL); 204 | nop(NULL,NULL,NULL); /* no operation */ 205 | loadi(0, NULL, &ts[11]); /* int i; */ 206 | mov(tc[8],NULL,&ts[11]); /* i = tc[8] */ 207 | l8: /* for */ 208 | comp_lt(ts[11],ts[7],&tp[30]); 209 | jump_f(tp[30],NULL,l9); 210 | loads("laco:",NULL,&tc[25]); 211 | param(tc[25],NULL,NULL); 212 | call("imprima",1,NULL); 213 | param(ts[11],NULL,NULL); 214 | call("imprima",1,NULL); 215 | add(ts[11],tc[3],&tp[31]); 216 | mov(tp[31],NULL,&ts[11]); /* i = tp[31] */ 217 | jump(NULL,NULL,l8); 218 | l9: /* end_for */ 219 | param(tc[17],NULL,NULL); 220 | call("saia",1,NULL); 221 | } 222 | -------------------------------------------------------------------------------- /portugol.y: -------------------------------------------------------------------------------- 1 | %{ 2 | /* 3 | Compilador PORTUGOL v.2q 4 | Autor: Ruben Carlo Benante 5 | Email: benante@gmail.com 6 | Data criação: 23/04/2009 7 | Data modificação: 24/05/2009 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include "portugol.h" 16 | 17 | /* prototipos */ 18 | int debugArvore = 0; 19 | int debugTabela = 0; 20 | int lineno = 1; 21 | char msg[80], *tmp; 22 | int imaxts, imaxtc, imaxtf, imaxtp; 23 | tabelaSimb *prox; 24 | extern char *sTipoDado[]; 25 | 26 | %} 27 | 28 | %union { 29 | tabelaSimb *pSimb; /* yylval.pSimb ponteiro para o IDENT na TS */ 30 | nodo *pNodo; /* tipo do comando e expr */ 31 | }; 32 | 33 | %token SE ENTAO SENAO INICIO FIM IMPRIMA LEIA ENQUANTO ABORTE SAIA PARA 34 | %token INT REAL TEXTO DEFINE IMPORTE FUNC 35 | %token DEBUG ARVORE TABELA 36 | %token IDENT INTCON REALCON TEXTOCON 37 | 38 | %left OU 39 | %left E 40 | %left NAO 41 | %left GE LE EQ NE GT LT 42 | %left '+' '-' 43 | %left '*' '/' '%' 44 | %nonassoc UMENOS 45 | %nonassoc ENTAO 46 | %nonassoc SENAO 47 | 48 | %type comando expr lista_comandos bloco_comandos 49 | 50 | %% 51 | 52 | programa: 53 | bloco_comandos { 54 | fprintf(yyout, "// Gerado pelo compilador Portugol versao 2q\n"); 55 | fprintf(yyout, "// Autor: Ruben Carlo Benante\n"); 56 | fprintf(yyout, "// Email: benante@gmail.com\n"); 57 | fprintf(yyout, "// Data: 23/05/2009\n\n"); 58 | fprintf(yyout, "#include \n"); 59 | fprintf(yyout, "#include \"quadruplas.h\"\n"); 60 | fprintf(yyout, "#include \"saida.h\"\n\n"); 61 | fprintf(yyout, "void filltf(void)\n{\n"); 62 | prox=achaFuncs(NULL); 63 | while(prox!=NULL) 64 | { 65 | fprintf(yyout, " tf[%d].tipoRet=", prox->idx); 66 | switch(prox->tipoD) 67 | { 68 | case tipoIdFuncInt: 69 | fprintf(yyout, "tipoRetFuncInt;\n"); 70 | fprintf(yyout, " tf[%d].ifunc=%s;\n", prox->idx, prox->idFunc); 71 | break; 72 | case tipoIdFuncFloat: 73 | fprintf(yyout, "tipoRetFuncFloat;\n"); 74 | fprintf(yyout, " tf[%d].ffunc=%s;\n", prox->idx, prox->idFunc); 75 | break; 76 | case tipoIdFuncDouble: 77 | fprintf(yyout, "tipoRetFuncDouble;\n"); 78 | fprintf(yyout, " tf[%d].dfunc=%s;\n", prox->idx, prox->idFunc); 79 | break; 80 | case tipoIdFuncStr: 81 | fprintf(yyout, "tipoRetFuncStr;\n"); 82 | fprintf(yyout, " tf[%d].sfunc=%s;\n", prox->idx, prox->idFunc); 83 | break; 84 | case tipoIdFuncVoid: 85 | fprintf(yyout, "tipoRetFuncVoid;\n"); 86 | fprintf(yyout, " tf[%d].vfunc=(void *)%s;\n", prox->idx, prox->idFunc); 87 | break; 88 | default: 89 | yyerror("Funcao de tipo desconhecido.\n"); 90 | exit(1); 91 | } 92 | fprintf(yyout, " tf[%d].idNome=malloc(strlen(\"%s\")+1);\n", prox->idx, prox->idNome); 93 | fprintf(yyout, " strcpy(tf[%d].idNome,\"%s\");\n\n", prox->idx, prox->idNome); 94 | prox=achaFuncs(prox); 95 | } 96 | fprintf(yyout, "}\n\n"); 97 | fprintf(yyout, "int main(void)\n"); 98 | fprintf(yyout, "{\n filltf();\n\n"); 99 | gera_quad($1,0); 100 | liberaNodo($1); 101 | 102 | imaxts=geraTS(); 103 | imaxtc=geraTC(); 104 | imaxtf=geraTF(); 105 | tmp=geraTP(&imaxtp); 106 | fprintf(fhead, "// Gerado pelo compilador Portugol versao 2q\n"); 107 | fprintf(fhead, "// Autor: Ruben Carlo Benante\n"); 108 | fprintf(fhead, "// Email: benante@gmail.com\n"); 109 | fprintf(fhead, "// Data: 23/05/2009\n\n"); 110 | fprintf(fhead, "#define MAX_TS %d /* tabela de variaveis */\n", imaxts); 111 | fprintf(fhead, "#define MAX_TC %d /* tabela de constantes */\n", imaxtc); 112 | fprintf(fhead, "#define MAX_TP %d /* tabela de temporarios */\n\n", imaxtp); 113 | fprintf(fhead, "#define MAX_TF %d /* tabela de funcoes */\n\n", imaxtf); 114 | fprintf(fhead, "superTipo ts[MAX_TS];\n"); 115 | fprintf(fhead, "superTipo tc[MAX_TC];\n"); 116 | fprintf(fhead, "superTipo tp[MAX_TP];\n"); 117 | fprintf(fhead, "superFunc tf[MAX_TF];\n\n"); 118 | return 0; 119 | } 120 | ; 121 | 122 | bloco_comandos: 123 | preprocs INICIO ';' lista_comandos FIM ';' { $$ = opr(INICIO, 1, $4); } 124 | ; 125 | 126 | preprocs: 127 | preproc 128 | | preproc preproc 129 | | /* nada */ 130 | ; 131 | 132 | preproc: 133 | DEBUG ARVORE { debugArvore = 1; } 134 | | DEBUG TABELA { debugTabela = 1; } 135 | ; 136 | 137 | lista_comandos: 138 | comando { $$ = $1; } 139 | | lista_comandos comando { $$ = opr('l', 2, $1, $2); } /* l para lista de comandos */ 140 | ; 141 | 142 | comando: 143 | ';' /* nop ; */ { $$ = opr(';', 2, NULL, NULL); } 144 | | expr ';' { $$ = $1; } 145 | | INT IDENT ';' { $$ = opr(INT, 1, conv($2)); } 146 | | REAL IDENT ';' { $$ = opr(REAL, 1, conv($2)); } 147 | | TEXTO IDENT ';' { $$ = opr(TEXTO, 1, conv($2)); } 148 | | SE '(' expr ')' ENTAO comando { $$ = opr(SE, 2, $3, $6); } 149 | | SE '(' expr ')' ENTAO comando SENAO comando { $$ = opr(SE, 3, $3, $6, $8); } 150 | | ENQUANTO '(' expr ')' comando { $$ = opr(ENQUANTO, 2, $3, $5); } 151 | | PARA '(' comando expr ';' comando ')' comando { $$ = opr(PARA, 4, $3, $4, $6, $8); } 152 | | ABORTE ';' { $$ = opr(ABORTE, 0); } 153 | | IMPRIMA expr ';' { $$ = opr(IMPRIMA, 1, $2); } 154 | | LEIA IDENT ';' { $$ = opr(LEIA, 1, conv($2)); } 155 | | SAIA expr ';' { $$ = opr(SAIA, 1, $2); } 156 | | bloco_comandos { $$ = $1; } 157 | ; 158 | 159 | expr: 160 | INTCON { $$ = conv($1); } 161 | | REALCON { $$ = conv($1); } 162 | | TEXTOCON { $$ = conv($1); } 163 | | IDENT { $$ = conv($1); } 164 | | IDENT '=' expr { $$ = opr('=', 2, conv($1), $3); } 165 | | IDENT '(' expr ')' { $$ = opr(FUNC, 2, conv($1), $3); } 166 | | '-' expr %prec UMENOS { $$ = opr(UMENOS, 1, $2); } 167 | | expr '+' expr { $$ = opr('+', 2, $1, $3); } 168 | | expr '-' expr { $$ = opr('-', 2, $1, $3); } 169 | | expr '*' expr { $$ = opr('*', 2, $1, $3); } 170 | | expr '/' expr { $$ = opr('/', 2, $1, $3); } 171 | | expr '%' expr { $$ = opr('%', 2, $1, $3); } 172 | | expr GE expr { $$ = opr(GE, 2, $1, $3); } 173 | | expr LE expr { $$ = opr(LE, 2, $1, $3); } 174 | | expr NE expr { $$ = opr(NE, 2, $1, $3); } 175 | | expr EQ expr { $$ = opr(EQ, 2, $1, $3); } 176 | | expr GT expr { $$ = opr(GT, 2, $1, $3); } 177 | | expr LT expr { $$ = opr(LT, 2, $1, $3); } 178 | | expr E expr { $$ = opr(E, 2, $1, $3); } 179 | | expr OU expr { $$ = opr(OU, 2, $1, $3); } 180 | | NAO expr { $$ = opr(NAO, 1, $2); } 181 | | '(' expr ')' { $$ = opr('(', 1, $2); } 182 | ; 183 | 184 | %% 185 | 186 | /* Acha/cria ID e retorna o ponteiro para a tabelaSimb */ 187 | tabelaSimb *achaId(char *nome) 188 | { 189 | char *p; 190 | tabelaSimb *ps; 191 | 192 | for(ps=tabSimb; ps < &tabSimb[MAX_SIMB]; ps++) 193 | { 194 | if(ps->idNome && !strcmp(ps->idNome, nome)) /* encontrou ? */ 195 | return ps; /* sim ! */ 196 | if(!ps->idNome) /* ponteiro livre ? */ 197 | { 198 | ps->tipoD = tipoIdIndef; 199 | ps->idNome = strdup(nome); 200 | return ps; 201 | } 202 | } 203 | yyerror("Tabela de simbolos cheia!"); /* caso contrario */ 204 | exit(1); 205 | } 206 | 207 | /* Acha/cria ConInt e retorna o ponteiro para a TS */ 208 | tabelaSimb *achaInt(int iv) 209 | { 210 | char *p; 211 | tabelaSimb *ps; 212 | int i; 213 | 214 | for(ps=tabSimb; ps < &tabSimb[MAX_SIMB]; ps++) 215 | { 216 | if(ps->idNome && ps->ival==iv && ps->tipoD==tipoConInt) /* encontrou ? */ 217 | return ps; /* sim ! */ 218 | if(!ps->idNome) /* ponteiro livre ? */ 219 | { 220 | i=geraTC(); 221 | ps->tipoD = tipoConInt; 222 | ps->idNome = strdup("#ConInt"); 223 | ps->ival = iv; 224 | ps->idx = i; 225 | return ps; 226 | } 227 | } 228 | yyerror("Tabela de simbolos cheia!"); /* caso contrario */ 229 | exit(1); 230 | } 231 | 232 | /* Acha/cria ConFloat e retorna o ponteiro para a TS */ 233 | tabelaSimb *achaFloat(float fv) 234 | { 235 | char *p; 236 | tabelaSimb *ps; 237 | int i; 238 | 239 | for(ps=tabSimb; ps < &tabSimb[MAX_SIMB]; ps++) 240 | { 241 | if(ps->idNome && ps->fval==fv && ps->tipoD==tipoConFloat) /* encontrou ? */ 242 | return ps; /* sim ! */ 243 | if(!ps->idNome) /* ponteiro livre ? */ 244 | { 245 | i=geraTC(); 246 | ps->tipoD = tipoConFloat; 247 | ps->idNome = strdup("#ConFloat"); 248 | ps->fval = fv; 249 | ps->idx = i; 250 | return ps; 251 | } 252 | } 253 | yyerror("Tabela de simbolos cheia!"); /* caso contrario */ 254 | exit(1); 255 | } 256 | 257 | /* Acha/cria ConStr e retorna o ponteiro para a TS */ 258 | tabelaSimb *achaStr(char *sv) 259 | { 260 | char *p; 261 | tabelaSimb *ps; 262 | int i; 263 | 264 | for(ps=tabSimb; ps < &tabSimb[MAX_SIMB]; ps++) 265 | { 266 | if(ps->idNome && !strcmp(ps->sval, sv)) /* encontrou ? */ 267 | return ps; /* sim ! */ 268 | if(!ps->idNome) /* ponteiro livre ? */ 269 | { 270 | i=geraTC(); 271 | ps->tipoD = tipoConStr; 272 | ps->idNome = strdup("#ConStr"); 273 | strcpy(ps->sval,sv); 274 | ps->idx = i; 275 | return ps; 276 | } 277 | } 278 | yyerror("Tabela de simbolos cheia!"); /* caso contrario */ 279 | exit(1); 280 | } 281 | 282 | /* Apenas procura (nao cria) todas funcoes, a partir da ultima procurada, ou NULL para a primeira */ 283 | tabelaSimb *achaFuncs(tabelaSimb *ultima) 284 | { 285 | char *p; 286 | tabelaSimb *ps; 287 | 288 | if(ultima==NULL) //null? a partir do primeiro 289 | ps=tabSimb; 290 | else 291 | ps=++ultima; //senao a partir do proximo 292 | while(ps < &tabSimb[MAX_SIMB]) 293 | { 294 | if(ps->tipoD>=tipoIdFuncInt) /* encontrou func? */ 295 | return ps; /* sim ! */ 296 | ps++; 297 | } 298 | return NULL; 299 | } 300 | 301 | /* Converte constante/identificador da TS em nodo */ 302 | nodo *conv(tabelaSimb *ps) 303 | { 304 | nodo *tn; 305 | 306 | if((tn=malloc(sizeof(nodo)))==NULL) /* aloca nodo */ 307 | yyerror("Faltou memoria (cod. 2: conf)"); 308 | 309 | tn->linha = lineno; 310 | tn->tipoN = tipoSimb; 311 | tn->pSimb = ps; 312 | return tn; 313 | } 314 | 315 | /* Converte operador em nodo */ 316 | nodo *opr(int oper, int nops, ...) 317 | { 318 | va_list ap; 319 | nodo *tn; 320 | size_t tam; 321 | int i; 322 | 323 | tam = sizeof(nodo) + (nops - 1) * sizeof(nodo *); 324 | 325 | if((tn=malloc(tam))==NULL) /* aloca nodo */ 326 | yyerror("Faltou memoria (cod. 4: opr)"); 327 | 328 | tn->linha = lineno; 329 | tn->tipoN = tipoOper; 330 | tn->opr.oper = oper; 331 | tn->opr.nops = nops; 332 | va_start(ap, nops); 333 | for(i=0; iopr.ptn[i] = va_arg(ap, nodo*); 335 | va_end(ap); 336 | 337 | return tn; 338 | } 339 | 340 | /* Libera memoria de um nodo tipoNodo */ 341 | void liberaNodo(nodo *tn) 342 | { 343 | int i; 344 | 345 | if(!tn) 346 | return; 347 | if(tn->tipoN == tipoOper) 348 | { 349 | for(i=0; iopr.nops; i++) 350 | liberaNodo(tn->opr.ptn[i]); 351 | } 352 | free(tn); 353 | } 354 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | 341 | -------------------------------------------------------------------------------- /quadruplas.h: -------------------------------------------------------------------------------- 1 | // Compilador PORTUGOL versao 2q 2 | // Autor: Ruben Carlo Benante 3 | // Email: benante@gmail.com 4 | // Data: 23/04/2009 5 | // Modificado: 24/05/2009 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #define STACK_SIZE 200 13 | #define FUNC_NAME_SIZE 32 14 | #define MAX_PARAM 4 15 | #define MAX_SVAL 256 16 | 17 | /* Tipos de Base */ 18 | typedef enum 19 | { 20 | tipoIndef, 21 | tipoInt, 22 | tipoFloat, 23 | tipoStr 24 | } tipoBase; 25 | 26 | typedef enum 27 | { 28 | tipoRetFuncInt, 29 | tipoRetFuncFloat, 30 | tipoRetFuncDouble, 31 | tipoRetFuncChar, 32 | tipoRetFuncStr, 33 | tipoRetFuncVoid, 34 | tipoRetFuncPVoid 35 | } tipoRetFunc; 36 | 37 | /* Super Tipo */ 38 | typedef struct 39 | { 40 | tipoBase tipo; 41 | int ival; 42 | float fval; 43 | char sval[MAX_SVAL]; 44 | } superTipo; 45 | 46 | /* Super Func */ 47 | typedef struct 48 | { 49 | tipoRetFunc tipoRet; 50 | tipoBase tipoParam[MAX_PARAM]; 51 | int numParam; 52 | char *idNome; 53 | int (*ifunc)(); //ponteiro para funcao que retorna inteiro 54 | float (*ffunc)(); //ponteiro para funcao que retorna float 55 | double (*dfunc)(); //ponteiro para funcao que retorna double 56 | char (*cfunc)(); //ponteiro para funcao que retorna char 57 | char *(*sfunc)(); //ponteiro para funcao que retorna ponteiro para char 58 | void (*vfunc)(); //ponteiro para a funcao que retorna void 59 | void *(*pfunc)(); //ponteiro para a funcao que retorna ponteiro para void 60 | } superFunc; 61 | 62 | #include "saida.h" 63 | 64 | superTipo gstack[STACK_SIZE]; //pilha 65 | int gsi=0; //indice da pilha geral 66 | 67 | #define jump_f(Q1,NUL1,LABEL) if(!(Q1.ival)) goto LABEL /* jump to LABEL if Q1.ival==false */ 68 | #define jump(NUL1,NUL2,LABEL) goto LABEL /* jump to LABEL */ 69 | void nop(superTipo *nul1, superTipo *nul2, superTipo *nul3); // do nothing 70 | void halt(superTipo *nul1, superTipo *nul2, superTipo *nul3); // abort with exit(1) 71 | 72 | void loadi(int i, int *nul1, superTipo *tn);// { tn->tipo=tipoIntInt; tn->ival=i; } 73 | void loadf(float f, float *nul1, superTipo *tn);// { tn->tipo=tipoIntFloat; tn->fval=f; } 74 | void loads(char *s, char *nul1, superTipo *tn);// { tn->tipo=tipoIntStr; strcpy(tn->sval,s); } 75 | 76 | void mov(superTipo q1, superTipo *nul1, superTipo *qres); //qres=q1; 77 | 78 | void uminus(superTipo q1, superTipo *nul1, superTipo *qres); // *qres = -q1 79 | void add(superTipo q1, superTipo q2, superTipo *qres); // *qres = q1 + q2 80 | void sub(superTipo q1, superTipo q2, superTipo *qres); // *qres = q1 - q2 81 | void mult(superTipo q1, superTipo q2, superTipo *qres); // *qres = q1 * q2 82 | void divi(superTipo q1, superTipo q2, superTipo *qres); // *qres = q1 / q2 83 | void mod(superTipo q1, superTipo q2, superTipo *qres); // *qres = q1 % q2 84 | void comp_eq(superTipo q1, superTipo q2, superTipo *qres); // *qres = (q1 == q2) 85 | void comp_ne(superTipo q1, superTipo q2, superTipo *qres); // *qres = (q1 != q2) 86 | void comp_gt(superTipo q1, superTipo q2, superTipo *qres); // *qres = (q1 > q2) 87 | void comp_lt(superTipo q1, superTipo q2, superTipo *qres); // *qres = (q1 < q2) 88 | void comp_ge(superTipo q1, superTipo q2, superTipo *qres); // *qres = (q1 >= q2) 89 | void comp_le(superTipo q1, superTipo q2, superTipo *qres); // *qres = (q1 <= q2) 90 | void rela_an(superTipo q1, superTipo q2, superTipo *qres); // *qres = (q1 && q2) 91 | void rela_or(superTipo q1, superTipo q2, superTipo *qres); // *qres = (q1 || q2) 92 | void rela_no(superTipo q1, superTipo *nul1, superTipo *qres); // *qres = (!q1) 93 | void param(superTipo q1, void *nul1, void *nul2); // push(q1) 94 | void call(char *q1, int q2, superTipo *qres); // *qres = f_name(a[1], ..., a[q2]); where q1:f_name, q2:quantity of param 95 | 96 | void push(superTipo g); // poe na pilha de execucao 97 | superTipo *pop(void); // tira da pilha de execucao 98 | 99 | /* ------------------------------------------------------------------------------------------------- */ 100 | 101 | /* auxiliar functions */ 102 | //--------------------------- 103 | void push(superTipo g) // poe na pilha de execucao geral //push to stack 104 | { 105 | gstack[gsi]=g; //copia por valor 106 | gsi++; 107 | if(gsi>=STACK_SIZE) 108 | { 109 | fprintf(stderr,"ASM Error: stack overflow.\n"); 110 | exit(1); 111 | } 112 | } 113 | 114 | superTipo *pop(void) // tira da pilha de execucao geral //pop from stack 115 | { 116 | superTipo *r; 117 | if(gsi<=0) 118 | { 119 | fprintf(stderr,"ASM Error: stack underflow.\n"); 120 | exit(1); 121 | } 122 | r=malloc(sizeof(superTipo)); 123 | *r=gstack[--gsi]; //copia por valor 124 | return(r); //&gstack[--gsi] 125 | } 126 | 127 | /* jump operations */ 128 | //--------------------------- 129 | //see above 130 | 131 | /* misc operations */ 132 | //--------------------------- 133 | void nop(superTipo *nul1, superTipo *nul2, superTipo *nul3) //nop : //do nothing 134 | { 135 | ; 136 | } 137 | 138 | void halt(superTipo *nul1, superTipo *nul2, superTipo *nul3) // abort with exit(1) 139 | { 140 | exit(1); 141 | } 142 | 143 | /* memory operations */ 144 | //--------------------------- 145 | void loadi(int i, int *nul1, superTipo *qres) 146 | { 147 | qres->tipo=tipoInt; 148 | qres->ival=i; 149 | qres->fval=0.0; 150 | qres->sval[0]='\0'; 151 | } 152 | 153 | void loadf(float f, float *nul1, superTipo *qres) 154 | { 155 | qres->tipo=tipoFloat; 156 | qres->ival=0; 157 | qres->fval=f; 158 | qres->sval[0]='\0'; 159 | } 160 | 161 | void loads(char *s, char *nul1, superTipo *qres) 162 | { 163 | qres->tipo=tipoStr; 164 | qres->ival=0; 165 | qres->fval=0.0; 166 | strcpy(qres->sval, s); 167 | } 168 | 169 | void mov(superTipo q1, superTipo *nul1, superTipo *qres) 170 | { 171 | qres->tipo=q1.tipo; 172 | if(q1.tipo==tipoInt) 173 | qres->ival=q1.ival; 174 | else if(q1.tipo==tipoFloat) 175 | qres->fval=q1.fval; 176 | else if(q1.tipo==tipoStr) 177 | strcpy(qres->sval, q1.sval); 178 | else 179 | { 180 | fprintf(stderr,"ASM Error: invalid mov operation.\n"); 181 | exit(1); 182 | } 183 | } 184 | 185 | /*mathematical operations */ 186 | //--------------------------- 187 | 188 | void uminus(superTipo q1, superTipo *nul1, superTipo *qres) 189 | { 190 | if(q1.tipo==tipoStr) 191 | { 192 | fprintf(stderr,"ASM Error: invalid uminus operation.\n"); 193 | exit(1); 194 | } 195 | qres->tipo=q1.tipo; 196 | if(q1.tipo==tipoInt) 197 | qres->ival=-q1.ival; 198 | else 199 | qres->fval=-q1.fval; 200 | } 201 | 202 | void add(superTipo q1, superTipo q2, superTipo *qres) 203 | { 204 | 205 | float arg1, arg2; 206 | 207 | if((q1.tipo == tipoStr || q2.tipo == tipoStr) && (q1.tipo != tipoStr || q2.tipo != tipoStr)) 208 | { 209 | fprintf(stderr,"ASM Error: invalid add operation.\n"); 210 | exit(1); 211 | } 212 | 213 | if(q1.tipo == tipoStr) //se um eh, ambos sao 214 | { 215 | qres->tipo=tipoStr; 216 | strcpy(qres->sval, q1.sval); 217 | strcat(qres->sval, q2.sval); 218 | return; 219 | } 220 | 221 | if(q1.tipo == tipoFloat) 222 | arg1=q1.fval; 223 | else 224 | arg1=(float)q1.ival; 225 | if(q2.tipo == tipoFloat) 226 | arg2=q2.fval; 227 | else 228 | arg2=(float)q2.ival; 229 | 230 | if(q1.tipo == tipoFloat || q2.tipo == tipoFloat) 231 | { 232 | qres->fval=arg1 + arg2; 233 | qres->tipo=tipoFloat; 234 | } 235 | else 236 | { 237 | qres->ival=(int)(arg1 + arg2); 238 | qres->tipo=tipoInt; 239 | } 240 | } 241 | 242 | void sub(superTipo q1, superTipo q2, superTipo *qres) 243 | { 244 | 245 | float arg1, arg2; 246 | 247 | if(q1.tipo == tipoStr || q2.tipo == tipoStr) 248 | { 249 | fprintf(stderr,"ASM Error: invalid sub operation.\n"); 250 | exit(1); 251 | } 252 | 253 | if(q1.tipo == tipoFloat) 254 | arg1=q1.fval; 255 | else 256 | arg1=(float)q1.ival; 257 | if(q2.tipo == tipoFloat) 258 | arg2=q2.fval; 259 | else 260 | arg2=(float)q2.ival; 261 | 262 | if(q1.tipo == tipoFloat || q2.tipo == tipoFloat) 263 | { 264 | qres->fval=arg1 - arg2; 265 | qres->tipo=tipoFloat; 266 | } 267 | else 268 | { 269 | qres->ival=(int)(arg1 - arg2); 270 | qres->tipo=tipoInt; 271 | } 272 | } 273 | 274 | void mult(superTipo q1, superTipo q2, superTipo *qres) 275 | { 276 | 277 | float arg1, arg2; 278 | 279 | if(q1.tipo == tipoStr || q2.tipo == tipoStr) 280 | { 281 | fprintf(stderr,"ASM Error: invalid mult operation.\n"); 282 | exit(1); 283 | } 284 | 285 | if(q1.tipo == tipoFloat) 286 | arg1=q1.fval; 287 | else 288 | arg1=(float)q1.ival; 289 | if(q2.tipo == tipoFloat) 290 | arg2=q2.fval; 291 | else 292 | arg2=(float)q2.ival; 293 | 294 | if(q1.tipo == tipoFloat || q2.tipo == tipoFloat) 295 | { 296 | qres->fval=arg1 * arg2; 297 | qres->tipo=tipoFloat; 298 | } 299 | else 300 | { 301 | qres->ival=(int)(arg1 * arg2); 302 | qres->tipo=tipoInt; 303 | } 304 | } 305 | 306 | void divi(superTipo q1, superTipo q2, superTipo *qres) 307 | { 308 | 309 | float arg1, arg2; 310 | 311 | if(q1.tipo == tipoStr || q2.tipo == tipoStr) 312 | { 313 | fprintf(stderr,"ASM Error: invalid divi operation.\n"); 314 | exit(1); 315 | } 316 | 317 | if(q2.tipo == tipoFloat) 318 | arg2=q2.fval; 319 | else 320 | arg2=(float)q2.ival; 321 | if(arg2==0.0) 322 | { 323 | fprintf(stderr,"ASM Error: division by zero.\n"); 324 | exit(1); 325 | } 326 | if(q1.tipo == tipoFloat) 327 | arg1=q1.fval; 328 | else 329 | arg1=(float)q1.ival; 330 | 331 | if(q1.tipo == tipoFloat || q2.tipo == tipoFloat) 332 | { 333 | qres->fval=arg1 / arg2; 334 | qres->tipo=tipoFloat; 335 | } 336 | else 337 | { 338 | qres->ival=(int)(arg1 / arg2); 339 | qres->tipo=tipoInt; 340 | } 341 | } 342 | 343 | void mod(superTipo q1, superTipo q2, superTipo *qres) // *qres = q1 % q2 344 | { 345 | 346 | int arg1, arg2; 347 | 348 | if(q1.tipo == tipoStr || q2.tipo == tipoStr) 349 | { 350 | fprintf(stderr,"ASM Error: invalid mod operation.\n"); 351 | exit(1); 352 | } 353 | 354 | if(q2.tipo == tipoFloat) 355 | arg2=(int)q2.fval; 356 | else 357 | arg2=q2.ival; 358 | if(arg2==0) 359 | { 360 | fprintf(stderr,"ASM Error: mod division by zero.\n"); 361 | exit(1); 362 | } 363 | if(q1.tipo == tipoFloat) 364 | arg1=(int)q1.fval; 365 | else 366 | arg1=q1.ival; 367 | 368 | qres->tipo=tipoInt; 369 | qres->ival=arg1 % arg2; 370 | } 371 | 372 | /* logical operations */ 373 | //--------------------------- 374 | 375 | void comp_eq(superTipo q1, superTipo q2, superTipo *qres) 376 | { 377 | 378 | float arg1, arg2; 379 | 380 | if((q1.tipo == tipoStr || q2.tipo == tipoStr) && (q1.tipo != tipoStr || q2.tipo != tipoStr)) 381 | { 382 | fprintf(stderr,"ASM Error: invalid comp_eq operation.\n"); 383 | exit(1); 384 | } 385 | 386 | qres->tipo=tipoInt; 387 | if(q1.tipo == tipoStr) 388 | { 389 | qres->ival = !(strcmp(q1.sval, q2.sval)); 390 | return; 391 | } 392 | 393 | if(q1.tipo == tipoFloat) 394 | arg1=q1.fval; 395 | else 396 | arg1=(float)q1.ival; 397 | if(q2.tipo == tipoFloat) 398 | arg2=q2.fval; 399 | else 400 | arg2=(float)q2.ival; 401 | 402 | qres->ival=(int)(arg1 == arg2); 403 | } 404 | 405 | void comp_ne(superTipo q1, superTipo q2, superTipo *qres) 406 | { 407 | 408 | float arg1, arg2; 409 | 410 | if((q1.tipo == tipoStr || q2.tipo == tipoStr) && (q1.tipo != tipoStr || q2.tipo != tipoStr)) 411 | { 412 | fprintf(stderr,"ASM Error: invalid comp_ne operation.\n"); 413 | exit(1); 414 | } 415 | 416 | qres->tipo=tipoInt; 417 | if(q1.tipo == tipoStr) 418 | { 419 | qres->ival = !!(strcmp(q1.sval, q2.sval)); 420 | return; 421 | } 422 | 423 | if(q1.tipo == tipoFloat) 424 | arg1=q1.fval; 425 | else 426 | arg1=(float)q1.ival; 427 | if(q2.tipo == tipoFloat) 428 | arg2=q2.fval; 429 | else 430 | arg2=(float)q2.ival; 431 | 432 | qres->ival=(int)(arg1 != arg2); 433 | } 434 | 435 | void comp_gt(superTipo q1, superTipo q2, superTipo *qres) 436 | { 437 | 438 | float arg1, arg2; 439 | 440 | if((q1.tipo == tipoStr || q2.tipo == tipoStr) && (q1.tipo != tipoStr || q2.tipo != tipoStr)) 441 | { 442 | fprintf(stderr,"ASM Error: invalid comp_gt operation.\n"); 443 | exit(1); 444 | } 445 | 446 | qres->tipo=tipoInt; 447 | if(q1.tipo == tipoStr) 448 | { 449 | qres->ival = (strcmp(q1.sval, q2.sval)>0); 450 | return; 451 | } 452 | 453 | if(q1.tipo == tipoFloat) 454 | arg1=q1.fval; 455 | else 456 | arg1=(float)q1.ival; 457 | if(q2.tipo == tipoFloat) 458 | arg2=q2.fval; 459 | else 460 | arg2=(float)q2.ival; 461 | 462 | qres->ival=(int)(arg1 > arg2); 463 | } 464 | 465 | 466 | void comp_lt(superTipo q1, superTipo q2, superTipo *qres) 467 | { 468 | float arg1, arg2; 469 | 470 | if((q1.tipo == tipoStr || q2.tipo == tipoStr) && (q1.tipo != tipoStr || q2.tipo != tipoStr)) 471 | { 472 | fprintf(stderr,"ASM Error: invalid comp_lt operation.\n"); 473 | exit(1); 474 | } 475 | 476 | qres->tipo=tipoInt; 477 | if(q1.tipo == tipoStr) 478 | { 479 | qres->ival = (strcmp(q1.sval, q2.sval)<0); 480 | return; 481 | } 482 | 483 | if(q1.tipo == tipoFloat) 484 | arg1=q1.fval; 485 | else 486 | arg1=(float)q1.ival; 487 | if(q2.tipo == tipoFloat) 488 | arg2=q2.fval; 489 | else 490 | arg2=(float)q2.ival; 491 | 492 | qres->ival=(int)(arg1 < arg2); 493 | } 494 | 495 | void comp_ge(superTipo q1, superTipo q2, superTipo *qres) 496 | { 497 | float arg1, arg2; 498 | 499 | if((q1.tipo == tipoStr || q2.tipo == tipoStr) && (q1.tipo != tipoStr || q2.tipo != tipoStr)) 500 | { 501 | fprintf(stderr,"ASM Error: invalid comp_ge operation.\n"); 502 | exit(1); 503 | } 504 | 505 | qres->tipo=tipoInt; 506 | if(q1.tipo == tipoStr) 507 | { 508 | qres->ival = (strcmp(q1.sval, q2.sval)>=0); 509 | return; 510 | } 511 | 512 | if(q1.tipo == tipoFloat) 513 | arg1=q1.fval; 514 | else 515 | arg1=(float)q1.ival; 516 | if(q2.tipo == tipoFloat) 517 | arg2=q2.fval; 518 | else 519 | arg2=(float)q2.ival; 520 | 521 | qres->ival=(int)(arg1 >= arg2); 522 | } 523 | 524 | void comp_le(superTipo q1, superTipo q2, superTipo *qres) 525 | { 526 | float arg1, arg2; 527 | 528 | if((q1.tipo == tipoStr || q2.tipo == tipoStr) && (q1.tipo != tipoStr || q2.tipo != tipoStr)) 529 | { 530 | fprintf(stderr,"ASM Error: invalid comp_le operation.\n"); 531 | exit(1); 532 | } 533 | 534 | qres->tipo=tipoInt; 535 | if(q1.tipo == tipoStr) 536 | { 537 | qres->ival = (strcmp(q1.sval, q2.sval)<=0); 538 | return; 539 | } 540 | 541 | if(q1.tipo == tipoFloat) 542 | arg1=q1.fval; 543 | else 544 | arg1=(float)q1.ival; 545 | if(q2.tipo == tipoFloat) 546 | arg2=q2.fval; 547 | else 548 | arg2=(float)q2.ival; 549 | 550 | qres->ival=(int)(arg1 <= arg2); 551 | } 552 | 553 | /* relational operations */ 554 | //--------------------------- 555 | 556 | void rela_an(superTipo q1, superTipo q2, superTipo *qres) 557 | { 558 | float arg1, arg2; 559 | 560 | if(q1.tipo == tipoStr || q2.tipo == tipoStr) 561 | { 562 | fprintf(stderr,"ASM Error: invalid rela_an operation.\n"); 563 | exit(1); 564 | } 565 | 566 | qres->tipo=tipoInt; 567 | if(q1.tipo == tipoFloat) 568 | arg1=q1.fval; 569 | else 570 | arg1=(float)q1.ival; 571 | if(q2.tipo == tipoFloat) 572 | arg2=q2.fval; 573 | else 574 | arg2=(float)q2.ival; 575 | 576 | qres->ival=(int)(arg1 && arg2); 577 | } 578 | 579 | void rela_or(superTipo q1, superTipo q2, superTipo *qres) 580 | { 581 | float arg1, arg2; 582 | 583 | if(q1.tipo == tipoStr || q2.tipo == tipoStr) 584 | { 585 | fprintf(stderr,"ASM Error: invalid rela_or operation.\n"); 586 | exit(1); 587 | } 588 | 589 | qres->tipo=tipoInt; 590 | if(q1.tipo == tipoFloat) 591 | arg1=q1.fval; 592 | else 593 | arg1=(float)q1.ival; 594 | if(q2.tipo == tipoFloat) 595 | arg2=q2.fval; 596 | else 597 | arg2=(float)q2.ival; 598 | 599 | qres->ival=(int)(arg1 || arg2); 600 | } 601 | 602 | void rela_no(superTipo q1, superTipo *nul1, superTipo *qres) 603 | { 604 | 605 | if(q1.tipo == tipoStr) 606 | { 607 | fprintf(stderr,"ASM Error: invalid rela_no operation.\n"); 608 | exit(1); 609 | } 610 | 611 | qres->tipo=tipoInt; 612 | if(q1.tipo == tipoFloat) 613 | qres->ival=(int)(!(q1.fval)); 614 | else 615 | qres->ival=!(q1.ival); 616 | } 617 | 618 | /*stack and function operations */ 619 | //--------------------------- 620 | 621 | void param(superTipo q1, void *nul1, void *nul2) 622 | { 623 | push(q1); 624 | } 625 | 626 | void call(char *q1, int i, superTipo *qres) 627 | { 628 | int j=0, idx; 629 | superTipo *g[MAX_PARAM];//maximo funcao com 4 argumentos f(a0, a1, a2, a3); 630 | 631 | if(i>MAX_PARAM) 632 | { 633 | fprintf(stderr, "ASM Error: cant call function with more than %d (MAX_PARAM) parameters.\n", MAX_PARAM); 634 | exit(1); 635 | } 636 | 637 | for(j=0; jtipo==tipoStr) 654 | (*tf[idx].vfunc)("%s\n", g[0]->sval); //printf("%s\n",sval); 655 | else if(g[0]->tipo==tipoInt) 656 | (*tf[idx].vfunc)("%d\n", g[0]->ival); //printf("%d\n",ival); 657 | else /* tipoFloat */ 658 | (*tf[idx].vfunc)("%.2f\n", g[0]->fval); //printf("%.2f\n",fval); 659 | break; 660 | case 1: //scanf 661 | (*tf[idx].vfunc)("%f", &qres->fval); //scanf("%f",&ts[1]); 662 | qres->tipo=tipoFloat; 663 | break; 664 | case 2: //exit 665 | (*tf[idx].vfunc)(g[0]->ival); //exit(ival) 666 | break; 667 | case 3: //sqrt 668 | qres->fval=(*tf[idx].dfunc)(g[0]->fval); //sqrt(fval) 669 | qres->tipo=tipoFloat; 670 | break; 671 | case 4: //exp 672 | qres->fval=(*tf[idx].dfunc)(g[0]->fval); //sqrt(fval) 673 | qres->tipo=tipoFloat; 674 | break; 675 | default: 676 | fprintf(stderr, "ASM Error: function not in tf[] table. (default switch)\n"); 677 | exit(1); 678 | } 679 | } 680 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Como contribuir 2 | 3 | Sua contribuição ao código é essencial pois é através dela que você demonstra o seu conhecimento, seu entendimento das características (das básicas até as mais sutís) do programa, e também a sua atividade e determinação. 4 | 5 | Para que suas contribuições sejam maximizadas (o que impacta positivamente sua nota), siga este pequeno guia de 'Como contribuir'. 6 | 7 | # Iniciando 8 | 9 | Tenha certeza de que sua conta está devidamente configurada. Cheque os seguintes itens: 10 | 11 | * Cadastre-se no servidor Hydra 12 | * Cadastre-se no Dropbox 13 | * Cadastre-se no grupo por email Contauto (google groups, prefira gmail) 14 | * Cadastre-se no GitHub 15 | * Baixe para seu computador/notebook os textos do Hydrabox (Dropbox) 16 | - Leia-os atentamente. Lá as explicações são muito mais detalhadas que as que você lerá neste pequeno guia 17 | * No Hydra, crie uma chave SSH 18 | * Adicione sua chave SSH pública para login no Github 19 | * Nas configurações do git no Hydra, confira seu nome completo e email (o mesmo que usou para se cadastrar no GitHub) 20 | * Nas configurações do GitHub: 21 | - coloque seu nome completo no perfil 22 | - habilite mostrar suas contribuições privadas nas estatísticas 23 | - aceite o convite para o time do BecoSystems da disciplina/semestre que está cursando 24 | - acesse o link do GitHub classroom para iniciar uma atividade (pegue o link com o professor) 25 | * Siga o código de [conduta do bom programador BecoSystems](BECOSYSTEMS_CODE_OF_CONDUCT.md) 26 | 27 | # Repositório 28 | 29 | Os trabalhos podem ser em grupos ou individuais, com ou sem repositório _upstream_. Confirme em aula como será cada exercício. 30 | 31 | ## Trabalhos pelo Classroom (assignments) 32 | 33 | * O professor enviará um email com o link para o cadastro do grupo e o repositório será criado automaticamente para cada grupo. 34 | * Não tem _upstream_. 35 | * Todos devem fazer o clone do repositório no Hydra. 36 | * Ao final, faça também um clone (ou copie a pasta clonada em _rascunhos_) na pasta _trabalhos_ no Hydra. 37 | 38 | ## Trabalhos em grupos criados manualmente (BecoSystems) 39 | 40 | * Os alunos se dividem em grupos e um representante cria o repositório e adiciona todos os outros como colaboradores. 41 | * Não tem _upstream_. 42 | * Todos devem fazer o clone do repositório no Hydra. 43 | * Ao final, faça também um clone (ou copie a pasta clonada em _rascunhos_) na pasta _trabalhos_ no Hydra. 44 | 45 | ## Trabalhos em grupo com _upstream_ 46 | 47 | * O professor cria o repositório _upstream_ e adiciona os colaboradores com permissão de apenas leitura. 48 | * Um representante de cada time fará um _fork_ 49 | * Este representante adiciona todos os outros membros do time como colaboradores deste _fork_. Ninguém mais faz _fork_. 50 | * O representante também configura o seu _fork_ para permitir a criação de _issues_. 51 | * Os _issues_ no _upstream_ são usados para comunicar com todos os times e tratar de problemas que envolvem todos globalmente (como API por exemplo). 52 | * Os _issues_ no _origin_ (repositório do _fork_ feito por cada time) são usados para comunicação interna do time, para tratar problemas locais. 53 | * O código vai sendo colaborativamente adicionado no _upstream_ pelo professor, conforme cada aluno faz um _pull request_ 54 | * Todos devem fazer o clone do repositório no Hydra. 55 | * Ao final, faça também um clone (ou copie a pasta clonada em _rascunhos_) na pasta _trabalhos_ no Hydra. 56 | 57 | ## Trabalhos individuais com _upstream_ 58 | 59 | * O professor cria o repositório _upstream_ e adiciona os colaboradores com permissão de apenas leitura. 60 | * Cada aluno faz seu _fork_ e trabalha de forma individual. 61 | * O código vai sendo colaborativamente adicionado no _upstream_ pelo professor, conforme cada aluno faz um _pull request_ 62 | * Todos devem fazer o clone do repositório no Hydra. 63 | * Ao final, faça também um clone (ou copie a pasta clonada em _rascunhos_) na pasta _trabalhos_ no Hydra. 64 | 65 | # Antes de mais nada! 66 | 67 | * Confira se você está trabalhando no ramo **feature-nome** ou **develop** 68 | * **NUNCA** (never, jamais, mai, noot, nie, em tempo algum) o _master_ ficará na **frente** do _develop_ 69 | 70 | # Editor de textos 71 | 72 | O editor de textos usados é o _vi_ (lê-se "vi-ai") ou _vim_ (que é o _vi improved_), disponível na quase totalidade dos sistemas Linux, Unix e Mac (existe também para instalação gratuita em Windows). Sua grande vantagem é a operação remota, além de uma quantidade enorme de comandos para configuração e facilidades para programação. 73 | 74 | O _vi_ é um excelente editor para quem o conhece. Para quem não o conhece, é difícil e pode ser muito frustrante. 75 | 76 | Felizmente existe um excelente arquivo em _PDF_ na pasta hydrabox com explicações sobre a maioria dos comandos. Não deixe de ler. 77 | 78 | # Atividade registrada 79 | 80 | Tenha certeza de seguir estas recomendações para ter um maior aproveitamento: 81 | 82 | * Se possível, faça login todo dia no Hydra 83 | * Os comandos lá digitados são registrados e contam para sua atividade 84 | * Leia o arquivo sobre Linux no hydrabox 85 | * Configure sua conta, ajuste seu arquivo _.project_ com seus hobbies, faça bom uso de toda a ferramenta, explore, aprenda. 86 | * Confira suas estatísticas no GitHub: seu perfil pessoal e as estatísticas de cada repositório que estiver trabalhando. Tenha certeza que seus _commits_ estão sendo registrados em seu nome e que aparece nos gráficos. 87 | * Desafio: Mantenha a grade do seu perfil com quadradinhos verdinhos durante todo o semestre! E não pare mais: incorpore o GitHub em todos seus projetos de faculdade e leve-o para sua vida. É a rede social do programador, muito mais útil que o Facebook! ;) 88 | 89 | # Arquivos no repositório 90 | 91 | * Arquivo fonte e arquivos de bibliotecas 92 | * As extensões são, fonte e binário, respectivamente (exemplo para exercício 11): 93 | - Linguagem C: ex11.c e ex11 ou ex11.x 94 | - Biblioteca em C: ex11.h 95 | - PROLOG: ex11.pl (e se houver, ex11.pl.x) 96 | - Portugol: ex11.gpt e ex11.gpt.x 97 | - Texto Markdown: ex11.md 98 | - Bash Script: ex11.sh 99 | - Assembly: ex11.s (sintaxe AT&T) 100 | * AUTHORS: lista os autores do programa (em grupo ou individual) 101 | * LICENSE: a licença do programa (prefira GNU GPL v2, MIT ou BSD-3) 102 | * VERSION: contém o número da versão atual (de preferência modificado automaticamente pelo _make_) 103 | * makefile: o _script_ rodado pelo comando _make_ 104 | * README.md: em sintaxe de Markdown, contém a "capa" que aparece no GitHub. Deve ter uma explicação sobre: 105 | - O que é o programa 106 | - Como compilar 107 | - Quais opções para iniciar a execução 108 | - Como funciona, quais opções durante execução 109 | - Lista de autores 110 | - Licença 111 | - Referências: Links para páginas relevantes 112 | * Outros arquivos relevantes 113 | * Índice _ctags_ opcional 114 | * _.gitignore_ : faz o git ignorar certos arquivos 115 | * _.gitattributes_ : permite configurar atributos por arquivo (veja abaixo) 116 | 117 | # Formatação 118 | 119 | ## O estilo de indentação 120 | 121 | ### Linguagem C 122 | 123 | * A indentação é feita de acordo com o estilo **A1** descrito pelo _astyle_, também conhecido por _--style=allman_, _--style=bsd_ ou _--style=break_. 124 | 125 | O estilo _Allman_ é um entre mais de 15 estilos e variantes disponíveis e encontradas em vários tipos de código. Não misture os estilos. Este estilo utiliza a seguinte sintaxe, chamada de _broken brackets_ (ou chaves quebradas). Atente para os espaços entre operadores e mudanças de linhas no exemplo abaixo: 126 | 127 | ``` 128 | /** 129 | * @ingroup GrupoUnico 130 | * @brief Breve descricao blablabla 131 | * ... 132 | */ 133 | int foonc(int is_bar[MAX], int x) 134 | { 135 | int p; /* a really though condition */ 136 | 137 | p = !(is_bar[0] || isBar[1]); 138 | 139 | if(is_bar[x] == 2 && !p) 140 | { 141 | bar(p + 1); 142 | return 1; 143 | } 144 | else 145 | return 0; 146 | } 147 | 148 | ``` 149 | 150 | ### PROLOG 151 | 152 | * Use 4 espaços para indentar (não use _TAB's_) 153 | * Não use `;` para `OR`. Prefira repetir a regra (ou fato, claro). 154 | * Deixe um espaço entre a cabeça da regra e o `se` (`:-`) 155 | 156 | Um exemplo de trecho de código seria: 157 | 158 | ``` 159 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 160 | % Aqui vai a licenca, copyright, etc. 161 | % Uma breve descrição do programa 162 | % Autor, data, email para contato 163 | 164 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 165 | % Sessao de modulos 166 | 167 | :- dynamic([mulher/1]). 168 | 169 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 170 | % Sessao da base de conhecimento estatico 171 | 172 | % Lista de homens, vivos e mortos 173 | homem(socrates). 174 | homem(platao). 175 | 176 | % Lista de homens ainda vivos 177 | vivo(platao). 178 | 179 | % Lista de objetos inanimados 180 | pedra(diamante). 181 | pedra(rubi). 182 | 183 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 184 | % Sessao de regras sobre a mortalidade 185 | 186 | % indica as condicoes necessarias para um objeto ser mortal 187 | % caso homem 188 | mortal(X) :- 189 | vivo(X), 190 | homem(X). 191 | 192 | % caso mulher (clausula dinamica) 193 | mortal(X) :- 194 | vivo(X), 195 | mulher(X). % BUG: lembrar de fazer assert! 196 | ... 197 | ``` 198 | 199 | Conheça todos os estilos na [página de documentação do astyle](http://astyle.sourceforge.net/astyle.html). 200 | 201 | * Para aplicar o estilo no seu código, pode-se rodar o programa _$astyle -A1 ex11.c_ 202 | 203 | ## Dicas para um bom código fonte: 204 | 205 | ### Comentários 206 | 207 | * Use comentários /* estilo C */ 208 | * Coloque um espaço após o /* e um antes do */ 209 | * Faça comentários _em linha_ nas declarações de variável. `int i; /* indice geral */` 210 | * Evite comentários em linha em outros locais 211 | * Na medida do possível e do seu conhecimento, escreva tudo em **inglês**, desde nomes de variáveis até comentários. Se for importante usar português, então escreva as variáveis em inglês e os comentários nas **duas** línguas. Caso não seja possível, tudo bem usar apenas português. 212 | * Coloque os comentários na linha _anterior_ ao bloco ou comando a comentar 213 | * Não use acentos (nem c-cedilhas) no código ou comentários 214 | * Use as palavras nos comentários: 215 | - /* TODO: alguma tarefa */ : para indicar algo que falta fazer 216 | - /* BUG: esta errado assim e assado */ : para indicar um bug conhecido que precisa ser corrigido no futuro. 217 | 218 | ### Comentários DOXYGEN 219 | 220 | Antes de cada função, coloque comentários na sintaxe _DOXYGEN_. O mínimo necessário para bem explicar uma função é detalhar: 221 | 222 | * Grupo do módulo: `@ingroup` 223 | * Resumo: `@brief` 224 | * Detalhes: `@details` 225 | * Opcional, pré-condições: `@pre` 226 | * Parâmetros de entrada: `@param[in]` 227 | * Parâmetros de saída: `@param[out]` 228 | * Parâmetros de entrada e saída: `@param[in, out]` 229 | * Valor de retorno: `@return` ou `@retval` (ou ambos) 230 | * Opcional, um aviso: `@warning` 231 | * Opcional, se a função está depreciada: `@deprecated` 232 | * Opcional, indicar funções semelhantes: `@see` 233 | * Opcional, indicar _bugs_: `@bug` 234 | * Opcional, indicar _to do_: `@todo` 235 | * Opcional, escrever uma nota: `@note` 236 | * Autor: `@author` 237 | * Opcional, colocar versão: `@version` 238 | * Data que foi escrita/modificada: `@date` (formato YYYY-MM-DD, ano, mes, dia) 239 | * Opcional, caso diferente do resto do código, colocar a licença de _copyright_: `@copyright` 240 | 241 | O exemplo abaixo mostra somente os campos _obrigatórios_, e descreve hipotéticas variáveis _i_, _o_ e _z_: 242 | 243 | ``` 244 | 245 | /** 246 | * @ingroup Modulo 247 | * @brief Breve descricao 248 | * @details Descricao detalhada 249 | * que pode estar em multiplas linhas 250 | * 251 | * @param[in] i indice de entrada 252 | * @param[out] o indice recalculado de saida 253 | * @param[in,out] z Entra com um valor blablabla e devolve blebleble 254 | * 255 | * @return Descricao do que a funcao retorna 256 | * @author Ruben Carlo Benante 257 | * @date 2016-06-05 258 | */ 259 | ``` 260 | 261 | ### No meio do código 262 | 263 | * Apague espaços sobrando ao final da linha 264 | * Não inclua espaços após `(`, `[`, `{` ou antes de `}`, `]` e `)` 265 | * Use espaços após vírgulas e ponto-e-vírgulas 266 | * Use espaços em volta de operadores (exceto os unários como `!`) 267 | * Não cometa erros de grafia (**não** use acentos!) 268 | * Não alinhe tokens verticalmente em linhas consecutivas 269 | * Use indentação de 4 espaços (não use _TABS_) 270 | * Se quebrar uma linha, indente-a 4 espaços 271 | * Use uma linha em branco entre métodos, funções ou blocos lógicos importantes 272 | * Use final de linha de um byte (`\n`) **estilo Unix** (\*) 273 | * Deixe uma linha em branco ao final do arquivo [conforme padrão POSIX](http://unix.stackexchange.com/questions/23903/should-i-end-my-text-script-files-with-a-newline) 274 | 275 | ### Variáveis 276 | 277 | * Variáveis com letras maiúsculas somente se: 278 | - São PROLOG, claro ;) 279 | - São MACROS (logo não são _variáveis_) em C (exemplo: `#define CINCO 1`) 280 | - São _MUIIIITO_ importantes e precisam de algum destaque. Não tente usar assim, pois você provavelmente não vai convencer ninguém. ;) 281 | * Use nomes claros para as variáveis 282 | * O nome da variável deve indicar sua _intenção_, i.é., o dado que ela carrega. 283 | * Prefira nomes que demonstrem o conceito geral do domínio, ao invés dos padrões que eles implementam. 284 | * Não faça nomes gigantes. Um tamanho _máximo_ que já não fica tão bom é até 15 caracteres. Tente nomes menores, até 10 no pior caso. 285 | * Use sublinhados para _sufixos_ apenas se for criar variáveis que tenham alguma característica em comum. Exemplo: `salario_antes` e `salario_depois`. Se existirem muitas características em comum em um tipo de dados, considere agrupar com _struct_ 286 | * Não coloque o _tipo_ no nome da variável. Exemplo: `vetor_de_alunos`. 287 | * Coloque `t_` no início de _typedef_. Exemplo: `typedef int t_meuint;` 288 | * Coloque `st_` no início de _structs_. Exemplo: `struct st_concreto { ... };` 289 | * Coloque `s` no início de variáveis _string_. Exemplo: `char snome[MAX];` 290 | * Coloque `p` no início de ponteiros. Exemplo: `t_carro *pcarro;` ou `char *pnome;`. 291 | * Nomeie uma _enum_ (enumeração) pelo substantivo comum do objeto que ela enumera. 292 | 293 | ### Organização 294 | 295 | A ordem que o esqueleto do programa deve ter é como segue: 296 | 297 | #### Em linguagem C 298 | 299 | * Comentário com _copyright_, descrição do programa, autor, contato e data 300 | * Comentários com uma introdução à leitura do código, explicações gerais, compilação, etc. 301 | * O(s) `#include <...>` 302 | * O(s) `#include "..."` 303 | * Se o programa **não** tem uma biblioteca própria, seguem: 304 | - Os _defines_ 305 | - Os TAD's (tipos abstratos de dados): _struct_, _enum_, _typedef_, etc. 306 | - Os tipos globais 307 | - Os protótipos das funções 308 | * Se o programa tem biblioteca própria, estes ficam no `.h` 309 | * A função `int main(void)` ou `int main(int argc, char *argv[])` 310 | * As outras funções, de preferência em uma ordem que faça um mínimo de sentido com o próprio fluxo do programa 311 | 312 | #### Em PROLOG 313 | 314 | * Comentários iniciam como em C (_copyright_, e explicações gerais) 315 | * Os módulos lidos 316 | * As diretrizes (_dynamic_, etc.) 317 | * Os fatos 318 | * As regras, em uma ordem que ajude a clarificar a sequência lógica da solução engedrada 319 | 320 | # Ciclo de trabalho 321 | 322 | * Ligou o computador, **primeira** vez neste repositório 323 | - Tudo configurado no GitHub e no Hydra? 324 | - Repositório criado no GitHub (seu ou com _fork_ conforme o caso) 325 | - Faça o _clone_ no Hydra 326 | - Crie seu ramo _feature-nome_ 327 | - Crie o esqueleto do codigo (exemplo _ex11.c_) 328 | - Adicione (_git add_) o fonte criado 329 | - Faça o primeiro _commit_ do ramo _feature-nome_ 330 | - Vá para o _develop_ 331 | - Faça o _merge_ com o _feature-nome_ 332 | - Faça o primeiro _push_ do _develop_ 333 | - Coloque a _tag_ `v0.0` e novo `push` das _tags_. 334 | - Faça o _merge_ com o _master_ 335 | - E faça o primeiro _commit_ e _push_ no master. 336 | * Ligou o computador para trabalhar do **segundo** dia em diante 337 | - Atualize todos os ramos remotos (_master_ e _develop_) 338 | - Resolva conflitos se houver 339 | - Vá para seu ramo de trabalho _feature-nome_ (opcional, fazer o _merge_ antes, ou continuar trabalhando e fazer o _merge_ só no final) 340 | - (1) Edite o arquivo fonte no _vi_ 341 | - (2) Compile (_gcc_ ou _make_, ou teste no _swipl_) 342 | - (3) Erros: volte para passo (1) 343 | - (4) Compilou sem erros: faça _commit_ 344 | - (5) Vai trabalhar mais, volte para o passo (1) 345 | - (6) Fim do dia de trabalho: 346 | * Vá para o _develop_ e atualize-o 347 | * Faça _merge_ do _feature-nome_ com o _develop_ 348 | * Resolva conflitos se houver 349 | * Faça o _push_ do _develop_ para o GitHub 350 | - (7) Dia de _release_ no _master_: 351 | * Vá para o _master_ e atualize-o 352 | * Faça _merge_ do _develop_ com o _master_ 353 | * Resolva conflitos se houver 354 | * Faça o _push_ do _master_ para o GitHub 355 | * Crie uma _tag_ e faça o _push_ das _tags_ 356 | * Se houve alterações por conflito, o _master_ está na frente do _develop_, então passe o _merge_ para baixo, para o _develop_ e para o _feature-nome_: 357 | - Vá para o _develop_, atualize-o e _merge_ com _master_ 358 | - Vá para o _feature-nome_, e _merge_ com o _develop_ 359 | 360 | # Teste 361 | 362 | * Não tenha pressa de fazer _push_! O _push_ é irreversível, manda para o GitHub. Enquanto estiver só na sua máquina você pode corrigir quaisquer _bugs_ 363 | * Compile. Use todas as chaves de aviso que o _gcc_ pode oferecer. O _gcc_ é seu amigo! 364 | * Crie páginas com mensagens de erro com o comando _sprunge_ para discutir nos _issues_ se necessário 365 | * Use _makefile_ para compilar seus exercícios 366 | - Não deixe de conhecer as opções do _gcc_ para compilação. Este é um comando fundamental em vários sistemas operacionais, inclusive embarcados (arduino, pic, raspberry pi, etc.) 367 | * Teste! Rode o programa, faça entrada de dados, veja se o que acabou de programar realmente faz o que você deseja, e se não quebrou nada em outra função do programa. 368 | * Tudo ok? Então faça o _push_! 369 | * Se o trabalho exige _pull request_, faça suas modificações chegarem até o _master_ e então faça o _pull request_ do seu _master_ (_origin_) para o _master_ do _upstream_. 370 | * No _pull request_ coloque um título descritivo. Se seu trabalho é em grupo, coloque também no início do título o número do grupo. 371 | 372 | # Faça uma boa mensagem de commit 373 | 374 | * Se é um pequeno _commit_ tudo bem abreviar com o comando `git cm "uma descricao do que este commit faz em ate 50 caracteres"` 375 | * Mas se é um _commit_ que vai influenciar muito o código de outros _ramos_ ou que vai ser usado para _pull request_ então é importante escrever uma boa mensagem. Neste caso, **não** use o comando abreviado `git cm "mensagem"`. Use os comandos: 376 | - `git add arquivo` : se necessário adicionar algum arquivo 377 | - `git commit` : sem abreviação e sem mensagem. Este comando vai abrir o _vi_ para você digitar uma mensagem de _commit_ maior. 378 | * Na primeira linha, escreva um título do _commit_ com até 50 caracteres, como você já está acostumado. 379 | * Pule uma linha. 380 | * Da terceira linha para baixo, descreva com mais detalhes tudo o que você fez, o que este _commit_ inclui, o que muda, qual funcionalidade é acrescentada ou _bug_ é resolvido. 381 | * Saia com `:x` para salvar e fazer o _commit_ 382 | * Saia com `:q!` para abortar a edição e **não** fazer o _commit_ 383 | * Linhas iniciadas com \# são ignoradas pelo _git_ como sendo comentários e não são escritas no _commit_. 384 | * Exemplo de uma boa mensagem de _commit_: 385 | 386 | ``` 387 | Faz um exemplo para demonstrar a clareza do commit 388 | 389 | Sem este commit a explicação sobre mensagens de commit ficaria falha, sem um exemplo concreto. 390 | Este é um problema, porque assim fica apenas na imaginação o que seria um bom commit. 391 | Este commit corrige este problema ao fazer aqui um exemplo concreto e imperativo. 392 | 393 | A primeira linha é um título imperativo descritivo do essencial. Os dois parágrafos seguintes, 394 | o de cima e este, são explicações mais aprofundadas. É importante descrever (1) _o que ocorria_ 395 | antes do commit, (2) _qual_ é o problema que este commit resolve, (3) _porque_ este comportamento 396 | é problemático, e (3) _como_ este commit corrige este problema. 397 | 398 | Também é possível usar enumerações para clarificar algumas mudanças em pontos 399 | específicos, como: 400 | 401 | * mudafunc() : agora não retorna mais void e sim o código do cliente 402 | * funcoutra() : criada para cumprir outra finalidade que estava faltando 403 | * divideaqui() : criada para cumprir uma finalidade tal e tal que antes 404 | estava sendo feita na função mudafunc() de modo a ficar mais clara a divisão do que cada função faz. 405 | ``` 406 | 407 | Lembre que a primeira linha é importante para ver o _log_ e acompanhar a evolução do programa. 408 | 409 | * Referência: [A Note About Git Commit Messages](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) 410 | 411 | # Dicas de configuração 412 | 413 | ## Final de linha estilo Unix (`\n`) 414 | 415 | * Para o final de linha `\n`, use em suas configurações 416 | - Linux, Mac ou Unix: `git configure --global core.autocrlf input` 417 | - Windows: `git configure --global core.autocrlf true` 418 | * Outra opção para configurar `\n` é por repositório. Inclua um novo arquivo _.gitattributes_ com os comandos: 419 | 420 | 421 | ``` 422 | # Arquivo .gitattributes 423 | 424 | * text=auto 425 | *.c text 426 | *.h text 427 | *.x binary 428 | ``` 429 | 430 | * Veja detalhes de como atualizar o repositório após alterar estas configurações na [página de help do GitHub](https://help.github.com/articles/dealing-with-line-endings/#platform-all) 431 | * Veja também [configurando o Git](https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration) 432 | 433 | # Obrigado! 434 | 435 | Agora é com você! Bom estudo! 436 | 437 | Atenciosamente, 438 | 439 | Prof. Dr. Ruben Carlo Benante \<\> 440 | 441 | -------------------------------------------------------------------------------- /portugol.c: -------------------------------------------------------------------------------- 1 | /* 2 | Compilador PORTUGOL v.2q 3 | Autor: Ruben Carlo Benante 4 | Email: benante@gmail.com 5 | Data criação: 23/04/2009 6 | Data modificação: 25/05/2009 7 | */ 8 | 9 | //Falta: (to do) 10 | // IMPORTE = 273, 11 | // DEFINE = 272, 12 | 13 | #include 14 | #include 15 | #include 16 | #include "portugol.h" 17 | #include "y.tab.h" 18 | 19 | char *sTipoDado[14]={"tipoIdIndef", "tipoConInt", "tipoConFloat", "tipoConStr", "tipoIdInt", "tipoIdFloat", "tipoIdStr", "tipoIdFuncInt", "tipoIdFuncFloat", "tipoIdFuncDouble", "tipoIdFuncChar", "tipoIdFuncStr", "tipoIdFuncVoid", "tipoIdFuncPVoid"}; 20 | char *sTipoBase[4]={"tipoIndef", "tipoInt", "tipoFloat", "tipoStr"}; 21 | extern int debugArvore; 22 | extern int debugTabela; 23 | 24 | char *gera_quad(nodo *tn, int n) 25 | { 26 | char *q1=NULL, *q2=NULL, *q3=NULL, *qres=NULL, qtemp[20]=""; 27 | char msg[128]; 28 | int itemp, t0, t1; 29 | 30 | if(tn==NULL) 31 | return strdup(qtemp); 32 | 33 | switch(tn->tipoN) 34 | { 35 | case tipoSimb: 36 | switch(tn->pSimb->tipoD) 37 | { 38 | case tipoConInt: 39 | sprintf(qtemp,"tc[%d]",tn->pSimb->idx); //achaId preenche idx 40 | if(!tn->pSimb->uso) 41 | fprintf(yyout, " loadi(%d,%s,&%s);\n", tn->pSimb->ival, "NULL", qtemp); 42 | tn->pSimb->uso=1; 43 | break; 44 | case tipoConFloat: 45 | sprintf(qtemp,"tc[%d]",tn->pSimb->idx); 46 | if(!tn->pSimb->uso) 47 | fprintf(yyout, " loadf(%.2f,%s,&%s);\n", tn->pSimb->fval, "NULL", qtemp); 48 | tn->pSimb->uso=1; 49 | break; 50 | case tipoConStr: 51 | sprintf(qtemp,"tc[%d]",tn->pSimb->idx); 52 | if(!tn->pSimb->uso) 53 | fprintf(yyout, " loads(%s,%s,&%s);\n", tn->pSimb->sval, "NULL", qtemp); 54 | tn->pSimb->uso=1; 55 | break; 56 | case tipoIdInt: 57 | case tipoIdFloat: 58 | case tipoIdStr: 59 | sprintf(qtemp,"ts[%d]",tn->pSimb->idx); 60 | break; 61 | case tipoIdIndef: 62 | default: //funcao? 63 | sprintf(qtemp,"ts[?]"); 64 | break; 65 | } 66 | case tipoOper: 67 | switch(tn->opr.oper) 68 | { 69 | case INICIO: //INICIO; comandos FIM; 70 | if(n==0) 71 | { 72 | if(debugTabela) 73 | printTS(); 74 | if(debugArvore) 75 | printNodo(tn,0,"tn"); 76 | } 77 | gera_quad(tn->opr.ptn[0], n+1); 78 | if(n==0) 79 | fprintf(yyout, "}\n"); 80 | break; 81 | case SE: 82 | q1=gera_quad(tn->opr.ptn[0], n+1); //expr 83 | q2=geraLB(&itemp);//inicio_senao ou fim_se 84 | if(tn->opr.nops>2) //tem senao 85 | q3=geraLB(&itemp);//fim_se 86 | fprintf(yyout, " jump_f(");//caso falso pula para senao ou para fim_se 87 | fprintf(yyout, "%s,", q1); 88 | fprintf(yyout, "%s,", "NULL"); 89 | fprintf(yyout, "%s);\t/* if(F) goto %s */\n", q2, q2); //pula para senao ou para fim_se 90 | gera_quad(tn->opr.ptn[1], n+1); //comandos do entao 91 | if(tn->opr.nops>2) //tem senao, pula para fim_se 92 | { 93 | fprintf(yyout, " jump(");//pulo incondicional para fim_se 94 | fprintf(yyout, "%s,", "NULL"); 95 | fprintf(yyout, "%s,", "NULL"); 96 | fprintf(yyout, "%s);\n", q3); 97 | fprintf(yyout, "%s:\t/* else */\n", q2);//inicio_senao: 98 | gera_quad(tn->opr.ptn[2], n+1); //comandos senao 99 | fprintf(yyout, "%s:\t/* endif */\n", q3);//fim_se: 100 | } 101 | else //nao tem senao 102 | fprintf(yyout, "%s:\t/* endif */\n", q2);//fim_se: 103 | break; 104 | case IMPRIMA: 105 | q1=gera_quad(tn->opr.ptn[0], n+1); //ts, tp ou tc; 106 | fprintf(yyout, " param(%s,NULL,NULL);\n", q1); //string ts[0], tc[0] ou tp[0] 107 | fprintf(yyout, " call(\"imprima\",1,NULL);\n"); 108 | break; 109 | case LEIA: 110 | qres=gera_quad(tn->opr.ptn[0], n+1); 111 | if(tn->opr.ptn[0]->pSimb->tipoD!=tipoIdFloat) 112 | { 113 | sprintf(msg,"Chamada da funcao leia com argumento de tipo incorreto. leia <%s>.", nomeTipo(tn->opr.ptn[0])); 114 | erroSemantico(msg, tn->linha); 115 | } 116 | tabelaSimb *ps = achaStr("?"); 117 | sprintf(qtemp,"tc[%d]",ps->idx); 118 | if(!ps->uso) 119 | fprintf(yyout, " loads(\"?\",NULL,&%s);\n", qtemp); 120 | ps->uso=1; 121 | fprintf(yyout, " param(%s,NULL,NULL);\n", qtemp); 122 | fprintf(yyout, " call(\"imprima\",1,NULL);\n"); 123 | fprintf(yyout, " call(\"leia\",0,&%s);\n", qres); 124 | break; 125 | case ENQUANTO: 126 | q1=geraLB(&itemp); // inicio_enquanto 127 | q2=geraLB(&itemp); // fim_enquanto 128 | fprintf(yyout, "%s:\t/* while */\n", q1); // inicio_enquanto: 129 | q3=gera_quad(tn->opr.ptn[0], n+1); // expr condicional 130 | fprintf(yyout, " jump_f(%s,%s,%s);\n",q3,"NULL",q2); // caso falso pula para fim_enquanto 131 | gera_quad(tn->opr.ptn[1], n+1); // comandos do laco 132 | fprintf(yyout, " jump(%s,%s,%s);\n","NULL","NULL",q1); // pula para inicio_enquanto 133 | fprintf(yyout, "%s:\t/* end_while */\n", q2); // fim_enquanto: 134 | break; 135 | case PARA: 136 | q1=geraLB(&itemp); //loop_para: 137 | q2=geraLB(&itemp); //fim_para: 138 | gera_quad(tn->opr.ptn[0], n+1); //stmt1=inicializacao 139 | fprintf(yyout, "%s:\t/* for */\n", q1);//loop_para: 140 | q3=gera_quad(tn->opr.ptn[1], n+1); //stmt2=condicao 141 | fprintf(yyout, " jump_f(%s,NULL,%s);\n", q3, q2);//se falso pula para fim_para 142 | gera_quad(tn->opr.ptn[3], n+1); //stmt4=comandos do loop 143 | gera_quad(tn->opr.ptn[2], n+1); //stmt3=incremento 144 | fprintf(yyout, " jump(NULL,NULL,%s);\n",q1);//pula para loop_para 145 | fprintf(yyout, "%s:\t/* end_for */\n", q2);//fim_para: 146 | break; 147 | case FUNC: // | IDENT '(' expr ')' { $$ = opr(FUNC, 2, $1, $3); } 148 | q1=gera_quad(tn->opr.ptn[0], n+1); 149 | q2=gera_quad(tn->opr.ptn[1], n+1); 150 | qres=geraTP(&itemp); 151 | t0=pegaTipoBase(tn->opr.ptn[0]); //tipoInt, tipoFloat, tipoStr, tipoIndef 152 | t1=pegaTipoBase(tn->opr.ptn[1]); //tipoInt, tipoFloat, tipoStr, tipoIndef 153 | if(t1 == tipoIndef) 154 | { 155 | sprintf(msg,"Operando nao declarado na chamada da funcao <%s>.", tn->opr.ptn[0]->pSimb->idNome); 156 | erroSemantico(msg, tn->linha); 157 | } 158 | if(t1 == tipoStr) 159 | { 160 | sprintf(msg,"Funcao <%s> com argumento tipoStr nao implementada.", tn->opr.ptn[0]->pSimb->idNome); 161 | erroSemantico(msg, tn->linha); 162 | } 163 | tn->opr.tipoBOper = tipoFloat;//bug: esta fixo! De onde vem o tipo de retorno? 164 | fprintf(yyout," param(%s, NULL, NULL);\n call(\"%s\", 1, &%s);\n", q2, tn->opr.ptn[0]->pSimb->idNome, qres); 165 | break; 166 | case ABORTE: 167 | fprintf(yyout, " halt(NULL,NULL,NULL);\n"); 168 | break; 169 | case SAIA: 170 | q1=gera_quad(tn->opr.ptn[0], n+1); 171 | fprintf(yyout, " param(%s,%s,%s);\n",q1,"NULL","NULL"); 172 | fprintf(yyout, " call(%s,%s,%s);\n","\"saia\"","1","NULL"); 173 | break; 174 | case INT: 175 | if(tn->opr.ptn[0]->pSimb->tipoD!=tipoIdIndef) 176 | { 177 | sprintf(msg,"Redeclaracao da variavel <%s>.", tn->opr.ptn[0]->pSimb->idNome); 178 | erroSemantico(msg, tn->linha); 179 | } 180 | tn->opr.ptn[0]->pSimb->tipoD=tipoIdInt; 181 | tn->opr.ptn[0]->pSimb->idx=geraTS(); 182 | fprintf(yyout," loadi(0, NULL, &ts[%d]); /* int %s; */\n", tn->opr.ptn[0]->pSimb->idx, tn->opr.ptn[0]->pSimb->idNome); 183 | break; 184 | case REAL: 185 | if(tn->opr.ptn[0]->pSimb->tipoD!=tipoIdIndef) 186 | { 187 | sprintf(msg,"Redeclaracao da variavel <%s>.", tn->opr.ptn[0]->pSimb->idNome); 188 | erroSemantico(msg, tn->linha); 189 | } 190 | tn->opr.ptn[0]->pSimb->tipoD=tipoIdFloat; 191 | tn->opr.ptn[0]->pSimb->idx=geraTS(); 192 | fprintf(yyout," loadf(0.00, NULL, &ts[%d]); /* real %s; */\n", tn->opr.ptn[0]->pSimb->idx, tn->opr.ptn[0]->pSimb->idNome); 193 | break; 194 | case TEXTO: 195 | if(tn->opr.ptn[0]->pSimb->tipoD!=tipoIdIndef) 196 | { 197 | sprintf(msg,"Redeclaracao da variavel <%s>.", tn->opr.ptn[0]->pSimb->idNome); 198 | erroSemantico(msg, tn->linha); 199 | } 200 | tn->opr.ptn[0]->pSimb->tipoD=tipoIdStr; 201 | tn->opr.ptn[0]->pSimb->idx=geraTS(); 202 | fprintf(yyout," loads(\"\\0\", NULL, &ts[%d]); /* str %s; */\n", tn->opr.ptn[0]->pSimb->idx, tn->opr.ptn[0]->pSimb->idNome); 203 | break; 204 | case ';': 205 | fprintf(yyout, " nop(NULL,NULL,NULL);\t/* no operation */\n"); 206 | break; 207 | case 'l': /* lista de comandos */ 208 | gera_quad(tn->opr.ptn[0], n); 209 | gera_quad(tn->opr.ptn[1], n); 210 | break; 211 | case '=': 212 | qres=gera_quad(tn->opr.ptn[0], n+1); 213 | q1=gera_quad(tn->opr.ptn[1], n+1); 214 | if(tn->opr.ptn[0]->pSimb->tipoD == tipoIdIndef) 215 | { 216 | sprintf(msg,"Atribuicao invalida a variavel <%s> nao declarada.", tn->opr.ptn[0]->pSimb->idNome); 217 | erroSemantico(msg, tn->linha); 218 | } 219 | if(!variavel(tn->opr.ptn[0])) // tentou func(a)=1; 220 | { 221 | sprintf(msg,"Atribuicao invalida a uma funcao <%s>.", tn->opr.ptn[0]->pSimb->idNome); 222 | erroSemantico(msg, tn->linha); 223 | } 224 | t0=pegaTipoBase(tn->opr.ptn[0]); //tipoInt, tipoFloat, tipoStr, tipoIndef 225 | t1=pegaTipoBase(tn->opr.ptn[1]); 226 | if(t0==t1) 227 | fprintf(yyout, " mov(%s,NULL,&%s); /* %s = %s */\n", q1, qres, tn->opr.ptn[0]->pSimb->idNome, q1); 228 | else 229 | { /* tipos diferentes */ 230 | sprintf(msg,"Atribuicao de tipos diferentes. <%s, %s> = <%s, %s>.", nomeTipo(tn->opr.ptn[0]), sTipoBase[t0], nomeTipo(tn->opr.ptn[1]), sTipoBase[t1]); 231 | erroSemantico(msg, tn->linha); 232 | } 233 | break; 234 | case UMENOS: 235 | q1=gera_quad(tn->opr.ptn[0], n+1); 236 | qres=geraTP(&itemp); 237 | tn->opr.tipoBOper = pegaTipoBase(tn->opr.ptn[0]); 238 | if(tn->opr.tipoBOper == tipoIndef) 239 | { 240 | sprintf(msg,"Operando nao declarado na operacao de menos unario. - <%s>", sTipoBase[tn->opr.tipoBOper]); 241 | erroSemantico(msg, tn->linha); 242 | } 243 | fprintf(yyout, " uminus(%s,NULL,&%s);\n", q1, qres); 244 | break; 245 | case '+': 246 | q1=gera_quad(tn->opr.ptn[0], n+1); 247 | q2=gera_quad(tn->opr.ptn[1], n+1); 248 | qres=geraTP(&itemp); 249 | t0=pegaTipoBase(tn->opr.ptn[0]); 250 | t1=pegaTipoBase(tn->opr.ptn[1]); 251 | if(t0 == tipoIndef || t1 == tipoIndef) 252 | { 253 | sprintf(msg,"Operando nao declarado na operacao de soma. <%s> + <%s>", sTipoBase[t0], sTipoBase[t1]); 254 | erroSemantico(msg, tn->linha); 255 | } 256 | if((t0 == tipoStr || t1 == tipoStr) && (t0 != tipoStr || t1 != tipoStr)) 257 | erroSemantico("Nao posso somar textos com numeros.", tn->linha); 258 | if(t0==tipoFloat || t1==tipoFloat) 259 | tn->opr.tipoBOper = tipoFloat; 260 | else 261 | tn->opr.tipoBOper = tipoInt;//t0; //bug: 262 | //erroSemantico("Nao posso somar textos com numeros.", tn->linha); 263 | //bug: cade a soma de strings? tipoBOPer=tipoStr 264 | if(t0 == tipoStr) 265 | tn->opr.tipoBOper = tipoStr; 266 | fprintf(yyout, " add(%s,%s,&%s);\n", q1, q2, qres); 267 | break; 268 | case '-': 269 | q1=gera_quad(tn->opr.ptn[0], n+1); 270 | q2=gera_quad(tn->opr.ptn[1], n+1); 271 | qres=geraTP(&itemp); 272 | t0=pegaTipoBase(tn->opr.ptn[0]); 273 | t1=pegaTipoBase(tn->opr.ptn[1]); 274 | if(t0 == tipoIndef || t1 == tipoIndef) 275 | { 276 | sprintf(msg,"Operando nao declarado na operacao de subtracao. <%s> - <%s>", sTipoBase[t0], sTipoBase[t1]); 277 | erroSemantico(msg, tn->linha); 278 | } 279 | if(t0 == tipoStr || t1 == tipoStr) 280 | erroSemantico("Nao posso subtrair textos.", tn->linha); 281 | if(t0==tipoFloat || t1==tipoFloat) 282 | tn->opr.tipoBOper = tipoFloat; 283 | else 284 | tn->opr.tipoBOper = tipoInt; 285 | fprintf(yyout, " sub(%s,%s,&%s);\n", q1, q2, qres); 286 | break; 287 | case '*': 288 | q1=gera_quad(tn->opr.ptn[0], n+1); 289 | q2=gera_quad(tn->opr.ptn[1], n+1); 290 | qres=geraTP(&itemp); 291 | t0=pegaTipoBase(tn->opr.ptn[0]); 292 | t1=pegaTipoBase(tn->opr.ptn[1]); 293 | if(t0 == tipoIndef || t1 == tipoIndef) 294 | { 295 | sprintf(msg,"Operando nao declarado na operacao de multiplicacao. <%s> * <%s>", sTipoBase[t0], sTipoBase[t1]); 296 | erroSemantico(msg, tn->linha); 297 | } 298 | if(t0 == tipoStr || t1 == tipoStr) 299 | erroSemantico("Nao posso multiplicar textos.", tn->linha); 300 | if(t0==tipoFloat || t1==tipoFloat) 301 | tn->opr.tipoBOper = tipoFloat; 302 | else 303 | tn->opr.tipoBOper = tipoInt; 304 | fprintf(yyout, " mult(%s,%s,&%s);\n", q1, q2, qres); 305 | break; 306 | case '/': 307 | q1=gera_quad(tn->opr.ptn[0], n+1); 308 | q2=gera_quad(tn->opr.ptn[1], n+1); 309 | qres=geraTP(&itemp); 310 | t0=pegaTipoBase(tn->opr.ptn[0]); 311 | t1=pegaTipoBase(tn->opr.ptn[1]); 312 | if(t0 == tipoIndef || t1 == tipoIndef) 313 | { 314 | sprintf(msg,"Operando nao declarado na operacao de divisao. <%s> / <%s>", sTipoBase[t0], sTipoBase[t1]); 315 | erroSemantico(msg, tn->linha); 316 | } 317 | if(t0 == tipoStr || t1 == tipoStr) 318 | erroSemantico("Nao posso dividir textos.", tn->linha); 319 | if(t0==tipoFloat || t1==tipoFloat) 320 | tn->opr.tipoBOper = tipoFloat; 321 | else 322 | tn->opr.tipoBOper = tipoInt; 323 | fprintf(yyout, " divi(%s,%s,&%s);\n", q1, q2, qres); 324 | break; 325 | case '%': 326 | q1=gera_quad(tn->opr.ptn[0], n+1); 327 | q2=gera_quad(tn->opr.ptn[1], n+1); 328 | qres=geraTP(&itemp); 329 | t0=pegaTipoBase(tn->opr.ptn[0]); 330 | t1=pegaTipoBase(tn->opr.ptn[1]); 331 | if(t0 == tipoIndef || t1 == tipoIndef) 332 | { 333 | sprintf(msg,"Operando nao declarado na operacao de modulo. <%s> % <%s>", sTipoBase[t0], sTipoBase[t1]); 334 | erroSemantico(msg, tn->linha); 335 | } 336 | if(t0 == tipoStr || t1 == tipoStr) 337 | erroSemantico("Nao posso calcular modulo de textos.", tn->linha); 338 | if(t0 == tipoFloat || t1 == tipoFloat) 339 | erroSemantico("Nao posso calcular modulo de .", tn->linha); 340 | tn->opr.tipoBOper = tipoInt; 341 | fprintf(yyout, " mod(%s,%s,&%s);\n", q1, q2, qres); 342 | break; 343 | case '(': 344 | qres=gera_quad(tn->opr.ptn[0], n+1); 345 | tn->opr.tipoBOper = pegaTipoBase(tn->opr.ptn[0]); 346 | if(tn->opr.tipoBOper == tipoIndef) 347 | { 348 | sprintf(msg,"Operando nao declarado na operacao de parenteses. ( <%s> )", sTipoBase[tn->opr.tipoBOper]); 349 | erroSemantico(msg, tn->linha); 350 | } 351 | break; 352 | case LT: //compara texto com texto ou numero com numero. retorna tipoInt 353 | q1=gera_quad(tn->opr.ptn[0], n+1); 354 | q2=gera_quad(tn->opr.ptn[1], n+1); 355 | qres=geraTP(&itemp); 356 | t0=pegaTipoBase(tn->opr.ptn[0]); 357 | t1=pegaTipoBase(tn->opr.ptn[1]); 358 | if(t0 == tipoIndef || t1 == tipoIndef) 359 | { 360 | sprintf(msg,"Operando nao declarado na operacao de menor-que. <%s> < <%s>", sTipoBase[t0], sTipoBase[t1]); 361 | erroSemantico(msg, tn->linha); 362 | } 363 | if((t0 == tipoStr || t1 == tipoStr) && (t0 != tipoStr || t1 != tipoStr)) 364 | erroSemantico("Nao posso comparar (<) textos com numeros.", tn->linha); 365 | tn->opr.tipoBOper = tipoInt; 366 | fprintf(yyout, " comp_lt(%s,%s,&%s);\n", q1, q2, qres); 367 | break; 368 | case GT: 369 | q1=gera_quad(tn->opr.ptn[0], n+1); 370 | q2=gera_quad(tn->opr.ptn[1], n+1); 371 | qres=geraTP(&itemp); 372 | t0=pegaTipoBase(tn->opr.ptn[0]); 373 | t1=pegaTipoBase(tn->opr.ptn[1]); 374 | if(t0 == tipoIndef || t1 == tipoIndef) 375 | { 376 | sprintf(msg,"Operando nao declarado na operacao de maior-que. <%s> > <%s>", sTipoBase[t0], sTipoBase[t1]); 377 | erroSemantico(msg, tn->linha); 378 | } 379 | if((t0 == tipoStr || t1 == tipoStr) && (t0 != tipoStr || t1 != tipoStr)) 380 | erroSemantico("Nao posso comparar (>) textos com numeros.", tn->linha); 381 | tn->opr.tipoBOper = tipoInt; 382 | fprintf(yyout, " comp_gt(%s,%s,&%s);\n", q1, q2, qres); 383 | break; 384 | case GE: 385 | q1=gera_quad(tn->opr.ptn[0], n+1); 386 | q2=gera_quad(tn->opr.ptn[1], n+1); 387 | qres=geraTP(&itemp); 388 | t0=pegaTipoBase(tn->opr.ptn[0]); 389 | t1=pegaTipoBase(tn->opr.ptn[1]); 390 | if(t0 == tipoIndef || t1 == tipoIndef) 391 | { 392 | sprintf(msg,"Operando nao declarado na operacao de maior-igual. <%s> >= <%s>", sTipoBase[t0], sTipoBase[t1]); 393 | erroSemantico(msg, tn->linha); 394 | } 395 | if((t0 == tipoStr || t1 == tipoStr) && (t0 != tipoStr || t1 != tipoStr)) 396 | erroSemantico("Nao posso comparar (>=) textos com numeros.", tn->linha); 397 | tn->opr.tipoBOper = tipoInt; 398 | fprintf(yyout, " comp_ge(%s,%s,&%s);\n", q1, q2, qres); 399 | break; 400 | case LE: 401 | q1=gera_quad(tn->opr.ptn[0], n+1); 402 | q2=gera_quad(tn->opr.ptn[1], n+1); 403 | qres=geraTP(&itemp); 404 | t0=pegaTipoBase(tn->opr.ptn[0]); 405 | t1=pegaTipoBase(tn->opr.ptn[1]); 406 | if(t0 == tipoIndef || t1 == tipoIndef) 407 | { 408 | sprintf(msg,"Operando nao declarado na operacao de menor-igual. <%s> <= <%s>", sTipoBase[t0], sTipoBase[t1]); 409 | erroSemantico(msg, tn->linha); 410 | } 411 | if((t0 == tipoStr || t1 == tipoStr) && (t0 != tipoStr || t1 != tipoStr)) 412 | erroSemantico("Nao posso comparar (<=) textos com numeros.", tn->linha); 413 | tn->opr.tipoBOper = tipoInt; 414 | fprintf(yyout, " comp_le(%s,%s,&%s);\n", q1, q2, qres); 415 | break; 416 | case NE: 417 | q1=gera_quad(tn->opr.ptn[0], n+1); 418 | q2=gera_quad(tn->opr.ptn[1], n+1); 419 | qres=geraTP(&itemp); 420 | t0=pegaTipoBase(tn->opr.ptn[0]); 421 | t1=pegaTipoBase(tn->opr.ptn[1]); 422 | if(t0 == tipoIndef || t1 == tipoIndef) 423 | { 424 | sprintf(msg,"Operando nao declarado na operacao de diferente. <%s> != <%s>", sTipoBase[t0], sTipoBase[t1]); 425 | erroSemantico(msg, tn->linha); 426 | } 427 | if((t0 == tipoStr || t1 == tipoStr) && (t0 != tipoStr || t1 != tipoStr)) 428 | erroSemantico("Nao posso comparar (!=) textos com numeros.", tn->linha); 429 | tn->opr.tipoBOper = tipoInt; 430 | fprintf(yyout, " comp_ne(%s,%s,&%s);\n", q1, q2, qres); 431 | break; 432 | case EQ: 433 | q1=gera_quad(tn->opr.ptn[0], n+1); 434 | q2=gera_quad(tn->opr.ptn[1], n+1); 435 | qres=geraTP(&itemp); 436 | t0=pegaTipoBase(tn->opr.ptn[0]); 437 | t1=pegaTipoBase(tn->opr.ptn[1]); 438 | if(t0 == tipoIndef || t1 == tipoIndef) 439 | { 440 | sprintf(msg,"Operando nao declarado na operacao de igual. <%s> == <%s>", sTipoBase[t0], sTipoBase[t1]); 441 | erroSemantico(msg, tn->linha); 442 | } 443 | if((t0 == tipoStr || t1 == tipoStr) && (t0 != tipoStr || t1 != tipoStr)) 444 | erroSemantico("Nao posso comparar (==) textos com numeros.", tn->linha); 445 | tn->opr.tipoBOper = tipoInt; 446 | fprintf(yyout, " comp_eq(%s,%s,&%s);\n", q1, q2, qres); 447 | break; 448 | case E: 449 | q1=gera_quad(tn->opr.ptn[0], n+1); 450 | q2=gera_quad(tn->opr.ptn[1], n+1); 451 | qres=geraTP(&itemp); 452 | t0=pegaTipoBase(tn->opr.ptn[0]); 453 | t1=pegaTipoBase(tn->opr.ptn[1]); 454 | if(t0 == tipoIndef || t1 == tipoIndef) 455 | { 456 | sprintf(msg,"Operando nao declarado na operacao de E logico. <%s> E <%s>", sTipoBase[t0], sTipoBase[t1]); 457 | erroSemantico(msg, tn->linha); 458 | } 459 | if(t0 == tipoStr || t1 == tipoStr) 460 | erroSemantico("Nao posso operar (E) em textos.", tn->linha); 461 | tn->opr.tipoBOper = tipoInt; 462 | fprintf(yyout, " rela_an(%s,%s,&%s);\n", q1,q2,qres); 463 | break; 464 | case OU: 465 | q1=gera_quad(tn->opr.ptn[0], n+1); 466 | q2=gera_quad(tn->opr.ptn[1], n+1); 467 | qres=geraTP(&itemp); 468 | t0=pegaTipoBase(tn->opr.ptn[0]); 469 | t1=pegaTipoBase(tn->opr.ptn[1]); 470 | if(t0 == tipoIndef || t1 == tipoIndef) 471 | { 472 | sprintf(msg,"Operando nao declarado na operacao de OU logico. <%s> OU <%s>", sTipoBase[t0], sTipoBase[t1]); 473 | erroSemantico(msg, tn->linha); 474 | } 475 | if(t0 == tipoStr || t1 == tipoStr) 476 | erroSemantico("Nao posso operar (OU) em textos.", tn->linha); 477 | tn->opr.tipoBOper = tipoInt; 478 | fprintf(yyout, " rela_or(%s,%s,&%s);\n", q1,q2,qres); 479 | break; 480 | case NAO: 481 | q1=gera_quad(tn->opr.ptn[0], n+1); 482 | qres=geraTP(&itemp); 483 | t0=pegaTipoBase(tn->opr.ptn[0]); 484 | if(t0 == tipoIndef) 485 | { 486 | sprintf(msg,"Operando nao declarado na operacao de NAO logico. NAO <%s>", sTipoBase[t0]); 487 | erroSemantico(msg, tn->linha); 488 | } 489 | if(t0 == tipoStr) 490 | erroSemantico("Nao posso operar (NAO) em textos.", tn->linha); 491 | tn->opr.tipoBOper = tipoInt; 492 | fprintf(yyout, " rela_no(%s,%s,&%s);\n", q1,"NULL",qres); 493 | break; 494 | } 495 | } 496 | if(qres!=NULL) 497 | strcpy(qtemp,qres); 498 | free(q1); free(q2); free(q3); free(qres); 499 | return strdup(qtemp); 500 | } 501 | 502 | int geraTF(void) //tabela de funcoes 503 | { 504 | static int itf=-1; 505 | itf++; 506 | return itf; 507 | } 508 | 509 | int geraTC(void) //tabela de constantes 510 | { 511 | static int itc=-1; 512 | itc++; 513 | return itc; 514 | } 515 | 516 | int geraTS(void) //tabela de variaveis 517 | { 518 | static int its=-1; 519 | its++; 520 | return its; 521 | } 522 | 523 | char *geraTP(int *i) 524 | { 525 | static int itp=-1; 526 | char temp[20]; 527 | itp++; 528 | *i=itp; 529 | sprintf(temp,"tp[%d]",itp); 530 | return strdup(temp); 531 | } 532 | 533 | char *geraLB(int *i) 534 | { 535 | static int l=0; 536 | char tmp[20]; 537 | l++; 538 | *i=l; 539 | 540 | sprintf(tmp,"l%d",l); 541 | return strdup(tmp); 542 | } 543 | 544 | void printTS(void) 545 | { 546 | int n; 547 | 548 | printf("---------------------------- Tabela de Simbolos ----------------------------\n"); 549 | for(n=0; ntipoN==tipoSimb) 615 | { 616 | printf("----------------------------\n"); 617 | printf("(%d) %s->pSimb->tipoD=%s\n", n, var, nome); 618 | printf("(%d) %s->pSimb->idx=%d\n", n, var, tn->pSimb->idx); 619 | printf("(%d) %s->pSimb->idNome=%s\n", n, var, tn->pSimb->idNome); 620 | switch(tn->pSimb->tipoD) 621 | { 622 | case tipoConInt: 623 | printf("(%d) %s->pSimb->uso=%d\n", n, var, tn->pSimb->uso); 624 | printf("(%d) %s->pSimb->ival=%d\n", n, var, tn->pSimb->ival); 625 | break; 626 | case tipoConFloat: 627 | printf("(%d) %s->pSimb->uso=%d\n", n, var, tn->pSimb->uso); 628 | printf("(%d) %s->pSimb->fval=%.2f\n", n, var, tn->pSimb->fval); 629 | break; 630 | case tipoConStr: 631 | printf("(%d) %s->pSimb->uso=%d\n", n, var, tn->pSimb->uso); 632 | printf("(%d) %s->pSimb->sval=%s\n", n, var, tn->pSimb->sval); 633 | break; 634 | case tipoIdInt: 635 | case tipoIdFloat: 636 | case tipoIdStr: 637 | case tipoIdIndef: 638 | break; 639 | case tipoIdFuncInt: 640 | printf("(%d) %s->pSimb->idFunc=%s\n", n, var, tn->pSimb->idFunc); 641 | printf("(%d) %s->pSimb->ifunc=%u\n", n, var, tn->pSimb->ifunc); 642 | break; 643 | case tipoIdFuncFloat: 644 | printf("(%d) %s->pSimb->idFunc=%s\n", n, var, tn->pSimb->idFunc); 645 | printf("(%d) %s->pSimb->ffunc=%u\n", n, var, tn->pSimb->ffunc); 646 | break; 647 | case tipoIdFuncDouble: 648 | printf("(%d) %s->pSimb->idFunc=%s\n", n, var, tn->pSimb->idFunc); 649 | printf("(%d) %s->pSimb->dfunc=%u\n", n, var, tn->pSimb->dfunc); 650 | break; 651 | case tipoIdFuncChar: 652 | break; 653 | case tipoIdFuncStr: 654 | printf("(%d) %s->pSimb->idFunc=%s\n", n, var, tn->pSimb->idFunc); 655 | printf("(%d) %s->pSimb->sfunc=%u\n", n, var, tn->pSimb->sfunc); 656 | break; 657 | case tipoIdFuncVoid: 658 | printf("(%d) %s->pSimb->idFunc=%s\n", n, var, tn->pSimb->idFunc); 659 | printf("(%d) %s->pSimb->vfunc=%u\n", n, var, tn->pSimb->vfunc); 660 | break; 661 | } 662 | } 663 | else //tipoOper 664 | { 665 | printf("----------------------------\n"); 666 | printf("(%d) %s->opr.oper=%d", n, var, tn->opr.oper); 667 | printf(" (%s)\n", token(tn->opr.oper)); 668 | printf("(%d) %s->opr.tipoBOper=%d (%s)\n", n, var, tn->opr.tipoBOper, nome); 669 | printf("(%d) %s->opr.nops=%d\n", n, var, tn->opr.nops); 670 | if(tn->opr.nops>0) 671 | printNodo(tn->opr.ptn[0], n+1, "ptn[0]"); 672 | if(tn->opr.nops>1) 673 | printNodo(tn->opr.ptn[1], n+1, "ptn[1]"); 674 | if(tn->opr.nops>2) 675 | printNodo(tn->opr.ptn[2], n+1, "ptn[2]"); 676 | if(tn->opr.nops>3) 677 | printNodo(tn->opr.ptn[3], n+1, "ptn[3]"); 678 | } 679 | } 680 | 681 | int variavel(nodo *p) 682 | { 683 | if(p->tipoN==tipoOper) 684 | return 0; 685 | 686 | switch(p->pSimb->tipoD) 687 | { 688 | case tipoIdInt: 689 | case tipoIdFloat: 690 | case tipoIdStr: 691 | return 1; 692 | case tipoIdIndef: //variavel ou funcao ainda sem tipo 693 | default: 694 | return 0; 695 | } 696 | } 697 | 698 | int pegaTipoBase(nodo *p) 699 | { 700 | 701 | if(!p) 702 | return tipoIndef; 703 | 704 | if(p->tipoN==tipoOper) 705 | return (p->opr.tipoBOper); 706 | 707 | if(!p->pSimb) 708 | return tipoIndef; 709 | 710 | switch(p->pSimb->tipoD) 711 | { 712 | case tipoConInt: 713 | case tipoIdInt: 714 | case tipoIdFuncInt: 715 | return tipoInt; //------------ tipoInt 716 | case tipoConFloat: 717 | case tipoIdFloat: 718 | case tipoIdFuncFloat: 719 | case tipoIdFuncDouble: 720 | return tipoFloat; //------------ tipoFloat 721 | case tipoConStr: 722 | case tipoIdStr: 723 | case tipoIdFuncStr: 724 | return tipoStr; //------------ tipoStr 725 | case tipoIdFuncChar: 726 | case tipoIdFuncVoid: 727 | case tipoIdFuncPVoid: 728 | case tipoIdIndef: 729 | default: 730 | return tipoIndef; //------------ tipoIndef 731 | } 732 | } 733 | 734 | char *nomeTipo(nodo *p) 735 | { 736 | if(!p) 737 | return(strdup("(null)")); 738 | if(p->tipoN==tipoSimb) 739 | return(strdup(sTipoDado[p->pSimb->tipoD])); 740 | else /* tipoOper */ 741 | return(strdup(sTipoBase[p->opr.tipoBOper])); 742 | } 743 | 744 | char *token(int tk) 745 | { 746 | char tmp[2]; 747 | if(tk>32 && tk<127) 748 | { 749 | sprintf(tmp, "%c", tk); 750 | return strdup(tmp); 751 | } 752 | switch(tk) 753 | { 754 | case SE: 755 | return(strdup("SE")); 756 | case ENTAO: 757 | return(strdup("ENTAO")); 758 | case SENAO: 759 | return(strdup("SENAO")); 760 | case INICIO: 761 | return(strdup("INICIO")); 762 | case FIM: 763 | return(strdup("FIM")); 764 | case IMPRIMA: 765 | return(strdup("IMPRIMA")); 766 | case LEIA: 767 | return(strdup("LEIA")); 768 | case ENQUANTO: 769 | return(strdup("ENQUANTO")); 770 | case ABORTE: 771 | return(strdup("ABORTE")); 772 | case SAIA: 773 | return(strdup("SAIA")); 774 | case PARA: 775 | return(strdup("PARA")); 776 | case INT: 777 | return(strdup("INT")); 778 | case REAL: 779 | return(strdup("REAL")); 780 | case TEXTO: 781 | return(strdup("TEXTO")); 782 | case DEFINE: 783 | return(strdup("DEFINE")); 784 | case IMPORTE: 785 | return(strdup("IMPORTE")); 786 | case IDENT: 787 | return(strdup("IDENT")); 788 | case INTCON: 789 | return(strdup("INTCON")); 790 | case REALCON: 791 | return(strdup("REALCON")); 792 | case TEXTOCON: 793 | return(strdup("TEXTOCON")); 794 | case OU: 795 | return(strdup("OU")); 796 | case E: 797 | return(strdup("E")); 798 | case NAO: 799 | return(strdup("NAO")); 800 | case LT: 801 | return(strdup("LT")); 802 | case GT: 803 | return(strdup("GT")); 804 | case NE: 805 | return(strdup("NE")); 806 | case EQ: 807 | return(strdup("EQ")); 808 | case LE: 809 | return(strdup("LE")); 810 | case GE: 811 | return(strdup("GE")); 812 | case UMENOS: 813 | return(strdup("UMENOS")); 814 | case FUNC: 815 | return(strdup("FUNC")); 816 | default: 817 | return(strdup("default")); 818 | } 819 | } 820 | 821 | void erroSemantico(char *s, int linha) 822 | { 823 | fprintf(stderr,"// Linha:%d. Erro semantico: %s\n", linha, s); 824 | fflush(yyout); 825 | fclose(yyout); 826 | exit(1); 827 | } 828 | --------------------------------------------------------------------------------