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:
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 = [