mirror of
https://github.com/irmen/prog8.git
synced 2024-11-29 17:50:35 +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 {
|
||||
|
||||
%option no_symbol_prefixing, ignore_unused
|
||||
|
||||
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.
|
||||
; 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) {
|
||||
val targetDt = target.inferType(program)
|
||||
val valueDt = value.inferType(program)
|
||||
if(valueDt.isKnown && !(valueDt isAssignableTo targetDt)) {
|
||||
if(targetDt.isIterable)
|
||||
errors.err("cannot assign value to string or array", value.position)
|
||||
else if(!(valueDt.isString && targetDt issimpletype BaseDataType.UWORD)) {
|
||||
if(valueDt.isKnown && !(valueDt isAssignableTo targetDt) && !targetDt.isIterable) {
|
||||
if(!(valueDt issimpletype BaseDataType.STR && targetDt issimpletype BaseDataType.UWORD)) {
|
||||
if(targetDt.isUnknown) {
|
||||
if(target.identifier?.targetStatement(program)!=null)
|
||||
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) {
|
||||
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 {
|
||||
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)
|
||||
|
||||
if(targetType.isArray && valueType.isArray) {
|
||||
if (assignment.value is ArrayLiteral) {
|
||||
errors.err("cannot assign array literal here, use separate assignment per element", assignment.position)
|
||||
} else {
|
||||
return copyArrayValue(assignment)
|
||||
}
|
||||
checkCopyArrayValue(assignment)
|
||||
}
|
||||
|
||||
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
|
||||
return copyStringValue(assignment)
|
||||
}
|
||||
@ -250,18 +246,22 @@ internal class StatementReorderer(
|
||||
return noModifications
|
||||
}
|
||||
|
||||
private fun copyArrayValue(assign: Assignment): List<IAstModification> {
|
||||
private fun checkCopyArrayValue(assign: Assignment) {
|
||||
val identifier = assign.target.identifier!!
|
||||
val targetVar = identifier.targetVarDecl(program)!!
|
||||
|
||||
if(targetVar.arraysize==null) {
|
||||
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) {
|
||||
errors.err("invalid array value to assign to other array", assign.value.position)
|
||||
return noModifications
|
||||
return
|
||||
}
|
||||
val sourceIdent = assign.value as IdentifierReference
|
||||
val sourceVar = sourceIdent.targetVarDecl(program)!!
|
||||
@ -276,7 +276,6 @@ internal class StatementReorderer(
|
||||
errors.err("element size mismatch", assign.position)
|
||||
}
|
||||
}
|
||||
return noModifications
|
||||
}
|
||||
|
||||
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
|
||||
(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.
|
||||
Here are some examples of arrays::
|
||||
always have to be constants. Here are some examples of arrays::
|
||||
|
||||
byte[10] array ; array of 10 bytes, initially set to 0
|
||||
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)
|
||||
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)
|
||||
flags = [false, true] ; reset all flags in the array
|
||||
|
||||
.. note::
|
||||
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``
|
||||
for instance.
|
||||
|
||||
|
||||
It's possible to assign a new array to another array, this will overwrite all elements in the original
|
||||
array with those in the value array. The number and types of elements have to match.
|
||||
It's possible to assign an array to another array; this will overwrite all elements in the target
|
||||
array with those in the source array. The number and types of elements have to match for this to work!
|
||||
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,
|
||||
@ -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
|
||||
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
|
||||
for the three individual assignments with the same value 42.
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
Put palette fade to white / black in.
|
||||
|
||||
Regenerate skeleton doc files.
|
||||
|
||||
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
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- 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
|
||||
- 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?)
|
||||
|
@ -1,10 +1,30 @@
|
||||
%import textio
|
||||
%import string
|
||||
%zeropage basicsafe
|
||||
%option no_sysinit
|
||||
|
||||
main {
|
||||
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