switch cast expressions from being formally represented in the expression tree - instead use cast-like tree shapes to perform casts in the ir/typechecking phase. this is odd, given C's casting syntax, but it is much more natural given that the parser is not any longer doing identifier resolution, and as such it fixes a bunch of nasty edge cases.

This commit is contained in:
Ryan Fleury
2025-04-28 11:50:23 -07:00
parent 81425e8b90
commit c62ad20a9a
13 changed files with 325 additions and 130 deletions
+49 -48
View File
@@ -82,63 +82,64 @@ E_TypeKindTable:
@table(name op_kind precedence op_pre op_sep op_pos op_chain)
E_ExprKindTable:
{
{ Nil Null 0 "" "" "" "" }
{ Ref Null 0 "" "" "" "" }
{ Nil Null 0 "" "" "" "" }
{ Ref Null 0 "" "" "" "" }
{ ArrayIndex Null 0 "" "[" "]" "" }
{ MemberAccess Null 0 "" "." "" "" }
{ Deref UnaryPrefix 2 "*" "" "" "" }
{ Address UnaryPrefix 2 "&" "" "" "" }
{ ArrayIndex Null 0 "" "[" "]" "" }
{ MemberAccess Null 0 "" "." "" "" }
{ Deref UnaryPrefix 2 "*" "" "" "" }
{ Address UnaryPrefix 2 "&" "" "" "" }
{ Cast Null 1 "(" ")" "" "" }
{ Sizeof UnaryPrefix 1 "sizeof" "(" ")" "" }
{ Typeof UnaryPrefix 1 "typeof" "(" ")" "" }
{ ByteSwap UnaryPrefix 1 "bswap" "(" ")" "" }
{ Cast Null 1 "(" ")" "" "" }
{ Sizeof UnaryPrefix 1 "sizeof" "(" ")" "" }
{ Typeof UnaryPrefix 1 "typeof" "(" ")" "" }
{ ByteSwap UnaryPrefix 1 "bswap" "(" ")" "" }
{ Pos UnaryPrefix 2 "+" "" "" "" }
{ Neg UnaryPrefix 2 "-" "" "" "" }
{ LogNot UnaryPrefix 2 "!" "" "" "" }
{ BitNot UnaryPrefix 2 "~" "" "" "" }
{ Mul Binary 3 "" " * " "" "" }
{ Div Binary 3 "" " / " "" "" }
{ Mod Binary 3 "" " % " "" "" }
{ Add Binary 4 "" " + " "" "" }
{ Sub Binary 4 "" " - " "" "" }
{ LShift Binary 5 "" " << " "" "" }
{ RShift Binary 5 "" " >> " "" "" }
{ Less Binary 6 "" " < " "" "" }
{ LsEq Binary 6 "" " <= " "" "" }
{ Grtr Binary 6 "" " > " "" "" }
{ GrEq Binary 6 "" " >= " "" "" }
{ EqEq Binary 7 "" " == " "" "" }
{ NtEq Binary 7 "" " != " "" "" }
{ Pos UnaryPrefix 2 "+" "" "" "" }
{ Neg UnaryPrefix 2 "-" "" "" "" }
{ LogNot UnaryPrefix 2 "!" "" "" "" }
{ BitNot UnaryPrefix 2 "~" "" "" "" }
{ Mul Binary 3 "" " * " "" "" }
{ Div Binary 3 "" " / " "" "" }
{ Mod Binary 3 "" " % " "" "" }
{ Add Binary 4 "" " + " "" "" }
{ Sub Binary 4 "" " - " "" "" }
{ LShift Binary 5 "" " << " "" "" }
{ RShift Binary 5 "" " >> " "" "" }
{ Less Binary 6 "" " < " "" "" }
{ LsEq Binary 6 "" " <= " "" "" }
{ Grtr Binary 6 "" " > " "" "" }
{ GrEq Binary 6 "" " >= " "" "" }
{ EqEq Binary 7 "" " == " "" "" }
{ NtEq Binary 7 "" " != " "" "" }
{ BitAnd Binary 8 "" " & " "" "" }
{ BitXor Binary 9 "" " ^ " "" "" }
{ BitOr Binary 10 "" " | " "" "" }
{ LogAnd Binary 11 "" " && " "" "" }
{ LogOr Binary 12 "" " || " "" "" }
{ BitAnd Binary 8 "" " & " "" "" }
{ BitXor Binary 9 "" " ^ " "" "" }
{ BitOr Binary 10 "" " | " "" "" }
{ LogAnd Binary 11 "" " && " "" "" }
{ LogOr Binary 12 "" " || " "" "" }
{ Ternary Null 0 "" " ? " " : " "" }
{ Ternary Null 0 "" " ? " " : " "" }
{ Call Null 15 "" "(" ")" ", "}
{ Call Null 15 "" "(" ")" ", "}
{ LeafBytecode Null 0 "" "" "" "" }
{ LeafStringLiteral Null 0 "" "" "" "" }
{ LeafU64 Null 0 "" "" "" "" }
{ LeafF64 Null 0 "" "" "" "" }
{ LeafF32 Null 0 "" "" "" "" }
{ LeafIdentifier Null 0 "" "" "" "" }
{ LeafOffset Null 0 "" "" "" "" }
{ LeafValue Null 0 "" "" "" "" }
{ LeafFilePath Null 0 "" "" "" "" }
{ LeafBytecode Null 0 "" "" "" "" }
{ LeafStringLiteral Null 0 "" "" "" "" }
{ LeafU64 Null 0 "" "" "" "" }
{ LeafF64 Null 0 "" "" "" "" }
{ LeafF32 Null 0 "" "" "" "" }
{ LeafIdentifier Null 0 "" "" "" "" }
{ LeafOffset Null 0 "" "" "" "" }
{ LeafValue Null 0 "" "" "" "" }
{ LeafFilePath Null 0 "" "" "" "" }
{ TypeIdent Null 0 "" "" "" "" }
{ Ptr Null 0 "" "" "" "" }
{ Array Null 0 "" "" "" "" }
{ Func Null 0 "" "" "" "" }
{ TypeIdent Null 0 "" "" "" "" }
{ Ptr Null 0 "" "" "" "" }
{ Array Null 0 "" "" "" "" }
{ Func Null 0 "" "" "" "" }
{ Unsigned Null 0 "unsigned " "" "" "" }
{ Define Binary 13 "" " = " "" "" }
{ Define Binary 13 "" " = " "" "" }
}
@table(name display_string)
+28 -13
View File
@@ -430,26 +430,41 @@ e_auto_hook_map_make(Arena *arena, U64 slots_count)
internal void
e_auto_hook_map_insert_new_(Arena *arena, E_AutoHookMap *map, E_AutoHookParams *params)
{
// rjf: get type key
E_TypeKey type_key = params->type_key;
if(params->type_pattern.size != 0)
{
E_Parse parse = e_push_parse_from_string(arena, params->type_pattern);
type_key = e_type_key_from_expr(parse.expr);
}
E_AutoHookNode *node = push_array(arena, E_AutoHookNode, 1);
node->type_string = str8_skip_chop_whitespace(e_type_string_from_key(arena, type_key));
U8 pattern_split = '?';
node->type_pattern_parts = str8_split(arena, params->type_pattern, &pattern_split, 1, StringSplitFlag_KeepEmpties);
node->expr = e_parse_from_string(params->tag_expr_string).expr;
if(!e_type_key_match(e_type_key_zero(), type_key))
// rjf: get type pattern parts
String8List pattern_parts = {0};
if(e_type_key_match(e_type_key_zero(), type_key))
{
U64 hash = e_hash_from_string(5381, node->type_string);
U64 slot_idx = hash%map->slots_count;
SLLQueuePush_N(map->slots[slot_idx].first, map->slots[slot_idx].last, node, hash_next);
U8 pattern_split = '?';
pattern_parts = str8_split(arena, params->type_pattern, &pattern_split, 1, StringSplitFlag_KeepEmpties);
}
else
// rjf: if the type key is nonzero, *or* we have type patterns, then insert
// into map accordingle
if(!e_type_key_match(e_type_key_zero(), type_key) ||
pattern_parts.node_count != 0)
{
SLLQueuePush_N(map->first_pattern, map->last_pattern, node, pattern_order_next);
E_AutoHookNode *node = push_array(arena, E_AutoHookNode, 1);
node->type_string = str8_skip_chop_whitespace(e_type_string_from_key(arena, type_key));
node->type_pattern_parts = pattern_parts;
node->expr = e_parse_from_string(params->tag_expr_string).expr;
if(!e_type_key_match(e_type_key_zero(), type_key))
{
U64 hash = e_hash_from_string(5381, node->type_string);
U64 slot_idx = hash%map->slots_count;
SLLQueuePush_N(map->slots[slot_idx].first, map->slots[slot_idx].last, node, hash_next);
}
else
{
SLLQueuePush_N(map->first_pattern, map->last_pattern, node, pattern_order_next);
}
}
}
@@ -825,7 +840,7 @@ e_irtree_from_bundle(E_CacheBundle *bundle)
bundle->flags |= E_CacheBundleFlag_IRTree;
E_IRTreeAndType overridden = e_irtree_from_key(bundle->parent_key);
E_Parse parse = e_parse_from_bundle(bundle);
bundle->irtree = e_push_irtree_and_type_from_expr(e_cache->arena, &overridden, 0, 0, parse.expr);
bundle->irtree = e_push_irtree_and_type_from_expr(e_cache->arena, &overridden, 0, 0, 0, parse.expr);
E_MsgList msgs_copy = e_msg_list_copy(e_cache->arena, &bundle->irtree.msgs);
e_msg_list_concat_in_place(&bundle->msgs, &msgs_copy);
}
@@ -1243,7 +1258,7 @@ e_debug_log_from_expr_string(Arena *arena, String8 string)
}
//- rjf: type
E_IRTreeAndType irtree = e_push_irtree_and_type_from_expr(scratch.arena, 0, 0, 0, parse.expr);
E_IRTreeAndType irtree = e_push_irtree_and_type_from_expr(scratch.arena, 0, 0, 0, 0, parse.expr);
{
str8_list_pushf(scratch.arena, &strings, " type:\n");
S32 indent = 2;
+173 -30
View File
@@ -492,7 +492,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(default)
E_Expr *exprl = expr->first;
E_Expr *exprr = exprl->next;
E_IRTreeAndType l = *lhs_irtree;
E_IRTreeAndType r = e_push_irtree_and_type_from_expr(arena, overridden, 0, 0, exprr);
E_IRTreeAndType r = e_push_irtree_and_type_from_expr(arena, overridden, 0, 0, 0, exprr);
e_msg_list_concat_in_place(&result.msgs, &r.msgs);
E_TypeKey l_restype = e_type_key_unwrap(l.type_key, E_TypeUnwrapFlag_AllDecorative);
E_TypeKey r_restype = e_type_key_unwrap(r.type_key, E_TypeUnwrapFlag_AllDecorative);
@@ -585,7 +585,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(default)
//- rjf: top-level irtree/type extraction
internal E_IRTreeAndType
e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, B32 disallow_autohooks, B32 disallow_chained_fastpaths, E_Expr *root_expr)
e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, B32 disallow_autohooks, B32 disallow_chained_fastpaths, B32 disallow_chained_casts, E_Expr *root_expr)
{
ProfBeginFunction();
Temp scratch = scratch_begin(&arena, 1);
@@ -636,7 +636,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden,
{
// rjf: unpack left-hand-side
E_Expr *lhs = expr->first;
E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, lhs);
E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, lhs);
e_msg_list_concat_in_place(&result.msgs, &lhs_irtree.msgs);
// rjf: try all IR trees in chain
@@ -693,7 +693,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden,
{
// rjf: unpack operand
E_Expr *r_expr = expr->first;
E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr);
E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr);
e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs);
E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative);
E_TypeKind r_type_kind = e_type_kind_from_key(r_type);
@@ -752,7 +752,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden,
{
// rjf: unpack operand
E_Expr *r_expr = expr->first;
E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr);
E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr);
e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs);
E_TypeKey r_type = r_tree.type_key;
E_TypeKey r_type_unwrapped = e_type_key_unwrap(r_type, E_TypeUnwrapFlag_AllDecorative);
@@ -780,12 +780,12 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden,
// rjf: unpack operands
E_Expr *cast_type_expr = expr->first;
E_Expr *casted_expr = cast_type_expr->next;
E_IRTreeAndType cast_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, cast_type_expr);
E_IRTreeAndType cast_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, cast_type_expr);
e_msg_list_concat_in_place(&result.msgs, &cast_irtree.msgs);
E_TypeKey cast_type = cast_irtree.type_key;
E_TypeKind cast_type_kind = e_type_kind_from_key(cast_type);
U64 cast_type_byte_size = e_type_byte_size_from_key(cast_type);
E_IRTreeAndType casted_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, casted_expr);
E_IRTreeAndType casted_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, casted_expr);
e_msg_list_concat_in_place(&result.msgs, &casted_tree.msgs);
E_TypeKey casted_type = e_type_key_unwrap(casted_tree.type_key, E_TypeUnwrapFlag_AllDecorative);
E_TypeKind casted_type_kind = e_type_kind_from_key(casted_type);
@@ -840,7 +840,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden,
E_Expr *r_expr = expr->first;
E_TypeKey r_type = zero_struct;
E_Space space = r_expr->space;
E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr);
E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr);
e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs);
r_type = r_tree.type_key;
@@ -868,7 +868,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden,
{
// rjf: evaluate operand tree
E_Expr *r_expr = expr->first;
E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr);
E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr);
e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs);
// rjf: fill output
@@ -882,7 +882,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden,
{
// rjf: unpack operand
E_Expr *r_expr = expr->first;
E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr);
E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr);
e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs);
E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative);
E_TypeKind r_type_kind = e_type_kind_from_key(r_type);
@@ -910,14 +910,14 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden,
//- rjf: unary operations
case E_ExprKind_Pos:
{
result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, expr->first);
result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, expr->first);
}break;
case E_ExprKind_Neg:
case E_ExprKind_BitNot:
{
// rjf: unpack operand
E_Expr *r_expr = expr->first;
E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr);
E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr);
e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs);
E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative);
E_TypeKind r_type_kind = e_type_kind_from_key(r_type);
@@ -950,7 +950,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden,
{
// rjf: unpack operand
E_Expr *r_expr = expr->first;
E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr);
E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr);
e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs);
E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative);
E_TypeKind r_type_kind = e_type_kind_from_key(r_type);
@@ -1005,8 +1005,8 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden,
B32 is_comparison = e_expr_kind_is_comparison(kind);
E_Expr *l_expr = expr->first;
E_Expr *r_expr = l_expr->next;
E_IRTreeAndType l_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, l_expr);
E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr);
E_IRTreeAndType l_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, l_expr);
E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr);
e_msg_list_concat_in_place(&result.msgs, &l_tree.msgs);
e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs);
E_TypeKey l_type = e_type_key_unwrap(l_tree.type_key, E_TypeUnwrapFlag_AllDecorative);
@@ -1229,9 +1229,9 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden,
E_Expr *c_expr = expr->first;
E_Expr *l_expr = c_expr->next;
E_Expr *r_expr = l_expr->next;
E_IRTreeAndType c_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, c_expr);
E_IRTreeAndType l_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, l_expr);
E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr);
E_IRTreeAndType c_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, c_expr);
E_IRTreeAndType l_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, l_expr);
E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, r_expr);
e_msg_list_concat_in_place(&result.msgs, &c_tree.msgs);
e_msg_list_concat_in_place(&result.msgs, &l_tree.msgs);
e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs);
@@ -1275,18 +1275,72 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden,
case E_ExprKind_Call:
{
E_Expr *lhs = expr->first;
E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, 1, lhs);
E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, 1, lhs);
e_msg_list_concat_in_place(&result.msgs, &lhs_irtree.msgs);
E_TypeKey lhs_type_key = lhs_irtree.type_key;
E_Type *lhs_type = e_type_from_key__cached(lhs_type_key);
// rjf: calling a type? -> treat as a cast of that type
if(lhs_irtree.mode == E_Mode_Null)
{
E_IRTreeAndType casted_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, 1, disallow_chained_casts, expr->first->next);
e_msg_list_concat_in_place(&result.msgs, &casted_tree.msgs);
E_TypeKey cast_type = lhs_irtree.type_key;
E_TypeKind cast_type_kind = e_type_kind_from_key(cast_type);
U64 cast_type_byte_size = e_type_byte_size_from_key(cast_type);
E_TypeKey casted_type = casted_tree.type_key;
E_TypeKind casted_type_kind = e_type_kind_from_key(casted_type);
U64 casted_type_byte_size = e_type_byte_size_from_key(casted_type);
U8 in_group = e_type_group_from_kind(casted_type_kind);
U8 out_group = e_type_group_from_kind(cast_type_kind);
RDI_EvalConversionKind conversion_rule = rdi_eval_conversion_kind_from_typegroups(in_group, out_group);
// rjf: bad conditions? -> error if applicable, exit
if(casted_tree.root->op == 0)
{
break;
}
else if(cast_type_kind == E_TypeKind_Null)
{
break;
}
else if(conversion_rule != RDI_EvalConversionKind_Noop &&
conversion_rule != RDI_EvalConversionKind_Legal)
{
String8 text = str8_lit("Unknown cast conversion rule.");
if(conversion_rule < RDI_EvalConversionKind_COUNT)
{
text.str = rdi_explanation_string_from_eval_conversion_kind(conversion_rule, &text.size);
}
e_msg(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, text);
break;
}
// rjf: generate casted result
{
E_IRNode *in_tree = e_irtree_resolve_to_value(arena, casted_tree.mode, casted_tree.root, casted_type);
E_IRNode *new_tree = in_tree;
if(conversion_rule == RDI_EvalConversionKind_Legal)
{
new_tree = e_irtree_convert_lo(arena, in_tree, out_group, in_group);
}
if(cast_type_byte_size < casted_type_byte_size && e_type_kind_is_integer(cast_type_kind))
{
new_tree = e_irtree_trunc(arena, in_tree, cast_type);
}
result.root = new_tree;
result.type_key = cast_type;
result.mode = E_Mode_Value;
}
}
// rjf: calling an unresolved leaf-identifier member access, and we can determine
// that that identifer maps to a type? -> generate a call expression with the
// left-hand-side of the dot operator as the first argument. this is a fast path
// which prevents paren nesting in simple cases, to easily chain multiple
// calls - for example, bin(2).digits(4)
if(lhs_type == &e_type_nil &&
lhs->kind == E_ExprKind_MemberAccess)
else if(lhs_type == &e_type_nil &&
lhs->kind == E_ExprKind_MemberAccess)
{
E_Expr *callee = lhs->first->next;
E_Expr *first_arg = e_expr_ref(arena, lhs->first);
@@ -1297,7 +1351,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden,
{
e_expr_push_child(call, e_expr_copy(arena, arg));
}
result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, call);
result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, call);
E_MsgList new_msgs = {0};
e_msg_list_concat_in_place(&new_msgs, &lhs_irtree.msgs);
e_msg_list_concat_in_place(&new_msgs, &result.msgs);
@@ -1337,7 +1391,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden,
Temp scratch = scratch_begin(&arena, 1);
// rjf: generate result via first argument to lens
result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, 1, lhs->next);
result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, 1, disallow_chained_casts, lhs->next);
// rjf: count extra arguments
U64 arg_count = 0;
@@ -1379,7 +1433,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden,
}
else
{
result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, 1, lhs->next);
result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, 1, disallow_chained_casts, lhs->next);
result.type_key = e_type_key_unwrap(result.type_key, E_TypeUnwrapFlag_Lenses);
}
}
@@ -1522,9 +1576,8 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden,
//- rjf: try to map name as implicit access of overridden expression ('$.member_name', where the $. prefix is omitted)
if(!string_mapped && overridden->root != &e_irnode_nil)
{
// TODO(rjf): @eval
E_Expr *access = e_expr_irext_member_access(scratch.arena, &e_expr_nil, overridden, string);
E_IRTreeAndType access_irtree = e_push_irtree_and_type_from_expr(scratch.arena, overridden, disallow_autohooks, disallow_chained_fastpaths, access);
E_IRTreeAndType access_irtree = e_push_irtree_and_type_from_expr(scratch.arena, overridden, disallow_autohooks, 1, 1, access);
if(access_irtree.root != &e_irnode_nil)
{
string_mapped = 1;
@@ -1892,7 +1945,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden,
{
generated = 1;
e_string2expr_map_inc_poison(e_ir_ctx->macro_map, string);
result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, macro_expr);
result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, macro_expr);
e_string2expr_map_dec_poison(e_ir_ctx->macro_map, string);
}
}
@@ -1977,15 +2030,45 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden,
result.type_key = expr->type_key;
result.mode = E_Mode_Null;
}break;
case E_ExprKind_Unsigned:
{
E_IRTreeAndType direct_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, expr->first);
result = direct_irtree;
E_TypeKey direct_type_key = result.type_key;
E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key);
if(e_type_kind_is_signed(direct_type_kind))
{
E_TypeKind new_kind = direct_type_kind;
switch(direct_type_kind)
{
default:{}break;
case E_TypeKind_Char8: {new_kind = E_TypeKind_UChar8;}break;
case E_TypeKind_Char16:{new_kind = E_TypeKind_UChar16;}break;
case E_TypeKind_Char32:{new_kind = E_TypeKind_UChar32;}break;
case E_TypeKind_S8:{new_kind = E_TypeKind_U8;}break;
case E_TypeKind_S16:{new_kind = E_TypeKind_U16;}break;
case E_TypeKind_S32:{new_kind = E_TypeKind_U32;}break;
case E_TypeKind_S64:{new_kind = E_TypeKind_U64;}break;
case E_TypeKind_S128:{new_kind = E_TypeKind_U128;}break;
case E_TypeKind_S256:{new_kind = E_TypeKind_U256;}break;
case E_TypeKind_S512:{new_kind = E_TypeKind_U512;}break;
}
result.type_key = e_type_key_basic(new_kind);
}
else
{
e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->first->location, "Cannot apply an `unsigned` modifier to this type.");
}
}break;
case E_ExprKind_Ptr:
{
E_IRTreeAndType ptee_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, expr->first);
E_IRTreeAndType ptee_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, expr->first);
result = ptee_irtree;
result.type_key = e_type_key_cons_ptr(e_base_ctx->primary_module->arch, result.type_key, 1, 0);
}break;
case E_ExprKind_Array:
{
E_IRTreeAndType element_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, expr->first);
E_IRTreeAndType element_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, expr->first);
result = element_irtree;
result.type_key = e_type_key_cons_array(result.type_key, expr->value.u64, 0);
}break;
@@ -1999,7 +2082,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden,
{
E_Expr *lhs = expr->first;
E_Expr *rhs = lhs->next;
result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, rhs);
result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, disallow_chained_casts, rhs);
if(lhs->kind != E_ExprKind_LeafIdentifier)
{
e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Left side of assignment must be an unused identifier.");
@@ -2007,6 +2090,66 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden,
}break;
}
//- rjf: if our currently-computed result is just a type, and we have
// a chained expression, then treat the first expression as a cast on
// the second.
if(!disallow_chained_casts && result.mode == E_Mode_Null && expr->next != &e_expr_nil)
{
// rjf: unpack
E_IRTreeAndType cast_type_tree = result;
E_IRTreeAndType casted_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, 1, disallow_chained_casts, expr->next);
e_msg_list_concat_in_place(&result.msgs, &casted_tree.msgs);
E_TypeKey cast_type = cast_type_tree.type_key;
E_TypeKind cast_type_kind = e_type_kind_from_key(cast_type);
U64 cast_type_byte_size = e_type_byte_size_from_key(cast_type);
E_TypeKey casted_type = casted_tree.type_key;
E_TypeKind casted_type_kind = e_type_kind_from_key(casted_type);
U64 casted_type_byte_size = e_type_byte_size_from_key(casted_type);
U8 in_group = e_type_group_from_kind(casted_type_kind);
U8 out_group = e_type_group_from_kind(cast_type_kind);
RDI_EvalConversionKind conversion_rule = rdi_eval_conversion_kind_from_typegroups(in_group, out_group);
// rjf: bad conditions? -> error if applicable, exit
if(casted_tree.root->op == 0)
{
goto end_cast_gen;
}
else if(cast_type_kind == E_TypeKind_Null)
{
goto end_cast_gen;
}
else if(conversion_rule != RDI_EvalConversionKind_Noop &&
conversion_rule != RDI_EvalConversionKind_Legal)
{
String8 text = str8_lit("Unknown cast conversion rule.");
if(conversion_rule < RDI_EvalConversionKind_COUNT)
{
text.str = rdi_explanation_string_from_eval_conversion_kind(conversion_rule, &text.size);
}
e_msg(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, text);
goto end_cast_gen;
}
// rjf: generate casted result
{
E_IRNode *in_tree = e_irtree_resolve_to_value(arena, casted_tree.mode, casted_tree.root, casted_type);
E_IRNode *new_tree = in_tree;
if(conversion_rule == RDI_EvalConversionKind_Legal)
{
new_tree = e_irtree_convert_lo(arena, in_tree, out_group, in_group);
}
if(cast_type_byte_size < casted_type_byte_size && e_type_kind_is_integer(cast_type_kind))
{
new_tree = e_irtree_trunc(arena, in_tree, cast_type);
}
result.root = new_tree;
result.type_key = cast_type;
result.mode = E_Mode_Value;
}
end_cast_gen:;
}
//- rjf: check chained expressions for simple wrappers
if(!disallow_chained_fastpaths)
{
+1 -1
View File
@@ -88,7 +88,7 @@ internal void e_expr_unpoison(E_Expr *expr);
//- rjf: top-level irtree/type extraction
E_TYPE_ACCESS_FUNCTION_DEF(default);
internal E_IRTreeAndType e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, B32 disallow_autohooks, B32 disallow_chained_fastpaths, E_Expr *root_expr);
internal E_IRTreeAndType e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, B32 disallow_autohooks, B32 disallow_chained_fastpaths, B32 disallow_chained_casts, E_Expr *root_expr);
//- rjf: irtree -> linear ops/bytecode
internal void e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_Space *current_space, E_OpList *out);
+23 -1
View File
@@ -672,6 +672,10 @@ e_type_key_from_expr(E_Expr *expr)
{
// TODO(rjf): do we support E_ExprKind_Func here?
default:{}break;
case E_ExprKind_LeafIdentifier:
{
result = e_leaf_type_from_name(expr->string);
}break;
case E_ExprKind_TypeIdent:
{
result = expr->type_key;
@@ -867,6 +871,13 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t
}
}
// rjf: try 'unsigned' marker
if(str8_match(token_string, str8_lit("unsigned"), 0))
{
prefix_unary_kind = E_ExprKind_Unsigned;
prefix_unary_precedence = 2;
}
// rjf: consume valid op
if(prefix_unary_precedence != 0)
{
@@ -875,6 +886,7 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t
}
// rjf: try casting expression
#if 0
if(prefix_unary_precedence == 0 && str8_match(token_string, str8_lit("("), 0))
{
E_Token some_type_identifier_maybe = e_token_at_it(it+1, &tokens);
@@ -915,6 +927,7 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t
}
}
}
#endif
// rjf: break if we got no operators
if(prefix_unary_precedence == 0)
@@ -1341,7 +1354,16 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t
e_msg_list_concat_in_place(&result.msgs, &rhs_expr_parse.msgs);
E_Expr *rhs = rhs_expr_parse.expr;
it = rhs_expr_parse.last_token;
if(rhs == &e_expr_nil)
if(rhs == &e_expr_nil && binary_kind == E_ExprKind_Mul)
{
// NOTE(rjf): C-style pointer syntax is shared with multiplication.
// carving out a special case here to allow "unfinished *s" to be
// treated as pointers instead.
E_Expr *ptee = atom;
atom = e_push_expr(arena, E_ExprKind_Ptr, token_string.str);
e_expr_push_child(atom, ptee);
}
else if(rhs == &e_expr_nil)
{
e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Missing right-hand-side of `%S`.", token_string);
}
+1 -1
View File
@@ -2477,7 +2477,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(slice)
// rjf: compute struct.base_ptr IR tree
E_IRTreeAndType override = {&e_irnode_nil};
result = e_push_irtree_and_type_from_expr(arena, &override, 0, 0, idx_expr);
result = e_push_irtree_and_type_from_expr(arena, &override, 0, 0, 0, idx_expr);
scratch_end(scratch);
}break;
+4 -2
View File
@@ -144,7 +144,7 @@ U8 e_type_kind_basic_byte_size_table[61] =
0,
};
String8 e_expr_kind_strings[48] =
String8 e_expr_kind_strings[49] =
{
str8_lit_comp("Nil"),
str8_lit_comp("Ref"),
@@ -193,10 +193,11 @@ str8_lit_comp("TypeIdent"),
str8_lit_comp("Ptr"),
str8_lit_comp("Array"),
str8_lit_comp("Func"),
str8_lit_comp("Unsigned"),
str8_lit_comp("Define"),
};
E_OpInfo e_expr_kind_op_info_table[48] =
E_OpInfo e_expr_kind_op_info_table[49] =
{
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
@@ -245,6 +246,7 @@ E_OpInfo e_expr_kind_op_info_table[48] =
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp("unsigned "), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Binary, 13, str8_lit_comp(""), str8_lit_comp(" = "), str8_lit_comp(""), str8_lit_comp("") },
};
+3 -2
View File
@@ -145,6 +145,7 @@ E_ExprKind_TypeIdent,
E_ExprKind_Ptr,
E_ExprKind_Array,
E_ExprKind_Func,
E_ExprKind_Unsigned,
E_ExprKind_Define,
E_ExprKind_COUNT,
} E_ExprKindEnum;
@@ -169,8 +170,8 @@ C_LINKAGE_BEGIN
extern String8 e_token_kind_strings[6];
extern String8 e_type_kind_basic_string_table[61];
extern U8 e_type_kind_basic_byte_size_table[61];
extern String8 e_expr_kind_strings[48];
extern E_OpInfo e_expr_kind_op_info_table[48];
extern String8 e_expr_kind_strings[49];
extern E_OpInfo e_expr_kind_op_info_table[49];
extern String8 e_interpretation_code_display_strings[11];
C_LINKAGE_END
+6 -6
View File
@@ -160,12 +160,12 @@ struct {RDI_EvalConversionKind dst_typegroups[RDI_EvalTypeGroup_COUNT];} rdi_eva
struct {RDI_U8 *str; RDI_U64 size;} rdi_eval_conversion_kind_message_string_table[6] =
{
{(RDI_U8 *)"Other", sizeof("Other")},
{(RDI_U8 *)"U", sizeof("U")},
{(RDI_U8 *)"S", sizeof("S")},
{(RDI_U8 *)"F32", sizeof("F32")},
{(RDI_U8 *)"F64", sizeof("F64")},
{(RDI_U8 *)"COUNT", sizeof("COUNT")},
{(RDI_U8 *)"", sizeof("")},
{(RDI_U8 *)"", sizeof("")},
{(RDI_U8 *)"Cannot convert between these types.", sizeof("Cannot convert between these types.")},
{(RDI_U8 *)"Cannot convert to this type.", sizeof("Cannot convert to this type.")},
{(RDI_U8 *)"Cannot convert this type.", sizeof("Cannot convert this type.")},
{(RDI_U8 *)"", sizeof("")},
};
RDI_PROC RDI_U64
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -225,9 +225,9 @@ RD_VocabTable:
@default(1) 'scrolling_animations': bool,
//- rjf: fonts
@display_name('UI Font') @description("The name or path to the font used when displaying non-code UI elements.")
@display_name('UI Font') @description("The name of, or path to, the font used when displaying non-code UI elements.")
'main_font': string,
@display_name('Code Font') @description("The name or path to the font used when displaying code.")
@display_name('Code Font') @description("The name of, or path to, the font used when displaying code.")
'code_font': string,
//- rjf: colors
+32 -21
View File
@@ -1301,36 +1301,48 @@ rd_setting_from_name(String8 name)
internal B32
rd_setting_b32_from_name(String8 name)
{
Temp scratch = scratch_begin(0, 0);
B32 result = 0;
String8 value = rd_setting_from_name(name);
String8 expr = push_str8f(scratch.arena, "(bool)(%S)", value);
E_Eval eval = e_eval_from_string(expr);
B32 result = !!e_value_eval_from_eval(eval).value.u64;
scratch_end(scratch);
if(value.size != 0)
{
Temp scratch = scratch_begin(0, 0);
String8 expr = push_str8f(scratch.arena, "(bool)(%S)", value);
E_Eval eval = e_eval_from_string(expr);
result = !!e_value_eval_from_eval(eval).value.u64;
scratch_end(scratch);
}
return result;
}
internal U64
rd_setting_u64_from_name(String8 name)
{
Temp scratch = scratch_begin(0, 0);
U64 result = 0;
String8 value = rd_setting_from_name(name);
String8 expr = push_str8f(scratch.arena, "(uint64)(%S)", value);
E_Eval eval = e_eval_from_string(expr);
U64 result = e_value_eval_from_eval(eval).value.u64;
scratch_end(scratch);
if(value.size != 0)
{
Temp scratch = scratch_begin(0, 0);
String8 expr = push_str8f(scratch.arena, "(uint64)(%S)", value);
E_Eval eval = e_eval_from_string(expr);
result = e_value_eval_from_eval(eval).value.u64;
scratch_end(scratch);
}
return result;
}
internal F32
rd_setting_f32_from_name(String8 name)
{
Temp scratch = scratch_begin(0, 0);
F32 result = 0.f;
String8 value = rd_setting_from_name(name);
String8 expr = push_str8f(scratch.arena, "(float32)(%S)", value);
E_Eval eval = e_eval_from_string(expr);
F32 result = e_value_eval_from_eval(eval).value.f32;
scratch_end(scratch);
if(value.size != 0)
{
Temp scratch = scratch_begin(0, 0);
String8 expr = push_str8f(scratch.arena, "(float32)(%S)", value);
E_Eval eval = e_eval_from_string(expr);
result = e_value_eval_from_eval(eval).value.f32;
scratch_end(scratch);
}
return result;
}
@@ -4357,16 +4369,15 @@ rd_view_ui(Rng2F32 rect)
F32 cell_slider_value = 0.f;
if(str8_match(cell_type->name, str8_lit("range1"), 0) && cell_type->args != 0 && cell_type->count >= 2)
{
E_Expr *min_expr = cell_type->args[0];
E_Expr *max_expr = cell_type->args[1];
E_Key min_key = e_key_from_expr(cell_type->args[0]);
E_Key max_key = e_key_from_expr(cell_type->args[1]);
E_ParentKey(cell->eval.key)
{
E_TypeKey slider_value_type = e_type_key_unwrap(cell_type->direct_type_key, E_TypeUnwrapFlag_AllDecorative);
slider_value_type_kind = e_type_kind_from_key(slider_value_type);
E_Expr *min_casted = e_expr_ref_cast(scratch.arena, slider_value_type, min_expr);
E_Expr *max_casted = e_expr_ref_cast(scratch.arena, slider_value_type, max_expr);
cell_slider_min = e_value_from_expr(min_casted);
cell_slider_max = e_value_from_expr(max_casted);
String8 slider_type_name = e_type_string_from_key(scratch.arena, slider_value_type);
cell_slider_min = e_value_from_key(e_key_wrapf(min_key, "(%S)$", slider_type_name));
cell_slider_max = e_value_from_key(e_key_wrapf(max_key, "(%S)$", slider_type_name));
}
}
switch(slider_value_type_kind)
+2 -2
View File
@@ -1376,7 +1376,7 @@ rdi_eval_typegroup_conversion_kind_matrix:
@data(`struct {RDI_U8 *str; RDI_U64 size;}`) @c_file
rdi_eval_conversion_kind_message_string_table:
{
@expand(RDI_EvalTypeGroupTable a) `{(RDI_U8 *)"$(a.error_string)", sizeof("$(a.error_string)")}`
@expand(RDI_EvalConversionKindTable a) `{(RDI_U8 *)"$(a.error_string)", sizeof("$(a.error_string)")}`
}
////////////////////////////////
@@ -1503,7 +1503,7 @@ rdi_hash(RDI_U8 *ptr, RDI_U64 size)
@expand(RDI_TypeKindTable a) ` case RDI_TypeKind_$(a.name): {result = (RDI_U8*)"$(a.name)"; *size_out = sizeof("$(a.name)")-1;}break;`,
`}`;
`return result;`;
`}`;
`}`;
``;
}