1
0
mirror of https://github.com/ksherlock/x65.git synced 2024-12-28 19:32:25 +00:00

Merlin macro fix

- Does not require merlin macro parameters to be listed after the
keyword MAC
- Updated struse.h
This commit is contained in:
Carl-Henrik Skårstedt 2016-03-17 00:05:36 -07:00
parent 73d67d0657
commit 9752c1d8a1
2 changed files with 34 additions and 8 deletions

View File

@ -3194,6 +3194,7 @@ enum WILDCARD_SEGMENT_TYPE {
WCST_END,
WCST_FIND_SUBSTR,
WCST_FIND_SUBSTR_RANGE,
WCST_SUBSTR_MATCH_RANGE,
WCST_FIND_RANGE_CHAR,
WCST_FIND_RANGE_CHAR_RANGED,
WCST_FIND_WORD_START,
@ -3258,11 +3259,14 @@ static int _build_wildcard_steps(const strref wild, strref *segs, char *type, in
int next_pos = wild.find_any_char_of(_wildcard_control, pos);
if (next_pos<0) { // completed? (found no wildcard token)
// add last segment if there was one
if (wild.get_len() >(strl_t)last) {
if (wild.get_len() > (strl_t)last) {
segs[numSeg++] = wild.get_substr(last, wild.get_len()-last);
if (search && range)
segs[numSeg++] = range;
type[numType++] = search ? (range ? WCST_FIND_SUBSTR_RANGE : WCST_FIND_SUBSTR) : WCST_NEXT_SUBSTR;
} else if (range) {
segs[numSeg++] = range;
type[numType++] = WCST_SUBSTR_MATCH_RANGE;
}
range.clear();
break;
@ -3484,6 +3488,12 @@ strref strref::find_wildcard(const strref wild, strl_t start, bool case_sensitiv
seg += 2;
break;
case WCST_SUBSTR_MATCH_RANGE:
while ((strl_t)pos < length && segs[seg].char_matches_ranges(get_at(pos)))
pos++;
seg++;
break;
case WCST_FIND_RANGE_CHAR:
find = true;
pos = find_any_char_or_range(segs[seg++], pos);

30
x65.cpp
View File

@ -124,6 +124,7 @@ enum StatusCode {
ERROR_BAD_MACRO_FORMAT,
ERROR_ALIGN_MUST_EVALUATE_IMMEDIATELY,
ERROR_OUT_OF_MEMORY_FOR_MACRO_EXPANSION,
ERROR_MACRO_ARGUMENT,
ERROR_CONDITION_COULD_NOT_BE_RESOLVED,
ERROR_ENDIF_WITHOUT_CONDITION,
ERROR_ELSE_WITHOUT_IF,
@ -194,6 +195,7 @@ const char *aStatusStrings[STATUSCODE_COUNT] = {
"Unexpected macro formatting",
"Align must evaluate immediately",
"Out of memory for macro expansion",
"Problem with macro argument",
"Conditional could not be resolved",
"#endif encountered outside conditional block",
"#else or #elif outside conditional block",
@ -2882,10 +2884,24 @@ StatusCode Asm::BuildMacro(Macro &m, strref arg_list)
macexp.copy(macro_src);
arg = arg_list;
if (tag) {
for (int t=1; t<t_max; t++) {
tag.sprintf("]%d", t);
strref a = arg.split_token_trim(';');
macexp.replace_bookend(tag.get_strref(), a, label_end_char_range_merlin);
strref match("]*{0-9}");
strl_t pos = 0;
while (strref tag = macexp.find_wildcard(match, pos)) {
bool success = false;
strl_t offs = strl_t(tag.get() - macexp.get());
if (!offs || !strref::is_valid_label(macexp[offs])) {
int t = (tag + 1).atoi();
strref args = arg;
if (t > 0) {
for (int skip = 1; skip < t; skip++)
args.split_token_trim(';');
strref a = args.split_token_trim(';');
macexp.exchange(offs, tag.get_len(), a);
success = true;
}
}
if (!success)
return ERROR_MACRO_ARGUMENT;
}
}
PushContext(m.source_name, macexp.get_strref(), macexp.get_strref());
@ -5673,7 +5689,7 @@ StatusCode Asm::BuildLine(strref line)
line = line.before_or_full(';'); // clip any line comments
line = line.before_or_full(c_comment);
line.clip_trailing_whitespace();
if (line[0]==':' && syntax!=SYNTAX_MERLIN) // Kick Assembler macro prefix (incompatible with merlin)
if (line[0]==':' && !Merlin()) // Kick Assembler macro prefix (incompatible with merlin)
++line;
strref line_nocom = line;
strref operation = line.split_range(Merlin() ? label_end_char_range_merlin : label_end_char_range);
@ -5684,7 +5700,7 @@ StatusCode Asm::BuildLine(strref line)
bool force_label = charE==':' || charE=='$';
if (!force_label && Merlin() && (line || operation)) // MERLIN fixes and PoP does some naughty stuff like 'and = 0'
force_label = !strref::is_ws(char0) || char1==']' || charE=='?';
else if (!force_label && syntax!=SYNTAX_MERLIN && line[0]==':')
else if (!Merlin() && line[0]==':')
force_label = true;
if (!operation && !force_label) {
if (ConditionalAsm()) {
@ -5720,7 +5736,7 @@ StatusCode Asm::BuildLine(strref line)
} else {
// ignore leading period for instructions and directives - not for labels
strref label = operation;
if ((syntax != SYNTAX_MERLIN && operation[0]==':') || operation[0]=='.')
if ((!Merlin() && operation[0]==':') || operation[0]=='.')
++operation;
operation = operation.before_or_full('.');