llvm.org GIT mirror llvm / 241c3da
Remove BFtoLLVM. It was old, and a poor example because it didn't use best practices for making a LLVM frontend in C++. Maybe someday it will be rewritten.. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37858 91177308-0d34-0410-b5e6-96231b3b80d8 Owen Anderson 12 years ago
6 changed file(s) with 1 addition(s) and 274 deletion(s). Raw diff Collapse all Expand all
+0
-209
examples/BFtoLLVM/BFtoLLVM.cpp less more
None //===-- BFtoLLVM.cpp - BF language Front End for LLVM ---------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file was developed by the LLVM research group and is distributed under
5 // the University of Illinois Open Source License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This is a simple front end for the BF language. It is compatible with the
10 // language as described in "The BrainF*** Language Specification (01 January
11 // 2002)", which is available from http://esoteric.sange.fi/ENSI . It does not
12 // implement the optional keyword # ("Output partial tape state").
13 //
14 //===----------------------------------------------------------------------===//
15
16 #include
17 #include
18 #include
19 #include
20 #include
21 #include
22 #include
23 #include
24
25 void emitDeclarations(std::ofstream &dest) {
26 dest << "; This assembly code brought to you by BFtoLLVM\n"
27 << "\nimplementation\n"
28 << "\n; Declarations\n"
29 << "\ndeclare int %getchar()\n"
30 << "declare int %putchar(int)\n"
31 << "declare void %llvm.memset.i32(sbyte*, ubyte, uint, uint)\n"
32 << "\n";
33 }
34
35 void emitMainFunctionProlog(std::ofstream &dest) {
36 dest << "\n; Main function\n"
37 << "int %main(int %argc, sbyte** %argv) {\n"
38 << "\nentry:\n"
39 << "%arr = alloca sbyte, uint 30000\n"
40 << "call void (sbyte*, ubyte, uint, uint)* %llvm.memset.i32"
41 << "(sbyte* %arr, ubyte 0, uint 30000, uint 1)\n"
42 << "%ptrbox = alloca sbyte*\n"
43 << "store sbyte* %arr, sbyte **%ptrbox\n"
44 << "\n";
45 }
46
47 void emitMainFunctionEpilog(std::ofstream &dest) {
48 dest << "ret int 0\n"
49 << "}\n";
50 }
51
52 std::string gensym (const std::string varName, bool percent = true) {
53 char buf[80];
54 static unsigned int SymbolCounter = 0;
55 sprintf (buf, "%s%s%u", percent ? "%" : "", varName.c_str(), SymbolCounter++);
56 return std::string (buf);
57 }
58
59 void emitArith (std::string op, char delta, std::ofstream &dest) {
60 std::string ptr = gensym (op + "ptr"),
61 val = gensym (op + "val"),
62 result = gensym (op + "result");
63 dest << ptr << " = load sbyte** %ptrbox\n"
64 << val << " = load sbyte* " << ptr << "\n"
65 << result << " = add sbyte " << val << ", " << (int)delta << "\n"
66 << "store sbyte " << result << ", sbyte* " << ptr << "\n";
67 }
68
69 // + becomes ++*p; and - becomes --*p;
70 void emitPlus (std::ofstream &dest, int ct) { emitArith ("plus", +ct, dest); }
71 void emitMinus (std::ofstream &dest, int ct) { emitArith ("minus", -ct, dest); }
72
73 void emitLoadAndCast (std::string ptr, std::string val, std::string cast,
74 std::string type, std::ofstream &dest) {
75 dest << ptr << " = load sbyte** %ptrbox\n"
76 << val << " = load sbyte* " << ptr << "\n"
77 << cast << " = cast sbyte " << val << " to " << type << "\n";
78 }
79
80 // , becomes *p = getchar();
81 void emitComma(std::ofstream &dest, int ct) {
82 assert (ct == 1);
83 std::string ptr = gensym("commaptr"), read = gensym("commaread"),
84 cast = gensym("commacast");
85 dest << ptr << " = load sbyte** %ptrbox\n"
86 << read << " = call int %getchar()\n"
87 << cast << " = cast int " << read << " to sbyte\n"
88 << "store sbyte " << cast << ", sbyte* " << ptr << "\n";
89 }
90
91 // . becomes putchar(*p);
92 void emitDot(std::ofstream &dest, int ct) {
93 assert (ct == 1);
94 std::string ptr = gensym("dotptr"), val = gensym("dotval"),
95 cast = gensym("dotcast");
96 emitLoadAndCast (ptr, val, cast, "int", dest);
97 dest << "call int %putchar(int " << cast << ")\n";
98 }
99
100 void emitPointerArith(std::string opname, int delta, std::ofstream &dest) {
101 std::string ptr = gensym(opname + "ptr"), result = gensym(opname + "result");
102 dest << ptr << " = load sbyte** %ptrbox\n"
103 << result << " = getelementptr sbyte* " << ptr << ", int " << delta
104 << "\n"
105 << "store sbyte* " << result << ", sbyte** %ptrbox\n";
106 }
107
108 // < becomes --p; and > becomes ++p;
109 void emitLT(std::ofstream &dest, int ct) { emitPointerArith ("lt", -ct, dest); }
110 void emitGT(std::ofstream &dest, int ct) { emitPointerArith ("gt", +ct, dest); }
111
112 static std::vector whileStack;
113
114 // [ becomes while (*p) {
115 void emitLeftBracket(std::ofstream &dest, int ct) {
116 assert (ct == 1);
117 std::string whileName = gensym ("While", false);
118 whileStack.push_back (whileName);
119 dest << "br label %testFor" << whileName << "\n"
120 << "\ninside" << whileName << ":\n";
121 }
122
123 // ] becomes }
124 void emitRightBracket(std::ofstream &dest, int ct) {
125 assert (ct == 1);
126 std::string whileName = whileStack.back (),
127 ptr = gensym("bracketptr"),
128 val = gensym("bracketval"),
129 cast = gensym("bracketcast");
130 whileStack.pop_back ();
131 dest << "br label %testFor" << whileName << "\n"
132 << "\ntestFor" << whileName << ":\n";
133 emitLoadAndCast (ptr, val, cast, "bool", dest);
134 dest << "br bool " << cast << ", label %inside" << whileName << ", "
135 << "label %after" << whileName << "\n"
136 << "\nafter" << whileName << ":\n";
137 }
138
139 typedef void (*FuncTy)(std::ofstream &, int);
140 static FuncTy table[256];
141 static bool multi[256];
142
143 void consume (int ch, int repeatCount, std::ofstream &dest) {
144 FuncTy func = table[ch];
145 if (!func)
146 return;
147 else if (multi[ch])
148 func (dest, repeatCount);
149 else
150 for (int i = 0; i < repeatCount; ++i)
151 func (dest, 1);
152 }
153
154 void initializeTable() {
155 memset (table, 0, 256);
156 memset (multi, 0, 256);
157 table[(int)'+'] = emitPlus; multi[(int)'+'] = true;
158 table[(int)'-'] = emitMinus; multi[(int)'-'] = true;
159 table[(int)','] = emitComma; multi[(int)','] = false;
160 table[(int)'.'] = emitDot; multi[(int)'.'] = false;
161 table[(int)'<'] = emitLT; multi[(int)'<'] = true;
162 table[(int)'>'] = emitGT; multi[(int)'>'] = true;
163 table[(int)'['] = emitLeftBracket; multi[(int)'['] = false;
164 table[(int)']'] = emitRightBracket; multi[(int)']'] = false;
165 }
166
167 int main (int argc, char **argv) {
168 if (argc != 3) {
169 std::cerr << "usage: " << argv[0] << " input-source output-llvm\n";
170 return 1;
171 }
172
173 char *sourceFileName = argv[1];
174 char *destFileName = argv[2];
175
176 std::ifstream src (sourceFileName);
177 if (!src.good()) {
178 std::cerr << sourceFileName << ": " << strerror(errno) << "\n";
179 return 1;
180 }
181
182 std::ofstream dest (destFileName);
183 if (!dest.good()) {
184 std::cerr << destFileName << ": " << strerror(errno) << "\n";
185 return 1;
186 }
187
188 emitDeclarations(dest);
189 emitMainFunctionProlog(dest);
190
191 initializeTable();
192 char ch, lastCh;
193 src >> lastCh;
194 int repeatCount = 1;
195 for (src >> ch; !src.eof (); src >> ch, ++repeatCount)
196 if (ch != lastCh) {
197 consume (lastCh, repeatCount, dest);
198 lastCh = ch;
199 repeatCount = 0;
200 }
201 consume (lastCh, repeatCount, dest);
202
203 emitMainFunctionEpilog(dest);
204
205 src.close();
206 dest.close();
207 return 0;
208 }
+0
-13
examples/BFtoLLVM/Makefile less more
None ##===- examples/BFtoLLVM/Makefile --------------------------*- Makefile -*-===##
1 #
2 # The LLVM Compiler Infrastructure
3 #
4 # This file was developed by the LLVM research group and is distributed under
5 # the University of Illinois Open Source License. See LICENSE.TXT for details.
6 #
7 ##===----------------------------------------------------------------------===##
8
9 LEVEL = ../..
10 TOOLNAME = BFtoLLVM
11 EXAMPLE_TOOL = 1
12 include $(LEVEL)/Makefile.common
+0
-45
examples/BFtoLLVM/tests/Makefile less more
None ##===- examples/BFtoLLVM/tests/Makefile --------------------*- Makefile -*-===##
1 #
2 # The LLVM Compiler Infrastructure
3 #
4 # This file was developed by the LLVM research group and is distributed under
5 # the University of Illinois Open Source License. See LICENSE.TXT for details.
6 #
7 ##===----------------------------------------------------------------------===##
8
9 # Makefile for bf2llvm tests.
10
11 LEVEL = ../../..
12 BFTOLLVM = $(LLVMTOOLCURRENT)/BFtoLLVM
13
14 include $(LEVEL)/Makefile.common
15
16 all:: check
17
18 clean::
19 rm -rf Output
20
21 .SUFFIXES: .ll .gccas.bc .llvm .cbe.c .cbe
22
23 Output/%.ll: %.b $(BFTOLLVM) Output/.dir
24 $(BFTOLLVM) $< $@
25
26 Output/%.gccas.bc: Output/%.ll Output/.dir
27 $(LGCCAS) $< -o $@
28
29 Output/%.llvm Output/%.llvm.bc: Output/%.gccas.bc Output/.dir
30 $(LGCCLD) $< -lc -lcrtend -o Output/$*.llvm
31
32 Output/%.cbe.c: Output/%.llvm.bc Output/.dir
33 $(LLC) -march=c -f -o=$@ $<
34
35 Output/%.cbe: Output/%.cbe.c Output/.dir
36 $(CC) -O2 $< -o $@
37
38 check: Output/hello.cbe hello.expected-out
39 @echo "Running test"
40 Output/hello.cbe > Output/hello.out-cbe
41 @echo "Checking result"
42 diff Output/hello.out-cbe hello.expected-out
43 @echo "Test passed"
44
+0
-5
examples/BFtoLLVM/tests/hello.b less more
None Hello World program
1 >+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.[-]>++++++++[<++++>-]
2 <.#>+++++++++++[<+++++>-]<.>++++++++[<+++>-]<.+++.------.--------.[-]>++++++++[
3 <++++>-]<+.[-]++++++++++.
4
+0
-1
examples/BFtoLLVM/tests/hello.expected-out less more
None Hello World!
99
1010 include $(LEVEL)/Makefile.config
1111
12 PARALLEL_DIRS:= Fibonacci HowToUseJIT ModuleMaker BFtoLLVM
12 PARALLEL_DIRS:= Fibonacci HowToUseJIT ModuleMaker
1313
1414 ifeq ($(HAVE_PTHREAD),1)
1515 PARALLEL_DIRS += ParallelJIT