summaryrefslogtreecommitdiff
path: root/types.c
diff options
context:
space:
mode:
Diffstat (limited to 'types.c')
-rw-r--r--types.c79
1 files changed, 59 insertions, 20 deletions
diff --git a/types.c b/types.c
index 887c39b..22f8648 100644
--- a/types.c
+++ b/types.c
@@ -168,6 +168,7 @@ static bool expr_must_lval(Expression *e) {
case EXPR_EACH:
case EXPR_CALL:
case EXPR_C:
+ case EXPR_BUILTIN:
case EXPR_BLOCK:
case EXPR_SLICE:
case EXPR_TYPE:
@@ -925,6 +926,47 @@ static bool call_arg_param_order(Allocator *allocr, FnExpr *fn, Type *fn_type, A
return true;
}
+static void get_builtin_val(BuiltinVal val, Value *v) {
+ switch (val) {
+ case BUILTIN_STDOUT:
+ v->ptr = stdout;
+ break;
+ }
+}
+
+static void get_builtin_val_type(Allocator *a, BuiltinVal val, Type *t) {
+ t->flags = TYPE_IS_RESOLVED;
+ switch (val) {
+ case BUILTIN_STDOUT:
+ t->kind = TYPE_PTR;
+ t->ptr = allocr_calloc(a, 1, sizeof *t->ptr);
+ t->ptr->flags = TYPE_IS_RESOLVED;
+ t->ptr->kind = TYPE_BUILTIN;
+ t->ptr->builtin = BUILTIN_U8;
+ break;
+ }
+}
+
+/* returns NULL if an error occured */
+static char *eval_expr_as_cstr(Typer *tr, Expression *e, const char *what_is_this) {
+ Value e_val;
+ if (!types_expr(tr, e))
+ return NULL;
+ if (!type_is_slicechar(&e->type)) {
+ char *got = type_to_str(&e->type);
+ err_print(e->where, "Expected []char for %s, but got %s.", what_is_this, got);
+ free(got);
+ return NULL;
+ }
+ if (!eval_expr(tr->evalr, e, &e_val))
+ return NULL;
+ Slice e_slice = e_val.slice;
+ char *str = typer_malloc(tr, (size_t)e_slice.n + 1);
+ str[e_slice.n] = 0;
+ memcpy(str, e_slice.data, (size_t)e_slice.n);
+ return str;
+}
+
static bool types_expr(Typer *tr, Expression *e) {
if (e->flags & EXPR_FOUND_TYPE) return true;
Type *t = &e->type;
@@ -1645,6 +1687,23 @@ static bool types_expr(Typer *tr, Expression *e) {
code->kind = EXPR_VAL;
t->kind = TYPE_UNKNOWN;
} break;
+ case EXPR_BUILTIN: {
+ char *builtin_name = eval_expr_as_cstr(tr, e->builtin.which.expr, "#builtin value name");
+ if (!builtin_name) return false;
+ int which = -1;
+ for (BuiltinVal b = 0; b < BUILTIN_VAL_COUNT; b = b + 1) {
+ if (strs_equal(builtin_val_names[b], builtin_name)) {
+ which = b;
+ }
+ }
+ if (which == -1) {
+ err_print(e->where, "Unrecognized builtin value: %s.", builtin_name);
+ return false;
+ }
+ e->builtin.which.val = (BuiltinVal)which;
+ get_builtin_val_type(tr->allocr, e->builtin.which.val, t);
+ assert(t->flags & TYPE_IS_RESOLVED);
+ } break;
case EXPR_UNARY_OP: {
Expression *of = e->unary.of;
Type *of_type = &of->type;
@@ -2136,26 +2195,6 @@ static bool types_block(Typer *tr, Block *b) {
return success;
}
-/* returns NULL if an error occured */
-static char *eval_expr_as_cstr(Typer *tr, Expression *e, const char *what_is_this) {
- Value e_val;
- if (!types_expr(tr, e))
- return NULL;
- if (!type_is_slicechar(&e->type)) {
- char *got = type_to_str(&e->type);
- err_print(e->where, "Expected []char for %s, but got %s.", what_is_this, got);
- free(got);
- return NULL;
- }
- if (!eval_expr(tr->evalr, e, &e_val))
- return NULL;
- Slice e_slice = e_val.slice;
- char *str = typer_malloc(tr, (size_t)e_slice.n + 1);
- str[e_slice.n] = 0;
- memcpy(str, e_slice.data, (size_t)e_slice.n);
- return str;
-}
-
static bool types_decl(Typer *tr, Declaration *d) {
bool success = true;
if (d->flags & DECL_FOUND_TYPE) return true;