xref: /openbsd/gnu/llvm/llvm/examples/BrainF/BrainF.h (revision 09467b48)
1 //===-- BrainF.h - BrainF compiler class ------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This class stores the data for the BrainF compiler so it doesn't have
10 // to pass all of it around.  The main method is parse.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef BRAINF_H
15 #define BRAINF_H
16 
17 #include "llvm/IR/IRBuilder.h"
18 #include "llvm/IR/LLVMContext.h"
19 #include "llvm/IR/Module.h"
20 #include <istream>
21 
22 using namespace llvm;
23 
24 /// This class provides a parser for the BrainF language.
25 /// The class itself is made to store values during
26 /// parsing so they don't have to be passed around
27 /// as much.
28 class BrainF {
29   public:
30     /// Options for how BrainF should compile
31     enum CompileFlags {
32       flag_off         = 0,
33       flag_arraybounds = 1
34     };
35 
36     /// This is the main method.  It parses BrainF from in1
37     /// and returns the module with a function
38     /// void brainf()
39     /// containing the resulting code.
40     /// On error, it calls abort.
41     /// The caller must delete the returned module.
42     Module *parse(std::istream *in1, int mem, CompileFlags cf,
43                   LLVMContext& C);
44 
45   protected:
46     /// The different symbols in the BrainF language
47     enum Symbol {
48       SYM_NONE,
49       SYM_READ,
50       SYM_WRITE,
51       SYM_MOVE,
52       SYM_CHANGE,
53       SYM_LOOP,
54       SYM_ENDLOOP,
55       SYM_EOF
56     };
57 
58     /// Names of the different parts of the language.
59     /// Tape is used for reading and writing the tape.
60     /// headreg is used for the position of the head.
61     /// label is used for the labels for the BasicBlocks.
62     /// testreg is used for testing the loop exit condition.
63     static const char *tapereg;
64     static const char *headreg;
65     static const char *label;
66     static const char *testreg;
67 
68     /// Put the brainf function preamble and other fixed pieces of code
69     void header(LLVMContext& C);
70 
71     /// The main loop for parsing.  It calls itself recursively
72     /// to handle the depth of nesting of "[]".
73     void readloop(PHINode *phi, BasicBlock *oldbb,
74                   BasicBlock *testbb, LLVMContext &Context);
75 
76     /// Constants during parsing
77     int memtotal;
78     CompileFlags comflag;
79     std::istream *in;
80     Module *module;
81     Function *brainf_func;
82     FunctionCallee getchar_func;
83     FunctionCallee putchar_func;
84     Value *ptr_arr;
85     Value *ptr_arrmax;
86     BasicBlock *endbb;
87     BasicBlock *aberrorbb;
88 
89     /// Variables
90     IRBuilder<> *builder;
91     Value *curhead;
92 };
93 
94 #endif // BRAINF_H
95