hare

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

commit d8b3d3bce9cb5bb5f1aacfd13e0e9a0757e979a5
parent 08b027326d8bcf627b315d73c6ecc7810305773d
Author: Pierre Curto <pierre.curto@gmail.com>
Date:   Mon,  5 Dec 2022 20:05:25 +0100

hare/lex: handle threadlocal attribute on global declarations

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>

Diffstat:
Mhare/ast/decl.ha | 1+
Mhare/lex/token.ha | 2++
Mhare/parse/decl.ha | 14++++++++++----
Mhare/unparse/decl.ha | 14+++++++++++++-
4 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/hare/ast/decl.ha b/hare/ast/decl.ha @@ -18,6 +18,7 @@ export type decl_const = struct { // const foo: int = 0; export type decl_global = struct { is_const: bool, + is_threadlocal: bool, symbol: str, ident: ident, _type: _type, diff --git a/hare/lex/token.ha b/hare/lex/token.ha @@ -16,6 +16,7 @@ export type ltok = enum uint { ATTR_OFFSET, ATTR_SYMBOL, ATTR_TEST, + ATTR_THREADLOCAL, UNDERSCORE, ABORT, ALLOC, @@ -164,6 +165,7 @@ const bmap: [_]str = [ "@offset", "@symbol", "@test", + "@threadlocal", "_", "abort", "alloc", diff --git a/hare/parse/decl.ha b/hare/parse/decl.ha @@ -60,11 +60,16 @@ fn decl_global( ) ([]ast::decl_global | error) = { let decl: []ast::decl_global = []; for (true) { - const symbol = match (try(lexer, ltok::ATTR_SYMBOL)?) { + const (symbol, threadlocal) = match (try(lexer, + ltok::ATTR_SYMBOL, ltok::ATTR_THREADLOCAL)?) { case void => - yield ""; - case lex::token => - yield attr_symbol(lexer)?; + yield ("", false); + case let t: lex::token => + yield if (t.0 == ltok::ATTR_SYMBOL) { + yield (attr_symbol(lexer)?, false); + } else { + yield ("", true); + }; }; const ident = ident(lexer)?; want(lexer, ltok::COLON)?; @@ -79,6 +84,7 @@ fn decl_global( const btok = try(lexer, ltok::COMMA)?; append(decl, ast::decl_global { is_const = tok == ltok::CONST, + is_threadlocal = threadlocal, symbol = symbol, ident = ident, _type = _type, diff --git a/hare/unparse/decl.ha b/hare/unparse/decl.ha @@ -39,6 +39,8 @@ export fn decl(out: io::handle, d: ast::decl) (size | io::error) = { if (len(g[i].symbol) != 0) { n += fmt::fprintf(out, "@symbol(\"{}\") ", g[i].symbol)?; + } else if (g[i].is_threadlocal) { + n += fmt::fprintf(out, "@threadlocal ")?; }; n += ident(out, g[i].ident)?; n += fmt::fprint(out, ": ")?; @@ -166,6 +168,7 @@ fn decl_test(d: ast::decl, expected: str) bool = { decl = [ ast::decl_global { is_const = false, + is_threadlocal = false, symbol = "", ident = ["foo", "bar"], _type = type_int, @@ -173,6 +176,15 @@ fn decl_test(d: ast::decl, expected: str) bool = { }, ast::decl_global { is_const = false, + is_threadlocal = true, + symbol = "", + ident = ["boo"], + _type = type_int, + init = alloc(expr_void), + }, + ast::decl_global { + is_const = false, + is_threadlocal = false, symbol = "foobar", ident = ["baz"], _type = type_int, @@ -181,7 +193,7 @@ fn decl_test(d: ast::decl, expected: str) bool = { ], ... }; - assert(decl_test(d, "let foo::bar: int = void, @symbol(\"foobar\") baz: int = void;")); + assert(decl_test(d, "let foo::bar: int = void, @threadlocal boo: int = void, @symbol(\"foobar\") baz: int = void;")); d.exported = true; d.decl = [