aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-04-23 13:12:49 -0400
committerBruce Hill <bruce@bruce-hill.com>2024-04-23 13:12:49 -0400
commit63083252522d22f5ed9d14912696fab1c8347b65 (patch)
tree36dd280608719c0d77539631f585cde25a6ea0dd
parent005427744daa8d70abeffde9a05831b4bdb0682f (diff)
Add constructor/casting for ints and nums
-rw-r--r--compile.c17
-rw-r--r--test/integers.tm3
-rw-r--r--test/nums.tm3
-rw-r--r--typecheck.c2
4 files changed, 20 insertions, 5 deletions
diff --git a/compile.c b/compile.c
index 850f2e2a..fa836414 100644
--- a/compile.c
+++ b/compile.c
@@ -1621,11 +1621,20 @@ CORD compile(env_t *env, ast_t *ast)
return CORD_all(fn, "(", compile_arguments(env, ast, Match(fn_t, FunctionType)->args, call->args), ")");
} else if (fn_t->tag == TypeInfoType) {
type_t *t = Match(fn_t, TypeInfoType)->type;
- if (!(t->tag == StructType))
+ if (t->tag == StructType) {
+ fn_t = Type(FunctionType, .args=Match(t, StructType)->fields, .ret=t);
+ CORD fn = compile(env, call->fn);
+ return CORD_all(fn, "(", compile_arguments(env, ast, Match(fn_t, FunctionType)->args, call->args), ")");
+ } else if (t->tag == IntType || t->tag == NumType) {
+ if (!call->args || call->args->next)
+ code_err(call->fn, "This constructor takes exactly 1 argument");
+ type_t *actual = get_type(env, call->args->value);
+ if (actual->tag != IntType && actual->tag != NumType)
+ code_err(call->args->value, "This %T value cannot be converted to a %T", actual, t);
+ return CORD_all("((", compile_type(env, t), ")(", compile(env, call->args->value), "))");
+ } else {
code_err(call->fn, "This is not a type that has a constructor");
- fn_t = Type(FunctionType, .args=Match(t, StructType)->fields, .ret=t);
- CORD fn = compile(env, call->fn);
- return CORD_all(fn, "(", compile_arguments(env, ast, Match(fn_t, FunctionType)->args, call->args), ")");
+ }
} else if (fn_t->tag == ClosureType) {
fn_t = Match(fn_t, ClosureType)->fn;
arg_t *type_args = Match(fn_t, FunctionType)->args;
diff --git a/test/integers.tm b/test/integers.tm
index 376e0319..9b573aac 100644
--- a/test/integers.tm
+++ b/test/integers.tm
@@ -53,3 +53,6 @@ func main()
= "0x7B"
>> 123_i8:hex()
= "0x7B"
+
+ >> Int(2.1)
+ = 2 : Int
diff --git a/test/nums.tm b/test/nums.tm
index aee7c688..4e9c81a4 100644
--- a/test/nums.tm
+++ b/test/nums.tm
@@ -53,3 +53,6 @@ func main()
= 12.5
>> 2.0:mix(10, 20)
= 30
+
+ >> Num(5)
+ = 5 : Num
diff --git a/typecheck.c b/typecheck.c
index 229a8cd2..4fcbcf20 100644
--- a/typecheck.c
+++ b/typecheck.c
@@ -509,7 +509,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)
+ if (t->tag == StructType || t->tag == IntType || t->tag == NumType)
return t; // Constructor
code_err(call->fn, "This is not a type that has a constructor");
}