diff --git a/.run/spicetest.run.xml b/.run/spicetest.run.xml index 4e6a6a964..b13e08ceb 100644 --- a/.run/spicetest.run.xml +++ b/.run/spicetest.run.xml @@ -1,5 +1,5 @@ - + diff --git a/docs/docs/language/builtin-types.md b/docs/docs/language/builtin-types.md index 265bdaf4e..92453547c 100644 --- a/docs/docs/language/builtin-types.md +++ b/docs/docs/language/builtin-types.md @@ -112,4 +112,20 @@ The `Result` builtin type offers the following static functions: - `Result ok(const T&)`: Returns a Result object with a value - `Result err(const Error&)`: Returns a Result object with an error - `Result err(int, string)`: Returns a Result object with an error, constructed with an error code and an error message -- `Result err(string)`: Returns a Result object with an error, constructed with an error message \ No newline at end of file +- `Result err(string)`: Returns a Result object with an error, constructed with an error message + +## The `Error` data type +The `Error` builtin type is used to represent an error. It can be used e.g. in combination with the `Result` type. + +### Constructors +The `Error` builtin type offers the following constructors: + +- `void Error()`: Initialize an empty error object. This object has an error code of 0 and the error message `Runtime error` +- `void Error(int, string)`: Initialize an error object with an error code and an error message +- `void Error(string)`: Initialize an error object with an error message + +### Methods +The `Error` builtin type offers the following methods: + +- `void print()`: Prints the error message to the standard error output +- `void toPanic()`: Triggers a panic with this error \ No newline at end of file diff --git a/src-bootstrap/global/runtime-module-manager.spice b/src-bootstrap/global/runtime-module-manager.spice index e01e08528..5abff8bce 100644 --- a/src-bootstrap/global/runtime-module-manager.spice +++ b/src-bootstrap/global/runtime-module-manager.spice @@ -1,14 +1,16 @@ const string STRING_RT_IMPORT_NAME = "__rt_string"; const string RESULT_RT_IMPORT_NAME = "__rt_result"; +const string ERROR_RT_IMPORT_NAME = "__rt_error"; const string MEMORY_RT_IMPORT_NAME = "__rt_memory"; const string RTTI_RT_IMPORT_NAME = "__rt_rtti"; public type RuntimeModule enum { STRING_RT = 1, RESULT_RT = 2, - ARRAY_RT = 4, - OBJECT_RT = 8 + ERROR_RT = 4, + ARRAY_RT = 8, + OBJECT_RT = 16 } type ModuleNamePair struct { @@ -77,6 +79,8 @@ public f RuntimeModuleManager.resolveNamePair(RuntimeModule requ return ModuleNamePair{STRING_RT_IMPORT_NAME, "string_rt"}; case RuntimeModule::RESULT_RT: return ModuleNamePair{RESULT_RT_IMPORT_NAME, "result_rt"}; + case RuntimeModule::ERROR_RT: + return ModuleNamePair{ERROR_RT_IMPORT_NAME, "error_rt"}; case RuntimeModule::ARRAY_RT: return ModuleNamePair{MEMORY_RT_IMPORT_NAME, "memory_rt"}; case RuntimeModule::OBJECT_RT: diff --git a/src-bootstrap/lexer/lexer.spice b/src-bootstrap/lexer/lexer.spice index 38baa6e87..a2a147377 100644 --- a/src-bootstrap/lexer/lexer.spice +++ b/src-bootstrap/lexer/lexer.spice @@ -1,6 +1,5 @@ // Std imports import "std/data/vector"; -import "std/type/error"; import "std/text/format"; import "std/text/analysis"; diff --git a/src-bootstrap/linker/external-linker-interface.spice b/src-bootstrap/linker/external-linker-interface.spice index a10dd8c55..472d6cc43 100644 --- a/src-bootstrap/linker/external-linker-interface.spice +++ b/src-bootstrap/linker/external-linker-interface.spice @@ -1,7 +1,6 @@ // Std imports import "std/data/vector"; import "std/io/filepath"; -import "std/type/error"; // Own imports import "../driver"; diff --git a/src-bootstrap/reader/reader.spice b/src-bootstrap/reader/reader.spice index c152f2540..d8bbe3b5d 100644 --- a/src-bootstrap/reader/reader.spice +++ b/src-bootstrap/reader/reader.spice @@ -1,7 +1,6 @@ // Std imports import "std/io/filepath"; import "std/io/file"; -import "std/type/error"; import "std/os/os"; // Own imports diff --git a/src-bootstrap/util/block-allocator.spice b/src-bootstrap/util/block-allocator.spice index 4d813df7f..0ddd07328 100644 --- a/src-bootstrap/util/block-allocator.spice +++ b/src-bootstrap/util/block-allocator.spice @@ -1,6 +1,5 @@ // Std imports import "std/data/vector"; -import "std/type/error"; import "std/type/long"; import "std/os/system"; diff --git a/src-bootstrap/util/file-util.spice b/src-bootstrap/util/file-util.spice index 3255ee4c6..158820371 100644 --- a/src-bootstrap/util/file-util.spice +++ b/src-bootstrap/util/file-util.spice @@ -4,7 +4,6 @@ import "std/os/cmd"; import "std/os/env"; import "std/io/file"; import "std/io/filepath"; -import "std/type/error"; import "std/iterator/array-iterator"; public type ExecResult struct { diff --git a/src/global/RuntimeModuleManager.cpp b/src/global/RuntimeModuleManager.cpp index d64757430..72adc80c6 100644 --- a/src/global/RuntimeModuleManager.cpp +++ b/src/global/RuntimeModuleManager.cpp @@ -61,6 +61,8 @@ ModuleNamePair RuntimeModuleManager::resolveNamePair(RuntimeModule runtimeModule return {STRING_RT_IMPORT_NAME, "string_rt"}; case RESULT_RT: return {RESULT_RT_IMPORT_NAME, "result_rt"}; + case ERROR_RT: + return {RESULT_RT_IMPORT_NAME, "error_rt"}; case MEMORY_RT: return {MEMORY_RT_IMPORT_NAME, "memory_rt"}; case RTTI_RT: diff --git a/src/global/RuntimeModuleManager.h b/src/global/RuntimeModuleManager.h index d437ca1b1..78b42f888 100644 --- a/src/global/RuntimeModuleManager.h +++ b/src/global/RuntimeModuleManager.h @@ -16,19 +16,22 @@ class Scope; const char *const STRING_RT_IMPORT_NAME = "__rt_string"; const char *const RESULT_RT_IMPORT_NAME = "__rt_result"; +const char *const ERROR_RT_IMPORT_NAME = "__rt_error"; const char *const MEMORY_RT_IMPORT_NAME = "__rt_memory"; const char *const RTTI_RT_IMPORT_NAME = "__rt_rtti"; enum RuntimeModule : uint8_t { STRING_RT = 1 << 0, RESULT_RT = 1 << 1, - MEMORY_RT = 1 << 2, - RTTI_RT = 1 << 3, + ERROR_RT = 1 << 2, + MEMORY_RT = 1 << 3, + RTTI_RT = 1 << 4, }; const std::unordered_map TYPE_NAME_TO_RT_MODULE_MAPPING = { {STROBJ_NAME, STRING_RT}, {RESULTOBJ_NAME, RESULT_RT}, + {ERROBJ_NAME, ERROR_RT}, }; const std::unordered_map FCT_NAME_TO_RT_MODULE_MAPPING = { @@ -49,6 +52,7 @@ const std::unordered_map FCT_NAME_TO_RT_MODULE_MAPP const std::unordered_map IDENTIFYING_TOP_LEVEL_NAMES = { {STRING_RT, STROBJ_NAME}, // String struct {RESULT_RT, RESULTOBJ_NAME}, // Result struct + {ERROR_RT, ERROBJ_NAME}, // Error struct {MEMORY_RT, "sAlloc"}, // sAlloc function {RTTI_RT, TIOBJ_NAME}, // TypeInfo struct }; diff --git a/std/data/doubly-linked-list.spice b/std/data/doubly-linked-list.spice index 295677aa1..b41265217 100644 --- a/std/data/doubly-linked-list.spice +++ b/std/data/doubly-linked-list.spice @@ -1,5 +1,3 @@ -import "std/type/error"; - // Add generic type definitions type T dyn; diff --git a/std/data/hash-table.spice b/std/data/hash-table.spice index c7cdcc2aa..2b2dd61ce 100644 --- a/std/data/hash-table.spice +++ b/std/data/hash-table.spice @@ -1,6 +1,5 @@ import "std/data/vector"; import "std/data/linked-list"; -import "std/type/error"; import "std/math/hash"; // Generic types for key and value diff --git a/std/data/linked-list.spice b/std/data/linked-list.spice index 6524b699d..57a2d6f33 100644 --- a/std/data/linked-list.spice +++ b/std/data/linked-list.spice @@ -1,4 +1,3 @@ -import "std/type/error"; import "std/iterator/iterable"; import "std/iterator/iterator"; import "std/data/pair"; diff --git a/std/data/optional.spice b/std/data/optional.spice index b8d574b0a..cf0fb9fdc 100644 --- a/std/data/optional.spice +++ b/std/data/optional.spice @@ -1,5 +1,3 @@ -import "std/type/error"; - // Generic types type T dyn; diff --git a/std/data/queue.spice b/std/data/queue.spice index 53ac49cb7..609392253 100644 --- a/std/data/queue.spice +++ b/std/data/queue.spice @@ -1,5 +1,3 @@ -import "std/type/error"; - // Constants const unsigned long INITIAL_ALLOC_COUNT = 5l; const unsigned int RESIZE_FACTOR = 2; diff --git a/std/data/red-black-tree.spice b/std/data/red-black-tree.spice index 6c4a7a4cb..2a9b80fdb 100644 --- a/std/data/red-black-tree.spice +++ b/std/data/red-black-tree.spice @@ -1,5 +1,3 @@ -import "std/type/error"; - // Add generic type definitions type K dyn; type V dyn; diff --git a/std/data/stack.spice b/std/data/stack.spice index 245cf5d19..9498f7157 100644 --- a/std/data/stack.spice +++ b/std/data/stack.spice @@ -1,5 +1,3 @@ -import "std/type/error"; - // Constants const unsigned long INITIAL_ALLOC_COUNT = 5l; const unsigned int RESIZE_FACTOR = 2; diff --git a/std/data/vector.spice b/std/data/vector.spice index 4f9f4b551..1da9c041a 100644 --- a/std/data/vector.spice +++ b/std/data/vector.spice @@ -1,4 +1,3 @@ -import "std/type/error"; import "std/iterator/iterable"; import "std/iterator/iterator"; import "std/data/pair"; diff --git a/std/io/file.spice b/std/io/file.spice index 836fa8165..4daa8d231 100644 --- a/std/io/file.spice +++ b/std/io/file.spice @@ -1,5 +1,3 @@ -import "std/type/error"; - // File open modes public const string MODE_READ = "r"; public const string MODE_WRITE = "w"; diff --git a/std/iterator/array-iterator.spice b/std/iterator/array-iterator.spice index 76a201588..0f64733d0 100644 --- a/std/iterator/array-iterator.spice +++ b/std/iterator/array-iterator.spice @@ -1,6 +1,5 @@ import "std/iterator/iterator"; import "std/data/pair"; -import "std/type/error"; // Generic type definitions type I dyn; diff --git a/std/iterator/number-iterator.spice b/std/iterator/number-iterator.spice index 971406969..385e37daf 100644 --- a/std/iterator/number-iterator.spice +++ b/std/iterator/number-iterator.spice @@ -1,6 +1,5 @@ import "std/iterator/iterator"; import "std/data/pair"; -import "std/type/error"; // Generic type definitions type N int|long|short; diff --git a/std/os/thread.spice b/std/os/thread.spice index b18a1dc0d..e98e00512 100644 --- a/std/os/thread.spice +++ b/std/os/thread.spice @@ -1,7 +1,5 @@ #![core.linker.flag = "-pthread"] -import "std/type/error"; - // Type definitions type Pthread_t alias long; type Pthread_attr_t struct { diff --git a/std/type/error.spice b/std/runtime/error_rt.spice similarity index 92% rename from std/type/error.spice rename to std/runtime/error_rt.spice index fd27ae2f1..b62049fce 100644 --- a/std/type/error.spice +++ b/std/runtime/error_rt.spice @@ -1,3 +1,5 @@ +#![core.compiler.alwaysKeepOnNameCollision = true] + /** * This is the generalized error type in Spice and part of the error handling mechanism. */ diff --git a/std/runtime/result_rt.spice b/std/runtime/result_rt.spice index 8557564e1..2960a7ade 100644 --- a/std/runtime/result_rt.spice +++ b/std/runtime/result_rt.spice @@ -1,7 +1,5 @@ #![core.compiler.alwaysKeepOnNameCollision = true] -import "std/type/error"; - // Generic types type T dyn; diff --git a/std/runtime/string_rt.spice b/std/runtime/string_rt.spice index eabf6b22e..07dcf644e 100644 --- a/std/runtime/string_rt.spice +++ b/std/runtime/string_rt.spice @@ -1,7 +1,5 @@ #![core.compiler.alwaysKeepOnNameCollision = true] -import "std/type/error"; - // Link external functions // We intentionally do not use the memory_rt here to avoid dependency circles ext f malloc(unsigned long); diff --git a/test/test-files/irgenerator/debug-info/success-dbg-info-complex/ir-code.ll b/test/test-files/irgenerator/debug-info/success-dbg-info-complex/ir-code.ll index fcd458a27..d3ecf695d 100644 --- a/test/test-files/irgenerator/debug-info/success-dbg-info-complex/ir-code.ll +++ b/test/test-files/irgenerator/debug-info/success-dbg-info-complex/ir-code.ll @@ -496,7 +496,7 @@ attributes #3 = { cold noreturn nounwind } !0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) !1 = distinct !DIGlobalVariable(name: "printf.str.0", linkageName: "printf.str.0", scope: !2, file: !5, line: 68, type: !6, isLocal: true, isDefinition: true) !2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !3, producer: "spice version dev (https://github.com/spicelang/spice)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None) -!3 = !DIFile(filename: "C:\\Users\\Marc\\Documents\\JustForFunGitHubClonesFast\\spice\\cmake-build-debug\\test\\test-files\\irgenerator\\debug-info\\success-dbg-info-complex\\source.spice", directory: ".\\test-files\\irgenerator\\debug-info\\success-dbg-info-complex") +!3 = !DIFile(filename: "C:\\Users\\Marc\\Documents\\JustForFunGitHubClonesFast\\spice\\cmake-build-release\\test\\test-files\\irgenerator\\debug-info\\success-dbg-info-complex\\source.spice", directory: ".\\test-files\\irgenerator\\debug-info\\success-dbg-info-complex") !4 = !{!0} !5 = !DIFile(filename: "source.spice", directory: ".\\test-files\\irgenerator\\debug-info\\success-dbg-info-complex") !6 = !DIStringType(name: "printf.str.0", size: 192) @@ -521,14 +521,14 @@ attributes #3 = { cold noreturn nounwind } !25 = !DILocalVariable(name: "_argc", arg: 1, scope: !15, file: !5, line: 4, type: !18) !26 = !DILocalVariable(name: "_argv", arg: 2, scope: !15, file: !5, line: 4, type: !19) !27 = !DILocalVariable(name: "vi", scope: !15, file: !5, line: 6, type: !28) -!28 = !DICompositeType(tag: DW_TAG_structure_type, name: "Vector", scope: !29, file: !29, line: 26, size: 256, align: 8, flags: DIFlagTypePassByReference | DIFlagNonTrivial, elements: !30, identifier: "struct.Vector") +!28 = !DICompositeType(tag: DW_TAG_structure_type, name: "Vector", scope: !29, file: !29, line: 25, size: 256, align: 8, flags: DIFlagTypePassByReference | DIFlagNonTrivial, elements: !30, identifier: "struct.Vector") !29 = !DIFile(filename: "vector.spice", directory: "C:\\Users\\Marc\\Documents\\JustForFunGitHubClonesFast\\spice\\std\\data") !30 = !{!31, !33, !35} -!31 = !DIDerivedType(tag: DW_TAG_member, name: "contents", scope: !28, file: !29, line: 27, baseType: !32, size: 64, offset: 64) +!31 = !DIDerivedType(tag: DW_TAG_member, name: "contents", scope: !28, file: !29, line: 26, baseType: !32, size: 64, offset: 64) !32 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !18, size: 64) -!33 = !DIDerivedType(tag: DW_TAG_member, name: "capacity", scope: !28, file: !29, line: 28, baseType: !34, size: 64, offset: 128) +!33 = !DIDerivedType(tag: DW_TAG_member, name: "capacity", scope: !28, file: !29, line: 27, baseType: !34, size: 64, offset: 128) !34 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) -!35 = !DIDerivedType(tag: DW_TAG_member, name: "size", scope: !28, file: !29, line: 29, baseType: !34, size: 64, offset: 192) +!35 = !DIDerivedType(tag: DW_TAG_member, name: "size", scope: !28, file: !29, line: 28, baseType: !34, size: 64, offset: 192) !36 = !DILocation(line: 6, column: 5, scope: !15) !37 = !DILocation(line: 6, column: 22, scope: !15) !38 = !DILocation(line: 7, column: 17, scope: !15) @@ -539,11 +539,11 @@ attributes #3 = { cold noreturn nounwind } !43 = !{!"branch_weights", i32 2000, i32 1} !44 = !DILocation(line: 13, column: 14, scope: !15) !45 = !DILocalVariable(name: "it", scope: !15, file: !5, line: 13, type: !46) -!46 = !DICompositeType(tag: DW_TAG_structure_type, name: "VectorIterator", scope: !29, file: !29, line: 254, size: 192, align: 8, flags: DIFlagTypePassByReference | DIFlagNonTrivial, elements: !47, identifier: "struct.VectorIterator") +!46 = !DICompositeType(tag: DW_TAG_structure_type, name: "VectorIterator", scope: !29, file: !29, line: 253, size: 192, align: 8, flags: DIFlagTypePassByReference | DIFlagNonTrivial, elements: !47, identifier: "struct.VectorIterator") !47 = !{!48, !50} -!48 = !DIDerivedType(tag: DW_TAG_member, name: "vector", scope: !46, file: !29, line: 255, baseType: !49, size: 64, offset: 64) +!48 = !DIDerivedType(tag: DW_TAG_member, name: "vector", scope: !46, file: !29, line: 254, baseType: !49, size: 64, offset: 64) !49 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !28, size: 64) -!50 = !DIDerivedType(tag: DW_TAG_member, name: "cursor", scope: !46, file: !29, line: 256, baseType: !34, size: 64, offset: 128) +!50 = !DIDerivedType(tag: DW_TAG_member, name: "cursor", scope: !46, file: !29, line: 255, baseType: !34, size: 64, offset: 128) !51 = !DILocation(line: 13, column: 5, scope: !15) !52 = !DILocation(line: 14, column: 12, scope: !15) !53 = !DILocation(line: 15, column: 12, scope: !15) diff --git a/test/test-files/irgenerator/debug-info/success-dbg-info-simple/ir-code.ll b/test/test-files/irgenerator/debug-info/success-dbg-info-simple/ir-code.ll index a4897d5c1..b505a80a4 100644 --- a/test/test-files/irgenerator/debug-info/success-dbg-info-simple/ir-code.ll +++ b/test/test-files/irgenerator/debug-info/success-dbg-info-simple/ir-code.ll @@ -92,7 +92,7 @@ attributes #3 = { nofree nounwind } !0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) !1 = distinct !DIGlobalVariable(name: "anon.string.0", linkageName: "anon.string.0", scope: !2, file: !7, line: 8, type: !15, isLocal: true, isDefinition: true) !2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !3, producer: "spice version dev (https://github.com/spicelang/spice)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None) -!3 = !DIFile(filename: "C:\\Users\\Marc\\Documents\\JustForFunGitHubClonesFast\\spice\\cmake-build-debug\\test\\test-files\\irgenerator\\debug-info\\success-dbg-info-simple\\source.spice", directory: ".\\test-files\\irgenerator\\debug-info\\success-dbg-info-simple") +!3 = !DIFile(filename: "C:\\Users\\Marc\\Documents\\JustForFunGitHubClonesFast\\spice\\cmake-build-release\\test\\test-files\\irgenerator\\debug-info\\success-dbg-info-simple\\source.spice", directory: ".\\test-files\\irgenerator\\debug-info\\success-dbg-info-simple") !4 = !{!0, !5, !9, !12} !5 = !DIGlobalVariableExpression(var: !6, expr: !DIExpression()) !6 = distinct !DIGlobalVariable(name: "printf.str.0", linkageName: "printf.str.0", scope: !2, file: !7, line: 15, type: !8, isLocal: true, isDefinition: true) @@ -122,15 +122,15 @@ attributes #3 = { nofree nounwind } !30 = !DIDerivedType(tag: DW_TAG_member, name: "lng", scope: !28, file: !7, line: 2, baseType: !31, size: 64) !31 = !DIBasicType(name: "long", size: 64, encoding: DW_ATE_signed) !32 = !DIDerivedType(tag: DW_TAG_member, name: "str", scope: !28, file: !7, line: 3, baseType: !33, size: 192, align: 8, offset: 64) -!33 = !DICompositeType(tag: DW_TAG_structure_type, name: "String", scope: !34, file: !34, line: 20, size: 192, align: 8, flags: DIFlagTypePassByReference | DIFlagNonTrivial, elements: !35, identifier: "struct.String") +!33 = !DICompositeType(tag: DW_TAG_structure_type, name: "String", scope: !34, file: !34, line: 18, size: 192, align: 8, flags: DIFlagTypePassByReference | DIFlagNonTrivial, elements: !35, identifier: "struct.String") !34 = !DIFile(filename: "string_rt.spice", directory: "C:\\Users\\Marc\\Documents\\JustForFunGitHubClonesFast\\spice\\std\\runtime") !35 = !{!36, !39, !41} -!36 = !DIDerivedType(tag: DW_TAG_member, name: "contents", scope: !33, file: !34, line: 21, baseType: !37, size: 64) +!36 = !DIDerivedType(tag: DW_TAG_member, name: "contents", scope: !33, file: !34, line: 19, baseType: !37, size: 64) !37 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !38, size: 64) !38 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_unsigned_char) -!39 = !DIDerivedType(tag: DW_TAG_member, name: "capacity", scope: !33, file: !34, line: 22, baseType: !40, size: 64, offset: 64) +!39 = !DIDerivedType(tag: DW_TAG_member, name: "capacity", scope: !33, file: !34, line: 20, baseType: !40, size: 64, offset: 64) !40 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) -!41 = !DIDerivedType(tag: DW_TAG_member, name: "length", scope: !33, file: !34, line: 23, baseType: !40, size: 64, offset: 128) +!41 = !DIDerivedType(tag: DW_TAG_member, name: "length", scope: !33, file: !34, line: 21, baseType: !40, size: 64, offset: 128) !42 = !DIDerivedType(tag: DW_TAG_member, name: "i", scope: !28, file: !7, line: 4, baseType: !43, size: 32, offset: 256) !43 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) !44 = !{}