BrainF.h revision 7a61d701c0870642e075e90b6a1ad03a8ac9bc67
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
18bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner#include "llvm/Module.h"
1989f6d88db334ba088672ae0753deb7d7b7509bacDuncan Sands#include "llvm/Support/IRBuilder.h"
20bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner
21bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattnerusing namespace llvm;
22bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner
23bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner/// This class provides a parser for the BrainF language.
24bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner/// The class itself is made to store values during
25bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner/// parsing so they don't have to be passed around
26bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner/// as much.
27bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattnerclass BrainF {
28bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner  public:
29bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    /// Options for how BrainF should compile
30bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    enum CompileFlags {
31bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner      flag_off         = 0,
32bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner      flag_arraybounds = 1
33bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    };
34bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner
35bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    /// This is the main method.  It parses BrainF from in1
36bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    /// and returns the module with a function
37bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    /// void brainf()
38bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    /// containing the resulting code.
39bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    /// On error, it calls abort.
40bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    /// The caller must delete the returned module.
41bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    Module *parse(std::istream *in1, int mem, CompileFlags cf);
42bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner
43bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner  protected:
44bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    /// The different symbols in the BrainF language
45bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    enum Symbol {
46bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner      SYM_NONE,
47bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner      SYM_READ,
48bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner      SYM_WRITE,
49bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner      SYM_MOVE,
50bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner      SYM_CHANGE,
51bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner      SYM_LOOP,
52bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner      SYM_ENDLOOP,
53bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner      SYM_EOF
54bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    };
55bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner
56bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    /// Names of the different parts of the language.
57bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    /// Tape is used for reading and writing the tape.
58bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    /// headreg is used for the position of the head.
59bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    /// label is used for the labels for the BasicBlocks.
60bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    /// testreg is used for testing the loop exit condition.
61bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    static const char *tapereg;
62bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    static const char *headreg;
63bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    static const char *label;
64bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    static const char *testreg;
65bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner
66bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    /// Put the brainf function preamble and other fixed pieces of code
67bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    void header();
68bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner
69bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    /// The main loop for parsing.  It calls itself recursively
70bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    /// to handle the depth of nesting of "[]".
71bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    void readloop(PHINode *phi, BasicBlock *oldbb, BasicBlock *testbb);
72bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner
73bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    /// Constants during parsing
74bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    int memtotal;
75bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    CompileFlags comflag;
76bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    std::istream *in;
77bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    Module *module;
78bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    Function *brainf_func;
79bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    Function *getchar_func;
80bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    Function *putchar_func;
81bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    Value *ptr_arr;
82bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    Value *ptr_arrmax;
83bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    BasicBlock *endbb;
84bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    BasicBlock *aberrorbb;
85bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner
86bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    /// Variables
877a61d701c0870642e075e90b6a1ad03a8ac9bc67Eric Christopher    IRBuilder<> *builder;
88bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner    Value *curhead;
89bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner};
90bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner
91bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner#endif
92