add if
This commit is contained in:
parent
ec138f82b3
commit
a1c0f7a19f
7 changed files with 130 additions and 36 deletions
49
al.lex
49
al.lex
|
@ -2,6 +2,7 @@
|
|||
#include "asm_instructions.h"
|
||||
#include "symbol_table.h"
|
||||
#include "as.tab.h"
|
||||
#include "yacc_util.h"
|
||||
%}
|
||||
|
||||
D [0-9]
|
||||
|
@ -36,13 +37,49 @@ D [0-9]
|
|||
"," { return tVIRG; }
|
||||
"{" { return tAO; }
|
||||
"}" { return tAF; }
|
||||
"==" {
|
||||
struct Condition* c = malloc(sizeof(struct Condition));
|
||||
c->instruction = EQU;
|
||||
c->not = 0;
|
||||
yylval.condition = c;
|
||||
return tEQ2;
|
||||
}
|
||||
"!=" {
|
||||
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 tEQ2; }
|
||||
"!=" { return tNOTEQ; }
|
||||
"<" { return tINF; }
|
||||
"<=" { return tINFEQ; }
|
||||
">" { return tSUP; }
|
||||
">=" { return tSUPEQ; }
|
||||
"&&" { return tAND; }
|
||||
"||" { return tOR; }
|
||||
[ \t\n]+ { }
|
||||
|
|
53
as.y
53
as.y
|
@ -16,7 +16,9 @@ InstructionTable instruction_table;
|
|||
char* symbol_name;
|
||||
SymbolItem* symbol;
|
||||
int nombre;
|
||||
int address;
|
||||
Instruction instruction;
|
||||
struct Condition* condition;
|
||||
}
|
||||
|
||||
%token<nombre> tNB
|
||||
|
@ -31,13 +33,13 @@ InstructionTable instruction_table;
|
|||
%token tAO
|
||||
%token tAF
|
||||
%token tEQ
|
||||
%token tEQ2
|
||||
%token tNOTEQ
|
||||
%token<condition> tEQ2
|
||||
%token<condition> tNOTEQ
|
||||
%token<condition> tINF
|
||||
%token<condition> tINFEQ
|
||||
%token<condition> tSUP
|
||||
%token<condition> tSUPEQ
|
||||
%token tNOT
|
||||
%token tINF
|
||||
%token tINFEQ
|
||||
%token tSUP
|
||||
%token tSUPEQ
|
||||
%token tAND
|
||||
%token tOR
|
||||
|
||||
|
@ -56,6 +58,8 @@ InstructionTable instruction_table;
|
|||
%left tMUL
|
||||
%left tDIV
|
||||
%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"); } ;
|
||||
|
||||
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); } ;
|
||||
|
||||
|
@ -97,30 +101,29 @@ DeclarationConst : tCONST { current_type = TYPE_CONST; } DeclarationBody tPV ;
|
|||
|
||||
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"); } ;
|
||||
//
|
||||
// If : IfSimple | IfElse { printf("If\n"); } ;
|
||||
//
|
||||
// IfSimple : tIF tPO Cond tPF Body { printf("IfSimple\n"); } ;
|
||||
//
|
||||
|
||||
If : IfSimple { update_jmf(&instruction_table, $1); } ;
|
||||
|
||||
IfSimple : tIF tPO Cond tPF { $<address>$ = write_jmf(&instruction_table, $3); } Body { $$ = $<address>5; };
|
||||
|
||||
// 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); } ;
|
||||
|
||||
// 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>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
int get_current_address(struct InstructionTable *table) {
|
||||
return table->index;
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
#define COMPILATOR_2000_ASM_INSTRUCTIONS_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include "symbol_table.h"
|
||||
|
||||
#define INSTRUCTION_TABLE_SIZE 100
|
||||
|
||||
|
@ -43,4 +44,6 @@ void write_instruction_table(InstructionTable *table, FILE *file);
|
|||
|
||||
void write_instruction(InstructionItem *item, FILE *file);
|
||||
|
||||
int get_current_address(InstructionTable *table);
|
||||
|
||||
#endif //COMPILATOR_2000_ASM_INSTRUCTIONS_H
|
||||
|
|
5
test.c
5
test.c
|
@ -4,4 +4,9 @@ int main(){
|
|||
x = 2;
|
||||
printf(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) {
|
||||
// Create temp variable with 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
|
||||
add_instruction(instruction_table, SOU, dest->address, op1->address, op2->address);
|
||||
return dest;
|
||||
add_instruction(instruction_table, SOU, op1->address, op1->address, op2->address);
|
||||
return op1;
|
||||
}
|
||||
|
||||
|
||||
const SymbolItem* init_temp_symbol(SymbolTable* symbol_table, InstructionTable *instruction_table, int constant) {
|
||||
const SymbolItem* dest = add_temp_symbol(symbol_table, TYPE_INT);
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
#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);
|
||||
|
||||
|
@ -15,4 +19,12 @@ const SymbolItem* init_temp_symbol(SymbolTable* symbol_table, InstructionTable *
|
|||
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue