aboutsummaryrefslogtreecommitdiff
path: root/typecheck.c
diff options
context:
space:
mode:
Diffstat (limited to 'typecheck.c')
-rw-r--r--typecheck.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/typecheck.c b/typecheck.c
index 5bc33181..fbee0d07 100644
--- a/typecheck.c
+++ b/typecheck.c
@@ -123,6 +123,13 @@ type_t *parse_type_ast(env_t *env, type_ast_t *ast)
code_err(ast, "Nested optional types are not currently supported");
return Type(OptionalType, .type=t);
}
+ case MutexedTypeAST: {
+ type_ast_t *mutexed = Match(ast, MutexedTypeAST)->type;
+ type_t *t = parse_type_ast(env, mutexed);
+ if (t->tag == VoidType || t->tag == AbortType || t->tag == ReturnType)
+ code_err(ast, "Mutexed %T types are not supported.", t);
+ return Type(MutexedType, .type=t);
+ }
case UnknownTypeAST: code_err(ast, "I don't know how to get this type");
}
#pragma GCC diagnostic pop
@@ -952,9 +959,18 @@ type_t *get_type(env_t *env, ast_t *ast)
}
case Mutexed: {
type_t *item_type = get_type(env, Match(ast, Mutexed)->value);
- type_t *user_thunk = Type(ClosureType, Type(FunctionType, .args=new(arg_t, .name="object", .type=Type(PointerType, .pointed=item_type, .is_stack=true)),
- .ret=Type(VoidType)));
- return Type(ClosureType, Type(FunctionType, .args=new(arg_t, .name="fn", .type=user_thunk), .ret=Type(VoidType)));
+ return Type(MutexedType, .type=item_type);
+ }
+ case Holding: {
+ ast_t *held = Match(ast, Holding)->mutexed;
+ type_t *held_type = get_type(env, held);
+ if (held_type->tag != MutexedType)
+ code_err(held, "This is a %t, not a mutexed value", held_type);
+ if (held->tag == Var) {
+ env = fresh_scope(env);
+ set_binding(env, Match(held, Var)->name, new(binding_t, .type=Type(PointerType, .pointed=Match(held_type, MutexedType)->type, .is_stack=true)));
+ }
+ return get_type(env, Match(ast, Holding)->body);
}
case BinaryOp: {
auto binop = Match(ast, BinaryOp);