From 5a82f672b5d71cbcf7405a0a7a010e51858a23b9 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Thu, 19 Feb 2026 12:16:46 +0100 Subject: [PATCH] Update to constdef --- lib/std/compression/qoi.c3 | 4 +- lib/std/core/ansi.c3 | 2 +- lib/std/hash/blake3.c3 | 2 +- lib/std/hash/gost/streebog.c3 | 2 +- lib/std/libc/os/posix.c3 | 20 +++---- lib/std/net/socket.c3 | 4 +- lib/std/os/linux/epoll.c3 | 2 +- lib/std/os/macos/core_foundation.c3 | 2 +- lib/std/os/macos/general.c3 | 4 +- lib/std/os/macos/objc.c3 | 22 +++---- lib/std/os/win32/console.c3 | 2 +- lib/std/os/win32/memoryapi.c3 | 6 +- lib/std/os/win32/winnt.c3 | 2 +- releasenotes.md | 6 +- resources/examples/opengl/src/gl/gl.c3 | 10 ++-- .../raylib/raylib_2d_camera_platformer.c3 | 10 ++-- resources/examples/raylib/raylib_snake.c3 | 8 +-- scripts/tools/ci_tests.sh | 57 ++++++++++--------- src/compiler/ast.c | 6 +- src/compiler/compiler_internal.h | 14 ++--- src/compiler/context.c | 4 +- src/compiler/copying.c | 2 +- src/compiler/enums.h | 4 +- src/compiler/json_output.c | 2 +- src/compiler/llvm_codegen.c | 4 +- src/compiler/llvm_codegen_type.c | 2 +- src/compiler/parse_global.c | 56 ++++++++---------- src/compiler/parse_stmt.c | 2 +- src/compiler/sema_casts.c | 4 +- src/compiler/sema_decls.c | 26 ++++----- src/compiler/sema_expr.c | 26 ++++++--- src/compiler/sema_liveness.c | 2 +- src/compiler/sema_types.c | 2 +- src/compiler/semantic_analyser.c | 2 +- src/compiler/tokens.c | 4 +- src/compiler/types.c | 4 +- .../any/generic_interface_stage.c3t | 2 +- test/test_suite/enumerations/const_enum.c3 | 2 +- .../enumerations/const_enum_inline.c3t | 2 +- .../enumerations/const_enum_inline_member.c3t | 2 +- .../enumerations/const_enum_methods.c3t | 2 +- .../enumerations/const_enum_self_ref.c3 | 4 +- .../enumerations/const_enum_vector.c3t | 2 +- .../const_enum_with_function_ptr.c3t | 2 +- test/test_suite/enumerations/enum_const.c3t | 8 +-- .../enum_const_inline_interface.c3 | 2 +- .../enum_const_resolution_order.c3t | 2 +- .../enumerations/enum_no_inline_property.c3 | 2 +- .../enumerations/recursive_const_enum.c3 | 2 +- .../casts/inline_to_underlying.c3t | 2 +- test/unit/stdlib/collections/linked_map.c3 | 2 +- test/unit/stdlib/collections/map.c3 | 2 +- 52 files changed, 189 insertions(+), 182 deletions(-) diff --git a/lib/std/compression/qoi.c3 b/lib/std/compression/qoi.c3 index a3153de6f..dc6f57efd 100644 --- a/lib/std/compression/qoi.c3 +++ b/lib/std/compression/qoi.c3 @@ -7,7 +7,7 @@ const uint PIXELS_MAX = 400000000; Purely informative. It will be saved to the file header, but does not affect how chunks are en-/decoded. *> -const enum QOIColorspace : char +constdef QOIColorspace : char { <* sRGB with linear alpha *> SRGB = 0, @@ -21,7 +21,7 @@ const enum QOIColorspace : char AUTO can be used when decoding to automatically determine the channels from the file's header. *> -const enum QOIChannels : inline char +constdef QOIChannels : inline char { AUTO = 0, RGB = 3, diff --git a/lib/std/core/ansi.c3 b/lib/std/core/ansi.c3 index a10870b41..b0d69964c 100644 --- a/lib/std/core/ansi.c3 +++ b/lib/std/core/ansi.c3 @@ -1,7 +1,7 @@ module std::core::string::ansi; import std::io; -const enum Ansi : inline String +constdef Ansi : inline String { RESET = "\e[0m", BOLD = "\e[1m", diff --git a/lib/std/hash/blake3.c3 b/lib/std/hash/blake3.c3 index 5cfe4f357..f0fb0ab19 100644 --- a/lib/std/hash/blake3.c3 +++ b/lib/std/hash/blake3.c3 @@ -91,7 +91,7 @@ macro @simd_degree() @local } <* Flags used during hash computation based on its state. *> -const enum Blake3Flags : inline char +constdef Blake3Flags : inline char { CHUNK_START = 1 << 0, CHUNK_END = 1 << 1, diff --git a/lib/std/hash/gost/streebog.c3 b/lib/std/hash/gost/streebog.c3 index 27a6018dc..8e8752696 100644 --- a/lib/std/hash/gost/streebog.c3 +++ b/lib/std/hash/gost/streebog.c3 @@ -8,7 +8,7 @@ module std::hash::streebog; -const enum StreebogLength : inline uint +constdef StreebogLength : inline uint { SIZE_256 = 32, SIZE_512 = 64, diff --git a/lib/std/libc/os/posix.c3 b/lib/std/libc/os/posix.c3 index 5f17f234a..9cc493fc3 100644 --- a/lib/std/libc/os/posix.c3 +++ b/lib/std/libc/os/posix.c3 @@ -168,13 +168,13 @@ bitstruct Tc_lflags : CUInt bool extproc : 16; } -const enum T_nldly : char +constdef T_nldly : char { NL0 = 0b0, NL1 = 0b1, } -const enum T_crdly : char +constdef T_crdly : char { CR0 = 0b00, CR1 = 0b01, @@ -182,7 +182,7 @@ const enum T_crdly : char CR3 = 0b11, } -const enum T_tabdly : char +constdef T_tabdly : char { TAB0 = 0b00, TAB1 = 0b01, @@ -191,25 +191,25 @@ const enum T_tabdly : char XTABS = TAB3, } -const enum T_bsdly : char +constdef T_bsdly : char { BS0 = 0b0, BS1 = 0b1, } -const enum T_ffdly : char +constdef T_ffdly : char { FF0 = 0b0, FF1 = 0b1, } -const enum T_vtdly : char +constdef T_vtdly : char { VT0 = 0b0, VT1 = 0b1, } -const enum T_csize : char +constdef T_csize : char { CS5 = 0b00, CS6 = 0b01, @@ -217,7 +217,7 @@ const enum T_csize : char CS8 = 0b11, } -const enum Speed : CUInt +constdef Speed : CUInt { B0 = 0o0000000, B50 = 0o0000001, @@ -253,7 +253,7 @@ const enum Speed : CUInt MAX_BAUD = B4000000, } -const enum Cc : inline char +constdef Cc : inline char { VINTR = 0, VQUIT = 1, @@ -274,7 +274,7 @@ const enum Cc : inline char VEOL2 = 16, } -const enum Tcactions : CInt +constdef Tcactions : CInt { TCOOFF = 0, TCOON = 1, diff --git a/lib/std/net/socket.c3 b/lib/std/net/socket.c3 index aa2c0fe18..31b18ee55 100644 --- a/lib/std/net/socket.c3 +++ b/lib/std/net/socket.c3 @@ -25,7 +25,7 @@ macro void @loop_over_ai(AddrInfo* ai; @body(NativeSocket fd, AddrInfo* ai)) const Duration POLL_FOREVER = (Duration)-1; -const enum PollSubscribe +constdef PollSubscribe { ANY_READ = os::POLLIN, PRIO_READ = os::POLLPRI, @@ -44,7 +44,7 @@ const PollSubscribe SUBSCRIBE_ANY_WRITE = (PollSubscribe)os::POLLOUT; const PollSubscribe SUBSCRIBE_OOB_WRITE = (PollSubscribe)os::POLLWRBAND; const PollSubscribe SUBSCRIBE_WRITE = (PollSubscribe)os::POLLWRNORM; -const enum PollEvent : ushort +constdef PollEvent : ushort { READ_PRIO = os::POLLPRI, READ_OOB = os::POLLRDBAND, diff --git a/lib/std/os/linux/epoll.c3 b/lib/std/os/linux/epoll.c3 index b02efeff8..dd15179b1 100644 --- a/lib/std/os/linux/epoll.c3 +++ b/lib/std/os/linux/epoll.c3 @@ -18,7 +18,7 @@ const uint EPOLLWAKEUP = EpollEvents.EPOLLWAKEUP; const uint EPOLLONESHOT = EpollEvents.EPOLLONESHOT; const uint EPOLLET = EpollEvents.EPOLLET; -const enum EpollEvents : inline uint +constdef EpollEvents : inline uint { EPOLLIN = 0x001, EPOLLPRI = 0x002, diff --git a/lib/std/os/macos/core_foundation.c3 b/lib/std/os/macos/core_foundation.c3 index 695be5ba6..d09bf0046 100644 --- a/lib/std/os/macos/core_foundation.c3 +++ b/lib/std/os/macos/core_foundation.c3 @@ -40,7 +40,7 @@ extern fn CFTypeRef CFType.retain(&self) @cname("CFRetain"); extern fn void CFType.release(&self) @cname("CFRelease"); extern fn CFIndex CFType.getRetainCount(&self) @cname("CFGetRetainCount"); -const enum CFStringEncoding : uint +constdef CFStringEncoding : uint { INVALID_ID = 0xffffffffU, MAC_ROMAN = 0, diff --git a/lib/std/os/macos/general.c3 b/lib/std/os/macos/general.c3 index 0fccbc434..506761af4 100644 --- a/lib/std/os/macos/general.c3 +++ b/lib/std/os/macos/general.c3 @@ -1,7 +1,7 @@ module std::os::darwin @if(env::DARWIN) @link("Foundation.framework"); import std::os::macos::cf, std::os::macos::objc, std::io; -const enum NSSearchPathDomainMask : NSUInteger +constdef NSSearchPathDomainMask : NSUInteger { USER = 1, LOCAL = 2, @@ -10,7 +10,7 @@ const enum NSSearchPathDomainMask : NSUInteger ALL = 0x0ffff } -const enum NSSearchPathDirectory : NSUInteger +constdef NSSearchPathDirectory : NSUInteger { APPLICATION = 1, DEMO_APPLICATION, diff --git a/lib/std/os/macos/objc.c3 b/lib/std/os/macos/objc.c3 index 00fd13259..cd1ff78c4 100644 --- a/lib/std/os/macos/objc.c3 +++ b/lib/std/os/macos/objc.c3 @@ -88,7 +88,7 @@ enum ApplicationActivationPolicy : (int val) @deprecated("Use NSApplicationActiv PROHIBITED { 2 }, } -const enum NSApplicationActivationPolicy : inline NSInteger +constdef NSApplicationActivationPolicy : inline NSInteger { REGULAR = 0, ACCESSORY = 1, @@ -119,7 +119,7 @@ enum BackingStore : (int val) @deprecated("Use NSBackingStoreType.") BUFFERED { 2 } } -const enum NSBackingStoreType : inline NSUInteger +constdef NSBackingStoreType : inline NSUInteger { RETAINED = 0, NONRETAINED = 1, @@ -164,7 +164,7 @@ enum EventType : (long val) @deprecated("Use NSEventType.") CHANGE_MODE { 38 }, } -const enum NSEventType : inline NSUInteger +constdef NSEventType : inline NSUInteger { LEFT_MOUSE_DOWN = 1, LEFT_MOUSE_UP = 2, @@ -280,7 +280,7 @@ enum EventMask : (long val) @deprecated("Use NSEventMask.") ANY { long.max }, } -const enum NSEventMask : inline ulong +constdef NSEventMask : inline ulong { LEFT_MOUSE_DOWN = 1ul << NSEventType.LEFT_MOUSE_DOWN, LEFT_MOUSE_UP = 1ul << NSEventType.LEFT_MOUSE_UP, @@ -333,7 +333,7 @@ enum EventModifierFlag : (int val) @deprecated("Use NSEventModifierFlags.") HELP { 1 << 22 }, } -const enum NSEventModifierFlags : inline NSUInteger +constdef NSEventModifierFlags : inline NSUInteger { CAPS_LOCK = 1 << 16, SHIFT = 1 << 17, @@ -346,7 +346,7 @@ const enum NSEventModifierFlags : inline NSUInteger DEVICE_INDEPENDENT_FLAGS_MASK = 0xffff0000UL, } -const enum NSWindowCollectionBehavior : inline NSUInteger +constdef NSWindowCollectionBehavior : inline NSUInteger { DEFAULT = 0, CAN_JOIN_ALL_SPACES = 1 << 0, @@ -366,7 +366,7 @@ const enum NSWindowCollectionBehavior : inline NSUInteger CAN_JOIN_ALL_APPLICATIONS = 1 << 18, } -const enum NSWindowLevel : inline NSInteger +constdef NSWindowLevel : inline NSInteger { NORMAL = 0, FLOATING = 3, @@ -379,7 +379,7 @@ const enum NSWindowLevel : inline NSInteger SCREEN_SAVER = 1000, } -const enum NSWindowStyleMask : inline NSUInteger +constdef NSWindowStyleMask : inline NSUInteger { BORDERLESS = 0, TITLED = 1 << 0, @@ -396,20 +396,20 @@ const enum NSWindowStyleMask : inline NSUInteger HUD_WINDOW = 1 << 13 } -const enum NSWindowTabbingMode : inline NSInteger +constdef NSWindowTabbingMode : inline NSInteger { AUTOMATIC = 0, DISALLOWED = 2, PREFERRED = 1, } -const enum NSStatusItemLength : inline CGFloat +constdef NSStatusItemLength : inline CGFloat { VARIABLE = -1.0, SQUARE = -2.0 } -const enum NSApplicationTerminateReply : inline NSUInteger +constdef NSApplicationTerminateReply : inline NSUInteger { CANCEL = 0, NOW = 1, diff --git a/lib/std/os/win32/console.c3 b/lib/std/os/win32/console.c3 index 39253e73b..2540110e6 100644 --- a/lib/std/os/win32/console.c3 +++ b/lib/std/os/win32/console.c3 @@ -1,6 +1,6 @@ module std::os::win32 @if(env::WIN32); -const enum Win32_CODEPAGE : Win32_UINT +constdef Win32_CODEPAGE : Win32_UINT { IBM037 = 037, // IBM EBCDIC US-Canada IBM437 = 437, // OEM United States diff --git a/lib/std/os/win32/memoryapi.c3 b/lib/std/os/win32/memoryapi.c3 index 0fe7e7321..66c112385 100644 --- a/lib/std/os/win32/memoryapi.c3 +++ b/lib/std/os/win32/memoryapi.c3 @@ -1,6 +1,6 @@ module std::os::win32 @if(env::WIN32); -const enum Win32_AllocationType +constdef Win32_AllocationType { MEM_COMMIT = 0x00001000, MEM_RESERVE = 0x00002000, @@ -12,7 +12,7 @@ const enum Win32_AllocationType MEM_WRITE_WATCH = 0x00200000 } -const enum Win32_Protect : Win32_DWORD +constdef Win32_Protect : Win32_DWORD { PAGE_EXECUTE = 0x10, PAGE_EXECUTE_READ = 0x20, @@ -29,7 +29,7 @@ const enum Win32_Protect : Win32_DWORD PAGE_WRITECOMBINE = 0x400, } -const enum Win32_FreeType : Win32_DWORD +constdef Win32_FreeType : Win32_DWORD { MEM_DECOMMIT = 0x00004000, MEM_RELEASE = 0x00008000, diff --git a/lib/std/os/win32/winnt.c3 b/lib/std/os/win32/winnt.c3 index 8ebd0aebf..9e6a4c5b4 100644 --- a/lib/std/os/win32/winnt.c3 +++ b/lib/std/os/win32/winnt.c3 @@ -13,7 +13,7 @@ enum Win32_MEM_EXTENDED_PARAMETER_TYPE : CInt } alias Win32_PMEM_EXTENDED_PARAMETER_TYPE = Win32_MEM_EXTENDED_PARAMETER_TYPE; -const enum Win32_MEM_EXTENDED_PARAMETER_ATTRIBUTE : Win32_DWORD64 +constdef Win32_MEM_EXTENDED_PARAMETER_ATTRIBUTE : Win32_DWORD64 { <* The allocation is non-pageable. *> NONPAGED = 0x02, diff --git a/releasenotes.md b/releasenotes.md index 395eb0f65..2b11f0f80 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -9,7 +9,6 @@ - Integrated download of the MSVC SDK when compiling for Windows. - For `c3c init` with library templates, provide example exported functions. #2898 - `unsigned % signed` and `unsigned / signed` is no longer allowed without explicit casts, except for const denominators. #2928 -- New const enum declaration syntax. - New enum associated value syntax. - Individual warning settings added. - Change typedef and const enums to not convert from literals by default. @@ -17,7 +16,10 @@ - Include actual element count in the error message when the array initializer size does not match the expected size. - Add `--print-large-functions` for checking which functions likely dominate the compile time. - Improve error message when providing `alias` with a typeid expression where a type was expected. #2944 - +- Const enums removed. +- Constdef declarations introduced. + + ### Stdlib changes - Summarize sort macros as generic function wrappers to reduce the amount of generated code. #2831 - Remove dependency on temp allocator in String.join. diff --git a/resources/examples/opengl/src/gl/gl.c3 b/resources/examples/opengl/src/gl/gl.c3 index 96e898efe..f7ea1ba53 100644 --- a/resources/examples/opengl/src/gl/gl.c3 +++ b/resources/examples/opengl/src/gl/gl.c3 @@ -1,15 +1,13 @@ module gl; -alias BitField = int; - -enum BufferBit : int (int value) +constdef BufferBit : int { COLOR = 0x00004000, STENCIL = 0x00000400, DEPTH = 0x00000100, } -enum Primitive : int (int value) +constdef Primitive : int { POINTS = 0, LINES = 1, @@ -23,9 +21,9 @@ enum Primitive : int (int value) POLYGON = 9, } -extern fn void clear(BitField mask) @cname("glClear") @public; +extern fn void clear(BufferBit mask) @cname("glClear") @public; -extern fn void begin(BitField mask) @cname("glBegin") @public; +extern fn void begin(BufferBit mask) @cname("glBegin") @public; extern fn void end() @cname("glEnd") @public; diff --git a/resources/examples/raylib/raylib_2d_camera_platformer.c3 b/resources/examples/raylib/raylib_2d_camera_platformer.c3 index 7fb5676bb..faa00b504 100644 --- a/resources/examples/raylib/raylib_2d_camera_platformer.c3 +++ b/resources/examples/raylib/raylib_2d_camera_platformer.c3 @@ -45,11 +45,11 @@ alias CameraUpdateFn = fn void(RLCamera2D* camera, Player* player, EnvItem[] env enum CameraUpdateType : (ZString text, CameraUpdateFn func) { - CENTER = { "Follow player center", &update_camera_center }, - CENTER_INSIDE_MAP = { "Follow player center, but clamp to map edges", &update_camera_center_inside_map }, - CENTER_SMOOTH_FOLLOW = { "Follow player center; smoothed", &update_camera_center_smooth_follow }, - EVEN_OUT_ON_LANDING = { "Follow player center horizontally; update player center vertically after landing", &update_camera_even_out_on_landing }, - PLAYER_BOUNDS_PUSH = { "Player push camera on getting too close to screen edge", &update_camera_player_bounds_push } + CENTER { "Follow player center", &update_camera_center }, + CENTER_INSIDE_MAP { "Follow player center, but clamp to map edges", &update_camera_center_inside_map }, + CENTER_SMOOTH_FOLLOW { "Follow player center; smoothed", &update_camera_center_smooth_follow }, + EVEN_OUT_ON_LANDING { "Follow player center horizontally; update player center vertically after landing", &update_camera_even_out_on_landing }, + PLAYER_BOUNDS_PUSH { "Player push camera on getting too close to screen edge", &update_camera_player_bounds_push } } //------------------------------------------------------------------------------------ diff --git a/resources/examples/raylib/raylib_snake.c3 b/resources/examples/raylib/raylib_snake.c3 index f25fab7fe..eb147fde6 100644 --- a/resources/examples/raylib/raylib_snake.c3 +++ b/resources/examples/raylib/raylib_snake.c3 @@ -18,10 +18,10 @@ const int SCREEN_HEIGHT = 450; enum SnakeDirection : (RLVector2 dir) { - RIGHT = { SQUARE_SIZE, 0 }, - DOWN = { 0, SQUARE_SIZE }, - LEFT = { -SQUARE_SIZE, 0 }, - UP = { 0, -SQUARE_SIZE } + RIGHT {{ SQUARE_SIZE, 0 }}, + DOWN {{ 0, SQUARE_SIZE }}, + LEFT {{ -SQUARE_SIZE, 0 }}, + UP {{ 0, -SQUARE_SIZE }} } struct Snake { diff --git a/scripts/tools/ci_tests.sh b/scripts/tools/ci_tests.sh index 9727eb0e7..bbd54f49e 100755 --- a/scripts/tools/ci_tests.sh +++ b/scripts/tools/ci_tests.sh @@ -64,35 +64,36 @@ cd "$ROOT_DIR/resources" run_examples() { echo "--- Running Standard Examples ---" - "$C3C_BIN" compile examples/base64.c3 - "$C3C_BIN" compile examples/binarydigits.c3 - "$C3C_BIN" compile examples/brainfk.c3 - "$C3C_BIN" compile examples/factorial_macro.c3 - "$C3C_BIN" compile examples/fasta.c3 - "$C3C_BIN" compile examples/gameoflife.c3 - "$C3C_BIN" compile examples/hash.c3 - "$C3C_BIN" compile-only examples/levenshtein.c3 - "$C3C_BIN" compile examples/load_world.c3 - "$C3C_BIN" compile-only examples/map.c3 - "$C3C_BIN" compile examples/mandelbrot.c3 - "$C3C_BIN" compile examples/plus_minus.c3 - "$C3C_BIN" compile examples/nbodies.c3 - "$C3C_BIN" compile examples/spectralnorm.c3 - "$C3C_BIN" compile examples/swap.c3 - "$C3C_BIN" compile examples/contextfree/boolerr.c3 - "$C3C_BIN" compile examples/contextfree/dynscope.c3 - "$C3C_BIN" compile examples/contextfree/guess_number.c3 - "$C3C_BIN" compile examples/contextfree/multi.c3 - "$C3C_BIN" compile examples/contextfree/cleanup.c3 + "$C3C_BIN" compile-only -vv examples/base64.c3 --target linux-x64 + "$C3C_BIN" compile -vv examples/base64.c3 + "$C3C_BIN" compile -vv examples/binarydigits.c3 + "$C3C_BIN" compile -vv examples/brainfk.c3 + "$C3C_BIN" compile -vv examples/factorial_macro.c3 + "$C3C_BIN" compile -vv examples/fasta.c3 + "$C3C_BIN" compile -vv examples/gameoflife.c3 + "$C3C_BIN" compile -vv examples/hash.c3 + "$C3C_BIN" compile-only -vv examples/levenshtein.c3 + "$C3C_BIN" compile -vv examples/load_world.c3 + "$C3C_BIN" compile-only -vv examples/map.c3 + "$C3C_BIN" compile -vv examples/mandelbrot.c3 + "$C3C_BIN" compile -vv examples/plus_minus.c3 + "$C3C_BIN" compile -vv examples/nbodies.c3 + "$C3C_BIN" compile -vv examples/spectralnorm.c3 + "$C3C_BIN" compile -vv examples/swap.c3 + "$C3C_BIN" compile -vv examples/contextfree/boolerr.c3 + "$C3C_BIN" compile -vv examples/contextfree/dynscope.c3 + "$C3C_BIN" compile -vv examples/contextfree/guess_number.c3 + "$C3C_BIN" compile -vv examples/contextfree/multi.c3 + "$C3C_BIN" compile -vv examples/contextfree/cleanup.c3 - "$C3C_BIN" compile-run examples/hello_world_many.c3 - "$C3C_BIN" compile-run examples/time.c3 - "$C3C_BIN" compile-run examples/fannkuch-redux.c3 - "$C3C_BIN" compile-run examples/contextfree/boolerr.c3 - "$C3C_BIN" compile-run examples/load_world.c3 - "$C3C_BIN" compile-run examples/process.c3 - "$C3C_BIN" compile-run examples/ls.c3 - "$C3C_BIN" compile-run examples/args.c3 -- foo -bar "baz baz" + "$C3C_BIN" compile-run -vv examples/hello_world_many.c3 + "$C3C_BIN" compile-run -vv examples/time.c3 + "$C3C_BIN" compile-run -vv examples/fannkuch-redux.c3 + "$C3C_BIN" compile-run -vv examples/contextfree/boolerr.c3 + "$C3C_BIN" compile-run -vv examples/load_world.c3 + "$C3C_BIN" compile-run -vv examples/process.c3 + "$C3C_BIN" compile-run -vv examples/ls.c3 + "$C3C_BIN" compile-run -vv examples/args.c3 -- foo -bar "baz baz" if [[ "$OS_MODE" == "linux" ]]; then "$C3C_BIN" compile-run --linker=builtin linux_stack.c3 || echo "Warning: linux_stack builtin linker skipped" diff --git a/src/compiler/ast.c b/src/compiler/ast.c index fc83299b6..4a5f49f13 100644 --- a/src/compiler/ast.c +++ b/src/compiler/ast.c @@ -68,7 +68,7 @@ Decl *decl_new_with_type(const char *name, SourceSpan span, DeclKind decl_type) case DECL_ENUM: kind = TYPE_ENUM; break; - case DECL_CONST_ENUM: + case DECL_CONSTDEF: kind = TYPE_CONST_ENUM; break; case DECL_TYPEDEF: @@ -127,7 +127,7 @@ const char *decl_to_a_name(Decl *decl) case DECL_ALIAS: case DECL_ALIAS_PATH: case DECL_TYPE_ALIAS: return "an alias"; case DECL_TYPEDEF: return "a distinct type"; case DECL_ENUM: return "an enum"; - case DECL_CONST_ENUM: return "a raw enum"; + case DECL_CONSTDEF: return "a set of constants"; case DECL_ENUM_CONSTANT: return "an enum value"; case DECL_ERASED: return "an erased declaration"; case DECL_FAULT: return "a fault"; @@ -346,7 +346,7 @@ bool decl_may_be_generic(Decl *decl) case DECL_GENERIC_INSTANCE: case DECL_IMPORT: case DECL_LABEL: - case DECL_CONST_ENUM: + case DECL_CONSTDEF: return false; case DECL_ATTRIBUTE: case DECL_BITSTRUCT: diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index 9c6064869..4905a2521 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -565,7 +565,7 @@ typedef struct AstId docs; union { - struct + struct // Function related { bool attr_inline : 1; bool attr_noinline : 1; @@ -593,7 +593,7 @@ typedef struct Decl **lambda_ct_parameters; }; }; - struct + struct // Macro related { DeclId body_param; CompilationUnit *unit; @@ -4328,7 +4328,7 @@ INLINE void expr_rewrite_const_int(Expr *expr, Type *type, uint64_t v) expr->type = type; expr->resolve_status = RESOLVE_DONE; TypeKind kind = type_flatten(type)->type_kind; - (&expr->const_expr)->ixx.i.high = 0; + expr->const_expr.ixx.i.high = 0; if (type_kind_is_signed(kind)) { if (v > (uint64_t)INT64_MAX) (&expr->const_expr)->ixx.i.high = UINT64_MAX; @@ -4350,10 +4350,10 @@ INLINE void expr_rewrite_const_int(Expr *expr, Type *type, uint64_t v) break; } } - (&expr->const_expr)->ixx.i.low = v; - (&expr->const_expr)->ixx.type = kind; - (&expr->const_expr)->is_character = false; - (&expr->const_expr)->const_kind = CONST_INTEGER; + expr->const_expr.ixx.i.low = v; + expr->const_expr.ixx.type = kind; + expr->const_expr.is_character = false; + expr->const_expr.const_kind = CONST_INTEGER; } INLINE void expr_rewrite_to_int_to_float(Expr *expr, Type *type) diff --git a/src/compiler/context.c b/src/compiler/context.c index 8664dad9b..900b1150b 100644 --- a/src/compiler/context.c +++ b/src/compiler/context.c @@ -164,7 +164,7 @@ void decl_register(CompilationUnit *unit, Decl *decl) case DECL_BITSTRUCT: case DECL_TYPEDEF: case DECL_ENUM: - case DECL_CONST_ENUM: + case DECL_CONSTDEF: case DECL_STRUCT: case DECL_TYPE_ALIAS: case DECL_UNION: @@ -273,7 +273,7 @@ void unit_register_global_decl(CompilationUnit *unit, Decl *decl) vec_add(unit->generic_defines, decl); decl_register(unit, decl); return; - case DECL_CONST_ENUM: + case DECL_CONSTDEF: case DECL_ENUM: ASSERT(decl->name); vec_add(unit->enums, decl); diff --git a/src/compiler/copying.c b/src/compiler/copying.c index 9fbc62606..96c4db17f 100644 --- a/src/compiler/copying.c +++ b/src/compiler/copying.c @@ -1117,7 +1117,7 @@ Decl *copy_decl(CopyStruct *c, Decl *decl) break; case DECL_FAULT: break; - case DECL_CONST_ENUM: + case DECL_CONSTDEF: copy_decl_type(copy); MACRO_COPY_TYPE_LIST(copy->interfaces); MACRO_COPY_DECL_METHODS(copy->method_table); diff --git a/src/compiler/enums.h b/src/compiler/enums.h index e35c9a0f8..97f32d8c2 100644 --- a/src/compiler/enums.h +++ b/src/compiler/enums.h @@ -1050,7 +1050,7 @@ typedef enum DECL_LABEL, DECL_MACRO, DECL_INTERFACE, - DECL_CONST_ENUM, + DECL_CONSTDEF, DECL_STRUCT, DECL_TYPE_ALIAS, DECL_UNION, @@ -1579,7 +1579,7 @@ typedef enum TOKEN_BREAK, TOKEN_CASE, TOKEN_CATCH, - TOKEN_CENUM, + TOKEN_CONSTDEF, TOKEN_CONST, TOKEN_CONTINUE, TOKEN_DEFAULT, diff --git a/src/compiler/json_output.c b/src/compiler/json_output.c index 8bbe0ac72..9565e8124 100644 --- a/src/compiler/json_output.c +++ b/src/compiler/json_output.c @@ -95,7 +95,7 @@ static inline const char *decl_type_to_string(Decl *type) case DECL_STRUCT: return "struct"; case DECL_UNION: return "union"; case DECL_TYPE_ALIAS: return "type_alias"; - case DECL_CONST_ENUM: return "raw_enum"; + case DECL_CONSTDEF: return "constdef"; case DECL_BODYPARAM: case DECL_DECLARRAY: case DECL_ERASED: diff --git a/src/compiler/llvm_codegen.c b/src/compiler/llvm_codegen.c index 90f4d4909..6a8eff01f 100644 --- a/src/compiler/llvm_codegen.c +++ b/src/compiler/llvm_codegen.c @@ -1036,7 +1036,7 @@ static void llvm_emit_type_decls(GenContext *context, Decl *decl) case DECL_UNION: case DECL_ENUM: case DECL_BITSTRUCT: - case DECL_CONST_ENUM: + case DECL_CONSTDEF: llvm_get_typeid(context, decl->type); break; } @@ -1389,7 +1389,7 @@ LLVMValueRef llvm_get_ref(GenContext *c, Decl *decl) case DECL_CT_ASSERT: case DECL_TYPEDEF: case DECL_ENUM: - case DECL_CONST_ENUM: + case DECL_CONSTDEF: case DECL_ENUM_CONSTANT: case DECL_IMPORT: case DECL_ALIAS_PATH: diff --git a/src/compiler/llvm_codegen_type.c b/src/compiler/llvm_codegen_type.c index be1b0a133..5763bc6d4 100644 --- a/src/compiler/llvm_codegen_type.c +++ b/src/compiler/llvm_codegen_type.c @@ -25,7 +25,7 @@ static inline LLVMTypeRef llvm_type_from_decl(GenContext *c, Decl *decl) UNREACHABLE_VOID case DECL_TYPE_ALIAS: return llvm_get_type(c, decl->type); - case DECL_CONST_ENUM: + case DECL_CONSTDEF: return llvm_get_type(c, decl->enums.type_info->type); case DECL_TYPEDEF: return llvm_get_type(c, decl->distinct->type); diff --git a/src/compiler/parse_global.c b/src/compiler/parse_global.c index 2d6bfb5a5..4093077f9 100644 --- a/src/compiler/parse_global.c +++ b/src/compiler/parse_global.c @@ -13,7 +13,7 @@ typedef enum FunctionParse_ FUNC_PARSE_INTERFACE, } FunctionParse; -static inline Decl *parse_enum_declaration(ParseContext *c, bool is_const); +static inline Decl *parse_enum_declaration(ParseContext *c); static inline Decl *parse_func_definition(ParseContext *c, AstId contracts, FunctionParse parse_kind); static inline bool parse_bitstruct_body(ParseContext *c, Decl *decl); static inline bool parse_enum_param_list(ParseContext *c, Decl*** parameters_ref, ArrayIndex *inline_index); @@ -23,7 +23,6 @@ static bool parse_attributes_for_global(ParseContext *c, Decl *decl); INLINE bool parse_decl_initializer(ParseContext *c, Decl *decl); INLINE Decl *decl_new_var_current(ParseContext *c, TypeInfo *type, VarDeclKind kind); static bool parse_contracts(ParseContext *c, AstId *contracts_ref); -static Ast *contracts_first_real(AstId contracts); INLINE Decl *decl_new_var_current(ParseContext *c, TypeInfo *type, VarDeclKind kind) { @@ -2289,10 +2288,6 @@ static inline Decl *parse_bitstruct_declaration(ParseContext *c) static inline Decl *parse_top_level_const_declaration(ParseContext *c, bool is_extern) { - if (!is_extern && peek(c) == TOKEN_ENUM) - { - return parse_enum_declaration(c, true); - } ASSIGN_DECL_OR_RET(Decl *decl, parse_const_declaration(c, true, is_extern), poisoned_decl); CONSUME_EOS_OR_RET(poisoned_decl); return decl; @@ -2795,7 +2790,7 @@ static inline bool parse_enum_param_list(ParseContext *c, Decl*** parameters_ref return true; } -static bool parse_enum_values(ParseContext *c, Decl*** values_ref, Visibility visibility, bool is_single_value, bool is_const_enum) +static bool parse_enum_values(ParseContext *c, Decl*** values_ref, Visibility visibility, bool is_single_value, bool is_constdef) { Decl **values = NULL; bool deprecate_warn = true; @@ -2803,7 +2798,7 @@ static bool parse_enum_values(ParseContext *c, Decl*** values_ref, Visibility vi { if (!parse_element_contract(c, "enum values")) return false; Decl *enum_const = decl_new(DECL_ENUM_CONSTANT, symstr(c), c->span); - if (is_const_enum) enum_const->enum_constant.is_raw = is_const_enum; + if (is_constdef) enum_const->enum_constant.is_raw = is_constdef; enum_const->visibility = visibility; const char *name = enum_const->name; if (!consume_const_name(c, "enum constant")) return false; @@ -2820,7 +2815,7 @@ static bool parse_enum_values(ParseContext *c, Decl*** values_ref, Visibility vi if (try_consume(c, TOKEN_EQ)) { Expr **args = NULL; - if (!is_const_enum && deprecate_warn) + if (!is_constdef && deprecate_warn) { deprecate_warn = false; print_deprecation_at(c->prev_span, "Use () declaration of associated values instead."); @@ -2828,7 +2823,7 @@ static bool parse_enum_values(ParseContext *c, Decl*** values_ref, Visibility vi if (is_single_value || !tok_is(c, TOKEN_LBRACE)) { ASSIGN_EXPR_OR_RET(Expr *single, parse_constant_expr(c), false); - if (is_const_enum) + if (is_constdef) { enum_const->enum_constant.value = single; goto NEXT; @@ -2862,7 +2857,7 @@ static bool parse_enum_values(ParseContext *c, Decl*** values_ref, Visibility vi } enum_const->enum_constant.associated = args; } - else if (!is_const_enum && try_consume(c, TOKEN_LBRACE)) + else if (!is_constdef && try_consume(c, TOKEN_LBRACE)) { Expr **args = NULL; while (1) @@ -2913,13 +2908,13 @@ NEXT: * enum_body ::= enum_def (',' enum_def)* ','? * enum_def ::= CONST_IDENT ('(' arg_list ')')? */ -static inline Decl *parse_enum_declaration(ParseContext *c, bool is_const) +static inline Decl *parse_enum_declaration(ParseContext *c) { - if (is_const) advance_and_verify(c, TOKEN_CONST); - if (tok_is(c, TOKEN_CENUM)) + bool is_constdef = false; + if (tok_is(c, TOKEN_CONSTDEF)) { - advance_and_verify(c, TOKEN_CENUM); - is_const = true; + advance_and_verify(c, TOKEN_CONSTDEF); + is_constdef = true; } else { @@ -2928,23 +2923,22 @@ static inline Decl *parse_enum_declaration(ParseContext *c, bool is_const) const char *name = symstr(c); SourceSpan span = c->span; - if (!consume_type_name(c, "enum")) return poisoned_decl; + if (!consume_type_name(c, is_constdef ? "constdef" : "enum" )) return poisoned_decl; TypeInfo **interfaces = NULL; if (!parse_interface_impls(c, &interfaces)) return poisoned_decl; TypeInfo *type = NULL; bool val_is_inline = false; ArrayIndex inline_index = -1; - bool is_const_enum = is_const; Decl **param_list = NULL; if (try_consume(c, TOKEN_COLON)) { - if (!is_const) + if (!is_constdef) { - is_const_enum = try_consume(c, TOKEN_CONST); - if (is_const_enum) + is_constdef = try_consume(c, TOKEN_CONST); + if (is_constdef) { - print_deprecation_at(c->prev_span, "Declare const enums using 'const enum' instead."); + print_deprecation_at(c->prev_span, "Declare constdefs using 'constdef' instead."); } } if (!tok_is(c, TOKEN_LPAREN) && !tok_is(c, TOKEN_LBRACE)) @@ -2953,14 +2947,14 @@ static inline Decl *parse_enum_declaration(ParseContext *c, bool is_const) ASSIGN_TYPE_OR_RET(type, parse_optional_type_no_generic(c), poisoned_decl); if (type->optional) { - RETURN_PRINT_ERROR_AT(poisoned_decl, type, "An enum can't have an optional type."); + RETURN_PRINT_ERROR_AT(poisoned_decl, type, "An enum or constdef can't have an optional type."); } } - if (is_const_enum) + if (is_constdef) { if (tok_is(c, TOKEN_LPAREN)) { - PRINT_ERROR_HERE("Const enums cannot have associated values."); + PRINT_ERROR_HERE("Constdefs cannot have associated values."); return poisoned_decl; } } @@ -2970,7 +2964,7 @@ static inline Decl *parse_enum_declaration(ParseContext *c, bool is_const) } } - Decl *decl = decl_new_with_type(name, span, is_const_enum ? DECL_CONST_ENUM : DECL_ENUM); + Decl *decl = decl_new_with_type(name, span, is_constdef ? DECL_CONSTDEF : DECL_ENUM); decl->interfaces = interfaces; if (param_list) decl->enums.parameters = param_list; if (!parse_attributes_for_global(c, decl)) return poisoned_decl; @@ -2980,9 +2974,9 @@ static inline Decl *parse_enum_declaration(ParseContext *c, bool is_const) decl->enums.type_info = type ? type : type_info_new_base(type_int, decl->span); decl->enums.inline_index = (int16_t)inline_index; - decl->enums.inline_value = is_const_enum ? false : val_is_inline; - if (is_const_enum && val_is_inline) decl->is_substruct = true; - if (!parse_enum_values(c, &decl->enums.values, visibility, is_const_enum || expected_parameters == 1, is_const_enum)) return poisoned_decl; + decl->enums.inline_value = is_constdef ? false : val_is_inline; + if (is_constdef && val_is_inline) decl->is_substruct = true; + if (!parse_enum_values(c, &decl->enums.values, visibility, is_constdef || expected_parameters == 1, is_constdef)) return poisoned_decl; return decl; } @@ -3642,8 +3636,8 @@ Decl *parse_top_level_statement(ParseContext *c, ParseContext **context_out) decl = parse_macro_declaration(c, contracts); break; case TOKEN_ENUM: - case TOKEN_CENUM: - decl = parse_enum_declaration(c, false); + case TOKEN_CONSTDEF: + decl = parse_enum_declaration(c); attach_contracts = true; break; case TOKEN_FAULTDEF: diff --git a/src/compiler/parse_stmt.c b/src/compiler/parse_stmt.c index 3877e9a99..94ba3ef75 100644 --- a/src/compiler/parse_stmt.c +++ b/src/compiler/parse_stmt.c @@ -1444,7 +1444,7 @@ Ast *parse_stmt(ParseContext *c) case TOKEN_BIT_AND_ASSIGN: case TOKEN_BIT_OR_ASSIGN: case TOKEN_BIT_XOR_ASSIGN: - case TOKEN_CENUM: + case TOKEN_CONSTDEF: case TOKEN_COLON: case TOKEN_COMMA: case TOKEN_CT_CASE: diff --git a/src/compiler/sema_casts.c b/src/compiler/sema_casts.c index 3980c3bcd..2cfa61de6 100644 --- a/src/compiler/sema_casts.c +++ b/src/compiler/sema_casts.c @@ -1238,7 +1238,7 @@ RETRY:; inner = decl->strukt.members[0]->type->canonical; break; case DECL_ENUM: - case DECL_CONST_ENUM: + case DECL_CONSTDEF: // Could be made to work. return false; default: @@ -1656,7 +1656,7 @@ static bool rule_enum_to_value(CastContext *cc, bool is_explicit, bool is_silent return cast_is_allowed(cc, is_explicit, is_silent); } - ASSERT(enum_decl->decl_kind != DECL_CONST_ENUM); + ASSERT(enum_decl->decl_kind != DECL_CONSTDEF); Type *inner = enum_decl->enums.type_info->type; if (!type_is_integer_or_bool_kind(type_flatten(cc->to))) diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index 281f45fb4..1fe107656 100644 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -71,7 +71,7 @@ static inline bool sema_resolve_align_expr(SemaContext *context, Expr *expr, Ali } static inline bool sema_analyse_enum_param(SemaContext *context, Decl *param); static inline bool sema_analyse_enum(SemaContext *context, Decl *decl, bool *erase_decl); -static inline bool sema_analyse_raw_enum(SemaContext *context, Decl *decl, bool *erase_decl); +static inline bool sema_analyse_constdef(SemaContext *context, Decl *decl, bool *erase_decl); static bool sema_check_section(SemaContext *context, Attr *attr) { @@ -1636,11 +1636,11 @@ static inline void sema_print_enum_to_cenum_error(SemaContext *context, Decl *de TypeInfo *type_info = decl->enums.type_info; if (type_info->type == type_int) { - SEMA_ERROR(arg, "Assigning a value requires the declaration of associated values for the enum. Did you perhaps want C-style enums? In that case use const enums, defined like 'enum %s : const { ... }'", decl->name); + SEMA_ERROR(arg, "Assigning a value requires the declaration of associated values for the enum. Did you perhaps want C-style enums? In that case use constdef, defined like 'constdef %s : { ... }'", decl->name); } else { - SEMA_ERROR(arg, "Assigning a value requires the declaration of associated values for the enum. Did you perhaps want C-style enums? In that case use const enums, defined like 'enum %s : const %s { ... }'", decl->name, type_to_error_string(type_info->type)); + SEMA_ERROR(arg, "Assigning a value requires the declaration of associated values for the enum. Did you perhaps want C-style enums? In that case use constdef, defined like 'constdef %s : %s { ... }'", decl->name, type_to_error_string(type_info->type)); } } static inline bool sema_analyse_enum(SemaContext *context, Decl *decl, bool *erase_decl) @@ -1812,7 +1812,7 @@ static bool sema_analyse_const_enum_constant_val(SemaContext *context, Decl *dec } return true; } -static inline bool sema_analyse_raw_enum(SemaContext *context, Decl *decl, bool *erase_decl) +static inline bool sema_analyse_constdef(SemaContext *context, Decl *decl, bool *erase_decl) { if (!sema_analyse_attributes(context, decl, decl->attributes, ATTR_ENUM, erase_decl)) return decl_poison(decl); if (*erase_decl) return true; @@ -1836,18 +1836,18 @@ static inline bool sema_analyse_raw_enum(SemaContext *context, Decl *decl, bool SEMA_ERROR(decl->enums.type_info, "No type can be inferred from the optional result."); return decl_poison(decl); case STORAGE_VOID: - SEMA_ERROR(decl->enums.type_info, "An enum may not have a void type."); + SEMA_ERROR(decl->enums.type_info, "A constdef may not have a void type."); return decl_poison(decl); case STORAGE_COMPILE_TIME: - SEMA_ERROR(decl->enums.type_info, "An enum may not be %s.", type_invalid_storage_type_name(type)); + SEMA_ERROR(decl->enums.type_info, "A constdef may not be %s.", type_invalid_storage_type_name(type)); return decl_poison(decl); case STORAGE_UNKNOWN: - SEMA_ERROR(decl->enums.type_info, "An enum may not be %s, as it has an unknown size.", + SEMA_ERROR(decl->enums.type_info, "A constdef may not be %s, as it has an unknown size.", type_quoted_error_string(type)); return decl_poison(decl); } - DEBUG_LOG("* Raw enum type resolved to %s.", type->name); + DEBUG_LOG("* Constdef type resolved to %s.", type->name); ASSERT_SPAN(decl, !decl->enums.parameters); @@ -1865,7 +1865,7 @@ static inline bool sema_analyse_raw_enum(SemaContext *context, Decl *decl, bool { if (enums == 1) { - RETURN_SEMA_ERROR(decl, "No enum values left in enum after @if resolution, there must be at least one."); + RETURN_SEMA_ERROR(decl, "No constdef values left in constdef after @if resolution, there must be at least one."); } vec_erase_at(enum_values, i); enums--; @@ -1873,12 +1873,12 @@ static inline bool sema_analyse_raw_enum(SemaContext *context, Decl *decl, bool continue; } enum_value->type = decl->type; - DEBUG_LOG("* Checking enum constant %s.", enum_value->name); + DEBUG_LOG("* Checking constdef constant %s.", enum_value->name); if (!enum_value->enum_constant.value) { if (!type_is_integer(flat)) { - RETURN_SEMA_ERROR(enum_value, "Enums with missing values must be an integer type."); + RETURN_SEMA_ERROR(enum_value, "Constdefs with missing values must be of integer type."); } if (i == 0) { @@ -5733,8 +5733,8 @@ bool sema_analyse_decl(SemaContext *context, Decl *decl) case DECL_ENUM: if (!sema_analyse_enum(context, decl, &erase_decl)) goto FAILED; break; - case DECL_CONST_ENUM: - if (!sema_analyse_raw_enum(context, decl, &erase_decl)) goto FAILED; + case DECL_CONSTDEF: + if (!sema_analyse_constdef(context, decl, &erase_decl)) goto FAILED; break; case DECL_FAULT: if (!sema_analyse_fault(context, decl, &erase_decl)) goto FAILED; diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 7108a8738..46ba61279 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -999,8 +999,10 @@ static inline bool sema_cast_ident_rvalue(SemaContext *context, Expr *expr) case DECL_UNION: SEMA_ERROR(expr, "Expected union followed by {...} or '.'."); return expr_poison(expr); + case DECL_CONSTDEF: + SEMA_ERROR(expr, "Expected constdef name followed by '.' and a constdef value."); + return expr_poison(expr); case DECL_ENUM: - case DECL_CONST_ENUM: SEMA_ERROR(expr, "Expected enum name followed by '.' and an enum value."); return expr_poison(expr); } @@ -1187,7 +1189,14 @@ static inline bool sema_expr_analyse_enum_constant(SemaContext *context, Expr *e if (enum_constant->resolve_status == RESOLVE_NOT_DONE) { - SEMA_ERROR(expr, "Unable to properly resolve enum constant value, this can sometimes happen in recursive definitions."); + if (decl->decl_kind == DECL_ENUM) + { + SEMA_ERROR(expr, "Unable to properly resolve enum constant value, this can sometimes happen in recursive definitions."); + } + else + { + SEMA_ERROR(expr, "Unable to properly resolve constdef value, this can sometimes happen in recursive definitions."); + } return expr_poison(expr), true; } expr->type = decl->type; @@ -3502,7 +3511,7 @@ INLINE bool sema_expr_analyse_from_ordinal(SemaContext *context, Expr *expr, Exp { RETURN_SEMA_ERROR(key, "The ordinal should be an integer."); } - bool is_const_enum = decl->decl_kind == DECL_CONST_ENUM; + bool is_const_enum = decl->decl_kind == DECL_CONSTDEF; if (sema_cast_const(key)) { Int to_convert = key->const_expr.ixx; @@ -3532,7 +3541,7 @@ INLINE bool sema_expr_analyse_from_ordinal(SemaContext *context, Expr *expr, Exp } if (is_const_enum) { - RETURN_SEMA_ERROR(key, ".from_ordinal on const enums is only valid with compile time constant arguments, maybe you can try using regular enums?"); + RETURN_SEMA_ERROR(key, ".from_ordinal on constdefs is only valid with compile time constant arguments, maybe you want to use enums instead?"); } expr->expr_kind = EXPR_ENUM_FROM_ORD; expr->inner_expr = key; @@ -5086,15 +5095,18 @@ static inline bool sema_expr_analyse_type_access(SemaContext *context, Expr *exp switch (decl->decl_kind) { case DECL_ENUM: - case DECL_CONST_ENUM: + case DECL_CONSTDEF: if (is_const) { if (!sema_expr_analyse_enum_constant(context, expr, name, decl)) { if (missing_ref) goto MISSING_REF; if (!decl_ok(decl)) return false; + if (decl->decl_kind != DECL_ENUM) + { + RETURN_SEMA_ERROR(expr, "'%s' has no value '%s'.", decl->name, name); + } RETURN_SEMA_ERROR(expr, "'%s' has no enumeration value '%s'.", decl->name, name); - return false; } return expr_ok(expr); } @@ -10522,7 +10534,7 @@ static inline bool sema_expr_analyse_ct_nameof(SemaContext *context, Expr *expr, case DECL_BITSTRUCT: case DECL_TYPEDEF: case DECL_ENUM: - case DECL_CONST_ENUM: + case DECL_CONSTDEF: case DECL_ENUM_CONSTANT: case DECL_FNTYPE: case DECL_FUNC: diff --git a/src/compiler/sema_liveness.c b/src/compiler/sema_liveness.c index bbba85998..1b68a9bdc 100644 --- a/src/compiler/sema_liveness.c +++ b/src/compiler/sema_liveness.c @@ -604,7 +604,7 @@ RETRY: case DECL_TYPEDEF: sema_trace_type_liveness(decl->distinct->type); FALLTHROUGH; - case DECL_CONST_ENUM: + case DECL_CONSTDEF: case DECL_BITSTRUCT: case DECL_INTERFACE: case DECL_UNION: diff --git a/src/compiler/sema_types.c b/src/compiler/sema_types.c index 36fe6987d..b39c95416 100644 --- a/src/compiler/sema_types.c +++ b/src/compiler/sema_types.c @@ -243,7 +243,7 @@ static bool sema_resolve_type_identifier(SemaContext *context, TypeInfo *type_in type_info->type = decl->type; type_info->resolve_status = RESOLVE_DONE; return true; - case DECL_CONST_ENUM: + case DECL_CONSTDEF: case DECL_TYPEDEF: if (resolve_type_kind & RESOLVE_TYPE_NO_CHECK_DISTINCT) { diff --git a/src/compiler/semantic_analyser.c b/src/compiler/semantic_analyser.c index 76da9002b..30df4753f 100644 --- a/src/compiler/semantic_analyser.c +++ b/src/compiler/semantic_analyser.c @@ -262,7 +262,7 @@ static void register_generic_decls(CompilationUnit *unit, Decl **decls) case DECL_ALIAS: case DECL_ATTRIBUTE: case DECL_BITSTRUCT: - case DECL_CONST_ENUM: + case DECL_CONSTDEF: case DECL_TYPEDEF: case DECL_ENUM: case DECL_INTERFACE: diff --git a/src/compiler/tokens.c b/src/compiler/tokens.c index 8d659ba2e..dc12d9fe0 100644 --- a/src/compiler/tokens.c +++ b/src/compiler/tokens.c @@ -199,12 +199,12 @@ const char *token_type_to_string(TokenType type) return "break"; case TOKEN_CASE: return "case"; - case TOKEN_CENUM: - return "cenum"; case TOKEN_CATCH: return "catch"; case TOKEN_CONST: return "const"; + case TOKEN_CONSTDEF: + return "constdef"; case TOKEN_CONTINUE: return "continue"; case TOKEN_DEFAULT: diff --git a/src/compiler/types.c b/src/compiler/types.c index e91f7c5df..4d869a354 100644 --- a/src/compiler/types.c +++ b/src/compiler/types.c @@ -2131,7 +2131,7 @@ RETRY_DISTINCT: return NULL; case ALL_INTS: { - // If Foo + 1, then we allow this if Foo is a distinct type or const enum that has + // If Foo + 1, then we allow this if Foo is a distinct type or constdef that has // integer or float as the base type. if (first && type_is_distinct_like(other) && type_underlying_is_numeric(other) && expr_is_const(first)) return other; // See if we can flatten it. @@ -2145,7 +2145,7 @@ RETRY_DISTINCT: } case ALL_FLOATS: { - // If Foo + 1.0, then we allow this if Foo is a distinct type or const enum that has + // If Foo + 1.0, then we allow this if Foo is a distinct type or constdef that has // float as the base type. if (first && type_is_distinct_like(other) && type_underlying_is_numeric(other) && expr_is_const(first)) return other; // See if we can flatten it. diff --git a/test/test_suite/any/generic_interface_stage.c3t b/test/test_suite/any/generic_interface_stage.c3t index 371b45e6f..f46a40224 100644 --- a/test/test_suite/any/generic_interface_stage.c3t +++ b/test/test_suite/any/generic_interface_stage.c3t @@ -1,7 +1,7 @@ import std; fn int foo() => 0; alias FooFn = fn int(); -const enum Bar : FooFn +constdef Bar : FooFn { FOO = fn () => (int)(iptr)ExclusiveRange{int}.typeid, BAR = &foo, diff --git a/test/test_suite/enumerations/const_enum.c3 b/test/test_suite/enumerations/const_enum.c3 index 7ebf564d2..49cdc1e92 100644 --- a/test/test_suite/enumerations/const_enum.c3 +++ b/test/test_suite/enumerations/const_enum.c3 @@ -1,6 +1,6 @@ import std::io; -const enum MyEnum : inline CInt +constdef MyEnum : inline CInt { FOO = 1, BAR = 5, diff --git a/test/test_suite/enumerations/const_enum_inline.c3t b/test/test_suite/enumerations/const_enum_inline.c3t index d2ab2aba8..a923c5b54 100644 --- a/test/test_suite/enumerations/const_enum_inline.c3t +++ b/test/test_suite/enumerations/const_enum_inline.c3t @@ -1,6 +1,6 @@ // #target: macos-x64 module test; -const enum Foo : inline String +constdef Foo : inline String { HELO = "Helo" } diff --git a/test/test_suite/enumerations/const_enum_inline_member.c3t b/test/test_suite/enumerations/const_enum_inline_member.c3t index 662a06d52..7beeac27f 100644 --- a/test/test_suite/enumerations/const_enum_inline_member.c3t +++ b/test/test_suite/enumerations/const_enum_inline_member.c3t @@ -5,7 +5,7 @@ struct Bar uint x, y, z; } -const enum Foo : inline Bar +constdef Foo : inline Bar { X = {1, 0, 0}, Y = {0, 1, 0}, diff --git a/test/test_suite/enumerations/const_enum_methods.c3t b/test/test_suite/enumerations/const_enum_methods.c3t index b176d0556..0e40ff6d9 100644 --- a/test/test_suite/enumerations/const_enum_methods.c3t +++ b/test/test_suite/enumerations/const_enum_methods.c3t @@ -1,7 +1,7 @@ // #target: macos-x64 module test; -const enum Enum : int +constdef Enum : int { E0, E1 } diff --git a/test/test_suite/enumerations/const_enum_self_ref.c3 b/test/test_suite/enumerations/const_enum_self_ref.c3 index 7a5e8d821..e2798b7bd 100644 --- a/test/test_suite/enumerations/const_enum_self_ref.c3 +++ b/test/test_suite/enumerations/const_enum_self_ref.c3 @@ -1,6 +1,6 @@ -const enum MyEnum +constdef MyEnum { - VAL1 = VAL3, // #error: Unable to properly resolve enum constant value, this can sometimes happen in recursive definitions + VAL1 = VAL3, // #error: Unable to properly resolve constdef value, this can sometimes happen in recursive definitions VAL2 , VAL3 } diff --git a/test/test_suite/enumerations/const_enum_vector.c3t b/test/test_suite/enumerations/const_enum_vector.c3t index 307ab99bc..cc9b9f2f3 100644 --- a/test/test_suite/enumerations/const_enum_vector.c3t +++ b/test/test_suite/enumerations/const_enum_vector.c3t @@ -2,7 +2,7 @@ module test; import std; -const enum Color : char[<4>] +constdef Color : char[<4>] { LIGHTGRAY = { 200, 200, 200, 255 }, } diff --git a/test/test_suite/enumerations/const_enum_with_function_ptr.c3t b/test/test_suite/enumerations/const_enum_with_function_ptr.c3t index fdbada087..d06c07d8c 100644 --- a/test/test_suite/enumerations/const_enum_with_function_ptr.c3t +++ b/test/test_suite/enumerations/const_enum_with_function_ptr.c3t @@ -10,7 +10,7 @@ enum Foo : (FooFn f) BAR { &foo }, // allowed } -const enum Bar : FooFn +constdef Bar : FooFn { FOO = fn int() => 0, // allowed BAR = &foo, // Error: Expected an constant enum value. diff --git a/test/test_suite/enumerations/enum_const.c3t b/test/test_suite/enumerations/enum_const.c3t index 147ffc728..fbe2b2977 100644 --- a/test/test_suite/enumerations/enum_const.c3t +++ b/test/test_suite/enumerations/enum_const.c3t @@ -2,13 +2,13 @@ module test; import std; -const enum Bar : String +constdef Bar : String { XABC = "foekf", XDEF = "foekfokef" } -const enum Foo : int +constdef Foo : int { ABC = 4, DEF, @@ -18,7 +18,7 @@ const enum Foo : int } -const enum Bde2 : int +constdef Bde2 : int { FOO = 2, BAR = 100 @@ -30,7 +30,7 @@ const BDE3_BAR = 100; -const enum Abc2 : int +constdef Abc2 : int { UP, DOWN, diff --git a/test/test_suite/enumerations/enum_const_inline_interface.c3 b/test/test_suite/enumerations/enum_const_inline_interface.c3 index 23bfd8a74..2ab0c9fd5 100644 --- a/test/test_suite/enumerations/enum_const_inline_interface.c3 +++ b/test/test_suite/enumerations/enum_const_inline_interface.c3 @@ -12,7 +12,7 @@ fn void Foo.x(&self) @dynamic io::printn("Foo!"); } -const enum Tester : inline Foo +constdef Tester : inline Foo { ABC = 1 } diff --git a/test/test_suite/enumerations/enum_const_resolution_order.c3t b/test/test_suite/enumerations/enum_const_resolution_order.c3t index ea79c2dfb..55cb8eddb 100644 --- a/test/test_suite/enumerations/enum_const_resolution_order.c3t +++ b/test/test_suite/enumerations/enum_const_resolution_order.c3t @@ -8,7 +8,7 @@ struct Foo module bar; -const enum MyEnum : CInt +constdef MyEnum : CInt { VAL1 = 1, VAL2 = 2, diff --git a/test/test_suite/enumerations/enum_no_inline_property.c3 b/test/test_suite/enumerations/enum_no_inline_property.c3 index c8ddbe20e..3185c653d 100644 --- a/test/test_suite/enumerations/enum_no_inline_property.c3 +++ b/test/test_suite/enumerations/enum_no_inline_property.c3 @@ -1,5 +1,5 @@ module test; -const enum MyEnum : inline short +constdef MyEnum : inline short { ITEM1, ITEM2, diff --git a/test/test_suite/enumerations/recursive_const_enum.c3 b/test/test_suite/enumerations/recursive_const_enum.c3 index 2fc65533b..d7b5f8c15 100644 --- a/test/test_suite/enumerations/recursive_const_enum.c3 +++ b/test/test_suite/enumerations/recursive_const_enum.c3 @@ -2,7 +2,7 @@ module main; faultdef F; -const enum Foo : fault +constdef Foo : fault { F = F // #error: Recursive resolution of expression } diff --git a/test/test_suite/expressions/casts/inline_to_underlying.c3t b/test/test_suite/expressions/casts/inline_to_underlying.c3t index d17a31682..8fbe6f7a7 100644 --- a/test/test_suite/expressions/casts/inline_to_underlying.c3t +++ b/test/test_suite/expressions/casts/inline_to_underlying.c3t @@ -6,7 +6,7 @@ enum Foo : inline int { ABC, } -const enum Bar : inline int +constdef Bar : inline int { HELLO = 1 } diff --git a/test/unit/stdlib/collections/linked_map.c3 b/test/unit/stdlib/collections/linked_map.c3 index edb91be04..7a6ca1c1f 100644 --- a/test/unit/stdlib/collections/linked_map.c3 +++ b/test/unit/stdlib/collections/linked_map.c3 @@ -186,7 +186,7 @@ enum Foobar : inline char BAZ } -const enum Foobar2 : inline int +constdef Foobar2 : inline int { ABC = 3, DEF = 5, diff --git a/test/unit/stdlib/collections/map.c3 b/test/unit/stdlib/collections/map.c3 index b04da12c8..0b6e80a3b 100644 --- a/test/unit/stdlib/collections/map.c3 +++ b/test/unit/stdlib/collections/map.c3 @@ -63,7 +63,7 @@ enum Foobar : inline char BAZ } -const enum Foobar2 : inline int +constdef Foobar2 : inline int { ABC = 3, DEF = 5,