Implement PRINT and PRINTLN (#672)

Fixes #669
Closes #368
Closes #624

Deprecate PRINTT, PRINTV, PRINTI, and PRINTF

Default STRFMT("%f") to 5 fractional digits like "{f:}"
Any use of string formatting will share this default
This commit is contained in:
Rangi
2021-01-01 20:37:32 -05:00
committed by GitHub
parent 9d2d5cfcfe
commit a70ecba06f
64 changed files with 325 additions and 316 deletions

View File

@@ -220,12 +220,16 @@ void fmt_PrintNumber(char *buf, size_t bufLen, struct FormatSpec const *fmt, uin
}
} else if (fmt->type == 'f') {
/* Special case for fixed-point */
if (fmt->fracWidth) {
/* Default fractional width (C's is 6 for "%f"; here 5 is enough) */
uint8_t fracWidth = fmt->hasFrac ? fmt->fracWidth : 5;
if (fracWidth) {
char spec[16]; /* Max "%" + 5-char PRIu32 + ".%0255.f" + terminator */
snprintf(spec, sizeof(spec), "%%" PRIu32 ".%%0%d.f", fmt->fracWidth);
snprintf(spec, sizeof(spec), "%%" PRIu32 ".%%0%d.f", fracWidth);
snprintf(valueBuf, sizeof(valueBuf), spec, value >> 16,
(value % 65536) / 65536.0 * pow(10, fmt->fracWidth) + 0.5);
(value % 65536) / 65536.0 * pow(10, fracWidth) + 0.5);
} else {
snprintf(valueBuf, sizeof(valueBuf), "%" PRIu32, value >> 16);
}

View File

@@ -207,6 +207,8 @@ static struct KeywordMapping {
{"STRFMT", T_OP_STRFMT},
{"INCLUDE", T_POP_INCLUDE},
{"PRINT", T_POP_PRINT},
{"PRINTLN", T_POP_PRINTLN},
{"PRINTT", T_POP_PRINTT},
{"PRINTI", T_POP_PRINTI},
{"PRINTV", T_POP_PRINTV},
@@ -491,7 +493,7 @@ struct KeywordDictNode {
uint16_t children[0x60 - ' '];
struct KeywordMapping const *keyword;
/* Since the keyword structure is invariant, the min number of nodes is known at compile time */
} keywordDict[356] = {0}; /* Make sure to keep this correct when adding keywords! */
} keywordDict[353] = {0}; /* Make sure to keep this correct when adding keywords! */
/* Convert a char into its index into the dict */
static inline uint8_t dictIndex(char c)
@@ -1315,13 +1317,8 @@ static char const *readInterpolation(void)
fmt_UseCharacter(&fmt, symName[j]);
fmt_FinishCharacters(&fmt);
symName[i] = '\0';
if (!fmt_IsValid(&fmt)) {
if (!fmt_IsValid(&fmt))
error("Invalid format spec '%s'\n", symName);
} else if (!strcmp(symName, "f")) {
/* Format 'f' defaults to '.5f' like PRINTF */
fmt.hasFrac = true;
fmt.fracWidth = 5;
}
i = 0; /* Now that format has been set, restart at beginning of string */
} else {
shiftChars(1);

View File

@@ -317,6 +317,7 @@ static inline void failAssertMsg(enum AssertionType type, char const *msg)
%type <sVal> relocexpr
%type <sVal> relocexpr_no_str
%type <nConstValue> const
%type <nConstValue> const_no_str
%type <nConstValue> uconst
%type <nConstValue> rs_uconst
%type <nConstValue> const_3bit
@@ -399,7 +400,7 @@ static inline void failAssertMsg(enum AssertionType type, char const *msg)
%token T_POP_EQUAL
%token T_POP_EQUS
%token T_POP_INCLUDE T_POP_PRINTF T_POP_PRINTT T_POP_PRINTV T_POP_PRINTI
%token T_POP_INCLUDE T_POP_PRINT T_POP_PRINTLN T_POP_PRINTF T_POP_PRINTT T_POP_PRINTV T_POP_PRINTI
%token T_POP_IF T_POP_ELIF T_POP_ELSE T_POP_ENDC
%token T_POP_EXPORT T_POP_GLOBAL T_POP_XDEF
%token T_POP_DB T_POP_DS T_POP_DW T_POP_DL
@@ -617,6 +618,8 @@ pseudoop : equ
;
simple_pseudoop : include
| print
| println
| printf
| printt
| printv
@@ -966,16 +969,43 @@ pushc : T_POP_PUSHC { charmap_Push(); }
popc : T_POP_POPC { charmap_Pop(); }
;
printt : T_POP_PRINTT string { printf("%s", $2); }
print : T_POP_PRINT print_exprs
;
printv : T_POP_PRINTV const { printf("$%" PRIX32, $2); }
println : T_POP_PRINTLN { putchar('\n'); }
| T_POP_PRINTLN print_exprs { putchar('\n'); }
;
printi : T_POP_PRINTI const { printf("%" PRId32, $2); }
print_exprs : print_expr
| print_exprs T_COMMA print_expr
;
printf : T_POP_PRINTF const { math_Print($2); }
print_expr : const_no_str { printf("$%" PRIX32, $1); }
| string { printf("%s", $1); }
;
printt : T_POP_PRINTT string {
warning(WARNING_OBSOLETE, "`PRINTT` is deprecated; use `PRINT`\n");
printf("%s", $2);
}
;
printv : T_POP_PRINTV const {
warning(WARNING_OBSOLETE, "`PRINTV` is deprecated; use `PRINT`\n");
printf("$%" PRIX32, $2);
}
;
printi : T_POP_PRINTI const {
warning(WARNING_OBSOLETE, "`PRINTI` is deprecated; use `PRINT` with `STRFMT`\n");
printf("%" PRId32, $2);
}
;
printf : T_POP_PRINTF const {
warning(WARNING_OBSOLETE, "`PRINTF` is deprecated; use `PRINT` with `STRFMT`\n");
math_Print($2);
}
;
const_3bit : const {
@@ -1250,6 +1280,17 @@ const : relocexpr {
}
;
const_no_str : relocexpr_no_str {
if (!rpn_isKnown(&$1)) {
error("Expected constant expression: %s\n",
$1.reason);
$$ = 0;
} else {
$$ = $1.nVal;
}
}
;
string : T_STRING
| T_OP_STRSUB T_LPAREN string T_COMMA uconst T_COMMA uconst T_RPAREN {
strsubUTF8($$, $3, $5, $7);

View File

@@ -269,7 +269,7 @@ prepended.
TOPIC equs "life, the universe, and \[rs]"everything\[rs]""
ANSWER = 42
;\ Prints "The answer to life, the universe, and "everything" is $2A"
PRINTT "The answer to {TOPIC} is {ANSWER}\[rs]n"
PRINTLN "The answer to {TOPIC} is {ANSWER}"
.Ed
.Pp
Symbol interpolations can be nested, too!
@@ -313,6 +313,7 @@ followed by one or more
\[en]
.Ql 9 .
If specified, prints this many digits of a fixed-point fraction.
Defaults to 5 digits.
.It Ql <type> Ta Specifies the type of value.
.El
.Pp
@@ -334,11 +335,11 @@ Valid print types are:
Examples:
.Bd -literal -offset indent
; Prints "%0010 + $3 == 5"
PRINTT STRFMT("%#05b + %#x == %d\n", 2, 3, 2+3)
PRINTLN STRFMT("%#05b + %#x == %d", 2, 3, 2+3)
; Prints "32% of 20 = 6.40"
PRINTT STRFMT("%d%% of %d = %.2f\n", 32, 20, MUL(20.0, 0.32))
PRINTLN STRFMT("%d%% of %d = %.2f", 32, 20, MUL(20.0, 0.32))
; Prints "Hello world!"
PRINTT STRFMT("Hello %s!\n", STRLWR("WORLD"))
PRINTLN STRFMT("Hello %s!", STRLWR("WORLD"))
.Ed
.Pp
HINT: The
@@ -355,7 +356,7 @@ INDEX = 1{ZERO_STR}{{FMT}:ZERO_NUM}
;\ Defines ITEM_100 as "\[rs]"hundredth\[rs]""
{NAME}_{d:INDEX} equs "\[rs]"hundredth\[rs]""
;\ Prints "ITEM_100 is hundredth"
PRINTT STRCAT("{NAME}_{d:INDEX} is ", {NAME}_{d:INDEX})
PRINTLN STRCAT("{NAME}_{d:INDEX} is ", {NAME}_{d:INDEX})
;\ Purges ITEM_100
PURGE {NAME}_{d:INDEX}
.Ed
@@ -1065,7 +1066,7 @@ This won't work:
.Bd -literal -offset indent
outer: MACRO
inner: MACRO
PRINTT "Hello!\[rs]n"
PRINTLN "Hello!"
ENDM
ENDM
.Ed
@@ -1073,7 +1074,7 @@ ENDM
But this will:
.Bd -literal -offset indent
outer: MACRO
definition equs "inner: MACRO\[rs]nPRINTT \[rs]"Hello!\[rs]\[rs]n\[rs]"\[rs]nENDM"
definition equs "inner: MACRO\[rs]nPRINTLN \[rs]"Hello!\[rs]"\[rs]nENDM"
definition
PURGE definition
ENDM
@@ -1435,22 +1436,22 @@ if you perform further calculations on them.
For instance, consider the following:
.Bd -literal -offset indent
print_double: MACRO
PRINTV \[rs]1 * 2
PRINTLN \[rs]1 * 2
ENDM
print_double 1 + 2
.Ed
.Pp
The
.Ic PRINTV
.Ic PRINTLN
statement will expand to
.Ql PRINTV 1 + 2 * 2 ,
.Ql PRINTLN 1 + 2 * 2 ,
which will print 5 and not 6 as you might have expected.
.Pp
Line continuations work as usual inside macros or lists of macro arguments.
However, some characters need to be escaped, as in the following example:
.Bd -literal -offset indent
PrintMacro: MACRO
PRINTT \[rs]1
PRINT \[rs]1
ENDM
PrintMacro STRCAT("Hello "\[rs], \[rs]
@@ -1490,31 +1491,31 @@ This is the only way of accessing the value of arguments from 10 to 256.
.Ic SHIFT
can optionally be given an integer parameter, and will apply the above shifting that number of times.
.Ss Printing things during assembly
The next four commands print text and values to the standard output.
The
.Ic PRINT
and
.Ic PRINTLN
commands print text and values to the standard output.
Useful for debugging macros, or wherever you may feel the need to tell yourself some important information.
.Bd -literal -offset indent
PRINTT "I'm the greatest programmer in the whole wide world\[rs]n"
PRINTI (2 + 3) / 5
PRINTV $FF00 + $F0
PRINTF MUL(3.14, 3987.0)
PRINT "Hello world!\[rs]n"
PRINTLN "Hello world!"
PRINT _NARG, " arguments\[rs]n"
PRINTLN "sum: ", 2+3, " product: ", 2*3
PRINTLN "Line #", __LINE__
PRINTLN STRFMT("E = %f", 2.718)
.Ed
.Bl -inset
.It Ic PRINTT
prints out a string.
Be careful to add a line feed
.Pq Qq \[rs]n
at the end, as it is not added automatically.
.It Ic PRINTV
prints out an integer value in hexadecimal or, as in the example, the result of a calculation.
Unsurprisingly, you can also print out a constant symbol's value.
.It Ic PRINTI
prints out a signed integer value.
.It Ic PRINTF
prints out a fixed point value.
.It Ic PRINT
prints out each of its comma-separated arguments.
Numbers are printed as unsigned uppercase hexadecimal with a leading
.Ic $ .
For different formats, use
.Ic STRFMT .
.It Ic PRINTLN
prints out each of its comma-separated arguments, if any, followed by a line feed
.Pq Ql \[rs]n .
.El
.Pp
Be careful that none of those automatically print a line feed; if you need one, use
.Ic PRINTT "\[rs]n" .
.Ss Automatically repeating blocks of code
Suppose you want to unroll a time consuming loop without copy-pasting it.
.Ic REPT
@@ -1537,9 +1538,7 @@ You can also use
.Ic REPT
to generate tables on the fly:
.Bd -literal -offset indent
;\ --
;\ -- Generate a 256 byte sine table with values between 0 and 128
;\ --
; Generate a 256-byte sine table with values between 0 and 128
ANGLE = 0.0
REPT 256
db (MUL(64.0, SIN(ANGLE)) + 64.0) >> 16
@@ -1602,9 +1601,9 @@ until it reaches or exceeds
For example:
.Bd -literal -offset indent
FOR V, 4, 25, 5
PRINTT "{d:V} "
PRINT "{d:V} "
ENDR
PRINTT "done {d:V}\n"
PRINTLN "done {d:V}"
.Ed
This will print:
.Bd -literal -offset indent
@@ -1714,11 +1713,11 @@ skip over parts of your code depending on a condition.
This is a powerful feature commonly used in macros.
.Bd -literal -offset indent
IF NUM < 0
PRINTT "NUM < 0\[rs]n"
PRINTLN "NUM < 0"
ELIF NUM == 0
PRINTT "NUM == 0\[rs]n"
PRINTLN "NUM == 0"
ELSE
PRINTT "NUM > 0\[rs]n"
PRINTLN "NUM > 0"
ENDC
.Ed
.Pp

View File

@@ -1,24 +1,23 @@
print_all: MACRO
REPT _NARG
PRINTT " \1"
PRINT " \1"
SHIFT
ENDR
PRINTT "\n"
PRINTLN
ENDM
print_some: MACRO
PRINTT "\1"
PRINT "\1"
SHIFT 5
PRINTT "\2\6\9"
PRINT "\2\6\9"
SHIFT 17
SHIFT
PRINTT "\3\9"
PRINT "\3\9"
ENDM
bad: MACRO
shift _NARG - 1
PRINTT \1
PRINTT "\n"
PRINTLN \1
ENDM
bad_rept: MACRO
@@ -27,8 +26,7 @@ bad_rept: MACRO
shift
ENDR
ENDR
PRINTT \1
PRINTT "\n"
PRINTLN \1
ENDM
print_all This test, probably, passes\,, but who knows, ?

View File

@@ -5,8 +5,7 @@ def_sect: macro
SECTION "\1", \2, BANK[\3]
ENDC
PRINTV BANK("\1")
PRINTT "\n"
PRINTLN BANK("\1")
endm
def_sect ROM0_ok, ROM0

View File

@@ -1,9 +1,9 @@
ERROR: bank.asm(14) -> bank.asm::def_sect(8):
ERROR: bank.asm(13) -> bank.asm::def_sect(8):
Expected constant expression: Section "ROMX_bad"'s bank is not known
ERROR: bank.asm(16) -> bank.asm::def_sect(8):
ERROR: bank.asm(15) -> bank.asm::def_sect(8):
Expected constant expression: Section "VRAM_bad"'s bank is not known
ERROR: bank.asm(18) -> bank.asm::def_sect(8):
ERROR: bank.asm(17) -> bank.asm::def_sect(8):
Expected constant expression: Section "SRAM_bad"'s bank is not known
ERROR: bank.asm(21) -> bank.asm::def_sect(8):
ERROR: bank.asm(20) -> bank.asm::def_sect(8):
Expected constant expression: Section "WRAMX_bad"'s bank is not known
error: Assembly aborted (4 errors)!

View File

@@ -1,2 +1,2 @@
/* block comments containing /* throw warnings */
PRINTT "reachable\n"
PRINTLN "reachable"

View File

@@ -1 +1 @@
PRINTT /* block comments must terminate before EOF
PRINT /* block comments must terminate before EOF

View File

@@ -1,5 +1,5 @@
PRINTT /* block comments are ignored // ** */ "hi\n"
PRINTT "block (/* ... */) comments at ends of line are fine\n" /* hi */
PRINTT /* block comments
PRINTLN /* block comments are ignored // ** */ "hi"
PRINTLN "block (/* ... */) comments at ends of line are fine" /* hi */
PRINTLN /* block comments
can span multiple lines
*/ "mutliline\n"
*/ "mutliline"

View File

@@ -1,21 +1,21 @@
X = 42
PRINTT "{X}\n"
PRINTT "{x:X}\n"
PRINTT "{X:X}\n"
PRINTT "{d:X}\n"
PRINTT "{b:X}\n"
PRINTLN "{X}"
PRINTLN "{x:X}"
PRINTLN "{X:X}"
PRINTLN "{d:X}"
PRINTLN "{b:X}"
Y equ 1337
PRINTT "{b:Y}\n"
PRINTLN "{b:Y}"
rsreset
R rb 0
PRINTT "{d:R}\n"
PRINTLN "{d:R}"
S equs "You can't format me!"
PRINTT "{X:S}\n"
PRINTLN "{X:S}"
SECTION "Test", ROM0
Label:
PRINTT "{x:Label}\n"
PRINTT "{x:@}\n"
PRINTLN "{x:Label}"
PRINTLN "{x:@}"

View File

@@ -1,4 +1,3 @@
; Remove this test case when _PI is removed.
PRINTF _PI
PRINTT "\n"
PRINTLN "{f:_PI}"
PURGE _PI

View File

@@ -1,5 +1,5 @@
warning: deprecated-pi.asm(2): [-Wobsolete]
`_PI` is deprecated; use 3.14159
ERROR: deprecated-pi.asm(4):
ERROR: deprecated-pi.asm(3):
Built-in symbol '_PI' cannot be purged
error: Assembly aborted (1 errors)!

View File

@@ -1,3 +1,3 @@
DEFINE equs "mac: MACRO\nPRINTT \"Hello :D\\n\"\nENDM"
DEFINE equs "mac: MACRO\nPRINTLN \"Hello :D\"\nENDM"
DEFINE
mac

View File

@@ -1,4 +1,4 @@
X1 equs "Y1 equs \"\\\"Success!\\\\n\\\"\""
Y1 equs "Z1"
X1
PRINTT Z1
PRINT Z1

View File

@@ -1 +1 @@
PRINTT "{__FILE__}\n"
PRINTLN "{__FILE__}"

View File

@@ -1,48 +1,48 @@
for n, 10
printt "{d:n} "
print "{d:n} "
endr
printt "-> {d:n}\n"
println "-> {d:n}"
for v, 0
printt "unreached"
print "unreached"
endr
for v, 2, 1
printt "unreached"
print "unreached"
endr
for v, 1, 2, 0
printt "unreached"
print "unreached"
endr
for x, 1, 5+1
printt "{d:x} "
print "{d:x} "
endr
printt "-> {d:x}\n"
println "-> {d:x}"
for v, 10, -1, -1
printt "{d:v} "
print "{d:v} "
v = 42
endr
printt "-> {d:v}\n"
println "-> {d:v}"
for q, 5, 21, 5
printt "{d:q} "
print "{d:q} "
purge q
endr
printt "-> {d:q}\n"
println "-> {d:q}"
s EQUS "x"
for s, 3, 30, 3
printt "{d:x} "
print "{d:x} "
endr
printt "-> {d:x}\n"
println "-> {d:x}"
for v, 10
printt "{d:v}\n"
println "{d:v}"
if v == 3
purge v
v equ 42 ; causes a fatal error
endc
endr
printt "-> {d:v}\n"
println "-> {d:v}"

View File

@@ -9,7 +9,7 @@ INDEX = 1{ZERO_STR}{{FMT}:ZERO_NUM}
; Defines ITEM_100 as "\"hundredth\""
{NAME}_{d:INDEX} equs "\"hundredth\""
; Prints "ITEM_100 is hundredth"
PRINTT STRCAT("{NAME}_{d:INDEX} is ", {NAME}_{d:INDEX}, "\n")
PRINTLN STRCAT("{NAME}_{d:INDEX}", " is ", {NAME}_{d:INDEX})
; Purges ITEM_100
PURGE {NAME}_{d:INDEX}
ASSERT !DEF({NAME}_{d:INDEX})

View File

@@ -5,7 +5,7 @@ test_expr: MACRO
TEST_NUM = TEST_NUM + 1
IS_CONST = ISCONST(\1)
PRINTT "Test #{d:TEST_NUM}: ISCONST reports {IS_CONST}\n"
PRINTLN "Test #{d:TEST_NUM}: ISCONST reports {IS_CONST}"
IF (\1) || 1 ; Only test if the expression can be evaluated
WARN "Test #{d:TEST_NUM}: Compile-time constant"
ENDC

View File

@@ -3,4 +3,4 @@ SECTION "Test", ROM0
Label:
jr Label
DIFF equ Label - @
PRINTT "{DIFF}\n"
PRINTLN "{DIFF}"

View File

@@ -17,10 +17,8 @@ Constant2: ; Same as above
print_diff: MACRO
PRINTV (\1) - (\2)
PRINTT "\n"
PRINTV (\2) - (\1)
PRINTT "\n"
PRINTLN (\1) - (\2)
PRINTLN (\2) - (\1)
ENDM
POPS ; Ensure we are in neither section

View File

@@ -1,37 +1,37 @@
ERROR: label-diff.asm(32) -> label-diff.asm::print_diff(20):
Expected constant expression: 'Known' is not constant at assembly time
ERROR: label-diff.asm(32) -> label-diff.asm::print_diff(21):
Expected constant expression: 'Known' is not constant at assembly time
ERROR: label-diff.asm(34) -> label-diff.asm::print_diff(20):
Expected constant expression: 'Known' is not constant at assembly time
ERROR: label-diff.asm(34) -> label-diff.asm::print_diff(22):
Expected constant expression: 'Known' is not constant at assembly time
ERROR: label-diff.asm(36) -> label-diff.asm::print_diff(20):
Expected constant expression: 'Unknown' is not constant at assembly time
ERROR: label-diff.asm(36) -> label-diff.asm::print_diff(22):
ERROR: label-diff.asm(34) -> label-diff.asm::print_diff(21):
Expected constant expression: 'Unknown' is not constant at assembly time
ERROR: label-diff.asm(36) -> label-diff.asm::print_diff(20):
Expected constant expression: 'Known' is not constant at assembly time
ERROR: label-diff.asm(36) -> label-diff.asm::print_diff(21):
Expected constant expression: 'Unknown' is not constant at assembly time
ERROR: label-diff.asm(38) -> label-diff.asm::print_diff(20):
Expected constant expression: 'Known' is not constant at assembly time
ERROR: label-diff.asm(38) -> label-diff.asm::print_diff(22):
Expected constant expression: 'Unknown' is not constant at assembly time
ERROR: label-diff.asm(40) -> label-diff.asm::print_diff(20):
Expected constant expression: 'Unknown' is not constant at assembly time
ERROR: label-diff.asm(40) -> label-diff.asm::print_diff(22):
ERROR: label-diff.asm(38) -> label-diff.asm::print_diff(21):
Expected constant expression: 'Unknown2' is not constant at assembly time
ERROR: label-diff.asm(45) -> label-diff.asm::print_diff(20):
Expected constant expression: 'Known' is not constant at assembly time
ERROR: label-diff.asm(45) -> label-diff.asm::print_diff(21):
Expected constant expression: 'Known' is not constant at assembly time
ERROR: label-diff.asm(47) -> label-diff.asm::print_diff(20):
Expected constant expression: 'Known' is not constant at assembly time
ERROR: label-diff.asm(47) -> label-diff.asm::print_diff(22):
Expected constant expression: 'Known' is not constant at assembly time
ERROR: label-diff.asm(49) -> label-diff.asm::print_diff(20):
Expected constant expression: 'Unknown' is not constant at assembly time
ERROR: label-diff.asm(49) -> label-diff.asm::print_diff(22):
ERROR: label-diff.asm(47) -> label-diff.asm::print_diff(21):
Expected constant expression: 'Unknown' is not constant at assembly time
ERROR: label-diff.asm(60) -> label-diff.asm::print_diff(20):
ERROR: label-diff.asm(58) -> label-diff.asm::print_diff(20):
Expected constant expression: PC is not constant at assembly time
ERROR: label-diff.asm(60) -> label-diff.asm::print_diff(22):
ERROR: label-diff.asm(58) -> label-diff.asm::print_diff(21):
Expected constant expression: PC is not constant at assembly time
ERROR: label-diff.asm(60) -> label-diff.asm::print_diff(20):
Expected constant expression: 'Known' is not constant at assembly time
ERROR: label-diff.asm(60) -> label-diff.asm::print_diff(21):
Expected constant expression: PC is not constant at assembly time
ERROR: label-diff.asm(62) -> label-diff.asm::print_diff(20):
Expected constant expression: 'Known' is not constant at assembly time
ERROR: label-diff.asm(62) -> label-diff.asm::print_diff(22):
Expected constant expression: PC is not constant at assembly time
ERROR: label-diff.asm(64) -> label-diff.asm::print_diff(20):
Expected constant expression: 'Unknown' is not constant at assembly time
ERROR: label-diff.asm(64) -> label-diff.asm::print_diff(22):
ERROR: label-diff.asm(62) -> label-diff.asm::print_diff(21):
Expected constant expression: PC is not constant at assembly time
error: Assembly aborted (18 errors)!

View File

@@ -1,9 +1,3 @@
print: MACRO
printv \1
printt "\n"
ENDM
m1: MACRO
x\1
ENDM
@@ -20,10 +14,10 @@ ENDM
m1 x = 7
m2 2 = 8
print x
print y
print xx
print yy
println x
println y
println xx
println yy
test_char: MACRO
@@ -32,7 +26,7 @@ VAR_DEF
sizeof_\1something = 1
PURGE VAR_DEF
VAR_PRINT equs "printt \"sizeof_\1something equals {sizeof_\1something}\\n\""
VAR_PRINT equs "println \"sizeof_\1something equals {sizeof_\1something}\""
VAR_PRINT
PURGE VAR_PRINT
ENDM

View File

@@ -1,7 +1,7 @@
ERROR: label-macro-arg.asm(44) -> label-macro-arg.asm::test_char(31):
ERROR: label-macro-arg.asm(38) -> label-macro-arg.asm::test_char(25):
Local label 'sizeof_.something' in main scope
while expanding symbol "VAR_DEF"
ERROR: label-macro-arg.asm(44) -> label-macro-arg.asm::test_char(31):
ERROR: label-macro-arg.asm(38) -> label-macro-arg.asm::test_char(25):
syntax error
while expanding symbol "VAR_DEF"
error: Assembly aborted (2 errors)!

View File

@@ -1,4 +1,4 @@
bad:
SECTION "Test", ROM0
good:
PRINTT "OK!\n"
PRINTLN "OK!"

View File

@@ -5,4 +5,4 @@ SECTION "Test", ROM0[0]
Glob:
.loc
PURGE .loc
PRINTT "{.loc}\n" ; This should fail because the label doesn't exist anymore
PRINTLN "{.loc}" ; This should fail because the label doesn't exist anymore

View File

@@ -6,12 +6,9 @@ m: MACRO
\1 EQUS STRCAT("{X\2}", "+1")
ENDM
n = 0
REPT $7E
FOR n, $7E
n1 = n + 1
m X{X:n1}, {X:n}
n = n + 1
ENDR
; string of 127 zeros separated by plus signs

View File

@@ -27,7 +27,7 @@ ENDM
object 12, 6, $66, $77, $88
echo: MACRO
printt "\#\n"
println "\#"
ENDM
R EQUS "S"
@@ -36,11 +36,10 @@ R EQUS "S"
echo Q,R, {R}, T
echo 42,$2a
print: MACRO
printt STRCAT(\#)
printt "\n"
printall: MACRO
println \#
ENDM
print
print "A"
print "B", "C", "D"
printall
printall "A"
printall "B", "C", "D"

View File

@@ -1,18 +1,16 @@
print: MACRO
PRINTT "\1"
PRINTT "\n"
print1: MACRO
PRINTLN "\1"
ENDM
print John "Danger" Smith
print \\A\nB
print C\
print1 John "Danger" Smith
print1 \\A\nB
print1 C\
D
print E\!F ; illegal character escape
print1 E\!F ; illegal character escape
iprint: MACRO
PRINTT "{\1}"
PRINTT "\n"
PRINTLN "{\1}"
ENDM
s EQUS "hello"

View File

@@ -1,3 +1,3 @@
ERROR: macro-arg-in-string.asm(10) -> macro-arg-in-string.asm::print(2):
ERROR: macro-arg-in-string.asm(9) -> macro-arg-in-string.asm::print1(2):
Illegal character escape '!'
error: Assembly aborted (1 errors)!

View File

@@ -1,23 +1,23 @@
S EQUS "Hello"
PRINTT "\"\"\"\n"
PRINT "\"\"\"\n"
PRINTT """{S}
PRINT """{S}
world
"""
PRINTT """The multi-line string \ ; line continuations work
PRINT """The multi-line string \ ; line continuations work
can contain:
- "single quotes"
- ""double quotes""
- even escaped \"""triple"\"" ""\"quotes\"\"\"
!"""
PRINTT """\n"""
PRINT """\n"""
printarg: MACRO
PRINTT "arg <\1>\n"
PRINTT """arg (\1)\n"""
PRINTLN "arg <\1>"
PRINTLN """arg (\1)"""
ENDM
printarg "
@@ -29,4 +29,4 @@ EMPTY2 EQUS "\ ; comment
EMPTY3 EQUS """"""
EMPTY4 EQUS """\ ; comment
"""
PRINTT STRCAT("(", "{EMPTY1}", "{EMPTY2}", "{EMPTY3}", "{EMPTY4}", ")\n")
PRINTLN STRCAT("(", "{EMPTY1}", "{EMPTY2}", "{EMPTY3}", "{EMPTY4}", ")")

View File

@@ -1,81 +1,81 @@
new_: MACRO
IF _NARG > 1
printt "newcharmap \1, \2\n"
println "newcharmap \1, \2"
newcharmap \1, \2
ELSE
printt "newcharmap \1\n"
println "newcharmap \1"
newcharmap \1
ENDC
ENDM
set_: MACRO
printt "setcharmap \1\n"
println "setcharmap \1"
setcharmap \1
ENDM
push_: MACRO
printt "pushc\n"
println "pushc"
pushc
ENDM
pop_: MACRO
printt "popc\n"
println "popc"
popc
ENDM
print: MACRO
print_mapped: MACRO
x = \1
printt "{x}\n"
println "{x}"
ENDM
printt "main charmap\n"
println "main charmap"
charmap "ab", $0
print "ab"
print_mapped "ab"
new_ map1
print "ab"
print_mapped "ab"
new_ map2, main
print "ab"
print_mapped "ab"
set_ map1
print "ab"
print_mapped "ab"
new_ map3
charmap "ab", $1
print "ab"
print_mapped "ab"
new_ map4, map3
charmap "ab", $1
charmap "cd", $2
print "ab"
print "cd"
print_mapped "ab"
print_mapped "cd"
set_ map3
print "ab"
print "cd"
print_mapped "ab"
print_mapped "cd"
set_ main
SECTION "sec0", ROM0
print "ab"
print_mapped "ab"
printt "modify main charmap\n"
println "modify main charmap"
charmap "ef", $3
print "ab"
print "ef"
print_mapped "ab"
print_mapped "ef"
set_ map1
@@ -85,17 +85,17 @@ charmap "ef", $3
set_ map3
print "ab"
print "cd"
print "ef"
print_mapped "ab"
print_mapped "cd"
print_mapped "ef"
pop_
print "ab"
print_mapped "ab"
pop_
print "ab"
print_mapped "ab"
new_ map1

View File

@@ -1 +1 @@
PRINTT "{_NARG}\n"
PRINTLN "{_NARG}"

View File

@@ -1,6 +1,5 @@
STRING equs "OK"
WRAPPER equs "TRIN"
PRINTT "{S{WRAPPER}G}\n"
PRINTLN "{S{WRAPPER}G}"
PRINTT "{S{WRAPPER}G"
PRINTT "\n"
PRINTLN "{S{WRAPPER}G"

View File

@@ -1,5 +1,5 @@
outer_ok: MACRO
definition equs "inner_ok: MACRO\nPRINTT \"Hello!\\n\"\nENDM"
definition equs "inner_ok: MACRO\nPRINTLN \"Hello!\"\nENDM"
definition
PURGE definition
ENDM
@@ -9,7 +9,7 @@ ENDM
outer_arg: MACRO
definition equs "inner_arg: MACRO\nPRINTT \"outer: \1\\ninner: \\1\\n\"\nENDM"
definition equs "inner_arg: MACRO\nPRINTLN \"outer: \1\\ninner: \\1\"\nENDM"
definition
PURGE definition
ENDM

View File

@@ -1,7 +1,2 @@
print: MACRO
printv \1
printt "\n"
ENDM
print 1 == 1 || 1 == 2
print (1 == 1) || (1 == 2)
println 1 == 1 || 1 == 2
println (1 == 1) || (1 == 2)

View File

@@ -1,3 +1,2 @@
OPT b.X
PRINTV %..X.X.X.
PRINTT "\n"
PRINTLN %..X.X.X.

View File

@@ -1,3 +1,2 @@
OPT g.x0X
PRINTV `.x.x0X0X
PRINTT "\n"
PRINTLN `.x.x0X0X

View File

@@ -1,8 +1,7 @@
SECTION "sec", ROM0
print_x: MACRO
printv x
printt "\n"
println x
ENDM
x = 2147483647

View File

@@ -1,8 +1,8 @@
warning: overflow.asm(23): [-Wdiv]
Division of -2147483648 by -1 yields -2147483648
warning: overflow.asm(24): [-Wdiv]
Division of -2147483648 by -1 yields -2147483648
warning: overflow.asm(25): [-Wdiv]
Division of -2147483648 by -1 yields -2147483648
warning: overflow.asm(39): [-Wlarge-constant]
warning: overflow.asm(38): [-Wlarge-constant]
Integer constant is too large
warning: overflow.asm(42): [-Wlarge-constant]
warning: overflow.asm(41): [-Wlarge-constant]
Graphics constant is too long, only 8 first pixels considered

View File

@@ -6,6 +6,6 @@ X = BANK(@)
SECTION "Something else", ROMX
Y = BANK("Fixed bank")
PRINTT "@: {X}\nStr: {Y}\n"
PRINTLN "@: {X}\nStr: {Y}"
ERR = BANK(@)

View File

@@ -1,5 +1,5 @@
IF DEF(@)
PRINTT "defined\n"
PRINTLN "defined"
ELSE
PRINTT "not defined\n"
PRINTLN "not defined"
ENDC

View File

@@ -1,7 +1,7 @@
SECTION "fixed", ROM0[420]
PRINTT "{@}\n"
PRINTLN "{@}"
ds 69
PRINTT "{@}\n"
PRINTLN "{@}"
; FIXME: expected to land at $0000
SECTION "floating", ROM0

View File

@@ -1,8 +1,8 @@
SECTION "test", ROM0[1]
call Target
PRINTT "PC in ROM: {@}\n"
PRINTLN "PC in ROM: {@}"
LOAD "new", WRAMX[$D001],BANK[1]
PRINTT "PC in WRAM: {@}\n"
PRINTLN "PC in WRAM: {@}"
assert @ == $D001
Target: dl DEAD << 16 | BEEF
db BANK(@)
@@ -29,4 +29,4 @@ SECTION "small ram test", WRAMX,BANK[1] ; Should end up at $D000
Byte:
db
PRINTT "{Target}\n{Target.end}\n{After}\n"
PRINTLN "{Target}\n{Target.end}\n{After}"

View File

@@ -1,7 +1,7 @@
s EQUS "Hello, "
REDEF s EQUS "{s}world!"
; prints "Hello, world!"
PRINTT "{s}\n"
PRINTLN "{s}"
list: MACRO
LIST_NAME EQUS "\1"
@@ -15,9 +15,9 @@ PURGE LIST_NAME
ENDM
list FOO
PRINTT "{FOO}\n"
PRINTLN "{FOO}"
list FOO, 1, A, 2, B
PRINTT "{FOO}\n"
PRINTLN "{FOO}"
N EQU 42
REDEF N EQUS "X"

View File

@@ -1,9 +1,9 @@
m: macro
PRINTT "\1 "
PRINT "\1 "
REPT 4
SHIFT
ENDR
PRINTT "\1s!\n"
PRINTLN "\1s!"
; Shifting a little more to check that over-shifting doesn't crash
SHIFT
@@ -11,7 +11,7 @@ m: macro
REPT 256
SHIFT
ENDR
PRINTT "\1\n"
PRINTLN "\1"
endm
m This, used, not, to, work

View File

@@ -25,7 +25,7 @@ RESULT equs "expected {EXPECTED}"
ENDC
PURGE EXPECTED
PRINTT "\1 is at {\1} ({RESULT})\n"
PRINTLN "\1 is at {\1} ({RESULT})"
PURGE RESULT
ENDM

View File

@@ -4,7 +4,7 @@ test: macro
; ...as well as the constexpr system
result\@ equ \1
printt "\1 = {result\@}\n"
println "\1 = {result\@}"
endm
section "test", ROM0[0]

View File

@@ -1,9 +1,4 @@
print: MACRO
PRINTT \1
PRINTT "\n"
ENDM
print STRCAT()
print STRCAT("Durrr")
print STRCAT("Left"\, "right")
print STRCAT("Whoa"\, "\, "\, "baby!")
println STRCAT()
println STRCAT("Durrr")
println STRCAT("Left", "right")
println STRCAT("Whoa", ", ", "baby!")

View File

@@ -1,24 +1,26 @@
VAL EQUS STRFMT("Hello %s! I am %d years old today!", "world", $f)
PRINTT "{VAL}\n"
PRINTLN "{VAL}"
N = -42
PRINTT STRFMT("signed %010d == unsigned %010u\n", N, N)
PRINTLN STRFMT("signed %010d == unsigned %010u", N, N)
N = 112
FMT EQUS "X"
PRINTT STRFMT("\tdb %#03{s:FMT} %% 26\t; %#03{FMT}\n", N, N % 26)
PRINTLN STRFMT("\tdb %#03{s:FMT} %% 26\t; %#03{FMT}", N, N % 26)
TEMPLATE EQUS "\"%s are %s\\n\""
PRINTT STRFMT(TEMPLATE, "roses", "red")
PRINTT STRFMT(TEMPLATE, "violets", "blue")
PRINTT STRFMT(TEMPLATE, "void", 0, "extra")
PRINT STRFMT(TEMPLATE, "roses", "red")
PRINT STRFMT(TEMPLATE, "violets", "blue")
PRINT STRFMT(TEMPLATE, "void", 0, "extra")
PRINTT STRCAT(STRFMT(STRFMT("%%%s.%d%s", "", 9, "f"), 3.14159), \
STRFMT(" ~ %s\n", STRFMT("%s%x", "thr", 238)))
PRINTLN STRCAT(STRFMT(STRFMT("%%%s.%d%s", "", 9, "f"), 3.14159), \
STRFMT(" ~ %s", STRFMT("%s%x", "thr", 238)))
PRINTT STRFMT("%d eol %", 1)
PRINTT "\n"
N = 1.23456
PRINTLN STRFMT("%.f -> %.3f -> %f", N, N, N)
PRINTT STRFMT("invalid %w spec\n", 42)
PRINTLN STRFMT("%d eol %", 1)
PRINTT STRFMT("one=%d two=%d three=%d\n", 1)
PRINTLN STRFMT("invalid %w spec", 42)
PRINTLN STRFMT("one=%d two=%d three=%d", 1)

View File

@@ -2,10 +2,10 @@ ERROR: strfmt.asm(14):
Formatting number as type 's'
ERROR: strfmt.asm(14):
STRFMT: 1 unformatted argument(s)
ERROR: strfmt.asm(19):
STRFMT: Illegal '%' at end of format string
ERROR: strfmt.asm(22):
STRFMT: Invalid format spec for argument 1
STRFMT: Illegal '%' at end of format string
ERROR: strfmt.asm(24):
STRFMT: Invalid format spec for argument 1
ERROR: strfmt.asm(26):
STRFMT: Not enough arguments for format spec
error: Assembly aborted (5 errors)!

View File

@@ -5,6 +5,7 @@ roses are red
violets are blue
void are 0
3.141586304 ~ three
1 -> 1.235 -> 1.23456
1 eol %
invalid % spec
one=1 two=% three=%

View File

@@ -4,13 +4,13 @@ f equ -123.0456
pi equ 3.14159
s equs "hello"
printt "<{ -6d:n}> <{+06u:n}> <{5x:n}> <{#16b:n}>\n"
printt "<{u:m}> <{+3d:m}> <{#016o:m}>\n"
printt "<{f:pi}> <{06f:f}> <{.10f:f}>\n"
printt "<{#-10s:s}> <{10s:s}>\n"
println "<{ -6d:n}> <{+06u:n}> <{5x:n}> <{#16b:n}>"
println "<{u:m}> <{+3d:m}> <{#016o:m}>"
println "<{f:pi}> <{06.f:f}> <{.10f:f}>"
println "<{#-10s:s}> <{10s:s}>"
foo: macro
printt "<{\1}>\n"
println "<{\1}>"
endm
foo -6d:n ; space is trimmed

View File

@@ -1,8 +1,7 @@
SECTION "sec", ROM0
xstrlen: MACRO
PRINTV STRLEN(\1)
PRINTT "\n"
PRINTLN STRLEN(\1)
ENDM
xstrlen "ABC"

View File

@@ -1,8 +1,7 @@
SECTION "sec", ROM0
xstrsub: MACRO
PRINTT STRSUB(\1, \2, \3)
PRINTT "\n"
PRINTLN STRSUB(\1, \2, \3)
ENDM
xstrsub "ABC", 1, 1

View File

@@ -1,14 +1,14 @@
warning: strsub.asm(13) -> strsub.asm::xstrsub(4): [-Wbuiltin-args]
warning: strsub.asm(12) -> strsub.asm::xstrsub(4): [-Wbuiltin-args]
STRSUB: Length too big: 32
warning: strsub.asm(13) -> strsub.asm::xstrsub(4): [-Wbuiltin-args]
STRSUB: Length too big: 300
warning: strsub.asm(14) -> strsub.asm::xstrsub(4): [-Wbuiltin-args]
STRSUB: Position starts at 1
warning: strsub.asm(14) -> strsub.asm::xstrsub(4): [-Wbuiltin-args]
STRSUB: Length too big: 300
warning: strsub.asm(15) -> strsub.asm::xstrsub(4): [-Wbuiltin-args]
STRSUB: Position starts at 1
warning: strsub.asm(15) -> strsub.asm::xstrsub(4): [-Wbuiltin-args]
STRSUB: Length too big: 300
warning: strsub.asm(17) -> strsub.asm::xstrsub(4): [-Wbuiltin-args]
warning: strsub.asm(16) -> strsub.asm::xstrsub(4): [-Wbuiltin-args]
STRSUB: Position 4 is past the end of the string
warning: strsub.asm(17) -> strsub.asm::xstrsub(4): [-Wbuiltin-args]
warning: strsub.asm(16) -> strsub.asm::xstrsub(4): [-Wbuiltin-args]
STRSUB: Length too big: 1
warning: strsub.asm(20) -> strsub.asm::xstrsub(4): [-Wbuiltin-args]
warning: strsub.asm(19) -> strsub.asm::xstrsub(4): [-Wbuiltin-args]
STRSUB: Length too big: 10

View File

@@ -1,4 +1,4 @@
foo equs strupr("xii")
bar equs strlwr("LOL")
printt "foo={foo} bar={bar}\n"
println "foo={foo} bar={bar}"

View File

@@ -20,15 +20,15 @@ zxfr: ds 1
; Completely by accident, but cool
PURGE dork
PRINTT "aqfj: {aqfj}\n"
PRINTT "cxje: {cxje}\n"
PRINTT "dgsd: {dgsd}\n"
PRINTT "dork: {dork}\n"
PRINTT "lxok: {lxok}\n"
PRINTT "psgp: {psgp}\n"
PRINTT "sfly: {sfly}\n"
PRINTT "syyq: {syyq}\n"
PRINTT "ussg: {ussg}\n"
PRINTT "xlmm: {xlmm}\n"
PRINTT "xtzp: {xtzp}\n"
PRINTT "zxfr: {zxfr}\n"
PRINTLN "aqfj: {aqfj}"
PRINTLN "cxje: {cxje}"
PRINTLN "dgsd: {dgsd}"
PRINTLN "dork: {dork}"
PRINTLN "lxok: {lxok}"
PRINTLN "psgp: {psgp}"
PRINTLN "sfly: {sfly}"
PRINTLN "syyq: {syyq}"
PRINTLN "ussg: {ussg}"
PRINTLN "xlmm: {xlmm}"
PRINTLN "xtzp: {xtzp}"
PRINTLN "zxfr: {zxfr}"

View File

@@ -1,6 +1,6 @@
V set 0
V set 1
PRINTT "V={V}\n"
PRINTLN "V={V}"
W equ 1
W set 0

View File

@@ -28,7 +28,7 @@ tryCmp () {
# Add the version constants test, outputting the closest tag to the HEAD
if git describe --tags --abbrev=0 > version.out; then
cat > version.asm <<EOF
PRINTT "v{d:__RGBDS_MAJOR__}.{d:__RGBDS_MINOR__}.{d:__RGBDS_PATCH__}\n"
PRINTLN "v{d:__RGBDS_MAJOR__}.{d:__RGBDS_MINOR__}.{d:__RGBDS_PATCH__}"
EOF
else
echo "${bold}${orange}Warning: cannot run version test!${rescolors}${resbold}"

View File

@@ -1,15 +1,15 @@
print EQUS "WARN \"\\@\""
warn_unique EQUS "WARN \"\\@\""
m: macro
print
warn_unique
REPT 2
print
warn_unique
ENDR
print
warn_unique
endm
; TODO: Ideally we'd test now as well, but it'd cause a fatal error
;print
;warn_unique
m
;print
;warn_unique
m
print
warn_unique

View File

@@ -16,4 +16,4 @@ warning: unique-id.asm(14) -> unique-id.asm::m(8): [-Wuser]
_u4
FATAL: unique-id.asm(15):
Macro argument '\@' not defined
while expanding symbol "print"
while expanding symbol "warn_unique"

View File

@@ -1,3 +1,2 @@
lab:
PRINTV lab-lab
PRINTT "\n"
PRINTLN lab-lab

View File

@@ -1,2 +1,2 @@
PRINTT /* // PRINTT "this is **comm //ented out\n" */ "this is not commented out\n"
PRINTT /*//*/ "this is not commented out\n"
PRINTLN /* // PRINT "this is **comm //ented out\n" */ "this is not commented out"
PRINTLN /*//*/ "this is not commented out"