summaryrefslogtreecommitdiffstats
path: root/parse.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'parse.cxx')
-rw-r--r--parse.cxx49
1 files changed, 48 insertions, 1 deletions
diff --git a/parse.cxx b/parse.cxx
index 0419dcb9..aeb11998 100644
--- a/parse.cxx
+++ b/parse.cxx
@@ -2331,7 +2331,54 @@ parser::parse_symbol ()
bool pf_stream, pf_format, pf_delim, pf_newline, pf_char;
- if (name.size() > 0 && name[0] == '@')
+ if (name == "@cast")
+ {
+ // type-punning time
+ cast_op *cop = new cast_op;
+ cop->tok = t;
+ cop->base_name = name;
+ expect_op("(");
+ cop->operand = parse_expression ();
+ expect_op(",");
+ expect_unknown(tok_string, cop->type);
+ if (peek_op (","))
+ {
+ next();
+ expect_unknown(tok_string, cop->module);
+ }
+ expect_op(")");
+ while (true)
+ {
+ string c;
+ if (peek_op ("->"))
+ {
+ next();
+ expect_ident_or_keyword (c);
+ cop->components.push_back
+ (make_pair (target_symbol::comp_struct_member, c));
+ }
+ else if (peek_op ("["))
+ {
+ next();
+ expect_unknown (tok_number, c);
+ expect_op ("]");
+ cop->components.push_back
+ (make_pair (target_symbol::comp_literal_array_index, c));
+ }
+ else
+ break;
+ }
+ // if there aren't any dereferences, then the cast is pointless
+ if (cop->components.empty())
+ {
+ expression *op = cop->operand;
+ delete cop;
+ return op;
+ }
+ return cop;
+ }
+
+ else if (name.size() > 0 && name[0] == '@')
{
stat_op *sop = new stat_op;
if (name == "@avg")