Skip to content
This repository has been archived by the owner on Aug 22, 2018. It is now read-only.

Commit

Permalink
Read source code from file
Browse files Browse the repository at this point in the history
  • Loading branch information
ShinyaKato committed Aug 16, 2018
1 parent 091d476 commit 2c6f155
Show file tree
Hide file tree
Showing 6 changed files with 162 additions and 135 deletions.
14 changes: 4 additions & 10 deletions cc.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,7 @@ extern void map_clear();

extern noreturn void error(char *format, ...);

extern char peek_char();
extern char get_char();
extern void expect_char(char c);
extern bool read_char(char c);
extern char *read_source(char *file);

typedef enum token_type {
tVOID,
Expand Down Expand Up @@ -107,6 +104,7 @@ typedef enum token_type {
tSUB_ASSIGN,
tMUL_ASSIGN,
tCOMMA,
tHASH,
tEND
} TokenType;

Expand All @@ -117,11 +115,7 @@ typedef struct token {
char *identifier;
} Token;

extern Token *peek_token();
extern Token *get_token();
extern Token *expect_token(TokenType type);
extern Token *optional_token(TokenType type);
extern bool read_token(TokenType type);
extern Vector *lexical_analyze(char *source_buffer);

typedef enum type_type {
VOID,
Expand Down Expand Up @@ -260,7 +254,7 @@ typedef struct node {
} Node;

extern Node *node_new();
extern Node *parse();
extern Node *parse(Vector *token_vector);

extern void analyze(Node *node);

Expand Down
135 changes: 35 additions & 100 deletions lex.c
Original file line number Diff line number Diff line change
@@ -1,72 +1,30 @@
#include "cc.h"

char *token_type_name[] = {
"tVOID",
"tBOOL",
"tCHAR",
"tINT",
"tSTRUCT",
"tENUM",
"tTYPEDEF",
"tEXTERN",
"tNORETURN",
"tSIZEOF",
"tALIGNOF",
"tIF",
"tELSE",
"tWHILE",
"tDO",
"tFOR",
"tCONTINUE",
"tBREAK",
"tRETURN",
"tIDENTIFIER",
"tINT_CONST",
"tSTRING_LITERAL",
"tLBRACKET",
"tRBRACKET",
"tLPAREN",
"tRPAREN",
"tRBRACE",
"tLBRACE",
"tDOT",
"tARROW",
"tINC",
"tDEC",
"tNOT",
"tLNOT",
"tMUL",
"tDIV",
"tMOD",
"tADD",
"tSUB",
"tLSHIFT",
"tRSHIFT",
"tLT",
"tGT",
"tLTE",
"tGTE",
"tEQ",
"tNEQ",
"tAND",
"tXOR",
"tOR",
"tLAND",
"tLOR",
"tQUESTION",
"tCOLON",
"tSEMICOLON",
"tELLIPSIS",
"tASSIGN",
"tADD_ASSIGN",
"tSUB_ASSIGN",
"tMUL_ASSIGN",
"tCOMMA",
"tEND"
};
int buffer_pos;
char *buffer;

bool has_next_token = false;
Token *next_token;
char peek_char() {
return buffer[buffer_pos];
}

char get_char() {
return buffer[buffer_pos++];
}

void expect_char(char c) {
if (peek_char() != c) {
error("'%c' is expected.", c);
}
get_char();
}

bool read_char(char c) {
if (peek_char() == c) {
get_char();
return true;
}
return false;
}

Token *token_new() {
Token *token = (Token *) calloc(1, sizeof(Token));
Expand Down Expand Up @@ -94,7 +52,7 @@ Token *lex() {
get_char();
}

if (peek_char() == EOF) {
if (peek_char() == '\0') {
Token *token = token_new();
token->type = tEND;
return token;
Expand Down Expand Up @@ -281,45 +239,22 @@ Token *lex() {
token->type = tDOT;
}
} else {
error("unexpected character.");
error("unexpected character. %d");
}

return token;
}

Token *peek_token() {
if (has_next_token) {
return next_token;
}
has_next_token = true;
return next_token = lex();
}

Token *get_token() {
if (has_next_token) {
has_next_token = false;
return next_token;
}
return lex();
}
Vector *lexical_analyze(char *source_buffer) {
buffer_pos = 0;
buffer = source_buffer;

Token *expect_token(TokenType type) {
Token *token = get_token();
if (token->type != type) {
error("%s is expected.", token_type_name[type]);
Vector *tokens = vector_new();
while (1) {
Token *token = lex();
vector_push(tokens, token);
if (token->type == tEND) break;
}
return token;
}

Token *optional_token(TokenType type) {
if (peek_token()->type == type) {
return get_token();
}
return NULL;
}

bool read_token(TokenType type) {
bool equal = peek_token()->type == type;
if (equal) get_token();
return equal;
return tokens;
}
10 changes: 9 additions & 1 deletion main.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
#include "cc.h"

int main(int argc, char **argv) {
Node *node = parse();
if (argc != 2) {
printf("[usage] ./cc filename\n");
return 0;
}

char *file = argv[1];
char *src = read_source(file);
Vector *tokens = lexical_analyze(src);
Node *node = parse(tokens);
analyze(node);
gen(node);

Expand Down
102 changes: 101 additions & 1 deletion parse.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,104 @@
#include "cc.h"

char *token_type_name[] = {
"tVOID",
"tBOOL",
"tCHAR",
"tINT",
"tSTRUCT",
"tENUM",
"tTYPEDEF",
"tEXTERN",
"tNORETURN",
"tSIZEOF",
"tALIGNOF",
"tIF",
"tELSE",
"tWHILE",
"tDO",
"tFOR",
"tCONTINUE",
"tBREAK",
"tRETURN",
"tIDENTIFIER",
"tINT_CONST",
"tSTRING_LITERAL",
"tLBRACKET",
"tRBRACKET",
"tLPAREN",
"tRPAREN",
"tRBRACE",
"tLBRACE",
"tDOT",
"tARROW",
"tINC",
"tDEC",
"tNOT",
"tLNOT",
"tMUL",
"tDIV",
"tMOD",
"tADD",
"tSUB",
"tLSHIFT",
"tRSHIFT",
"tLT",
"tGT",
"tLTE",
"tGTE",
"tEQ",
"tNEQ",
"tAND",
"tXOR",
"tOR",
"tLAND",
"tLOR",
"tQUESTION",
"tCOLON",
"tSEMICOLON",
"tELLIPSIS",
"tASSIGN",
"tADD_ASSIGN",
"tSUB_ASSIGN",
"tMUL_ASSIGN",
"tCOMMA",
"tHASH",
"tEND"
};

int tokens_pos;
Vector *tokens;
Map *tags, *typedef_names, *enum_constants;

Token *peek_token() {
return tokens->array[tokens_pos];
}

Token *get_token() {
return tokens->array[tokens_pos++];
}

Token *expect_token(TokenType type) {
Token *token = get_token();
if (token->type != type) {
error("%s is expected.", token_type_name[type]);
}
return token;
}

Token *optional_token(TokenType type) {
if (peek_token()->type == type) {
return get_token();
}
return NULL;
}

bool read_token(TokenType type) {
bool equal = peek_token()->type == type;
if (equal) get_token();
return equal;
}

Symbol *symbol_new() {
Symbol *symbol = (Symbol *) calloc(1, sizeof(Symbol));
return symbol;
Expand Down Expand Up @@ -883,7 +980,10 @@ Node *translate_unit() {
return node;
}

Node *parse() {
Node *parse(Vector *token_vector) {
tokens_pos = 0;
tokens = token_vector;

tags = map_new();
typedef_names = map_new();
enum_constants = map_new();
Expand Down
30 changes: 9 additions & 21 deletions scan.c
Original file line number Diff line number Diff line change
@@ -1,26 +1,14 @@
#include "cc.h"

char peek_char() {
char c = fgetc(stdin);
ungetc(c, stdin);
return c;
}

char get_char() {
return fgetc(stdin);
}

void expect_char(char c) {
if (peek_char() != c) {
error("'%c' is expected.", c);
char *read_source(char *file) {
FILE *fp = fopen(file, "r");

String *src = string_new();
while(1) {
char c = fgetc(fp);
if (c == EOF) break;
string_push(src, c);
}
get_char();
}

bool read_char(char c) {
if (peek_char() == c) {
get_char();
return true;
}
return false;
return src->buffer;
}
6 changes: 4 additions & 2 deletions tests/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ failed() {

compile() {
prog=$1
echo "$prog" | $target > tmp/out.s || failed "failed to compile \"$prog\"."
echo "$prog" > tmp/out.c
$target tmp/out.c > tmp/out.s || failed "failed to compile \"$prog\"."
gcc -no-pie tmp/out.s tmp/func_call_stub.o -o tmp/out || failed "failed to link \"$prog\" and stubs."
}

Expand All @@ -33,7 +34,8 @@ test_stdout() {
test_error() {
prog=$1
expect="error: $2"
echo "$prog" | $target > /dev/null 2> tmp/stderr.txt && failed "compilation of \"$prog\" was unexpectedly succeeded."
echo "$prog" > tmp/out.c
$target tmp/out.c > /dev/null 2> tmp/stderr.txt && failed "compilation of \"$prog\" was unexpectedly succeeded."
echo "$expect" | diff - tmp/stderr.txt || failed "error message of \"$prog\" should be \"$expect\"."
}

Expand Down

0 comments on commit 2c6f155

Please sign in to comment.