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