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