allow sizeof(&thing), add sys.SIZEOF_POINTER

This commit is contained in:
Irmen de Jong
2025-05-29 15:58:29 +02:00
parent 33b3a1664c
commit 112ca3cc53
14 changed files with 29 additions and 9 deletions

View File

@@ -101,7 +101,7 @@ val BuiltinFunctions: Map<String, FSignature> = mapOf(
"abs__word" to FSignature(true, BaseDataType.UWORD, FParam("value", BaseDataType.WORD)),
"abs__float" to FSignature(true, BaseDataType.FLOAT, FParam("value", BaseDataType.FLOAT)),
"len" to FSignature(true, BaseDataType.UWORD, FParam("values", *IterableDatatypes)),
"sizeof" to FSignature(true, BaseDataType.UBYTE, FParam("object", *BaseDataType.entries.toTypedArray())),
"sizeof" to FSignature(true, BaseDataType.UBYTE, FParam("object", *(BaseDataType.entries - BaseDataType.STRUCT_INSTANCE).toTypedArray())),
"sgn" to FSignature(true, BaseDataType.BYTE, FParam("value", *NumericDatatypes)),
"sqrt" to FSignature(true, null, FParam("value", *NumericDatatypes)),
"sqrt__ubyte" to FSignature(true, BaseDataType.UBYTE, FParam("value", BaseDataType.UBYTE)),

View File

@@ -48,6 +48,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
"prog8_lib_square_byte" -> funcSquare(call, IRDataType.BYTE)
"prog8_lib_square_word" -> funcSquare(call, IRDataType.WORD)
"structalloc" -> funcStructAlloc(call)
"sizeof" -> throw AssemblyError("sizeof must have been replaced with a constant")
else -> throw AssemblyError("missing builtinfunc for ${call.name}")
}
}

View File

@@ -425,6 +425,7 @@ sys {
const ubyte SIZEOF_WORD = sizeof(word)
const ubyte SIZEOF_UWORD = sizeof(uword)
const ubyte SIZEOF_LONG = sizeof(long)
const ubyte SIZEOF_POINTER = sizeof(&sys.wait)
const ubyte SIZEOF_FLOAT = sizeof(float)
const byte MIN_BYTE = -128
const byte MAX_BYTE = 127

View File

@@ -445,6 +445,7 @@ sys {
const ubyte SIZEOF_WORD = sizeof(word)
const ubyte SIZEOF_UWORD = sizeof(uword)
const ubyte SIZEOF_LONG = sizeof(long)
const ubyte SIZEOF_POINTER = sizeof(&sys.wait)
const ubyte SIZEOF_FLOAT = sizeof(float)
const byte MIN_BYTE = -128
const byte MAX_BYTE = 127

View File

@@ -1521,6 +1521,7 @@ sys {
const ubyte SIZEOF_WORD = sizeof(word)
const ubyte SIZEOF_UWORD = sizeof(uword)
const ubyte SIZEOF_LONG = sizeof(long)
const ubyte SIZEOF_POINTER = sizeof(&sys.wait)
const ubyte SIZEOF_FLOAT = sizeof(float)
const byte MIN_BYTE = -128
const byte MAX_BYTE = 127

View File

@@ -104,6 +104,7 @@ sys {
const ubyte SIZEOF_WORD = sizeof(word)
const ubyte SIZEOF_UWORD = sizeof(uword)
const ubyte SIZEOF_LONG = sizeof(long)
const ubyte SIZEOF_POINTER = sizeof(&sys.wait)
const ubyte SIZEOF_FLOAT = sizeof(float)
const byte MIN_BYTE = -128
const byte MAX_BYTE = 127

View File

@@ -13,6 +13,7 @@ sys {
const ubyte SIZEOF_WORD = sizeof(word)
const ubyte SIZEOF_UWORD = sizeof(uword)
const ubyte SIZEOF_LONG = sizeof(long)
const ubyte SIZEOF_POINTER = sizeof(&sys.wait)
const ubyte SIZEOF_FLOAT = sizeof(float)
const byte MIN_BYTE = -128
const byte MAX_BYTE = 127

View File

@@ -94,16 +94,16 @@ private fun builtinSizeof(args: List<Expression>, position: Position, program: P
// 1 arg, type = anything, result type = ubyte or uword
if(args.size!=1)
throw SyntaxError("sizeof requires one argument", position)
if(args[0] !is IdentifierReference && args[0] !is NumericLiteral)
if(args[0] !is IdentifierReference && args[0] !is NumericLiteral && args[0] !is AddressOf)
throw CannotEvaluateException("sizeof","argument should be an identifier, number, or type name")
val dt = args[0].inferType(program)
if(dt.isKnown) {
if(args[0] is NumericLiteral)
if(args[0] is NumericLiteral || args[0] is AddressOf)
return NumericLiteral.optimalInteger(program.memsizer.memorySize(dt.getOrUndef(), null), position)
val target = (args[0] as IdentifierReference).targetStatement()
?: throw CannotEvaluateException("sizeof", "no target")
val target = (args[0] as? IdentifierReference)?.targetStatement()
?: throw SyntaxError("wrong argument type", position)
return when {
dt.isArray -> {
@@ -112,7 +112,7 @@ private fun builtinSizeof(args: List<Expression>, position: Position, program: P
NumericLiteral.optimalInteger(program.memsizer.memorySize(elementDt, length), position)
}
dt.isString -> throw SyntaxError("sizeof(str) is undefined, did you mean len, or perhaps strings.length?", position)
else -> NumericLiteral(BaseDataType.UBYTE, program.memsizer.memorySize(dt.getOrUndef(), null).toDouble(), position)
else -> NumericLiteral.optimalInteger( program.memsizer.memorySize(dt.getOrUndef(), null), position)
}
} else {
val identifier = args[0] as? IdentifierReference

View File

@@ -288,6 +288,8 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val
it.possibleDatatypes.map { dt ->
if(dt.isArray)
DataType.arrayFor(BaseDataType.BOOL, false) // the builtin function signature doesn't tell us the element type....
else if(dt.isPointer)
DataType.pointer(BaseDataType.UBYTE)
else
DataType.forDt(dt)
}

View File

@@ -1087,6 +1087,8 @@ main {
ub2 = sys.SIZEOF_WORD
ub1 = sys.SIZEOF_LONG
ub2 = sys.SIZEOF_FLOAT
ub1 = sys.SIZEOF_POINTER
ub2 = sys.SIZEOF_UBYTE
ub1 = sizeof(true)
ub2 = sizeof(1234)
@@ -1108,6 +1110,9 @@ main {
ub2 = sizeof(float)
ub1 = sizeof(List)
ub2 = sizeof(main.start.List)
ub1 = sizeof(&w)
;; TODO ub1 = sizeof(^^float)
;; TODO ub2 = sizeof(^^List)
}
@@ -1115,7 +1120,7 @@ main {
val result = compileText(VMTarget(), false, src, outputDir, writeAssembly = false)!!
val st = result.compilerAst.entrypoint.statements
st.size shouldBe 38
st.size shouldBe 41
val assignments = st.drop(14).dropLast(1)
assignments.all { it is Assignment } shouldBe true
assignments.forEach { a ->

View File

@@ -57,12 +57,12 @@ STRUCTS and TYPED POINTERS
- DONE: fix _msb/_lsb storage of the split-words pointer-arrays
- DONE: what about static initialization of an array of struct pointers? -> impossible right now because the pointer values are not constants.
- DONE: make typeForAddressOf() be even more specific about the typed pointers it returns for the address-of operator.
- make sizeof(^^type) parse correctly
- allow list1^^ = list2^^ (value wise assignment of List structures) by replacing it with a sys.memcopy(list2, list1, sizeof(List)) call.
- add unit tests for expected AST elements for all syntaxes dealing with pointers, dereference(chain), derefs, and indexing (both as value and assigntargets)
- fix parse error "barray[2]^^" where barray is ^^bool[10]
- add unit tests for all changes (pointers and structs)
- try to fix parse error l1^^.s[0] = 4242 (equivalent to l1.s[0]=4242 , which does parse correctly)
- try to make sizeof(^^type) parse correctly (or maybe replace it immediately with sys.SIZEOF_POINTER)
- 6502 codegen: remove checks in checkForPointerTypesOn6502()
- 6502 codegen should warn about writing to initialized struct instances when using romable code, like with arrays "can only be used as read-only in ROMable code"
- 6502 asm symbol name prefixing should work for dereferences too.

View File

@@ -29,6 +29,7 @@ sys {
const ubyte SIZEOF_WORD = sizeof(word)
const ubyte SIZEOF_UWORD = sizeof(uword)
const ubyte SIZEOF_LONG = sizeof(long)
const ubyte SIZEOF_POINTER = sizeof(&sys.wait)
const ubyte SIZEOF_FLOAT = 0 ; undefined, no floats supported
const byte MIN_BYTE = -128
const byte MAX_BYTE = 127

View File

@@ -21,6 +21,7 @@ sys {
const ubyte SIZEOF_WORD = sizeof(word)
const ubyte SIZEOF_UWORD = sizeof(uword)
const ubyte SIZEOF_LONG = sizeof(long)
const ubyte SIZEOF_POINTER = sizeof(&sys.wait)
const ubyte SIZEOF_FLOAT = 0 ; undefined, no floats supported
const byte MIN_BYTE = -128
const byte MAX_BYTE = 127

View File

@@ -22,6 +22,8 @@ main {
txt.spc()
txt.print_ub(sys.SIZEOF_WORD)
txt.spc()
txt.print_ub(sys.SIZEOF_POINTER)
txt.spc()
txt.print_ub(sys.SIZEOF_LONG)
txt.spc()
txt.print_ub(sys.SIZEOF_FLOAT)
@@ -59,11 +61,14 @@ main {
txt.spc()
txt.print_ub(sizeof(float))
txt.spc()
txt.print_ub(sizeof(List))
txt.spc()
txt.print_ub(sizeof(&w))
txt.spc()
; txt.print_ub(sizeof(^^float)) ; TODO parse this
; txt.spc()
; txt.print_ub(sizeof(^^List)) ; TODO parse this
; txt.spc()
txt.print_ub(sizeof(List))
txt.nl()
}
}