mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-30 04:50:08 +00:00
The parsers no longer own a tape, merely taking one as an argument. So they can be an adjunct.
This commit is contained in:
parent
bc83a8f2d0
commit
093eb55fc6
@ -24,30 +24,30 @@ enum class SymbolType {
|
||||
|
||||
class Acorn1200BaudTapeParser: public StaticAnalyer::TapeParser<WaveType, SymbolType> {
|
||||
public:
|
||||
Acorn1200BaudTapeParser(const std::shared_ptr<Storage::Tape::Tape> &tape) :
|
||||
TapeParser(tape),
|
||||
Acorn1200BaudTapeParser() :
|
||||
TapeParser(),
|
||||
_crc(0x1021, 0x0000) {}
|
||||
|
||||
int get_next_bit()
|
||||
int get_next_bit(const std::shared_ptr<Storage::Tape::Tape> &tape)
|
||||
{
|
||||
SymbolType symbol = get_next_symbol();
|
||||
SymbolType symbol = get_next_symbol(tape);
|
||||
return (symbol == SymbolType::One) ? 1 : 0;
|
||||
}
|
||||
|
||||
int get_next_byte()
|
||||
int get_next_byte(const std::shared_ptr<Storage::Tape::Tape> &tape)
|
||||
{
|
||||
int value = 0;
|
||||
int c = 8;
|
||||
if(get_next_bit())
|
||||
if(get_next_bit(tape))
|
||||
{
|
||||
set_error_flag();
|
||||
return -1;
|
||||
}
|
||||
while(c--)
|
||||
{
|
||||
value = (value >> 1) | (get_next_bit() << 7);
|
||||
value = (value >> 1) | (get_next_bit(tape) << 7);
|
||||
}
|
||||
if(!get_next_bit())
|
||||
if(!get_next_bit(tape))
|
||||
{
|
||||
set_error_flag();
|
||||
return -1;
|
||||
@ -56,17 +56,17 @@ class Acorn1200BaudTapeParser: public StaticAnalyer::TapeParser<WaveType, Symbol
|
||||
return value;
|
||||
}
|
||||
|
||||
int get_next_short()
|
||||
int get_next_short(const std::shared_ptr<Storage::Tape::Tape> &tape)
|
||||
{
|
||||
int result = get_next_byte();
|
||||
result |= get_next_byte() << 8;
|
||||
int result = get_next_byte(tape);
|
||||
result |= get_next_byte(tape) << 8;
|
||||
return result;
|
||||
}
|
||||
|
||||
int get_next_word()
|
||||
int get_next_word(const std::shared_ptr<Storage::Tape::Tape> &tape)
|
||||
{
|
||||
int result = get_next_short();
|
||||
result |= get_next_short() << 8;
|
||||
int result = get_next_short(tape);
|
||||
result |= get_next_short(tape) << 8;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -117,22 +117,22 @@ class Acorn1200BaudTapeParser: public StaticAnalyer::TapeParser<WaveType, Symbol
|
||||
NumberTheory::CRC16 _crc;
|
||||
};
|
||||
|
||||
static std::unique_ptr<File::Chunk> GetNextChunk(Acorn1200BaudTapeParser &parser)
|
||||
static std::unique_ptr<File::Chunk> GetNextChunk(const std::shared_ptr<Storage::Tape::Tape> &tape, Acorn1200BaudTapeParser &parser)
|
||||
{
|
||||
std::unique_ptr<File::Chunk> new_chunk(new File::Chunk);
|
||||
int shift_register = 0;
|
||||
|
||||
// TODO: move this into the parser
|
||||
#define shift() shift_register = (shift_register >> 1) | (parser.get_next_bit() << 9)
|
||||
#define shift() shift_register = (shift_register >> 1) | (parser.get_next_bit(tape) << 9)
|
||||
|
||||
// find next area of high tone
|
||||
while(!parser.is_at_end() && (shift_register != 0x3ff))
|
||||
while(!tape->is_at_end() && (shift_register != 0x3ff))
|
||||
{
|
||||
shift();
|
||||
}
|
||||
|
||||
// find next 0x2a (swallowing stop bit)
|
||||
while(!parser.is_at_end() && (shift_register != 0x254))
|
||||
while(!tape->is_at_end() && (shift_register != 0x254))
|
||||
{
|
||||
shift();
|
||||
}
|
||||
@ -145,9 +145,9 @@ static std::unique_ptr<File::Chunk> GetNextChunk(Acorn1200BaudTapeParser &parser
|
||||
// read out name
|
||||
char name[11];
|
||||
int name_ptr = 0;
|
||||
while(!parser.is_at_end() && name_ptr < sizeof(name))
|
||||
while(!tape->is_at_end() && name_ptr < sizeof(name))
|
||||
{
|
||||
name[name_ptr] = (char)parser.get_next_byte();
|
||||
name[name_ptr] = (char)parser.get_next_byte(tape);
|
||||
if(!name[name_ptr]) break;
|
||||
name_ptr++;
|
||||
}
|
||||
@ -155,15 +155,15 @@ static std::unique_ptr<File::Chunk> GetNextChunk(Acorn1200BaudTapeParser &parser
|
||||
new_chunk->name = name;
|
||||
|
||||
// addresses
|
||||
new_chunk->load_address = (uint32_t)parser.get_next_word();
|
||||
new_chunk->execution_address = (uint32_t)parser.get_next_word();
|
||||
new_chunk->block_number = (uint16_t)parser.get_next_short();
|
||||
new_chunk->block_length = (uint16_t)parser.get_next_short();
|
||||
new_chunk->block_flag = (uint8_t)parser.get_next_byte();
|
||||
new_chunk->next_address = (uint32_t)parser.get_next_word();
|
||||
new_chunk->load_address = (uint32_t)parser.get_next_word(tape);
|
||||
new_chunk->execution_address = (uint32_t)parser.get_next_word(tape);
|
||||
new_chunk->block_number = (uint16_t)parser.get_next_short(tape);
|
||||
new_chunk->block_length = (uint16_t)parser.get_next_short(tape);
|
||||
new_chunk->block_flag = (uint8_t)parser.get_next_byte(tape);
|
||||
new_chunk->next_address = (uint32_t)parser.get_next_word(tape);
|
||||
|
||||
uint16_t calculated_header_crc = parser.get_crc();
|
||||
uint16_t stored_header_crc = (uint16_t)parser.get_next_short();
|
||||
uint16_t stored_header_crc = (uint16_t)parser.get_next_short(tape);
|
||||
stored_header_crc = (uint16_t)((stored_header_crc >> 8) | (stored_header_crc << 8));
|
||||
new_chunk->header_crc_matched = stored_header_crc == calculated_header_crc;
|
||||
|
||||
@ -171,13 +171,13 @@ static std::unique_ptr<File::Chunk> GetNextChunk(Acorn1200BaudTapeParser &parser
|
||||
new_chunk->data.reserve(new_chunk->block_length);
|
||||
for(int c = 0; c < new_chunk->block_length; c++)
|
||||
{
|
||||
new_chunk->data.push_back((uint8_t)parser.get_next_byte());
|
||||
new_chunk->data.push_back((uint8_t)parser.get_next_byte(tape));
|
||||
}
|
||||
|
||||
if(new_chunk->block_length && !(new_chunk->block_flag&0x40))
|
||||
{
|
||||
uint16_t calculated_data_crc = parser.get_crc();
|
||||
uint16_t stored_data_crc = (uint16_t)parser.get_next_short();
|
||||
uint16_t stored_data_crc = (uint16_t)parser.get_next_short(tape);
|
||||
stored_data_crc = (uint16_t)((stored_data_crc >> 8) | (stored_data_crc << 8));
|
||||
new_chunk->data_crc_matched = stored_data_crc == calculated_data_crc;
|
||||
}
|
||||
@ -233,13 +233,13 @@ std::unique_ptr<File> GetNextFile(std::deque<File::Chunk> &chunks)
|
||||
|
||||
std::list<File> StaticAnalyser::Acorn::GetFiles(const std::shared_ptr<Storage::Tape::Tape> &tape)
|
||||
{
|
||||
Acorn1200BaudTapeParser parser(tape);
|
||||
Acorn1200BaudTapeParser parser;
|
||||
|
||||
// populate chunk list
|
||||
std::deque<File::Chunk> chunk_list;
|
||||
while(!parser.is_at_end())
|
||||
while(!tape->is_at_end())
|
||||
{
|
||||
std::unique_ptr<File::Chunk> chunk = GetNextChunk(parser);
|
||||
std::unique_ptr<File::Chunk> chunk = GetNextChunk(tape, parser);
|
||||
if(chunk)
|
||||
{
|
||||
chunk_list.push_back(*chunk);
|
||||
|
@ -49,7 +49,7 @@ struct Data {
|
||||
class CommodoreROMTapeParser: public StaticAnalyer::TapeParser<WaveType, SymbolType> {
|
||||
public:
|
||||
CommodoreROMTapeParser(const std::shared_ptr<Storage::Tape::Tape> &tape) :
|
||||
TapeParser(tape),
|
||||
TapeParser(),
|
||||
_wave_period(0.0f),
|
||||
_previous_was_high(false),
|
||||
_parity_byte(0) {}
|
||||
@ -58,11 +58,11 @@ class CommodoreROMTapeParser: public StaticAnalyer::TapeParser<WaveType, SymbolT
|
||||
Advances to the next block on the tape, treating it as a header, then consumes, parses, and returns it.
|
||||
Returns @c nullptr if any wave-encoding level errors are encountered.
|
||||
*/
|
||||
std::unique_ptr<Header> get_next_header()
|
||||
std::unique_ptr<Header> get_next_header(const std::shared_ptr<Storage::Tape::Tape> &tape)
|
||||
{
|
||||
return duplicate_match<Header>(
|
||||
get_next_header_body(true),
|
||||
get_next_header_body(false)
|
||||
get_next_header_body(tape, true),
|
||||
get_next_header_body(tape, false)
|
||||
);
|
||||
}
|
||||
|
||||
@ -70,29 +70,29 @@ class CommodoreROMTapeParser: public StaticAnalyer::TapeParser<WaveType, SymbolT
|
||||
Advances to the next block on the tape, treating it as data, then consumes, parses, and returns it.
|
||||
Returns @c nullptr if any wave-encoding level errors are encountered.
|
||||
*/
|
||||
std::unique_ptr<Data> get_next_data()
|
||||
std::unique_ptr<Data> get_next_data(const std::shared_ptr<Storage::Tape::Tape> &tape)
|
||||
{
|
||||
return duplicate_match<Data>(
|
||||
get_next_data_body(true),
|
||||
get_next_data_body(false)
|
||||
get_next_data_body(tape, true),
|
||||
get_next_data_body(tape, false)
|
||||
);
|
||||
}
|
||||
|
||||
void spin()
|
||||
{
|
||||
while(!is_at_end())
|
||||
{
|
||||
SymbolType symbol = get_next_symbol();
|
||||
switch(symbol)
|
||||
{
|
||||
case SymbolType::One: printf("1"); break;
|
||||
case SymbolType::Zero: printf("0"); break;
|
||||
case SymbolType::Word: printf(" "); break;
|
||||
case SymbolType::EndOfBlock: printf("\n"); break;
|
||||
case SymbolType::LeadIn: printf("-"); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// void spin()
|
||||
// {
|
||||
// while(!is_at_end())
|
||||
// {
|
||||
// SymbolType symbol = get_next_symbol();
|
||||
// switch(symbol)
|
||||
// {
|
||||
// case SymbolType::One: printf("1"); break;
|
||||
// case SymbolType::Zero: printf("0"); break;
|
||||
// case SymbolType::Word: printf(" "); break;
|
||||
// case SymbolType::EndOfBlock: printf("\n"); break;
|
||||
// case SymbolType::LeadIn: printf("-"); break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
private:
|
||||
/*!
|
||||
@ -122,20 +122,20 @@ class CommodoreROMTapeParser: public StaticAnalyer::TapeParser<WaveType, SymbolT
|
||||
return std::move(*copy_to_return);
|
||||
}
|
||||
|
||||
std::unique_ptr<Header> get_next_header_body(bool is_original)
|
||||
std::unique_ptr<Header> get_next_header_body(const std::shared_ptr<Storage::Tape::Tape> &tape, bool is_original)
|
||||
{
|
||||
std::unique_ptr<Header> header(new Header);
|
||||
reset_error_flag();
|
||||
|
||||
// find and proceed beyond lead-in tone
|
||||
proceed_to_symbol(SymbolType::LeadIn);
|
||||
proceed_to_symbol(tape, SymbolType::LeadIn);
|
||||
|
||||
// look for landing zone
|
||||
proceed_to_landing_zone(is_original);
|
||||
proceed_to_landing_zone(tape, is_original);
|
||||
reset_parity_byte();
|
||||
|
||||
// get header type
|
||||
uint8_t header_type = get_next_byte();
|
||||
uint8_t header_type = get_next_byte(tape);
|
||||
switch(header_type)
|
||||
{
|
||||
default: header->type = Header::Unknown; break;
|
||||
@ -150,11 +150,11 @@ class CommodoreROMTapeParser: public StaticAnalyer::TapeParser<WaveType, SymbolT
|
||||
header->data.reserve(191);
|
||||
for(size_t c = 0; c < 191; c++)
|
||||
{
|
||||
header->data.push_back(get_next_byte());
|
||||
header->data.push_back(get_next_byte(tape));
|
||||
}
|
||||
|
||||
uint8_t parity_byte = get_parity_byte();
|
||||
header->parity_was_valid = get_next_byte() == parity_byte;
|
||||
header->parity_was_valid = get_next_byte(tape) == parity_byte;
|
||||
|
||||
// parse if this is not pure data
|
||||
if(header->type != Header::DataBlock)
|
||||
@ -174,22 +174,22 @@ class CommodoreROMTapeParser: public StaticAnalyer::TapeParser<WaveType, SymbolT
|
||||
}
|
||||
|
||||
|
||||
std::unique_ptr<Data> get_next_data_body(bool is_original)
|
||||
std::unique_ptr<Data> get_next_data_body(const std::shared_ptr<Storage::Tape::Tape> &tape, bool is_original)
|
||||
{
|
||||
std::unique_ptr<Data> data(new Data);
|
||||
reset_error_flag();
|
||||
|
||||
// find and proceed beyond lead-in tone to the next landing zone
|
||||
proceed_to_symbol(SymbolType::LeadIn);
|
||||
proceed_to_landing_zone(is_original);
|
||||
proceed_to_symbol(tape, SymbolType::LeadIn);
|
||||
proceed_to_landing_zone(tape, is_original);
|
||||
reset_parity_byte();
|
||||
|
||||
// accumulate until the next non-word marker is hit
|
||||
while(!is_at_end())
|
||||
while(!tape->is_at_end())
|
||||
{
|
||||
SymbolType start_symbol = get_next_symbol();
|
||||
SymbolType start_symbol = get_next_symbol(tape);
|
||||
if(start_symbol != SymbolType::Word) break;
|
||||
data->data.push_back(get_next_byte_contents());
|
||||
data->data.push_back(get_next_byte_contents(tape));
|
||||
}
|
||||
|
||||
// the above has reead the parity byte to the end of the data; if it matched the calculated parity it'll now be zero
|
||||
@ -205,13 +205,13 @@ class CommodoreROMTapeParser: public StaticAnalyer::TapeParser<WaveType, SymbolT
|
||||
/*!
|
||||
Finds and completes the next landing zone.
|
||||
*/
|
||||
void proceed_to_landing_zone(bool is_original)
|
||||
void proceed_to_landing_zone(const std::shared_ptr<Storage::Tape::Tape> &tape, bool is_original)
|
||||
{
|
||||
uint8_t landing_zone[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
while(!is_at_end())
|
||||
while(!tape->is_at_end())
|
||||
{
|
||||
memmove(landing_zone, &landing_zone[1], sizeof(uint8_t) * 8);
|
||||
landing_zone[8] = get_next_byte();
|
||||
landing_zone[8] = get_next_byte(tape);
|
||||
|
||||
bool is_landing_zone = true;
|
||||
for(int c = 0; c < 9; c++)
|
||||
@ -230,11 +230,11 @@ class CommodoreROMTapeParser: public StaticAnalyer::TapeParser<WaveType, SymbolT
|
||||
Swallows symbols until it reaches the first instance of the required symbol, swallows that
|
||||
and returns.
|
||||
*/
|
||||
void proceed_to_symbol(SymbolType required_symbol)
|
||||
void proceed_to_symbol(const std::shared_ptr<Storage::Tape::Tape> &tape, SymbolType required_symbol)
|
||||
{
|
||||
while(!is_at_end())
|
||||
while(!tape->is_at_end())
|
||||
{
|
||||
SymbolType symbol = get_next_symbol();
|
||||
SymbolType symbol = get_next_symbol(tape);
|
||||
if(symbol == required_symbol) return;
|
||||
}
|
||||
}
|
||||
@ -242,9 +242,9 @@ class CommodoreROMTapeParser: public StaticAnalyer::TapeParser<WaveType, SymbolT
|
||||
/*!
|
||||
Swallows the next byte; sets the error flag if it is not equal to @c value.
|
||||
*/
|
||||
void expect_byte(uint8_t value)
|
||||
void expect_byte(const std::shared_ptr<Storage::Tape::Tape> &tape, uint8_t value)
|
||||
{
|
||||
uint8_t next_byte = get_next_byte();
|
||||
uint8_t next_byte = get_next_byte(tape);
|
||||
if(next_byte != value) set_error_flag();
|
||||
}
|
||||
|
||||
@ -256,10 +256,10 @@ class CommodoreROMTapeParser: public StaticAnalyer::TapeParser<WaveType, SymbolT
|
||||
/*!
|
||||
Proceeds to the next word marker then returns the result of @c get_next_byte_contents.
|
||||
*/
|
||||
uint8_t get_next_byte()
|
||||
uint8_t get_next_byte(const std::shared_ptr<Storage::Tape::Tape> &tape)
|
||||
{
|
||||
proceed_to_symbol(SymbolType::Word);
|
||||
return get_next_byte_contents();
|
||||
proceed_to_symbol(tape, SymbolType::Word);
|
||||
return get_next_byte_contents(tape);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -267,13 +267,13 @@ class CommodoreROMTapeParser: public StaticAnalyer::TapeParser<WaveType, SymbolT
|
||||
Returns a byte composed of the first eight of those as bits; sets the error flag if any symbol is not
|
||||
::One and not ::Zero, or if the ninth bit is not equal to the odd parity of the other eight.
|
||||
*/
|
||||
uint8_t get_next_byte_contents()
|
||||
uint8_t get_next_byte_contents(const std::shared_ptr<Storage::Tape::Tape> &tape)
|
||||
{
|
||||
int byte_plus_parity = 0;
|
||||
int c = 9;
|
||||
while(c--)
|
||||
{
|
||||
SymbolType next_symbol = get_next_symbol();
|
||||
SymbolType next_symbol = get_next_symbol(tape);
|
||||
if((next_symbol != SymbolType::One) && (next_symbol != SymbolType::Zero)) set_error_flag();
|
||||
byte_plus_parity = (byte_plus_parity >> 1) | (((next_symbol == SymbolType::One) ? 1 : 0) << 8);
|
||||
}
|
||||
@ -292,10 +292,10 @@ class CommodoreROMTapeParser: public StaticAnalyer::TapeParser<WaveType, SymbolT
|
||||
/*!
|
||||
Returns the result of two consecutive @c get_next_byte calls, arranged in little-endian format.
|
||||
*/
|
||||
uint16_t get_next_short()
|
||||
uint16_t get_next_short(const std::shared_ptr<Storage::Tape::Tape> &tape)
|
||||
{
|
||||
uint16_t value = get_next_byte();
|
||||
value |= get_next_byte() << 8;
|
||||
uint16_t value = get_next_byte(tape);
|
||||
value |= get_next_byte(tape) << 8;
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -376,13 +376,13 @@ std::list<File> StaticAnalyser::Commodore::GetFiles(const std::shared_ptr<Storag
|
||||
CommodoreROMTapeParser parser(tape);
|
||||
std::list<File> file_list;
|
||||
|
||||
std::unique_ptr<Header> header = parser.get_next_header();
|
||||
std::unique_ptr<Header> header = parser.get_next_header(tape);
|
||||
|
||||
while(!parser.is_at_end())
|
||||
while(!tape->is_at_end())
|
||||
{
|
||||
if(!header)
|
||||
{
|
||||
header = parser.get_next_header();
|
||||
header = parser.get_next_header(tape);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -398,9 +398,9 @@ std::list<File> StaticAnalyser::Commodore::GetFiles(const std::shared_ptr<Storag
|
||||
new_file.type = File::DataSequence;
|
||||
|
||||
new_file.data.swap(header->data);
|
||||
while(!parser.is_at_end())
|
||||
while(!tape->is_at_end())
|
||||
{
|
||||
header = parser.get_next_header();
|
||||
header = parser.get_next_header(tape);
|
||||
if(!header) continue;
|
||||
if(header->type != Header::DataBlock) break;
|
||||
std::copy(header->data.begin(), header->data.end(), std::back_inserter(new_file.data));
|
||||
@ -413,7 +413,7 @@ std::list<File> StaticAnalyser::Commodore::GetFiles(const std::shared_ptr<Storag
|
||||
case Header::RelocatableProgram:
|
||||
case Header::NonRelocatableProgram:
|
||||
{
|
||||
std::unique_ptr<Data> data = parser.get_next_data();
|
||||
std::unique_ptr<Data> data = parser.get_next_data(tape);
|
||||
if(data)
|
||||
{
|
||||
File new_file;
|
||||
@ -427,12 +427,12 @@ std::list<File> StaticAnalyser::Commodore::GetFiles(const std::shared_ptr<Storag
|
||||
file_list.push_back(new_file);
|
||||
}
|
||||
|
||||
header = parser.get_next_header();
|
||||
header = parser.get_next_header(tape);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
header = parser.get_next_header();
|
||||
header = parser.get_next_header(tape);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -21,14 +21,32 @@ namespace StaticAnalyer {
|
||||
template <typename WaveType, typename SymbolType> class TapeParser {
|
||||
public:
|
||||
/// Instantiates a new parser with the supplied @c tape.
|
||||
TapeParser(const std::shared_ptr<Storage::Tape::Tape> &tape) : _tape(tape), _has_next_symbol(false), _error_flag(false) {}
|
||||
TapeParser() : _has_next_symbol(false), _error_flag(false) {}
|
||||
|
||||
/// Resets the error flag.
|
||||
void reset_error_flag() { _error_flag = false; }
|
||||
/// @returns @c true if an error has occurred since the error flag was last reset; @c false otherwise.
|
||||
bool get_error_flag() { return _error_flag; }
|
||||
/// @returns @c true if the encapsulated tape has reached its end; @c false otherwise.
|
||||
bool is_at_end() { return _tape->is_at_end(); }
|
||||
|
||||
/*!
|
||||
Asks the parser to continue taking pulses from the tape until either the subclass next declares a symbol
|
||||
or the tape runs out, returning the most-recently declared symbol.
|
||||
*/
|
||||
SymbolType get_next_symbol(const std::shared_ptr<Storage::Tape::Tape> &tape)
|
||||
{
|
||||
while(!_has_next_symbol && !tape->is_at_end())
|
||||
{
|
||||
process_pulse(tape->get_next_pulse());
|
||||
}
|
||||
_has_next_symbol = false;
|
||||
return _next_symbol;
|
||||
}
|
||||
|
||||
/*!
|
||||
Should be implemented by subclasses. Consumes @c pulse. Is likely either to call @c push_wave
|
||||
or to take no action.
|
||||
*/
|
||||
virtual void process_pulse(Storage::Tape::Tape::Pulse pulse) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
@ -67,20 +85,6 @@ template <typename WaveType, typename SymbolType> class TapeParser {
|
||||
remove_waves(number_of_waves);
|
||||
}
|
||||
|
||||
/*!
|
||||
Asks the parser to continue taking pulses from the tape until either the subclass next declares a symbol
|
||||
or the tape runs out, returning the most-recently declared symbol.
|
||||
*/
|
||||
SymbolType get_next_symbol()
|
||||
{
|
||||
while(!_has_next_symbol && !is_at_end())
|
||||
{
|
||||
process_pulse(_tape->get_next_pulse());
|
||||
}
|
||||
_has_next_symbol = false;
|
||||
return _next_symbol;
|
||||
}
|
||||
|
||||
void set_error_flag()
|
||||
{
|
||||
_error_flag = true;
|
||||
@ -89,12 +93,6 @@ template <typename WaveType, typename SymbolType> class TapeParser {
|
||||
private:
|
||||
bool _error_flag;
|
||||
|
||||
/*!
|
||||
Should be implemented by subclasses. Consumes @c pulse. Is likely either to call @c push_wave
|
||||
or to take no action.
|
||||
*/
|
||||
virtual void process_pulse(Storage::Tape::Tape::Pulse pulse) = 0;
|
||||
|
||||
/*!
|
||||
Should be implemented by subclasses. Inspects @c waves for a potential new symbol. If one is
|
||||
found should call @c push_symbol. May wish alternatively to call @c remove_waves to have entries
|
||||
@ -106,8 +104,6 @@ template <typename WaveType, typename SymbolType> class TapeParser {
|
||||
std::vector<WaveType> _wave_queue;
|
||||
SymbolType _next_symbol;
|
||||
bool _has_next_symbol;
|
||||
|
||||
std::shared_ptr<Storage::Tape::Tape> _tape;
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user