Add some missing functionality for Bytes
This commit is contained in:
parent
81a180eda0
commit
b69d14b894
20
compile.c
20
compile.c
@ -679,7 +679,7 @@ CORD compile_statement(env_t *env, ast_t *ast)
|
||||
type_t *lhs_t = get_type(env, update->lhs);
|
||||
type_t *rhs_t = get_type(env, update->rhs);
|
||||
if (!promote(env, &rhs, rhs_t, lhs_t)) {
|
||||
if (update->rhs->tag == Int && lhs_t->tag == IntType)
|
||||
if (update->rhs->tag == Int && (lhs_t->tag == IntType || lhs_t->tag == ByteType))
|
||||
rhs = compile_int_to_type(env, update->rhs, lhs_t);
|
||||
else if (!(lhs_t->tag == ArrayType && promote(env, &rhs, rhs_t, Match(lhs_t, ArrayType)->item_type)))
|
||||
code_err(ast, "I can't do operations between %T and %T", lhs_t, rhs_t);
|
||||
@ -1623,7 +1623,6 @@ CORD compile_int_to_type(env_t *env, ast_t *ast, type_t *target)
|
||||
return code;
|
||||
}
|
||||
|
||||
int64_t target_bits = (int64_t)Match(target, IntType)->bits;
|
||||
OptionalInt_t int_val = Int$from_str(Match(ast, Int)->str);
|
||||
if (int_val.small == 0)
|
||||
code_err(ast, "Failed to parse this integer");
|
||||
@ -1631,6 +1630,13 @@ CORD compile_int_to_type(env_t *env, ast_t *ast, type_t *target)
|
||||
mpz_t i;
|
||||
mpz_init_set_int(i, int_val);
|
||||
|
||||
if (target->tag == ByteType) {
|
||||
if (mpz_cmp_si(i, UINT8_MAX) <= 0 && mpz_cmp_si(i, 0) >= 0)
|
||||
return CORD_asprintf("(Byte_t)(%s)", Match(ast, Int)->str);
|
||||
code_err(ast, "This integer cannot fit in a byte");
|
||||
}
|
||||
|
||||
int64_t target_bits = (int64_t)Match(target, IntType)->bits;
|
||||
switch (target_bits) {
|
||||
case TYPE_IBITS64:
|
||||
if (mpz_cmp_si(i, INT64_MAX) <= 0 && mpz_cmp_si(i, INT64_MIN) >= 0)
|
||||
@ -2075,7 +2081,7 @@ CORD compile(env_t *env, ast_t *ast)
|
||||
|
||||
// Special case for bit shifting by an integer literal:
|
||||
if (binop->op == BINOP_LSHIFT || binop->op == BINOP_RSHIFT || binop->op == BINOP_ULSHIFT || binop->op == BINOP_URSHIFT) {
|
||||
if (lhs_t->tag == IntType && rhs_t->tag == BigIntType && binop->rhs->tag == Int) {
|
||||
if ((lhs_t->tag == IntType || lhs_t->tag == ByteType) && rhs_t->tag == BigIntType && binop->rhs->tag == Int) {
|
||||
CORD shift_amount = compile_int_to_type(env, binop->rhs, lhs_t);
|
||||
if (binop->op == BINOP_LSHIFT)
|
||||
return CORD_all("(", lhs, " << ", shift_amount, ")");
|
||||
@ -3024,7 +3030,7 @@ CORD compile(env_t *env, ast_t *ast)
|
||||
type_t *actual = get_type(env, call->args->value);
|
||||
arg_t *args = new(arg_t, .name="i", .type=actual); // No truncation argument
|
||||
CORD arg_code = compile_arguments(env, ast, args, call->args);
|
||||
if (is_numeric_type(actual)) {
|
||||
if (is_numeric_type(actual) || actual->tag == ByteType) {
|
||||
return CORD_all(type_to_cord(actual), "_to_", type_to_cord(t), "(", arg_code, ")");
|
||||
} else if (actual->tag == BoolType) {
|
||||
if (t->tag == NumType) {
|
||||
@ -3035,9 +3041,9 @@ CORD compile(env_t *env, ast_t *ast)
|
||||
} else {
|
||||
code_err(ast, "You cannot convert a %T to a %T this way.", actual, t);
|
||||
}
|
||||
} else if (t->tag == IntType) {
|
||||
} else if (t->tag == IntType || t->tag == ByteType) {
|
||||
type_t *actual = get_type(env, call->args->value);
|
||||
if (is_numeric_type(actual)) {
|
||||
if (is_numeric_type(actual) || actual->tag == ByteType) {
|
||||
arg_t *args = new(arg_t, .name="i", .type=actual, .next=new(arg_t, .name="truncate", .type=Type(BoolType),
|
||||
.default_val=FakeAST(Bool, false)));
|
||||
CORD arg_code = compile_arguments(env, ast, args, call->args);
|
||||
@ -3427,7 +3433,7 @@ CORD compile(env_t *env, ast_t *ast)
|
||||
type_t *container_t = value_type(indexed_type);
|
||||
type_t *index_t = get_type(env, indexing->index);
|
||||
if (container_t->tag == ArrayType) {
|
||||
if (index_t->tag != IntType && index_t->tag != BigIntType)
|
||||
if (index_t->tag != IntType && index_t->tag != BigIntType && index_t->tag != ByteType)
|
||||
code_err(indexing->index, "Arrays can only be indexed by integers, not %T", index_t);
|
||||
type_t *item_type = Match(container_t, ArrayType)->item_type;
|
||||
CORD arr = compile_to_pointer_depth(env, indexing->indexed, 0, false);
|
||||
|
2
parse.c
2
parse.c
@ -1764,7 +1764,7 @@ static ast_t *parse_infix_expr(parse_ctx_t *ctx, const char *pos, int min_tightn
|
||||
else pos = key->end;
|
||||
}
|
||||
|
||||
spaces(&pos);
|
||||
whitespace(&pos);
|
||||
ast_t *rhs = parse_infix_expr(ctx, pos, op_tightness[op] + 1);
|
||||
if (!rhs) break;
|
||||
pos = rhs->end;
|
||||
|
@ -13,6 +13,16 @@
|
||||
|
||||
PUREFUNC Text_t Byte$as_text(const Byte_t *b, bool colorize, const TypeInfo_t *type);
|
||||
|
||||
#define Byte_to_Int64(b, _) ((Int64_t)(b))
|
||||
#define Byte_to_Int32(b, _) ((Int32_t)(b))
|
||||
#define Byte_to_Int16(b, _) ((Int16_t)(b))
|
||||
#define Byte_to_Int8(b, _) ((Int8_t)(b))
|
||||
|
||||
#define Int64_to_Byte(b, _) ((Byte_t)(b))
|
||||
#define Int32_to_Byte(b, _) ((Byte_t)(b))
|
||||
#define Int16_to_Byte(b, _) ((Byte_t)(b))
|
||||
#define Int8_to_Byte(b, _) ((Byte_t)(b))
|
||||
|
||||
extern const Byte_t Byte$min;
|
||||
extern const Byte_t Byte$max;
|
||||
|
||||
|
@ -702,7 +702,7 @@ type_t *get_type(env_t *env, ast_t *ast)
|
||||
if (value_t->tag == ArrayType) {
|
||||
if (!indexing->index) return indexed_t;
|
||||
type_t *index_t = get_type(env, indexing->index);
|
||||
if (index_t->tag == IntType || index_t->tag == BigIntType)
|
||||
if (index_t->tag == IntType || index_t->tag == BigIntType || index_t->tag == ByteType)
|
||||
return Match(value_t, ArrayType)->item_type;
|
||||
code_err(indexing->index, "I only know how to index lists using integers, not %T", index_t);
|
||||
} else if (value_t->tag == TableType) {
|
||||
@ -720,7 +720,7 @@ type_t *get_type(env_t *env, ast_t *ast)
|
||||
if (fn_type_t->tag == TypeInfoType) {
|
||||
type_t *t = Match(fn_type_t, TypeInfoType)->type;
|
||||
if (t->tag == StructType || t->tag == IntType || t->tag == BigIntType || t->tag == NumType
|
||||
|| t->tag == TextType || t->tag == CStringType || t->tag == DateTimeType)
|
||||
|| t->tag == ByteType || t->tag == TextType || t->tag == CStringType || t->tag == DateTimeType)
|
||||
return t; // Constructor
|
||||
code_err(call->fn, "This is not a type that has a constructor");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user