1
0
mirror of https://github.com/ksherlock/x65.git synced 2025-02-06 09:29:57 +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_END,
WCST_FIND_SUBSTR, WCST_FIND_SUBSTR,
WCST_FIND_SUBSTR_RANGE, WCST_FIND_SUBSTR_RANGE,
WCST_SUBSTR_MATCH_RANGE,
WCST_FIND_RANGE_CHAR, WCST_FIND_RANGE_CHAR,
WCST_FIND_RANGE_CHAR_RANGED, WCST_FIND_RANGE_CHAR_RANGED,
WCST_FIND_WORD_START, 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); int next_pos = wild.find_any_char_of(_wildcard_control, pos);
if (next_pos<0) { // completed? (found no wildcard token) if (next_pos<0) { // completed? (found no wildcard token)
// add last segment if there was one // 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); segs[numSeg++] = wild.get_substr(last, wild.get_len()-last);
if (search && range) if (search && range)
segs[numSeg++] = range; segs[numSeg++] = range;
type[numType++] = search ? (range ? WCST_FIND_SUBSTR_RANGE : WCST_FIND_SUBSTR) : WCST_NEXT_SUBSTR; 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(); range.clear();
break; break;
@ -3484,6 +3488,12 @@ strref strref::find_wildcard(const strref wild, strl_t start, bool case_sensitiv
seg += 2; seg += 2;
break; 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: case WCST_FIND_RANGE_CHAR:
find = true; find = true;
pos = find_any_char_or_range(segs[seg++], pos); 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_BAD_MACRO_FORMAT,
ERROR_ALIGN_MUST_EVALUATE_IMMEDIATELY, ERROR_ALIGN_MUST_EVALUATE_IMMEDIATELY,
ERROR_OUT_OF_MEMORY_FOR_MACRO_EXPANSION, ERROR_OUT_OF_MEMORY_FOR_MACRO_EXPANSION,
ERROR_MACRO_ARGUMENT,
ERROR_CONDITION_COULD_NOT_BE_RESOLVED, ERROR_CONDITION_COULD_NOT_BE_RESOLVED,
ERROR_ENDIF_WITHOUT_CONDITION, ERROR_ENDIF_WITHOUT_CONDITION,
ERROR_ELSE_WITHOUT_IF, ERROR_ELSE_WITHOUT_IF,
@ -194,6 +195,7 @@ const char *aStatusStrings[STATUSCODE_COUNT] = {
"Unexpected macro formatting", "Unexpected macro formatting",
"Align must evaluate immediately", "Align must evaluate immediately",
"Out of memory for macro expansion", "Out of memory for macro expansion",
"Problem with macro argument",
"Conditional could not be resolved", "Conditional could not be resolved",
"#endif encountered outside conditional block", "#endif encountered outside conditional block",
"#else or #elif 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); macexp.copy(macro_src);
arg = arg_list; arg = arg_list;
if (tag) { if (tag) {
for (int t=1; t<t_max; t++) { strref match("]*{0-9}");
tag.sprintf("]%d", t); strl_t pos = 0;
strref a = arg.split_token_trim(';'); while (strref tag = macexp.find_wildcard(match, pos)) {
macexp.replace_bookend(tag.get_strref(), a, label_end_char_range_merlin); 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()); 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(';'); // clip any line comments
line = line.before_or_full(c_comment); line = line.before_or_full(c_comment);
line.clip_trailing_whitespace(); 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; ++line;
strref line_nocom = line; strref line_nocom = line;
strref operation = line.split_range(Merlin() ? label_end_char_range_merlin : label_end_char_range); 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=='$'; bool force_label = charE==':' || charE=='$';
if (!force_label && Merlin() && (line || operation)) // MERLIN fixes and PoP does some naughty stuff like 'and = 0' 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=='?'; 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; force_label = true;
if (!operation && !force_label) { if (!operation && !force_label) {
if (ConditionalAsm()) { if (ConditionalAsm()) {
@ -5720,7 +5736,7 @@ StatusCode Asm::BuildLine(strref line)
} else { } else {
// ignore leading period for instructions and directives - not for labels // ignore leading period for instructions and directives - not for labels
strref label = operation; strref label = operation;
if ((syntax != SYNTAX_MERLIN && operation[0]==':') || operation[0]=='.') if ((!Merlin() && operation[0]==':') || operation[0]=='.')
++operation; ++operation;
operation = operation.before_or_full('.'); operation = operation.before_or_full('.');