removed the ".w" word suffix (it confused the parser).

This commit is contained in:
Irmen de Jong 2020-09-19 23:23:32 +02:00
parent ce9a90f626
commit dfa1d5e398
8 changed files with 61 additions and 18 deletions

View File

@ -566,4 +566,22 @@ asmsub plot (ubyte col @ Y, ubyte row @ A) clobbers(A) {
}}
}
asmsub width() clobbers(X,Y) -> ubyte @A {
; -- returns the text screen width (number of columns)
%asm {{
jsr c64.SCREEN
txa
rts
}}
}
asmsub height() clobbers(X, Y) -> ubyte @A {
; -- returns the text screen height (number of rows)
%asm {{
jsr c64.SCREEN
tya
rts
}}
}
}

View File

@ -15,7 +15,6 @@ sub clear_screen() {
c64.CHROUT(147) ; clear screen (spaces)
}
asmsub fill_screen (ubyte char @ A, ubyte txtcolor @ Y) clobbers(A) {
; ---- fill the character screen with the given fill character and character color.
; TODO this can be done more efficiently with the VERA auto increment mode?
@ -105,6 +104,7 @@ sub uppercase() {
cx16.screen_set_charset(2, 0) ; uppercase charset
}
; TODO implement clear_screencolors
; TODO implement the "missing" txtio scroll subroutines: scroll_left_full, (also right, up, down)
romsub $FFD2 = chrout(ubyte char @ A) ; for consistency. You can also use c64.CHROUT directly ofcourse.
@ -429,4 +429,22 @@ asmsub plot (ubyte col @ Y, ubyte row @ A) clobbers(A) {
}}
}
asmsub width() clobbers(X,Y) -> ubyte @A {
; -- returns the text screen width (number of columns)
%asm {{
jsr c64.SCREEN
txa
rts
}}
}
asmsub height() clobbers(X, Y) -> ubyte @A {
; -- returns the text screen height (number of rows)
%asm {{
jsr c64.SCREEN
tya
rts
}}
}
}

View File

@ -397,7 +397,7 @@ private fun prog8Parser.DirectiveargContext.toAst() : DirectiveArg {
}
private fun prog8Parser.IntegerliteralContext.toAst(): NumericLiteral {
fun makeLiteral(text: String, radix: Int, forceWord: Boolean): NumericLiteral {
fun makeLiteral(text: String, radix: Int): NumericLiteral {
val integer: Int
var datatype = DataType.UBYTE
when (radix) {
@ -435,14 +435,14 @@ private fun prog8Parser.IntegerliteralContext.toAst(): NumericLiteral {
}
else -> throw FatalAstException("invalid radix")
}
return NumericLiteral(integer, if (forceWord) DataType.UWORD else datatype)
return NumericLiteral(integer, datatype)
}
val terminal: TerminalNode = children[0] as TerminalNode
val integerPart = this.intpart.text
return when (terminal.symbol.type) {
prog8Parser.DEC_INTEGER -> makeLiteral(integerPart, 10, wordsuffix()!=null)
prog8Parser.HEX_INTEGER -> makeLiteral(integerPart.substring(1), 16, wordsuffix()!=null)
prog8Parser.BIN_INTEGER -> makeLiteral(integerPart.substring(1), 2, wordsuffix()!=null)
prog8Parser.DEC_INTEGER -> makeLiteral(integerPart, 10)
prog8Parser.HEX_INTEGER -> makeLiteral(integerPart.substring(1), 16)
prog8Parser.BIN_INTEGER -> makeLiteral(integerPart.substring(1), 2)
else -> throw FatalAstException(terminal.text)
}
}

View File

@ -578,25 +578,24 @@ within parentheses will be evaluated first. So ``(4 + 8) * 2`` is 24 and not 20,
and ``(true or false) and false`` is false instead of true.
.. attention::
**calculations keep their datatype:**
**calculations keep their datatype even if the target variable is larger:**
When you do calculations on a BYTE type, the result will remain a BYTE.
When you do calculations on a WORD type, the result will remain a WORD.
For instance::
byte b = 44
word w = b*55 ; the result will be 116! (even though the target variable is a word)
w *= 999 ; the result will be -15188 (the multiplication stays within a word)
w *= 999 ; the result will be -15188 (the multiplication stays within a word, but overflows)
The compiler will NOT give a warning about this! It's doing this for
*The compiler does NOT warn about this!* It's doing this for
performance reasons - so you won't get sudden 16 bit (or even float)
calculations where you needed only simple fast byte arithmetic.
If you do need the extended resulting value, cast at least one of the
operands of an operator to the larger datatype. For example::
operands explicitly to the larger datatype. For example::
byte b = 44
word w = b*55.w ; the result will be 2420
w = (b as word)*55 ; same result
w = (b as word)*55
w = b*(55 as word)

View File

@ -297,7 +297,8 @@ of something with an operand starting with 1 or 0, you'll have to add a space in
- When an integer value ranges from 256..65535 the compiler sees it as a ``uword``. For -32768..32767 it's a ``word``.
- When a hex number has 3 or 4 digits, for example ``$0004``, it is seen as a ``word`` otherwise as a ``byte``.
- When a binary number has 9 to 16 digits, for example ``%1100110011``, it is seen as a ``word`` otherwise as a ``byte``.
- You can force a byte value into a word value by adding the ``.w`` datatype suffix to the number: ``$2a.w`` is equivalent to ``$002a``.
- If the number fits in a byte but you really require it as a word value, you'll have to explicitly cast it: ``60 as uword``
or you can use the full word hexadecimal notation ``$003c``.
Data type conversion

View File

@ -104,7 +104,7 @@ main {
b |= bittab[ii]
}
}
@(CHARSET + i + c*8.w) = b
@(CHARSET + i + c*$0008) = b
}
}
}

View File

@ -14,6 +14,10 @@ main {
txt.lowercase()
txt.print("Hello there")
uword ww
ubyte bb=44
ww = bb*($0032)
txt.print_uw(ww)
txt.setchr(5, 5, '*')
txt.setchr(6, 5, '*')
@ -51,5 +55,10 @@ main {
txt.print_ub(txt.getclr(8,5))
txt.chrout('\n')
txt.print("width:")
txt.print_ub(txt.width())
txt.print(" height:")
txt.print_ub(txt.height())
}
}

View File

@ -217,9 +217,7 @@ identifier : NAME ;
scoped_identifier : NAME ('.' NAME)* ;
integerliteral : intpart=(DEC_INTEGER | HEX_INTEGER | BIN_INTEGER) wordsuffix? ;
wordsuffix : '.w' ;
integerliteral : intpart=(DEC_INTEGER | HEX_INTEGER | BIN_INTEGER) ;
booleanliteral : 'true' | 'false' ;