mirror of
https://github.com/irmen/prog8.git
synced 2024-12-01 15:52:54 +00:00
Merge branch 'master' into next_compositetypes
# Conflicts: # compiler/src/prog8/compiler/astprocessing/AstChecker.kt # compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt # examples/test.p8
This commit is contained in:
commit
d217d4ab01
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
compression {
|
compression {
|
||||||
|
|
||||||
|
%option no_symbol_prefixing, ignore_unused
|
||||||
|
|
||||||
sub encode_rle_outfunc(uword data, uword size, uword output_function, bool is_last_block) {
|
sub encode_rle_outfunc(uword data, uword size, uword output_function, bool is_last_block) {
|
||||||
; -- Compress the given data block using ByteRun1 aka PackBits RLE encoding.
|
; -- Compress the given data block using ByteRun1 aka PackBits RLE encoding.
|
||||||
; output_function = address of a routine that gets a byte arg in A,
|
; output_function = address of a routine that gets a byte arg in A,
|
||||||
|
@ -551,10 +551,8 @@ internal class AstChecker(private val program: Program,
|
|||||||
fun checkType(target: AssignTarget, value: Expression, augmentable: Boolean) {
|
fun checkType(target: AssignTarget, value: Expression, augmentable: Boolean) {
|
||||||
val targetDt = target.inferType(program)
|
val targetDt = target.inferType(program)
|
||||||
val valueDt = value.inferType(program)
|
val valueDt = value.inferType(program)
|
||||||
if(valueDt.isKnown && !(valueDt isAssignableTo targetDt)) {
|
if(valueDt.isKnown && !(valueDt isAssignableTo targetDt) && !targetDt.isIterable) {
|
||||||
if(targetDt.isIterable)
|
if(!(valueDt issimpletype BaseDataType.STR && targetDt issimpletype BaseDataType.UWORD)) {
|
||||||
errors.err("cannot assign value to string or array", value.position)
|
|
||||||
else if(!(valueDt.isString && targetDt issimpletype BaseDataType.UWORD)) {
|
|
||||||
if(targetDt.isUnknown) {
|
if(targetDt.isUnknown) {
|
||||||
if(target.identifier?.targetStatement(program)!=null)
|
if(target.identifier?.targetStatement(program)!=null)
|
||||||
errors.err("target datatype is unknown", target.position)
|
errors.err("target datatype is unknown", target.position)
|
||||||
@ -1843,6 +1841,12 @@ internal class AstChecker(private val program: Program,
|
|||||||
else if(targetDatatype.isBool && !sourceDatatype.isBool) {
|
else if(targetDatatype.isBool && !sourceDatatype.isBool) {
|
||||||
errors.err("type of value $sourceDatatype doesn't match target $targetDatatype", position)
|
errors.err("type of value $sourceDatatype doesn't match target $targetDatatype", position)
|
||||||
}
|
}
|
||||||
|
else if(targetDatatype.isString) {
|
||||||
|
if(sourceDatatype.isUnsignedWord)
|
||||||
|
errors.err("can't assign UWORD to STR. If the source is a string and you actually want to overwrite the target string, use an explicit string.copy(src,tgt) instead.", position)
|
||||||
|
else
|
||||||
|
errors.err("type of value $sourceDatatype doesn't match target $targetDatatype", position)
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
errors.err("type of value $sourceDatatype doesn't match target $targetDatatype", position)
|
errors.err("type of value $sourceDatatype doesn't match target $targetDatatype", position)
|
||||||
}
|
}
|
||||||
|
@ -213,15 +213,11 @@ internal class StatementReorderer(
|
|||||||
val targetType = assignment.target.inferType(program)
|
val targetType = assignment.target.inferType(program)
|
||||||
|
|
||||||
if(targetType.isArray && valueType.isArray) {
|
if(targetType.isArray && valueType.isArray) {
|
||||||
if (assignment.value is ArrayLiteral) {
|
checkCopyArrayValue(assignment)
|
||||||
errors.err("cannot assign array literal here, use separate assignment per element", assignment.position)
|
|
||||||
} else {
|
|
||||||
return copyArrayValue(assignment)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!assignment.isAugmentable) {
|
if(!assignment.isAugmentable) {
|
||||||
if (valueType.isString && (targetType issimpletype BaseDataType.STR || targetType.isByteArray)) {
|
if (valueType issimpletype BaseDataType.STR && targetType issimpletype BaseDataType.STR) {
|
||||||
// replace string assignment by a call to stringcopy
|
// replace string assignment by a call to stringcopy
|
||||||
return copyStringValue(assignment)
|
return copyStringValue(assignment)
|
||||||
}
|
}
|
||||||
@ -250,18 +246,22 @@ internal class StatementReorderer(
|
|||||||
return noModifications
|
return noModifications
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun copyArrayValue(assign: Assignment): List<IAstModification> {
|
private fun checkCopyArrayValue(assign: Assignment) {
|
||||||
val identifier = assign.target.identifier!!
|
val identifier = assign.target.identifier!!
|
||||||
val targetVar = identifier.targetVarDecl(program)!!
|
val targetVar = identifier.targetVarDecl(program)!!
|
||||||
|
|
||||||
if(targetVar.arraysize==null) {
|
if(targetVar.arraysize==null) {
|
||||||
errors.err("array has no defined size", assign.position)
|
errors.err("array has no defined size", assign.position)
|
||||||
return noModifications
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if(assign.value is ArrayLiteral) {
|
||||||
|
return // invalid assignment of literals will be reported elsewhere
|
||||||
}
|
}
|
||||||
|
|
||||||
if(assign.value !is IdentifierReference) {
|
if(assign.value !is IdentifierReference) {
|
||||||
errors.err("invalid array value to assign to other array", assign.value.position)
|
errors.err("invalid array value to assign to other array", assign.value.position)
|
||||||
return noModifications
|
return
|
||||||
}
|
}
|
||||||
val sourceIdent = assign.value as IdentifierReference
|
val sourceIdent = assign.value as IdentifierReference
|
||||||
val sourceVar = sourceIdent.targetVarDecl(program)!!
|
val sourceVar = sourceIdent.targetVarDecl(program)!!
|
||||||
@ -276,7 +276,6 @@ internal class StatementReorderer(
|
|||||||
errors.err("element size mismatch", assign.position)
|
errors.err("element size mismatch", assign.position)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return noModifications
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun copyStringValue(assign: Assignment): List<IAstModification> {
|
private fun copyStringValue(assign: Assignment): List<IAstModification> {
|
||||||
|
@ -286,8 +286,7 @@ Arrays
|
|||||||
^^^^^^
|
^^^^^^
|
||||||
Array types are also supported. They can be formed from a list of booleans, bytes, words, floats, or addresses of other variables
|
Array types are also supported. They can be formed from a list of booleans, bytes, words, floats, or addresses of other variables
|
||||||
(such as explicit address-of expressions, strings, or other array variables) - values in an array literal
|
(such as explicit address-of expressions, strings, or other array variables) - values in an array literal
|
||||||
always have to be constants. Putting variables inside an array has to be done on a value-by-value basis.
|
always have to be constants. Here are some examples of arrays::
|
||||||
Here are some examples of arrays::
|
|
||||||
|
|
||||||
byte[10] array ; array of 10 bytes, initially set to 0
|
byte[10] array ; array of 10 bytes, initially set to 0
|
||||||
byte[] array = [1, 2, 3, 4] ; initialize the array, size taken from value
|
byte[] array = [1, 2, 3, 4] ; initialize the array, size taken from value
|
||||||
@ -300,6 +299,7 @@ Here are some examples of arrays::
|
|||||||
value = array[3] ; the fourth value in the array (index is 0-based)
|
value = array[3] ; the fourth value in the array (index is 0-based)
|
||||||
char = string[4] ; the fifth character (=byte) in the string
|
char = string[4] ; the fifth character (=byte) in the string
|
||||||
char = string[-2] ; the second-to-last character in the string (Python-style indexing from the end)
|
char = string[-2] ; the second-to-last character in the string (Python-style indexing from the end)
|
||||||
|
flags = [false, true] ; reset all flags in the array
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
Right now, the array should be small enough to be indexable by a single byte index.
|
Right now, the array should be small enough to be indexable by a single byte index.
|
||||||
@ -312,9 +312,8 @@ Note that the various keywords for the data type and variable type (``byte``, ``
|
|||||||
can't be used as *identifiers* elsewhere. You can't make a variable, block or subroutine with the name ``byte``
|
can't be used as *identifiers* elsewhere. You can't make a variable, block or subroutine with the name ``byte``
|
||||||
for instance.
|
for instance.
|
||||||
|
|
||||||
|
It's possible to assign an array to another array; this will overwrite all elements in the target
|
||||||
It's possible to assign a new array to another array, this will overwrite all elements in the original
|
array with those in the source array. The number and types of elements have to match for this to work!
|
||||||
array with those in the value array. The number and types of elements have to match.
|
|
||||||
For large arrays this is a slow operation because every element is copied over. It should probably be avoided.
|
For large arrays this is a slow operation because every element is copied over. It should probably be avoided.
|
||||||
|
|
||||||
Using the ``in`` operator you can easily check if a value is present in an array,
|
Using the ``in`` operator you can easily check if a value is present in an array,
|
||||||
@ -650,10 +649,6 @@ Assignment statements assign a single value to a target variable or memory locat
|
|||||||
Augmented assignments (such as ``aa += xx``) are also available, but these are just shorthands
|
Augmented assignments (such as ``aa += xx``) are also available, but these are just shorthands
|
||||||
for normal assignments (``aa = aa + xx``).
|
for normal assignments (``aa = aa + xx``).
|
||||||
|
|
||||||
Only variables of type byte, word and float can be assigned a new value.
|
|
||||||
It's not possible to set a new value to string or array variables etc, because they get allocated
|
|
||||||
a fixed amount of memory which will not change. (You *can* change the value of elements in a string or array though).
|
|
||||||
|
|
||||||
It is possible to "chain" assignments: ``x = y = z = 42``, this is just a shorthand
|
It is possible to "chain" assignments: ``x = y = z = 42``, this is just a shorthand
|
||||||
for the three individual assignments with the same value 42.
|
for the three individual assignments with the same value 42.
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
|
Put palette fade to white / black in.
|
||||||
|
|
||||||
Regenerate skeleton doc files.
|
Regenerate skeleton doc files.
|
||||||
|
|
||||||
Improve register load order in subroutine call args assignments:
|
Improve register load order in subroutine call args assignments:
|
||||||
@ -12,6 +14,7 @@ Maybe this routine can be made more intelligent. See usesOtherRegistersWhileEva
|
|||||||
Future Things and Ideas
|
Future Things and Ideas
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
- The string assignment footgun should be removed in favor of just calling string.copy explicitly. Get rid of sys.internal_stringcopy asm routine. Fix docs too.
|
||||||
- Improve the SublimeText syntax file for prog8, you can also install this for 'bat': https://github.com/sharkdp/bat?tab=readme-ov-file#adding-new-syntaxes--language-definitions
|
- Improve the SublimeText syntax file for prog8, you can also install this for 'bat': https://github.com/sharkdp/bat?tab=readme-ov-file#adding-new-syntaxes--language-definitions
|
||||||
- Can we support signed % (remainder) somehow?
|
- Can we support signed % (remainder) somehow?
|
||||||
- Don't add "random" rts to %asm blocks but instead give a warning about it? (but this breaks existing behavior that others already depend on... command line switch? block directive?)
|
- Don't add "random" rts to %asm blocks but instead give a warning about it? (but this breaks existing behavior that others already depend on... command line switch? block directive?)
|
||||||
|
@ -1,10 +1,30 @@
|
|||||||
%import textio
|
%import textio
|
||||||
|
%import string
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
%option no_sysinit
|
|
||||||
|
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
txt.print("hello")
|
str name1 = "irmen"
|
||||||
|
str name2 = "other"
|
||||||
|
bool[2] flags = [true, false]
|
||||||
|
|
||||||
|
txt.print(name1)
|
||||||
|
txt.nl()
|
||||||
|
name1 = name2
|
||||||
|
txt.print(name1)
|
||||||
|
txt.nl()
|
||||||
|
flags = [false, true]
|
||||||
|
|
||||||
|
ubyte[10] array
|
||||||
|
ubyte[10] array2
|
||||||
|
|
||||||
|
void string.copy(name2, name1)
|
||||||
|
array = array2
|
||||||
|
name2 = "zzz"
|
||||||
|
array = [1,2,3,4,5,6,7,8,9,10]
|
||||||
|
;; array = cx16.r0
|
||||||
|
;; array = name1
|
||||||
|
;; name1 = array
|
||||||
|
;; name1 = cx16.r0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user