aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-11-04 01:12:37 -0500
committerBruce Hill <bruce@bruce-hill.com>2024-11-04 01:12:37 -0500
commitb69d14b89492919dc5c1669d2c569ee3baf1bbb0 (patch)
tree4244c09bb428709f0e1f6e53f25e9125c4ae3cd4
parent81a180eda0efda86256b4aa2f8f6caecac3a9151 (diff)
Add some missing functionality for Bytes
-rw-r--r--compile.c20
-rw-r--r--parse.c2
-rw-r--r--stdlib/bytes.h10
-rw-r--r--typecheck.c4
4 files changed, 26 insertions, 10 deletions
diff --git a/compile.c b/compile.c
index 1cd0c2d9..5a481e0f 100644
--- a/compile.c
+++ b/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);
diff --git a/parse.c b/parse.c
index 0130673a..94f0cd0a 100644
--- a/parse.c
+++ b/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;
diff --git a/stdlib/bytes.h b/stdlib/bytes.h
index 2a92f658..f073979f 100644
--- a/stdlib/bytes.h
+++ b/stdlib/bytes.h
@@ -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;
diff --git a/typecheck.c b/typecheck.c
index e5255959..44068f5a 100644
--- a/typecheck.c
+++ b/typecheck.c
@@ -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");
}