hare

The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit 6507fa604db4cb304daaa6ba2f3ae86e3706557c
parent 157c3599983c93b5df5fb2355470ceaa0e47c7a0
Author: Drew DeVault <sir@cmpwn.com>
Date:   Tue, 23 Nov 2021 09:42:41 +0100

all: remove reflection

Signed-off-by: Drew DeVault <sir@cmpwn.com>

Diffstat:
Mcmd/haredoc/html.ha | 2--
Mhare/ast/decl.ha | 1-
Mhare/ast/expr.ha | 8+-------
Mhare/ast/type.ha | 2+-
Mhare/lex/token.ha | 2--
Mhare/module/scan.ha | 2+-
Mhare/parse/+test/expr.ha | 1-
Mhare/parse/decl.ha | 2--
Mhare/parse/expr.ha | 12+-----------
Mhare/parse/type.ha | 2--
Mhare/types/hash.ha | 169+------------------------------------------------------------------------------
Mhare/types/store.ha | 4----
Mhare/types/types.ha | 2+-
Mhare/unparse/decl.ha | 2--
Mhare/unparse/expr.ha | 5-----
Mhare/unparse/type.ha | 2--
Drt/types.ha | 148-------------------------------------------------------------------------------
Drt/types_arch+aarch64.ha | 33---------------------------------
Drt/types_arch+riscv64.ha | 33---------------------------------
Drt/types_arch+x86_64.ha | 33---------------------------------
Mscripts/gen-stdlib | 20++------------------
Mslice/trunc.ha | 2+-
Mslice/void.ha | 2+-
Mstdlib.mk | 15+--------------
Mstrings/dup.ha | 2+-
Dtypes/+test.ha | 38--------------------------------------
Mtypes/README | 19+++++--------------
Mtypes/classes.ha | 2+-
Dtypes/reflect.ha | 120-------------------------------------------------------------------------------
Dtypes/util.ha | 122-------------------------------------------------------------------------------
30 files changed, 19 insertions(+), 788 deletions(-)

diff --git a/cmd/haredoc/html.ha b/cmd/haredoc/html.ha @@ -466,8 +466,6 @@ fn builtin_type(b: ast::builtin_type) str = { return "uintptr"; case ast::builtin_type::VOID => return "void"; - case ast::builtin_type::TYPE => - return "type"; }; }; diff --git a/hare/ast/decl.ha b/hare/ast/decl.ha @@ -15,7 +15,6 @@ export type decl_const = struct { // const foo: int = 0; export type decl_global = struct { is_const: bool, - is_hidden: bool, symbol: str, ident: ident, _type: _type, diff --git a/hare/ast/expr.ha b/hare/ast/expr.ha @@ -336,9 +336,6 @@ export type switch_expr = struct { cases: []switch_case, }; -// A type expression -export type type_expr = *_type; - // A unary operator export type unarithm_op = enum { // TODO: Should this be rehomed with the checked AST? @@ -376,8 +373,7 @@ export type expr = struct { defer_expr | delete_expr | for_expr | free_expr | if_expr | insert_expr | compound_expr | match_expr | len_expr | size_expr | offset_expr | propagate_expr | return_expr | - slice_expr | switch_expr | type_expr | unarithm_expr | - yield_expr), + slice_expr | switch_expr | unarithm_expr | yield_expr), }; // Frees resources associated with a Hare [[expr]]ession. @@ -542,8 +538,6 @@ case e: expr => free(exprs); }; free(s.cases); - case t: type_expr => - type_free(t); case u: unarithm_expr => expr_free(u.operand); case y: yield_expr => diff --git a/hare/ast/type.ha b/hare/ast/type.ha @@ -9,7 +9,7 @@ export type alias_type = struct { // A built-in primitive type (int, bool, str, etc). export type builtin_type = enum { BOOL, CHAR, F32, F64, FCONST, I16, I32, I64, I8, ICONST, INT, NULL, - RUNE, SIZE, STR, TYPE, U16, U32, U64, U8, UINT, UINTPTR, VOID, + RUNE, SIZE, STR, U16, U32, U64, U8, UINT, UINTPTR, VOID, }; // An enumeration field (and optional value). diff --git a/hare/lex/token.ha b/hare/lex/token.ha @@ -6,7 +6,6 @@ export type ltok = enum uint { // Keep ordered with bmap // Alpha sorted ATTR_FINI, - ATTR_HIDDEN, ATTR_INIT, ATTR_NORETURN, ATTR_OFFSET, @@ -153,7 +152,6 @@ export type ltok = enum uint { const bmap: [_]str = [ // Keep ordered with tok "@fini", - "@hidden", "@init", "@noreturn", "@offset", diff --git a/hare/module/scan.ha b/hare/module/scan.ha @@ -14,7 +14,7 @@ use sort; use strings; use strio; -def ABI_VERSION: u8 = 1; +def ABI_VERSION: u8 = 2; // Scans the files in a directory for eligible build inputs and returns a // [[version]] which includes all applicable files and their dependencies. diff --git a/hare/parse/+test/expr.ha b/hare/parse/+test/expr.ha @@ -65,7 +65,6 @@ len([1, 2, 3, 4]); offset(foo.bar); size(u32); - type(u32); }; "); }; diff --git a/hare/parse/decl.ha b/hare/parse/decl.ha @@ -64,7 +64,6 @@ fn decl_global( case lex::token => yield attr_symbol(lexer)?; }; - const hidden = try(lexer, ltok::ATTR_HIDDEN)? is lex::token; const ident = ident(lexer)?; want(lexer, ltok::COLON)?; const _type = _type(lexer)?; @@ -78,7 +77,6 @@ fn decl_global( const btok = try(lexer, ltok::COMMA)?; append(decl, ast::decl_global { is_const = tok == ltok::CONST, - is_hidden = hidden, symbol = symbol, ident = ident, _type = _type, diff --git a/hare/parse/expr.ha b/hare/parse/expr.ha @@ -340,7 +340,7 @@ fn builtin(lexer: *lex::lexer) (ast::expr | error) = { const tok = match (peek(lexer, ltok::ALLOC, ltok::APPEND, ltok::FREE, ltok::DELETE, ltok::ABORT, ltok::ASSERT, ltok::INSERT, ltok::STATIC, ltok::SIZE, ltok::LEN, ltok::OFFSET, - ltok::DEFER, ltok::TYPE)?) { + ltok::DEFER)?) { case tok: lex::token => yield tok; case void => @@ -381,16 +381,6 @@ fn builtin(lexer: *lex::lexer) (ast::expr | error) = { }; case ltok::SIZE, ltok::LEN, ltok::OFFSET => return measurement(lexer); - case ltok::TYPE => - want(lexer, ltok::TYPE)?; - want(lexer, ltok::LPAREN)?; - let expr = ast::expr { - start = tok.2, - end = lex::prevloc(lexer), - expr = alloc(_type(lexer)?): ast::type_expr, - }; - want(lexer, ltok::RPAREN)?; - return expr; case ltok::DEFER => want(lexer, ltok::DEFER)?; let expr = alloc(expression(lexer)?); diff --git a/hare/parse/type.ha b/hare/parse/type.ha @@ -116,8 +116,6 @@ fn primitive_type(lexer: *lex::lexer) (ast::_type | error) = { yield builtin_type::F64; case ltok::BOOL => yield builtin_type::BOOL; - case ltok::TYPE => - yield builtin_type::TYPE; case ltok::VOID => yield builtin_type::VOID; case => diff --git a/hare/types/hash.ha b/hare/types/hash.ha @@ -7,8 +7,8 @@ use fmt; // Keep ordered with respect to bootstrap harec:include/types.h type storage = enum u8 { BOOL, CHAR, F32, F64, I16, I32, I64, I8, INT, NULL, RUNE, SIZE, STRING, - U16, U32, U64, U8, UINT, UINTPTR, VOID, TYPE, ALIAS, ARRAY, ENUM, - FUNCTION, POINTER, SLICE, STRUCT, TAGGED, TUPLE, UNION, + U16, U32, U64, U8, UINT, UINTPTR, VOID, ALIAS, ARRAY, ENUM, FUNCTION, + POINTER, SLICE, STRUCT, TAGGED, TUPLE, UNION, }; fn builtin_storage(b: builtin) u8 = { @@ -39,8 +39,6 @@ fn builtin_storage(b: builtin) u8 = { return storage::SIZE; case builtin::STR => return storage::STRING; - case builtin::TYPE => - return storage::TYPE; case builtin::U16 => return storage::U16; case builtin::U32 => @@ -162,166 +160,3 @@ export fn hash(t: *_type) u32 = { return fnv::sum32(&id); }; - -@test fn hash() void = { - // Test a few samples for ABI compatibility with harec - let sample = _type { - flags = flags::NONE, - repr = builtin::STR, - ... - }; - assert(hash(&sample) == 2843771249); - - let sample = _type { - flags = flags::NONE, - repr = alias { - id = ["foo", "bar"], - ... - }, - ... - }; - assert(hash(&sample) == 385303307); - - let sample = _type { - flags = flags::ERROR, - repr = alias { - id = ["foo", "bar"], - ... - }, - ... - }; - assert(hash(&sample) == 4117101293); - - let _int = _type { - flags = flags::NONE, - repr = builtin::INT, - ... - }; - assert(hash(&_int) == 1099590421); - - let sample = _type { - flags = flags::NONE, - repr = pointer { - referent = &_int, - flags = pointer_flags::NONE, - }, - ... - }; - assert(hash(&sample) == 2081672869); - - let sample = _type { - flags = flags::NONE, - repr = pointer { - referent = &_int, - flags = pointer_flags::NULLABLE, - }, - ... - }; - assert(hash(&sample) == 841481858); - - let sample = _type { - flags = flags::NONE, - repr = _struct { - kind = struct_union::STRUCT, - fields = [ - struct_field { - name = "bar", - offs = 4, - _type = &_int, - }, - struct_field { - name = "foo", - offs = 0, - _type = &_int, - }, - ], - }, - ... - }; - assert(hash(&sample) == 2453524063); - - let sample = _type { - flags = flags::NONE, - repr = [ - tuple_value { - offs = 0, - _type = &_int, - }, - tuple_value { - offs = 4, - _type = &_int, - }, - tuple_value { - offs = 8, - _type = &_int, - }, - ], - ... - }; - assert(hash(&sample) == 2230759349); - - let sample = _type { - flags = flags::NONE, - repr = array { - length = 5, - member = &_int, - }, - ... - }; - assert(hash(&sample) == 3903522747); - - let _uint = _type { - flags = flags::NONE, - repr = builtin::UINT, - ... - }; - let _void = _type { - flags = flags::NONE, - repr = builtin::VOID, - ... - }; - - let sample = _type { - flags = flags::NONE, - repr = [ - &_int, - &_uint, - &_void, - ]: tagged, - ... - }; - assert(hash(&sample) == 2847927164); - - let sample = _type { - flags = flags::NONE, - repr = _enum { - storage = builtin::INT, - values = [ - ("FOO", 0), - ("BAR", 42), - ("BAZ", 69), - ], - }, - ... - }; - assert(hash(&sample) == 94471087); - - let sample = _type { - flags = flags::NONE, - repr = func { - result = &_void, - variadism = variadism::C, - flags = func_flags::NORETURN, - params = [&_uint, &_int], - }, - ... - }; - assert(hash(&sample) == 1223530078); - - let sample = _type { - flags = flags::NONE, - repr = &_void: slice, - ... - }; - assert(hash(&sample) == 263911532); -}; diff --git a/hare/types/store.ha b/hare/types/store.ha @@ -173,10 +173,6 @@ fn fromast(store: *typestore, atype: *ast::_type) (_type | deferred | error) = { else store.arch._pointer; yield builtin::STR; - case ast::builtin_type::TYPE => - sz = store.arch._pointer; - align = store.arch._pointer; - yield builtin::TYPE; case ast::builtin_type::U16 => sz = 2; align = 2; yield builtin::U16; diff --git a/hare/types/types.ha b/hare/types/types.ha @@ -18,7 +18,7 @@ export type array = struct { export type builtin = enum u8 { // Keep me consistent with ast::builtin BOOL, CHAR, F32, F64, I16, I32, I64, I8, INT, NULL, RUNE, SIZE, STR, - TYPE, U16, U32, U64, U8, UINT, UINTPTR, VOID, + U16, U32, U64, U8, UINT, UINTPTR, VOID, }; // An enum type, e.g. enum { FOO = 0 } diff --git a/hare/unparse/decl.ha b/hare/unparse/decl.ha @@ -141,7 +141,6 @@ fn decl_test(d: ast::decl, expected: str) bool = { decl = [ ast::decl_global { is_const = false, - is_hidden = false, symbol = "", ident = ["foo", "bar"], _type = type_int, @@ -149,7 +148,6 @@ fn decl_test(d: ast::decl, expected: str) bool = { }, ast::decl_global { is_const = false, - is_hidden = false, symbol = "foobar", ident = ["baz"], _type = type_int, diff --git a/hare/unparse/expr.ha b/hare/unparse/expr.ha @@ -355,11 +355,6 @@ export fn expr( return z; case e: ast::switch_expr => return switch_expr(out, indent, e)?; - case t: ast::type_expr => - let z = fmt::fprint(out, "type(")?; - z += _type(out, indent, *t)?; - z += fmt::fprint(out, ")")?; - return z; case e: ast::unarithm_expr => let z = fmt::fprintf(out, "{}", switch (e.op) { case ast::unarithm_op::ADDR => diff --git a/hare/unparse/type.ha b/hare/unparse/type.ha @@ -34,8 +34,6 @@ case ast::builtin_type::SIZE => yield "size"; case ast::builtin_type::STR => yield "str"; -case ast::builtin_type::TYPE => - yield "type"; case ast::builtin_type::U16 => yield "u16"; case ast::builtin_type::U32 => diff --git a/rt/types.ha b/rt/types.ha @@ -1,148 +0,0 @@ -// This defines a subset of types/reflect.ha so we can declare static typeinfo -// structures for builtins. -type types::typeinfo = struct { - id: uint, - sz: size, - al: size, - flags: types::flags, - repr: types::repr, -}; - -type types::flags = enum uint { - NONE = 0, - CONST = 1 << 0, - ERROR = 1 << 1, -}; - -type types::repr = (types::alias | types::array | types::builtin - | types::enum_ | types::func | types::pointer | types::slice_repr - | types::struct_union | types::tagged | types::tuple); - -type types::alias = struct { - ident: []str, - secondary: type, -}; - -type types::array = struct { - length: size, - members: type, -}; - -type types::builtin = enum uint { - BOOL, CHAR, F32, F64, I16, I32, I64, I8, INT, NULL, RUNE, SIZE, STR, - U16, U32, U64, U8, UINT, UINTPTR, VOID, TYPE, -}; - -type types::enum_ = struct { - storage: types::builtin, - values: [](str, u64), -}; - -type types::variadism = enum { - NONE, - C, - HARE, -}; - -type types::func_flags = enum uint { - NONE = 0, - NORETURN = 1 << 0, -}; - -type types::func = struct { - result: type, - variadism: types::variadism, - flags: types::func_flags, - params: []type, -}; - -type types::pointer_flags = enum uint { - NONE = 0, - NULLABLE = 1 << 0, -}; - -type types::pointer = struct { - referent: type, - flags: types::pointer_flags, -}; - -type types::slice_repr = type; - -type types::struct_kind = enum { - STRUCT, - UNION, -}; - -type types::struct_union = struct { - kind: types::struct_kind, - fields: []types::struct_field, -}; - -type types::struct_field = struct { - name: str, - offs: size, - type_: type, -}; - -type types::tagged = []type; - -type types::tuple = []types::tuple_value; - -type types::tuple_value = struct { - offs: size, - type_: type, -}; - -export const @hidden builtin_char: types::typeinfo = types::typeinfo { - id = 3950255460, - sz = 1, al = 1, flags = 0, - repr = types::builtin::CHAR, -}, @hidden builtin_f32: types::typeinfo = types::typeinfo { - id = 1568378015, - sz = 4, al = 4, flags = 0, - repr = types::builtin::F32, -}, @hidden builtin_f64: types::typeinfo = types::typeinfo { - id = 930681398, - sz = 8, al = 8, flags = 0, - repr = types::builtin::F64, -}, @hidden builtin_i8: types::typeinfo = types::typeinfo { - id = 2674862226, - sz = 1, al = 1, flags = 0, - repr = types::builtin::I8, -}, @hidden builtin_i16: types::typeinfo = types::typeinfo { - id = 2037165609, - sz = 2, al = 2, flags = 0, - repr = types::builtin::I16, -}, @hidden builtin_i32: types::typeinfo = types::typeinfo { - id = 1399468992, - sz = 4, al = 4, flags = 0, - repr = types::builtin::I32, -}, @hidden builtin_i64: types::typeinfo = types::typeinfo { - id = 3312558843, - sz = 8, al = 8, flags = 0, - repr = types::builtin::I64, -}, @hidden builtin_rune: types::typeinfo = types::typeinfo { - id = 2374983655, - sz = 4, al = 4, flags = 0, - repr = types::builtin::RUNE, -}, @hidden builtin_u8: types::typeinfo = types::typeinfo { - id = 1906196061, - sz = 1, al = 1, flags = 0, - repr = types::builtin::U8, -}, @hidden builtin_u16: types::typeinfo = types::typeinfo { - id = 2206074632, - sz = 2, al = 2, flags = 0, - repr = types::builtin::U16, -}, @hidden builtin_u32: types::typeinfo = types::typeinfo { - id = 4119164483, - sz = 4, al = 4, flags = 0, - repr = types::builtin::U32, -}, @hidden builtin_u64: types::typeinfo = types::typeinfo { - id = 3481467866, - sz = 8, al = 8, flags = 0, - repr = types::builtin::U64, -}, @hidden builtin_void: types::typeinfo = types::typeinfo { - id = 2543892678, - sz = 0, al = 0, flags = 0, - repr = types::builtin::VOID, -}; diff --git a/rt/types_arch+aarch64.ha b/rt/types_arch+aarch64.ha @@ -1,33 +0,0 @@ -export const @hidden builtin_int: types::typeinfo = types::typeinfo { - id = 1099590421, - sz = 4, al = 4, flags = 0, - repr = types::builtin::INT, -}, @hidden builtin_uint: types::typeinfo = types::typeinfo { - id = 1268499444, - sz = 4, al = 4, flags = 0, - repr = types::builtin::UINT, -}, @hidden builtin_bool: types::typeinfo = types::typeinfo { - id = 292984781, - sz = 4, al = 4, flags = 0, - repr = types::builtin::BOOL, -}, @hidden builtin_size: types::typeinfo = types::typeinfo { - id = 1737287038, - sz = 8, al = 8, flags = 0, - repr = types::builtin::SIZE, -}, @hidden builtin_uintptr: types::typeinfo = types::typeinfo { - id = 3181589295, - sz = 8, al = 8, flags = 0, - repr = types::builtin::UINTPTR, -}, @hidden builtin_str: types::typeinfo = types::typeinfo { - id = 2843771249, - sz = 24, al = 8, flags = 0, - repr = types::builtin::STR, -}, @hidden builtin_null: types::typeinfo = types::typeinfo { - id = 461893804, - sz = 8, al = 8, flags = 0, - repr = types::builtin::NULL, -}, @hidden builtin_type: types::typeinfo = types::typeinfo { - id = 3650376889, - sz = 8, al = 8, flags = 0, - repr = types::builtin::TYPE, -}; diff --git a/rt/types_arch+riscv64.ha b/rt/types_arch+riscv64.ha @@ -1,33 +0,0 @@ -export const @hidden builtin_int: types::typeinfo = types::typeinfo { - id = 1099590421, - sz = 4, al = 4, flags = 0, - repr = types::builtin::INT, -}, @hidden builtin_uint: types::typeinfo = types::typeinfo { - id = 1268499444, - sz = 4, al = 4, flags = 0, - repr = types::builtin::UINT, -}, @hidden builtin_bool: types::typeinfo = types::typeinfo { - id = 292984781, - sz = 4, al = 4, flags = 0, - repr = types::builtin::BOOL, -}, @hidden builtin_size: types::typeinfo = types::typeinfo { - id = 1737287038, - sz = 8, al = 8, flags = 0, - repr = types::builtin::SIZE, -}, @hidden builtin_uintptr: types::typeinfo = types::typeinfo { - id = 3181589295, - sz = 8, al = 8, flags = 0, - repr = types::builtin::UINTPTR, -}, @hidden builtin_str: types::typeinfo = types::typeinfo { - id = 2843771249, - sz = 24, al = 8, flags = 0, - repr = types::builtin::STR, -}, @hidden builtin_null: types::typeinfo = types::typeinfo { - id = 461893804, - sz = 8, al = 8, flags = 0, - repr = types::builtin::NULL, -}, @hidden builtin_type: types::typeinfo = types::typeinfo { - id = 3650376889, - sz = 8, al = 8, flags = 0, - repr = types::builtin::TYPE, -}; diff --git a/rt/types_arch+x86_64.ha b/rt/types_arch+x86_64.ha @@ -1,33 +0,0 @@ -export const @hidden builtin_int: types::typeinfo = types::typeinfo { - id = 1099590421, - sz = 4, al = 4, flags = 0, - repr = types::builtin::INT, -}, @hidden builtin_uint: types::typeinfo = types::typeinfo { - id = 1268499444, - sz = 4, al = 4, flags = 0, - repr = types::builtin::UINT, -}, @hidden builtin_bool: types::typeinfo = types::typeinfo { - id = 292984781, - sz = 4, al = 4, flags = 0, - repr = types::builtin::BOOL, -}, @hidden builtin_size: types::typeinfo = types::typeinfo { - id = 1737287038, - sz = 8, al = 8, flags = 0, - repr = types::builtin::SIZE, -}, @hidden builtin_uintptr: types::typeinfo = types::typeinfo { - id = 3181589295, - sz = 8, al = 8, flags = 0, - repr = types::builtin::UINTPTR, -}, @hidden builtin_str: types::typeinfo = types::typeinfo { - id = 2843771249, - sz = 24, al = 8, flags = 0, - repr = types::builtin::STR, -}, @hidden builtin_null: types::typeinfo = types::typeinfo { - id = 461893804, - sz = 8, al = 8, flags = 0, - repr = types::builtin::NULL, -}, @hidden builtin_type: types::typeinfo = types::typeinfo { - id = 3650376889, - sz = 8, al = 8, flags = 0, - repr = types::builtin::TYPE, -}; diff --git a/scripts/gen-stdlib b/scripts/gen-stdlib @@ -34,7 +34,6 @@ gensrcs_rt() { +linux/socket.ha \ '+$(ARCH)'/jmp.ha \ '+$(ARCH)'/backtrace.ha \ - types_arch+'$(ARCH)'.ha \ ensure.ha \ jmp.ha \ malloc.ha \ @@ -42,7 +41,6 @@ gensrcs_rt() { memmove.ha \ memset.ha \ strcmp.ha \ - types.ha \ $* gen_srcs -pfreebsd rt \ +freebsd/abort.ha \ @@ -57,7 +55,6 @@ gensrcs_rt() { +freebsd/types.ha \ +'$(ARCH)'/jmp.ha \ +'$(ARCH)'/backtrace.ha \ - types_arch+'$(ARCH)'.ha \ ensure.ha \ jmp.ha \ malloc.ha \ @@ -65,7 +62,6 @@ gensrcs_rt() { memmove.ha \ memset.ha \ strcmp.ha \ - types.ha \ $* } @@ -1009,23 +1005,11 @@ time() { gen_ssa -pfreebsd time } -gensrcs_types() { +types() { gen_srcs types \ limits.ha \ classes.ha \ - reflect.ha \ - util.ha \ - 'arch+$(ARCH).ha' \ - $* -} - -types() { - if [ $testing -eq 0 ]; then - gensrcs_types - else - gensrcs_types \ - +test.ha - fi + 'arch+$(ARCH).ha' gen_ssa types } diff --git a/slice/trunc.ha b/slice/trunc.ha @@ -3,6 +3,6 @@ use types; // Truncates a slice, setting its length to zero without freeing the underlying // storage or altering its capacity. export fn trunc(sl: *[]void) void = { - let sl = sl: *types::slice_repr; + let sl = sl: *types::slice; sl.length = 0; }; diff --git a/slice/void.ha b/slice/void.ha @@ -6,7 +6,7 @@ export fn appendto(sl: *[]void, itemsz: size, items: const *void...) void = { if (len(items) == 0) { return; }; - let sl = sl: *types::slice_repr; + let sl = sl: *types::slice; let end = sl.length; sl.length += len(items); rt::ensure(sl, itemsz); diff --git a/stdlib.mk b/stdlib.mk @@ -18,7 +18,6 @@ stdlib_rt_linux_srcs= \ $(STDLIB)/rt/+linux/socket.ha \ $(STDLIB)/rt/+$(ARCH)/jmp.ha \ $(STDLIB)/rt/+$(ARCH)/backtrace.ha \ - $(STDLIB)/rt/types_arch+$(ARCH).ha \ $(STDLIB)/rt/ensure.ha \ $(STDLIB)/rt/jmp.ha \ $(STDLIB)/rt/malloc.ha \ @@ -26,7 +25,6 @@ stdlib_rt_linux_srcs= \ $(STDLIB)/rt/memmove.ha \ $(STDLIB)/rt/memset.ha \ $(STDLIB)/rt/strcmp.ha \ - $(STDLIB)/rt/types.ha \ $(STDLIB)/rt/abort.ha \ $(STDLIB)/rt/start.ha @@ -44,7 +42,6 @@ stdlib_rt_freebsd_srcs= \ $(STDLIB)/rt/+freebsd/types.ha \ $(STDLIB)/rt/+$(ARCH)/jmp.ha \ $(STDLIB)/rt/+$(ARCH)/backtrace.ha \ - $(STDLIB)/rt/types_arch+$(ARCH).ha \ $(STDLIB)/rt/ensure.ha \ $(STDLIB)/rt/jmp.ha \ $(STDLIB)/rt/malloc.ha \ @@ -52,7 +49,6 @@ stdlib_rt_freebsd_srcs= \ $(STDLIB)/rt/memmove.ha \ $(STDLIB)/rt/memset.ha \ $(STDLIB)/rt/strcmp.ha \ - $(STDLIB)/rt/types.ha \ $(STDLIB)/rt/abort.ha \ $(STDLIB)/rt/start.ha @@ -1585,8 +1581,6 @@ $(HARECACHE)/time/time-freebsd.ssa: $(stdlib_time_freebsd_srcs) $(stdlib_rt) stdlib_types_any_srcs= \ $(STDLIB)/types/limits.ha \ $(STDLIB)/types/classes.ha \ - $(STDLIB)/types/reflect.ha \ - $(STDLIB)/types/util.ha \ $(STDLIB)/types/arch+$(ARCH).ha $(HARECACHE)/types/types-any.ssa: $(stdlib_types_any_srcs) $(stdlib_rt) @@ -1729,7 +1723,6 @@ testlib_rt_linux_srcs= \ $(STDLIB)/rt/+linux/socket.ha \ $(STDLIB)/rt/+$(ARCH)/jmp.ha \ $(STDLIB)/rt/+$(ARCH)/backtrace.ha \ - $(STDLIB)/rt/types_arch+$(ARCH).ha \ $(STDLIB)/rt/ensure.ha \ $(STDLIB)/rt/jmp.ha \ $(STDLIB)/rt/malloc.ha \ @@ -1737,7 +1730,6 @@ testlib_rt_linux_srcs= \ $(STDLIB)/rt/memmove.ha \ $(STDLIB)/rt/memset.ha \ $(STDLIB)/rt/strcmp.ha \ - $(STDLIB)/rt/types.ha \ $(STDLIB)/rt/start+test.ha \ $(STDLIB)/rt/abort+test.ha \ $(STDLIB)/rt/+test/+$(PLATFORM).ha \ @@ -1759,7 +1751,6 @@ testlib_rt_freebsd_srcs= \ $(STDLIB)/rt/+freebsd/types.ha \ $(STDLIB)/rt/+$(ARCH)/jmp.ha \ $(STDLIB)/rt/+$(ARCH)/backtrace.ha \ - $(STDLIB)/rt/types_arch+$(ARCH).ha \ $(STDLIB)/rt/ensure.ha \ $(STDLIB)/rt/jmp.ha \ $(STDLIB)/rt/malloc.ha \ @@ -1767,7 +1758,6 @@ testlib_rt_freebsd_srcs= \ $(STDLIB)/rt/memmove.ha \ $(STDLIB)/rt/memset.ha \ $(STDLIB)/rt/strcmp.ha \ - $(STDLIB)/rt/types.ha \ $(STDLIB)/rt/start+test.ha \ $(STDLIB)/rt/abort+test.ha \ $(STDLIB)/rt/+test/+$(PLATFORM).ha \ @@ -3342,10 +3332,7 @@ $(TESTCACHE)/time/time-freebsd.ssa: $(testlib_time_freebsd_srcs) $(testlib_rt) testlib_types_any_srcs= \ $(STDLIB)/types/limits.ha \ $(STDLIB)/types/classes.ha \ - $(STDLIB)/types/reflect.ha \ - $(STDLIB)/types/util.ha \ - $(STDLIB)/types/arch+$(ARCH).ha \ - $(STDLIB)/types/+test.ha + $(STDLIB)/types/arch+$(ARCH).ha $(TESTCACHE)/types/types-any.ssa: $(testlib_types_any_srcs) $(testlib_rt) @printf 'HAREC \t$@\n' diff --git a/strings/dup.ha b/strings/dup.ha @@ -29,7 +29,7 @@ export fn dup(s: const str) str = { // Creates a copy of a []str slice with all the strings duplicated. The result // must be freed using [[freeall]]. export fn dupall(s: []str) []str = { - let newsl = *(&types::slice_repr { + let newsl = *(&types::slice { data = match (rt::malloc(len(s) * size(str))) { case null => abort("Out of memory"); diff --git a/types/+test.ha b/types/+test.ha @@ -1,38 +0,0 @@ -type language = enum { - C, - HARE, - PYTHON, - MYRDDIN, -}; - -@test fn strenum() void = { - assert(strenum(type(language), &language::C) == "C"); - assert(strenum(type(language), &language::HARE) == "HARE"); - assert(strenum(type(language), &language::PYTHON) == "PYTHON"); - assert(strenum(type(language), &language::MYRDDIN) == "MYRDDIN"); -}; - -type perm = enum u8 { - NONE = 0, - READ = 1 << 0, - WRITE = 1 << 1, - EXECUTE = 1 << 2, -}; - -@test fn strflag() void = { - const res = strflag(type(perm), &perm::READ); - defer free(res); - assert(res == "READ"); - - const res = strflag(type(perm), &(perm::READ | perm::WRITE)); - defer free(res); - assert(res == "READ|WRITE"); - - const res = strflag(type(perm), &(perm::WRITE | perm::EXECUTE)); - defer free(res); - assert(res == "WRITE|EXECUTE"); - - const res = strflag(type(perm), &perm::NONE); - defer free(res); - assert(res == "NONE"); -}; diff --git a/types/README b/types/README @@ -1,14 +1,5 @@ -The types module provides runtime access to the Hare type system. It provides -constants like [[INT_MAX]], which defines the useful range for integer types -(see [[math]] for f32 and f64 limits), as well as types like [[slice_repr]], -which describe the internal structure of data types like slices and str. - -The types module additionally provides support for reflection. A typical program -which needs to make use of reflection will pass a type value to [[reflect]], -like so: - - let info = types::reflect(type(str)); - assert(info.repr is types::builtin::STR); - -Additional helpers like [[unwrap]] are provided to further assist with -reflection-related tasks. +The types module provides access to some information about the Hare type system. +It provides constants like [[INT_MAX]], which defines the useful range for +integer types (see [[math]] for f32 and f64 limits), as well as types like +[[slice]], which describe the internal structure of data types like slices and +str. diff --git a/types/classes.ha b/types/classes.ha @@ -30,7 +30,7 @@ export type string = struct { // A type representing the internal structure of slices, useful for low-level // slice manipulation. -export type slice_repr = struct { +export type slice = struct { // The slice contents. data: nullable *void, diff --git a/types/reflect.ha b/types/reflect.ha @@ -1,120 +0,0 @@ -// The sz field of [[typeinfo]] is set to this value to indicate that the size -// of the type is undefined. -export def SIZE_UNDEFINED: size = -1: size; - -// Structure detailing information about a specific type. -export type typeinfo = struct { - id: uint, - sz: size, - al: size, - flags: flags, - repr: repr, -}; - -// Returns [[typeinfo]] for the provided type. -export fn reflect(in: type) const *typeinfo = in: *typeinfo; - -// Type flags. -export type flags = enum uint { - NONE = 0, - CONST = 1 << 0, - ERROR = 1 << 1, -}; - -// Details of the type representation. -export type repr = (alias | array | builtin - | enumerated | func | pointer | slice - | struct_union | tagged | tuple); - -// A type alias. -export type alias = struct { - ident: []str, - secondary: type, -}; - -// An array type. -export type array = struct { - length: size, - members: type, -}; - -// A built-in type. -export type builtin = enum uint { - BOOL, CHAR, F32, F64, I16, I32, I64, I8, INT, NULL, RUNE, SIZE, STR, - U16, U32, U64, U8, UINT, UINTPTR, VOID, TYPE, -}; - -// An enum type. -export type enumerated = struct { - storage: builtin, - values: [](str, union { u: u64, i: i64 }), -}; - -// Indicates the variadism of a [[func]]. -export type variadism = enum { - NONE, - C, - HARE, -}; - -// Indicats if a [[func]] has the @noreturn attribute. -export type func_flags = enum uint { - NONE = 0, - NORETURN = 1 << 0, -}; - -// A function type, e.g. fn(x: int, y: int) int. -export type func = struct { - result: type, - variadism: variadism, - flags: func_flags, - params: []type, -}; - -// Flags which apply to a pointer type. -export type pointer_flags = enum uint { - NONE = 0, - NULLABLE = 1 << 0, -}; - -// *int -export type pointer = struct { - secondary: type, - flags: pointer_flags, -}; - -// Type information for slice members. Distinct from [[slice_repr]], which is -// the representation of a slice object at runtime. -export type slice = type; - -// Indicates if a [[_struct]] was declared as a struct or union type. -export type struct_kind = enum { - STRUCT, - UNION, -}; - -// struct { ... } or union { ... } -export type struct_union = struct { - kind: struct_kind, - fields: []struct_field, -}; - -// A single struct field. -export type struct_field = struct { - // "" for an anonymous field - name: str, - offs: size, - type_: type, -}; - -// A tagged union type, e.g. (int | uint | void). -export type tagged = []type; - -// A tuple type, e.g. (a, b, c) -export type tuple = []tuple_value; - -// A single value of a tuple type. -export type tuple_value = struct { - offs: size, - type_: type, -}; diff --git a/types/util.ha b/types/util.ha @@ -1,122 +0,0 @@ -// Returns the value of the enum at "val" as a string. Aborts if the value is -// not present. Note that this does not work with enums being used as a flag -// type, see [[strflag]] instead. -export fn strenum(ty: type, val: *void) str = { - const ty = unwrap(ty); - const en = ty.repr as enumerated; - const value: u64 = switch (en.storage) { - case builtin::CHAR, builtin::I8, builtin::U8 => - yield *(val: *u8); - case builtin::I16, builtin::U16 => - yield *(val: *u16); - case builtin::I32, builtin::U32 => - yield *(val: *u32); - case builtin::I64, builtin::U64 => - yield *(val: *u64); - case builtin::INT, builtin::UINT => - yield switch (size(int)) { - case 4 => - yield *(val: *u32); - case 8 => - yield *(val: *u64); - case => abort(); - }; - case builtin::SIZE => - yield switch (size(size)) { - case 4 => - yield *(val: *u32); - case 8 => - yield *(val: *u64); - case => abort(); - }; - case => abort(); - }; - - for (let i = 0z; i < len(en.values); i += 1) { - if (en.values[i].1.u == value) { - return en.values[i].0; - }; - }; - - abort("enum has invalid value"); -}; - -// TODO: should we have a static version of that? - -// Returns the names of enabled flags of a bitfield enum at "val" formatted as -// '|' operation. The string must be freed by the caller. -export fn strflag(ty: type, val: *void) str = { - const ty = unwrap(ty); - const en = ty.repr as enumerated; - const value: u64 = switch (en.storage) { - case builtin::CHAR, builtin::I8, builtin::U8 => - yield *(val: *u8); - case builtin::I16, builtin::U16 => - yield *(val: *u16); - case builtin::I32, builtin::U32 => - yield *(val: *u32); - case builtin::I64, builtin::U64 => - yield *(val: *u64); - case builtin::INT, builtin::UINT => - yield switch (size(int)) { - case 4 => - yield *(val: *u32); - case 8 => - yield *(val: *u64); - case => abort(); - }; - case builtin::SIZE => - yield switch (size(size)) { - case 4 => - yield *(val: *u32); - case 8 => - yield *(val: *u64); - case => abort(); - }; - case => abort(); - }; - - let buf: []u8 = alloc([]); - let zeroname = ""; - - let pipe = false; - - for (let i = 0z; i < len(en.values); i += 1) { - const val = en.values[i]; - if (val.1.u == 0) { - zeroname = val.0; - continue; - }; - if (val.1.u & value != 0) { - if (pipe) { - append(buf, '|': u8); - }; - append(buf, *(&val.0: *[]u8)...); - pipe = true; - } else { - pipe = false; - }; - }; - - if (value == 0) { - append(buf, *(&zeroname: *[]u8)...); - }; - - if (len(buf) == 0) { - abort("Enum has invalid value"); - }; - - return *(&buf: *str); -}; - -// Returns [[typeinfo]] for the provided type, unwrapping any aliases along the -// way. -export fn unwrap(in: type) const *typeinfo = { - let info = reflect(in); - match (info.repr) { - case a: alias => - return unwrap(a.secondary); - case => - return info; - }; -};