Skip to content

Commit

Permalink
Make Error type builtin (#502)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcauberer committed Mar 18, 2024
1 parent ae34b7d commit b8ec751
Show file tree
Hide file tree
Showing 27 changed files with 47 additions and 47 deletions.
2 changes: 1 addition & 1 deletion .run/spicetest.run.xml
@@ -1,5 +1,5 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="spicetest" type="CMakeGoogleTestRunConfigurationType" factoryName="Google Test" PROGRAM_PARAMS="--update-refs=false" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="Spice" TARGET_NAME="spicetest" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="Spice" RUN_TARGET_NAME="spicetest" TEST_CLASS="BootstrapCompilerTests" TEST_MODE="SUITE_TEST">
<configuration default="false" name="spicetest" type="CMakeGoogleTestRunConfigurationType" factoryName="Google Test" PROGRAM_PARAMS="--update-refs=false" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="Spice" TARGET_NAME="spicetest" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="Spice" RUN_TARGET_NAME="spicetest" TEST_MODE="SUITE_TEST">
<envs>
<env name="LLVM_BUILD_INCLUDE_DIR" value="D:/LLVM/build-release/include" />
<env name="LLVM_INCLUDE_DIR" value="D:/LLVM/llvm/include" />
Expand Down
18 changes: 17 additions & 1 deletion docs/docs/language/builtin-types.md
Expand Up @@ -112,4 +112,20 @@ The `Result<T>` builtin type offers the following static functions:
- `Result<T> ok(const T&)`: Returns a Result object with a value
- `Result<T> err(const Error&)`: Returns a Result object with an error
- `Result<T> err(int, string)`: Returns a Result object with an error, constructed with an error code and an error message
- `Result<T> err(string)`: Returns a Result object with an error, constructed with an error message
- `Result<T> 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<T>` 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
8 changes: 6 additions & 2 deletions 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 {
Expand Down Expand Up @@ -77,6 +79,8 @@ public f<ModuleNamePair> 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:
Expand Down
1 change: 0 additions & 1 deletion 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";

Expand Down
1 change: 0 additions & 1 deletion 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";
Expand Down
1 change: 0 additions & 1 deletion 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
Expand Down
1 change: 0 additions & 1 deletion 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";

Expand Down
1 change: 0 additions & 1 deletion src-bootstrap/util/file-util.spice
Expand Up @@ -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 {
Expand Down
2 changes: 2 additions & 0 deletions src/global/RuntimeModuleManager.cpp
Expand Up @@ -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:
Expand Down
8 changes: 6 additions & 2 deletions src/global/RuntimeModuleManager.h
Expand Up @@ -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<const char *, RuntimeModule> TYPE_NAME_TO_RT_MODULE_MAPPING = {
{STROBJ_NAME, STRING_RT},
{RESULTOBJ_NAME, RESULT_RT},
{ERROBJ_NAME, ERROR_RT},
};

const std::unordered_map<const char *, RuntimeModule> FCT_NAME_TO_RT_MODULE_MAPPING = {
Expand All @@ -49,6 +52,7 @@ const std::unordered_map<const char *, RuntimeModule> FCT_NAME_TO_RT_MODULE_MAPP
const std::unordered_map<RuntimeModule, const char *> 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
};
Expand Down
2 changes: 0 additions & 2 deletions std/data/doubly-linked-list.spice
@@ -1,5 +1,3 @@
import "std/type/error";

// Add generic type definitions
type T dyn;

Expand Down
1 change: 0 additions & 1 deletion 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
Expand Down
1 change: 0 additions & 1 deletion 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";
Expand Down
2 changes: 0 additions & 2 deletions std/data/optional.spice
@@ -1,5 +1,3 @@
import "std/type/error";

// Generic types
type T dyn;

Expand Down
2 changes: 0 additions & 2 deletions 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;
Expand Down
2 changes: 0 additions & 2 deletions std/data/red-black-tree.spice
@@ -1,5 +1,3 @@
import "std/type/error";

// Add generic type definitions
type K dyn;
type V dyn;
Expand Down
2 changes: 0 additions & 2 deletions 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;
Expand Down
1 change: 0 additions & 1 deletion std/data/vector.spice
@@ -1,4 +1,3 @@
import "std/type/error";
import "std/iterator/iterable";
import "std/iterator/iterator";
import "std/data/pair";
Expand Down
2 changes: 0 additions & 2 deletions 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";
Expand Down
1 change: 0 additions & 1 deletion 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;
Expand Down
1 change: 0 additions & 1 deletion 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;
Expand Down
2 changes: 0 additions & 2 deletions 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 {
Expand Down
2 changes: 2 additions & 0 deletions std/type/error.spice → 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.
*/
Expand Down
2 changes: 0 additions & 2 deletions std/runtime/result_rt.spice
@@ -1,7 +1,5 @@
#![core.compiler.alwaysKeepOnNameCollision = true]

import "std/type/error";

// Generic types
type T dyn;

Expand Down
2 changes: 0 additions & 2 deletions 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<heap char*> malloc(unsigned long);
Expand Down
Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand Down
Expand Up @@ -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)
Expand Down Expand Up @@ -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 = !{}
Expand Down

0 comments on commit b8ec751

Please sign in to comment.