parent
37aae53009
commit
5c18826240
@ -7,7 +7,7 @@ Root : many(TopLevelDecl) "EOF"
|
||||
|
||||
TopLevelDecl : FnDef | ExternBlock | RootExportDecl | Import | ContainerDecl | VariableDeclaration | ErrorValueDecl
|
||||
|
||||
ErrorValueDecl : option(FnVisibleMod) "%." "Symbol"
|
||||
ErrorValueDecl : option(FnVisibleMod) "error" "Symbol"
|
||||
|
||||
VariableDeclaration : option(FnVisibleMod) ("var" | "const") "Symbol" ("=" Expression | ":" PrefixOpExpression option("=" Expression))
|
||||
|
||||
@ -133,9 +133,9 @@ ContainerInitBody : list(StructLiteralField, ",") | list(Expression, ",")
|
||||
|
||||
StructLiteralField : "." "Symbol" "=" Expression
|
||||
|
||||
PrefixOp : "!" | "-" | "~" | "*" | ("&" option("const")) | "?"
|
||||
PrefixOp : "!" | "-" | "~" | "*" | ("&" option("const")) | "?" | "%"
|
||||
|
||||
PrimaryExpression : "Number" | "String" | "CharLiteral" | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | "Symbol" | ("@" "Symbol" FnCallExpression) | ArrayType | AsmExpression | ("%." "Symbol")
|
||||
PrimaryExpression : "Number" | "String" | "CharLiteral" | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | "Symbol" | ("@" "Symbol" FnCallExpression) | ArrayType | AsmExpression | ("error" "." "Symbol")
|
||||
|
||||
ArrayType : "[" option(Expression) "]" option("const") PrefixOpExpression
|
||||
|
||||
@ -143,7 +143,7 @@ GotoExpression: "goto" "Symbol"
|
||||
|
||||
GroupedExpression : "(" Expression ")"
|
||||
|
||||
KeywordLiteral : "true" | "false" | "null" | "break" | "continue" | "undefined"
|
||||
KeywordLiteral : "true" | "false" | "null" | "break" | "continue" | "undefined" | "error"
|
||||
```
|
||||
|
||||
## Operator Precedence
|
||||
|
@ -15,7 +15,7 @@ syn keyword zigRepeat while for
|
||||
|
||||
syn keyword zigConstant null undefined
|
||||
syn keyword zigKeyword fn import
|
||||
syn keyword zigType bool i8 u8 i16 u16 i32 u32 i64 u64 isize usize f32 f64 f128 void unreachable type
|
||||
syn keyword zigType bool i8 u8 i16 u16 i32 u32 i64 u64 isize usize f32 f64 f128 void unreachable type error
|
||||
|
||||
syn keyword zigBoolean true false
|
||||
|
||||
|
@ -10,6 +10,7 @@ import "std.zig";
|
||||
// * %% binary operator
|
||||
// * %% prefix operator
|
||||
// * cast err type to string
|
||||
// * string equality
|
||||
|
||||
pub fn main(args: [][]u8) %void => {
|
||||
const exe = args[0];
|
||||
@ -39,7 +40,7 @@ pub fn main(args: [][]u8) %void => {
|
||||
|
||||
fn usage(exe: []u8) %void => {
|
||||
%%stderr.print("Usage: {} [FILE]...\n", exe);
|
||||
return %.Invalid;
|
||||
return error.Invalid;
|
||||
}
|
||||
|
||||
fn cat_stream(is: InputStream) %void => {
|
||||
|
@ -3,8 +3,8 @@ export executable "guess_number";
|
||||
import "std.zig";
|
||||
import "rand.zig";
|
||||
|
||||
%.GetRandomFail;
|
||||
%.ReadInputFail;
|
||||
error GetRandomFail;
|
||||
error ReadInputFail;
|
||||
|
||||
pub fn main(args: [][]u8) %void => {
|
||||
print_str("Welcome to the Guess Number Game in Zig.\n");
|
||||
@ -15,7 +15,7 @@ pub fn main(args: [][]u8) %void => {
|
||||
if (err != @sizeof(u32)) {
|
||||
// TODO full error message
|
||||
fprint_str(stderr_fileno, "unable to get random bytes\n");
|
||||
return %.GetRandomFail;
|
||||
return error.GetRandomFail;
|
||||
}
|
||||
|
||||
var rand : Rand;
|
||||
@ -31,7 +31,7 @@ pub fn main(args: [][]u8) %void => {
|
||||
if (readline(line_buf, &line_len) || line_len == line_buf.len) {
|
||||
// TODO full error message
|
||||
fprint_str(stderr_fileno, "unable to read input\n");
|
||||
return %.ReadInputFail;
|
||||
return error.ReadInputFail;
|
||||
}
|
||||
|
||||
var guess : u64;
|
||||
|
@ -133,7 +133,6 @@ enum NodeType {
|
||||
NodeTypeNumberLiteral,
|
||||
NodeTypeStringLiteral,
|
||||
NodeTypeCharLiteral,
|
||||
NodeTypeErrorLiteral,
|
||||
NodeTypeSymbol,
|
||||
NodeTypePrefixOpExpr,
|
||||
NodeTypeFnCallExpr,
|
||||
@ -161,6 +160,7 @@ enum NodeType {
|
||||
NodeTypeContainerInitExpr,
|
||||
NodeTypeStructValueField,
|
||||
NodeTypeArrayType,
|
||||
NodeTypeErrorType,
|
||||
};
|
||||
|
||||
struct AstNodeRoot {
|
||||
@ -315,6 +315,7 @@ enum CastOp {
|
||||
CastOpToUnknownSizeArray,
|
||||
CastOpMaybeWrap,
|
||||
CastOpErrorWrap,
|
||||
CastOpPureErrorWrap,
|
||||
CastOpPointerReinterpret,
|
||||
CastOpErrToInt,
|
||||
};
|
||||
@ -584,13 +585,6 @@ struct AstNodeNumberLiteral {
|
||||
Expr resolved_expr;
|
||||
};
|
||||
|
||||
struct AstNodeErrorLiteral {
|
||||
Buf symbol;
|
||||
|
||||
// populated by semantic analyzer
|
||||
Expr resolved_expr;
|
||||
};
|
||||
|
||||
struct AstNodeStructValueField {
|
||||
Buf name;
|
||||
AstNode *expr;
|
||||
@ -663,6 +657,11 @@ struct AstNodeArrayType {
|
||||
Expr resolved_expr;
|
||||
};
|
||||
|
||||
struct AstNodeErrorType {
|
||||
// populated by semantic analyzer
|
||||
Expr resolved_expr;
|
||||
};
|
||||
|
||||
struct AstNode {
|
||||
enum NodeType type;
|
||||
int line;
|
||||
@ -705,7 +704,6 @@ struct AstNode {
|
||||
AstNodeStringLiteral string_literal;
|
||||
AstNodeCharLiteral char_literal;
|
||||
AstNodeNumberLiteral number_literal;
|
||||
AstNodeErrorLiteral error_literal;
|
||||
AstNodeContainerInitExpr container_init_expr;
|
||||
AstNodeStructValueField struct_val_field;
|
||||
AstNodeNullLiteral null_literal;
|
||||
@ -715,6 +713,7 @@ struct AstNode {
|
||||
AstNodeBreakExpr break_expr;
|
||||
AstNodeContinueExpr continue_expr;
|
||||
AstNodeArrayType array_type;
|
||||
AstNodeErrorType error_type;
|
||||
} data;
|
||||
};
|
||||
|
||||
@ -820,7 +819,8 @@ enum TypeTableEntryId {
|
||||
TypeTableEntryIdNumLitInt,
|
||||
TypeTableEntryIdUndefLit,
|
||||
TypeTableEntryIdMaybe,
|
||||
TypeTableEntryIdError,
|
||||
TypeTableEntryIdErrorUnion,
|
||||
TypeTableEntryIdPureError,
|
||||
TypeTableEntryIdEnum,
|
||||
TypeTableEntryIdFn,
|
||||
};
|
||||
@ -961,6 +961,7 @@ struct CodeGen {
|
||||
TypeTableEntry *entry_num_lit_int;
|
||||
TypeTableEntry *entry_num_lit_float;
|
||||
TypeTableEntry *entry_undef;
|
||||
TypeTableEntry *entry_pure_error;
|
||||
} builtin_types;
|
||||
|
||||
LLVMTargetDataRef target_data_ref;
|
||||
|
161
src/analyze.cpp
161
src/analyze.cpp
@ -19,6 +19,8 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE
|
||||
static TypeTableEntry *unwrapped_node_type(AstNode *node);
|
||||
static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
|
||||
AstNode *node);
|
||||
static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *import,
|
||||
BlockContext *context, AstNode *node, Buf *err_name);
|
||||
|
||||
static AstNode *first_executing_node(AstNode *node) {
|
||||
switch (node->type) {
|
||||
@ -47,7 +49,6 @@ static AstNode *first_executing_node(AstNode *node) {
|
||||
case NodeTypeVariableDeclaration:
|
||||
case NodeTypeErrorValueDecl:
|
||||
case NodeTypeNumberLiteral:
|
||||
case NodeTypeErrorLiteral:
|
||||
case NodeTypeStringLiteral:
|
||||
case NodeTypeCharLiteral:
|
||||
case NodeTypeSymbol:
|
||||
@ -71,6 +72,7 @@ static AstNode *first_executing_node(AstNode *node) {
|
||||
case NodeTypeSwitchExpr:
|
||||
case NodeTypeSwitchProng:
|
||||
case NodeTypeArrayType:
|
||||
case NodeTypeErrorType:
|
||||
case NodeTypeContainerInitExpr:
|
||||
return node;
|
||||
}
|
||||
@ -110,7 +112,8 @@ TypeTableEntry *new_type_table_entry(TypeTableEntryId id) {
|
||||
case TypeTableEntryIdNumLitInt:
|
||||
case TypeTableEntryIdMaybe:
|
||||
case TypeTableEntryIdFn:
|
||||
case TypeTableEntryIdError:
|
||||
case TypeTableEntryIdErrorUnion:
|
||||
case TypeTableEntryIdPureError:
|
||||
case TypeTableEntryIdUndefLit:
|
||||
// nothing to init
|
||||
break;
|
||||
@ -200,7 +203,7 @@ static TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type) {
|
||||
"val", di_file, line, child_type->size_in_bits, child_type->align_in_bits, 0, 0,
|
||||
child_type->di_type),
|
||||
LLVMZigCreateDebugMemberType(g->dbuilder, LLVMZigTypeToScope(entry->di_type),
|
||||
"maybe", di_file, line, 8, 8, 8, 0,
|
||||
"maybe", di_file, line, 8, 8, child_type->size_in_bits, 0,
|
||||
child_type->di_type),
|
||||
};
|
||||
LLVMZigDIType *replacement_di_type = LLVMZigCreateDebugStructType(g->dbuilder,
|
||||
@ -223,7 +226,7 @@ static TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) {
|
||||
if (child_type->error_parent) {
|
||||
return child_type->error_parent;
|
||||
} else {
|
||||
TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdError);
|
||||
TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdErrorUnion);
|
||||
assert(child_type->type_ref);
|
||||
assert(child_type->di_type);
|
||||
|
||||
@ -239,7 +242,38 @@ static TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) {
|
||||
entry->di_type = g->err_tag_type->di_type;
|
||||
|
||||
} else {
|
||||
zig_panic("TODO get_error_type non-void");
|
||||
LLVMTypeRef elem_types[] = {
|
||||
g->err_tag_type->type_ref,
|
||||
child_type->type_ref,
|
||||
};
|
||||
entry->type_ref = LLVMStructType(elem_types, 2, false);
|
||||
entry->size_in_bits = g->err_tag_type->size_in_bits + child_type->size_in_bits;
|
||||
entry->align_in_bits = g->err_tag_type->align_in_bits;
|
||||
|
||||
LLVMZigDIScope *compile_unit_scope = LLVMZigCompileUnitToScope(g->compile_unit);
|
||||
LLVMZigDIFile *di_file = nullptr;
|
||||
unsigned line = 0;
|
||||
entry->di_type = LLVMZigCreateReplaceableCompositeType(g->dbuilder,
|
||||
LLVMZigTag_DW_structure_type(), buf_ptr(&entry->name),
|
||||
compile_unit_scope, di_file, line);
|
||||
|
||||
LLVMZigDIType *di_element_types[] = {
|
||||
LLVMZigCreateDebugMemberType(g->dbuilder, LLVMZigTypeToScope(entry->di_type),
|
||||
"tag", di_file, line, g->err_tag_type->size_in_bits, g->err_tag_type->align_in_bits,
|
||||
0, 0, child_type->di_type),
|
||||
LLVMZigCreateDebugMemberType(g->dbuilder, LLVMZigTypeToScope(entry->di_type),
|
||||
"value", di_file, line, child_type->size_in_bits, child_type->align_in_bits,
|
||||
g->err_tag_type->size_in_bits, 0, child_type->di_type),
|
||||
};
|
||||
|
||||
LLVMZigDIType *replacement_di_type = LLVMZigCreateDebugStructType(g->dbuilder,
|
||||
compile_unit_scope,
|
||||
buf_ptr(&entry->name),
|
||||
di_file, line, entry->size_in_bits, entry->align_in_bits, 0,
|
||||
nullptr, di_element_types, 2, 0, nullptr, "");
|
||||
|
||||
LLVMZigReplaceTemporary(g->dbuilder, entry->di_type, replacement_di_type);
|
||||
entry->di_type = replacement_di_type;
|
||||
}
|
||||
|
||||
child_type->error_parent = entry;
|
||||
@ -1012,7 +1046,6 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode
|
||||
case NodeTypeArrayAccessExpr:
|
||||
case NodeTypeSliceExpr:
|
||||
case NodeTypeNumberLiteral:
|
||||
case NodeTypeErrorLiteral:
|
||||
case NodeTypeStringLiteral:
|
||||
case NodeTypeCharLiteral:
|
||||
case NodeTypeBoolLiteral:
|
||||
@ -1037,6 +1070,7 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode
|
||||
case NodeTypeStructValueField:
|
||||
case NodeTypeContainerInitExpr:
|
||||
case NodeTypeArrayType:
|
||||
case NodeTypeErrorType:
|
||||
zig_unreachable();
|
||||
}
|
||||
}
|
||||
@ -1083,7 +1117,8 @@ static bool type_has_codegen_value(TypeTableEntryId id) {
|
||||
case TypeTableEntryIdArray:
|
||||
case TypeTableEntryIdStruct:
|
||||
case TypeTableEntryIdMaybe:
|
||||
case TypeTableEntryIdError:
|
||||
case TypeTableEntryIdErrorUnion:
|
||||
case TypeTableEntryIdPureError:
|
||||
case TypeTableEntryIdEnum:
|
||||
case TypeTableEntryIdFn:
|
||||
return true;
|
||||
@ -1166,8 +1201,8 @@ static bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTable
|
||||
}
|
||||
|
||||
// error
|
||||
if (expected_type->id == TypeTableEntryIdError &&
|
||||
actual_type->id == TypeTableEntryIdError)
|
||||
if (expected_type->id == TypeTableEntryIdErrorUnion &&
|
||||
actual_type->id == TypeTableEntryIdErrorUnion)
|
||||
{
|
||||
return types_match_const_cast_only(
|
||||
expected_type->data.error.child_type,
|
||||
@ -1224,11 +1259,11 @@ static TypeTableEntry *determine_peer_type_compatibility(CodeGen *g, AstNode *pa
|
||||
prev_type = cur_type;
|
||||
prev_node = cur_node;
|
||||
}
|
||||
} else if (prev_type->id == TypeTableEntryIdError &&
|
||||
} else if (prev_type->id == TypeTableEntryIdErrorUnion &&
|
||||
types_match_const_cast_only(prev_type->data.error.child_type, cur_type))
|
||||
{
|
||||
continue;
|
||||
} else if (cur_type->id == TypeTableEntryIdError &&
|
||||
} else if (cur_type->id == TypeTableEntryIdErrorUnion &&
|
||||
types_match_const_cast_only(cur_type->data.error.child_type, prev_type))
|
||||
{
|
||||
prev_type = cur_type;
|
||||
@ -1287,13 +1322,20 @@ static bool types_match_with_implicit_cast(CodeGen *g, TypeTableEntry *expected_
|
||||
}
|
||||
|
||||
// implicit conversion from error child type to error type
|
||||
if (expected_type->id == TypeTableEntryIdError &&
|
||||
if (expected_type->id == TypeTableEntryIdErrorUnion &&
|
||||
types_match_with_implicit_cast(g, expected_type->data.error.child_type, actual_type,
|
||||
literal_node, reported_err))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// implicit conversion from pure error to error union type
|
||||
if (expected_type->id == TypeTableEntryIdErrorUnion &&
|
||||
actual_type->id == TypeTableEntryIdPureError)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// implicit widening conversion
|
||||
if (expected_type->id == TypeTableEntryIdInt &&
|
||||
actual_type->id == TypeTableEntryIdInt &&
|
||||
@ -1695,12 +1737,11 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i
|
||||
|
||||
AstNode *struct_expr_node = node->data.field_access_expr.struct_expr;
|
||||
TypeTableEntry *struct_type = analyze_expression(g, import, context, nullptr, struct_expr_node);
|
||||
Buf *field_name = &node->data.field_access_expr.field_name;
|
||||
|
||||
if (struct_type->id == TypeTableEntryIdStruct || (struct_type->id == TypeTableEntryIdPointer &&
|
||||
struct_type->data.pointer.child_type->id == TypeTableEntryIdStruct))
|
||||
{
|
||||
Buf *field_name = &node->data.field_access_expr.field_name;
|
||||
|
||||
TypeTableEntry *bare_struct_type = (struct_type->id == TypeTableEntryIdStruct) ?
|
||||
struct_type : struct_type->data.pointer.child_type;
|
||||
|
||||
@ -1713,15 +1754,14 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i
|
||||
return g->builtin_types.entry_invalid;
|
||||
}
|
||||
} else if (struct_type->id == TypeTableEntryIdArray) {
|
||||
Buf *name = &node->data.field_access_expr.field_name;
|
||||
if (buf_eql_str(name, "len")) {
|
||||
if (buf_eql_str(field_name, "len")) {
|
||||
return g->builtin_types.entry_isize;
|
||||
} else if (buf_eql_str(name, "ptr")) {
|
||||
} else if (buf_eql_str(field_name, "ptr")) {
|
||||
// TODO determine whether the pointer should be const
|
||||
return get_pointer_to_type(g, struct_type->data.array.child_type, false);
|
||||
} else {
|
||||
add_node_error(g, node,
|
||||
buf_sprintf("no member named '%s' in '%s'", buf_ptr(name),
|
||||
buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name),
|
||||
buf_ptr(&struct_type->name)));
|
||||
return g->builtin_types.entry_invalid;
|
||||
}
|
||||
@ -1731,8 +1771,9 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i
|
||||
if (enum_type->id == TypeTableEntryIdInvalid) {
|
||||
return g->builtin_types.entry_invalid;
|
||||
} else if (enum_type->id == TypeTableEntryIdEnum) {
|
||||
Buf *field_name = &node->data.field_access_expr.field_name;
|
||||
return analyze_enum_value_expr(g, import, context, node, nullptr, enum_type, field_name);
|
||||
} else if (enum_type->id == TypeTableEntryIdPureError) {
|
||||
return analyze_error_literal_expr(g, import, context, node, field_name);
|
||||
} else {
|
||||
add_node_error(g, node,
|
||||
buf_sprintf("type '%s' does not support field access", buf_ptr(&struct_type->name)));
|
||||
@ -1846,7 +1887,7 @@ static TypeTableEntry *resolve_expr_const_val_as_err(CodeGen *g, AstNode *node,
|
||||
Expr *expr = get_resolved_expr(node);
|
||||
expr->const_val.ok = true;
|
||||
expr->const_val.data.x_err.err = err;
|
||||
return get_error_type(g, g->builtin_types.entry_void);
|
||||
return g->builtin_types.entry_pure_error;
|
||||
}
|
||||
|
||||
static TypeTableEntry *resolve_expr_const_val_as_bool(CodeGen *g, AstNode *node, bool value) {
|
||||
@ -1959,6 +2000,21 @@ static TypeTableEntry *resolve_expr_const_val_as_bignum_op(CodeGen *g, AstNode *
|
||||
return resolved_type;
|
||||
}
|
||||
|
||||
static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *import,
|
||||
BlockContext *context, AstNode *node, Buf *err_name)
|
||||
{
|
||||
auto err_table_entry = import->block_context->error_table.maybe_get(err_name);
|
||||
|
||||
if (err_table_entry) {
|
||||
return resolve_expr_const_val_as_err(g, node, err_table_entry->value);
|
||||
}
|
||||
|
||||
add_node_error(g, node,
|
||||
buf_sprintf("use of undeclared error value '%s'", buf_ptr(err_name)));
|
||||
|
||||
return get_error_type(g, g->builtin_types.entry_void);
|
||||
}
|
||||
|
||||
|
||||
static TypeTableEntry *analyze_symbol_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
|
||||
TypeTableEntry *expected_type, AstNode *node)
|
||||
@ -2564,23 +2620,6 @@ static TypeTableEntry *analyze_number_literal_expr(CodeGen *g, ImportTableEntry
|
||||
}
|
||||
}
|
||||
|
||||
static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *import,
|
||||
BlockContext *block_context, TypeTableEntry *expected_type, AstNode *node)
|
||||
{
|
||||
Buf *err_name = &node->data.error_literal.symbol;
|
||||
|
||||
auto err_table_entry = import->block_context->error_table.maybe_get(err_name);
|
||||
|
||||
if (err_table_entry) {
|
||||
return resolve_expr_const_val_as_err(g, node, err_table_entry->value);
|
||||
}
|
||||
|
||||
add_node_error(g, node,
|
||||
buf_sprintf("use of undeclared error value '%s'", buf_ptr(err_name)));
|
||||
|
||||
return get_error_type(g, g->builtin_types.entry_void);
|
||||
}
|
||||
|
||||
static TypeTableEntry *analyze_array_type(CodeGen *g, ImportTableEntry *import, BlockContext *context,
|
||||
TypeTableEntry *expected_type, AstNode *node)
|
||||
{
|
||||
@ -2906,6 +2945,10 @@ static void eval_const_expr_implicit_cast(CodeGen *g, AstNode *node, AstNode *ex
|
||||
const_val->data.x_err.payload = other_val;
|
||||
const_val->ok = true;
|
||||
break;
|
||||
case CastOpPureErrorWrap:
|
||||
const_val->data.x_err.err = other_val->data.x_err.err;
|
||||
const_val->ok = true;
|
||||
break;
|
||||
case CastOpErrToInt:
|
||||
{
|
||||
uint64_t value = other_val->data.x_err.err ? other_val->data.x_err.err->value : 0;
|
||||
@ -3007,7 +3050,7 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B
|
||||
}
|
||||
|
||||
// explicit cast from child type of error type to error type
|
||||
if (wanted_type->id == TypeTableEntryIdError) {
|
||||
if (wanted_type->id == TypeTableEntryIdErrorUnion) {
|
||||
if (types_match_const_cast_only(wanted_type->data.error.child_type, actual_type)) {
|
||||
node->data.fn_call_expr.cast_op = CastOpErrorWrap;
|
||||
eval_const_expr_implicit_cast(g, node, expr_node);
|
||||
@ -3025,6 +3068,15 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B
|
||||
}
|
||||
}
|
||||
|
||||
// explicit cast from pure error to error union type
|
||||
if (wanted_type->id == TypeTableEntryIdErrorUnion &&
|
||||
actual_type->id == TypeTableEntryIdPureError)
|
||||
{
|
||||
node->data.fn_call_expr.cast_op = CastOpPureErrorWrap;
|
||||
eval_const_expr_implicit_cast(g, node, expr_node);
|
||||
return wanted_type;
|
||||
}
|
||||
|
||||
// explicit cast from number literal to another type
|
||||
if (actual_type->id == TypeTableEntryIdNumLitFloat ||
|
||||
actual_type->id == TypeTableEntryIdNumLitInt)
|
||||
@ -3039,8 +3091,10 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B
|
||||
}
|
||||
|
||||
// explicit cast from %void to integer type which can fit it
|
||||
if (actual_type->id == TypeTableEntryIdError &&
|
||||
actual_type->data.error.child_type->size_in_bits == 0 &&
|
||||
bool actual_type_is_void_err = actual_type->id == TypeTableEntryIdErrorUnion &&
|
||||
actual_type->data.error.child_type->size_in_bits == 0;
|
||||
bool actual_type_is_pure_err = actual_type->id == TypeTableEntryIdPureError;
|
||||
if ((actual_type_is_void_err || actual_type_is_pure_err) &&
|
||||
wanted_type->id == TypeTableEntryIdInt)
|
||||
{
|
||||
BigNum bn;
|
||||
@ -3754,9 +3808,6 @@ static TypeTableEntry *analyze_expression(CodeGen *g, ImportTableEntry *import,
|
||||
case NodeTypeNumberLiteral:
|
||||
return_type = analyze_number_literal_expr(g, import, context, expected_type, node);
|
||||
break;
|
||||
case NodeTypeErrorLiteral:
|
||||
return_type = analyze_error_literal_expr(g, import, context, expected_type, node);
|
||||
break;
|
||||
case NodeTypeStringLiteral:
|
||||
return_type = analyze_string_literal_expr(g, import, context, expected_type, node);
|
||||
break;
|
||||
@ -3794,6 +3845,9 @@ static TypeTableEntry *analyze_expression(CodeGen *g, ImportTableEntry *import,
|
||||
case NodeTypeArrayType:
|
||||
return_type = analyze_array_type(g, import, context, expected_type, node);
|
||||
break;
|
||||
case NodeTypeErrorType:
|
||||
return_type = resolve_expr_const_val_as_type(g, node, g->builtin_types.entry_pure_error);
|
||||
break;
|
||||
case NodeTypeSwitchExpr:
|
||||
return_type = analyze_switch_expr(g, import, context, expected_type, node);
|
||||
break;
|
||||
@ -3933,7 +3987,6 @@ static void analyze_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode
|
||||
case NodeTypeArrayAccessExpr:
|
||||
case NodeTypeSliceExpr:
|
||||
case NodeTypeNumberLiteral:
|
||||
case NodeTypeErrorLiteral:
|
||||
case NodeTypeStringLiteral:
|
||||
case NodeTypeCharLiteral:
|
||||
case NodeTypeBoolLiteral:
|
||||
@ -3958,6 +4011,7 @@ static void analyze_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode
|
||||
case NodeTypeStructValueField:
|
||||
case NodeTypeContainerInitExpr:
|
||||
case NodeTypeArrayType:
|
||||
case NodeTypeErrorType:
|
||||
zig_unreachable();
|
||||
}
|
||||
}
|
||||
@ -3967,7 +4021,6 @@ static void collect_expr_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode
|
||||
{
|
||||
switch (node->type) {
|
||||
case NodeTypeNumberLiteral:
|
||||
case NodeTypeErrorLiteral:
|
||||
case NodeTypeStringLiteral:
|
||||
case NodeTypeCharLiteral:
|
||||
case NodeTypeBoolLiteral:
|
||||
@ -3977,6 +4030,7 @@ static void collect_expr_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode
|
||||
case NodeTypeBreak:
|
||||
case NodeTypeContinue:
|
||||
case NodeTypeErrorValueDecl:
|
||||
case NodeTypeErrorType:
|
||||
// no dependencies on other top level declarations
|
||||
break;
|
||||
case NodeTypeSymbol:
|
||||
@ -4286,7 +4340,6 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast
|
||||
case NodeTypeArrayAccessExpr:
|
||||
case NodeTypeSliceExpr:
|
||||
case NodeTypeNumberLiteral:
|
||||
case NodeTypeErrorLiteral:
|
||||
case NodeTypeStringLiteral:
|
||||
case NodeTypeCharLiteral:
|
||||
case NodeTypeBoolLiteral:
|
||||
@ -4311,6 +4364,7 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast
|
||||
case NodeTypeContainerInitExpr:
|
||||
case NodeTypeStructValueField:
|
||||
case NodeTypeArrayType:
|
||||
case NodeTypeErrorType:
|
||||
zig_unreachable();
|
||||
}
|
||||
}
|
||||
@ -4419,7 +4473,14 @@ void semantic_analyze(CodeGen *g) {
|
||||
}
|
||||
}
|
||||
|
||||
g->err_tag_type = get_smallest_unsigned_int_type(g, g->error_value_count);
|
||||
{
|
||||
g->err_tag_type = get_smallest_unsigned_int_type(g, g->error_value_count);
|
||||
|
||||
g->builtin_types.entry_pure_error->type_ref = g->err_tag_type->type_ref;
|
||||
g->builtin_types.entry_pure_error->size_in_bits = g->err_tag_type->size_in_bits;
|
||||
g->builtin_types.entry_pure_error->align_in_bits = g->err_tag_type->align_in_bits;
|
||||
g->builtin_types.entry_pure_error->di_type = g->err_tag_type->di_type;
|
||||
}
|
||||
|
||||
{
|
||||
auto it = g->import_table.entry_iterator();
|
||||
@ -4493,8 +4554,6 @@ Expr *get_resolved_expr(AstNode *node) {
|
||||
return &node->data.container_init_expr.resolved_expr;
|
||||
case NodeTypeNumberLiteral:
|
||||
return &node->data.number_literal.resolved_expr;
|
||||
case NodeTypeErrorLiteral:
|
||||
return &node->data.error_literal.resolved_expr;
|
||||
case NodeTypeStringLiteral:
|
||||
return &node->data.string_literal.resolved_expr;
|
||||
case NodeTypeBlock:
|
||||
@ -4521,6 +4580,8 @@ Expr *get_resolved_expr(AstNode *node) {
|
||||
return &node->data.label.resolved_expr;
|
||||
case NodeTypeArrayType:
|
||||
return &node->data.array_type.resolved_expr;
|
||||
case NodeTypeErrorType:
|
||||
return &node->data.error_type.resolved_expr;
|
||||
case NodeTypeSwitchExpr:
|
||||
return &node->data.switch_expr.resolved_expr;
|
||||
case NodeTypeSwitchProng:
|
||||
@ -4554,7 +4615,6 @@ TopLevelDecl *get_resolved_top_level_decl(AstNode *node) {
|
||||
case NodeTypeErrorValueDecl:
|
||||
return &node->data.error_value_decl.top_level_decl;
|
||||
case NodeTypeNumberLiteral:
|
||||
case NodeTypeErrorLiteral:
|
||||
case NodeTypeReturnExpr:
|
||||
case NodeTypeBinOpExpr:
|
||||
case NodeTypePrefixOpExpr:
|
||||
@ -4593,6 +4653,7 @@ TopLevelDecl *get_resolved_top_level_decl(AstNode *node) {
|
||||
case NodeTypeStructField:
|
||||
case NodeTypeStructValueField:
|
||||
case NodeTypeArrayType:
|
||||
case NodeTypeErrorType:
|
||||
zig_unreachable();
|
||||
}
|
||||
zig_unreachable();
|
||||
|
@ -306,7 +306,7 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {
|
||||
case CastOpNoop:
|
||||
return expr_val;
|
||||
case CastOpErrToInt:
|
||||
assert(actual_type->id == TypeTableEntryIdError);
|
||||
assert(actual_type->id == TypeTableEntryIdErrorUnion);
|
||||
if (actual_type->data.error.child_type->size_in_bits == 0) {
|
||||
return gen_widen_or_shorten(g, node, g->err_tag_type, wanted_type, expr_val);
|
||||
} else {
|
||||
@ -330,12 +330,19 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {
|
||||
return cast_expr->tmp_ptr;
|
||||
}
|
||||
case CastOpErrorWrap:
|
||||
assert(wanted_type->id == TypeTableEntryIdError);
|
||||
assert(wanted_type->id == TypeTableEntryIdErrorUnion);
|
||||
if (wanted_type->data.error.child_type->size_in_bits == 0) {
|
||||
return LLVMConstNull(g->err_tag_type->type_ref);
|
||||
} else {
|
||||
zig_panic("TODO");
|
||||
}
|
||||
case CastOpPureErrorWrap:
|
||||
assert(wanted_type->id == TypeTableEntryIdErrorUnion);
|
||||
if (wanted_type->data.error.child_type->size_in_bits == 0) {
|
||||
return expr_val;
|
||||
} else {
|
||||
zig_panic("TODO");
|
||||
}
|
||||
case CastOpPtrToInt:
|
||||
add_debug_source_node(g, node);
|
||||
return LLVMBuildPtrToInt(g->builder, expr_val, wanted_type->type_ref, "");
|
||||
@ -1292,7 +1299,7 @@ static LLVMValueRef gen_if_bool_expr_raw(CodeGen *g, AstNode *source_node, LLVMV
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
assert(!use_expr_value || then_type->id == TypeTableEntryIdError);
|
||||
assert(!use_expr_value || then_type->id == TypeTableEntryIdErrorUnion);
|
||||
|
||||
LLVMBasicBlockRef then_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "Then");
|
||||
LLVMBasicBlockRef endif_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "EndIf");
|
||||
@ -2011,7 +2018,6 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
|
||||
return gen_container_init_expr(g, node);
|
||||
case NodeTypeSwitchExpr:
|
||||
return gen_switch_expr(g, node);
|
||||
case NodeTypeErrorLiteral:
|
||||
case NodeTypeNumberLiteral:
|
||||
case NodeTypeBoolLiteral:
|
||||
case NodeTypeStringLiteral:
|
||||
@ -2033,6 +2039,7 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
|
||||
case NodeTypeStructField:
|
||||
case NodeTypeStructValueField:
|
||||
case NodeTypeArrayType:
|
||||
case NodeTypeErrorType:
|
||||
case NodeTypeSwitchProng:
|
||||
case NodeTypeSwitchRange:
|
||||
case NodeTypeErrorValueDecl:
|
||||
@ -2063,6 +2070,9 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE
|
||||
|
||||
if (type_entry->id == TypeTableEntryIdInt) {
|
||||
return LLVMConstInt(type_entry->type_ref, bignum_to_twos_complement(&const_val->data.x_bignum), false);
|
||||
} else if (type_entry->id == TypeTableEntryIdPureError) {
|
||||
assert(const_val->data.x_err.err);
|
||||
return LLVMConstInt(g->builtin_types.entry_pure_error->type_ref, const_val->data.x_err.err->value, false);
|
||||
} else if (type_entry->id == TypeTableEntryIdFloat) {
|
||||
if (const_val->data.x_bignum.kind == BigNumKindFloat) {
|
||||
return LLVMConstReal(type_entry->type_ref, const_val->data.x_bignum.data.x_float);
|
||||
@ -2148,12 +2158,26 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE
|
||||
} else {
|
||||
return global_value;
|
||||
}
|
||||
} else if (type_entry->id == TypeTableEntryIdError) {
|
||||
if (type_entry->data.error.child_type->size_in_bits == 0) {
|
||||
} else if (type_entry->id == TypeTableEntryIdErrorUnion) {
|
||||
TypeTableEntry *child_type = type_entry->data.error.child_type;
|
||||
if (child_type->size_in_bits == 0) {
|
||||
uint64_t value = const_val->data.x_err.err ? const_val->data.x_err.err->value : 0;
|
||||
return LLVMConstInt(g->err_tag_type->type_ref, value, false);
|
||||
} else {
|
||||
zig_panic("TODO");
|
||||
LLVMValueRef err_tag_value;
|
||||
LLVMValueRef err_payload_value;
|
||||
if (const_val->data.x_err.err) {
|
||||
err_tag_value = LLVMConstInt(g->err_tag_type->type_ref, const_val->data.x_err.err->value, false);
|
||||
err_payload_value = LLVMConstNull(child_type->type_ref);
|
||||
} else {
|
||||
err_tag_value = LLVMConstNull(g->err_tag_type->type_ref);
|
||||
err_payload_value = gen_const_val(g, child_type, const_val->data.x_err.payload);
|
||||
}
|
||||
LLVMValueRef fields[] = {
|
||||
err_tag_value,
|
||||
err_payload_value,
|
||||
};
|
||||
return LLVMConstStruct(fields, 2, false);
|
||||
}
|
||||
} else {
|
||||
zig_unreachable();
|
||||
@ -2557,6 +2581,14 @@ static void define_builtin_types(CodeGen *g) {
|
||||
g->builtin_types.entry_type = entry;
|
||||
g->primitive_type_table.put(&entry->name, entry);
|
||||
}
|
||||
{
|
||||
// partially complete the error type. we complete it later after we know
|
||||
// error_value_count.
|
||||
TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdPureError);
|
||||
buf_init_from_str(&entry->name, "error");
|
||||
g->builtin_types.entry_pure_error = entry;
|
||||
g->primitive_type_table.put(&entry->name, entry);
|
||||
}
|
||||
|
||||
g->builtin_types.entry_u8 = get_int_type(g, false, 8);
|
||||
g->builtin_types.entry_u16 = get_int_type(g, false, 16);
|
||||
|
@ -113,8 +113,6 @@ const char *node_type_str(NodeType node_type) {
|
||||
return "ErrorValueDecl";
|
||||
case NodeTypeNumberLiteral:
|
||||
return "NumberLiteral";
|
||||
case NodeTypeErrorLiteral:
|
||||
return "ErrorLiteral";
|
||||
case NodeTypeStringLiteral:
|
||||
return "StringLiteral";
|
||||
case NodeTypeCharLiteral:
|
||||
@ -167,6 +165,8 @@ const char *node_type_str(NodeType node_type) {
|
||||
return "ContainerInitExpr";
|
||||
case NodeTypeArrayType:
|
||||
return "ArrayType";
|
||||
case NodeTypeErrorType:
|
||||
return "ErrorType";
|
||||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
@ -313,11 +313,6 @@ void ast_print(AstNode *node, int indent) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NodeTypeErrorLiteral:
|
||||
{
|
||||
fprintf(stderr, "%s '%s'", node_type_str(node->type), buf_ptr(&node->data.error_literal.symbol));
|
||||
break;
|
||||
}
|
||||
case NodeTypeStringLiteral:
|
||||
{
|
||||
const char *c = node->data.string_literal.c ? "c" : "";
|
||||
@ -465,6 +460,9 @@ void ast_print(AstNode *node, int indent) {
|
||||
ast_print(node->data.array_type.child_type, indent + 2);
|
||||
break;
|
||||
}
|
||||
case NodeTypeErrorType:
|
||||
fprintf(stderr, "%s\n", node_type_str(node->type));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1372,8 +1370,8 @@ static AstNode *ast_parse_asm_expr(ParseContext *pc, int *token_index, bool mand
|
||||
}
|
||||
|
||||
/*
|
||||
PrimaryExpression : "Number" | "String" | "CharLiteral" | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | "Symbol" | ("@" "Symbol" FnCallExpression) | ArrayType | AsmExpression | ("%." "Symbol")
|
||||
KeywordLiteral : "true" | "false" | "null" | "break" | "continue" | "undefined"
|
||||
PrimaryExpression : "Number" | "String" | "CharLiteral" | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | "Symbol" | ("@" "Symbol" FnCallExpression) | ArrayType | AsmExpression | ("error" "." "Symbol")
|
||||
KeywordLiteral : "true" | "false" | "null" | "break" | "continue" | "undefined" | "error"
|
||||
*/
|
||||
static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool mandatory) {
|
||||
Token *token = &pc->tokens->at(*token_index);
|
||||
@ -1419,6 +1417,10 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool
|
||||
AstNode *node = ast_create_node(pc, NodeTypeUndefinedLiteral, token);
|
||||
*token_index += 1;
|
||||
return node;
|
||||
} else if (token->id == TokenIdKeywordError) {
|
||||
AstNode *node = ast_create_node(pc, NodeTypeErrorType, token);
|
||||
*token_index += 1;
|
||||
return node;
|
||||
} else if (token->id == TokenIdAtSign) {
|
||||
*token_index += 1;
|
||||
Token *name_tok = ast_eat_token(pc, token_index, TokenIdSymbol);
|
||||
@ -1448,12 +1450,6 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool
|
||||
|
||||
ast_buf_from_token(pc, dest_symbol, &node->data.goto_expr.name);
|
||||
return node;
|
||||
} else if (token->id == TokenIdPercentDot) {
|
||||
*token_index += 1;
|
||||
Token *symbol_tok = ast_eat_token(pc, token_index, TokenIdSymbol);
|
||||
AstNode *node = ast_create_node(pc, NodeTypeErrorLiteral, token);
|
||||
ast_buf_from_token(pc, symbol_tok, &node->data.error_literal.symbol);
|
||||
return node;
|
||||
}
|
||||
|
||||
AstNode *grouped_expr_node = ast_parse_grouped_expr(pc, token_index, false);
|
||||
@ -2969,7 +2965,7 @@ static AstNode *ast_parse_struct_decl(ParseContext *pc, int *token_index) {
|
||||
}
|
||||
|
||||
/*
|
||||
ErrorValueDecl : option(FnVisibleMod) "%." "Symbol"
|
||||
ErrorValueDecl : option(FnVisibleMod) "error" "Symbol"
|
||||
*/
|
||||
static AstNode *ast_parse_error_value_decl(ParseContext *pc, int *token_index, bool mandatory) {
|
||||
Token *first_token = &pc->tokens->at(*token_index);
|
||||
@ -2978,7 +2974,7 @@ static AstNode *ast_parse_error_value_decl(ParseContext *pc, int *token_index, b
|
||||
|
||||
if (first_token->id == TokenIdKeywordPub) {
|
||||
Token *next_token = &pc->tokens->at(*token_index + 1);
|
||||
if (next_token->id == TokenIdPercentDot) {
|
||||
if (next_token->id == TokenIdKeywordError) {
|
||||
visib_mod = VisibModPub;
|
||||
*token_index += 2;
|
||||
} else if (mandatory) {
|
||||
@ -2988,7 +2984,7 @@ static AstNode *ast_parse_error_value_decl(ParseContext *pc, int *token_index, b
|
||||
}
|
||||
} else if (first_token->id == TokenIdKeywordExport) {
|
||||
Token *next_token = &pc->tokens->at(*token_index + 1);
|
||||
if (next_token->id == TokenIdPercentDot) {
|
||||
if (next_token->id == TokenIdKeywordError) {
|
||||
visib_mod = VisibModExport;
|
||||
*token_index += 2;
|
||||
} else if (mandatory) {
|
||||
@ -2996,7 +2992,7 @@ static AstNode *ast_parse_error_value_decl(ParseContext *pc, int *token_index, b
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
} else if (first_token->id == TokenIdPercentDot) {
|
||||
} else if (first_token->id == TokenIdKeywordError) {
|
||||
visib_mod = VisibModPrivate;
|
||||
*token_index += 1;
|
||||
} else if (mandatory) {
|
||||
@ -3177,9 +3173,6 @@ void normalize_parent_ptrs(AstNode *node) {
|
||||
case NodeTypeCharLiteral:
|
||||
// none
|
||||
break;
|
||||
case NodeTypeErrorLiteral:
|
||||
// none
|
||||
break;
|
||||
case NodeTypeSymbol:
|
||||
// none
|
||||
break;
|
||||
@ -3290,5 +3283,8 @@ void normalize_parent_ptrs(AstNode *node) {
|
||||
set_field(&node->data.array_type.size);
|
||||
set_field(&node->data.array_type.child_type);
|
||||
break;
|
||||
case NodeTypeErrorType:
|
||||
// none
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -247,6 +247,8 @@ static void end_token(Tokenize *t) {
|
||||
t->cur_tok->id = TokenIdKeywordSwitch;
|
||||
} else if (mem_eql_str(token_mem, token_len, "undefined")) {
|
||||
t->cur_tok->id = TokenIdKeywordUndefined;
|
||||
} else if (mem_eql_str(token_mem, token_len, "error")) {
|
||||
t->cur_tok->id = TokenIdKeywordError;
|
||||
}
|
||||
|
||||
t->cur_tok = nullptr;
|
||||
@ -1046,6 +1048,7 @@ const char * token_name(TokenId id) {
|
||||
case TokenIdKeywordNoAlias: return "noalias";
|
||||
case TokenIdKeywordSwitch: return "switch";
|
||||
case TokenIdKeywordUndefined: return "undefined";
|
||||
case TokenIdKeywordError: return "error";
|
||||
case TokenIdLParen: return "(";
|
||||
case TokenIdRParen: return ")";
|
||||
case TokenIdComma: return ",";
|
||||
|
@ -38,6 +38,7 @@ enum TokenId {
|
||||
TokenIdKeywordNoAlias,
|
||||
TokenIdKeywordSwitch,
|
||||
TokenIdKeywordUndefined,
|
||||
TokenIdKeywordError,
|
||||
TokenIdLParen,
|
||||
TokenIdRParen,
|
||||
TokenIdComma,
|
||||
|
46
std/std.zig
46
std/std.zig
@ -25,15 +25,15 @@ pub var stderr = OutStream {
|
||||
};
|
||||
*/
|
||||
|
||||
pub %.Unexpected;
|
||||
pub %.DiskQuota;
|
||||
pub %.FileTooBig;
|
||||
pub %.SigInterrupt;
|
||||
pub %.Io;
|
||||
pub %.NoSpaceLeft;
|
||||
pub %.BadPerm;
|
||||
pub %.PipeFail;
|
||||
pub %.Invalid;
|
||||
pub error Unexpected;
|
||||
pub error DiskQuota;
|
||||
pub error FileTooBig;
|
||||
pub error SigInterrupt;
|
||||
pub error Io;
|
||||
pub error NoSpaceLeft;
|
||||
pub error BadPerm;
|
||||
pub error PipeFail;
|
||||
pub error Invalid;
|
||||
|
||||
const buffer_size = 4 * 1024;
|
||||
const max_u64_base10_digits = 20;
|
||||
@ -100,14 +100,14 @@ pub struct OutStream {
|
||||
os.index = 0;
|
||||
switch (write(os.fd, os.buffer.ptr, amt_to_write)) {
|
||||
EINVAL => unreachable{},
|
||||
EDQUOT => %.DiskQuota,
|
||||
EFBIG => %.FileTooBig,
|
||||
EINTR => %.SigInterrupt,
|
||||
EIO => %.Io,
|
||||
ENOSPC => %.NoSpaceLeft,
|
||||
EPERM => %.BadPerm,
|
||||
EPIPE => %.PipeFail,
|
||||
else => %.Unexpected,
|
||||
EDQUOT => error.DiskQuota,
|
||||
EFBIG => error.FileTooBig,
|
||||
EINTR => error.SigInterrupt,
|
||||
EIO => error.Io,
|
||||
ENOSPC => error.NoSpaceLeft,
|
||||
EPERM => error.BadPerm,
|
||||
EPIPE => error.PipeFail,
|
||||
else => error.Unexpected,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -121,10 +121,10 @@ pub struct InStream {
|
||||
switch (-amt_read) {
|
||||
EINVAL => unreachable{},
|
||||
EFAULT => unreachable{},
|
||||
EBADF => %.BadFd,
|
||||
EINTR => %.SigInterrupt,
|
||||
EIO => %.Io,
|
||||
else => %.Unexpected,
|
||||
EBADF => error.BadFd,
|
||||
EINTR => error.SigInterrupt,
|
||||
EIO => error.Io,
|
||||
else => error.Unexpected,
|
||||
}
|
||||
}
|
||||
return amt_read;
|
||||
@ -136,8 +136,8 @@ pub fn os_get_random_bytes(buf: []u8) %void => {
|
||||
switch (getrandom(buf.ptr, buf.len, 0)) {
|
||||
EINVAL => unreachable{},
|
||||
EFAULT => unreachable{},
|
||||
EINTR => %.SigInterrupt,
|
||||
else => %.Unexpected,
|
||||
EINTR => error.SigInterrupt,
|
||||
else => error.Unexpected,
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
@ -1213,11 +1213,11 @@ pub fn main(args: [][]u8) %void => {
|
||||
|
||||
add_simple_case("error values", R"SOURCE(
|
||||
import "std.zig";
|
||||
%.err1;
|
||||
%.err2;
|
||||
error err1;
|
||||
error err2;
|
||||
pub fn main(args: [][]u8) %void => {
|
||||
const a = i32(%.err1);
|
||||
const b = i32(%.err2);
|
||||
const a = i32(error.err1);
|
||||
const b = i32(error.err2);
|
||||
if (a == b) {
|
||||
print_str("BAD\n");
|
||||
}
|
||||
@ -1467,8 +1467,8 @@ enum A {}
|
||||
)SOURCE", 1, ".tmp_source.zig:3:1: error: redefinition of 'A'");
|
||||
|
||||
add_compile_fail_case("redefinition of error values", R"SOURCE(
|
||||
%.A;
|
||||
%.A;
|
||||
error A;
|
||||
error A;
|
||||
)SOURCE", 1, ".tmp_source.zig:3:1: error: redefinition of error 'A'");
|
||||
|
||||
add_compile_fail_case("redefinition of global variables", R"SOURCE(
|
||||
|
Loading…
x
Reference in New Issue
Block a user