relax .if to allow undefined expressions

This commit is contained in:
Bernd Boeckmann
2023-04-25 16:58:08 +02:00
parent 5a99e6a9a2
commit fb0fd431b3
5 changed files with 63 additions and 8 deletions

View File

@@ -256,7 +256,7 @@ static char* err_msg[] = {
#define ERR_PHASE 30
"symbol value mismatch between pass one and two",
#define ERR_PHASE_SIZE 31
"code size mismatch between pass one and two"
"pass two code size greater than pass one code size"
};
#define ERROR_NORM 1
@@ -430,9 +430,10 @@ static void define_variable(const char *id, const value v, symbol *parent)
if (pass == 1) error(ERR_REDEF);
else error(ERR_PHASE);
}
sym->value.v = v.v;
sym->value.defined = v.defined;
sym->filename = current_file->filename;
sym->filename = (current_file) ? current_file->filename : NULL;
sym->line = line;
/* if the type is already set do not change it */
@@ -1434,8 +1435,8 @@ static void directive_if(char **p)
if (process_statements) {
v = expr(p);
if (!DEFINED(v)) error(ERR_UNDEF);
process_statements = v.v != 0;
/*if (!DEFINED(v)) error(ERR_UNDEF);*/
process_statements = DEFINED(v) && v.v != 0;
if_stack[if_stack_count].condition_met = process_statements;
}
else {
@@ -1506,6 +1507,7 @@ static void echo(char **p)
static void directive_echo(char **p)
{
/* echo on second pass */
if (pass == 1) {
skip_to_eol(p);
return;
@@ -1513,6 +1515,16 @@ static void directive_echo(char **p)
echo(p);
}
static void directive_echo1(char **p)
{
/* echo on first pass */
if (pass == 2) {
skip_to_eol(p);
return;
}
echo(p);
}
static void directive_diagnostic(char **p, int level)
{
/* warnings and errors are processed at pass 1 */
@@ -1564,6 +1576,9 @@ static int directive(char **p)
else if (!strcmp(id, "ECHO")) {
directive_echo(p);
}
else if (!strcmp(id, "ECHO1")) {
directive_echo1(p);
}
else if (!strcmp(id, "ERROR")) {
directive_diagnostic(p, 1);
}
@@ -2087,6 +2102,7 @@ int main(int argc, char *argv[])
pass = 1;
ttext = current_file->text;
do_pass(&ttext);
code_size = oc;
if (errors) {
goto ret1;
}
@@ -2098,15 +2114,19 @@ int main(int argc, char *argv[])
errors = 1;
goto ret1;
}
if (!flag_quiet) printf("writing listing to %s\n", argv[3]);
}
/* second assembler pass */
pass = 2;
ttext = current_file->text;
code_size = oc;
code = malloc(code_size);
do_pass(&ttext);
if (oc != code_size && !errors) {
printf("error: pass two code size less than pass one code size\n");
errors++;
}
if (errors) {
goto ret2;
}
@@ -2114,8 +2134,11 @@ int main(int argc, char *argv[])
if (listing)
list_symbols();
if (!flag_quiet) printf("output size = %d bytes\n", oc);
fflush(stdout);
if (!flag_quiet) {
printf("output file %s, %d bytes written\n", output_filename, oc);
if (listing_filename)
printf("listing written to %s\n", listing_filename);
}
if (!save_code(output_filename, code, oc)) {
printf("error saving file\n");

6
tests/phase1.a65 Normal file
View File

@@ -0,0 +1,6 @@
; pass 2 output larger than pass 1
.if HELLO
.byte HELLO
.else
HELLO = 1
.endif

7
tests/phase2.a65 Normal file
View File

@@ -0,0 +1,7 @@
; pass 1 output larger than pass 2
.if HELLO
.byte HELLO
.else
HELLO = 1
.fill HELLO+1
.endif

8
tests/phase3.a65 Normal file
View File

@@ -0,0 +1,8 @@
.if X
.fill 2
.else
X = 1
.fill 1
.endif
sentinal:

11
tests/phase4.a65 Normal file
View File

@@ -0,0 +1,11 @@
.echo1 "I am written at the first pass!"
.echo "I am written at the second pass!"
.if X
.echo "X is defined as ", X
.fill X
.else
.echo "X is undefined, defaulting to 1"
X = 1
.fill X
.endif