exprs[0], exprs[1]);
break;
case opid1('^'):
- compile_error(ast_ctx(exprs[0]), "Not Yet Implemented: bit-xor via ^");
- return false;
+ /*
+ * ^ can be implemented as:
+ * (LHS | RHS) & ~(LHS & RHS)
+ * to implement ~ we need to use -1-X, as you can see the
+ * whole process ends up becoming:
+ * (LHS | RHS) & (-1 - (LHS & RHS))
+ */
+ if (NotSameType(TYPE_FLOAT)) {
+ compile_error(ctx, "invalid types used in expression: cannot perform bit operations between types %s and %s",
+ type_name[exprs[0]->vtype],
+ type_name[exprs[1]->vtype]);
+ return false;
+ }
+
+ if(CanConstFold(exprs[0], exprs[1])) {
+ out = (ast_expression*)parser_const_float(parser, (float)((qcint)(ConstF(0)) ^ ((qcint)(ConstF(1)))));
+ } else {
+ ast_binary *expr = ast_binary_new(
+ ctx,
+ INSTR_SUB_F,
+ (ast_expression*)parser_const_float_neg1(parser),
+ (ast_expression*)ast_binary_new(
+ ctx,
+ INSTR_BITAND,
+ exprs[0],
+ exprs[1]
+ )
+ );
+ expr->refs = AST_REF_NONE;
+
+ out = (ast_expression*)
+ ast_binary_new(
+ ctx,
+ INSTR_BITAND,
+ (ast_expression*)ast_binary_new(
+ ctx,
+ INSTR_BITOR,
+ exprs[0],
+ exprs[1]
+ ),
+ (ast_expression*)expr
+ );
+ }
+ break;
case opid2('<','<'):
case opid2('>','>'):
} else {
ast_binary *eq = ast_binary_new(ctx, INSTR_EQ_F, exprs[0], exprs[1]);
- eq->refs = (ast_binary_ref)false; /* references nothing */
+ eq->refs = AST_REF_NONE;
/* if (lt) { */
out = (ast_expression*)ast_ternary_new(ctx,
* it in the predef table. And diagnose it better :)
*/
if (!OPTS_FLAG(FTEPP_PREDEFS) && ftepp_predef_exists(parser_tokval(parser))) {
- parseerror(parser, "unexpected ident: %s (use -fftepp-predef to enable pre-defined macros)", parser_tokval(parser));
+ parseerror(parser, "unexpected identifier: %s (use -fftepp-predef to enable pre-defined macros)", parser_tokval(parser));
return false;
}
correct_free(&corr);
if (correct) {
- parseerror(parser, "unexpected ident: %s (did you mean %s?)", parser_tokval(parser), correct);
+ parseerror(parser, "unexpected identifier: %s (did you mean %s?)", parser_tokval(parser), correct);
mem_d(correct);
return false;
}
}
- parseerror(parser, "unexpected ident: %s", parser_tokval(parser));
+ parseerror(parser, "unexpected identifier: %s", parser_tokval(parser));
return false;
}
}
while (true)
{
if (parser->tok == TOKEN_TYPENAME) {
- parseerror(parser, "unexpected typename");
+ parseerror(parser, "unexpected typename `%s`", parser_tokval(parser));
goto onerr;
}
{
if (!parser_global_statement(parser)) {
if (parser->tok == TOKEN_EOF)
- parseerror(parser, "unexpected eof");
+ parseerror(parser, "unexpected end of file");
else if (compile_errors)
parseerror(parser, "there have been errors, bailing out");
lex_close(parser->lex);