add if
This commit is contained in:
parent
ec138f82b3
commit
a1c0f7a19f
7 changed files with 130 additions and 36 deletions
51
al.lex
51
al.lex
|
@ -2,6 +2,7 @@
|
||||||
#include "asm_instructions.h"
|
#include "asm_instructions.h"
|
||||||
#include "symbol_table.h"
|
#include "symbol_table.h"
|
||||||
#include "as.tab.h"
|
#include "as.tab.h"
|
||||||
|
#include "yacc_util.h"
|
||||||
%}
|
%}
|
||||||
|
|
||||||
D [0-9]
|
D [0-9]
|
||||||
|
@ -36,13 +37,49 @@ D [0-9]
|
||||||
"," { return tVIRG; }
|
"," { return tVIRG; }
|
||||||
"{" { return tAO; }
|
"{" { return tAO; }
|
||||||
"}" { return tAF; }
|
"}" { return tAF; }
|
||||||
"!" { return tNOT; }
|
"==" {
|
||||||
"==" { return tEQ2; }
|
struct Condition* c = malloc(sizeof(struct Condition));
|
||||||
"!=" { return tNOTEQ; }
|
c->instruction = EQU;
|
||||||
"<" { return tINF; }
|
c->not = 0;
|
||||||
"<=" { return tINFEQ; }
|
yylval.condition = c;
|
||||||
">" { return tSUP; }
|
return tEQ2;
|
||||||
">=" { return tSUPEQ; }
|
}
|
||||||
|
"!=" {
|
||||||
|
struct Condition* c = malloc(sizeof(struct Condition));
|
||||||
|
c->instruction = EQU;
|
||||||
|
c->not = 1;
|
||||||
|
yylval.condition = c;
|
||||||
|
return tNOTEQ;
|
||||||
|
}
|
||||||
|
"<" {
|
||||||
|
struct Condition* c = malloc(sizeof(struct Condition));
|
||||||
|
c->instruction = INF;
|
||||||
|
c->not = 0;
|
||||||
|
yylval.condition = c;
|
||||||
|
return tINF;
|
||||||
|
}
|
||||||
|
"<=" {
|
||||||
|
struct Condition* c = malloc(sizeof(struct Condition));
|
||||||
|
c->instruction = SUP;
|
||||||
|
c->not = 1;
|
||||||
|
yylval.condition = c;
|
||||||
|
return tINFEQ;
|
||||||
|
}
|
||||||
|
">" {
|
||||||
|
struct Condition* c = malloc(sizeof(struct Condition));
|
||||||
|
c->instruction = SUP;
|
||||||
|
c->not = 0;
|
||||||
|
yylval.condition = c;
|
||||||
|
return tSUP;
|
||||||
|
}
|
||||||
|
">=" {
|
||||||
|
struct Condition* c = malloc(sizeof(struct Condition));
|
||||||
|
c->instruction = INF;
|
||||||
|
c->not = 1;
|
||||||
|
yylval.condition = c;
|
||||||
|
return tSUPEQ;
|
||||||
|
}
|
||||||
|
"!" { return tNOT; }
|
||||||
"&&" { return tAND; }
|
"&&" { return tAND; }
|
||||||
"||" { return tOR; }
|
"||" { return tOR; }
|
||||||
[ \t\n]+ { }
|
[ \t\n]+ { }
|
||||||
|
|
53
as.y
53
as.y
|
@ -16,7 +16,9 @@ InstructionTable instruction_table;
|
||||||
char* symbol_name;
|
char* symbol_name;
|
||||||
SymbolItem* symbol;
|
SymbolItem* symbol;
|
||||||
int nombre;
|
int nombre;
|
||||||
|
int address;
|
||||||
Instruction instruction;
|
Instruction instruction;
|
||||||
|
struct Condition* condition;
|
||||||
}
|
}
|
||||||
|
|
||||||
%token<nombre> tNB
|
%token<nombre> tNB
|
||||||
|
@ -31,13 +33,13 @@ InstructionTable instruction_table;
|
||||||
%token tAO
|
%token tAO
|
||||||
%token tAF
|
%token tAF
|
||||||
%token tEQ
|
%token tEQ
|
||||||
%token tEQ2
|
%token<condition> tEQ2
|
||||||
%token tNOTEQ
|
%token<condition> tNOTEQ
|
||||||
|
%token<condition> tINF
|
||||||
|
%token<condition> tINFEQ
|
||||||
|
%token<condition> tSUP
|
||||||
|
%token<condition> tSUPEQ
|
||||||
%token tNOT
|
%token tNOT
|
||||||
%token tINF
|
|
||||||
%token tINFEQ
|
|
||||||
%token tSUP
|
|
||||||
%token tSUPEQ
|
|
||||||
%token tAND
|
%token tAND
|
||||||
%token tOR
|
%token tOR
|
||||||
|
|
||||||
|
@ -56,6 +58,8 @@ InstructionTable instruction_table;
|
||||||
%left tMUL
|
%left tMUL
|
||||||
%left tDIV
|
%left tDIV
|
||||||
%type<symbol> E
|
%type<symbol> E
|
||||||
|
%type<symbol> Cond
|
||||||
|
%type<address> IfSimple
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
|
@ -74,7 +78,7 @@ Body : tAO Instructions tAF { printf("Body\n"); } ;
|
||||||
|
|
||||||
Instructions : Instruction Instructions | { printf("Instructions\n"); } ;
|
Instructions : Instruction Instructions | { printf("Instructions\n"); } ;
|
||||||
|
|
||||||
Instruction : Aff | Printf { printf("Instruction\n"); } ;
|
Instruction : Aff | Printf | If { printf("Instruction\n"); } ;
|
||||||
|
|
||||||
Aff : tID tEQ E tPV { write_affectation(&symbol_table, &instruction_table, $1, $3); } ;
|
Aff : tID tEQ E tPV { write_affectation(&symbol_table, &instruction_table, $1, $3); } ;
|
||||||
|
|
||||||
|
@ -97,30 +101,29 @@ DeclarationConst : tCONST { current_type = TYPE_CONST; } DeclarationBody tPV ;
|
||||||
|
|
||||||
DeclarationBody : VariableIdentifier tVIRG DeclarationBody | VariableIdentifier ;
|
DeclarationBody : VariableIdentifier tVIRG DeclarationBody | VariableIdentifier ;
|
||||||
|
|
||||||
VariableIdentifier: tID { add_symbol(&symbol_table, current_type, $1); }
|
VariableIdentifier: tID { add_symbol(&symbol_table, current_type, $1); } ;
|
||||||
|
|
||||||
// While : tWHILE tPO Cond tPF Body { printf("While\n"); } ;
|
// While : tWHILE tPO Cond tPF Body { printf("While\n"); } ;
|
||||||
//
|
|
||||||
// If : IfSimple | IfElse { printf("If\n"); } ;
|
If : IfSimple { update_jmf(&instruction_table, $1); } ;
|
||||||
//
|
|
||||||
// IfSimple : tIF tPO Cond tPF Body { printf("IfSimple\n"); } ;
|
IfSimple : tIF tPO Cond tPF { $<address>$ = write_jmf(&instruction_table, $3); } Body { $$ = $<address>5; };
|
||||||
//
|
|
||||||
// IfElse : IfSimple tELSE Body { printf("IfElse\n"); } ;
|
// IfElse : IfSimple tELSE Body { printf("IfElse\n"); } ;
|
||||||
//
|
|
||||||
// Cond : tNOT Cond | Cond tAND Cond | Cond tOR Cond | E tEQ2 E | E tINF E | E tINFEQ E | E tSUP E | E tSUPEQ E | E tNOTEQ E | tNOT tPO Cond tPF { printf("Cond\n"); } ;
|
Cond : tNOT Cond { $$ = write_not_condition(&symbol_table, &instruction_table, $2); }
|
||||||
|
| Cond tAND Cond { $$ = write_op(&symbol_table, &instruction_table, MUL, $1, $3); }
|
||||||
|
| Cond tOR Cond { $$ = write_op(&symbol_table, &instruction_table, ADD, $1, $3); }
|
||||||
|
| E tEQ2 E { $$ = write_condition(&symbol_table, &instruction_table, $2, $1, $3); }
|
||||||
|
| E tINF E { $$ = write_condition(&symbol_table, &instruction_table, $2, $1, $3); }
|
||||||
|
| E tINFEQ E { $$ = write_condition(&symbol_table, &instruction_table, $2, $1, $3); }
|
||||||
|
| E tSUP E { $$ = write_condition(&symbol_table, &instruction_table, $2, $1, $3); }
|
||||||
|
| E tSUPEQ E { $$ = write_condition(&symbol_table, &instruction_table, $2, $1, $3); }
|
||||||
|
| E tNOTEQ E { $$ = write_condition(&symbol_table, &instruction_table, $2, $1, $3); }
|
||||||
|
| tNOT tPO Cond tPF { $$ = write_not_condition(&symbol_table, &instruction_table, $3); } ;
|
||||||
|
|
||||||
Printf : tPRINTF tPO E tPF tPV { write_print(&instruction_table, $3); } ;
|
Printf : tPRINTF tPO E tPF tPV { write_print(&instruction_table, $3); } ;
|
||||||
|
|
||||||
// If : tIF tPO Cond tPF Body ;
|
|
||||||
//
|
|
||||||
// Cond : Cond tAND Cond | Cond tOR Cond | E tEQ2 E | E tINF E | tNOT Cond ;
|
|
||||||
|
|
||||||
// Invocation : tID tPO Args tPF ;
|
|
||||||
|
|
||||||
// Args : .... cf params
|
|
||||||
|
|
||||||
// Return : tRET E tPV ;
|
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
|
@ -49,3 +49,7 @@ void write_instruction(InstructionItem *item, FILE *file) {
|
||||||
fprintf(file, "%s %d %d %d\n", instructions_labels[item->instruction], item->arg1, item->arg2, item->arg3);
|
fprintf(file, "%s %d %d %d\n", instructions_labels[item->instruction], item->arg1, item->arg2, item->arg3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int get_current_address(struct InstructionTable *table) {
|
||||||
|
return table->index;
|
||||||
|
}
|
|
@ -2,6 +2,7 @@
|
||||||
#define COMPILATOR_2000_ASM_INSTRUCTIONS_H
|
#define COMPILATOR_2000_ASM_INSTRUCTIONS_H
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include "symbol_table.h"
|
||||||
|
|
||||||
#define INSTRUCTION_TABLE_SIZE 100
|
#define INSTRUCTION_TABLE_SIZE 100
|
||||||
|
|
||||||
|
@ -43,4 +44,6 @@ void write_instruction_table(InstructionTable *table, FILE *file);
|
||||||
|
|
||||||
void write_instruction(InstructionItem *item, FILE *file);
|
void write_instruction(InstructionItem *item, FILE *file);
|
||||||
|
|
||||||
|
int get_current_address(InstructionTable *table);
|
||||||
|
|
||||||
#endif //COMPILATOR_2000_ASM_INSTRUCTIONS_H
|
#endif //COMPILATOR_2000_ASM_INSTRUCTIONS_H
|
||||||
|
|
5
test.c
5
test.c
|
@ -4,4 +4,9 @@ int main(){
|
||||||
x = 2;
|
x = 2;
|
||||||
printf(x);
|
printf(x);
|
||||||
y = 3 + 3 + x;
|
y = 3 + 3 + x;
|
||||||
|
if (x == 2) {
|
||||||
|
printf(x);
|
||||||
|
printf(y);
|
||||||
|
}
|
||||||
|
x = 3;
|
||||||
}
|
}
|
||||||
|
|
38
yacc_util.c
38
yacc_util.c
|
@ -15,13 +15,11 @@ const SymbolItem* write_op(SymbolTable* symbol_table, InstructionTable *instruct
|
||||||
const SymbolItem* write_negation(SymbolTable* symbol_table, InstructionTable *instruction_table, SymbolItem *op2) {
|
const SymbolItem* write_negation(SymbolTable* symbol_table, InstructionTable *instruction_table, SymbolItem *op2) {
|
||||||
// Create temp variable with 0
|
// Create temp variable with 0
|
||||||
const SymbolItem* op1 = init_temp_symbol(symbol_table, instruction_table, 0);
|
const SymbolItem* op1 = init_temp_symbol(symbol_table, instruction_table, 0);
|
||||||
const SymbolItem* dest = add_temp_symbol(symbol_table, TYPE_INT);
|
|
||||||
// Make the 0 - variable operation
|
// Make the 0 - variable operation
|
||||||
add_instruction(instruction_table, SOU, dest->address, op1->address, op2->address);
|
add_instruction(instruction_table, SOU, op1->address, op1->address, op2->address);
|
||||||
return dest;
|
return op1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const SymbolItem* init_temp_symbol(SymbolTable* symbol_table, InstructionTable *instruction_table, int constant) {
|
const SymbolItem* init_temp_symbol(SymbolTable* symbol_table, InstructionTable *instruction_table, int constant) {
|
||||||
const SymbolItem* dest = add_temp_symbol(symbol_table, TYPE_INT);
|
const SymbolItem* dest = add_temp_symbol(symbol_table, TYPE_INT);
|
||||||
add_instruction(instruction_table, AFC, dest->address, constant, 0);
|
add_instruction(instruction_table, AFC, dest->address, constant, 0);
|
||||||
|
@ -32,4 +30,36 @@ void write_print(InstructionTable *instruction_table, SymbolItem *src) {
|
||||||
add_instruction(instruction_table, PRI, src->address, 0, 0);
|
add_instruction(instruction_table, PRI, src->address, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int update_jmf(InstructionTable *table, int address) {
|
||||||
|
if (address > table->index) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
table->table[address].arg2 = get_current_address(table);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int write_jmf(InstructionTable *table, SymbolItem* cond) {
|
||||||
|
int addr = get_current_address(table);
|
||||||
|
add_instruction(table, JMF, cond->address, 0, 0);
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SymbolItem* write_not_condition(SymbolTable* symbol_table, InstructionTable *instruction_table, const SymbolItem* cond) {
|
||||||
|
// Create temp variable with 0
|
||||||
|
const SymbolItem* op1 = init_temp_symbol(symbol_table, instruction_table, 0);
|
||||||
|
// Check if the condition is equal to 0 (makes the negation)
|
||||||
|
add_instruction(instruction_table, EQU, op1->address, op1->address, cond->address);
|
||||||
|
return op1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SymbolItem* write_condition(SymbolTable* symbol_table, InstructionTable *instruction_table, Condition* op, SymbolItem* cond1, SymbolItem* cond2) {
|
||||||
|
const SymbolItem *dest = write_op(symbol_table, instruction_table, op->instruction, cond1, cond2);
|
||||||
|
if (op->not) {
|
||||||
|
return write_not_condition(symbol_table, instruction_table, dest);
|
||||||
|
}
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
12
yacc_util.h
12
yacc_util.h
|
@ -4,6 +4,10 @@
|
||||||
#ifndef COMPILATOR_2000_YACC_UTIL_H
|
#ifndef COMPILATOR_2000_YACC_UTIL_H
|
||||||
#define COMPILATOR_2000_YACC_UTIL_H
|
#define COMPILATOR_2000_YACC_UTIL_H
|
||||||
|
|
||||||
|
typedef struct Condition {
|
||||||
|
Instruction instruction;
|
||||||
|
int not;
|
||||||
|
} Condition;
|
||||||
|
|
||||||
void write_affectation(SymbolTable* symbolTable, InstructionTable *instructionTable, char* symbol_dest, SymbolItem* src);
|
void write_affectation(SymbolTable* symbolTable, InstructionTable *instructionTable, char* symbol_dest, SymbolItem* src);
|
||||||
|
|
||||||
|
@ -15,4 +19,12 @@ const SymbolItem* init_temp_symbol(SymbolTable* symbol_table, InstructionTable *
|
||||||
|
|
||||||
void write_print(InstructionTable *instruction_table, SymbolItem *src);
|
void write_print(InstructionTable *instruction_table, SymbolItem *src);
|
||||||
|
|
||||||
|
int update_jmf(InstructionTable *table, int address);
|
||||||
|
|
||||||
|
int write_jmf(InstructionTable *table, SymbolItem* cond);
|
||||||
|
|
||||||
|
const SymbolItem* write_not_condition(SymbolTable* symbol_table, InstructionTable *table, const SymbolItem* cond);
|
||||||
|
|
||||||
|
const SymbolItem* write_condition(SymbolTable* symbol_table, InstructionTable *table, Condition* op, SymbolItem* cond1, SymbolItem* cond2);
|
||||||
|
|
||||||
#endif //COMPILATOR_2000_YACC_UTIL_H
|
#endif //COMPILATOR_2000_YACC_UTIL_H
|
||||||
|
|
Loading…
Reference in a new issue