|  | @@ -1,7 +1,7 @@
 | 
	
		
			
				|  |  |  #include "Parser.h"
 | 
	
		
			
				|  |  |  #include <string>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -using zp::Parser;
 | 
	
		
			
				|  |  | +using namespace zp;
 | 
	
		
			
				|  |  |  using namespace std;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  Parser::Parser(istream& in) :
 | 
	
	
		
			
				|  | @@ -10,17 +10,64 @@ Parser::Parser(istream& in) :
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -void Parser::parse(void)
 | 
	
		
			
				|  |  | +unique_ptr<Block> Parser::parse(void)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -    while (!in.eof())
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -        char chr;
 | 
	
		
			
				|  |  | -        in >> chr;
 | 
	
		
			
				|  |  | +    return parseBlock(false);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +unique_ptr<Block> Parser::parseBlock(bool isLoop)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    unique_ptr<UnionBlock> wrapper = nullptr;
 | 
	
		
			
				|  |  | +    unique_ptr<InstructionBlock> block = make_unique<InstructionBlock>();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    char chr;
 | 
	
		
			
				|  |  | +    while (in >> chr) {
 | 
	
		
			
				|  |  |          switch(chr) {
 | 
	
		
			
				|  |  |              case '+':
 | 
	
		
			
				|  |  | -                program.instructions.push_back(
 | 
	
		
			
				|  |  | -                        std::make_unique<UnaryInstruction>());
 | 
	
		
			
				|  |  | +                block->addInstruction(Instruction::PLUS);
 | 
	
		
			
				|  |  | +                break;
 | 
	
		
			
				|  |  | +            case '-':
 | 
	
		
			
				|  |  | +                block->addInstruction(Instruction::MINUS);
 | 
	
		
			
				|  |  | +                break;
 | 
	
		
			
				|  |  | +            case '<':
 | 
	
		
			
				|  |  | +                block->addInstruction(Instruction::LEFT);
 | 
	
		
			
				|  |  | +                break;
 | 
	
		
			
				|  |  | +            case '>':
 | 
	
		
			
				|  |  | +                block->addInstruction(Instruction::RIGHT);
 | 
	
		
			
				|  |  | +                break;
 | 
	
		
			
				|  |  | +            case '.':
 | 
	
		
			
				|  |  | +                block->addInstruction(Instruction::DOT);
 | 
	
		
			
				|  |  | +                break;
 | 
	
		
			
				|  |  | +            case ',':
 | 
	
		
			
				|  |  | +                block->addInstruction(Instruction::COMMA);
 | 
	
		
			
				|  |  | +                break;
 | 
	
		
			
				|  |  | +            case '[':
 | 
	
		
			
				|  |  | +                if (wrapper == nullptr) {
 | 
	
		
			
				|  |  | +                    wrapper = isLoop ? make_unique<Loop>() : make_unique<UnionBlock>();
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                if (!block->isEmpty()) {
 | 
	
		
			
				|  |  | +                    wrapper->addBlock(move(block));
 | 
	
		
			
				|  |  | +                    block = make_unique<InstructionBlock>();
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                wrapper->addBlock(parseBlock(true));
 | 
	
		
			
				|  |  | +                break;
 | 
	
		
			
				|  |  | +            case ']':
 | 
	
		
			
				|  |  | +                if (isLoop) {
 | 
	
		
			
				|  |  | +                    if (wrapper == nullptr)
 | 
	
		
			
				|  |  | +                        return block;
 | 
	
		
			
				|  |  | +                    else
 | 
	
		
			
				|  |  | +                        return wrapper;
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                else
 | 
	
		
			
				|  |  | +                    throw ParserException("encountered unexpected ']'");
 | 
	
		
			
				|  |  | +            default:;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | +    if (isLoop)
 | 
	
		
			
				|  |  | +        throw ParserException("number of '['s and ']'s not matching");
 | 
	
		
			
				|  |  | +    else if (wrapper == nullptr)
 | 
	
		
			
				|  |  | +        return block;
 | 
	
		
			
				|  |  | +    else
 | 
	
		
			
				|  |  | +        return wrapper;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  | -
 |