mirror of
https://github.com/irmen/prog8.git
synced 2025-11-03 04:17:16 +00:00
allow sizeof(&thing), add sys.SIZEOF_POINTER
This commit is contained in:
@@ -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)),
|
||||
|
||||
@@ -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}")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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 ->
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user