static ASTPtr parseRepeatedCharFL(const char** fptr, const LengthFunc** lengthFuncsPtr) { assert(**fptr == '#'); const char* f_at = *fptr; ASTPtr ast; FunctionLength length = parseFunctionLength(fptr, lengthFuncsPtr); if (**fptr == '\'') { char c = parseCharLiteral(fptr); ast.reset(new RepeatedCharFL(f_at, length, c)); } else { throw DSLException(*fptr, "Expected char literal after function length."); } return ast; }
static char parseSilhouetteCharLiteral(const char** fptr) { assert(**fptr == '-'); ++*fptr; if (**fptr != '>') { throw DSLException(*fptr, "Expected > immediately after -."); } ++*fptr; parseWhitespaces(fptr); // -> is a token if (**fptr != '\'') { throw DSLException(*fptr, "Expected char literal after ->."); } return parseCharLiteral(fptr); }
static ASTPtr parseSpecifiedLengthContent(const char** fptr, const char*** wordSourcesPtr, const LengthFunc** lengthFuncsPtr) { assert(**fptr == '\'' || std::isdigit(**fptr) || **fptr == '#'); ASTPtr slc; if (**fptr == '\'') { slc = parseStringLiteral(fptr); } else if (**fptr == '#') { slc = parseRepeatedCharFL(fptr, lengthFuncsPtr); } else { const char* f_at = *fptr; LiteralLength length = parseLiteralLength(fptr); if (**fptr == '\'') { slc.reset(new RepeatedCharLL(f_at, length, parseCharLiteral(fptr))); } else if (**fptr == '[') { Block* block = new Block(f_at, length); slc.reset(block); ++*fptr; parseWhitespaces(fptr); // [ is a token while (**fptr != ']') { if (**fptr == '\'' || std::isdigit(**fptr) || **fptr == '#') { block->addChild(parseSpecifiedLengthContent(fptr, wordSourcesPtr, lengthFuncsPtr)); } else if (**fptr == '{') { block->addWords(parseWords(fptr, wordSourcesPtr)); } else { throw DSLException(*fptr, "Expected ', digit, or # to begin specified-length content, " "or { to begin greedy-length content."); } } ++*fptr; parseWhitespaces(fptr); // ] is a token if (**fptr == '^') { parseTopOrBottomFiller(fptr, &block->topFillers, true); if (**fptr == 'v') { parseTopOrBottomFiller(fptr, &block->bottomFillers, false); } } else if (**fptr == 'v') { parseTopOrBottomFiller(fptr, &block->bottomFillers, false); if (**fptr == '^') { parseTopOrBottomFiller(fptr, &block->topFillers, true); } } } else { throw DSLException(*fptr, "Expected ' or [ after length specifier."); } } return slc; }
// Parses 0 or more fillers static void parseFillers(const char** fptr, std::vector<FillerPtr>* fillers) { while (**fptr == '\'' || std::isdigit(**fptr)) { FillerPtr filler; if (**fptr == '\'') { filler = parseStringLiteral(fptr); } else { const char* f_at = *fptr; LiteralLength length = parseLiteralLength(fptr); if (**fptr == '\'') { char c = parseCharLiteral(fptr); filler.reset(new RepeatedCharLL(f_at, length, c)); } else { throw DSLException(*fptr, "Expected char literal after literal length."); } } fillers->push_back(std::move(filler)); } }
bool FormProcTokenParse(Units *units, Function *fn, llvm::BasicBlock *block, Node *node, bool get_address, bool prefixed_with_core, Type *wanted_type, ParseResult *pr) { Context *ctx = units->top()->ctx; Token *t = node->token; if (t->type == TokenType::Int) { parseIntegerLiteral(ctx, wanted_type, block, t, pr); return true; } else if (t->type == TokenType::FloatingPoint) { parseFloatingPointLiteral(ctx, wanted_type, block, t, pr); return true; } Enum *enum_obj; if (wanted_type && (wanted_type->struct_name.size()) && (enum_obj = ctx->getEnum(wanted_type->struct_name.c_str()))) { Struct *st = ctx->getStruct(wanted_type->struct_name.c_str()); assert(st && "no struct associated with enum"); int error_count_begin = ctx->er->getErrorTypeCount(ErrorType::Error); /* This will fail when the token is not a valid literal, so * in that case just continue onwards, because the token may * be validly parsed in other ways. */ bool res = FormLiteralEnumParse(units, block, node, enum_obj, wanted_type, st, get_address, pr); if (res) { return res; } else { ctx->er->popErrors(error_count_begin); } } if (t->type == TokenType::String) { pr->value = NULL; parseBoolLiteral(ctx, block, node, pr); if (pr->value) { return true; } parseCharLiteral(ctx, block, node, pr); if (pr->value) { return true; } parseVariableLiteral(ctx, block, node, get_address, pr); if (pr->value) { return true; } else { return false; } } else if (t->type == TokenType::StringLiteral) { pr->value = NULL; return parseStringLiteral(units, ctx, block, node, pr); } else { Error *e = new Error(UnableToParseForm, node); ctx->er->addError(e); return false; } }