feat: implement format strings
This commit is contained in:
@@ -251,11 +251,83 @@ void skip_comment(fzl_reader_t *reader)
|
||||
}
|
||||
}
|
||||
|
||||
// Parse string format
|
||||
fzl_token_t *parse_fmtstring_part(fzl_reader_t *reader)
|
||||
{
|
||||
size_t p = reader->position;
|
||||
char *src = reader->source;
|
||||
|
||||
fzl_file_loc l;
|
||||
bool ok = fzl_linked_getpos(reader->linked, reader->position, &l);
|
||||
if (!ok)
|
||||
{
|
||||
snprintf(last_err, sizeof(last_err), "failed to locate line:col");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (src[p] == '{')
|
||||
{
|
||||
move(reader, 1);
|
||||
fzl_token_t *id = parse_name(reader);
|
||||
|
||||
if (id == NULL || src[reader->position] != '}')
|
||||
{
|
||||
snprintf(last_err, sizeof(last_err),
|
||||
"'%s':%zu:%zu => failed to parse format string", l.filename,
|
||||
l.line, l.col);
|
||||
fzl_freetoken(id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
move(reader, 1);
|
||||
return id;
|
||||
}
|
||||
|
||||
if (src[p] == '"')
|
||||
{
|
||||
move(reader, 1);
|
||||
|
||||
return fzl_mktoken(FZL_TOKTYPE_STR_FORMAT_END, l.line, l.col, NULL, 0,
|
||||
l.filename);
|
||||
}
|
||||
|
||||
size_t size = 0;
|
||||
size_t lpos = p;
|
||||
|
||||
do
|
||||
{
|
||||
if (src[lpos + 1] == '"')
|
||||
break;
|
||||
|
||||
size++;
|
||||
lpos++;
|
||||
} while (lpos < reader->size && reader->source[lpos] != '{' &&
|
||||
reader->source[lpos] != '"');
|
||||
|
||||
ok = fzl_linked_getpos(reader->linked, reader->position, &l);
|
||||
if (!ok)
|
||||
{
|
||||
snprintf(last_err, sizeof(last_err), "failed to locate line:col");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *value = malloc(size);
|
||||
memcpy(value, reader->source + reader->position, size);
|
||||
fzl_token_t *tok = fzl_mktoken(FZL_TOKTYPE_STR_LITERAL, l.line, l.col, value,
|
||||
size, l.filename);
|
||||
free(value);
|
||||
move(reader, size);
|
||||
|
||||
return tok;
|
||||
}
|
||||
|
||||
int fzl_read(fzl_reader_t *reader)
|
||||
{
|
||||
if (reader->position >= reader->size)
|
||||
return 0;
|
||||
|
||||
bool is_format_str = false;
|
||||
|
||||
do
|
||||
{
|
||||
size_t p = reader->position;
|
||||
@@ -268,7 +340,13 @@ int fzl_read(fzl_reader_t *reader)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (curr == '\'' || curr == '"')
|
||||
if (is_format_str)
|
||||
{
|
||||
token = parse_fmtstring_part(reader);
|
||||
if (token && token->type == FZL_TOKTYPE_STR_FORMAT_END)
|
||||
is_format_str = false;
|
||||
}
|
||||
else if (curr == '\'' || curr == '"')
|
||||
token = parse_string_literal(reader);
|
||||
else if (curr == '/' && reader->source[p + 1] == '/')
|
||||
{
|
||||
@@ -321,6 +399,12 @@ int fzl_read(fzl_reader_t *reader)
|
||||
token = add_single(reader, FZL_TOKTYPE_PERCENT);
|
||||
else if (curr == '=')
|
||||
token = add_single(reader, FZL_TOKTYPE_EQ);
|
||||
else if (curr == '$' && reader->source[p + 1] == '"')
|
||||
{
|
||||
move(reader, 2);
|
||||
is_format_str = true;
|
||||
token = fzl_mktoken(FZL_TOKTYPE_STR_FORMAT_START, 0, 0, NULL, 0, "");
|
||||
}
|
||||
else if ((curr >= 'A' && curr <= 'Z') || (curr >= 'a' && curr <= 'z') ||
|
||||
curr == '_')
|
||||
token = parse_name(reader);
|
||||
|
||||
Reference in New Issue
Block a user