@@ -266,16 +266,19 @@ AST *Parser::make_return() {
266
266
llvm::Type *Parser::make_struct_declaration () {
267
267
if (!token.skip (" struct" )) return nullptr ;
268
268
std::string name;
269
+
269
270
if (token.get ().type == TOK_TYPE_IDENT)
270
271
name = token.next ().val ;
272
+
271
273
if (name.empty ()) [](std::string &str) { // if name is empty, generate random name
272
274
int len = 8 ; while (len--)
273
275
str += (rand () % 26 ) + 65 ;
274
276
}(name);
275
277
276
278
llvm::StructType *new_struct = nullptr ;
277
279
auto t_strct = this ->struct_list .get (" struct." + name);
278
- if (!t_strct) {
280
+ if (!t_strct) { // if not declared
281
+ // create empty struct
279
282
new_struct = llvm::StructType::create (context, " struct." + name);
280
283
this ->struct_list .add (" struct." + name, std::vector<std::string>(), new_struct);
281
284
t_strct = this ->struct_list .get (" struct." + name);
@@ -310,7 +313,6 @@ llvm::Type *Parser::make_struct_declaration() {
310
313
}
311
314
312
315
llvm::Type *Parser::make_enum_declaration () {
313
- if (!token.skip (" enum" )) return nullptr ;
314
316
std::string name;
315
317
if (token.get ().type == TOK_TYPE_IDENT)
316
318
name = token.next ().val ;
@@ -405,6 +407,7 @@ bool Parser::is_type() {
405
407
cur == " int" ||
406
408
cur == " char" ||
407
409
cur == " short" ||
410
+ cur == " long" ||
408
411
cur == " double" ||
409
412
cur == " struct" ||
410
413
cur == " enum" ||
@@ -417,27 +420,58 @@ bool Parser::is_type() {
417
420
return false ;
418
421
}
419
422
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
-
429
423
llvm::Type *Parser::read_type_spec () {
430
424
int d;
431
425
return read_type_spec (d);
432
426
}
433
427
434
428
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
+
441
475
return nullptr ;
442
476
}
443
477
@@ -458,54 +492,11 @@ llvm::Type *Parser::read_struct_union_type() {
458
492
}
459
493
460
494
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 { ... }
463
497
return make_enum_declaration ();
464
- token.skip (" enum" );
465
498
if (token.get ().type == TOK_TYPE_IDENT)
466
499
token.skip ();
467
500
return builder.getInt32Ty ();
468
501
}
469
502
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
- }
0 commit comments