4
4
#include < memory>
5
5
#include < exception>
6
6
#include < vector>
7
+ #include < iterator>
7
8
#include < map>
8
9
#include < algorithm>
9
10
#include < cstdlib>
@@ -155,12 +156,18 @@ namespace kaleidoscope
155
156
156
157
// Types
157
158
158
- llvm::Type * resolve_type ( const codegen_ctx &ctx, const std::string &name)
159
+ struct type_node
159
160
{
160
- auto it = ctx.tenv_ .find (name);
161
+ const std::string name;
162
+ const bool is_pointer;
163
+ };
164
+
165
+ llvm::Type *resolve_type (const codegen_ctx &ctx, const type_node &type)
166
+ {
167
+ auto it = ctx.tenv_ .find (type.name );
161
168
if (it == ctx.tenv_ .end ())
162
- throw std::domain_error (" unknown type " + name);
163
- return it->second ;
169
+ throw std::domain_error (" unknown type " + type. name );
170
+ return type. is_pointer ? llvm::PointerType::getUnqual (it-> second ) : it->second ;
164
171
}
165
172
166
173
// AST
@@ -202,7 +209,7 @@ namespace kaleidoscope
202
209
203
210
llvm::Type *type (codegen_ctx &ctx)
204
211
{
205
- return resolve_type (ctx, " int32" );
212
+ return resolve_type (ctx, { " int32" , false } );
206
213
}
207
214
208
215
llvm::Value *codegen (codegen_ctx &ctx)
@@ -232,6 +239,7 @@ namespace kaleidoscope
232
239
233
240
llvm::Value *codegen (codegen_ctx &ctx)
234
241
{
242
+ std::cout << " codegen " << name_ << std::endl;
235
243
symbol sym;
236
244
ctx.symtab_ .lookup (name_, sym);
237
245
return sym.value ();
@@ -336,7 +344,7 @@ namespace kaleidoscope
336
344
337
345
llvm::Type *type (codegen_ctx &ctx)
338
346
{
339
- return resolve_type (ctx, " int32" );
347
+ return resolve_type (ctx, { " int32" , false } );
340
348
}
341
349
342
350
llvm::Value *codegen (codegen_ctx &ctx)
@@ -424,28 +432,28 @@ namespace kaleidoscope
424
432
}
425
433
};
426
434
427
- class def_node
435
+ class decl_node
428
436
{
429
437
protected:
430
438
llvm::Type *type_;
431
439
432
440
public:
433
- virtual ~def_node () { }
441
+ virtual ~decl_node () { }
434
442
435
443
virtual llvm::Type *type (codegen_ctx &ctx) = 0;
436
444
437
445
// XXX This is too restrictive, e.g. type defs don't return Function *
438
446
virtual llvm::Function *codegen (codegen_ctx &ctx) = 0;
439
447
};
440
448
441
- class struct_node : public def_node
449
+ class struct_node : public decl_node
442
450
{
443
451
std::string name_;
444
- std::vector<std::pair<std::string, std::string >> fields_;
452
+ std::vector<std::pair<std::string, type_node >> fields_;
445
453
446
454
llvm::Function *ctor_fun_;
447
455
public:
448
- struct_node (std::string name, std::vector<std::pair<std::string, std::string >> fields)
456
+ struct_node (std::string name, std::vector<std::pair<std::string, type_node >> fields)
449
457
: name_(name), fields_(fields)
450
458
{ }
451
459
@@ -513,14 +521,14 @@ namespace kaleidoscope
513
521
}
514
522
};
515
523
516
- class prototype_node : public def_node
524
+ class prototype_node : public decl_node
517
525
{
518
526
std::string name_;
519
- std::vector<std::pair<std::string, std::string >> params_;
520
- std::string ty_annot_;
527
+ std::vector<std::pair<std::string, type_node >> params_;
528
+ type_node ty_annot_;
521
529
522
530
public:
523
- prototype_node (std::string name, std::vector<std::pair<std::string, std::string >> params, std::string ty_annot)
531
+ prototype_node (std::string name, std::vector<std::pair<std::string, type_node >> params, type_node ty_annot)
524
532
: name_(name), params_(params), ty_annot_(ty_annot)
525
533
{ }
526
534
@@ -577,7 +585,7 @@ namespace kaleidoscope
577
585
}
578
586
};
579
587
580
- class function_node : public def_node
588
+ class function_node : public decl_node
581
589
{
582
590
std::unique_ptr<prototype_node> proto_;
583
591
std::unique_ptr<expr_node> body_;
@@ -618,9 +626,9 @@ namespace kaleidoscope
618
626
619
627
class module_node
620
628
{
621
- std::vector<std::unique_ptr<def_node >> defs_;
629
+ std::vector<std::unique_ptr<decl_node >> defs_;
622
630
public:
623
- void add_def (std::unique_ptr<def_node > def)
631
+ void add_def (std::unique_ptr<decl_node > def)
624
632
{
625
633
defs_.push_back (std::move (def));
626
634
}
@@ -653,6 +661,7 @@ namespace kaleidoscope
653
661
kw_extern,
654
662
rarr,
655
663
eq,
664
+ star,
656
665
lpar,
657
666
rpar,
658
667
period,
@@ -686,6 +695,8 @@ namespace kaleidoscope
686
695
return " ->" ;
687
696
case token::eq:
688
697
return " =" ;
698
+ case token::star:
699
+ return " *" ;
689
700
case token::lpar:
690
701
return " (" ;
691
702
case token::rpar:
@@ -779,6 +790,9 @@ namespace kaleidoscope
779
790
} else if (in_.peek () == ' =' ) {
780
791
tok = token::eq;
781
792
in_.get ();
793
+ } else if (in_.peek () == ' *' ) {
794
+ tok = token::star;
795
+ in_.get ();
782
796
} else if (in_.peek () == ' (' ) {
783
797
tok = token::lpar;
784
798
in_.get ();
@@ -852,7 +866,7 @@ namespace kaleidoscope
852
866
}
853
867
854
868
// def = fun_proto | fun_decl
855
- std::unique_ptr<def_node > parse_def ()
869
+ std::unique_ptr<decl_node > parse_def ()
856
870
{
857
871
switch (curr_tok_) {
858
872
case token::kw_struct:
@@ -875,7 +889,7 @@ namespace kaleidoscope
875
889
876
890
expect (token::colon);
877
891
878
- std::vector<std::pair<std::string, std::string >> fields;
892
+ std::vector<std::pair<std::string, type_node >> fields;
879
893
880
894
expect (token::indent);
881
895
@@ -914,7 +928,7 @@ namespace kaleidoscope
914
928
915
929
expect (token::lpar);
916
930
917
- std::vector<std::pair<std::string, std::string >> params;
931
+ std::vector<std::pair<std::string, type_node >> params;
918
932
919
933
if (curr_tok_ != token::rpar) {
920
934
params.push_back (parse_annotated_ident ());
@@ -926,8 +940,7 @@ namespace kaleidoscope
926
940
927
941
expect (token::rpar);
928
942
expect (token::rarr);
929
- auto ty_annot = scanner_.lexeme ();
930
- expect (token::ident);
943
+ auto ty_annot = parse_type_annot ();
931
944
932
945
if (!is_extern)
933
946
expect (token::colon);
@@ -936,15 +949,26 @@ namespace kaleidoscope
936
949
}
937
950
938
951
// annotated_ident = ident ":" ident
939
- std::pair<std::string, std::string > parse_annotated_ident ()
952
+ std::pair<std::string, type_node > parse_annotated_ident ()
940
953
{
941
954
auto name = scanner_.lexeme ();
942
955
expect (token::ident);
943
956
expect (token::colon);
944
- auto ty_annot = scanner_.lexeme ();
945
- expect (token::ident);
957
+ auto ty_annot = parse_type_annot ();
946
958
return std::make_pair (name, ty_annot);
947
959
}
960
+
961
+ type_node parse_type_annot ()
962
+ {
963
+ auto is_pointer = false ;
964
+ if (curr_tok_ == token::star) {
965
+ move_next ();
966
+ is_pointer = true ;
967
+ }
968
+ auto ty_name = scanner_.lexeme ();
969
+ expect (token::ident);
970
+ return {ty_name, is_pointer};
971
+ }
948
972
949
973
// expr_seq = expr { ";" expr }
950
974
std::unique_ptr<expr_node> parse_expr_seq ()
@@ -1056,12 +1080,12 @@ namespace kaleidoscope
1056
1080
1057
1081
std::string basename (const std::string& pathname)
1058
1082
{
1059
- return std::string (std::find (rbegin (pathname ), rend (pathname ), ' /' ).base (), end (pathname));
1083
+ return std::string (std::find (pathname. rbegin (), pathname. rend (), ' /' ).base (), end (pathname));
1060
1084
}
1061
1085
1062
1086
std::string remove_extension (const std::string& filename)
1063
1087
{
1064
- auto pivot = std::find (rbegin (filename ), rend (filename ), ' .' );
1088
+ auto pivot = std::find (filename. rbegin (), filename. rend (), ' .' );
1065
1089
return pivot == filename.rend () ? filename : std::string (begin (filename), pivot.base () - 1 );
1066
1090
}
1067
1091
@@ -1098,9 +1122,9 @@ int main(int argc, const char *argv[])
1098
1122
llvm::WriteBitcodeToFile (&ctx.module_ , os);
1099
1123
os.close ();
1100
1124
1101
- system ((" /usr/local/opt/llvm/bin/ llc -filetype=obj " + project_path + bc_file_name + " -o " + project_path + obj_file_name).c_str ());
1102
- system ((" clang -std=c11 -O1 -Wall -Werror -c " + project_path + " lib.c" + " -o " + project_path + " lib.o" ).c_str ());
1103
- system ((" clang " + project_path + " lib.o " + project_path + obj_file_name + " -o " + project_path + exe_file_name).c_str ());
1125
+ system ((" llc-3.7 -filetype=obj " + project_path + bc_file_name + " -o " + project_path + obj_file_name).c_str ());
1126
+ system ((" clang-3.7 -std=c11 -O1 -Wall -Werror -c " + project_path + " lib.c" + " -o " + project_path + " lib.o" ).c_str ());
1127
+ system ((" clang-3.7 " + project_path + " lib.o " + project_path + obj_file_name + " -o " + project_path + exe_file_name).c_str ());
1104
1128
1105
1129
return 0 ;
1106
1130
}
0 commit comments