media_type decode(wchar_t const *ct) { media_type v; auto o = ct; auto r = expect_type(o, v.type); if (!r) r = expect_slash(o); if (!r) r = expect_subtype(o, v.subtype); return v; }
// Returns the type of a unary expression. // // The operand of a unary arithmetic expression (-e, +e, and ~e) // shall have integer type. The result type the expression is `int`. // // The operand of the unary logical expression (!e) shall have // boolean type. The result type the expression is `bool`. Type const* get_type(Unary_op op, Expr const* e) { Type const* z = get_int_type(); Type const* b = get_bool_type(); switch (op) { case num_neg_op: case num_pos_op: case bit_not_op: return expect_type(e, z, z); case log_not_op: return expect_type(e, b, b); default: break; } lingo_unreachable(); }
// Returns the type of a binary expression. // // The operands of a binary arithmetic expression (e1 + e2, e1 - e2, // e1 * e2, e1 / e2, e1 % e2, e1 & e2, e1 | e2, e1 ^ e2, e1 << e2, // and e1 >> e2) shall have integer type. The result type the // expression is `int`. // // The operands of a binary relational expression (e1 < e2, e1 > e2, // e1 <= e2, e1 >= e2, e1 == e2, and e1 != e2) shall have integer or // boolean type. The result type the expression is `bool`. // // The operands of a binary logical expression (e1 && e2 and e1 || e2) // shall have boolean type. The result type the expression is `bool`. Type const* get_type(Binary_op op, Expr const* e1, Expr const* e2) { Type const* z = get_int_type(); Type const* b = get_bool_type(); switch (op) { case num_add_op: case num_sub_op: case num_mul_op: case num_div_op: case num_mod_op: case bit_and_op: case bit_or_op: case bit_xor_op: case bit_lsh_op: case bit_rsh_op: // Arithmetic expressions have integer opreands and results. return expect_type(e1, e2, z, z); case rel_eq_op: case rel_ne_op: case rel_lt_op: case rel_gt_op: case rel_le_op: case rel_ge_op: // Relational expressions have any type and the result // is bool. return b; case log_and_op: case log_or_op: // Logical expressions have boolean operands and result. return expect_type(e1, e2, b, b); default: break; } lingo_unreachable(); }
int32_t expect_subtype(wchar_t const* &ct, std::wstring &subtype) { return expect_type(ct, subtype); }