Skip to content

Commit

Permalink
Arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
pedrommaiaa committed Jun 18, 2021
1 parent 81df6ca commit 03c0597
Show file tree
Hide file tree
Showing 15 changed files with 114 additions and 86 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ clean:
test: flow tests/bash/runtests.sh
(cd tests/bash; chmod +x runtests.sh; ./runtests.sh)

test2: flow tests/input19.flow lib/printint.c
./flow tests/input19.flow
test2: flow tests/input20.flow lib/printint.c
./flow tests/input20.flow
gcc -o out out.s lib/printint.c
./out
Binary file modified flow
Binary file not shown.
7 changes: 6 additions & 1 deletion grammar.txt
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ global_declaration: function_declaration | var_declaration
function_declaration: type identifier '(' ')' compound_statement
;

var_declaration: type identifier_list ';'
variable_declaration: type identifier_List ';'
| type identifier '[' P_INTLIT ']' ';'
;

type: type_keyword opt_pointer
Expand Down Expand Up @@ -108,3 +109,7 @@ primary_expression: IDENTIFIER
| STRING_LITERAL
| '(' expression ')'
;

postfix_expression : primary_expression
| postfix_expression '[' expression ']'

Binary file modified out
Binary file not shown.
73 changes: 36 additions & 37 deletions out.s
Original file line number Diff line number Diff line change
Expand Up @@ -4,51 +4,50 @@
a: .long 0
.data
.globl b
b: .long 0
.data
.globl c
c: .long 0
.data
.globl d
d: .long 0
.data
.globl e
e: .long 0
b: .quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.text
.globl main
.type main, @function
main:
pushq %rbp
movq %rsp, %rbp
movq $2, %r8
movl %r8d, a(%rip)
movq $4, %r8
movl %r8d, b(%rip)
movq $3, %r8
movl %r8d, c(%rip)
movq $2, %r8
movl %r8d, d(%rip)
movzbl a(%rip), %r8
movzbl b(%rip), %r9
movq $12, %r8
leaq b(%rip), %r9
movq $3, %r10
salq $2, %r10
addq %r9, %r10
movq %r8, (%r10)
leaq b(%rip), %r8
movq $3, %r9
salq $2, %r9
addq %r8, %r9
movq %r9, %rdi
call printint
movq %rax, %r8
movzbl c(%rip), %r8
movzbl d(%rip), %r9
addq %r8, %r9
movq %r9, %rdi
call printint
movq %rax, %r8
movq (%r9), %r9
movl %r9d, a(%rip)
movzbl a(%rip), %r8
movzbl b(%rip), %r9
addq %r8, %r9
movzbl c(%rip), %r8
movzbl d(%rip), %r10
addq %r8, %r10
imulq %r9, %r10
movl %r10d, e(%rip)
movzbl e(%rip), %r8
movq %r8, %rdi
call printint
movq %rax, %r9
Expand Down
24 changes: 11 additions & 13 deletions src/cg.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

// Code generator for x86-64


// List of available registers and their names.
// We need a list of byte and doubleword registers, too
static int freereg[4];
Expand Down Expand Up @@ -139,13 +138,6 @@ int cgdiv(int r1, int r2) {
return (r1);
}

// Call printint() with the given register
void cgprintint(int r) {
fprintf(Outfile, "\tmovq\t%s, %%rdi\n", reglist[r]);
fprintf(Outfile, "\tcall\tprintint\n");
free_register(r);
}

// Call a function with one argument from the given register
// Return the register with the result
int cgcall(int r, int id) {
Expand Down Expand Up @@ -206,12 +198,18 @@ void cgglobsym(int id) {
// Get the size of the type
typesize = cgprimsize(Gsym[id].type);

// Generate the global identity and the label
fprintf(Outfile, "\t.data\n" "\t.globl\t%s\n", Gsym[id].name);
switch(typesize) {
case 1: fprintf(Outfile, "%s:\t.byte\t0\n", Gsym[id].name); break;
case 4: fprintf(Outfile, "%s:\t.long\t0\n", Gsym[id].name); break;
case 8: fprintf(Outfile, "%s:\t.quad\t0\n", Gsym[id].name); break;
default: fatald("Unknown typesize in cgglobsym: ", typesize);
fprintf(Outfile, "%s:", Gsym[id].name);

// Generate the space
for (int i=0; i < Gsym[id].size; i++) {
switch(typesize) {
case 1: fprintf(Outfile, "\t.byte\t0\n"); break;
case 4: fprintf(Outfile, "\t.long\t0\n"); break;
case 8: fprintf(Outfile, "\t.quad\t0\n"); break;
default: fatald("Unknown typesize in cgglobsym: ", typesize);
}
}
}

Expand Down
55 changes: 32 additions & 23 deletions src/decl.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,10 @@
int parse_type(void) {
int type;
switch (Token.token) {
case T_VOID:
type = P_VOID;
break;
case T_CHAR:
type = P_CHAR;
break;
case T_INT:
type = P_INT;
break;
case T_LONG:
type = P_LONG;
break;
case T_VOID: type = P_VOID; break;
case T_CHAR: type = P_CHAR; break;
case T_INT: type = P_INT; break;
case T_LONG: type = P_LONG; break;
default:
fatald("Illegal type, token", Token.token);
}
Expand All @@ -40,25 +32,42 @@ int parse_type(void) {
return (type);
}

// variable_declaration: type identifier ';' ;
//
// Parse the declaration of a variable.
// The identifier has been scanned & we have the type
void var_declaration(int type) {
int id;

// Text now has the identifier's name.
// Add it as a known identifier
// and generate its space in assembly
id = addglob(Text, type, S_VARIABLE, 0);
genglobsym(id);
// If the enxt token is a '['
if (Token.token == T_LBRACKET)
{
// Skip past the '['
scan(&Token);

// Check we have an array size
if (Token.token == T_INTLIT)
{
// Add this as a known array and generate its spaces in assembly.
// We treat the array as a pointer to its element's type
id = addglob(Text, pointer_to(type), S_ARRAY, 0, Token.intvalue);
genglobsym(id);
}

// Ensure we have a following ']'
scan(&Token);
match(T_RBRACKET, "]");
}
else
{
// Add it as a known identifier
// and generate its space in assembly
id = addglob(Text, type, S_VARIABLE, 0, 1);
genglobsym(id);
}
// Get the trailing semicolon
semi();
}

//
// function_declaration: type identifier '(' ')' compound_statement ;
//
// Parse the declaration of a simplistic function.
// The identifier has been scanned & we have the type
AST_T *function_declaration(int type) {
Expand All @@ -70,7 +79,7 @@ AST_T *function_declaration(int type) {
// to the symbol table, and set the Functionid global
// to the function's symbol-id
endlabel = genlabel();
nameslot = addglob(Text, type, S_FUNCTION, endlabel);
nameslot = addglob(Text, type, S_FUNCTION, endlabel, 0);
Functionid = nameslot;

// Scan in the parentheses
Expand Down
8 changes: 5 additions & 3 deletions src/gen.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,21 +186,23 @@ int genAST(AST_T *n, int label, int parentASTop) {
return (NOREG); // Keep -Wall happy
}


void genpreamble() {
cgpreamble();
}

void genpostamble() {
cgpostamble();
}

void genfreeregs() {
freeall_registers();
}
void genprintint(int reg) {
cgprintint(reg);
}

void genglobsym(int id) {
cgglobsym(id);
}

int genprimsize(int type) {
return (cgprimsize(type));
}
4 changes: 1 addition & 3 deletions src/include/decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ int genAST(struct ASTnode *n, int reg, int parentASTop);
void genpreamble();
void genpostamble();
void genfreeregs();
void genprintint(int reg);
void genglobsym(int id);
int genprimsize(int type);
void genreturn(int reg, int id);
Expand All @@ -39,7 +38,6 @@ int cgsub(int r1, int r2);
int cgmul(int r1, int r2);
int cgdiv(int r1, int r2);
int cgshlconst(int r, int val);
void cgprintint(int r);
int cgcall(int r, int id);
int cgstorglob(int r, int id);
void cgglobsym(int id);
Expand Down Expand Up @@ -76,7 +74,7 @@ void fatalc(char *s, int c);

// sym.c
int findglob(char *s);
int addglob(char *name, int type, int stype, int endlabel);
int addglob(char *name, int type, int stype, int endlabel, int size);

// decl.c
void var_declaration(int type);
Expand Down
1 change: 1 addition & 0 deletions src/include/defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,5 @@ typedef struct symtable {
int type; // Primitive type for the symbol
int stype; // Structural type for the symbol
int endlabel; // For S_FUNCTIONs, the end label
int size; // Number of elements in the symbol
}SymTable_T;
2 changes: 1 addition & 1 deletion src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ int main(int argc, char *argv[]) {
exit(1);
}
// For now, ensure that void printint() is defined
addglob("printint", P_CHAR, S_FUNCTION, 0);
addglob("printint", P_CHAR, S_FUNCTION, 0, 0);

scan(&Token); // Get the first token from the input
genpreamble(); // Output the preamble
Expand Down
2 changes: 2 additions & 0 deletions src/scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ int scan(token_T *t) {
case '}': t->token = T_RBRACE; break;
case '(': t->token = T_LPAREN; break;
case ')': t->token = T_RPAREN; break;
case '[': t->token = T_LBRACKET; break;
case ']': t->token = T_RBRACKET; break;
case '=': if ((c = next()) == '=') { t->token = T_EQ; } else { putback(c); t->token = T_ASSIGN; } break;
case '!': if ((c = next()) == '=') { t->token = T_NE; } else { fatalc("Unrecognised character", c); } break;
case '<': if ((c = next()) == '=') { t->token = T_LE; } else { putback(c); t->token = T_LT; } break;
Expand Down
10 changes: 7 additions & 3 deletions src/sym.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,13 @@ static int newglob(void) {
return (p);
}

// Add a global symbol to the symbol table.
// Also set up its type and structural type.
// Add a global symbol to the symbol table. Set up its:
// + type: char, int etc.
// + structural typ: var, function, array etc.
// + size: number of elements
// + endlabel: if this is a function
// Return the slot number in the symbol table
int addglob(char *name, int type, int stype, int endlabel) {
int addglob(char *name, int type, int stype, int endlabel, int size) {
int y;

// If this is already in the symbol table, return the existing slot
Expand All @@ -44,5 +47,6 @@ int addglob(char *name, int type, int stype, int endlabel) {
Gsym[y].type = type;
Gsym[y].stype = stype;
Gsym[y].endlabel = endlabel;
Gsym[y].size = size;
return (y);
}
9 changes: 9 additions & 0 deletions tests/input20.flow
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
int a;
int b[25];

int main() {
b[3] = 12;
a = b[3];
printint(a);
return(0);
}
1 change: 1 addition & 0 deletions tests/results/out.input20.flow
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
12

0 comments on commit 03c0597

Please sign in to comment.