Skip to content

Commit 0b94c43

Browse files
rewritten read_type_spec, and deleted some unnecessary functions
1 parent c7ff2b3 commit 0b94c43

File tree

2 files changed

+53
-67
lines changed

2 files changed

+53
-67
lines changed

src/parse.cpp

Lines changed: 53 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -266,16 +266,19 @@ AST *Parser::make_return() {
266266
llvm::Type *Parser::make_struct_declaration() {
267267
if(!token.skip("struct")) return nullptr;
268268
std::string name;
269+
269270
if(token.get().type == TOK_TYPE_IDENT)
270271
name = token.next().val;
272+
271273
if(name.empty()) [](std::string &str) { // if name is empty, generate random name
272274
int len = 8; while(len--)
273275
str += (rand() % 26) + 65;
274276
}(name);
275277

276278
llvm::StructType *new_struct = nullptr;
277279
auto t_strct = this->struct_list.get("struct." + name);
278-
if(!t_strct) {
280+
if(!t_strct) { // if not declared
281+
// create empty struct
279282
new_struct = llvm::StructType::create(context, "struct." + name);
280283
this->struct_list.add("struct." + name, std::vector<std::string>(), new_struct);
281284
t_strct = this->struct_list.get("struct." + name);
@@ -310,7 +313,6 @@ llvm::Type *Parser::make_struct_declaration() {
310313
}
311314

312315
llvm::Type *Parser::make_enum_declaration() {
313-
if(!token.skip("enum")) return nullptr;
314316
std::string name;
315317
if(token.get().type == TOK_TYPE_IDENT)
316318
name = token.next().val;
@@ -405,6 +407,7 @@ bool Parser::is_type() {
405407
cur == "int" ||
406408
cur == "char" ||
407409
cur == "short" ||
410+
cur == "long" ||
408411
cur == "double" ||
409412
cur == "struct" ||
410413
cur == "enum" ||
@@ -417,27 +420,58 @@ bool Parser::is_type() {
417420
return false;
418421
}
419422

420-
llvm::Type *Parser::read_type_declarator() {
421-
if(!is_type()) return nullptr;
422-
llvm::Type *type = read_type_spec();
423-
if(type == nullptr) return nullptr;
424-
for(int i=skip_pointer(); i > 0; i--)
425-
type = type->getPointerTo(); //new llvm::Type(TY_PTR, type);
426-
return type;
427-
}
428-
429423
llvm::Type *Parser::read_type_spec() {
430424
int d;
431425
return read_type_spec(d);
432426
}
433427

434428
llvm::Type *Parser::read_type_spec(int &stg) {
435-
if(token.skip("extern")) stg = STG_EXTERN;
436-
else if(token.skip("static")) stg = STG_STATIC;
437-
if(token.is("struct") || token.is("union")) return read_struct_union_type();
438-
else if(token.is("enum")) return read_enum_type();
439-
else if(token.get().type == TOK_TYPE_IDENT) return read_primitive_type();
440-
else if(token.skip("...")) return nullptr; // null is variable argument
429+
enum { tsigned, tunsigned } sign = tsigned;
430+
enum { tvoid, tchar, tint, tdouble } type = tint;
431+
enum { tshort, tdefault, tlong, tllong } size = tdefault;
432+
433+
for(;;) {
434+
if(typedef_map.count(token.get().val)) {
435+
std::string t = token.next().val; return typedef_map[t];
436+
}
437+
if(token.skip("extern")) stg = STG_EXTERN;
438+
else if(token.skip("static")) stg = STG_STATIC;
439+
440+
// TODO: wanna use skip(), not is().
441+
else if(token.is("struct") ||
442+
token.is("union")) return read_struct_union_type();
443+
else if(token.skip("enum")) return read_enum_type();
444+
445+
else if(token.skip("...")) return nullptr;
446+
447+
else if(token.skip("signed")) sign = tsigned;
448+
else if(token.skip("unsigned")) sign = tunsigned;
449+
450+
else if(token.skip("void")) type = tvoid;
451+
else if(token.skip("int")) type = tint;
452+
else if(token.skip("char")) type = tchar;
453+
else if(token.skip("double")) type = tdouble;
454+
else if(token.skip("short")) size = tshort;
455+
else if(token.skip("long")) {
456+
if(size == tlong) size = tllong;
457+
else size = tlong;
458+
} else break;
459+
}
460+
461+
switch(type) {
462+
case tvoid: return builder.getVoidTy();
463+
case tchar: return builder.getInt8Ty();
464+
case tdouble: return builder.getDoubleTy();
465+
default: break;
466+
}
467+
468+
switch(size) {
469+
case tshort: return builder.getInt16Ty();
470+
case tlong: return builder.getInt32Ty();
471+
case tllong: return builder.getInt64Ty();
472+
default: return builder.getInt32Ty();
473+
}
474+
441475
return nullptr;
442476
}
443477

@@ -458,54 +492,11 @@ llvm::Type *Parser::read_struct_union_type() {
458492
}
459493

460494
llvm::Type *Parser::read_enum_type() {
461-
if( token.get(1).val == "{" || // struct { ... }
462-
token.get(2).val == "{") // struct NAME { ... }
495+
if( token.get().val == "{" || // enum { ... }
496+
token.get(1).val == "{") // enum NAME { ... }
463497
return make_enum_declaration();
464-
token.skip("enum");
465498
if(token.get().type == TOK_TYPE_IDENT)
466499
token.skip();
467500
return builder.getInt32Ty();
468501
}
469502

470-
llvm::Type *Parser::read_primitive_type() {
471-
std::string name = token.next().val;
472-
if(name == "signed" || name == "unsigned")
473-
name = token.next().val;
474-
return to_llvm_type(name);
475-
}
476-
477-
int Parser::skip_pointer() {
478-
int count = 0;
479-
while(token.get().type == TOK_TYPE_SYMBOL && token.get().val == "*")
480-
count++, token.skip();
481-
return count;
482-
}
483-
484-
std::vector<int> Parser::skip_array() {
485-
std::vector<int> ary;
486-
while(token.skip("[")) {
487-
int ary_size = -1;
488-
if(token.get().type == TOK_TYPE_NUMBER)
489-
ary_size = atoi(token.next().val.c_str());
490-
token.expect_skip("]");
491-
ary.push_back(ary_size);
492-
}
493-
return ary;
494-
}
495-
496-
llvm::Type *Parser::to_llvm_type(std::string ty) {
497-
if(ty == "int") {
498-
return builder.getInt32Ty();
499-
} else if(ty == "short") {
500-
return builder.getInt16Ty();
501-
} else if(ty == "void") {
502-
return builder.getVoidTy();
503-
} else if(ty == "char") {
504-
return builder.getInt8Ty();
505-
} else if(ty == "double") {
506-
return builder.getDoubleTy();
507-
} else { // typedef
508-
if(!typedef_map.count(ty)) return nullptr;
509-
return typedef_map[ty];
510-
}
511-
}

src/parse.hpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,10 @@ class Parser {
5050
AST *make_for();
5151
AST *make_return();
5252

53-
llvm::Type *to_llvm_type(std::string);
5453
llvm::Type *read_type_spec();
5554
llvm::Type *read_type_spec(int &);
56-
llvm::Type *read_primitive_type();
5755
llvm::Type *read_struct_union_type();
5856
llvm::Type *read_enum_type();
59-
llvm::Type *read_type_declarator();
60-
int skip_pointer();
61-
std::vector<int> skip_array(); // .size() = number of [], elem = ary size
6257

6358
std::map<std::string, int> op_prec;
6459
int get_op_prec(std::string);

0 commit comments

Comments
 (0)