aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2017-04-30 15:09:36 +0100
committerGinger Bill <bill@gingerbill.org>2017-04-30 15:09:36 +0100
commit784f3ecf7e427c1d948541f62253d6d2eab9e70d (patch)
treedd1dba8ff48b3b31944773fc341de8832b0fd582 /src
parent54ea70df985546fa2d1fc95f55b5a83a41ee469c (diff)
Syntax change: cast(T)x => T(x); union_cast(T)x => x.(T); transmute(T)x => transmute(T, x); `y:=^x` => `y:=&x;`
Sorry for all the code breaking in this commit :(
Diffstat (limited to 'src')
-rw-r--r--src/check_expr.c245
-rw-r--r--src/checker.c5
-rw-r--r--src/ir.c81
-rw-r--r--src/parser.c97
-rw-r--r--src/ssa.c61
-rw-r--r--src/tokenizer.c36
6 files changed, 226 insertions, 299 deletions
diff --git a/src/check_expr.c b/src/check_expr.c
index 607a7ab5d..c700e7d25 100644
--- a/src/check_expr.c
+++ b/src/check_expr.c
@@ -1839,6 +1839,12 @@ bool check_representable_as_constant(Checker *c, ExactValue in_value, Type *type
return false;
}
if (out_value) *out_value = v;
+
+
+ if (is_type_untyped(type)) {
+ return true;
+ }
+
i64 i = v.value_integer;
u64 u = *cast(u64 *)&i;
i64 s = 8*type_size_of(c->allocator, type);
@@ -2005,7 +2011,7 @@ bool check_is_vector_elem(Checker *c, AstNode *expr) {
void check_unary_expr(Checker *c, Operand *o, Token op, AstNode *node) {
switch (op.kind) {
- case Token_Pointer: { // Pointer address
+ case Token_And: { // Pointer address
if (o->mode == Addressing_Type) {
o->type = make_type_pointer(c->allocator, o->type);
return;
@@ -3217,6 +3223,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
case BuiltinProc_align_of:
case BuiltinProc_offset_of:
case BuiltinProc_type_info:
+ case BuiltinProc_transmute:
// NOTE(bill): The first arg may be a Type, this will be checked case by case
break;
default:
@@ -4463,6 +4470,56 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
}
}
} break;
+
+ case BuiltinProc_transmute: {
+ Operand op = {0};
+ check_expr_or_type(c, &op, ce->args.e[0]);
+ Type *t = op.type;
+ if ((op.mode != Addressing_Type && t == NULL) || t == t_invalid) {
+ error_node(ce->args.e[0], "Expected a type for `transmute`");
+ return false;
+ }
+ AstNode *expr = ce->args.e[1];
+ Operand *o = operand;
+ check_expr(c, o, expr);
+ if (o->mode == Addressing_Invalid) {
+ return false;
+ }
+
+ if (o->mode == Addressing_Constant) {
+ gbString expr_str = expr_to_string(o->expr);
+ error_node(o->expr, "Cannot transmute a constant expression: `%s`", expr_str);
+ gb_string_free(expr_str);
+ o->mode = Addressing_Invalid;
+ o->expr = expr;
+ return false;
+ }
+
+ if (is_type_untyped(o->type)) {
+ gbString expr_str = expr_to_string(o->expr);
+ error_node(o->expr, "Cannot transmute untyped expression: `%s`", expr_str);
+ gb_string_free(expr_str);
+ o->mode = Addressing_Invalid;
+ o->expr = expr;
+ return false;
+ }
+
+ i64 srcz = type_size_of(c->allocator, o->type);
+ i64 dstz = type_size_of(c->allocator, t);
+ if (srcz != dstz) {
+ gbString expr_str = expr_to_string(o->expr);
+ gbString type_str = type_to_string(t);
+ error_node(o->expr, "Cannot transmute `%s` to `%s`, %lld vs %lld bytes", expr_str, type_str, srcz, dstz);
+ gb_string_free(type_str);
+ gb_string_free(expr_str);
+ o->mode = Addressing_Invalid;
+ o->expr = expr;
+ return false;
+ }
+
+ o->mode = Addressing_Value;
+ o->type = t;
+ } break;
}
return true;
@@ -4766,13 +4823,14 @@ ExprKind check_call_expr(Checker *c, Operand *operand, AstNode *call) {
}
if (operand->mode == Addressing_Type) {
+ #if 0
gbString str = type_to_string(operand->type);
error_node(call, "Expected a procedure, got a type `%s`", str);
gb_string_free(str);
operand->mode = Addressing_Invalid;
operand->expr = call;
return Expr_Stmt;
- #if 0
+ #else
Type *t = operand->type;
gbString str = type_to_string(t);
operand->mode = Addressing_Invalid;
@@ -5480,129 +5538,85 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
o->expr = node;
case_end;
- case_ast_node(ce, CastExpr, node);
- Type *t = check_type(c, ce->type);
- check_expr(c, o, ce->expr);
+ case_ast_node(ta, TypeAssertion, node);
+ check_expr(c, o, ta->expr);
if (o->mode == Addressing_Invalid) {
o->expr = node;
return kind;
}
- switch (ce->token.kind) {
- case Token_cast:
- check_cast(c, o, t);
- break;
- case Token_transmute: {
- if (o->mode == Addressing_Constant) {
- gbString expr_str = expr_to_string(o->expr);
- error_node(o->expr, "Cannot transmute a constant expression: `%s`", expr_str);
- gb_string_free(expr_str);
- o->mode = Addressing_Invalid;
- o->expr = node;
- return kind;
- }
-
- if (is_type_untyped(o->type)) {
- gbString expr_str = expr_to_string(o->expr);
- error_node(o->expr, "Cannot transmute untyped expression: `%s`", expr_str);
- gb_string_free(expr_str);
- o->mode = Addressing_Invalid;
- o->expr = node;
- return kind;
- }
-
- i64 srcz = type_size_of(c->allocator, o->type);
- i64 dstz = type_size_of(c->allocator, t);
- if (srcz != dstz) {
- gbString expr_str = expr_to_string(o->expr);
- gbString type_str = type_to_string(t);
- error_node(o->expr, "Cannot transmute `%s` to `%s`, %lld vs %lld bytes", expr_str, type_str, srcz, dstz);
- gb_string_free(type_str);
- gb_string_free(expr_str);
- o->mode = Addressing_Invalid;
- o->expr = node;
- return kind;
- }
+ Type *t = check_type(c, ta->type);
- o->type = t;
- } break;
-
- case Token_union_cast: {
- if (o->mode == Addressing_Constant) {
- gbString expr_str = expr_to_string(o->expr);
- error_node(o->expr, "Cannot `union_cast` a constant expression: `%s`", expr_str);
- gb_string_free(expr_str);
- o->mode = Addressing_Invalid;
- o->expr = node;
- return kind;
- }
+ if (o->mode == Addressing_Constant) {
+ gbString expr_str = expr_to_string(o->expr);
+ error_node(o->expr, "A type assertion cannot be applied to a constant expression: `%s`", expr_str);
+ gb_string_free(expr_str);
+ o->mode = Addressing_Invalid;
+ o->expr = node;
+ return kind;
+ }
- if (is_type_untyped(o->type)) {
- gbString expr_str = expr_to_string(o->expr);
- error_node(o->expr, "Cannot `union_cast` an untyped expression: `%s`", expr_str);
- gb_string_free(expr_str);
- o->mode = Addressing_Invalid;
- o->expr = node;
- return kind;
- }
+ if (is_type_untyped(o->type)) {
+ gbString expr_str = expr_to_string(o->expr);
+ error_node(o->expr, "A type assertion cannot be applied to an untyped expression: `%s`", expr_str);
+ gb_string_free(expr_str);
+ o->mode = Addressing_Invalid;
+ o->expr = node;
+ return kind;
+ }
- bool src_is_ptr = is_type_pointer(o->type);
- bool dst_is_ptr = is_type_pointer(t);
- Type *src = type_deref(o->type);
- Type *dst = type_deref(t);
- Type *bsrc = base_type(src);
- Type *bdst = base_type(dst);
- if (src_is_ptr != dst_is_ptr) {
- gbString src_type_str = type_to_string(o->type);
- gbString dst_type_str = type_to_string(t);
- error_node(o->expr, "Invalid `union_cast` types: `%s` and `%s`", src_type_str, dst_type_str);
- gb_string_free(dst_type_str);
- gb_string_free(src_type_str);
- o->mode = Addressing_Invalid;
- o->expr = node;
- return kind;
- }
+ bool src_is_ptr = is_type_pointer(o->type);
+ bool dst_is_ptr = is_type_pointer(t);
+ Type *src = type_deref(o->type);
+ Type *dst = type_deref(t);
+ Type *bsrc = base_type(src);
+ Type *bdst = base_type(dst);
- if (!is_type_union(src)) {
- error_node(o->expr, "`union_cast` can only operate on unions");
- o->mode = Addressing_Invalid;
- o->expr = node;
- return kind;
- }
+ if (src_is_ptr != dst_is_ptr) {
+ gbString src_type_str = type_to_string(o->type);
+ gbString dst_type_str = type_to_string(t);
+ error_node(o->expr, "Invalid type assertion types: `%s` and `%s`", src_type_str, dst_type_str);
+ gb_string_free(dst_type_str);
+ gb_string_free(src_type_str);
+ o->mode = Addressing_Invalid;
+ o->expr = node;
+ return kind;
+ }
- bool ok = false;
- for (isize i = 1; i < bsrc->Record.variant_count; i++) {
- Entity *f = bsrc->Record.variants[i];
- if (are_types_identical(f->type, dst)) {
- ok = true;
- break;
- }
- }
+ if (!is_type_union(src)) {
+ error_node(o->expr, "Type assertions can only operate on unions");
+ o->mode = Addressing_Invalid;
+ o->expr = node;
+ return kind;
+ }
- if (!ok) {
- gbString expr_str = expr_to_string(o->expr);
- gbString dst_type_str = type_to_string(t);
- error_node(o->expr, "Cannot `union_cast` `%s` to `%s`", expr_str, dst_type_str);
- gb_string_free(dst_type_str);
- gb_string_free(expr_str);
- o->mode = Addressing_Invalid;
- o->expr = node;
- return kind;
+ bool ok = false;
+ for (isize i = 1; i < bsrc->Record.variant_count; i++) {
+ Entity *f = bsrc->Record.variants[i];
+ if (are_types_identical(f->type, dst)) {
+ ok = true;
+ break;
}
+ }
- add_type_info_type(c, o->type);
- add_type_info_type(c, t);
+ if (!ok) {
+ gbString expr_str = expr_to_string(o->expr);
+ gbString dst_type_str = type_to_string(t);
+ error_node(o->expr, "Cannot type assert `%s` to `%s`", expr_str, dst_type_str);
+ gb_string_free(dst_type_str);
+ gb_string_free(expr_str);
+ o->mode = Addressing_Invalid;
+ o->expr = node;
+ return kind;
+ }
- o->type = t;
- o->mode = Addressing_OptionalOk;
- } break;
+ add_type_info_type(c, o->type);
+ add_type_info_type(c, t);
- default:
- GB_PANIC("Unknown cast expression");
- }
+ o->type = t;
+ o->mode = Addressing_OptionalOk;
case_end;
-
case_ast_node(ue, UnaryExpr, node);
check_expr_base(c, o, ue->expr, type_hint);
if (o->mode == Addressing_Invalid) {
@@ -6022,14 +6036,6 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
str = write_expr_to_string(str, ue->expr);
case_end;
- case_ast_node(ce, CastExpr, node);
- str = string_append_token(str, ce->token);
- str = gb_string_appendc(str, "(");
- str = write_expr_to_string(str, ce->type);
- str = gb_string_appendc(str, ")");
- str = write_expr_to_string(str, ce->expr);
- case_end;
-
case_ast_node(de, DerefExpr, node);
str = write_expr_to_string(str, de->expr);
str = gb_string_appendc(str, "^");
@@ -6055,6 +6061,13 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
str = write_expr_to_string(str, se->selector);
case_end;
+ case_ast_node(ta, TypeAssertion, node);
+ str = write_expr_to_string(str, ta->expr);
+ str = gb_string_appendc(str, ".(");
+ str = write_expr_to_string(str, ta->type);
+ str = gb_string_appendc(str, ")");
+ case_end;
+
case_ast_node(ie, IndexExpr, node);
str = write_expr_to_string(str, ie->expr);
str = gb_string_appendc(str, "[");
diff --git a/src/checker.c b/src/checker.c
index d61e33633..9c40cd348 100644
--- a/src/checker.c
+++ b/src/checker.c
@@ -52,7 +52,6 @@ typedef enum BuiltinProcId {
BuiltinProc_panic,
BuiltinProc_copy,
- // BuiltinProc_append,
BuiltinProc_swizzle,
@@ -72,6 +71,8 @@ typedef enum BuiltinProcId {
BuiltinProc_abs,
BuiltinProc_clamp,
+ BuiltinProc_transmute,
+
BuiltinProc_Count,
} BuiltinProcId;
gb_global BuiltinProc builtin_procs[BuiltinProc_Count] = {
@@ -123,6 +124,8 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_Count] = {
{STR_LIT("max"), 2, false, Expr_Expr},
{STR_LIT("abs"), 1, false, Expr_Expr},
{STR_LIT("clamp"), 3, false, Expr_Expr},
+
+ {STR_LIT("transmute"), 2, false, Expr_Expr},
};
diff --git a/src/ir.c b/src/ir.c
index 6de568b91..12bb07826 100644
--- a/src/ir.c
+++ b/src/ir.c
@@ -3105,7 +3105,7 @@ irValue *ir_emit_union_cast(irProcedure *proc, irValue *value, Type *type, Token
args[4] = ir_type_info(proc, src_type);
args[5] = ir_type_info(proc, dst_type);
- ir_emit_global_call(proc, "__union_cast_check", args, 6);
+ ir_emit_global_call(proc, "__type_assertion_check", args, 6);
return ir_emit_load(proc, ir_emit_struct_ep(proc, v, 0));
}
@@ -3606,36 +3606,21 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
case_end;
#endif
- case_ast_node(ce, CastExpr, expr);
+ case_ast_node(ta, TypeAssertion, expr);
Type *type = tv->type;
- irValue *e = ir_build_expr(proc, ce->expr);
- switch (ce->token.kind) {
- case Token_cast:
- ir_emit_comment(proc, str_lit("cast - cast"));
- return ir_emit_conv(proc, e, type);
-
- case Token_transmute:
- ir_emit_comment(proc, str_lit("cast - transmute"));
- return ir_emit_transmute(proc, e, type);
-
- #if 0
- case Token_down_cast:
- ir_emit_comment(proc, str_lit("cast - down_cast"));
- return ir_emit_down_cast(proc, e, type);
- #endif
-
- case Token_union_cast:
+ irValue *e = ir_build_expr(proc, ta->expr);
+ Type *t = type_deref(ir_type(e));
+ if (is_type_union(t)) {
ir_emit_comment(proc, str_lit("cast - union_cast"));
return ir_emit_union_cast(proc, e, type, ast_node_token(expr).pos);
-
- default:
- GB_PANIC("Unknown cast expression");
+ } else {
+ GB_PANIC("TODO(bill): type assertion %s", type_to_string(ir_type(e)));
}
case_end;
case_ast_node(ue, UnaryExpr, expr);
switch (ue->op.kind) {
- case Token_Pointer:
+ case Token_And:
return ir_emit_ptr_offset(proc, ir_build_addr(proc, ue->expr).addr, v_zero); // Make a copy of the pointer
default:
return ir_emit_unary_arith(proc, ue->op.kind, ir_build_expr(proc, ue->expr), tv->type);
@@ -3734,6 +3719,11 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
return ir_type_info(proc, t);
} break;
+ case BuiltinProc_transmute: {
+ irValue *x = ir_build_expr(proc, ce->args.e[1]);
+ return ir_emit_transmute(proc, x, tv->type);
+ }
+
case BuiltinProc_len: {
irValue *v = ir_build_expr(proc, ce->args.e[0]);
Type *t = base_type(ir_type(v));
@@ -4736,50 +4726,23 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
}
case_end;
- case_ast_node(ce, CastExpr, expr);
- switch (ce->token.kind) {
- case Token_cast: {
- ir_emit_comment(proc, str_lit("Cast - cast"));
- // NOTE(bill): Needed for dereference of pointer conversion
- Type *type = type_of_expr(proc->module->info, expr);
- irValue *v = ir_add_local_generated(proc, type);
- ir_emit_store(proc, v, ir_emit_conv(proc, ir_build_expr(proc, ce->expr), type));
- return ir_addr(v);
- }
- case Token_transmute: {
- ir_emit_comment(proc, str_lit("Cast - transmute"));
- // NOTE(bill): Needed for dereference of pointer conversion
- Type *type = type_of_expr(proc->module->info, expr);
- irValue *v = ir_add_local_generated(proc, type);
- ir_emit_store(proc, v, ir_emit_transmute(proc, ir_build_expr(proc, ce->expr), type));
- return ir_addr(v);
- }
- #if 0
- case Token_down_cast: {
- ir_emit_comment(proc, str_lit("Cast - down_cast"));
- // NOTE(bill): Needed for dereference of pointer conversion
+ case_ast_node(ta, TypeAssertion, expr);
+ irValue *e = ir_build_expr(proc, ta->expr);
+ Type *t = type_deref(ir_type(e));
+ if (is_type_union(t)) {
Type *type = type_of_expr(proc->module->info, expr);
irValue *v = ir_add_local_generated(proc, type);
- ir_emit_store(proc, v, ir_emit_down_cast(proc, ir_build_expr(proc, ce->expr), type));
- return ir_addr(v);
- }
- #endif
- case Token_union_cast: {
- ir_emit_comment(proc, str_lit("Cast - union_cast"));
- // NOTE(bill): Needed for dereference of pointer conversion
- Type *type = type_of_expr(proc->module->info, expr);
- irValue *v = ir_add_local_generated(proc, type);
- ir_emit_store(proc, v, ir_emit_union_cast(proc, ir_build_expr(proc, ce->expr), type, ast_node_token(expr).pos));
+ ir_emit_comment(proc, str_lit("cast - union_cast"));
+ ir_emit_store(proc, v, ir_emit_union_cast(proc, ir_build_expr(proc, ta->expr), type, ast_node_token(expr).pos));
return ir_addr(v);
- }
- default:
- GB_PANIC("Unknown cast expression");
+ } else {
+ GB_PANIC("TODO(bill): type assertion %s", type_to_string(ir_type(e)));
}
case_end;
case_ast_node(ue, UnaryExpr, expr);
switch (ue->op.kind) {
- case Token_Pointer: {
+ case Token_And: {
return ir_build_addr(proc, ue->expr);
}
default:
diff --git a/src/parser.c b/src/parser.c
index 3dab46644..ad1e2945f 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -182,9 +182,9 @@ AST_NODE_KIND(_ExprBegin, "", i32) \
Token open; \
Token close; \
}) \
- AST_NODE_KIND(CastExpr, "cast expression", struct { Token token; AstNode *type, *expr; Token open, close; }) \
- AST_NODE_KIND(FieldValue, "field value", struct { Token eq; AstNode *field, *value; }) \
- AST_NODE_KIND(TernaryExpr, "ternary expression", struct { AstNode *cond, *x, *y; }) \
+ AST_NODE_KIND(FieldValue, "field value", struct { Token eq; AstNode *field, *value; }) \
+ AST_NODE_KIND(TernaryExpr, "ternary expression", struct { AstNode *cond, *x, *y; }) \
+ AST_NODE_KIND(TypeAssertion, "type assertion", struct { AstNode *expr; Token dot; AstNode *type; }) \
AST_NODE_KIND(_ExprEnd, "", i32) \
AST_NODE_KIND(_StmtBegin, "", i32) \
AST_NODE_KIND(BadStmt, "bad statement", struct { Token begin, end; }) \
@@ -485,13 +485,13 @@ Token ast_node_token(AstNode *node) {
return ast_node_token(node->SelectorExpr.selector);
}
return node->SelectorExpr.token;
- case AstNode_IndexExpr: return node->IndexExpr.open;
- case AstNode_SliceExpr: return node->SliceExpr.open;
- case AstNode_Ellipsis: return node->Ellipsis.token;
- case AstNode_CastExpr: return node->CastExpr.token;
- case AstNode_FieldValue: return node->FieldValue.eq;
- case AstNode_DerefExpr: return node->DerefExpr.op;
- case AstNode_TernaryExpr: return ast_node_token(node->TernaryExpr.cond);
+ case AstNode_IndexExpr: return node->IndexExpr.open;
+ case AstNode_SliceExpr: return node->SliceExpr.open;
+ case AstNode_Ellipsis: return node->Ellipsis.token;
+ case AstNode_FieldValue: return node->FieldValue.eq;
+ case AstNode_DerefExpr: return node->DerefExpr.op;
+ case AstNode_TernaryExpr: return ast_node_token(node->TernaryExpr.cond);
+ case AstNode_TypeAssertion: return ast_node_token(node->TypeAssertion.expr);
case AstNode_BadStmt: return node->BadStmt.begin;
case AstNode_EmptyStmt: return node->EmptyStmt.token;
@@ -773,16 +773,6 @@ AstNode *ast_field_value(AstFile *f, AstNode *field, AstNode *value, Token eq) {
return result;
}
-AstNode *ast_cast_expr(AstFile *f, Token token, AstNode *type, AstNode *expr, Token open, Token close) {
- AstNode *result = make_ast_node(f, AstNode_CastExpr);
- result->CastExpr.token = token;
- result->CastExpr.type = type;
- result->CastExpr.expr = expr;
- result->CastExpr.open = open;
- result->CastExpr.close = close;
- return result;
-}
-
AstNode *ast_compound_lit(AstFile *f, AstNode *type, AstNodeArray elems, Token open, Token close) {
AstNode *result = make_ast_node(f, AstNode_CompoundLit);
result->CompoundLit.type = type;
@@ -806,6 +796,14 @@ AstNode *ast_ternary_expr(AstFile *f, AstNode *cond, AstNode *x, AstNode *y) {
result->TernaryExpr.y = y;
return result;
}
+AstNode *ast_type_assertion(AstFile *f, AstNode *expr, Token dot, AstNode *type) {
+ AstNode *result = make_ast_node(f, AstNode_TypeAssertion);
+ result->TypeAssertion.expr = expr;
+ result->TypeAssertion.dot = dot;
+ result->TypeAssertion.type = type;
+ return result;
+}
+
@@ -1977,6 +1975,13 @@ AstNode *parse_atom_expr(AstFile *f, bool lhs) {
// case Token_Integer:
// operand = ast_selector_expr(f, token, operand, parse_expr(f, lhs));
// break;
+ case Token_OpenParen: {
+ Token open = expect_token(f, Token_OpenParen);
+ AstNode *type = parse_type(f);
+ Token close = expect_token(f, Token_CloseParen);
+ operand = ast_type_assertion(f, operand, token, type);
+ } break;
+
default:
syntax_error(f->curr_token, "Expected a selector");
next_token(f);
@@ -2073,32 +2078,33 @@ AstNode *parse_atom_expr(AstFile *f, bool lhs) {
AstNode *parse_unary_expr(AstFile *f, bool lhs) {
switch (f->curr_token.kind) {
- case Token_cast:
- case Token_transmute:
- case Token_union_cast:
- {
- Token token = f->curr_token; next_token(f);
- Token open = expect_token(f, Token_OpenParen);
- AstNode *type = parse_type(f);
- Token close = expect_token(f, Token_CloseParen);
- AstNode *expr = parse_unary_expr(f, lhs);
- return ast_cast_expr(f, token, type, expr, open, close);
- } break;
+ // case Token_cast:
+ // case Token_transmute:
+ // case Token_union_cast:
+ // {
+ // Token token = f->curr_token; next_token(f);
+ // Token open = expect_token(f, Token_OpenParen);
+ // AstNode *type = parse_type(f);
+ // Token close = expect_token(f, Token_CloseParen);
+ // AstNode *expr = parse_unary_expr(f, lhs);
+ // return ast_cast_expr(f, token, type, expr, open, close);
+ // } break;
+
+ // case Token_Pointer: {
+ // Token op = f->curr_token;
+ // next_token(f);
+ // AstNode *expr = parse_unary_expr(f, lhs);
+ // if (is_ast_node_type(expr)) {
+ // return ast_pointer_type(f, op, expr);
+ // }
+ // return ast_unary_expr(f, op, expr);
+ // } break;
- case Token_Pointer: {
- Token op = f->curr_token;
- next_token(f);
- AstNode *expr = parse_unary_expr(f, lhs);
- if (is_ast_node_type(expr)) {
- return ast_pointer_type(f, op, expr);
- }
- return ast_unary_expr(f, op, expr);
- } break;
- // case Token_Maybe:
case Token_Add:
case Token_Sub:
case Token_Not:
- case Token_Xor: {
+ case Token_Xor:
+ case Token_And: {
Token op = f->curr_token;
next_token(f);
return ast_unary_expr(f, op, parse_unary_expr(f, lhs));
@@ -2663,10 +2669,11 @@ AstNode *parse_type_or_ident(AstFile *f) {
AstNode *sel = parse_ident(f);
e = ast_selector_expr(f, token, e, sel);
}
- if (f->curr_token.kind == Token_OpenParen) {
+ // TODO(bill): Merge type_or_ident into the general parsing for expressions
+ // if (f->curr_token.kind == Token_OpenParen) {
// HACK NOTE(bill): For type_of_val(expr) et al.
- e = parse_call_expr(f, e);
- }
+ // e = parse_call_expr(f, e);
+ // }
return e;
}
diff --git a/src/ssa.c b/src/ssa.c
index 2c4394cd3..de4e4ad80 100644
--- a/src/ssa.c
+++ b/src/ssa.c
@@ -1111,40 +1111,6 @@ ssaAddr ssa_build_addr(ssaProc *p, AstNode *expr) {
}
case_end;
-
- case_ast_node(ce, CastExpr, expr);
- switch (ce->token.kind) {
- case Token_cast: {
- ssa_emit_comment(p, str_lit("Cast - cast"));
- // NOTE(bill): Needed for dereference of pointer conversion
- Type *type = type_of_expr(p->module->info, expr);
- ssaAddr addr = ssa_add_local_generated(p, type);
- ssa_addr_store(p, addr, ssa_emit_conv(p, ssa_build_expr(p, ce->expr), type));
- return addr;
- }
- #if 0
- case Token_transmute: {
- ssa_emit_comment(p, str_lit("Cast - transmute"));
- // NOTE(bill): Needed for dereference of pointer conversion
- Type *type = type_of_expr(p->module->info, expr);
- ssaValue *v = ssa_add_local_generated(p, type);
- ssa_emit_store(p, v, ssa_emit_transmute(p, ssa_build_expr(p, ce->expr), type));
- return ssa_addr(v);
- }
- case Token_union_cast: {
- ssa_emit_comment(p, str_lit("Cast - union_cast"));
- // NOTE(bill): Needed for dereference of pointer conversion
- Type *type = type_of_expr(p->module->info, expr);
- ssaValue *v = ssa_add_local_generated(p, type);
- ssa_emit_store(p, v, ssa_emit_union_cast(p, ssa_build_expr(p, ce->expr), type, ast_node_token(expr).pos));
- return ssa_addr(v);
- }
- #endif
- default:
- GB_PANIC("Unknown cast expression");
- }
- case_end;
-
case_ast_node(ue, UnaryExpr, expr);
switch (ue->op.kind) {
case Token_Pointer: {
@@ -1841,33 +1807,6 @@ ssaValue *ssa_build_expr(ssaProc *p, AstNode *expr) {
case_end;
- case_ast_node(ce, CastExpr, expr);
- Type *type = tv->type;
- ssaValue *e = ssa_build_expr(p, ce->expr);
- switch (ce->token.kind) {
- case Token_cast:
- ssa_emit_comment(p, str_lit("cast - cast"));
- return ssa_emit_conv(p, e, type);
-
- // case Token_transmute:
- // ssa_emit_comment(p, str_lit("cast - transmute"));
- // return ssa_emit_transmute(p, e, type);
-
- #if 0
- case Token_down_cast:
- ssa_emit_comment(p, str_lit("cast - down_cast"));
- return ssa_emit_down_cast(p, e, type);
- #endif
-
- // case Token_union_cast:
- // ssa_emit_comment(p, str_lit("cast - union_cast"));
- // return ssa_emit_union_cast(p, e, type, ast_node_token(expr).pos);
-
- default:
- GB_PANIC("Unhandled cast expression %.*s", LIT(token_strings[ce->token.kind]));
- }
- case_end;
-
case_ast_node(pl, ProcLit, expr);
GB_PANIC("TODO(bill): ssa_build_expr ProcLit");
#if 0
diff --git a/src/tokenizer.c b/src/tokenizer.c
index 9a4ecea59..56186f914 100644
--- a/src/tokenizer.c
+++ b/src/tokenizer.c
@@ -76,6 +76,7 @@ TOKEN_KIND(Token__ComparisonEnd, "_ComparisonEnd"), \
TOKEN_KIND(Token_Comma, ","), \
TOKEN_KIND(Token_Ellipsis, ".."), \
TOKEN_KIND(Token_HalfClosed, "..<"), \
+ TOKEN_KIND(Token_BackSlash, "\\"), \
TOKEN_KIND(Token__OperatorEnd, "_OperatorEnd"), \
\
TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \
@@ -106,9 +107,9 @@ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \
TOKEN_KIND(Token_using, "using"), \
TOKEN_KIND(Token_no_alias, "no_alias"), \
TOKEN_KIND(Token_immutable, "immutable"), \
- TOKEN_KIND(Token_cast, "cast"), \
- TOKEN_KIND(Token_transmute, "transmute"), \
- TOKEN_KIND(Token_union_cast, "union_cast"), \
+ /* TOKEN_KIND(Token_cast, "cast"), */ \
+ /* TOKEN_KIND(Token_transmute, "transmute"), */ \
+ /* TOKEN_KIND(Token_union_cast, "union_cast"), */ \
TOKEN_KIND(Token_context, "context"), \
TOKEN_KIND(Token_push_context, "push_context"), \
TOKEN_KIND(Token_push_allocator, "push_allocator"), \
@@ -878,20 +879,21 @@ Token tokenizer_get_token(Tokenizer *t) {
}
break;
- case '#': token.kind = Token_Hash; break;
- case '@': token.kind = Token_At; break;
- case '$': token.kind = Token_Dollar; break;
- case '?': token.kind = Token_Question; break;
- case '^': token.kind = Token_Pointer; break;
- case ';': token.kind = Token_Semicolon; break;
- case ',': token.kind = Token_Comma; break;
- case ':': token.kind = Token_Colon; break;
- case '(': token.kind = Token_OpenParen; break;
- case ')': token.kind = Token_CloseParen; break;
- case '[': token.kind = Token_OpenBracket; break;
- case ']': token.kind = Token_CloseBracket; break;
- case '{': token.kind = Token_OpenBrace; break;
- case '}': token.kind = Token_CloseBrace; break;
+ case '#': token.kind = Token_Hash; break;
+ case '@': token.kind = Token_At; break;
+ case '$': token.kind = Token_Dollar; break;
+ case '?': token.kind = Token_Question; break;
+ case '^': token.kind = Token_Pointer; break;
+ case ';': token.kind = Token_Semicolon; break;
+ case ',': token.kind = Token_Comma; break;
+ case ':': token.kind = Token_Colon; break;
+ case '(': token.kind = Token_OpenParen; break;
+ case ')': token.kind = Token_CloseParen; break;
+ case '[': token.kind = Token_OpenBracket; break;
+ case ']': token.kind = Token_CloseBracket; break;
+ case '{': token.kind = Token_OpenBrace; break;
+ case '}': token.kind = Token_CloseBrace; break;
+ case '\\': token.kind = Token_BackSlash; break;
case '*': token.kind = token_kind_variant2(t, Token_Mul, Token_MulEq); break;
case '%': token.kind = token_kind_variant2(t, Token_Mod, Token_ModEq); break;