summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-07-13 16:15:01 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2020-07-13 16:15:01 -0400
commita12739cd3f2ae5c78eca04cb3a1b30243db4f4fe (patch)
tree2c7660893237e942db84e5cbd04a4c7d762d8fdd
parent0c5d34b277e4e99b4cb4396d547620aaf6d044d7 (diff)
more type information
-rw-r--r--main.c3
-rw-r--r--std/types.toc31
-rw-r--r--test.toc90
-rw-r--r--types.c8
-rw-r--r--types.h54
5 files changed, 155 insertions, 31 deletions
diff --git a/main.c b/main.c
index fc8f345..4f49357 100644
--- a/main.c
+++ b/main.c
@@ -8,6 +8,7 @@
see development.md for development information
@TODO:
+#for
figure out how printf is gonna work
make a global table of builtin types, so if you ever need a pointer to one you can just point to the table
improve type_to_str:
@@ -21,6 +22,8 @@ unions
bitwise operations
---
#compile_only for functions only used at compile time
+if we do bar ::= nms { #include "foo.toc", foo; } ; #include "foo.toc", foo;
+ foo's functions should be defined as foo__etc, not bar__foo__etc
warn about x : u8 = 1283;
switch to / add as an alternative: libffi
- better yet, inline assembly
diff --git a/std/types.toc b/std/types.toc
new file mode 100644
index 0000000..973b1d8
--- /dev/null
+++ b/std/types.toc
@@ -0,0 +1,31 @@
+// @TODO: enum
+TypeKind ::= nms {
+ UNKNOWN ::= 0;
+ BUILTIN ::= 1;
+ FN ::= 2;
+ TUPLE ::= 3;
+ ARR ::= 4;
+ PTR ::= 5;
+ SLICE ::= 6;
+ EXPR ::= 7; // in theory, you should never get this kind of type (it's only used internally by the compiler)
+ STRUCT ::= 8;
+}
+
+BuiltinType ::= nms {
+ I8 ::= 0;
+ U8 ::= 1;
+ I16 ::= 2;
+ U16 ::= 3;
+ I32 ::= 4;
+ U32 ::= 5;
+ I64 ::= 6;
+ U64 ::= 7;
+ F32 ::= 8;
+ F64 ::= 9;
+ CHAR ::= 10;
+ BOOL ::= 11;
+ TYPE ::= 12;
+ VARARGS ::= 13;
+ NMS ::= 14;
+ VOID ::= 15;
+}
diff --git a/test.toc b/test.toc
index bf5ae21..597a41a 100644
--- a/test.toc
+++ b/test.toc
@@ -1,4 +1,76 @@
#include "std/io.toc", io;
+#include "std/types.toc";
+
+print_type ::= fn(t :: Type) {
+ k ::= t._kind;
+ use TypeKind;
+ #if k == UNKNOWN {
+ io.puts("???");
+ } elif k == BUILTIN {
+ b ::= t._builtin;
+ use BuiltinType;
+ #if b == I8 {
+ io.puts("i8");
+ } elif b == U8 {
+ io.puts("u8");
+ } elif b == I16 {
+ io.puts("i16");
+ } elif b == U16 {
+ io.puts("u16");
+ } elif b == I32 {
+ io.puts("i32");
+ } elif b == U32 {
+ io.puts("u32");
+ } elif b == I64 {
+ io.puts("i64");
+ } elif b == U64 {
+ io.puts("u64");
+ } elif b == F32 {
+ io.puts("f32");
+ } elif b == F64 {
+ io.puts("f64");
+ } elif b == CHAR {
+ io.puts("char");
+ } elif b == BOOL {
+ io.puts("bool");
+ } elif b == TYPE {
+ io.puts("Type");
+ } elif b == VARARGS {
+ io.puts("..");
+ } elif b == NMS {
+ io.puts("Namespace");
+ } elif b == VOID {
+ io.puts("void");
+ } else {
+ io.puts("<unknown builtin type>");
+ }
+ } elif k == FN {
+ // @TODO
+ } elif k == TUPLE {
+ // @TODO
+ } elif k == ARR {
+ io.writes("[");
+ io.writei(t._n);
+ io.writes("]");
+ print_type(t._of);
+ } elif k == PTR {
+ io.writes("&");
+ print_type(t._of);
+ } elif k == SLICE {
+ io.writes("[]");
+ print_type(t._of);
+ } elif k == EXPR {
+ io.puts("<type expression>");
+ } elif k == STRUCT {
+ // @TODO
+ } else {
+ io.puts("<unknown type kind>");
+ }
+}
+
+print_typeof ::= fn (t ::=, x : t) {
+ print_type(t);
+}
main ::= fn() {
foo0 := int == int;
@@ -11,12 +83,20 @@ main ::= fn() {
io.putb(bar1);
x ::= 4 as u64;
+ y := 7.3432;
+ z := "foo";
+ w := &z;
+ t : [x*x]int;
+ u := &t;
+ v : &void;
- t ::= typeof(x);
- if t._kind == 1 {
- io.writes("BUILTIN ");
- io.puti(t._builtin);
- }
+ print_typeof(x);
+ print_typeof(y);
+ print_typeof(z);
+ print_typeof(w);
+ print_typeof(t);
+ print_typeof(u);
+ print_typeof(v);
}
main();
diff --git a/types.c b/types.c
index 5bdc08e..83e3a66 100644
--- a/types.c
+++ b/types.c
@@ -2914,6 +2914,10 @@ static Status types_expr(Typer *tr, Expression *e) {
}
break;
} else if (str_eq_cstr(member, "_returns")) {
+ if (ltype->kind != TYPE_FN) {
+ err_print(e->where, "This type doesn't have a '_returns' member (only functions do).");
+ return false;
+ }
construct_resolved_builtin_type(t, BUILTIN_TYPE);
e->kind = EXPR_VAL;
Type *ret = e->val.type = &ltype->fn->types[0];
@@ -2923,6 +2927,10 @@ static Status types_expr(Typer *tr, Expression *e) {
}
break;
} else if (str_eq_cstr(member, "_is_template")) {
+ if (ltype->kind != TYPE_FN) {
+ err_print(e->where, "This type doesn't have a '_is_template' member (only functions do).");
+ return false;
+ }
construct_resolved_builtin_type(t, BUILTIN_BOOL);
e->kind = EXPR_VAL;
e->val.boolv = false;
diff --git a/types.h b/types.h
index 0015b89..6c5907c 100644
--- a/types.h
+++ b/types.h
@@ -393,36 +393,38 @@ typedef struct Tokenizer {
typedef enum {
- TYPE_UNKNOWN,
- TYPE_BUILTIN,
- TYPE_FN,
- TYPE_TUPLE,
- TYPE_ARR,
- TYPE_PTR,
- TYPE_SLICE,
- TYPE_EXPR, // just use this expression as the type. this kind of type doesn't exist after resolving.
- TYPE_STRUCT
-#define TYPE_COUNT (TYPE_STRUCT+1)
+ // if you change this enum, make sure you change std/types.toc (preferrably, add stuff to the end of the enum)
+ TYPE_UNKNOWN = 0,
+ TYPE_BUILTIN = 1,
+ TYPE_FN = 2,
+ TYPE_TUPLE = 3,
+ TYPE_ARR = 4,
+ TYPE_PTR = 5,
+ TYPE_SLICE = 6,
+ TYPE_EXPR = 7, // just use this expression as the type. this kind of type doesn't exist after resolving.
+ TYPE_STRUCT = 8
+#define TYPE_COUNT 9
} TypeKind;
typedef enum {
- BUILTIN_I8,
- BUILTIN_U8,
- BUILTIN_I16,
- BUILTIN_U16,
- BUILTIN_I32,
- BUILTIN_U32,
- BUILTIN_I64,
- BUILTIN_U64,
- BUILTIN_F32,
- BUILTIN_F64,
- BUILTIN_CHAR,
- BUILTIN_BOOL,
- BUILTIN_TYPE,
- BUILTIN_VARARGS,
- BUILTIN_NMS,
- BUILTIN_VOID
+ // if you change this enum, make sure you change std/types.toc (preferrably, add stuff to the end of the enum)
+ BUILTIN_I8 = 0,
+ BUILTIN_U8 = 1,
+ BUILTIN_I16 = 2,
+ BUILTIN_U16 = 3,
+ BUILTIN_I32 = 4,
+ BUILTIN_U32 = 5,
+ BUILTIN_I64 = 6,
+ BUILTIN_U64 = 7,
+ BUILTIN_F32 = 8,
+ BUILTIN_F64 = 9,
+ BUILTIN_CHAR = 10,
+ BUILTIN_BOOL = 11,
+ BUILTIN_TYPE = 12,
+ BUILTIN_VARARGS = 13,
+ BUILTIN_NMS = 14,
+ BUILTIN_VOID = 15
} BuiltinType;