Skip to content

Commit cf6ce84

Browse files
author
Alex Muscar
committed
Refactored types
1 parent 91178ea commit cf6ce84

File tree

4 files changed

+84
-35
lines changed

4 files changed

+84
-35
lines changed

Makefile

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
1-
CC=clang++
1+
CC=clang++-3.7
22
CXXFLAGS=-std=c++1y -Wall
3-
LDFLAGS=$(shell /usr/local/opt/llvm/bin/llvm-config --cppflags --ldflags --libs core native bitwriter support --system-libs)
3+
CXXFLAGS+=$(shell llvm-config-3.7 --cppflags)
4+
LDFLAGS=$(shell llvm-config-3.7 --ldflags --libs core native bitwriter support --system-libs)
45
TARGET=klc
56

67
VALGRIND=valgrind
78
VALGRINDFLAGS=--leak-check=full --show-leak-kinds=all
89

910
all:
10-
$(CC) $(CXXFLAGS) $(LDFLAGS) -O2 klc.cpp -o $(TARGET)
11+
$(CC) $(CXXFLAGS) -O2 klc.cpp -o $(TARGET) $(LDFLAGS)
1112

1213
debug:
13-
$(CC) $(CXXFLAGS) $(LDFLAGS) -g -UNDEBUG klc.cpp -o $(TARGET)
14+
$(CC) $(CXXFLAGS) -g -UNDEBUG klc.cpp -o $(TARGET) $(LDFLAGS)
1415

1516
memcheck:
1617
$(VALGRIND) $(VALGRINDFLAGS) ./$(TARGET) $(SOURCE)

examples/ex1.kl

+9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1+
extern def version() -> *int8
12
extern def println() -> int32
23
extern def print_int32(n: int32) -> int32
4+
extern def print_string(s: *int8) -> int32
5+
6+
struct String:
7+
c_str: *int8
8+
len: int64
39

410
struct Point:
511
x: int32
@@ -29,4 +35,7 @@ def main() -> int32:
2935
println()
3036
print_point(p2)
3137
println()
38+
v = version()
39+
print_string(v)
40+
println()
3241
0

klc.cpp

+55-31
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <memory>
55
#include <exception>
66
#include <vector>
7+
#include <iterator>
78
#include <map>
89
#include <algorithm>
910
#include <cstdlib>
@@ -155,12 +156,18 @@ namespace kaleidoscope
155156

156157
// Types
157158

158-
llvm::Type *resolve_type(const codegen_ctx &ctx, const std::string &name)
159+
struct type_node
159160
{
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);
161168
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;
164171
}
165172

166173
// AST
@@ -202,7 +209,7 @@ namespace kaleidoscope
202209

203210
llvm::Type *type(codegen_ctx &ctx)
204211
{
205-
return resolve_type(ctx, "int32");
212+
return resolve_type(ctx, {"int32", false});
206213
}
207214

208215
llvm::Value *codegen(codegen_ctx &ctx)
@@ -232,6 +239,7 @@ namespace kaleidoscope
232239

233240
llvm::Value *codegen(codegen_ctx &ctx)
234241
{
242+
std::cout << "codegen " << name_ << std::endl;
235243
symbol sym;
236244
ctx.symtab_.lookup(name_, sym);
237245
return sym.value();
@@ -336,7 +344,7 @@ namespace kaleidoscope
336344

337345
llvm::Type *type(codegen_ctx &ctx)
338346
{
339-
return resolve_type(ctx, "int32");
347+
return resolve_type(ctx, {"int32", false});
340348
}
341349

342350
llvm::Value *codegen(codegen_ctx &ctx)
@@ -424,28 +432,28 @@ namespace kaleidoscope
424432
}
425433
};
426434

427-
class def_node
435+
class decl_node
428436
{
429437
protected:
430438
llvm::Type *type_;
431439

432440
public:
433-
virtual ~def_node() { }
441+
virtual ~decl_node() { }
434442

435443
virtual llvm::Type *type(codegen_ctx &ctx) = 0;
436444

437445
// XXX This is too restrictive, e.g. type defs don't return Function *
438446
virtual llvm::Function *codegen(codegen_ctx &ctx) = 0;
439447
};
440448

441-
class struct_node : public def_node
449+
class struct_node : public decl_node
442450
{
443451
std::string name_;
444-
std::vector<std::pair<std::string, std::string>> fields_;
452+
std::vector<std::pair<std::string, type_node>> fields_;
445453

446454
llvm::Function *ctor_fun_;
447455
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)
449457
: name_(name), fields_(fields)
450458
{ }
451459

@@ -513,14 +521,14 @@ namespace kaleidoscope
513521
}
514522
};
515523

516-
class prototype_node : public def_node
524+
class prototype_node : public decl_node
517525
{
518526
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_;
521529

522530
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)
524532
: name_(name), params_(params), ty_annot_(ty_annot)
525533
{ }
526534

@@ -577,7 +585,7 @@ namespace kaleidoscope
577585
}
578586
};
579587

580-
class function_node : public def_node
588+
class function_node : public decl_node
581589
{
582590
std::unique_ptr<prototype_node> proto_;
583591
std::unique_ptr<expr_node> body_;
@@ -618,9 +626,9 @@ namespace kaleidoscope
618626

619627
class module_node
620628
{
621-
std::vector<std::unique_ptr<def_node>> defs_;
629+
std::vector<std::unique_ptr<decl_node>> defs_;
622630
public:
623-
void add_def(std::unique_ptr<def_node> def)
631+
void add_def(std::unique_ptr<decl_node> def)
624632
{
625633
defs_.push_back(std::move(def));
626634
}
@@ -653,6 +661,7 @@ namespace kaleidoscope
653661
kw_extern,
654662
rarr,
655663
eq,
664+
star,
656665
lpar,
657666
rpar,
658667
period,
@@ -686,6 +695,8 @@ namespace kaleidoscope
686695
return "->";
687696
case token::eq:
688697
return "=";
698+
case token::star:
699+
return "*";
689700
case token::lpar:
690701
return "(";
691702
case token::rpar:
@@ -779,6 +790,9 @@ namespace kaleidoscope
779790
} else if (in_.peek() == '=') {
780791
tok = token::eq;
781792
in_.get();
793+
} else if (in_.peek() == '*') {
794+
tok = token::star;
795+
in_.get();
782796
} else if (in_.peek() == '(') {
783797
tok = token::lpar;
784798
in_.get();
@@ -852,7 +866,7 @@ namespace kaleidoscope
852866
}
853867

854868
// def = fun_proto | fun_decl
855-
std::unique_ptr<def_node> parse_def()
869+
std::unique_ptr<decl_node> parse_def()
856870
{
857871
switch (curr_tok_) {
858872
case token::kw_struct:
@@ -875,7 +889,7 @@ namespace kaleidoscope
875889

876890
expect(token::colon);
877891

878-
std::vector<std::pair<std::string, std::string>> fields;
892+
std::vector<std::pair<std::string, type_node>> fields;
879893

880894
expect(token::indent);
881895

@@ -914,7 +928,7 @@ namespace kaleidoscope
914928

915929
expect(token::lpar);
916930

917-
std::vector<std::pair<std::string, std::string>> params;
931+
std::vector<std::pair<std::string, type_node>> params;
918932

919933
if (curr_tok_ != token::rpar) {
920934
params.push_back(parse_annotated_ident());
@@ -926,8 +940,7 @@ namespace kaleidoscope
926940

927941
expect(token::rpar);
928942
expect(token::rarr);
929-
auto ty_annot = scanner_.lexeme();
930-
expect(token::ident);
943+
auto ty_annot = parse_type_annot();
931944

932945
if (!is_extern)
933946
expect(token::colon);
@@ -936,15 +949,26 @@ namespace kaleidoscope
936949
}
937950

938951
// annotated_ident = ident ":" ident
939-
std::pair<std::string, std::string> parse_annotated_ident()
952+
std::pair<std::string, type_node> parse_annotated_ident()
940953
{
941954
auto name = scanner_.lexeme();
942955
expect(token::ident);
943956
expect(token::colon);
944-
auto ty_annot = scanner_.lexeme();
945-
expect(token::ident);
957+
auto ty_annot = parse_type_annot();
946958
return std::make_pair(name, ty_annot);
947959
}
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+
}
948972

949973
// expr_seq = expr { ";" expr }
950974
std::unique_ptr<expr_node> parse_expr_seq()
@@ -1056,12 +1080,12 @@ namespace kaleidoscope
10561080

10571081
std::string basename(const std::string& pathname)
10581082
{
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));
10601084
}
10611085

10621086
std::string remove_extension(const std::string& filename)
10631087
{
1064-
auto pivot = std::find(rbegin(filename), rend(filename), '.');
1088+
auto pivot = std::find(filename.rbegin(), filename.rend(), '.');
10651089
return pivot == filename.rend() ? filename : std::string(begin(filename), pivot.base() - 1);
10661090
}
10671091

@@ -1098,9 +1122,9 @@ int main(int argc, const char *argv[])
10981122
llvm::WriteBitcodeToFile(&ctx.module_, os);
10991123
os.close();
11001124

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());
11041128

11051129
return 0;
11061130
}

lib.c

+15
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
11
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <string.h>
4+
5+
char *version()
6+
{
7+
char *s = (char *) malloc(5);
8+
strcpy(s, "v0.1");
9+
return s;
10+
}
211

312
int println()
413
{
@@ -15,3 +24,9 @@ int print_int32(int n)
1524
{
1625
return printf("%d", n);
1726
}
27+
28+
int print_string(char *s)
29+
{
30+
return printf("%s", s);
31+
}
32+

0 commit comments

Comments
 (0)