From ebf1f12e97ac72a221140ac2c67c7535499edcad Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sun, 23 Jan 2022 17:24:39 +0100 Subject: [PATCH] inferred type for len() is now more precise --- .../compilerinterface/BuiltinFunctions.kt | 21 ++++++++++++++++--- docs/source/syntaxreference.rst | 1 + docs/source/todo.rst | 9 ++------ 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/compilerInterfaces/src/prog8/compilerinterface/BuiltinFunctions.kt b/compilerInterfaces/src/prog8/compilerinterface/BuiltinFunctions.kt index 2fc45e937..035f2f34e 100644 --- a/compilerInterfaces/src/prog8/compilerinterface/BuiltinFunctions.kt +++ b/compilerInterfaces/src/prog8/compilerinterface/BuiltinFunctions.kt @@ -233,9 +233,24 @@ fun builtinFunctionReturnType(function: String, args: List, program: } } "len" -> { - // a length can be >255 so in that case, the result is an UWORD instead of an UBYTE - // but to avoid a lot of code duplication we simply assume UWORD in all cases for now - return InferredTypes.knownFor(DataType.UWORD) + when(args.single().inferType(program).getOr(DataType.UNDEFINED)) { + in ArrayDatatypes -> { + val value = args.single() as? ArrayLiteralValue + if(value!=null) { + return if(value.value.size<256) InferredTypes.knownFor(DataType.UBYTE) else InferredTypes.knownFor(DataType.UWORD) + } else { + val targetVar = (args.single() as? IdentifierReference)?.targetVarDecl(program) + if (targetVar?.isArray == true) { + val length = targetVar.arraysize?.constIndex() + if(length!=null) + return if(length<256) InferredTypes.knownFor(DataType.UBYTE) else InferredTypes.knownFor(DataType.UWORD) + } + } + return InferredTypes.knownFor(DataType.UWORD) + } + DataType.STR -> return InferredTypes.knownFor(DataType.UBYTE) + else -> InferredTypes.unknown() + } } else -> return InferredTypes.unknown() } diff --git a/docs/source/syntaxreference.rst b/docs/source/syntaxreference.rst index 3c2054fa3..0edb554a1 100644 --- a/docs/source/syntaxreference.rst +++ b/docs/source/syntaxreference.rst @@ -441,6 +441,7 @@ String A string literal can occur with or without an encoding prefix (encoding followed by ':' followed by the string itself). When this is omitted, the string is stored in the machine's default character encoding (which is PETSCII on the CBM machines). You can choose to store the string in other encodings such as ``sc`` (screencodes) or ``iso`` (iso-8859-15). +String length is limited to 255 characters. Here are several examples: - ``"hello"`` a string translated into the default character encoding (PETSCII) diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 2ee775100..a5b3b84ca 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,16 +3,11 @@ TODO For next release ^^^^^^^^^^^^^^^^ -- Fix compiler stack overflow crash: +- BUGFIX RELEASE: Fix compiler stack overflow crash: sub sprite_y_for_row(ubyte row) -> word { return (8-row as byte) } -- Fix: better error message for len() in: - ubyte[64] chessboard - sub init() { - ubyte xx=len(board) - sys.memset(chessboard, len(board), 0) - } + - move vload() to cx16diskio module - nameInAssemblyCode() should search smarter - if char in "string" should fall back to string.find if string is longer than... 12?