mirror of
				https://github.com/irmen/prog8.git
				synced 2025-10-31 00:16:08 +00:00 
			
		
		
		
	fixing alias bugs
This commit is contained in:
		| @@ -210,6 +210,12 @@ class AstPreprocessor(val program: Program, | ||||
|                 decl.datatype.setActualSubType(node) | ||||
|             } else if(antlrTypeName.size==1 && antlrTypeName[0] in program.builtinFunctions.names) { | ||||
|                 errors.err("builtin function can only be called, not used as a type name", decl.position) | ||||
|             } else if(node is Alias) { | ||||
|                 val actual = decl.definingScope.lookup(node.target.nameInSource) | ||||
|                 if(actual is StructDecl) | ||||
|                     decl.datatype.setActualSubType(actual) | ||||
|                 else if(actual==null) | ||||
|                     errors.err("cannot find struct type ${node.target.nameInSource.joinToString(".")}", decl.position) | ||||
|             } | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -530,7 +530,7 @@ _after: | ||||
|                 var struct = firstDt.subType | ||||
|                 for(name in identifier.nameInSource.drop(1)) { | ||||
|                     if(struct==null) { | ||||
|                         errors.err("unknown field '${name}", position = identifier.position) | ||||
|                         errors.err("unknown field '${name}'", position = identifier.position) | ||||
|                         return noModifications | ||||
|                     } | ||||
|                     val fieldDt = struct.getFieldType(name) | ||||
|   | ||||
| @@ -148,6 +148,15 @@ internal class LiteralsToAutoVarsAndRecombineIdentifiers(private val program: Pr | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if(target==null && identifier.nameInSource.size>1) { | ||||
|             // maybe the first component of the scoped name is an alias? | ||||
|             val tgt2 = identifier.definingScope.lookup(identifier.nameInSource.take(1)) as? Alias | ||||
|             if(tgt2!=null && parent !is Alias) { | ||||
|                 if(tgt2.target.targetStatement() !is Alias) | ||||
|                     return listOf(IAstModification.ReplaceNode(identifier, tgt2.target.copy(position = identifier.position), parent)) | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // don't replace an identifier in an Alias or when the alias points to another alias (that will be resolved first elsewhere) | ||||
|         if(target is Alias && parent !is Alias) { | ||||
|             if(target.target.targetStatement() !is Alias) | ||||
|   | ||||
| @@ -2349,4 +2349,40 @@ main { | ||||
|         compileText(C64Target(), false, src, outputDir) shouldNotBe null | ||||
|     } | ||||
|  | ||||
|     test("struct and pointer aliasing") { | ||||
|         val src=""" | ||||
| main { | ||||
|     sub start() { | ||||
|         alias1() | ||||
|         alias2() | ||||
|         alias3() | ||||
|     } | ||||
|  | ||||
|     sub alias1() { | ||||
|         alias TheNode = structdefs.Node | ||||
|         ^^TheNode node = 20000 | ||||
|         node.value = 100        ; TODO fix unknown field 'value' | ||||
|     } | ||||
|  | ||||
|     sub alias2() { | ||||
|         ^^structdefs.Node node = 20000 | ||||
|         alias thing = node | ||||
|         thing.value=200         ; TODO fix undefined symbol: thing.value | ||||
|     } | ||||
|  | ||||
|     sub alias3() { | ||||
|         alias TheNode = structdefs.Node | ||||
|         ^^TheNode node = 20000 | ||||
|         node++      ;; TODO fix compiler crash Key POINTER is missing in the map | ||||
|     } | ||||
| } | ||||
|  | ||||
| structdefs { | ||||
|     struct Node { | ||||
|         ubyte value | ||||
|     } | ||||
| }""" | ||||
|  | ||||
|         compileText(VMTarget(), false, src, outputDir) shouldNotBe null | ||||
|     } | ||||
| }) | ||||
| @@ -56,6 +56,15 @@ main { | ||||
| STRUCTS and TYPED POINTERS (6502 codegen specific) | ||||
| -------------------------------------------------- | ||||
|  | ||||
| - Bugs: | ||||
|         ;node2.type = 10     ;; TODO: fix undefined symbol error | ||||
|         ;^^StructAlias node3 = 30000 | ||||
|         ; node3.type = 10     ;; TODO: fix "unknown field 'type"  error | ||||
|  | ||||
|         ^^OtherNodeAlias other = 20000 | ||||
|         other++         ;; TODO fix compiler crash Key POINTER is missing in the map | ||||
|  | ||||
|  | ||||
| - in CodeDesugarer there is support for ptr1[idx]^^ = ptr2^^  into memcopy() but it doesn't seem to trigger? | ||||
|  | ||||
| - allow struct initialization syntax in an array such as [ Node(), Node(), Node() ],  update sorting example to use list of countries like that | ||||
|   | ||||
							
								
								
									
										120
									
								
								examples/test.p8
									
									
									
									
									
								
							
							
						
						
									
										120
									
								
								examples/test.p8
									
									
									
									
									
								
							| @@ -1,61 +1,81 @@ | ||||
| %import textio | ||||
| %zeropage basicsafe | ||||
|  | ||||
|  | ||||
| main { | ||||
|     struct Ptr { | ||||
|         word value | ||||
|         byte bvalue | ||||
|     } | ||||
|  | ||||
|     sub start() { | ||||
|         ^^Ptr pp = Ptr() | ||||
|         uword @nozp plainptr = &pp.bvalue | ||||
|         pp.value = -999 | ||||
|         pp.bvalue = -99 | ||||
|         txt.print_w(clamp(pp.value, 10, 2000)) | ||||
|         txt.spc() | ||||
|         txt.print_b(clamp(pp.bvalue, 10, 100)) | ||||
|         txt.spc() | ||||
|         pp.bvalue = 5 | ||||
|         txt.print_ub(clamp(plainptr[0], 10, 100)) | ||||
|         txt.nl() | ||||
|  | ||||
|         pp.value = 5000 | ||||
|         pp.bvalue = 120 | ||||
|         txt.print_w(clamp(pp.value, 10, 2000)) | ||||
|         txt.spc() | ||||
|         txt.print_b(clamp(pp.bvalue, 10, 100)) | ||||
|         txt.spc() | ||||
|         pp.bvalue = 120 | ||||
|         txt.print_ub(clamp(plainptr[0], 10, 100)) | ||||
|         txt.nl() | ||||
|  | ||||
|         pp.value = 1234 | ||||
|         pp.bvalue = 66 | ||||
|         txt.print_w(clamp(pp.value, 10, 2000)) | ||||
|         txt.spc() | ||||
|         txt.print_b(clamp(pp.bvalue, 10, 100)) | ||||
|         txt.spc() | ||||
|         pp.bvalue = 66 | ||||
|         txt.print_ub(clamp(plainptr[0], 10, 100)) | ||||
|         txt.nl() | ||||
|         alias derp = structdefs.normal | ||||
|         derp ++ | ||||
|         alias1() | ||||
|         alias2() | ||||
|         alias3() | ||||
|     } | ||||
|  | ||||
|     sub alias1() { | ||||
|         alias TheNode = structdefs.Node | ||||
|         ^^TheNode node = 20000 | ||||
|         node.value = 100 | ||||
|     } | ||||
|  | ||||
| ;%import floats | ||||
|     sub alias2() { | ||||
|         ^^structdefs.Node node = 20000 | ||||
|         alias thing = node | ||||
|         thing.value=200 | ||||
|     } | ||||
|  | ||||
|     sub alias3() { | ||||
|         alias TheNode = structdefs.Node | ||||
|         ^^TheNode node = 20000 | ||||
|         node++ | ||||
|     } | ||||
| } | ||||
|  | ||||
| structdefs { | ||||
|     struct Node { | ||||
|         ubyte value | ||||
|     } | ||||
|  | ||||
|     ubyte @shared normal | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| ; | ||||
| ;%import textio | ||||
| ;%zeropage kernalsafe | ||||
| ; | ||||
| ; | ||||
| ;main { | ||||
| ;    struct Node { | ||||
| ;        ubyte type, frame, framecounter | ||||
| ;    } | ||||
| ; | ||||
| ; | ||||
| ;    sub start() { | ||||
| ;        struct List { | ||||
| ;            uword s | ||||
| ;            float fl | ||||
| ;            uword n | ||||
| ;        } | ||||
| ;        ^^List  l = List() | ||||
| ;        l.n[cx16.r0L] = 99 | ||||
| ;;        l.s[cx16.r0L+2] = 42 | ||||
| ;;        l.n[cx16.r0L+2] = 99 | ||||
| ;        ^^Node storageElementBuffer = 20000 | ||||
| ;        ^^Node t_element = 30000 | ||||
| ; | ||||
| ;        alias node2 = t_element | ||||
| ;        alias StructAlias = Node | ||||
| ;        alias OtherNodeAlias = structdefs.OtherNode | ||||
| ; | ||||
| ;        ;node2.type = 10     ;; TODO: fix undefined symbol error | ||||
| ;        ;^^StructAlias node3 = 30000 | ||||
| ;        ; node3.type = 10     ;; TODO: fix "unknown field 'type"  error | ||||
| ; | ||||
| ;        ^^OtherNodeAlias other = 20000 | ||||
| ;        other++         ;; TODO fix compiler crash Key POINTER is missing in the map | ||||
| ; | ||||
| ; | ||||
| ;        ubyte @shared i = 0 | ||||
| ;        storageElementBuffer[0] = t_element^^ | ||||
| ;        storageElementBuffer[0] = t_element^^ | ||||
| ;        storageElementBuffer[1] = t_element^^ | ||||
| ;        storageElementBuffer[2] = t_element^^ | ||||
| ;        storageElementBuffer[i] = t_element^^ | ||||
| ;        ;storageElementBuffer[10]^^ = t_element^^        ; TODO support this with memcopy it's the same as the one above | ||||
| ;        ;storageElementBuffer[i]^^ = t_element^^ | ||||
| ;    } | ||||
| ;} | ||||
| ; | ||||
| ;structdefs { | ||||
| ;    struct OtherNode { | ||||
| ;        ubyte type, frame, framecounter | ||||
| ;    } | ||||
| ;} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user