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