Skip to content

Commit

Permalink
Hello World!
Browse files Browse the repository at this point in the history
  • Loading branch information
pedrommaiaa committed Jun 18, 2021
1 parent 03c0597 commit ccec338
Show file tree
Hide file tree
Showing 16 changed files with 161 additions and 85 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/input20.flow lib/printint.c
./flow tests/input20.flow
test2: flow tests/input21.flow lib/printint.c
./flow tests/input21.flow
gcc -o out out.s lib/printint.c
./out
Binary file modified flow
Binary file not shown.
11 changes: 9 additions & 2 deletions lib/printint.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
#include <stdio.h>
void printint(long x) {

void printint(long x)
{
printf("%ld\n", x);
}
}

void printchar(long x)
{
putc((char)(x & 0x7f), stdout);
}
Binary file removed out
Binary file not shown.
59 changes: 0 additions & 59 deletions out.s

This file was deleted.

23 changes: 23 additions & 0 deletions src/cg.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,17 @@ int cgloadglob(int id) {
return (r);
}


// Given the label number of a global string,
// load its address into a new register
int cgloadglobstr(int id) {
// Get a new register
int r = alloc_register();
fprintf(Outfile, "\tleaq\tL%d(\%%rip), %s\n", id, reglist[r]);
return (r);
}


// Add two registers together and return
// the number of the register with the result
int cgadd(int r1, int r2) {
Expand Down Expand Up @@ -213,6 +224,18 @@ void cgglobsym(int id) {
}
}


// Generate a global string and its start label
void cgglobstr(int l, char *strvalue) {
char *cptr;
cglabel(l);
for (cptr= strvalue; *cptr; cptr++) {
fprintf(Outfile, "\t.byte\t%d\n", *cptr);
}
fprintf(Outfile, "\t.byte\t0\n");
}


// List of comparison instructions,
// in AST order: A_EQ, A_NE, A_LT, A_GT, A_LE, A_GE
static char *cmplist[] =
Expand Down
9 changes: 8 additions & 1 deletion src/expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

// Parse a function call with a single expression
// argument and return its AST
AST_T *funccall(void) {
static AST_T *funccall(void) {
AST_T *tree;
int id;

Expand Down Expand Up @@ -88,6 +88,13 @@ static AST_T *primary(void) {
n = mkastleaf(A_INTLIT, P_INT, Token.intvalue);
break;

case T_STRLIT:
// For a STRLIT token, generate the assembly for it.
// Then make a leaf AST node for it. id is the string's label.
id = genglobstr(Text);
n = mkastleaf(A_STRLIT, P_CHARPTR, id);
break;

case T_IDENT:
// This could be a variable or a function call.
// Scan in the next token to find out
Expand Down
8 changes: 8 additions & 0 deletions src/gen.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ int genAST(AST_T *n, int label, int parentASTop) {
return (cgcompare_and_set(n->op, leftreg, rightreg));
case A_INTLIT:
return (cgloadint(n->v.intvalue, n->type));
case A_STRLIT:
return (cgloadglobstr(n->v.id));
case A_IDENT:
// Load our value if we are an rvalue
// or we are being dereferenced
Expand Down Expand Up @@ -203,6 +205,12 @@ void genglobsym(int id) {
cgglobsym(id);
}

int genglobstr(char *strvalue){
int l = genlabel();
cgglobstr(l, strvalue);
return(l);
}

int genprimsize(int type) {
return (cgprimsize(type));
}
34 changes: 18 additions & 16 deletions src/include/decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,27 @@


// scan.c
void reject_token(struct token *t);
int scan(struct token *t);
void reject_token(token_T *t);
int scan(token_T *t);

// tree.c
struct ASTnode *mkastnode(int op, int type,
struct ASTnode *left,
struct ASTnode *mid,
struct ASTnode *right, int intvalue);
struct ASTnode *mkastleaf(int op, int type, int intvalue);
struct ASTnode *mkastunary(int op, int type,
struct ASTnode *left, int intvalue);
void dumpAST(struct ASTnode *n, int label, int parentASTop);
AST_T *mkastnode(int op, int type,
AST_T *left,
AST_T *mid,
AST_T *right, int intvalue);
AST_T *mkastleaf(int op, int type, int intvalue);
AST_T *mkastunary(int op, int type,
AST_T *left, int intvalue);
void dumpAST(AST_T *n, int label, int parentASTop);

// gen.c
int genlabel(void);
int genAST(struct ASTnode *n, int reg, int parentASTop);
int genAST(AST_T *n, int reg, int parentASTop);
void genpreamble();
void genpostamble();
void genfreeregs();
void genglobsym(int id);
int genglobstr(char *strvalue);
int genprimsize(int type);
void genreturn(int reg, int id);

Expand All @@ -33,6 +34,7 @@ void cgfuncpreamble(int id);
void cgfuncpostamble(int id);
int cgloadint(int value, int type);
int cgloadglob(int id);
int cgloadglobstr(int id);
int cgadd(int r1, int r2);
int cgsub(int r1, int r2);
int cgmul(int r1, int r2);
Expand All @@ -41,6 +43,7 @@ int cgshlconst(int r, int val);
int cgcall(int r, int id);
int cgstorglob(int r, int id);
void cgglobsym(int id);
void cgglobstr(int l, char *strvalue);
int cgcompare_and_set(int ASTop, int r1, int r2);
int cgcompare_and_jump(int ASTop, int r1, int r2, int label);
void cglabel(int l);
Expand All @@ -53,11 +56,10 @@ int cgderef(int r, int type);
int cgstorderef(int r1, int r2, int type);

// expr.c
struct ASTnode *funccall(void);
struct ASTnode *binexpr(int ptp);
AST_T *binexpr(int ptp);

// stmt.c
struct ASTnode *compound_statement(void);
AST_T *compound_statement(void);

// misc.c
void match(int t, char *what);
Expand All @@ -78,12 +80,12 @@ int addglob(char *name, int type, int stype, int endlabel, int size);

// decl.c
void var_declaration(int type);
struct ASTnode *function_declaration(int type);
AST_T *function_declaration(int type);
void global_declarations(void);

// types.c
int inttype(int type);
int parse_type(void);
int pointer_to(int type);
int value_at(int type);
struct ASTnode *modify_type(struct ASTnode *tree, int rtype, int op);
AST_T *modify_type(AST_T *tree, int rtype, int op);
7 changes: 3 additions & 4 deletions src/include/defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,9 @@ enum {
// Type keywords
T_VOID, T_CHAR, T_INT, T_LONG,
// Structural tokens
T_INTLIT, T_SEMI, T_IDENT,
T_INTLIT, T_STRLIT, T_SEMI, T_IDENT,
T_LBRACE, T_RBRACE, T_LPAREN, T_RPAREN,
T_LBRACKET, T_RBRACKET,
T_AMPER, T_LOGAND,
T_LBRACKET, T_RBRACKET, T_AMPER, T_LOGAND,
// Other keywords
T_IF, T_ELSE, T_WHILE, T_FOR, T_RETURN
};
Expand All @@ -39,7 +38,7 @@ typedef struct token {
enum {
A_ASSIGN= 1, A_ADD, A_SUBTRACT, A_MULTIPLY, A_DIVIDE,
A_EQ, A_NE, A_LT, A_GT, A_LE, A_GE,
A_INTLIT, A_IDENT, A_GLUE,
A_INTLIT, A_STRLIT, A_IDENT, A_GLUE,
A_IF, A_WHILE, A_FUNCTION, A_WIDEN, A_RETURN,
A_FUNCCALL, A_DEREF, A_ADDR, A_SCALE
};
Expand Down
1 change: 1 addition & 0 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ int main(int argc, char *argv[]) {
}
// For now, ensure that void printint() is defined
addglob("printint", P_CHAR, S_FUNCTION, 0, 0);
addglob("printchar", P_VOID, S_FUNCTION, 0, 0);

scan(&Token); // Get the first token from the input
genpreamble(); // Output the preamble
Expand Down
1 change: 1 addition & 0 deletions src/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ void ident(void) {
match(T_IDENT, "identifier");
}


// Print out fatal messages
void fatal(char *s) {
fprintf(stderr, "%s on line %d\n", s, Line);
Expand Down
72 changes: 72 additions & 0 deletions src/scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,37 @@ static int skip(void) {
return (c);
}


// Return the next character froma character
// or string literal
static int scanch(void)
{
int c;

// Get the next input character and interpret
// metacharacters that start with a backslash
c = next();
if (c == '\\')
{
switch (c = next())
{
case 'a': return '\a';
case 'b': return '\b';
case 'f': return '\f';
case 'n': return '\n';
case 'r': return '\r';
case 't': return '\t';
case 'v': return '\v';
case '"': return '"';
case '\'': return '\'';
default: fatalc("Unknown escape sequence", c);
}
}
return (c); // Just an ordinary old character!

}


// Scan and return an integer literal
// value from the input file.
static int scanint(int c) {
Expand All @@ -65,6 +96,33 @@ static int scanint(int c) {
return (val);
}


// Scan in a string literal from the input file,
// and store it in buf[]. Return the length of
// the string.
static int scanstr(char *buf)
{
int i, c;

// Loop while we have enough buffer space
for (i=0; i<TEXTLEN-1; i++)
{
// Get the next char and append to buf
// Return when we hit the ending double quote
if ((c = scanch()) == '"')
{
buf[i] = 0;
return (i);
}
buf[i] = c;
}
// Ran out of buf[] space
fatal("String literal too long");
return(0);
}



// Scan an identifier from the input file and
// store it in buf[]. Return the identifier's length
static int scanident(int c, char *buf, int lim) {
Expand Down Expand Up @@ -176,6 +234,20 @@ int scan(token_T *t) {
case '<': if ((c = next()) == '=') { t->token = T_LE; } else { putback(c); t->token = T_LT; } break;
case '>': if ((c = next()) == '=') { t->token = T_GE; } else { putback(c); t->token = T_GT; } break;
case '&': if ((c = next()) == '&') { t->token = T_LOGAND; } else { putback(c); t->token = T_AMPER; } break;
case '\'':
// If it's a quote, scan in the
// literal character value and
// the trailing quote
t->intvalue = scanch();
t->token = T_INTLIT;
if (next() != '\'')
fatal("Expected '\\'' at end of char literal");
break;
case '"':
// Scan in a literal string
scanstr(Text);
t->token = T_STRLIT;
break;
default:

// If it's a digit, scan the
Expand Down
4 changes: 3 additions & 1 deletion src/types.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,9 @@ AST_T *modify_type(AST_T *tree, int rtype, int op) {
if (inttype(ltype) && ptrtype(rtype)) {
rsize = genprimsize(value_at(rtype));
if (rsize > 1)
return (mkastunary(A_SCALE, rtype, tree, rsize));
return (mkastunary(A_SCALE, rtype, tree, rsize));
else
return (tree); // Size 1, no need to scale
}
}
// If we get here, the types are not compatible
Expand Down
Loading

0 comments on commit ccec338

Please sign in to comment.