static malValuePtr readAtom(Tokeniser& tokeniser) { struct ReaderMacro { const char* token; const char* symbol; }; ReaderMacro macroTable[] = { { "@", "deref" }, { "`", "quasiquote" }, { "'", "quote" }, { "~@", "splice-unquote" }, { "~", "unquote" }, }; struct Constant { const char* token; malValuePtr value; }; Constant constantTable[] = { { "false", mal::falseValue() }, { "nil", mal::nilValue() }, { "true", mal::trueValue() }, }; String token = tokeniser.next(); if (token[0] == '"') { return mal::string(unescape(token)); } if (token[0] == ':') { return mal::keyword(token); } if (token == "^") { malValuePtr meta = readForm(tokeniser); malValuePtr value = readForm(tokeniser); // Note that meta and value switch places return mal::list(mal::symbol("with-meta"), value, meta); } for (auto &constant : constantTable) { if (token == constant.token) { return constant.value; } } for (auto ¯o : macroTable) { if (token == macro.token) { return processMacro(tokeniser, macro.symbol); } } if (std::regex_match(token, intRegex)) { return mal::integer(token); } return mal::symbol(token); }
Pointer readLine(const char* input) { Tokeniser t; tokeniser_init(&t, input); Pointer ptr = readForm(&t); tokeniser_deinit(&t); return ptr; }
malValuePtr readStr(const String& input) { Tokeniser tokeniser(input); if (tokeniser.eof()) { throw malEmptyInputException(); } return readForm(tokeniser); }
static void readList(Tokeniser& tokeniser, malValueVec* items, const String& end) { while (1) { MAL_CHECK(!tokeniser.eof(), "expected '%s', got EOF", end.c_str()); if (tokeniser.peek() == end) { tokeniser.next(); return; } items->push_back(readForm(tokeniser)); } }
static Pointer readList(Tokeniser* t) { if (tokeniser_eof(t)) { THROW("Expected ), got EOF"); } Pointer token = tokeniser_token(t); if ((token.type == Type_symbol) && util_streq(symbol_get(token), ")")) { tokeniser_next(t); return nil_make(); } StackIndex carIndex = PUSH(readForm(t)); StackIndex cdrIndex = PUSH(readList(t)); Pointer ret = pair_make(carIndex, cdrIndex); DROP(2); return ret; }
static malValuePtr processMacro(Tokeniser& tokeniser, const String& symbol) { return mal::list(mal::symbol(symbol), readForm(tokeniser)); }
void MergeFile::copyFormTo( MergeFile& out, dr_section sect, uint_32& off, uint_32 form, uint_8 addrSize ) //----------------------------------------------------------------------- { uint_32 num; char * buffer; uint_32 bufLen; uint_8 buf8[ 8 ]; switch( form ) { /* do all simple numeric forms */ case DW_FORM_addr: case DW_FORM_flag: case DW_FORM_data1: case DW_FORM_ref1: case DW_FORM_data2: case DW_FORM_ref2: case DW_FORM_data4: case DW_FORM_ref4: case DW_FORM_sdata: case DW_FORM_udata: case DW_FORM_ref_udata: case DW_FORM_ref_addr: num = readForm( sect, off, form, addrSize ); out.writeForm( form, num, addrSize ); break; case DW_FORM_block1: bufLen = readByte( sect, off ); out.writeByte( (uint_8) bufLen ); if( bufLen ) { buffer = new char[ bufLen ]; readBlock( sect, off, buffer, bufLen ); out.writeBlock( buffer, bufLen ); delete [] buffer; } break; case DW_FORM_block2: bufLen = readWord( sect, off ); out.writeWord( (uint_16) bufLen ); if( bufLen ) { buffer = new char[ bufLen ]; readBlock( sect, off, buffer, bufLen ); out.writeBlock( buffer, bufLen ); delete [] buffer; } break; case DW_FORM_block4: bufLen = readDWord( sect, off ); out.writeDWord( bufLen ); if( bufLen ) { buffer = new char[ bufLen ]; readBlock( sect, off, buffer, bufLen ); out.writeBlock( buffer, bufLen ); delete [] buffer; } break; case DW_FORM_block: bufLen = readULEB128( sect, off ); if( bufLen ) { buffer = new char[ bufLen ]; readBlock( sect, off, buffer, bufLen ); out.writeBlock( buffer, bufLen ); delete [] buffer; } break; case DW_FORM_data8: readBlock( sect, off, buf8, 8 ); out.writeBlock( buf8, 8 ); break; case DW_FORM_string: do { num = readByte( sect, off ); out.writeByte( (uint_8) num ); } while( num != 0 ); break; case DW_FORM_indirect: num = readULEB128( sect, off ); out.writeULEB128( num ); copyFormTo( out, sect, off, num, addrSize ); break; default: #if DEBUG printf( "ACK -- form %#x\n", form ); #endif InternalAssert( 0 ); } }