main returns %void
This commit is contained in:
parent
91d911007b
commit
c0ea9290c4
@ -4,14 +4,11 @@ import "std.zig";
|
|||||||
|
|
||||||
// Things to do to make this work:
|
// Things to do to make this work:
|
||||||
// * var args printing
|
// * var args printing
|
||||||
// * %void type
|
// * update std API
|
||||||
// * defer
|
// * defer
|
||||||
// * %return
|
// * %return
|
||||||
// * %% operator
|
// * %% operator
|
||||||
// * make main return %void
|
|
||||||
// * how to reference error values %.Invalid
|
|
||||||
// * cast err type to string
|
// * cast err type to string
|
||||||
// * update std API
|
|
||||||
|
|
||||||
pub %.Invalid;
|
pub %.Invalid;
|
||||||
|
|
||||||
|
@ -2,8 +2,7 @@ export executable "hello";
|
|||||||
|
|
||||||
import "std.zig";
|
import "std.zig";
|
||||||
|
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
//stderr.print_str("Hello, world!\n");
|
//stderr.print_str("Hello, world!\n");
|
||||||
print_str("Hello, world!\n");
|
print_str("Hello, world!\n");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ extern {
|
|||||||
fn printf(__format: &const u8, ...) i32;
|
fn printf(__format: &const u8, ...) i32;
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn main(argc: i32, argv: &&u8, env: &&u8) i32 => {
|
export fn main(argc: i32, argv: &&u8) i32 => {
|
||||||
printf(c"Hello, world!\n");
|
printf(c"Hello, world!\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -60,6 +60,11 @@ struct ConstPtrValue {
|
|||||||
uint64_t len;
|
uint64_t len;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ConstErrValue {
|
||||||
|
ErrorTableEntry *err;
|
||||||
|
ConstExprValue *payload;
|
||||||
|
};
|
||||||
|
|
||||||
struct ConstExprValue {
|
struct ConstExprValue {
|
||||||
bool ok; // true if constant expression evalution worked
|
bool ok; // true if constant expression evalution worked
|
||||||
bool depends_on_compile_var;
|
bool depends_on_compile_var;
|
||||||
@ -70,8 +75,8 @@ struct ConstExprValue {
|
|||||||
bool x_bool;
|
bool x_bool;
|
||||||
FnTableEntry *x_fn;
|
FnTableEntry *x_fn;
|
||||||
TypeTableEntry *x_type;
|
TypeTableEntry *x_type;
|
||||||
ErrorTableEntry *x_err;
|
|
||||||
ConstExprValue *x_maybe;
|
ConstExprValue *x_maybe;
|
||||||
|
ConstErrValue x_err;
|
||||||
ConstEnumValue x_enum;
|
ConstEnumValue x_enum;
|
||||||
ConstStructValue x_struct;
|
ConstStructValue x_struct;
|
||||||
ConstArrayValue x_array;
|
ConstArrayValue x_array;
|
||||||
@ -309,6 +314,7 @@ enum CastOp {
|
|||||||
CastOpIntWidenOrShorten,
|
CastOpIntWidenOrShorten,
|
||||||
CastOpToUnknownSizeArray,
|
CastOpToUnknownSizeArray,
|
||||||
CastOpMaybeWrap,
|
CastOpMaybeWrap,
|
||||||
|
CastOpErrorWrap,
|
||||||
CastOpPointerReinterpret,
|
CastOpPointerReinterpret,
|
||||||
CastOpErrToInt,
|
CastOpErrToInt,
|
||||||
};
|
};
|
||||||
|
275
src/analyze.cpp
275
src/analyze.cpp
@ -1130,78 +1130,6 @@ static bool num_lit_fits_in_other_type(CodeGen *g, AstNode *literal_node, TypeTa
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static TypeTableEntry *determine_peer_type_compatibility(CodeGen *g, AstNode *parent_source_node,
|
|
||||||
AstNode **child_nodes, TypeTableEntry **child_types, int child_count)
|
|
||||||
{
|
|
||||||
TypeTableEntry *prev_type = child_types[0];
|
|
||||||
AstNode *prev_node = child_nodes[0];
|
|
||||||
if (prev_type->id == TypeTableEntryIdInvalid) {
|
|
||||||
return prev_type;
|
|
||||||
}
|
|
||||||
for (int i = 1; i < child_count; i += 1) {
|
|
||||||
TypeTableEntry *cur_type = child_types[i];
|
|
||||||
AstNode *cur_node = child_nodes[i];
|
|
||||||
if (cur_type->id == TypeTableEntryIdInvalid) {
|
|
||||||
return cur_type;
|
|
||||||
} else if (prev_type->id == TypeTableEntryIdUnreachable) {
|
|
||||||
prev_type = cur_type;
|
|
||||||
prev_node = cur_node;
|
|
||||||
} else if (cur_type->id == TypeTableEntryIdUnreachable) {
|
|
||||||
continue;
|
|
||||||
} else if (prev_type->id == TypeTableEntryIdInt &&
|
|
||||||
cur_type->id == TypeTableEntryIdInt &&
|
|
||||||
prev_type->data.integral.is_signed == cur_type->data.integral.is_signed)
|
|
||||||
{
|
|
||||||
if (cur_type->size_in_bits > prev_type->size_in_bits) {
|
|
||||||
prev_type = cur_type;
|
|
||||||
prev_node = cur_node;
|
|
||||||
}
|
|
||||||
} else if (prev_type->id == TypeTableEntryIdFloat &&
|
|
||||||
cur_type->id == TypeTableEntryIdFloat)
|
|
||||||
{
|
|
||||||
if (cur_type->size_in_bits > prev_type->size_in_bits) {
|
|
||||||
prev_type = cur_type;
|
|
||||||
prev_node = cur_node;
|
|
||||||
}
|
|
||||||
} else if (prev_type->id == TypeTableEntryIdNumLitFloat &&
|
|
||||||
cur_type->id == TypeTableEntryIdNumLitFloat)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
} else if (prev_type->id == TypeTableEntryIdNumLitInt &&
|
|
||||||
cur_type->id == TypeTableEntryIdNumLitInt)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
} else if (prev_type->id == TypeTableEntryIdNumLitInt ||
|
|
||||||
prev_type->id == TypeTableEntryIdNumLitFloat)
|
|
||||||
{
|
|
||||||
if (num_lit_fits_in_other_type(g, prev_node, cur_type)) {
|
|
||||||
prev_type = cur_type;
|
|
||||||
prev_node = cur_node;
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
return g->builtin_types.entry_invalid;
|
|
||||||
}
|
|
||||||
} else if (cur_type->id == TypeTableEntryIdNumLitInt ||
|
|
||||||
cur_type->id == TypeTableEntryIdNumLitFloat)
|
|
||||||
{
|
|
||||||
if (num_lit_fits_in_other_type(g, cur_node, prev_type)) {
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
return g->builtin_types.entry_invalid;
|
|
||||||
}
|
|
||||||
} else if (prev_type == cur_type) {
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
add_node_error(g, parent_source_node,
|
|
||||||
buf_sprintf("incompatible types: '%s' and '%s'",
|
|
||||||
buf_ptr(&prev_type->name), buf_ptr(&cur_type->name)));
|
|
||||||
|
|
||||||
return g->builtin_types.entry_invalid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return prev_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *actual_type) {
|
static bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *actual_type) {
|
||||||
if (expected_type == actual_type)
|
if (expected_type == actual_type)
|
||||||
return true;
|
return true;
|
||||||
@ -1257,6 +1185,92 @@ static bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTable
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static TypeTableEntry *determine_peer_type_compatibility(CodeGen *g, AstNode *parent_source_node,
|
||||||
|
AstNode **child_nodes, TypeTableEntry **child_types, int child_count)
|
||||||
|
{
|
||||||
|
TypeTableEntry *prev_type = child_types[0];
|
||||||
|
AstNode *prev_node = child_nodes[0];
|
||||||
|
if (prev_type->id == TypeTableEntryIdInvalid) {
|
||||||
|
return prev_type;
|
||||||
|
}
|
||||||
|
for (int i = 1; i < child_count; i += 1) {
|
||||||
|
TypeTableEntry *cur_type = child_types[i];
|
||||||
|
AstNode *cur_node = child_nodes[i];
|
||||||
|
if (cur_type->id == TypeTableEntryIdInvalid) {
|
||||||
|
return cur_type;
|
||||||
|
} else if (types_match_const_cast_only(prev_type, cur_type)) {
|
||||||
|
continue;
|
||||||
|
} else if (types_match_const_cast_only(cur_type, prev_type)) {
|
||||||
|
prev_type = cur_type;
|
||||||
|
prev_node = cur_node;
|
||||||
|
continue;
|
||||||
|
} else if (prev_type->id == TypeTableEntryIdUnreachable) {
|
||||||
|
prev_type = cur_type;
|
||||||
|
prev_node = cur_node;
|
||||||
|
} else if (cur_type->id == TypeTableEntryIdUnreachable) {
|
||||||
|
continue;
|
||||||
|
} else if (prev_type->id == TypeTableEntryIdInt &&
|
||||||
|
cur_type->id == TypeTableEntryIdInt &&
|
||||||
|
prev_type->data.integral.is_signed == cur_type->data.integral.is_signed)
|
||||||
|
{
|
||||||
|
if (cur_type->size_in_bits > prev_type->size_in_bits) {
|
||||||
|
prev_type = cur_type;
|
||||||
|
prev_node = cur_node;
|
||||||
|
}
|
||||||
|
} else if (prev_type->id == TypeTableEntryIdFloat &&
|
||||||
|
cur_type->id == TypeTableEntryIdFloat)
|
||||||
|
{
|
||||||
|
if (cur_type->size_in_bits > prev_type->size_in_bits) {
|
||||||
|
prev_type = cur_type;
|
||||||
|
prev_node = cur_node;
|
||||||
|
}
|
||||||
|
} else if (prev_type->id == TypeTableEntryIdError &&
|
||||||
|
types_match_const_cast_only(prev_type->data.error.child_type, cur_type))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
} else if (cur_type->id == TypeTableEntryIdError &&
|
||||||
|
types_match_const_cast_only(cur_type->data.error.child_type, prev_type))
|
||||||
|
{
|
||||||
|
prev_type = cur_type;
|
||||||
|
prev_node = cur_node;
|
||||||
|
continue;
|
||||||
|
} else if (prev_type->id == TypeTableEntryIdNumLitFloat &&
|
||||||
|
cur_type->id == TypeTableEntryIdNumLitFloat)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
} else if (prev_type->id == TypeTableEntryIdNumLitInt &&
|
||||||
|
cur_type->id == TypeTableEntryIdNumLitInt)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
} else if (prev_type->id == TypeTableEntryIdNumLitInt ||
|
||||||
|
prev_type->id == TypeTableEntryIdNumLitFloat)
|
||||||
|
{
|
||||||
|
if (num_lit_fits_in_other_type(g, prev_node, cur_type)) {
|
||||||
|
prev_type = cur_type;
|
||||||
|
prev_node = cur_node;
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
return g->builtin_types.entry_invalid;
|
||||||
|
}
|
||||||
|
} else if (cur_type->id == TypeTableEntryIdNumLitInt ||
|
||||||
|
cur_type->id == TypeTableEntryIdNumLitFloat)
|
||||||
|
{
|
||||||
|
if (num_lit_fits_in_other_type(g, cur_node, prev_type)) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
return g->builtin_types.entry_invalid;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
add_node_error(g, parent_source_node,
|
||||||
|
buf_sprintf("incompatible types: '%s' and '%s'",
|
||||||
|
buf_ptr(&prev_type->name), buf_ptr(&cur_type->name)));
|
||||||
|
|
||||||
|
return g->builtin_types.entry_invalid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return prev_type;
|
||||||
|
}
|
||||||
|
|
||||||
static bool types_match_with_implicit_cast(CodeGen *g, TypeTableEntry *expected_type,
|
static bool types_match_with_implicit_cast(CodeGen *g, TypeTableEntry *expected_type,
|
||||||
TypeTableEntry *actual_type, AstNode *literal_node, bool *reported_err)
|
TypeTableEntry *actual_type, AstNode *literal_node, bool *reported_err)
|
||||||
{
|
{
|
||||||
@ -1272,6 +1286,14 @@ static bool types_match_with_implicit_cast(CodeGen *g, TypeTableEntry *expected_
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// implicit conversion from error child type to error type
|
||||||
|
if (expected_type->id == TypeTableEntryIdError &&
|
||||||
|
types_match_with_implicit_cast(g, expected_type->data.error.child_type, actual_type,
|
||||||
|
literal_node, reported_err))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// implicit widening conversion
|
// implicit widening conversion
|
||||||
if (expected_type->id == TypeTableEntryIdInt &&
|
if (expected_type->id == TypeTableEntryIdInt &&
|
||||||
actual_type->id == TypeTableEntryIdInt &&
|
actual_type->id == TypeTableEntryIdInt &&
|
||||||
@ -1381,9 +1403,10 @@ static TypeTableEntry *resolve_peer_type_compatibility(CodeGen *g, ImportTableEn
|
|||||||
if (!child_nodes[i]) {
|
if (!child_nodes[i]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Expr *expr = get_resolved_expr(child_nodes[i]);
|
AstNode **child_node = child_nodes[i]->parent_field;
|
||||||
TypeTableEntry *resolved_type = resolve_type_compatibility(g, import, block_context,
|
TypeTableEntry *resolved_type = resolve_type_compatibility(g, import, block_context,
|
||||||
child_nodes[i], expected_type, child_types[i]);
|
*child_node, expected_type, child_types[i]);
|
||||||
|
Expr *expr = get_resolved_expr(*child_node);
|
||||||
expr->type_entry = resolved_type;
|
expr->type_entry = resolved_type;
|
||||||
add_global_const_expr(g, expr);
|
add_global_const_expr(g, expr);
|
||||||
}
|
}
|
||||||
@ -1812,7 +1835,7 @@ static TypeTableEntry *resolve_expr_const_val_as_fn(CodeGen *g, AstNode *node, F
|
|||||||
static TypeTableEntry *resolve_expr_const_val_as_err(CodeGen *g, AstNode *node, ErrorTableEntry *err) {
|
static TypeTableEntry *resolve_expr_const_val_as_err(CodeGen *g, AstNode *node, ErrorTableEntry *err) {
|
||||||
Expr *expr = get_resolved_expr(node);
|
Expr *expr = get_resolved_expr(node);
|
||||||
expr->const_val.ok = true;
|
expr->const_val.ok = true;
|
||||||
expr->const_val.data.x_err = err;
|
expr->const_val.data.x_err.err = err;
|
||||||
return get_error_type(g, g->builtin_types.entry_void);
|
return get_error_type(g, g->builtin_types.entry_void);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2868,10 +2891,18 @@ static void eval_const_expr_implicit_cast(CodeGen *g, AstNode *node, AstNode *ex
|
|||||||
const_val->data.x_maybe = other_val;
|
const_val->data.x_maybe = other_val;
|
||||||
const_val->ok = true;
|
const_val->ok = true;
|
||||||
break;
|
break;
|
||||||
case CastOpErrToInt:
|
case CastOpErrorWrap:
|
||||||
bignum_init_unsigned(&const_val->data.x_bignum, other_val->data.x_err->value);
|
const_val->data.x_err.err = nullptr;
|
||||||
|
const_val->data.x_err.payload = other_val;
|
||||||
const_val->ok = true;
|
const_val->ok = true;
|
||||||
break;
|
break;
|
||||||
|
case CastOpErrToInt:
|
||||||
|
{
|
||||||
|
uint64_t value = other_val->data.x_err.err ? other_val->data.x_err.err->value : 0;
|
||||||
|
bignum_init_unsigned(&const_val->data.x_bignum, value);
|
||||||
|
const_val->ok = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2965,6 +2996,25 @@ 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 (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);
|
||||||
|
return wanted_type;
|
||||||
|
} else if (actual_type->id == TypeTableEntryIdNumLitInt ||
|
||||||
|
actual_type->id == TypeTableEntryIdNumLitFloat)
|
||||||
|
{
|
||||||
|
if (num_lit_fits_in_other_type(g, expr_node, wanted_type->data.error.child_type)) {
|
||||||
|
node->data.fn_call_expr.cast_op = CastOpErrorWrap;
|
||||||
|
eval_const_expr_implicit_cast(g, node, expr_node);
|
||||||
|
return wanted_type;
|
||||||
|
} else {
|
||||||
|
return g->builtin_types.entry_invalid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// explicit cast from number literal to another type
|
// explicit cast from number literal to another type
|
||||||
if (actual_type->id == TypeTableEntryIdNumLitFloat ||
|
if (actual_type->id == TypeTableEntryIdNumLitFloat ||
|
||||||
actual_type->id == TypeTableEntryIdNumLitInt)
|
actual_type->id == TypeTableEntryIdNumLitInt)
|
||||||
@ -3579,6 +3629,42 @@ static TypeTableEntry *analyze_string_literal_expr(CodeGen *g, ImportTableEntry
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static TypeTableEntry *analyze_block_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
|
||||||
|
TypeTableEntry *expected_type, AstNode *node)
|
||||||
|
{
|
||||||
|
BlockContext *child_context = new_block_context(node, context);
|
||||||
|
node->data.block.block_context = child_context;
|
||||||
|
TypeTableEntry *return_type = g->builtin_types.entry_void;
|
||||||
|
|
||||||
|
for (int i = 0; i < node->data.block.statements.length; i += 1) {
|
||||||
|
AstNode *child = node->data.block.statements.at(i);
|
||||||
|
if (child->type == NodeTypeLabel) {
|
||||||
|
LabelTableEntry *label_entry = child->data.label.label_entry;
|
||||||
|
assert(label_entry);
|
||||||
|
label_entry->entered_from_fallthrough = (return_type->id != TypeTableEntryIdUnreachable);
|
||||||
|
return_type = g->builtin_types.entry_void;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (return_type->id == TypeTableEntryIdUnreachable) {
|
||||||
|
if (is_node_void_expr(child)) {
|
||||||
|
// {unreachable;void;void} is allowed.
|
||||||
|
// ignore void statements once we enter unreachable land.
|
||||||
|
analyze_expression(g, import, context, g->builtin_types.entry_void, child);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
add_node_error(g, first_executing_node(child), buf_sprintf("unreachable code"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bool is_last = (i == node->data.block.statements.length - 1);
|
||||||
|
TypeTableEntry *passed_expected_type = is_last ? expected_type : nullptr;
|
||||||
|
return_type = analyze_expression(g, import, child_context, passed_expected_type, child);
|
||||||
|
if (!is_last && return_type->id == TypeTableEntryIdMetaType) {
|
||||||
|
add_node_error(g, child, buf_sprintf("expected expression, found type"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return return_type;
|
||||||
|
}
|
||||||
|
|
||||||
// When you call analyze_expression, the node you pass might no longer be the child node
|
// When you call analyze_expression, the node you pass might no longer be the child node
|
||||||
// you thought it was due to implicit casting rewriting the AST.
|
// you thought it was due to implicit casting rewriting the AST.
|
||||||
static TypeTableEntry *analyze_expression(CodeGen *g, ImportTableEntry *import, BlockContext *context,
|
static TypeTableEntry *analyze_expression(CodeGen *g, ImportTableEntry *import, BlockContext *context,
|
||||||
@ -3587,39 +3673,8 @@ static TypeTableEntry *analyze_expression(CodeGen *g, ImportTableEntry *import,
|
|||||||
TypeTableEntry *return_type = nullptr;
|
TypeTableEntry *return_type = nullptr;
|
||||||
switch (node->type) {
|
switch (node->type) {
|
||||||
case NodeTypeBlock:
|
case NodeTypeBlock:
|
||||||
{
|
return_type = analyze_block_expr(g, import, context, expected_type, node);
|
||||||
BlockContext *child_context = new_block_context(node, context);
|
break;
|
||||||
node->data.block.block_context = child_context;
|
|
||||||
return_type = g->builtin_types.entry_void;
|
|
||||||
|
|
||||||
for (int i = 0; i < node->data.block.statements.length; i += 1) {
|
|
||||||
AstNode *child = node->data.block.statements.at(i);
|
|
||||||
if (child->type == NodeTypeLabel) {
|
|
||||||
LabelTableEntry *label_entry = child->data.label.label_entry;
|
|
||||||
assert(label_entry);
|
|
||||||
label_entry->entered_from_fallthrough = (return_type->id != TypeTableEntryIdUnreachable);
|
|
||||||
return_type = g->builtin_types.entry_void;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (return_type->id == TypeTableEntryIdUnreachable) {
|
|
||||||
if (is_node_void_expr(child)) {
|
|
||||||
// {unreachable;void;void} is allowed.
|
|
||||||
// ignore void statements once we enter unreachable land.
|
|
||||||
analyze_expression(g, import, context, g->builtin_types.entry_void, child);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
add_node_error(g, first_executing_node(child), buf_sprintf("unreachable code"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
bool is_last = (i == node->data.block.statements.length - 1);
|
|
||||||
TypeTableEntry *passed_expected_type = is_last ? expected_type : nullptr;
|
|
||||||
return_type = analyze_expression(g, import, child_context, passed_expected_type, child);
|
|
||||||
if (!is_last && return_type->id == TypeTableEntryIdMetaType) {
|
|
||||||
add_node_error(g, child, buf_sprintf("expected expression, found type"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case NodeTypeReturnExpr:
|
case NodeTypeReturnExpr:
|
||||||
return_type = analyze_return_expr(g, import, context, expected_type, node);
|
return_type = analyze_return_expr(g, import, context, expected_type, node);
|
||||||
|
@ -268,6 +268,26 @@ static LLVMValueRef gen_enum_value_expr(CodeGen *g, AstNode *node, TypeTableEntr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static LLVMValueRef gen_widen_or_shorten(CodeGen *g, AstNode *source_node, TypeTableEntry *actual_type,
|
||||||
|
TypeTableEntry *wanted_type, LLVMValueRef expr_val)
|
||||||
|
{
|
||||||
|
if (actual_type->size_in_bits == wanted_type->size_in_bits) {
|
||||||
|
return expr_val;
|
||||||
|
} else if (actual_type->size_in_bits < wanted_type->size_in_bits) {
|
||||||
|
if (actual_type->data.integral.is_signed) {
|
||||||
|
add_debug_source_node(g, source_node);
|
||||||
|
return LLVMBuildSExt(g->builder, expr_val, wanted_type->type_ref, "");
|
||||||
|
} else {
|
||||||
|
add_debug_source_node(g, source_node);
|
||||||
|
return LLVMBuildZExt(g->builder, expr_val, wanted_type->type_ref, "");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
assert(actual_type->size_in_bits > wanted_type->size_in_bits);
|
||||||
|
add_debug_source_node(g, source_node);
|
||||||
|
return LLVMBuildTrunc(g->builder, expr_val, wanted_type->type_ref, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {
|
static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {
|
||||||
assert(node->type == NodeTypeFnCallExpr);
|
assert(node->type == NodeTypeFnCallExpr);
|
||||||
|
|
||||||
@ -288,7 +308,7 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {
|
|||||||
case CastOpErrToInt:
|
case CastOpErrToInt:
|
||||||
assert(actual_type->id == TypeTableEntryIdError);
|
assert(actual_type->id == TypeTableEntryIdError);
|
||||||
if (actual_type->data.error.child_type->size_in_bits == 0) {
|
if (actual_type->data.error.child_type->size_in_bits == 0) {
|
||||||
return expr_val;
|
return gen_widen_or_shorten(g, node, g->err_tag_type, wanted_type, expr_val);
|
||||||
} else {
|
} else {
|
||||||
zig_panic("TODO");
|
zig_panic("TODO");
|
||||||
}
|
}
|
||||||
@ -309,6 +329,13 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {
|
|||||||
|
|
||||||
return cast_expr->tmp_ptr;
|
return cast_expr->tmp_ptr;
|
||||||
}
|
}
|
||||||
|
case CastOpErrorWrap:
|
||||||
|
assert(wanted_type->id == TypeTableEntryIdError);
|
||||||
|
if (wanted_type->data.error.child_type->size_in_bits == 0) {
|
||||||
|
return LLVMConstNull(g->err_tag_type->type_ref);
|
||||||
|
} else {
|
||||||
|
zig_panic("TODO");
|
||||||
|
}
|
||||||
case CastOpPtrToInt:
|
case CastOpPtrToInt:
|
||||||
add_debug_source_node(g, node);
|
add_debug_source_node(g, node);
|
||||||
return LLVMBuildPtrToInt(g->builder, expr_val, wanted_type->type_ref, "");
|
return LLVMBuildPtrToInt(g->builder, expr_val, wanted_type->type_ref, "");
|
||||||
@ -316,21 +343,7 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {
|
|||||||
add_debug_source_node(g, node);
|
add_debug_source_node(g, node);
|
||||||
return LLVMBuildBitCast(g->builder, expr_val, wanted_type->type_ref, "");
|
return LLVMBuildBitCast(g->builder, expr_val, wanted_type->type_ref, "");
|
||||||
case CastOpIntWidenOrShorten:
|
case CastOpIntWidenOrShorten:
|
||||||
if (actual_type->size_in_bits == wanted_type->size_in_bits) {
|
return gen_widen_or_shorten(g, node, actual_type, wanted_type, expr_val);
|
||||||
return expr_val;
|
|
||||||
} else if (actual_type->size_in_bits < wanted_type->size_in_bits) {
|
|
||||||
if (actual_type->data.integral.is_signed) {
|
|
||||||
add_debug_source_node(g, node);
|
|
||||||
return LLVMBuildSExt(g->builder, expr_val, wanted_type->type_ref, "");
|
|
||||||
} else {
|
|
||||||
add_debug_source_node(g, node);
|
|
||||||
return LLVMBuildZExt(g->builder, expr_val, wanted_type->type_ref, "");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
assert(actual_type->size_in_bits > wanted_type->size_in_bits);
|
|
||||||
add_debug_source_node(g, node);
|
|
||||||
return LLVMBuildTrunc(g->builder, expr_val, wanted_type->type_ref, "");
|
|
||||||
}
|
|
||||||
case CastOpToUnknownSizeArray:
|
case CastOpToUnknownSizeArray:
|
||||||
{
|
{
|
||||||
assert(cast_expr->tmp_ptr);
|
assert(cast_expr->tmp_ptr);
|
||||||
@ -1279,7 +1292,7 @@ static LLVMValueRef gen_if_bool_expr_raw(CodeGen *g, AstNode *source_node, LLVMV
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(!use_expr_value);
|
assert(!use_expr_value || then_type->id == TypeTableEntryIdError);
|
||||||
|
|
||||||
LLVMBasicBlockRef then_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "Then");
|
LLVMBasicBlockRef then_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "Then");
|
||||||
LLVMBasicBlockRef endif_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "EndIf");
|
LLVMBasicBlockRef endif_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "EndIf");
|
||||||
@ -1292,7 +1305,12 @@ static LLVMValueRef gen_if_bool_expr_raw(CodeGen *g, AstNode *source_node, LLVMV
|
|||||||
LLVMBuildBr(g->builder, endif_block);
|
LLVMBuildBr(g->builder, endif_block);
|
||||||
|
|
||||||
LLVMPositionBuilderAtEnd(g->builder, endif_block);
|
LLVMPositionBuilderAtEnd(g->builder, endif_block);
|
||||||
return nullptr;
|
|
||||||
|
if (use_expr_value) {
|
||||||
|
return LLVMConstNull(g->err_tag_type->type_ref);
|
||||||
|
} else {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static LLVMValueRef gen_if_bool_expr(CodeGen *g, AstNode *node) {
|
static LLVMValueRef gen_if_bool_expr(CodeGen *g, AstNode *node) {
|
||||||
@ -2132,7 +2150,8 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE
|
|||||||
}
|
}
|
||||||
} else if (type_entry->id == TypeTableEntryIdError) {
|
} else if (type_entry->id == TypeTableEntryIdError) {
|
||||||
if (type_entry->data.error.child_type->size_in_bits == 0) {
|
if (type_entry->data.error.child_type->size_in_bits == 0) {
|
||||||
return LLVMConstInt(g->err_tag_type->type_ref, const_val->data.x_err->value, false);
|
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 {
|
} else {
|
||||||
zig_panic("TODO");
|
zig_panic("TODO");
|
||||||
}
|
}
|
||||||
|
@ -29,5 +29,8 @@ fn call_main() unreachable => {
|
|||||||
const ptr = argv[i];
|
const ptr = argv[i];
|
||||||
args[i] = ptr[0...strlen(ptr)];
|
args[i] = ptr[0...strlen(ptr)];
|
||||||
}
|
}
|
||||||
exit(main(args))
|
// TODO: replace the i32 cast with:
|
||||||
|
// main(args) %% exit(1)
|
||||||
|
// exit(0)
|
||||||
|
exit(i32(main(args)))
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,7 @@ import "syscall.zig";
|
|||||||
fn empty_function_1() => {}
|
fn empty_function_1() => {}
|
||||||
fn empty_function_2() => { return; }
|
fn empty_function_2() => { return; }
|
||||||
|
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
empty_function_1();
|
empty_function_1();
|
||||||
empty_function_2();
|
empty_function_2();
|
||||||
this_is_a_function();
|
this_is_a_function();
|
||||||
@ -136,9 +136,8 @@ fn another_function() => {}
|
|||||||
|
|
||||||
/// this is a documentation comment
|
/// this is a documentation comment
|
||||||
/// doc comment line 2
|
/// doc comment line 2
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
print_str(/* mid-line comment /* nested */ */ "OK\n");
|
print_str(/* mid-line comment /* nested */ */ "OK\n");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
)SOURCE", "OK\n");
|
)SOURCE", "OK\n");
|
||||||
|
|
||||||
@ -147,10 +146,9 @@ pub fn main(args: [][]u8) i32 => {
|
|||||||
import "std.zig";
|
import "std.zig";
|
||||||
import "foo.zig";
|
import "foo.zig";
|
||||||
|
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
private_function();
|
private_function();
|
||||||
print_str("OK 2\n");
|
print_str("OK 2\n");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn private_function() => {
|
fn private_function() => {
|
||||||
@ -178,10 +176,9 @@ pub fn print_text() => {
|
|||||||
import "foo.zig";
|
import "foo.zig";
|
||||||
import "bar.zig";
|
import "bar.zig";
|
||||||
|
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
foo_function();
|
foo_function();
|
||||||
bar_function();
|
bar_function();
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
)SOURCE", "OK\nOK\n");
|
)SOURCE", "OK\nOK\n");
|
||||||
|
|
||||||
@ -214,7 +211,7 @@ pub fn foo_function() bool => {
|
|||||||
add_simple_case("if statements", R"SOURCE(
|
add_simple_case("if statements", R"SOURCE(
|
||||||
import "std.zig";
|
import "std.zig";
|
||||||
|
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
if (1 != 0) {
|
if (1 != 0) {
|
||||||
print_str("1 is true\n");
|
print_str("1 is true\n");
|
||||||
} else {
|
} else {
|
||||||
@ -228,7 +225,6 @@ pub fn main(args: [][]u8) i32 => {
|
|||||||
if (!(0 != 0)) {
|
if (!(0 != 0)) {
|
||||||
print_str("!0 is true\n");
|
print_str("!0 is true\n");
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
)SOURCE", "1 is true\n!0 is true\n");
|
)SOURCE", "1 is true\n!0 is true\n");
|
||||||
|
|
||||||
@ -239,11 +235,10 @@ fn add(a: i32, b: i32) i32 => {
|
|||||||
a + b
|
a + b
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
if (add(22, 11) == 33) {
|
if (add(22, 11) == 33) {
|
||||||
print_str("pass\n");
|
print_str("pass\n");
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
)SOURCE", "pass\n");
|
)SOURCE", "pass\n");
|
||||||
|
|
||||||
@ -261,41 +256,38 @@ done:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
loop(3);
|
loop(3);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
)SOURCE", "loop\nloop\nloop\n");
|
)SOURCE", "loop\nloop\nloop\n");
|
||||||
|
|
||||||
add_simple_case("local variables", R"SOURCE(
|
add_simple_case("local variables", R"SOURCE(
|
||||||
import "std.zig";
|
import "std.zig";
|
||||||
|
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
const a : i32 = 1;
|
const a : i32 = 1;
|
||||||
const b = i32(2);
|
const b = i32(2);
|
||||||
if (a + b == 3) {
|
if (a + b == 3) {
|
||||||
print_str("OK\n");
|
print_str("OK\n");
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
)SOURCE", "OK\n");
|
)SOURCE", "OK\n");
|
||||||
|
|
||||||
add_simple_case("bool literals", R"SOURCE(
|
add_simple_case("bool literals", R"SOURCE(
|
||||||
import "std.zig";
|
import "std.zig";
|
||||||
|
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
if (true) { print_str("OK 1\n"); }
|
if (true) { print_str("OK 1\n"); }
|
||||||
if (false) { print_str("BAD 1\n"); }
|
if (false) { print_str("BAD 1\n"); }
|
||||||
if (!true) { print_str("BAD 2\n"); }
|
if (!true) { print_str("BAD 2\n"); }
|
||||||
if (!false) { print_str("OK 2\n"); }
|
if (!false) { print_str("OK 2\n"); }
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
)SOURCE", "OK 1\nOK 2\n");
|
)SOURCE", "OK 1\nOK 2\n");
|
||||||
|
|
||||||
add_simple_case("separate block scopes", R"SOURCE(
|
add_simple_case("separate block scopes", R"SOURCE(
|
||||||
import "std.zig";
|
import "std.zig";
|
||||||
|
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
if (true) {
|
if (true) {
|
||||||
const no_conflict : i32 = 5;
|
const no_conflict : i32 = 5;
|
||||||
if (no_conflict == 5) { print_str("OK 1\n"); }
|
if (no_conflict == 5) { print_str("OK 1\n"); }
|
||||||
@ -306,16 +298,14 @@ pub fn main(args: [][]u8) i32 => {
|
|||||||
no_conflict
|
no_conflict
|
||||||
};
|
};
|
||||||
if (c == 10) { print_str("OK 2\n"); }
|
if (c == 10) { print_str("OK 2\n"); }
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
)SOURCE", "OK 1\nOK 2\n");
|
)SOURCE", "OK 1\nOK 2\n");
|
||||||
|
|
||||||
add_simple_case("void parameters", R"SOURCE(
|
add_simple_case("void parameters", R"SOURCE(
|
||||||
import "std.zig";
|
import "std.zig";
|
||||||
|
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
void_fun(1, void{}, 2);
|
void_fun(1, void{}, 2);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn void_fun(a : i32, b : void, c : i32) => {
|
fn void_fun(a : i32, b : void, c : i32) => {
|
||||||
@ -333,7 +323,7 @@ struct Foo {
|
|||||||
b : i32,
|
b : i32,
|
||||||
c : void,
|
c : void,
|
||||||
}
|
}
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
const foo = Foo {
|
const foo = Foo {
|
||||||
.a = void{},
|
.a = void{},
|
||||||
.b = 1,
|
.b = 1,
|
||||||
@ -346,7 +336,6 @@ pub fn main(args: [][]u8) i32 => {
|
|||||||
print_str("BAD\n");
|
print_str("BAD\n");
|
||||||
}
|
}
|
||||||
print_str("OK\n");
|
print_str("OK\n");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
)SOURCE", "OK\n");
|
)SOURCE", "OK\n");
|
||||||
@ -354,7 +343,7 @@ pub fn main(args: [][]u8) i32 => {
|
|||||||
add_simple_case("void arrays", R"SOURCE(
|
add_simple_case("void arrays", R"SOURCE(
|
||||||
import "std.zig";
|
import "std.zig";
|
||||||
|
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
var array: [4]void;
|
var array: [4]void;
|
||||||
array[0] = void{};
|
array[0] = void{};
|
||||||
array[1] = array[2];
|
array[1] = array[2];
|
||||||
@ -365,7 +354,6 @@ pub fn main(args: [][]u8) i32 => {
|
|||||||
print_str("BAD\n");
|
print_str("BAD\n");
|
||||||
}
|
}
|
||||||
print_str("OK\n");
|
print_str("OK\n");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
)SOURCE", "OK\n");
|
)SOURCE", "OK\n");
|
||||||
|
|
||||||
@ -373,27 +361,22 @@ pub fn main(args: [][]u8) i32 => {
|
|||||||
add_simple_case("mutable local variables", R"SOURCE(
|
add_simple_case("mutable local variables", R"SOURCE(
|
||||||
import "std.zig";
|
import "std.zig";
|
||||||
|
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
var zero : i32 = 0;
|
var zero : i32 = 0;
|
||||||
if (zero == 0) { print_str("zero\n"); }
|
if (zero == 0) { print_str("zero\n"); }
|
||||||
|
|
||||||
var i = i32(0);
|
var i = i32(0);
|
||||||
loop_start:
|
while (i != 3) {
|
||||||
if (i == 3) {
|
print_str("loop\n");
|
||||||
goto done;
|
i += 1;
|
||||||
}
|
}
|
||||||
print_str("loop\n");
|
|
||||||
i = i + 1;
|
|
||||||
goto loop_start;
|
|
||||||
done:
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
)SOURCE", "zero\nloop\nloop\nloop\n");
|
)SOURCE", "zero\nloop\nloop\nloop\n");
|
||||||
|
|
||||||
add_simple_case("arrays", R"SOURCE(
|
add_simple_case("arrays", R"SOURCE(
|
||||||
import "std.zig";
|
import "std.zig";
|
||||||
|
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
var array : [5]i32;
|
var array : [5]i32;
|
||||||
|
|
||||||
var i : i32 = 0;
|
var i : i32 = 0;
|
||||||
@ -417,8 +400,6 @@ pub fn main(args: [][]u8) i32 => {
|
|||||||
if (get_array_len(array) != 5) {
|
if (get_array_len(array) != 5) {
|
||||||
print_str("BAD\n");
|
print_str("BAD\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
fn get_array_len(a: []i32) isize => {
|
fn get_array_len(a: []i32) isize => {
|
||||||
a.len
|
a.len
|
||||||
@ -429,9 +410,8 @@ fn get_array_len(a: []i32) isize => {
|
|||||||
add_simple_case("hello world without libc", R"SOURCE(
|
add_simple_case("hello world without libc", R"SOURCE(
|
||||||
import "std.zig";
|
import "std.zig";
|
||||||
|
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
print_str("Hello, world!\n");
|
print_str("Hello, world!\n");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
)SOURCE", "Hello, world!\n");
|
)SOURCE", "Hello, world!\n");
|
||||||
|
|
||||||
@ -439,7 +419,7 @@ pub fn main(args: [][]u8) i32 => {
|
|||||||
add_simple_case("a + b + c", R"SOURCE(
|
add_simple_case("a + b + c", R"SOURCE(
|
||||||
import "std.zig";
|
import "std.zig";
|
||||||
|
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
if (false || false || false) { print_str("BAD 1\n"); }
|
if (false || false || false) { print_str("BAD 1\n"); }
|
||||||
if (true && true && false) { print_str("BAD 2\n"); }
|
if (true && true && false) { print_str("BAD 2\n"); }
|
||||||
if (1 | 2 | 4 != 7) { print_str("BAD 3\n"); }
|
if (1 | 2 | 4 != 7) { print_str("BAD 3\n"); }
|
||||||
@ -454,14 +434,13 @@ pub fn main(args: [][]u8) i32 => {
|
|||||||
if (i32(7) != --(i32(7))) { print_str("BAD 12\n"); }
|
if (i32(7) != --(i32(7))) { print_str("BAD 12\n"); }
|
||||||
|
|
||||||
print_str("OK\n");
|
print_str("OK\n");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
)SOURCE", "OK\n");
|
)SOURCE", "OK\n");
|
||||||
|
|
||||||
add_simple_case("short circuit", R"SOURCE(
|
add_simple_case("short circuit", R"SOURCE(
|
||||||
import "std.zig";
|
import "std.zig";
|
||||||
|
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
if (true || { print_str("BAD 1\n"); false }) {
|
if (true || { print_str("BAD 1\n"); false }) {
|
||||||
print_str("OK 1\n");
|
print_str("OK 1\n");
|
||||||
}
|
}
|
||||||
@ -476,15 +455,13 @@ pub fn main(args: [][]u8) i32 => {
|
|||||||
} else {
|
} else {
|
||||||
print_str("OK 4\n");
|
print_str("OK 4\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
)SOURCE", "OK 1\nOK 2\nOK 3\nOK 4\n");
|
)SOURCE", "OK 1\nOK 2\nOK 3\nOK 4\n");
|
||||||
|
|
||||||
add_simple_case("modify operators", R"SOURCE(
|
add_simple_case("modify operators", R"SOURCE(
|
||||||
import "std.zig";
|
import "std.zig";
|
||||||
|
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
var i : i32 = 0;
|
var i : i32 = 0;
|
||||||
i += 5; if (i != 5) { print_str("BAD +=\n"); }
|
i += 5; if (i != 5) { print_str("BAD +=\n"); }
|
||||||
i -= 2; if (i != 3) { print_str("BAD -=\n"); }
|
i -= 2; if (i != 3) { print_str("BAD -=\n"); }
|
||||||
@ -500,7 +477,6 @@ pub fn main(args: [][]u8) i32 => {
|
|||||||
i |= 3; if (i != 7) { print_str("BAD |=\n"); }
|
i |= 3; if (i != 7) { print_str("BAD |=\n"); }
|
||||||
|
|
||||||
print_str("OK\n");
|
print_str("OK\n");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
)SOURCE", "OK\n");
|
)SOURCE", "OK\n");
|
||||||
|
|
||||||
@ -636,7 +612,7 @@ export fn main(argc: i32, argv: &&u8) i32 => {
|
|||||||
add_simple_case("structs", R"SOURCE(
|
add_simple_case("structs", R"SOURCE(
|
||||||
import "std.zig";
|
import "std.zig";
|
||||||
|
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
var foo : Foo;
|
var foo : Foo;
|
||||||
@memset(&foo, 0, @sizeof(Foo));
|
@memset(&foo, 0, @sizeof(Foo));
|
||||||
foo.a += 1;
|
foo.a += 1;
|
||||||
@ -650,7 +626,6 @@ pub fn main(args: [][]u8) i32 => {
|
|||||||
test_byval_assign();
|
test_byval_assign();
|
||||||
test_initializer();
|
test_initializer();
|
||||||
print_str("OK\n");
|
print_str("OK\n");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
struct Foo {
|
struct Foo {
|
||||||
a : i32,
|
a : i32,
|
||||||
@ -711,23 +686,25 @@ import "std.zig";
|
|||||||
const g1 : i32 = 1233 + 1;
|
const g1 : i32 = 1233 + 1;
|
||||||
var g2 : i32 = 0;
|
var g2 : i32 = 0;
|
||||||
|
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
if (g2 != 0) { print_str("BAD\n"); }
|
if (g2 != 0) { print_str("BAD\n"); }
|
||||||
g2 = g1;
|
g2 = g1;
|
||||||
if (g2 != 1234) { print_str("BAD\n"); }
|
if (g2 != 1234) { print_str("BAD\n"); }
|
||||||
print_str("OK\n");
|
print_str("OK\n");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
)SOURCE", "OK\n");
|
)SOURCE", "OK\n");
|
||||||
|
|
||||||
add_simple_case("while loop", R"SOURCE(
|
add_simple_case("while loop", R"SOURCE(
|
||||||
import "std.zig";
|
import "std.zig";
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
var i : i32 = 0;
|
var i : i32 = 0;
|
||||||
while (i < 4) {
|
while (i < 4) {
|
||||||
print_str("loop\n");
|
print_str("loop\n");
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
|
g();
|
||||||
|
}
|
||||||
|
fn g() i32 => {
|
||||||
return f();
|
return f();
|
||||||
}
|
}
|
||||||
fn f() i32 => {
|
fn f() i32 => {
|
||||||
@ -739,7 +716,7 @@ fn f() i32 => {
|
|||||||
|
|
||||||
add_simple_case("continue and break", R"SOURCE(
|
add_simple_case("continue and break", R"SOURCE(
|
||||||
import "std.zig";
|
import "std.zig";
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
var i : i32 = 0;
|
var i : i32 = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
print_str("loop\n");
|
print_str("loop\n");
|
||||||
@ -749,13 +726,12 @@ pub fn main(args: [][]u8) i32 => {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
)SOURCE", "loop\nloop\nloop\nloop\n");
|
)SOURCE", "loop\nloop\nloop\nloop\n");
|
||||||
|
|
||||||
add_simple_case("maybe type", R"SOURCE(
|
add_simple_case("maybe type", R"SOURCE(
|
||||||
import "std.zig";
|
import "std.zig";
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
const x : ?bool = true;
|
const x : ?bool = true;
|
||||||
|
|
||||||
if (const y ?= x) {
|
if (const y ?= x) {
|
||||||
@ -783,19 +759,16 @@ pub fn main(args: [][]u8) i32 => {
|
|||||||
if (num != 13) {
|
if (num != 13) {
|
||||||
print_str("BAD\n");
|
print_str("BAD\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
)SOURCE", "x is true\n");
|
)SOURCE", "x is true\n");
|
||||||
|
|
||||||
add_simple_case("implicit cast after unreachable", R"SOURCE(
|
add_simple_case("implicit cast after unreachable", R"SOURCE(
|
||||||
import "std.zig";
|
import "std.zig";
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
const x = outer();
|
const x = outer();
|
||||||
if (x == 1234) {
|
if (x == 1234) {
|
||||||
print_str("OK\n");
|
print_str("OK\n");
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
fn inner() i32 => { 1234 }
|
fn inner() i32 => { 1234 }
|
||||||
fn outer() isize => {
|
fn outer() isize => {
|
||||||
@ -807,11 +780,10 @@ fn outer() isize => {
|
|||||||
import "std.zig";
|
import "std.zig";
|
||||||
const x: u16 = 13;
|
const x: u16 = 13;
|
||||||
const z: @typeof(x) = 19;
|
const z: @typeof(x) = 19;
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
const y: @typeof(x) = 120;
|
const y: @typeof(x) = 120;
|
||||||
print_u64(@sizeof(@typeof(y)));
|
print_u64(@sizeof(@typeof(y)));
|
||||||
print_str("\n");
|
print_str("\n");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
)SOURCE", "2\n");
|
)SOURCE", "2\n");
|
||||||
|
|
||||||
@ -823,20 +795,19 @@ struct Rand {
|
|||||||
r.seed
|
r.seed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
const r = Rand {.seed = 1234};
|
const r = Rand {.seed = 1234};
|
||||||
if (r.get_seed() != 1234) {
|
if (r.get_seed() != 1234) {
|
||||||
print_str("BAD seed\n");
|
print_str("BAD seed\n");
|
||||||
}
|
}
|
||||||
print_str("OK\n");
|
print_str("OK\n");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
)SOURCE", "OK\n");
|
)SOURCE", "OK\n");
|
||||||
|
|
||||||
add_simple_case("pointer dereferencing", R"SOURCE(
|
add_simple_case("pointer dereferencing", R"SOURCE(
|
||||||
import "std.zig";
|
import "std.zig";
|
||||||
|
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
var x = i32(3);
|
var x = i32(3);
|
||||||
const y = &x;
|
const y = &x;
|
||||||
|
|
||||||
@ -849,7 +820,6 @@ pub fn main(args: [][]u8) i32 => {
|
|||||||
print_str("BAD\n");
|
print_str("BAD\n");
|
||||||
}
|
}
|
||||||
print_str("OK\n");
|
print_str("OK\n");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
)SOURCE", "OK\n");
|
)SOURCE", "OK\n");
|
||||||
|
|
||||||
@ -858,17 +828,16 @@ import "std.zig";
|
|||||||
|
|
||||||
const ARRAY_SIZE : i8 = 20;
|
const ARRAY_SIZE : i8 = 20;
|
||||||
|
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
var array : [ARRAY_SIZE]u8;
|
var array : [ARRAY_SIZE]u8;
|
||||||
print_u64(@sizeof(@typeof(array)));
|
print_u64(@sizeof(@typeof(array)));
|
||||||
print_str("\n");
|
print_str("\n");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
)SOURCE", "20\n");
|
)SOURCE", "20\n");
|
||||||
|
|
||||||
add_simple_case("@min_value() and @max_value()", R"SOURCE(
|
add_simple_case("@min_value() and @max_value()", R"SOURCE(
|
||||||
import "std.zig";
|
import "std.zig";
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
print_str("max u8: ");
|
print_str("max u8: ");
|
||||||
print_u64(@max_value(u8));
|
print_u64(@max_value(u8));
|
||||||
print_str("\n");
|
print_str("\n");
|
||||||
@ -932,8 +901,6 @@ pub fn main(args: [][]u8) i32 => {
|
|||||||
print_str("min i64: ");
|
print_str("min i64: ");
|
||||||
print_i64(@min_value(i64));
|
print_i64(@min_value(i64));
|
||||||
print_str("\n");
|
print_str("\n");
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
)SOURCE",
|
)SOURCE",
|
||||||
"max u8: 255\n"
|
"max u8: 255\n"
|
||||||
@ -956,7 +923,7 @@ pub fn main(args: [][]u8) i32 => {
|
|||||||
|
|
||||||
add_simple_case("slicing", R"SOURCE(
|
add_simple_case("slicing", R"SOURCE(
|
||||||
import "std.zig";
|
import "std.zig";
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
var array : [20]i32;
|
var array : [20]i32;
|
||||||
|
|
||||||
array[5] = 1234;
|
array[5] = 1234;
|
||||||
@ -977,18 +944,16 @@ pub fn main(args: [][]u8) i32 => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
print_str("OK\n");
|
print_str("OK\n");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
)SOURCE", "OK\n");
|
)SOURCE", "OK\n");
|
||||||
|
|
||||||
|
|
||||||
add_simple_case("else if expression", R"SOURCE(
|
add_simple_case("else if expression", R"SOURCE(
|
||||||
import "std.zig";
|
import "std.zig";
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
if (f(1) == 1) {
|
if (f(1) == 1) {
|
||||||
print_str("OK\n");
|
print_str("OK\n");
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
fn f(c: u8) u8 => {
|
fn f(c: u8) u8 => {
|
||||||
if (c == 0) {
|
if (c == 0) {
|
||||||
@ -1003,7 +968,7 @@ fn f(c: u8) u8 => {
|
|||||||
|
|
||||||
add_simple_case("overflow intrinsics", R"SOURCE(
|
add_simple_case("overflow intrinsics", R"SOURCE(
|
||||||
import "std.zig";
|
import "std.zig";
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
var result: u8;
|
var result: u8;
|
||||||
if (!@add_with_overflow(u8, 250, 100, &result)) {
|
if (!@add_with_overflow(u8, 250, 100, &result)) {
|
||||||
print_str("BAD\n");
|
print_str("BAD\n");
|
||||||
@ -1015,13 +980,12 @@ pub fn main(args: [][]u8) i32 => {
|
|||||||
print_str("BAD\n");
|
print_str("BAD\n");
|
||||||
}
|
}
|
||||||
print_str("OK\n");
|
print_str("OK\n");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
)SOURCE", "OK\n");
|
)SOURCE", "OK\n");
|
||||||
|
|
||||||
add_simple_case("memcpy and memset intrinsics", R"SOURCE(
|
add_simple_case("memcpy and memset intrinsics", R"SOURCE(
|
||||||
import "std.zig";
|
import "std.zig";
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
var foo : [20]u8;
|
var foo : [20]u8;
|
||||||
var bar : [20]u8;
|
var bar : [20]u8;
|
||||||
|
|
||||||
@ -1033,7 +997,6 @@ pub fn main(args: [][]u8) i32 => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
print_str("OK\n");
|
print_str("OK\n");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
)SOURCE", "OK\n");
|
)SOURCE", "OK\n");
|
||||||
|
|
||||||
@ -1042,8 +1005,8 @@ import "std.zig";
|
|||||||
const z : @typeof(stdin_fileno) = 0;
|
const z : @typeof(stdin_fileno) = 0;
|
||||||
const x : @typeof(y) = 1234;
|
const x : @typeof(y) = 1234;
|
||||||
const y : u16 = 5678;
|
const y : u16 = 5678;
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
print_ok(x)
|
var x : i32 = print_ok(x);
|
||||||
}
|
}
|
||||||
fn print_ok(val: @typeof(x)) @typeof(foo) => {
|
fn print_ok(val: @typeof(x)) @typeof(foo) => {
|
||||||
print_str("OK\n");
|
print_str("OK\n");
|
||||||
@ -1073,7 +1036,7 @@ enum Bar {
|
|||||||
D,
|
D,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
const foo1 = Foo.One(13);
|
const foo1 = Foo.One(13);
|
||||||
const foo2 = Foo.Two(Point { .x = 1234, .y = 5678, });
|
const foo2 = Foo.Two(Point { .x = 1234, .y = 5678, });
|
||||||
const bar = Bar.B;
|
const bar = Bar.B;
|
||||||
@ -1098,15 +1061,13 @@ pub fn main(args: [][]u8) i32 => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
print_str("OK\n");
|
print_str("OK\n");
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
)SOURCE", "OK\n");
|
)SOURCE", "OK\n");
|
||||||
|
|
||||||
add_simple_case("array literal", R"SOURCE(
|
add_simple_case("array literal", R"SOURCE(
|
||||||
import "std.zig";
|
import "std.zig";
|
||||||
|
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
const HEX_MULT = []u16{4096, 256, 16, 1};
|
const HEX_MULT = []u16{4096, 256, 16, 1};
|
||||||
|
|
||||||
if (HEX_MULT.len != 4) {
|
if (HEX_MULT.len != 4) {
|
||||||
@ -1118,14 +1079,13 @@ pub fn main(args: [][]u8) i32 => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
print_str("OK\n");
|
print_str("OK\n");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
)SOURCE", "OK\n");
|
)SOURCE", "OK\n");
|
||||||
|
|
||||||
add_simple_case("nested arrays", R"SOURCE(
|
add_simple_case("nested arrays", R"SOURCE(
|
||||||
import "std.zig";
|
import "std.zig";
|
||||||
|
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
const array_of_strings = [][]u8 {"hello", "this", "is", "my", "thing"};
|
const array_of_strings = [][]u8 {"hello", "this", "is", "my", "thing"};
|
||||||
var i: @typeof(array_of_strings.len) = 0;
|
var i: @typeof(array_of_strings.len) = 0;
|
||||||
while (i < array_of_strings.len) {
|
while (i < array_of_strings.len) {
|
||||||
@ -1133,14 +1093,13 @@ pub fn main(args: [][]u8) i32 => {
|
|||||||
print_str("\n");
|
print_str("\n");
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
)SOURCE", "hello\nthis\nis\nmy\nthing\n");
|
)SOURCE", "hello\nthis\nis\nmy\nthing\n");
|
||||||
|
|
||||||
add_simple_case("for loops", R"SOURCE(
|
add_simple_case("for loops", R"SOURCE(
|
||||||
import "std.zig";
|
import "std.zig";
|
||||||
|
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
const array = []u8 {9, 8, 7, 6};
|
const array = []u8 {9, 8, 7, 6};
|
||||||
for (item, array) {
|
for (item, array) {
|
||||||
print_u64(item);
|
print_u64(item);
|
||||||
@ -1159,20 +1118,18 @@ pub fn main(args: [][]u8) i32 => {
|
|||||||
print_i64(index);
|
print_i64(index);
|
||||||
print_str("\n");
|
print_str("\n");
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
)SOURCE", "9\n8\n7\n6\n0\n1\n2\n3\n9\n8\n7\n6\n0\n1\n2\n3\n");
|
)SOURCE", "9\n8\n7\n6\n0\n1\n2\n3\n9\n8\n7\n6\n0\n1\n2\n3\n");
|
||||||
|
|
||||||
add_simple_case("function pointers", R"SOURCE(
|
add_simple_case("function pointers", R"SOURCE(
|
||||||
import "std.zig";
|
import "std.zig";
|
||||||
|
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
const fns = []@typeof(fn1) { fn1, fn2, fn3, fn4, };
|
const fns = []@typeof(fn1) { fn1, fn2, fn3, fn4, };
|
||||||
for (f, fns) {
|
for (f, fns) {
|
||||||
print_u64(f());
|
print_u64(f());
|
||||||
print_str("\n");
|
print_str("\n");
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fn1() u32 => {5}
|
fn fn1() u32 => {5}
|
||||||
@ -1191,7 +1148,7 @@ enum Foo {
|
|||||||
D,
|
D,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
const foo = Foo.C;
|
const foo = Foo.C;
|
||||||
const val: i32 = switch (foo) {
|
const val: i32 = switch (foo) {
|
||||||
Foo.A => 1,
|
Foo.A => 1,
|
||||||
@ -1204,7 +1161,6 @@ pub fn main(args: [][]u8) i32 => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
print_str("OK\n");
|
print_str("OK\n");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
)SOURCE", "OK\n");
|
)SOURCE", "OK\n");
|
||||||
|
|
||||||
@ -1213,7 +1169,7 @@ import "std.zig";
|
|||||||
|
|
||||||
const ten = 10;
|
const ten = 10;
|
||||||
|
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
const one = 1;
|
const one = 1;
|
||||||
const eleven = ten + one;
|
const eleven = ten + one;
|
||||||
|
|
||||||
@ -1222,7 +1178,6 @@ pub fn main(args: [][]u8) i32 => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
print_str("OK\n");
|
print_str("OK\n");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
)SOURCE", "OK\n");
|
)SOURCE", "OK\n");
|
||||||
|
|
||||||
@ -1233,28 +1188,26 @@ struct Foo {
|
|||||||
y: bool,
|
y: bool,
|
||||||
}
|
}
|
||||||
var foo = Foo { .x = 13, .y = true, };
|
var foo = Foo { .x = 13, .y = true, };
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
foo.x += 1;
|
foo.x += 1;
|
||||||
if (foo.x != 14) {
|
if (foo.x != 14) {
|
||||||
print_str("BAD\n");
|
print_str("BAD\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
print_str("OK\n");
|
print_str("OK\n");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
)SOURCE", "OK\n");
|
)SOURCE", "OK\n");
|
||||||
|
|
||||||
add_simple_case("statically initialized array literal", R"SOURCE(
|
add_simple_case("statically initialized array literal", R"SOURCE(
|
||||||
import "std.zig";
|
import "std.zig";
|
||||||
const x = []u8{1,2,3,4};
|
const x = []u8{1,2,3,4};
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
const y : [4]u8 = x;
|
const y : [4]u8 = x;
|
||||||
if (y[3] != 4) {
|
if (y[3] != 4) {
|
||||||
print_str("BAD\n");
|
print_str("BAD\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
print_str("OK\n");
|
print_str("OK\n");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
)SOURCE", "OK\n");
|
)SOURCE", "OK\n");
|
||||||
|
|
||||||
@ -1262,7 +1215,7 @@ pub fn main(args: [][]u8) i32 => {
|
|||||||
import "std.zig";
|
import "std.zig";
|
||||||
%.err1;
|
%.err1;
|
||||||
%.err2;
|
%.err2;
|
||||||
pub fn main(args: [][]u8) i32 => {
|
pub fn main(args: [][]u8) %void => {
|
||||||
const a = i32(%.err1);
|
const a = i32(%.err1);
|
||||||
const b = i32(%.err2);
|
const b = i32(%.err2);
|
||||||
if (a == b) {
|
if (a == b) {
|
||||||
@ -1270,7 +1223,6 @@ pub fn main(args: [][]u8) i32 => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
print_str("OK\n");
|
print_str("OK\n");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
)SOURCE", "OK\n");
|
)SOURCE", "OK\n");
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user