Bugfixes in macro expansion:

1. If expansion fails, don't crash.
2. Accept duplicate named arguments, the last one wins.
This commit is contained in:
Paul Koning 2022-06-29 09:45:37 -04:00
parent 7354aadbfc
commit 0513f914bc
4 changed files with 64 additions and 14 deletions

View File

@ -350,6 +350,10 @@ do_mcalled_macro:
list_location(stack->top, DOT);
macstr = expandmacro(stack->top, (MACRO *) op, ncp);
if (macstr == NULL) {
/* Error in expanding the macro, stop now. */
return 0;
}
stack_push(stack, macstr); /* Push macro expansion
onto input stream */

View File

@ -478,15 +478,19 @@ STREAM *expandmacro(
label = get_symbol(cp, &nextcp, NULL);
if (label && (nextcp = skipwhite(nextcp), *nextcp == '=') && (macarg = find_arg(mac->args, label))) {
/* Check if I've already got a value for it */
if (find_arg(args, label) != NULL) {
report(refstr, "Duplicate submission of keyword " "argument %s\n", label);
free(label);
free_args(args);
return NULL;
if ((arg = find_arg(args, label)) != NULL) {
/* Duplicate is legal; the last one wins. */
if (arg->value) {
free (arg->value);
arg->value = NULL;
}
}
else {
arg = new_arg();
arg->label = label;
arg->next = args;
args = arg;
}
arg = new_arg();
arg->label = label;
nextcp = skipwhite(nextcp + 1);
arg->value = getstring_macarg(refstr, nextcp, &nextcp);
} else {
@ -506,6 +510,8 @@ STREAM *expandmacro(
nextcp = skipwhite (cp);
arg = new_arg();
arg->label = memcheck(strdup(macarg->label)); /* Copy the name */
arg->next = args;
args = arg;
if (*nextcp != ',') {
arg->value = getstring_macarg(refstr, cp, &nextcp);
}
@ -515,9 +521,6 @@ STREAM *expandmacro(
nargs++; /* Count nonkeyword arguments only. */
}
arg->next = args;
args = arg;
/* If there is a trailing comma, there is an empty last argument */
cp = skipdelim_comma(nextcp, &onemore);
}

View File

@ -77,15 +77,41 @@
1 000003 .narg label ; second arg is "default"
53 000000 tstarg 1,2,3 ; 3 args
1 000003 .narg label ; second arg is "2"
53
54
55 ;
56 ; Test default args and strange commas
57 ;
58 .macro tstdef a=1,b=2
59 .word a,b
60 .endm
61
62 000000 tstdef
1 000000 000001 000002 .word 1,2
63 000004 tstdef 4,5
1 000004 000004 000005 .word 4,5
64 000010 tstdef 4,5,6 ; Excess argument is ignored
1 000010 000004 000005 .word 4,5
65 000014 tstdef b=42
1 000014 000001 000042 .word 1,42
66 000020 tstdef a=73
1 000020 000073 000002 .word 73,2
67 000024 tstdef ,b=11
1 000024 000001 000011 .word 1,11
68 000030 tstdef a=5,b=4
1 000030 000005 000004 .word 5,4
69 000034 tstdef ,a=5,b=4 ; Strange case seen in some sources
1 000034 000005 000004 .word 5,4
70 000040 tstdef a=5,a=4 ; Duplicate keyword argument -- legal!
1 000040 000004 000002 .word 4,2
70
Symbol table
. 000000R 001 LABEL = 000003 START 000000R 001
. 000044R 001 LABEL = 000003 START 000000R 001
Program sections:
. ABS. 000000 000 (RW,I,GBL,ABS,OVR,NOSAV)
000000 001 (RW,I,LCL,REL,CON,NOSAV)
000044 001 (RW,I,LCL,REL,CON,NOSAV)

View File

@ -51,3 +51,20 @@ start: tstarg ; 0 args
tstarg ,,3 ; 3 args
tstarg 1,,3 ; 3 args
tstarg 1,2,3 ; 3 args
;
; Test default args and strange commas
;
.macro tstdef a=1,b=2
.word a,b
.endm
tstdef
tstdef 4,5
tstdef 4,5,6 ; Excess argument is ignored
tstdef b=42
tstdef a=73
tstdef ,b=11
tstdef a=5,b=4
tstdef ,a=5,b=4 ; Strange case seen in some sources
tstdef a=5,a=4 ; Duplicate keyword argument -- legal!